예제 #1
0
        /// <summary>
        ///     NOT IMPLEMENTED FOR SET STATE
        /// </summary>
        public bool MeetsConditionsChanging(IEnumerable <ConditionExpression> conditions)
        {
            var metPrePlugin  = false;
            var metPostPlugin = false;

            switch (MessageName)
            {
            case PluginMessage.Create:
            {
                metPostPlugin = XrmEntity.MeetsConditions(GetField, conditions);
                break;
            }

            case PluginMessage.Update:
            {
                metPrePlugin  = XrmEntity.MeetsConditions(PreImageEntity.GetField, conditions);
                metPostPlugin = XrmEntity.MeetsConditions(GetField, conditions);
                break;
            }

            case PluginMessage.Delete:
            {
                metPrePlugin = XrmEntity.MeetsConditions(PreImageEntity.GetField, conditions);
                break;
            }

            default:
            {
                //not sure what to do for setstate with status
                throw new InvalidPluginExecutionException(
                          "MeetsConditionsChanging Not Implemented for plugin message " + MessageName);
            }
            }
            return(metPostPlugin != metPrePlugin);
        }
예제 #2
0
 /// <summary>
 ///     NOT IMPLEMENTED FOR SET STATE
 /// </summary>
 public bool MeetsConditions(IEnumerable <ConditionExpression> conditions)
 {
     if (IsMessage(PluginMessage.Create, PluginMessage.Update))
     {
         return(XrmEntity.MeetsConditions(GetField, conditions));
     }
     throw new NotSupportedException("Method Not Implemented For PLugin Message: " + MessageName);
 }
예제 #3
0
        public void SetField(string entityType, Guid guid, string fieldName, object value)
        {
            var entity = new Entity(entityType)
            {
                Id = guid
            };

            XrmEntity.SetField(entity, fieldName, value);
            Update(entity);
        }
예제 #4
0
        public void SetFieldIfChanging(string recordType, Guid id, string fieldName, object fieldValue)
        {
            var record       = Retrieve(recordType, id, new[] { fieldName });
            var currentValue = record.GetField(fieldName);

            if (!XrmEntity.FieldsEqual(currentValue, fieldValue))
            {
                record.SetField(fieldName, fieldValue);
                Update(record);
            }
        }
 /// <summary>
 ///     !!ONLY IMPLEMENTED FOR STATIC LOOKUP CODES
 /// </summary>
 public void AddLinkFilter(string entityType, string lookup, string fieldName, object value)
 {
     if (LinkEntity == null)
     {
         LinkEntity = new LinkEntity(RecordTypeAggregated, entityType, lookup,
                                     XrmEntity.GetPrimaryKeyName(entityType), JoinOperator.Inner);
         LinkEntity.LinkCriteria.AddCondition(new ConditionExpression(fieldName, ConditionOperator.Equal, value));
     }
     else
     {
         throw new InvalidPluginExecutionException("Only one link filter may be added to an aggregate");
     }
 }
예제 #6
0
 /// <summary>
 ///     MAYBE TRUE FOR DELETE! FIELD MUST BE IN PREIMAGE FOR UPDATE STEP! Returns if the fields value is logically changing
 ///     by inspecting the Target and Preimage
 /// </summary>
 public bool FieldChanging(string fieldName)
 {
     if (MessageName == PluginMessage.Create || MessageName == PluginMessage.Update)
     {
         return(TargetEntity.Contains(fieldName) &&
                !XrmEntity.FieldsEqual(PreImageEntity.GetField(fieldName), TargetEntity.GetField(fieldName)));
     }
     else if (MessageName == PluginMessage.Delete)
     {
         return(GetFieldFromPreImage(fieldName) != null);
     }
     else
     {
         //not sure how to get status if a setstate message
         throw new InvalidPluginExecutionException("FieldChanging Not Implemented for plugin message " +
                                                   MessageName);
     }
 }
예제 #7
0
        public static Entity ReplicateWithFields(Entity entity, IEnumerable <string> fieldsToSubmit)
        {
            var submissionEntity = new Entity(entity.LogicalName)
            {
                Id = entity.Id
            };

            if (fieldsToSubmit != null)
            {
                foreach (var field in fieldsToSubmit)
                {
                    if (entity.Contains(field))
                    {
                        XrmEntity.SetField(submissionEntity, field, XrmEntity.GetField(entity, field));
                    }
                }
            }
            return(submissionEntity);
        }
예제 #8
0
 protected void DerivedConcatenatedField(string fieldToSet, string[] fields, string separator)
 {
     if (IsMessage(PluginMessage.Create, PluginMessage.Update) &&
         Stage == PluginStage.PreOperationEvent)
     {
         if (FieldChanging(fields))
         {
             var values = new List <object>();
             foreach (var field in fields)
             {
                 var value = XrmEntity.GetFieldAsDisplayString(GetField(field));
                 if (!String.IsNullOrWhiteSpace(value))
                 {
                     values.Add(value);
                 }
             }
             SetField(fieldToSet, String.Join(separator, values));
         }
     }
 }
예제 #9
0
 public string GetFieldAsDisplayString(string recordType, string fieldName, object value, LocalisationService localisationService, bool isHtml = false, string func = null)
 {
     if (value == null)
     {
         return("");
     }
     else if (value is string)
     {
         if (isHtml)
         {
             return(((string)value).Replace(Environment.NewLine, "<br />").Replace("\n", "<br />"));
         }
         else
         {
             return((string)value);
         }
     }
     else if (value is EntityReference)
     {
         return(XrmEntity.GetLookupName(value));
     }
     else if (value is OptionSetValue)
     {
         if (value is OptionSetValue)
         {
             return(GetOptionLabel(((OptionSetValue)value).Value, fieldName, recordType));
         }
         throw new Exception("Value Type Not Matched For OptionSetValue " + value.GetType().Name);
     }
     else if (value is Money)
     {
         return(XrmEntity.GetMoneyValue(value).ToString("$##,###,###,###,##0.00"));
     }
     else if (value is DateTime)
     {
         var dt = (DateTime)value;
         if (dt.Kind == DateTimeKind.Utc)
         {
             dt = localisationService.ConvertToTargetTime(dt);
         }
         if (func == "year")
         {
             return(dt.ToString("yyyy"));
         }
         if (GetDateFormat(fieldName, recordType) == DateTimeFormat.DateAndTime)
         {
             return(dt.ToString("dd/MM/yyyy hh:mm:ss tt"));
         }
         return(dt.Date.ToString("dd/MM/yyyy"));
     }
     else if (IsActivityParty(fieldName, recordType))
     {
         if (value is Entity[])
         {
             var namesToOutput = new List <string>();
             foreach (var party in (Entity[])value)
             {
                 namesToOutput.Add(XrmEntity.GetLookupName(party, "partyid"));
             }
             return(string.Join(", ", namesToOutput.Where(f => !string.IsNullOrWhiteSpace(f))));
         }
     }
     else if (value is bool)
     {
         var metadata = GetFieldMetadata(fieldName, recordType) as BooleanAttributeMetadata;
         if (metadata != null)
         {
             var boolValue = (bool)value;
             if (boolValue && metadata.OptionSet != null && metadata.OptionSet.TrueOption != null && metadata.OptionSet.TrueOption.Label != null)
             {
                 return(GetLabelDisplay(metadata.OptionSet.TrueOption.Label));
             }
             if (!boolValue && metadata.OptionSet != null && metadata.OptionSet.FalseOption != null && metadata.OptionSet.FalseOption.Label != null)
             {
                 return(GetLabelDisplay(metadata.OptionSet.FalseOption.Label));
             }
             return(value.ToString());
         }
     }
     return(value.ToString());
 }
예제 #10
0
 public void SetOptionSetField(string fieldName, int index)
 {
     XrmEntity.SetOptionSetField(TargetEntity, fieldName, index);
 }
예제 #11
0
 /// <summary>
 ///     0 IF NOTHING!! FIELD MUST BE IN PREIMAGE FOR UPDATE STEP! Returns the effective value of the boolean field in the
 ///     context record (gets from the target entity or if not in gets from the preimage)
 /// </summary>
 public decimal GetMoneyValue(string fieldName)
 {
     return(XrmEntity.GetMoneyValue(GetField(fieldName)));
 }
예제 #12
0
 /// <summary>
 ///     FALSE IF NOTHING!! FIELD MUST BE IN PREIMAGE FOR UPDATE STEP! Returns the effective value of the boolean field in
 ///     the context record (gets from the target entity or if not in gets from the preimage)
 /// </summary>
 public bool GetBoolean(string fieldName)
 {
     return(XrmEntity.GetBoolean(GetField(fieldName)));
 }
예제 #13
0
 /// <summary>
 ///     -1 IF NOTHING!! FIELD MUST BE IN PREIMAGE FOR UPDATE STEP! Returns the effective int value of the optionset field
 ///     in the context record (gets from the target entity or if not in gets from the preimage)
 /// </summary>
 public int GetOptionSet(string fieldName)
 {
     return(XrmEntity.GetOptionSetValue(GetField(fieldName)));
 }
예제 #14
0
 /// <summary>
 ///     0 if null
 /// </summary>
 public int GetIntField(string fieldName)
 {
     return(XrmEntity.GetInt(GetField(fieldName)));
 }
예제 #15
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)));
 }
예제 #16
0
 public Guid?GetLookupGuidPreImage(string fieldName)
 {
     return(XrmEntity.GetLookupGuid(GetFieldFromPreImage(fieldName)));
 }
예제 #17
0
 /// <summary>
 ///     NULL IF NOTHING!! FIELD MUST BE IN PREIMAGE! Returns the effective id value of the lookup field in the context
 ///     record (gets from the target entity or if not in gets from the preimage)
 /// </summary>
 public Guid?GetLookupGuid(string fieldName)
 {
     return(XrmEntity.GetLookupGuid(GetField(fieldName)));
 }
예제 #18
0
 public object LookupField(string entityType, Guid id, string fieldName)
 {
     return(XrmEntity.GetField(Retrieve(entityType, id, new[] { fieldName }), fieldName));
 }
예제 #19
0
        public IEnumerable <Guid> GetIdsRequiringRefresh(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);
                    }
                }
            }

            return(idsRequireRefresh);
        }
예제 #20
0
        public object GetRollup(LookupRollup rollup, Guid id)
        {
            object newValue = null;

            switch (rollup.RollupType)
            {
            case RollupType.Exists:
            {
                //if the Rollup returns a result > 0 then one exists
                var fetch  = GetLookupFetch(rollup, id);
                var result = XrmService.Fetch(fetch);
                newValue = result.Any() &&
                           XrmEntity.GetInt(result.First().GetFieldValue(FetchAlias)) > 0;
                break;
            }

            case RollupType.Count:
            {
                var result = XrmService.Fetch(GetLookupFetch(rollup, id));
                if (result.Any())
                {
                    newValue = result.ElementAt(0).GetFieldValue(FetchAlias);
                }
                break;
            }

            case RollupType.Sum:
            {
                var result = XrmService.Fetch(GetLookupFetch(rollup, id));
                if (result.Any())
                {
                    newValue = result.ElementAt(0).GetFieldValue(FetchAlias);
                }
                break;
            }

            case RollupType.Min:
            {
                var query = GetRollupQueryForLookup(rollup, id);
                query.AddOrder(rollup.FieldRolledup, OrderType.Ascending);
                var minRecord = XrmService.RetrieveFirst(query);
                newValue = minRecord.GetField(rollup.FieldRolledup);
                break;
            }

            case RollupType.CSV:
            case RollupType.PSV:
            {
                var query = GetRollupQueryForLookup(rollup, id);

                query.AddOrder(rollup.FieldRolledup, OrderType.Ascending);
                var records = XrmService.RetrieveAll(query);
                var labels  =
                    records.Select(e => e.GetField(rollup.FieldRolledup)).
                    ToArray();
                if (rollup.RollupType == RollupType.CSV)
                {
                    newValue = string.Join(", ", labels);
                }
                else
                {
                    newValue = string.Join("|", labels);
                }
                newValue = ((string)newValue).Left(1000);
                break;
            }
            }
            if (newValue == null && rollup.NullAmount != null)
            {
                newValue = rollup.NullAmount;
            }
            if (newValue != null && rollup.ObjectType != null)
            {
                if (rollup.ObjectType == typeof(decimal))
                {
                    newValue = Convert.ToDecimal(newValue.ToString());
                }
            }
            return(newValue);
        }
예제 #21
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);
                }
            }
        }