/// <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); }
/// <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); }
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); }
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"); } }
/// <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); } }
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); }
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)); } } }
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()); }
public void SetOptionSetField(string fieldName, int index) { XrmEntity.SetOptionSetField(TargetEntity, fieldName, index); }
/// <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))); }
/// <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))); }
/// <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))); }
/// <summary> /// 0 if null /// </summary> public int GetIntField(string fieldName) { return(XrmEntity.GetInt(GetField(fieldName))); }
/// <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))); }
public Guid?GetLookupGuidPreImage(string fieldName) { return(XrmEntity.GetLookupGuid(GetFieldFromPreImage(fieldName))); }
/// <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))); }
public object LookupField(string entityType, Guid id, string fieldName) { return(XrmEntity.GetField(Retrieve(entityType, id, new[] { fieldName }), fieldName)); }
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); }
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); }
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); } } }