关于删除工作流和父母关系

时间:2014-01-22 14:09:37

标签: dynamics-crm-2013

我有一个自定义工作流活动,可以在删除父子关系中的子实体时执行。

删除父实体时会出现数据库错误。

我在运行工作流之前尝试检查父实体是否为空,但删除子项时它不为null; CRM必须先删除孩子。

我实施了自己的机会产品实体(称为机会线) 创建,更改或删除商机线时,将执行同步自定义工作流活动 工作流程在机会产品(原始实体)中创建隐藏的写入,其收入等于添加在一起的所有商机线;这样做是为了让系统计算出收入。我尝试直接更新est。收入字段,但是当机会设置为系统计算时出现问题。

/* Deletes all Opportunity Products for this Opportunity and adds a single write in product
 * with the amount equal to the sum of all Opportunity lines
 * If the current message is delete then do not include the current record in the calculation
 * */
private void UpdateOpportunity(WorkflowContext context) // WorkflowContext contains everything retrieved from the CodeActivityContext
{
    if (context.TargetReference != null || context.Target.Contains("wl_revenue")) // this is a delete or revenue update (or new record)
    {                
        var linq = context.Linq;
        var service = context.Service;
        var lineId = (context.Target != null) ? context.Target.Id : context.TargetReference.Id; // context contains Target and TargetReference, Target is an entity and TargetReference is an Entity Reference, one is always not null
        var opp = linq.wl_opportunitylineSet
            .Where(line => line.Id == lineId)
            .Select(line => line.wl_Opportunity)
            .FirstOrDefault();
        if (opp != null)
        {
            var oppId = opp.Id;
            if (oppId != null)
            {
                var lineAmounts = from line in linq.wl_opportunitylineSet
                                    where line.wl_Opportunity.Equals(oppId)
                                    where line.Id != lineId // The current line cannot be retrieved as it is the record in the transaction
                                    select line.wl_Revenue;
                decimal revenue = (context.Target != null && context.Target.Contains("wl_revenue"))
                    ? context.Target.GetAttributeValue<Money>("wl_revenue").Value : 0; // add the amount for this line if it just changed or was created
                foreach (var amount in lineAmounts)
                    revenue += (amount != null) ? amount.Value : 0;
                var oppProducts = from line in linq.OpportunityProductSet
                                    where line.OpportunityId.Equals(oppId)
                                    select line.Id;
                foreach (var line in oppProducts) // there should be 0 or 1
                    service.Delete(OpportunityProduct.EntityLogicalName, line);
                service.Create(new OpportunityProduct
                {
                    IsPriceOverridden = true,
                    IsProductOverridden = true,
                    ProductDescription = "Income",
                    OpportunityId = opp,
                    PricePerUnit = new Money(revenue),
                    Quantity = 1
                });
            }
        }
    }
}

这适用于除父母机会本身被删除之外的所有情况。 是否应该采用另一种方式,或者如果机会被删除,工作流程是否可能不执行,作为单个行的姿势?

我必须有一个自定义机会线,主要是因为机会产品不能用于任何自定义的1:N关系。

1 个答案:

答案 0 :(得分:0)

首先,尝试检查工作流程的执行深度:

if(context.Depth > 1)
    return;

我认为如果工作流由机会删除事件触发,那么您的工作流深度应该大于1.

如果它不起作用,您可以在Opportunity中创建一个检查字段,is_deleted(是/否,默认为否),然后创建一个插件,在Opportunity pre中将此字段更新为yes - 操作删除。之后,在您的工作流程代码中,您应检索并检查此字段,如果商机的is_deleted为是,则返回,无需更新收入。

关于Est。机会中的收入,我认为如果您使用手动计算而不是系统计算会更好更容易。你可以更新Est。直接在您的代码中收入,并且不需要使用商机产品(原始)实体使事情复杂化。