Exemplo n.º 1
0
 /// <summary>
 ///     EMPTY STRING IF NOTHING!! FIELD MUST BE IN PREIMAGE! Returns the effective entitytype  of the lookup field in the
 ///     context record (gets from the target entity or if not in gets from the preimage)
 /// </summary>
 public string GetLookupType(string fieldName)
 {
     return(XrmEntity.GetLookupType(GetField(fieldName)));
 }
Exemplo n.º 2
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))
                                   .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, rollup.ObjectType == typeof(decimal) ? (decimal) - 1 : (int)-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, rollup.ObjectType == typeof(decimal) ? (decimal)1 : (int)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.Service.SetField(targetType, id, "modifiedon", DateTime.UtcNow);
                    var fieldsForUpdating = idUpdates.Value.Select(kv => kv.Key).ToArray();
                    var targetRecord      = plugin.Service.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.Service.Update(targetRecord, fieldsForUpdating);
                }
            }
        }