protected override void ProcessAggregate(XrmEntityPlugin plugin)
 {
     if (plugin is XrmEntityPlugin)
     {
         ProcessLookupAggregate(plugin);
     }
 }
示例#2
0
 public void SetAutonumbers(XrmEntityPlugin plugin)
 {
     if (plugin.IsMessage(PluginMessage.Create) && plugin.IsStage(PluginStage.PreOperationEvent))
     {
         SetAutonumbers(plugin.TargetEntity);
     }
 }
示例#3
0
        private void ExecuteDependencyPluginRefreshForDifferenceNotSupported(XrmEntityPlugin plugin)
        {
            var dictionaryForDifferences = new Dictionary <string, Dictionary <Guid, List <KeyValuePair <string, object> > > >();

            var RollupsToProcess = GetRollupsForRolledupType(plugin.TargetType)
                                   .Where(a => !AllowsDifferenceChange(a.RollupType))
                                   .ToArray();

            foreach (var rollup in RollupsToProcess)
            {
                ExecuteDependencyPluginRefresh(plugin, rollup);
            }
        }
 private void CheckInitialValue(XrmEntityPlugin plugin)
 {
     //a count aggregate should be initialised to zero when the record created
     if (plugin.MessageName == PluginMessage.Create &&
         plugin.Stage == PluginStage.PreOperationEvent &&
         plugin.TargetType == RecordTypeWithAggregate)
     {
         if (NullAmount != null)
         {
             plugin.SetField(AggregateField, NullAmount);
         }
     }
 }
 public void SetInitialValues(XrmEntityPlugin plugin)
 {
     //a count Rollup should be initialised to zero when the record created
     if (plugin.MessageName == PluginMessage.Create &&
         plugin.Stage == PluginStage.PreOperationEvent)
     {
         var RollupsToProcess = GetRollupsForRollupType(plugin.TargetType)
                                .Where(a => AllowsDifferenceChange(a.RollupType))
                                .ToArray();
         foreach (var Rollup in RollupsToProcess)
         {
             if (Rollup.NullAmount != null)
             {
                 plugin.SetField(Rollup.RollupField, Rollup.NullAmount);
             }
         }
     }
 }
        private void CheckAggregation(XrmEntityPlugin plugin)
        {
            if (plugin.TargetType != RecordTypeAggregated)
                return;
            if (
                (plugin.MessageName == PluginMessage.Create || plugin.MessageName == PluginMessage.Update ||
                 plugin.MessageName == PluginMessage.Delete)
                && plugin.Stage == PluginStage.PostEvent
                && plugin.Mode == PluginMode.Synchronous
                )
            {
                var isDependencyChanging = false;

                switch (plugin.MessageName)
                {
                    case PluginMessage.Delete:
                        {
                            isDependencyChanging = plugin.PreImageEntity.Contains(LookupName) &&
                                                   plugin.MeetsConditionsChanging(Filters);
                            break;
                        }
                    case PluginMessage.Update:
                        {
                            if (plugin.FieldChanging(LookupName)
                                || (AggregatedField != null && plugin.FieldChanging(AggregatedField))
                                || (LinkEntity != null && plugin.FieldChanging(LinkEntity.LinkFromAttributeName)))
                                isDependencyChanging = true;
                            else
                                isDependencyChanging = plugin.MeetsConditionsChanging(Filters);
                            break;
                        }
                    case PluginMessage.Create:
                        {
                            isDependencyChanging =
                                plugin.TargetEntity.Contains(LookupName)
                                && (AggregatedField == null || plugin.TargetEntity.Contains(AggregatedField))
                                && plugin.MeetsConditionsChanging(Filters);
                            break;
                        }
                }

                if (isDependencyChanging)
                {
                    object preImageLookup = plugin.PreImageEntity.GetLookupGuid(LookupName);
                    object contextLookup = null;
                    if (plugin.MessageName == PluginMessage.Create || plugin.MessageName == PluginMessage.Update)
                        contextLookup = plugin.TargetEntity.GetLookupGuid(LookupName);
                    var processPreImage = false;
                    var processContextGuid = false;
                    //If they aren't the same do both
                    if (!XrmEntity.FieldsEqual(preImageLookup, contextLookup))
                    {
                        processPreImage = true;
                        processContextGuid = true;
                    }
                    //else just do the first not null one
                    else
                    {
                        if (preImageLookup != null)
                            processPreImage = true;
                        else
                            processContextGuid = true;
                    }
                    if (processPreImage && preImageLookup != null)
                        RefreshAggregate((Guid)preImageLookup, plugin.XrmService, plugin.Controller);
                    if (processContextGuid && contextLookup != null)
                        RefreshAggregate((Guid)contextLookup, plugin.XrmService, plugin.Controller);
                }
            }
        }
 private void ProcessLookupAggregate(XrmEntityPlugin plugin)
 {
     CheckInitialValue(plugin);
     CheckAggregation(plugin);
 }
 protected override void ProcessAggregate(XrmEntityPlugin plugin)
 {
     if (plugin is XrmEntityPlugin)
         ProcessLookupAggregate(plugin);
 }
 private void CheckInitialValue(XrmEntityPlugin plugin)
 {
     //a count aggregate should be initialised to zero when the record created
     if (plugin.MessageName == PluginMessage.Create
         && plugin.Stage == PluginStage.PreOperationEvent
         && plugin.TargetType == RecordTypeWithAggregate)
     {
         if (NullAmount != null)
             plugin.SetField(AggregateField, NullAmount);
     }
 }
 /// <summary>
 ///     If necessary updates the aggregate based on the pluginContext
 /// </summary>
 public void Execute(XrmEntityPlugin plugin)
 {
     ProcessAggregate(plugin);
 }
 public void SetAutonumbers(XrmEntityPlugin plugin)
 {
     if (plugin.IsMessage(PluginMessage.Create) && plugin.IsStage(PluginStage.PreOperationEvent))
     {
         SetAutonumbers(plugin.TargetEntity);
     }
 }
示例#12
0
        private void ExecuteDependencyPluginRefresh(XrmEntityPlugin plugin, LookupRollup rollup)
        {
            var idsRequireRefresh = new List <Guid>();

            var isDependencyChanging = false;

            if (
                (plugin.MessageName == PluginMessage.Create || plugin.MessageName == PluginMessage.Update ||
                 plugin.MessageName == PluginMessage.Delete) &&
                plugin.Stage == PluginStage.PostEvent &&
                plugin.Mode == PluginMode.Synchronous
                )
            {
                switch (plugin.MessageName)
                {
                case PluginMessage.Delete:
                {
                    isDependencyChanging = plugin.PreImageEntity.Contains(rollup.LookupName) &&
                                           plugin.MeetsConditionsChanging(rollup.Filters);
                    break;
                }

                case PluginMessage.Update:
                {
                    if (plugin.FieldChanging(rollup.LookupName) ||
                        (rollup.FieldRolledup != null && plugin.FieldChanging(rollup.FieldRolledup)) ||
                        (rollup.LinkEntity != null && plugin.FieldChanging(rollup.LinkEntity.LinkFromAttributeName)))
                    {
                        isDependencyChanging = true;
                    }
                    else
                    {
                        isDependencyChanging = plugin.MeetsConditionsChanging(rollup.Filters);
                    }
                    break;
                }

                case PluginMessage.Create:
                {
                    isDependencyChanging =
                        plugin.TargetEntity.Contains(rollup.LookupName) &&
                        (rollup.FieldRolledup == null || plugin.TargetEntity.Contains(rollup.FieldRolledup)) &&
                        plugin.MeetsConditionsChanging(rollup.Filters);
                    break;
                }
                }
                if (isDependencyChanging)
                {
                    object preImageLookup = plugin.PreImageEntity.GetLookupGuid(rollup.LookupName);
                    object contextLookup  = null;
                    if (plugin.MessageName == PluginMessage.Create || plugin.MessageName == PluginMessage.Update)
                    {
                        contextLookup = plugin.TargetEntity.GetLookupGuid(rollup.LookupName);
                    }
                    var processPreImage    = false;
                    var processContextGuid = false;
                    //If they aren't the same do both
                    if (!XrmEntity.FieldsEqual(preImageLookup, contextLookup))
                    {
                        processPreImage    = true;
                        processContextGuid = true;
                    }
                    //else just do the first not null one
                    else
                    {
                        if (preImageLookup != null)
                        {
                            processPreImage = true;
                        }
                        else
                        {
                            processContextGuid = true;
                        }
                    }
                    if (processPreImage && preImageLookup != null)
                    {
                        idsRequireRefresh.Add((Guid)preImageLookup);
                    }
                    if (processContextGuid && contextLookup != null)
                    {
                        idsRequireRefresh.Add((Guid)contextLookup);
                    }
                }
            }
            foreach (var id in idsRequireRefresh)
            {
                RefreshRollup(id, rollup);
            }
        }
示例#13
0
        private void ExecuteDependencyPluginDifferences(XrmEntityPlugin plugin)
        {
            var dictionaryForDifferences = new Dictionary <string, Dictionary <Guid, List <KeyValuePair <string, object> > > >();

            var rollupsToProcess = GetRollupsForRolledupType(plugin.TargetType)
                                   .Where(a => AllowsDifferenceChange(a.RollupType))
                                   .ToArray();

            if (plugin.IsMessage(PluginMessage.Create, PluginMessage.Update, PluginMessage.Delete) &&
                plugin.IsStage(PluginStage.PostEvent) &&
                plugin.IsMode(PluginMode.Synchronous))
            {
                //this dictionary will capture the changes we need to apply to parent records for all Rollups
                //type -> ids -> fields . values
                Action <string, Guid, string, object> addDifferenceToApply = (type, id, field, val) =>
                {
                    if (!dictionaryForDifferences.ContainsKey(type))
                    {
                        dictionaryForDifferences.Add(type, new Dictionary <Guid, List <KeyValuePair <string, object> > >());
                    }
                    if (!dictionaryForDifferences[type].ContainsKey(id))
                    {
                        dictionaryForDifferences[type].Add(id, new List <KeyValuePair <string, object> >());
                    }
                    dictionaryForDifferences[type][id].Add(new KeyValuePair <string, object>(field, val));
                };

                foreach (var rollup in rollupsToProcess)
                {
                    if (rollup.LinkEntity != null)
                    {
                        throw new NotImplementedException("Rollups with a LinkEntity are not implemented for the ProcessAsDifferences method");
                    }

                    //capture required facts in the plugin context to process our ifs and elses
                    var metConditionsBefore  = XrmEntity.MeetsConditions(plugin.GetFieldFromPreImage, rollup.Filters);
                    var meetsConditionsAfter = plugin.MessageName == PluginMessage.Delete
                        ? false
                        : XrmEntity.MeetsConditions(plugin.GetField, rollup.Filters);
                    var linkedIdBefore = XrmEntity.GetLookupType(plugin.GetFieldFromPreImage(rollup.LookupName)) == rollup.RecordTypeWithRollup
                        ? plugin.GetLookupGuidPreImage(rollup.LookupName)
                        : (Guid?)null;
                    var linkedIdAfter = plugin.MessageName == PluginMessage.Delete || XrmEntity.GetLookupType(plugin.GetField(rollup.LookupName)) != rollup.RecordTypeWithRollup
                        ? (Guid?)null
                        : plugin.GetLookupGuid(rollup.LookupName);
                    var isValueChanging = plugin.FieldChanging(rollup.FieldRolledup);

                    //this covers all scenarios I thought of which require changing the value in a parent record
                    if (linkedIdBefore.HasValue && linkedIdBefore == linkedIdAfter)
                    {
                        //the same record linked before and after
                        if (metConditionsBefore && meetsConditionsAfter)
                        {
                            //if part of Rollup before and after
                            if (isValueChanging)
                            {
                                //and the value is changing then apply difference
                                if (rollup.RollupType == RollupType.Sum)
                                {
                                    addDifferenceToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, GetDifferenceToApply(plugin.GetFieldFromPreImage(rollup.FieldRolledup), plugin.GetField(rollup.FieldRolledup)));
                                }
                                else if (rollup.RollupType == RollupType.Count)
                                {
                                    //for count only adjust if changing between null and not null
                                    if (plugin.GetFieldFromPreImage(rollup.FieldRolledup) == null)
                                    {
                                        addDifferenceToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, 1);
                                    }
                                    else if (plugin.GetField(rollup.FieldRolledup) == null)
                                    {
                                        addDifferenceToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, -1);
                                    }
                                }
                            }
                        }
                        if (!metConditionsBefore && meetsConditionsAfter)
                        {
                            //if was not part of Rollup before but is now apply the entire value
                            if (rollup.RollupType == RollupType.Sum)
                            {
                                addDifferenceToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, plugin.GetField(rollup.FieldRolledup));
                            }
                            else if (rollup.RollupType == RollupType.Count)
                            {
                                addDifferenceToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, 1);
                            }
                        }
                        if (metConditionsBefore && !meetsConditionsAfter)
                        {
                            //if was part of Rollup before but not now apply the entire value negative
                            if (rollup.RollupType == RollupType.Sum)
                            {
                                addDifferenceToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, GetNegative(plugin.GetFieldFromPreImage(rollup.FieldRolledup)));
                            }
                            else if (rollup.RollupType == RollupType.Count)
                            {
                                addDifferenceToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, -1);
                            }
                        }
                    }
                    else
                    {
                        //different parent linked before and after
                        if (linkedIdBefore.HasValue && metConditionsBefore)
                        {
                            //if was part of previous linked records Rollup then negate the previous value
                            if (rollup.RollupType == RollupType.Sum)
                            {
                                addDifferenceToApply(rollup.RecordTypeWithRollup, linkedIdBefore.Value, rollup.RollupField, GetNegative(plugin.GetFieldFromPreImage(rollup.FieldRolledup)));
                            }
                            else if (rollup.RollupType == RollupType.Count)
                            {
                                addDifferenceToApply(rollup.RecordTypeWithRollup, linkedIdBefore.Value, rollup.RollupField, -1);
                            }
                        }
                        if (linkedIdAfter.HasValue && meetsConditionsAfter)
                        {
                            //if part of new linked records Rollup then apply the entire value
                            if (rollup.RollupType == RollupType.Sum)
                            {
                                addDifferenceToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, plugin.GetField(rollup.FieldRolledup));
                            }
                            else if (rollup.RollupType == RollupType.Count)
                            {
                                addDifferenceToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, 1);
                            }
                        }
                    }
                }
            }
            if (dictionaryForDifferences.Any())
            {
                plugin.Trace("Updating Rollup Differences");
                foreach (var item in dictionaryForDifferences)
                {
                    foreach (var field in item.Value)
                    {
                        foreach (var value in field.Value)
                        {
                            plugin.Trace("Updating " + item.Key + " " + field.Key + " " + value.Key + " " + value.Value + (value.Value == null ? "(null)" : (" (" + value.Value.GetType().Name + ")")));
                        }
                    }
                }
            }
            //apply all required changes to parents we captured
            //type -> ids -> fields . values
            foreach (var item in dictionaryForDifferences)
            {
                var targetType = item.Key;
                foreach (var idUpdates in item.Value)
                {
                    var id = idUpdates.Key;
                    //lock the parent record then retreive it
                    plugin.XrmService.SetField(targetType, id, "modifiedon", DateTime.UtcNow);
                    var fieldsForUpdating = idUpdates.Value.Select(kv => kv.Key).ToArray();
                    var targetRecord      = plugin.XrmService.Retrieve(targetType, id, idUpdates.Value.Select(kv => kv.Key));
                    //update the fields
                    foreach (var fieldUpdate in idUpdates.Value)
                    {
                        targetRecord.SetField(fieldUpdate.Key, XrmEntity.SumFields(new[] { fieldUpdate.Value, targetRecord.GetField(fieldUpdate.Key) }));
                    }
                    plugin.XrmService.Update(targetRecord, fieldsForUpdating);
                }
            }
        }
示例#14
0
 /// <summary>
 /// Processes changes in the record type Rollup
 /// WARNING some types of Rollups have potential for deadlocks!
 /// </summary>
 /// <param name="plugin"></param>
 public void ExecuteDependencyPlugin(XrmEntityPlugin plugin)
 {
     ExecuteDependencyPluginDifferences(plugin);
     ExecuteDependencyPluginRefreshForDifferenceNotSupported(plugin);
 }
示例#15
0
 /// <summary>
 ///     If necessary updates the aggregate based on the pluginContext
 /// </summary>
 public void Execute(XrmEntityPlugin plugin)
 {
     ProcessAggregate(plugin);
 }
示例#16
0
 protected abstract void ProcessAggregate(XrmEntityPlugin plugin);
 private void ProcessLookupAggregate(XrmEntityPlugin plugin)
 {
     CheckInitialValue(plugin);
     CheckAggregation(plugin);
 }
 protected abstract void ProcessAggregate(XrmEntityPlugin plugin);
        private void CheckAggregation(XrmEntityPlugin plugin)
        {
            if (plugin.TargetType != RecordTypeAggregated)
            {
                return;
            }
            if (
                (plugin.MessageName == PluginMessage.Create || plugin.MessageName == PluginMessage.Update ||
                 plugin.MessageName == PluginMessage.Delete) &&
                plugin.Stage == PluginStage.PostEvent &&
                plugin.Mode == PluginMode.Synchronous
                )
            {
                var isDependencyChanging = false;

                switch (plugin.MessageName)
                {
                case PluginMessage.Delete:
                {
                    isDependencyChanging = plugin.PreImageEntity.Contains(LookupName) &&
                                           plugin.MeetsConditionsChanging(Filters);
                    break;
                }

                case PluginMessage.Update:
                {
                    if (plugin.FieldChanging(LookupName) ||
                        (AggregatedField != null && plugin.FieldChanging(AggregatedField)) ||
                        (LinkEntity != null && plugin.FieldChanging(LinkEntity.LinkFromAttributeName)))
                    {
                        isDependencyChanging = true;
                    }
                    else
                    {
                        isDependencyChanging = plugin.MeetsConditionsChanging(Filters);
                    }
                    break;
                }

                case PluginMessage.Create:
                {
                    isDependencyChanging =
                        plugin.TargetEntity.Contains(LookupName) &&
                        (AggregatedField == null || plugin.TargetEntity.Contains(AggregatedField)) &&
                        plugin.MeetsConditionsChanging(Filters);
                    break;
                }
                }
                if (isDependencyChanging)
                {
                    object preImageLookup = plugin.PreImageEntity.GetLookupGuid(LookupName);
                    object contextLookup  = null;
                    if (plugin.MessageName == PluginMessage.Create || plugin.MessageName == PluginMessage.Update)
                    {
                        contextLookup = plugin.TargetEntity.GetLookupGuid(LookupName);
                    }
                    var processPreImage    = false;
                    var processContextGuid = false;
                    //If they aren't the same do both
                    if (!XrmEntity.FieldsEqual(preImageLookup, contextLookup))
                    {
                        processPreImage    = true;
                        processContextGuid = true;
                    }
                    //else just do the first not null one
                    else
                    {
                        if (preImageLookup != null)
                        {
                            processPreImage = true;
                        }
                        else
                        {
                            processContextGuid = true;
                        }
                    }
                    if (processPreImage && preImageLookup != null)
                    {
                        RefreshAggregate((Guid)preImageLookup, plugin.XrmService, plugin.Controller);
                    }
                    if (processContextGuid && contextLookup != null)
                    {
                        RefreshAggregate((Guid)contextLookup, plugin.XrmService, plugin.Controller);
                    }
                }
            }
        }
        /// <summary>
        /// Processes plugin for a type type rolled up
        /// </summary>
        /// <param name="plugin"></param>
        public void ExecuteRollupPlugin(XrmEntityPlugin plugin)
        {
            if (plugin.IsMessage(PluginMessage.Create, PluginMessage.Update, PluginMessage.Delete) &&
                plugin.IsStage(PluginStage.PostEvent) &&
                plugin.IsMode(PluginMode.Synchronous))
            {
                var rollupsToProcess         = GetRollupsForRolledupType(plugin.TargetType).ToArray();
                var dictionaryForDifferences = new Dictionary <string, Dictionary <Guid, List <UpdateMeta> > >();

                Action <string, Guid, string, object, LookupRollup> addValueToApply = (type, id, field, val, rollup) =>
                {
                    if (!dictionaryForDifferences.ContainsKey(type))
                    {
                        dictionaryForDifferences.Add(type, new Dictionary <Guid, List <UpdateMeta> >());
                    }
                    if (!dictionaryForDifferences[type].ContainsKey(id))
                    {
                        dictionaryForDifferences[type].Add(id, new List <UpdateMeta>());
                    }
                    dictionaryForDifferences[type][id].Add(new UpdateMeta(field, rollup, val));
                };

                foreach (var rollup in rollupsToProcess)
                {
                    //capture required facts in the plugin context to process our ifs and elses
                    var metConditionsBefore  = XrmEntity.MeetsFilter(plugin.GetFieldFromPreImage, rollup.Filter);
                    var meetsConditionsAfter = plugin.MessageName == PluginMessage.Delete
                        ? false
                        : XrmEntity.MeetsFilter(plugin.GetField, rollup.Filter);
                    var linkedIdBefore = XrmEntity.GetLookupType(plugin.GetFieldFromPreImage(rollup.LookupName)) == rollup.RecordTypeWithRollup
                        ? plugin.GetLookupGuidPreImage(rollup.LookupName)
                        : null;
                    var linkedIdAfter = plugin.MessageName == PluginMessage.Delete || XrmEntity.GetLookupType(plugin.GetField(rollup.LookupName)) != rollup.RecordTypeWithRollup
                        ? null
                        : plugin.GetLookupGuid(rollup.LookupName);
                    var isValueChanging   = rollup.FieldRolledup != null && plugin.FieldChanging(rollup.FieldRolledup);
                    var isOrderByChanging = rollup.OrderByField != null && plugin.FieldChanging(rollup.OrderByField);

                    if (AllowsDifferenceChange(rollup.RollupType))
                    {
                        //this covers scenarios which require changing the value in a parent record
                        if (linkedIdBefore.HasValue && linkedIdBefore == linkedIdAfter)
                        {
                            //the same record linked before and after
                            if (metConditionsBefore && meetsConditionsAfter)
                            {
                                //if part of Rollup before and after
                                if (isValueChanging)
                                {
                                    //and the value is changing then apply difference
                                    if (rollup.RollupType == RollupType.Sum)
                                    {
                                        addValueToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, GetDifferenceToApply(plugin.GetFieldFromPreImage(rollup.FieldRolledup), plugin.GetField(rollup.FieldRolledup)), rollup);
                                    }
                                    else if (rollup.RollupType == RollupType.Count)
                                    {
                                        //for count only adjust if changing between null and not null
                                        if (plugin.GetFieldFromPreImage(rollup.FieldRolledup) == null)
                                        {
                                            addValueToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, 1, rollup);
                                        }
                                        else if (plugin.GetField(rollup.FieldRolledup) == null)
                                        {
                                            addValueToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, -1, rollup);
                                        }
                                    }
                                }
                            }
                            if (!metConditionsBefore && meetsConditionsAfter)
                            {
                                //if was not part of Rollup before but is now apply the entire value
                                if (rollup.RollupType == RollupType.Sum)
                                {
                                    addValueToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, plugin.GetField(rollup.FieldRolledup), rollup);
                                }
                                else if (rollup.RollupType == RollupType.Count)
                                {
                                    addValueToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, 1, rollup);
                                }
                            }
                            if (metConditionsBefore && !meetsConditionsAfter)
                            {
                                //if was part of Rollup before but not now apply the entire value negative
                                if (rollup.RollupType == RollupType.Sum)
                                {
                                    addValueToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, GetNegative(plugin.GetFieldFromPreImage(rollup.FieldRolledup)), rollup);
                                }
                                else if (rollup.RollupType == RollupType.Count)
                                {
                                    addValueToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, -1, rollup);
                                }
                            }
                        }
                        else
                        {
                            //different parent linked before and after
                            if (linkedIdBefore.HasValue && metConditionsBefore)
                            {
                                //if was part of previous linked records Rollup then negate the previous value
                                if (rollup.RollupType == RollupType.Sum)
                                {
                                    addValueToApply(rollup.RecordTypeWithRollup, linkedIdBefore.Value, rollup.RollupField, GetNegative(plugin.GetFieldFromPreImage(rollup.FieldRolledup)), rollup);
                                }
                                else if (rollup.RollupType == RollupType.Count)
                                {
                                    addValueToApply(rollup.RecordTypeWithRollup, linkedIdBefore.Value, rollup.RollupField, -1, rollup);
                                }
                            }
                            if (linkedIdAfter.HasValue && meetsConditionsAfter)
                            {
                                //if part of new linked records Rollup then apply the entire value
                                if (rollup.RollupType == RollupType.Sum)
                                {
                                    addValueToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, plugin.GetField(rollup.FieldRolledup), rollup);
                                }
                                else if (rollup.RollupType == RollupType.Count)
                                {
                                    addValueToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, 1, rollup);
                                }
                            }
                        }
                    }
                    else
                    {
                        //these ones just recalculate on the parent record(s)
                        var isDependencyChanging = false;
                        switch (plugin.MessageName)
                        {
                        case PluginMessage.Delete:
                        {
                            isDependencyChanging = linkedIdBefore.HasValue && metConditionsBefore;
                            break;
                        }

                        case PluginMessage.Update:
                        {
                            if (linkedIdBefore != linkedIdAfter || isValueChanging)
                            {
                                isDependencyChanging = true;
                            }
                            else if (isOrderByChanging)
                            {
                                isDependencyChanging = true;
                            }
                            else
                            {
                                isDependencyChanging = metConditionsBefore != meetsConditionsAfter;
                            }
                            break;
                        }

                        case PluginMessage.Create:
                        {
                            isDependencyChanging = linkedIdAfter.HasValue &&
                                                   (rollup.FieldRolledup == null || isValueChanging) &&
                                                   meetsConditionsAfter;
                            break;
                        }
                        }
                        if (isDependencyChanging)
                        {
                            var processPreReferenced  = false;
                            var processPostReferenced = false;
                            //If they aren't the same do both
                            if (!XrmEntity.FieldsEqual(linkedIdBefore, linkedIdAfter))
                            {
                                processPreReferenced  = true;
                                processPostReferenced = true;
                            }
                            //else just do the first not null one
                            else
                            {
                                if (linkedIdBefore.HasValue)
                                {
                                    processPreReferenced = true;
                                }
                                else
                                {
                                    processPostReferenced = true;
                                }
                            }
                            if (processPreReferenced && linkedIdBefore.HasValue)
                            {
                                addValueToApply(rollup.RecordTypeWithRollup, linkedIdBefore.Value, rollup.RollupField, null, rollup);
                            }
                            if (processPostReferenced && linkedIdAfter.HasValue)
                            {
                                addValueToApply(rollup.RecordTypeWithRollup, linkedIdAfter.Value, rollup.RollupField, null, rollup);
                            }
                        }
                    }
                }

                //apply all required changes to parents we captured
                //type -> ids -> fields . values
                foreach (var item in dictionaryForDifferences)
                {
                    var targetType = item.Key;
                    foreach (var idUpdates in item.Value)
                    {
                        var id = idUpdates.Key;
                        //lock the parent record then retreive it
                        plugin.XrmService.SetField(targetType, id, "modifiedon", DateTime.UtcNow);
                        var fieldsForUpdating = idUpdates.Value.Select(kv => kv.FieldName).ToArray();
                        var targetRecord      = plugin.XrmService.Retrieve(targetType, id, idUpdates.Value.Select(kv => kv.FieldName));
                        //update the fields
                        foreach (var fieldUpdate in idUpdates.Value)
                        {
                            if (AllowsDifferenceChange(fieldUpdate.Rollup.RollupType))
                            {
                                targetRecord.SetField(fieldUpdate.FieldName, XrmEntity.SumFields(new[] { fieldUpdate.DifferenceValue, targetRecord.GetField(fieldUpdate.FieldName) }));
                            }
                            else
                            {
                                targetRecord.SetField(fieldUpdate.FieldName, GetRollup(fieldUpdate.Rollup, id));
                            }
                        }
                        plugin.XrmService.Update(targetRecord, fieldsForUpdating);
                    }
                }
            }
        }
示例#21
0
 protected virtual void ProcessAggregate(XrmEntityPlugin plugin)
 {
     if (plugin is XrmEntityPlugin)
         ProcessLookupAggregate(plugin);
 }