private void SetViewName() { if (IsMessage(PluginMessage.Create, PluginMessage.Update) && IsStage(PluginStage.PreOperationEvent)) { if (FieldChanging(Fields.jmcg_workflowtask_.jmcg_targetviewid , Fields.jmcg_workflowtask_.jmcg_workflowexecutiontype)) { var savedQueryId = GetStringField(Fields.jmcg_workflowtask_.jmcg_targetviewid); var type = GetOptionSet(Fields.jmcg_workflowtask_.jmcg_workflowexecutiontype); var viewRequired = type == OptionSets.WorkflowTask.WorkflowExecutionType.TargetPerViewResult || type == OptionSets.WorkflowTask.WorkflowExecutionType.ViewNotification; if (viewRequired && string.IsNullOrWhiteSpace(savedQueryId)) { throw new InvalidPluginExecutionException(string.Format("{0} is required", GetFieldLabel(Fields.jmcg_workflowtask_.jmcg_targetviewid))); } if (!string.IsNullOrWhiteSpace(savedQueryId)) { var savedQuery = XrmService.Retrieve(Entities.savedquery, new Guid(savedQueryId)); if (!XrmEntity.FieldsEqual(GetField(Fields.jmcg_workflowtask_.jmcg_targetviewselectedname), savedQuery.GetStringField(Fields.savedquery_.name))) { SetField(Fields.jmcg_workflowtask_.jmcg_targetviewselectedname, savedQuery.GetStringField(Fields.savedquery_.name)); } } } } }
private void SetActivityCompleteTrigger(Func <string, object> getField) { if (!string.IsNullOrWhiteSpace((string)getField(Fields.jmcg_sms_.jmcg_setsentonregardingfield))) { var regardingType = XrmEntity.GetLookupType(getField(Fields.activitypointer_.regardingobjectid)); var regardingId = XrmEntity.GetLookupGuid(getField(Fields.activitypointer_.regardingobjectid)); if (regardingId.HasValue) { var fieldToSet = (string)getField(Fields.jmcg_sms_.jmcg_setsentonregardingfield); var fieldType = XrmService.GetFieldType(fieldToSet, regardingType); var completionTarget = XrmService.Retrieve(regardingType, regardingId.Value, new[] { fieldToSet }); if (fieldType == AttributeTypeCode.Boolean) { if (!completionTarget.GetBoolean(fieldToSet)) { XrmService.SetField(regardingType, regardingId.Value, fieldToSet, true); } } else if (fieldType == AttributeTypeCode.DateTime) { if (!XrmEntity.FieldsEqual(completionTarget.GetField(fieldToSet), LocalisationService.TodayUnspecifiedType)) { XrmService.SetField(regardingType, regardingId.Value, fieldToSet, LocalisationService.TodayUnspecifiedType); } } else { throw new NotImplementedException(string.Format("Setting the field type {0} of the field {1} on {2} type is not implemented", fieldType, fieldToSet, regardingType)); } } } }
/// <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); } } } }
private IEnumerable <Entity> MapToEntities(IEnumerable <IRecord> queryRows, IMapSpreadsheetImport mapping, ParseIntoEntitiesResponse response, bool useAmericanDates) { var result = new List <Entity>(); var nNRelationshipEntityNames = XrmRecordService .GetManyToManyRelationships() .Select(m => m.IntersectEntityName) .ToArray(); var duplicateLogged = false; var rowNumber = 0; foreach (var row in queryRows) { rowNumber++; var targetType = mapping.TargetType; try { var isNnRelation = nNRelationshipEntityNames.Contains(targetType); var entity = new Entity(targetType); //this is used in the import to output the rownumber //if the import throws an error foreach (var fieldMapping in mapping.FieldMappings) { var targetField = fieldMapping.TargetField; if (fieldMapping.TargetField != null) { var stringValue = row.GetStringField(fieldMapping.SourceField); if (stringValue != null) { stringValue = stringValue.Trim(); } if (isNnRelation) { //bit of hack //for csv relationships just set to a string and map it later //as the referenced record may not be created yet entity.SetField(targetField, stringValue); } else if (XrmRecordService.XrmService.IsLookup(targetField, targetType)) { //for lookups am going to set to a empty guid and allow the import part to replace with a correct guid if (!stringValue.IsNullOrWhiteSpace()) { entity.SetField(targetField, new EntityReference(XrmRecordService.XrmService.GetLookupTargetEntity(targetField, targetType), Guid.Empty) { Name = stringValue }); } } else { try { entity.SetField(targetField, XrmRecordService.XrmService.ParseField(targetField, targetType, stringValue, useAmericanDates)); } catch (Exception ex) { response.AddResponseItem(new ParseIntoEntitiesResponse.ParseIntoEntitiesError(rowNumber, targetType, targetField, null, stringValue, "Error Parsing Field - " + ex.Message, ex)); } } } } if (entity.GetFieldsInEntity().All(f => XrmEntity.FieldsEqual(null, entity.GetField(f)))) { //ignore any where all fields emopty continue; } //okay any which are exact duplicates to previous ones lets ignore if (result.Any(r => r.GetFieldsInEntity().Except(new[] { "Sheet.RowNumber" }).All(f => { //since for entity references we just load the name with empty guids //we check the dipslay name for them var fieldValue1 = r.GetField(f); var fieldValue2 = entity.GetField(f); if (fieldValue1 is EntityReference && fieldValue2 is EntityReference) { return(((EntityReference)fieldValue1).Name == ((EntityReference)fieldValue2).Name); } else { return(XrmRecordService.FieldsEqual(fieldValue1, fieldValue2)); } }))) { if (!duplicateLogged) { response.AddResponseItem(new ParseIntoEntitiesResponse.ParseIntoEntitiesError(rowNumber, targetType, null, null, null, "At Least One Duplicate Removed", null)); duplicateLogged = true; } continue; } result.Add(entity); } catch (Exception ex) { response.AddResponseItem(new ParseIntoEntitiesResponse.ParseIntoEntitiesError("Mapping Error", ex)); } } return(result); }
public void DeploymentImportXmlSimpleTest() { var type = TestEntityType; PrepareTests(); var workFolder = ClearFilesAndData(type); var importService = new ImportXmlService(XrmRecordService); var fields = GetFields(type, importService); var updateFields = GetUpdateFields(type, importService); var record = CreateTestRecord(type, importService); var createdEntity = XrmService.Retrieve(record.LogicalName, record.Id); var exportService = new ExportXmlService(XrmRecordService); var exportRequest = new ExportXmlRequest { Folder = new Folder(workFolder), RecordTypesToExport = new[] { new ExportRecordType() { RecordType = new RecordType(TestEntityType, TestEntityType) } } }; var exportResponse = exportService.Execute(exportRequest, new ServiceRequestController(Controller)); Assert.IsTrue(exportResponse.Success); XrmService.Delete(record); var application = CreateAndLoadTestApplication <ImportXmlModule>(); var importRequest = new ImportXmlRequest { Folder = new Folder(workFolder) }; var response = application.NavigateAndProcessDialog <ImportXmlModule, ImportXmlDialog, ImportXmlResponse>(importRequest); Assert.IsFalse(response.HasError); var createdRecord = XrmService.Retrieve(type, createdEntity.Id); foreach (var updateField in updateFields) { Assert.IsTrue(XrmEntity.FieldsEqual(createdEntity.GetField(updateField), createdRecord.GetField(updateField))); } foreach (var field in fields) { record.SetField(field, CreateNewEntityFieldValue(field, type, record)); } XrmService.Update(record); record = XrmService.Retrieve(record.LogicalName, record.Id); importRequest = new ImportXmlRequest { Folder = new Folder(workFolder) }; application = CreateAndLoadTestApplication <ImportXmlModule>(); response = application.NavigateAndProcessDialog <ImportXmlModule, ImportXmlDialog, ImportXmlResponse>(importRequest); Assert.IsFalse(response.HasError); var updatedRecord = XrmService.Retrieve(type, record.Id); foreach (var updateField in updateFields) { Assert.IsTrue(XrmEntity.FieldsEqual(createdEntity.GetField(updateField), updatedRecord.GetField(updateField))); } }
/// <summary> /// Basic script for verifying configured Rollups - not only uses active filter in scenarios /// </summary> /// <summary> /// Basic script for verifying configured Rollups - not only uses active filter in scenarios /// </summary> public void VerifyRollupScenarios(string parentType, string childType, string referenceField) { var Rollups = JosephMRollupService .GetRollupsForRolledupType(childType) .Where(a => a.RecordTypeWithRollup == parentType) .ToArray(); var contactFieldsRollupd = Rollups.Select(a => a.FieldRolledup).ToArray(); var parent1 = CreateTestRecord(parentType); foreach (var rollup in Rollups) { if (rollup.NullAmount != null) { Assert.IsTrue(XrmEntity.FieldsEqual(rollup.NullAmount, parent1.GetField(rollup.RollupField))); } } var parent2 = CreateTestRecord(parentType); //create new child linked to parent and verify the rollup fields populated var child1 = new Entity(childType); PopulateRollupFields(child1); child1.SetLookupField(referenceField, parent1); child1 = CreateAndRetrieve(child1); parent1 = Refresh(parent1); foreach (var rollup in Rollups) { var expectedValue1 = JosephMRollupService.GetRollup(rollup, parent1.Id); Assert.IsNotNull(child1.GetField(rollup.FieldRolledup)); Assert.IsTrue(XrmEntity.FieldsEqual(expectedValue1, parent1.GetField(rollup.RollupField))); } //create second child linked to parent and verify the rollup fields added var child2 = new Entity(childType); PopulateRollupFields(child2); child2.SetLookupField(referenceField, parent1); child2 = CreateAndRetrieve(child2); parent1 = Refresh(parent1); foreach (var rollup in Rollups) { Assert.IsNotNull(child1.GetField(rollup.FieldRolledup)); Assert.IsNotNull(child2.GetField(rollup.FieldRolledup)); var expectedValue1 = JosephMRollupService.GetRollup(rollup, parent1.Id); Assert.IsTrue(XrmEntity.FieldsEqual(expectedValue1, parent1.GetField(rollup.RollupField))); } //change second child to second parent and verify both parents updated child2.SetLookupField(referenceField, parent2); child2 = UpdateFieldsAndRetreive(child2, referenceField); parent1 = Refresh(parent1); foreach (var rollup in Rollups) { Assert.IsNotNull(child1.GetField(rollup.FieldRolledup)); var expectedValue1 = JosephMRollupService.GetRollup(rollup, parent1.Id); Assert.IsTrue(XrmEntity.FieldsEqual(expectedValue1, parent1.GetField(rollup.RollupField))); } parent2 = Refresh(parent2); foreach (var rollup in Rollups) { Assert.IsNotNull(child2.GetField(rollup.FieldRolledup)); var expectedValue2 = JosephMRollupService.GetRollup(rollup, parent1.Id); Assert.IsTrue(XrmEntity.FieldsEqual(expectedValue2, parent2.GetField(rollup.RollupField))); } //triple each value in child 1 and verify updated in parent PopulateRollupFields(child1, multiplier: 3); child1 = UpdateFieldsAndRetreive(child1, contactFieldsRollupd); parent1 = Refresh(parent1); foreach (var rollup in Rollups) { Assert.IsNotNull(child1.GetField(rollup.FieldRolledup)); var expectedValue1 = JosephMRollupService.GetRollup(rollup, parent1.Id); Assert.IsTrue(XrmEntity.FieldsEqual(expectedValue1, parent1.GetField(rollup.RollupField))); } //negate value in child 1 and verify updated in parent PopulateRollupFields(child1, multiplier: 2); child1 = UpdateFieldsAndRetreive(child1, contactFieldsRollupd); parent1 = Refresh(parent1); foreach (var rollup in Rollups) { Assert.IsNotNull(child1.GetField(rollup.FieldRolledup)); var expectedValue1 = JosephMRollupService.GetRollup(rollup, parent1.Id); Assert.IsTrue(XrmEntity.FieldsEqual(expectedValue1, parent1.GetField(rollup.RollupField))); } //create child in account 1 and verify updated var child3 = new Entity(childType); PopulateRollupFields(child3); child3.SetLookupField(referenceField, parent1); child3 = CreateAndRetrieve(child3); parent1 = Refresh(parent1); foreach (var rollup in Rollups) { Assert.IsNotNull(child3.GetField(rollup.FieldRolledup)); var expectedValue1 = JosephMRollupService.GetRollup(rollup, parent1.Id); Assert.IsTrue(XrmEntity.FieldsEqual(expectedValue1, parent1.GetField(rollup.RollupField))); } //deactivate and verify updated XrmService.SetState(child3.LogicalName, child3.Id, 1); parent1 = Refresh(parent1); foreach (var rollup in Rollups) { var expectedValue1 = JosephMRollupService.GetRollup(rollup, parent1.Id); Assert.IsTrue(XrmEntity.FieldsEqual(expectedValue1, parent1.GetField(rollup.RollupField))); } //activate and verify updated XrmService.SetState(child3.LogicalName, child3.Id, 0); parent1 = Refresh(parent1); foreach (var rollup in Rollups) { var expectedValue1 = JosephMRollupService.GetRollup(rollup, parent1.Id); Assert.IsTrue(XrmEntity.FieldsEqual(expectedValue1, parent1.GetField(rollup.RollupField))); } //delete and verify updated Delete(child3); parent1 = Refresh(parent1); foreach (var rollup in Rollups) { Assert.IsNotNull(child1.GetField(rollup.FieldRolledup)); var expectedValue1 = JosephMRollupService.GetRollup(rollup, parent1.Id); Assert.IsTrue(XrmEntity.FieldsEqual(expectedValue1, parent1.GetField(rollup.RollupField))); } //lets create one without the fields populated just to verify no error child3 = new Entity(childType); child3.SetLookupField(referenceField, parent1); child3 = CreateAndRetrieve(child3); parent1 = Refresh(parent1); foreach (var rollup in Rollups) { var expectedValue1 = JosephMRollupService.GetRollup(rollup, parent1.Id); Assert.IsTrue(XrmEntity.FieldsEqual(expectedValue1, parent1.GetField(rollup.RollupField))); } //same activate / deactivate / delete for the parent 2 //this includes changing to not exists //deactivate and verify updated XrmService.SetState(child2.LogicalName, child2.Id, 1); parent2 = Refresh(parent2); foreach (var rollup in Rollups) { var expectedValue2 = JosephMRollupService.GetRollup(rollup, parent2.Id); Assert.IsTrue(XrmEntity.FieldsEqual(expectedValue2, parent2.GetField(rollup.RollupField))); } //activate and verify updated XrmService.SetState(child2.LogicalName, child2.Id, 0); parent2 = Refresh(parent2); foreach (var rollup in Rollups) { var expectedValue2 = JosephMRollupService.GetRollup(rollup, parent2.Id); Assert.IsTrue(XrmEntity.FieldsEqual(expectedValue2, parent2.GetField(rollup.RollupField))); } //delete and verify updated Delete(child2); parent2 = Refresh(parent2); foreach (var rollup in Rollups) { var expectedValue2 = JosephMRollupService.GetRollup(rollup, parent2.Id); Assert.IsTrue(XrmEntity.FieldsEqual(expectedValue2, parent2.GetField(rollup.RollupField))); } DeleteMyToday(); }
public IEnumerable <DataImportResponseItem> DoImport(IEnumerable <Entity> entities, LogController controller, bool maskEmails) { controller.LogLiteral("Preparing Import"); var response = new List <DataImportResponseItem>(); var fieldsToRetry = new Dictionary <Entity, List <string> >(); var typesToImport = entities.Select(e => e.LogicalName).Distinct(); var allNNRelationships = XrmService.GetAllNnRelationshipEntityNames(); var associationTypes = typesToImport.Where(allNNRelationships.Contains).ToArray(); typesToImport = typesToImport.Where(t => !associationTypes.Contains(t)).ToArray(); var orderedTypes = new List <string>(); var idSwitches = new Dictionary <string, Dictionary <Guid, Guid> >(); foreach (var item in typesToImport) { idSwitches.Add(item, new Dictionary <Guid, Guid>()); } #region tryordertypes foreach (var type in typesToImport) { foreach (var type2 in orderedTypes) { var thatType = type2; var thatTypeEntities = entities.Where(e => e.LogicalName == thatType).ToList(); var fields = GetFieldsToImport(thatTypeEntities, thatType) .Where(f => XrmService.FieldExists(f, thatType) && XrmService.IsLookup(f, thatType)); foreach (var field in fields) { if (thatTypeEntities.Any(e => e.GetLookupType(field) == type)) { orderedTypes.Insert(orderedTypes.IndexOf(type2), type); break; } } if (orderedTypes.Contains(type)) { break; } } if (!orderedTypes.Contains(type)) { orderedTypes.Add(type); } } #endregion tryordertypes var countToImport = orderedTypes.Count; var countImported = 0; foreach (var recordType in orderedTypes) { try { var thisRecordType = recordType; controller.UpdateProgress(countImported++, countToImport, string.Format("Importing {0} Records", recordType)); var primaryField = XrmService.GetPrimaryNameField(recordType); var thisTypeEntities = entities.Where(e => e.LogicalName == recordType).ToList(); var orConditions = thisTypeEntities .Select( e => new ConditionExpression(XrmService.GetPrimaryKeyField(e.LogicalName), ConditionOperator.Equal, e.Id)) .ToArray(); var existingEntities = XrmService.RetrieveAllOrClauses(recordType, orConditions); var orderedEntities = new List <Entity>(); #region tryorderentities var importFieldsForEntity = GetFieldsToImport(thisTypeEntities, recordType).ToArray(); var fieldsDontExist = GetFieldsInEntities(thisTypeEntities) .Where(f => !XrmService.FieldExists(f, thisRecordType)) .Where(f => !HardcodedIgnoreFields.Contains(f)) .Distinct() .ToArray(); foreach (var field in fieldsDontExist) { response.Add( new DataImportResponseItem(recordType, field, null, string.Format("Field {0} On Entity {1} Doesn't Exist In Target Instance And Will Be Ignored", field, recordType), new NullReferenceException(string.Format("Field {0} On Entity {1} Doesn't Exist In Target Instance And Will Be Ignored", field, recordType)))); } var selfReferenceFields = importFieldsForEntity.Where( f => XrmService.IsLookup(f, recordType) && XrmService.GetLookupTargetEntity(f, recordType) == recordType).ToArray(); foreach (var entity in thisTypeEntities) { foreach (var entity2 in orderedEntities) { if (selfReferenceFields.Any(f => entity2.GetLookupGuid(f) == entity.Id || (entity2.GetLookupGuid(f) == Guid.Empty && entity2.GetLookupName(f) == entity.GetStringField(primaryField)))) { orderedEntities.Insert(orderedEntities.IndexOf(entity2), entity); break; } } if (!orderedEntities.Contains(entity)) { orderedEntities.Add(entity); } } #endregion tryorderentities var countRecordsToImport = orderedEntities.Count; var countRecordsImported = 0; foreach (var entity in orderedEntities) { var thisEntity = entity; try { controller.UpdateLevel2Progress(countRecordsImported++, countRecordsToImport, string.Format("Importing {0} Records", recordType)); var existingMatchingIds = GetMatchForExistingRecord(existingEntities, thisEntity); if (existingMatchingIds.Any()) { var matchRecord = existingMatchingIds.First(); idSwitches[recordType].Add(thisEntity.Id, matchRecord.Id); thisEntity.Id = matchRecord.Id; thisEntity.SetField(XrmService.GetPrimaryKeyField(thisEntity.LogicalName), thisEntity.Id); } var isUpdate = existingMatchingIds.Any(); foreach (var field in thisEntity.GetFieldsInEntity().ToArray()) { if (importFieldsForEntity.Contains(field) && XrmService.IsLookup(field, thisEntity.LogicalName) && thisEntity.GetField(field) != null) { var idNullable = thisEntity.GetLookupGuid(field); if (idNullable.HasValue) { var targetTypesToTry = GetTargetTypesToTry(thisEntity, field); var name = thisEntity.GetLookupName(field); var fieldResolved = false; foreach (var lookupEntity in targetTypesToTry) { var targetPrimaryKey = XrmRecordService.GetPrimaryKey(lookupEntity); var targetPrimaryField = XrmRecordService.GetPrimaryField(lookupEntity); var matchRecord = XrmService.GetFirst(lookupEntity, targetPrimaryKey, idNullable.Value); if (matchRecord != null) { thisEntity.SetLookupField(field, matchRecord); fieldResolved = true; } else { var matchRecords = name.IsNullOrWhiteSpace() ? new Entity[0] : GetMatchingEntities(lookupEntity, targetPrimaryField, name); if (matchRecords.Count() == 1) { thisEntity.SetLookupField(field, matchRecords.First()); fieldResolved = true; } } if (!fieldResolved) { if (!fieldsToRetry.ContainsKey(thisEntity)) { fieldsToRetry.Add(thisEntity, new List <string>()); } fieldsToRetry[thisEntity].Add(field); } } } } } var fieldsToSet = new List <string>(); fieldsToSet.AddRange(thisEntity.GetFieldsInEntity() .Where(importFieldsForEntity.Contains)); if (fieldsToRetry.ContainsKey(thisEntity)) { fieldsToSet.RemoveAll(f => fieldsToRetry[thisEntity].Contains(f)); } if (maskEmails) { var emailFields = new[] { "emailaddress1", "emailaddress2", "emailaddress3" }; foreach (var field in emailFields) { var theEmail = thisEntity.GetStringField(field); if (!string.IsNullOrWhiteSpace(theEmail)) { thisEntity.SetField(field, theEmail.Replace("@", "_AT_") + "*****@*****.**"); } } } if (isUpdate) { var existingRecord = existingMatchingIds.First(); XrmService.Update(thisEntity, fieldsToSet.Where(f => !XrmEntity.FieldsEqual(existingRecord.GetField(f), thisEntity.GetField(f)))); } else { PopulateRequiredCreateFields(fieldsToRetry, thisEntity, fieldsToSet); CheckThrowValidForCreate(thisEntity, fieldsToSet); thisEntity.Id = XrmService.Create(thisEntity, fieldsToSet); } if (!isUpdate && thisEntity.GetOptionSetValue("statecode") > 0) { XrmService.SetState(thisEntity, thisEntity.GetOptionSetValue("statecode"), thisEntity.GetOptionSetValue("statuscode")); } else if (isUpdate && existingMatchingIds.Any()) { var matchRecord = existingMatchingIds.First(); var thisState = thisEntity.GetOptionSetValue("statecode"); var thisStatus = thisEntity.GetOptionSetValue("statuscode"); var matchState = matchRecord.GetOptionSetValue("statecode"); var matchStatus = matchRecord.GetOptionSetValue("statuscode"); if ((thisState != -1 && thisState != matchState) || (thisStatus != -1 && thisState != matchStatus)) { XrmService.SetState(thisEntity, thisEntity.GetOptionSetValue("statecode"), thisEntity.GetOptionSetValue("statuscode")); } } } catch (Exception ex) { if (fieldsToRetry.ContainsKey(thisEntity)) { fieldsToRetry.Remove(thisEntity); } response.Add( new DataImportResponseItem(recordType, null, entity.GetStringField(primaryField), string.Format("Error Importing Record Id={0}", entity.Id), ex)); } } } catch (Exception ex) { response.Add( new DataImportResponseItem(recordType, null, null, string.Format("Error Importing Type {0}", recordType), ex)); } } controller.TurnOffLevel2(); countToImport = fieldsToRetry.Count; countImported = 0; foreach (var item in fieldsToRetry) { var thisEntity = item.Key; controller.UpdateProgress(countImported++, countToImport, string.Format("Retrying Unresolved Fields {0}", thisEntity.LogicalName)); var thisPrimaryField = XrmService.GetPrimaryNameField(thisEntity.LogicalName); try { foreach (var field in item.Value) { if (XrmService.IsLookup(field, thisEntity.LogicalName) && thisEntity.GetField(field) != null) { try { var targetTypesToTry = GetTargetTypesToTry(thisEntity, field); var name = thisEntity.GetLookupName(field); var idNullable = thisEntity.GetLookupGuid(field); var fieldResolved = false; foreach (var lookupEntity in targetTypesToTry) { var targetPrimaryKey = XrmRecordService.GetPrimaryKey(lookupEntity); var targetPrimaryField = XrmRecordService.GetPrimaryField(lookupEntity); var matchRecord = idNullable.HasValue ? XrmService.GetFirst(lookupEntity, targetPrimaryKey, idNullable.Value) : null; if (matchRecord != null) { thisEntity.SetLookupField(field, matchRecord); fieldResolved = true; } else { var matchRecords = name.IsNullOrWhiteSpace() ? new Entity[0] : GetMatchingEntities(lookupEntity, targetPrimaryField, name); if (matchRecords.Count() == 1) { thisEntity.SetLookupField(field, matchRecords.First()); fieldResolved = true; } } if (!fieldResolved) { throw new Exception(string.Format("Could not find matching record for field {0}.{1} {2}", thisEntity.LogicalName, field, name)); } } } catch (Exception ex) { if (thisEntity.Contains(field)) { thisEntity.Attributes.Remove(field); } response.Add( new DataImportResponseItem(thisEntity.LogicalName, field, thisEntity.GetStringField(thisPrimaryField), string.Format("Error Setting Lookup Field Id={0}", thisEntity.Id), ex)); } } } XrmService.Update(thisEntity, item.Value); } catch (Exception ex) { response.Add( new DataImportResponseItem(thisEntity.LogicalName, null, thisEntity.GetStringField(thisPrimaryField), string.Format("Error Importing Record Id={0}", thisEntity.Id), ex)); } } countToImport = associationTypes.Count(); countImported = 0; foreach (var relationshipEntityName in associationTypes) { var thisEntityName = relationshipEntityName; controller.UpdateProgress(countImported++, countToImport, string.Format("Associating {0} Records", thisEntityName)); var thisTypeEntities = entities.Where(e => e.LogicalName == thisEntityName).ToList(); var countRecordsToImport = thisTypeEntities.Count; var countRecordsImported = 0; foreach (var thisEntity in thisTypeEntities) { try { controller.UpdateLevel2Progress(countRecordsImported++, countRecordsToImport, string.Format("Associating {0} Records", thisEntityName)); var relationship = XrmService.GetRelationshipMetadataForEntityName(thisEntityName); var type1 = relationship.Entity1LogicalName; var field1 = relationship.Entity1IntersectAttribute; var type2 = relationship.Entity2LogicalName; var field2 = relationship.Entity2IntersectAttribute; //bit of hack //when importing from csv just set the fields to the string name of the referenced record //so either string when csv or guid when xml import/export var value1 = thisEntity.GetField(relationship.Entity1IntersectAttribute); var id1 = value1 is string ?GetUniqueMatchingEntity(type1, XrmRecordService.GetPrimaryField(type1), (string)value1).Id : thisEntity.GetGuidField(relationship.Entity1IntersectAttribute); var value2 = thisEntity.GetField(relationship.Entity2IntersectAttribute); var id2 = value2 is string ?GetUniqueMatchingEntity(type2, XrmRecordService.GetPrimaryField(type2), (string)value2).Id : thisEntity.GetGuidField(relationship.Entity2IntersectAttribute); //add a where field lookup reference then look it up if (idSwitches.ContainsKey(type1) && idSwitches[type1].ContainsKey(id1)) { id1 = idSwitches[type1][id1]; } if (idSwitches.ContainsKey(type2) && idSwitches[type2].ContainsKey(id2)) { id2 = idSwitches[type2][id2]; } XrmService.AssociateSafe(relationship.SchemaName, type1, field1, id1, type2, field2, new[] { id2 }); } catch (Exception ex) { response.Add( new DataImportResponseItem( string.Format("Error Associating Record Of Type {0} Id {1}", thisEntity.LogicalName, thisEntity.Id), ex)); } } } return(response); }
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 bool DoRefresh() { var target = XrmService.Retrieve(TargetType, TargetId); var fieldsToSet = new List <string>(); if (!target.GetBoolean(Fields.jmcg_calculatedfield_.jmcg_isrecalculating)) { target.SetField(Fields.jmcg_calculatedfield_.jmcg_isrecalculating, true); fieldsToSet.Add(Fields.jmcg_calculatedfield_.jmcg_isrecalculating); } if (!string.IsNullOrWhiteSpace(target.GetStringField(Fields.jmcg_calculatedfield_.jmcg_errorrecalculating))) { target.SetField(Fields.jmcg_calculatedfield_.jmcg_errorrecalculating, null); fieldsToSet.Add(Fields.jmcg_calculatedfield_.jmcg_errorrecalculating); } if (fieldsToSet.Any()) { XrmService.Update(target, fieldsToSet.ToArray()); } var isFinished = false; var createDateThreshold = target.GetDateTimeField(Fields.jmcg_calculatedfield_.jmcg_lastrecalculationcreatedate) ?? new DateTime(1910, 1, 1); try { var config = CalculatedService.LoadCalculatedFieldConfig(target); var startedAt = DateTime.UtcNow; var fieldsToLoad = new List <string>(); var calculatedFieldFieldName = target.GetStringField(Fields.jmcg_calculatedfield_.jmcg_field); var calciulatedFieldEntityName = target.GetStringField(Fields.jmcg_calculatedfield_.jmcg_entitytype); fieldsToLoad.Add(calculatedFieldFieldName); fieldsToLoad.Add("createdon"); fieldsToLoad.AddRange(CalculatedService.GetDependencyFields(config, config.CalculatedFieldEntity.GetStringField(Fields.jmcg_calculatedfield_.jmcg_entitytype))); fieldsToLoad.AddRange(XrmEntity.GetFieldsInFilter(config.ApplyFilterExpression)); while (true) { if (IsSandboxIsolated && DateTime.UtcNow - startedAt > new TimeSpan(0, 0, MaxSandboxIsolationExecutionSeconds - 10)) { break; } else { var processSetQuery = new QueryExpression(calciulatedFieldEntityName); processSetQuery.ColumnSet = new ColumnSet(fieldsToLoad.Distinct().ToArray()); processSetQuery.AddOrder("createdon", OrderType.Ascending); processSetQuery.Criteria.AddCondition(new ConditionExpression("createdon", ConditionOperator.GreaterEqual, createDateThreshold)); var processSet = XrmService.RetrieveMultiple(processSetQuery).Entities.ToList(); var countThisSet = processSet.Count; if (countThisSet == 0) { isFinished = true; } else { var countProcessed = 0; ProcessWhileInSandboxLimit(startedAt, processSet.ToArray(), (entity) => { try { if (target.GetOptionSetValue(Fields.jmcg_calculatedfield_.jmcg_type) == OptionSets.CalculatedField.Type.Rollup) { var rollup = CalculatedService.CreateRollup(config); var rollupService = new CalculatedRollupService(XrmService, new [] { rollup }); rollupService.RefreshRollup(entity.Id, rollup); } else { if (XrmEntity.MeetsFilter(entity.GetField, config.ApplyFilterExpression)) { var oldValue = entity.GetField(calculatedFieldFieldName); var newValue = CalculatedService.GetNewValue(config, entity.GetField); if (!XrmEntity.FieldsEqual(oldValue, newValue)) { entity.SetField(calculatedFieldFieldName, newValue); XrmService.Update(entity, calculatedFieldFieldName); } } } createDateThreshold = entity.GetDateTimeField("createdon") ?? throw new InvalidPluginExecutionException("Error empty createdon " + entity.Id); processSet.Remove(entity); countProcessed++; } catch (Exception ex) { throw new InvalidPluginExecutionException($"Error refreshing ecountered for ID {entity.Id}. Refresh will be discontinued", ex); } }); if (countThisSet < 5000 && countProcessed == countThisSet) { isFinished = true; } } } if (isFinished) { break; } } } catch (Exception ex) { target.SetField(Fields.jmcg_calculatedfield_.jmcg_errorrecalculating, ex.XrmDisplayString().Left(10000)); target.SetField(Fields.jmcg_calculatedfield_.jmcg_lastrecalculationcreatedate, null); target.SetField(Fields.jmcg_calculatedfield_.jmcg_isrecalculating, false); XrmService.Update(target, Fields.jmcg_calculatedfield_.jmcg_errorrecalculating, Fields.jmcg_calculatedfield_.jmcg_lastrecalculationcreatedate, Fields.jmcg_calculatedfield_.jmcg_isrecalculating); throw ex; } if (isFinished) { target.SetField(Fields.jmcg_calculatedfield_.jmcg_lastrecalculationcreatedate, null); target.SetField(Fields.jmcg_calculatedfield_.jmcg_isrecalculating, false); XrmService.Update(target, Fields.jmcg_calculatedfield_.jmcg_lastrecalculationcreatedate, Fields.jmcg_calculatedfield_.jmcg_isrecalculating); } else { target.SetField(Fields.jmcg_calculatedfield_.jmcg_lastrecalculationcreatedate, createDateThreshold); XrmService.Update(target, Fields.jmcg_calculatedfield_.jmcg_lastrecalculationcreatedate); } return(isFinished); }
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); } }