【问题标题】:Quote Validation Plugin Not Preventing Closing of Quote on InvalidPluginExecutionException报价验证插件不阻止在 InvalidPluginExecutionException 上关闭报价
【发布时间】:2017-09-27 20:13:17
【问题描述】:

我正在编写一个插件来在保存之前验证报价。我们要强制规定必须有报价产品线

报价前的项目可以激活、赢得或丢失。草稿模式没有这个要求。

我编写了以下代码,当按下功能区上的“关闭报价”按钮并选择Won作为原因时,会弹出一个带有错误消息的业务流程错误框。

但是,在关闭错误消息并刷新页面后,报价被设置为关闭。为什么即使抛出异常,报价也会关闭?

仅供参考,插件阶段设置为预操作。

这是我的源代码(2017 年 10 月 2 日更新):

using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ValbrunaPlugins
{
    public class QuoteValidation : IPlugin
    {
        private ITracingService tracingService;

        public void Execute(IServiceProvider serviceProvider)
        {

            // retrieve the context, factory, and service
            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = factory.CreateOrganizationService(context.UserId);

            bool isCorrectEvent = context.MessageName == "SetStateDynamicEntity" || context.MessageName == "SetState" || context.MessageName == "Win" || context.MessageName == "Close";
            bool hasEnityMoniker = context.InputParameters.Contains("EntityMoniker");

            // ensure we are handling the correct event and we were passed an entity from the context
            if (!isCorrectEvent || !hasEnityMoniker) return;
            // get the reference to the quote entity
            EntityReference quoteEntityReference = (EntityReference)context.InputParameters["EntityMoniker"];

            Entity quoteEntity = null;
            try
            {
                // get the quote entity from the entity reference
                quoteEntity = ActualEntity.GetActualEntity(quoteEntityReference, service);
            } catch (Exception ex)
            {
                throw new InvalidPluginExecutionException("Quote with id " + quoteEntityReference.Id + " not found.");
            }

            // ensure that we have the correct entity
            if (quoteEntity.LogicalName != "quote") return;

            // write query to retrieve all the details for this quote
            QueryExpression retrieveQuoteDetailsQuery = new QueryExpression
            {
                EntityName = "quotedetail",
                ColumnSet = new ColumnSet(),
                Criteria = new FilterExpression
                {
                    Conditions =
                        {
                            new ConditionExpression
                            {
                            AttributeName = "quoteid",
                            Operator = ConditionOperator.Equal,
                            Values = { (Guid)quoteEntity.Id }
                            }
                        }
                }
            };

            // execute the query to retrieve the details for this quote
            EntityCollection quoteDetails = service.RetrieveMultiple(retrieveQuoteDetailsQuery);

            // retrieve the current status of the quote
            // 0 - Draft
            // 1 - Active
            // 2 - Won
            // 3 - Closed
            int quoteStatus = ((OptionSetValue)(quoteEntity.Attributes["statecode"])).Value;

            // if not in draft mode
            if (quoteStatus != 0)
            {
                // if the amount of details for the quote is less than 1
                if (quoteDetails.Entities.Count < 1)
                {
                    throw new InvalidPluginExecutionException("There must be a quote product line item on a quote before a quote can be activated, won, or lost while not in draft mode.");
                }
            }
        }

    }
}

2017 年 10 月 2 日更新:

我为 SetState 创建了一个单独的步骤并更新了我的源代码。

但是,我仍然遇到同样的问题。当我关闭报价时出现错误,但当我刷新页面时,报价已设置为关闭。

注意:报价处于活动状态,没有报价详情,因此无法赢得报价。

按原样显示业务流程错误。但是,当我刷新页面时,报价单的状态已设置为“已关闭”。如果抛出异常,为什么要这样做?

【问题讨论】:

    标签: c# plugins dynamics-crm dynamics-crm-365


    【解决方案1】:

    您必须为SetStateSetStateDynamicEntity 消息注册插件步骤。

    reference

    为什么我需要在 SetState 和 SetStateDynamicEntity 上注册 分开?
    正如我之前提到的,有多个消息 在 CRM 中执行相同的操作。一个这样的例子是 SetStateRequest 和 SetStateDyanmicEntityRequest 。如果你想写一个插件 SetState,那么你需要在两条消息上注册它。

    Read more

    【讨论】:

    • 感谢您的回复!请看一下我上面更新的问题。我添加了步骤 setstate 但我仍然遇到同样的问题。
    • 您是否尝试检查“不要修改报价”并查看行为?如果您说“创建修订报价”,Bcoz CRM 将继续创建新版本
    • 这不是因为选择了修改后的报价...经过一些调试后,我意识到关闭报价时发送到插件的消息是关闭。 Close 消息包含 QuoteClose Entity 而不是 EntityMoniker EntityReference。因此 if (!isCorrectEvent || !hasEnityMoniker) 返回;退出插件,因为没有 EntityMoniker。完成清理后,我将更新我的代码,但问题已解决。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-25
    • 2016-03-28
    • 1970-01-01
    相关资源
    最近更新 更多