private ParsedFileRow GetParsedFileRow( IOrganizationService organisationService, Guid accountId, string line, string headerRow) { const string COLUMN_HEADER_ID = "ID"; const string COLUMN_HEADER_ABO_GROUP = "ABO Group"; const string COLUMN_HEADER_DONOR_COUNT = "Donor Count"; const string COLUMN_HEADER_FROZEN_UNIT_COUNT = "Frozen Unit Count"; var account = new Account(organisationService.Retrieve(Account.LogicalName, accountId, new ColumnSet(new string[] { Account.Properties.OwningTeam }))); var optionSetABO = Helper.GetOptionSet(organisationService, "nhs_abosubtypes"); var optionSetAntigenResults = Helper.GetOptionSet(organisationService, "nhs_antigenresultsourcecontext"); var allRarities = Helper.GetAllRarities(organisationService); var allAntigens = Helper.GetAllAntigens(organisationService); var columnHeaderValidation = new List <string>(new string[] { COLUMN_HEADER_ID, COLUMN_HEADER_ABO_GROUP, COLUMN_HEADER_DONOR_COUNT, COLUMN_HEADER_FROZEN_UNIT_COUNT }); string[] columnHeaders = headerRow.Split(','); var columnData = line.Split(','); var contributorCode = columnData[columnHeaderValidation.IndexOf(COLUMN_HEADER_ID)].Trim().Replace(@"\""", "\""); var parsedFileRow = new ParsedFileRow(contributorCode, account.OwningTeam, account.ToEntityReference(), headerRow, line); for (int index = columnHeaderValidation.Count(); index < columnHeaders.Length; index++) { var columnHeader = columnHeaders[index].Trim(); var columnValue = columnData[index].Trim(); if (columnHeader.Contains("Rarity")) { if (!String.IsNullOrEmpty(columnValue)) { var rarity = (from r in allRarities where r.Name_Unicode == columnValue select r).FirstOrDefault(); //...add it to the collection parsedFileRow.RaritySourceAssociations.Add( new Rarity_SourceAssociation() { Rarity = rarity.ToEntityReference(), Owner = account.OwningTeam }); } } //Else we have a value anitgen results column so... else if (!String.IsNullOrEmpty(columnValue)) { ////...try to get the Antigen form the Header Column text var antigen = (from a in allAntigens where a.Name_Unicode.Trim() == columnHeader select a).FirstOrDefault(); //Try to get the Antigen Result from column text var antigenResult = (from o in optionSetAntigenResults where o.Label.LocalizedLabels[0].Label == columnValue.ToUpper() //Check for lower case "w" select o).FirstOrDefault(); //...add it to the collection parsedFileRow.AntigenSourceAssociations.Add( new Antigen_SourceAssociation() { Antigen = antigen.ToEntityReference(), AntigenResult_OptionSetValue = new OptionSetValue(antigenResult.Value.Value), Owner = account.OwningTeam }); } } //...add it to the collection return(parsedFileRow); }
private ExecuteMultipleRequest AlignAntigenSourceAssociations(IOrganizationService organisationService, ParsedFileRow parsedFileRow, EntityReference rareBloodSource, ExecuteMultipleRequest executeMultipleRequest) { var sourceAntigens = Helper.GetAntigenAssociationsForSource(organisationService, rareBloodSource.Id); //Query the records prior to any create/update/remove actions var antigenSourceAssociationsToCreate = parsedFileRow.AntigenSourceAssociations.Where(pfr => sourceAntigens.All(source => pfr.Antigen.Id != source.Antigen.Id)); var antigenSourceAssociationsToUpdate = sourceAntigens.Where(source => parsedFileRow.AntigenSourceAssociations.Any(pfr => pfr.Antigen.Id == source.Antigen.Id)); var antigenSourceAssociationsToRemove = sourceAntigens.Where(source => parsedFileRow.AntigenSourceAssociations.All(pfr => pfr.Antigen.Id != source.Antigen.Id)); foreach (var antigenSourceAssociation in antigenSourceAssociationsToCreate) { antigenSourceAssociation.Source = rareBloodSource; antigenSourceAssociation.Explicit = true; executeMultipleRequest.Requests.Add( new CreateRequest() { Target = antigenSourceAssociation }); } List <EntityReference> antigensAlreadyRepresented = new List <EntityReference>(); foreach (var antigenSourceAssociation in antigenSourceAssociationsToUpdate) { //=========//=========//=========//=========// //========= Section 1 - Gather Data //=========//=========//=========//=========// //Finds the oldest instance of antigen associations matching the file upload //test whether the antigen association is active bool isAssociationActive = antigenSourceAssociation.Status == Antigen_SourceAssociation.eStatus.Active; //test whether it is explicit bool isAssociationExplicit = antigenSourceAssociation.Explicit.Value; //test whether it is implied by rarities bool isAssociationImpliedByRarities = CheckIfImpliedByRarities(organisationService, antigenSourceAssociation); //get the antigen association details from the parsed file row Antigen_SourceAssociation uploadedAntigenDetails = ( from a in parsedFileRow.AntigenSourceAssociations where a.Antigen.Id == antigenSourceAssociation.Antigen.Id select a ).First(); //test whether the result is already correct bool isResultCorrect = antigenSourceAssociation.AntigenResult == uploadedAntigenDetails.AntigenResult; //find the oldest existing antigen association //that we can reuse (i.e. result is already matching, or the result can be amended as it's not implied) Antigen_SourceAssociation oldestReusableMatchingAssociation = ( antigenSourceAssociationsToUpdate.Where( asatu => asatu.Antigen.Id == antigenSourceAssociation.Antigen.Id //where either the result is the same && (asatu.AntigenResult.Value == uploadedAntigenDetails.AntigenResult.Value //or it's not implied (i.e. its result can be updated) || CheckIfImpliedByRarities(organisationService, asatu) == false) ) ).FirstOrDefault(); //=========//=========//=========//=========//=========//=========// //========= Section 2 - Test the values to determine next action //=========//=========//=========//=========//=========//=========// //=== First Preference ===// if (oldestReusableMatchingAssociation != null && antigenSourceAssociation.Id == oldestReusableMatchingAssociation.Id) { //if this is the oldest association with the same result for this antigen/source combo if (!isAssociationActive || !isAssociationExplicit || !isResultCorrect) { //and if its either inactive or not marked as explicit or has the incorrect result //then update it antigenSourceAssociation.Explicit = true; antigenSourceAssociation.AntigenResult = uploadedAntigenDetails.AntigenResult; antigenSourceAssociation.Status = Antigen_SourceAssociation.eStatus.Active; antigenSourceAssociation.StatusReason = Antigen_SourceAssociation.eStatusReason.Active_Active; //and add the update to the execution queue. executeMultipleRequest.Requests.Add( new UpdateRequest() { Target = antigenSourceAssociation } ); //And record this antigen as processed antigensAlreadyRepresented.Add(antigenSourceAssociation.Antigen); } } else { //if this is not the oldest antigen association that we can reuse if (isAssociationActive && !isAssociationImpliedByRarities) // if it's active //and it's not implied by other rarities { //then it should simply be deactivated. executeMultipleRequest.Requests.Add( new SetStateRequest() { EntityMoniker = antigenSourceAssociation.ToEntityReference(), State = new OptionSetValue((int)Antigen_SourceAssociation.eStatus.Inactive), Status = new OptionSetValue((int)Antigen_SourceAssociation.eStatusReason.RemovedByImport_Inactive) }); } //test whether this antigen has been associated with the source already bool isAntigenAlreadyRepresented = antigensAlreadyRepresented.Where( newAntigens => newAntigens.Id == antigenSourceAssociation.Antigen.Id ).FirstOrDefault() != null; //if there is no reusable antigen association //and the antigen has not already been represented against this source if (oldestReusableMatchingAssociation == null && isAntigenAlreadyRepresented == false) { //then we need to create a new antigen-source association //to highlight the contradiction with the existing ones. uploadedAntigenDetails.Source = rareBloodSource; uploadedAntigenDetails.Explicit = true; executeMultipleRequest.Requests.Add( new CreateRequest() { Target = uploadedAntigenDetails }); //and record the fact that this antigen is now represented for this upload antigensAlreadyRepresented.Add(antigenSourceAssociation.Antigen); } } } foreach (var antigenSourceAssociation in antigenSourceAssociationsToRemove) { bool isImpliedByRarities = CheckIfImpliedByRarities(organisationService, antigenSourceAssociation); bool isActive = antigenSourceAssociation.Status == Antigen_SourceAssociation.eStatus.Active; if (!isImpliedByRarities && isActive) { //if it isn't implied, but is still active //then we can just deactivate it. executeMultipleRequest.Requests.Add( new SetStateRequest() { EntityMoniker = antigenSourceAssociation.ToEntityReference(), State = new OptionSetValue((int)Antigen_SourceAssociation.eStatus.Inactive), Status = new OptionSetValue((int)Antigen_SourceAssociation.eStatusReason.RemovedByImport_Inactive) }); } } return(executeMultipleRequest); }
private void ProcessSourceAssociations(IOrganizationService organisationService, ParsedFileRow parsedFileRow, Entity targetEntity) { var executeMultipleRequest = new ExecuteMultipleRequest() { // Assign settings that define execution behavior: continue on error, return responses. Settings = new ExecuteMultipleSettings() { ContinueOnError = true, ReturnResponses = true }, // Create an empty organization request collection. Requests = new OrganizationRequestCollection() }; targetEntity.Attributes[ProxyClasses.RareBloodSource.Properties.Rawdata] = null; targetEntity.Attributes[ProxyClasses.RareBloodSource.Properties.HeaderRow] = null; executeMultipleRequest.Requests.Add( new UpdateRequest() { Target = targetEntity } ); //Create, Update (set active), or Remove Rarities to align with uplaod document executeMultipleRequest = AlignRaritySourceAssociations(organisationService, parsedFileRow, targetEntity.ToEntityReference(), executeMultipleRequest); ////Implicit antigens are created and we may need to create, update and remove some to align with the upload document executeMultipleRequest = AlignAntigenSourceAssociations(organisationService, parsedFileRow, targetEntity.ToEntityReference(), executeMultipleRequest); ////Finally execute a batch of requests var executeMutlipleResponse = (ExecuteMultipleResponse)organisationService.Execute(executeMultipleRequest); if (executeMutlipleResponse.IsFaulted) { throw new InvalidPluginExecutionException("Failed to execute all of the requests in an ExecuteMultipleRequest while processing rarity/antigen associations for this Rare Blood Source"); } }
static ExecuteMultipleRequest AlignRaritySourceAssociations(IOrganizationService organisationService, ParsedFileRow parsedFileRow, EntityReference rareBloodSource, ExecuteMultipleRequest executeMultipleRequest) { //Get all the rarity asscoaiton for the source record var sourceRarities = Helper.GetRarityAssociationsForSource(organisationService, rareBloodSource.Id); //Get the set of the uplaoded rarity associations we need to create var raritiesToCreate = parsedFileRow.RaritySourceAssociations.Where( pfr => sourceRarities.All( source => pfr.Rarity.Id != source.Rarity.Id ) ); //Get the set of the uplaoded rarity associations we need to update (set active) var raritiesToUpdate = sourceRarities.Where( source => parsedFileRow.RaritySourceAssociations.Any( pfr => pfr.Rarity.Id == source.Rarity.Id ) ); // Get the set of the uplaoded rarity associations we need to remove (deactivate) var raritiesToRemove = sourceRarities.Where( source => parsedFileRow.RaritySourceAssociations.All( pfr => pfr.Rarity.Id != source.Rarity.Id && source.Status != ProxyClasses.Rarity_SourceAssociation.eStatus.Inactive ) ); //Foreach rarity association that needs creating... foreach (var raritySourceAssociation in raritiesToCreate) { //...set the source raritySourceAssociation.Source = rareBloodSource; executeMultipleRequest.Requests.Add( new CreateRequest() { Target = raritySourceAssociation }); } var activeRarityAssocsProcessed = new List <EntityReference>(); foreach (var raritySourceAssociation in raritiesToUpdate) // rarities to reactivate { //test whether a this rarity is already associated with this source via another association var isRarityAlreadyRepresented = activeRarityAssocsProcessed.Count > 0 && activeRarityAssocsProcessed.Where( reactivatedRarity => reactivatedRarity.Id == raritySourceAssociation.Rarity.Id ).Count() > 0; //test whether this association is already active var isThisAssocActive = raritySourceAssociation.Status == Rarity_SourceAssociation.eStatus.Active; if (!isThisAssocActive && !isRarityAlreadyRepresented) { //if we've not already activated a rarity association for this rarity //(and this one is inactive) // then activate this one executeMultipleRequest.Requests.Add( new SetStateRequest() { EntityMoniker = raritySourceAssociation.ToEntityReference(), State = new OptionSetValue((int)Rarity_SourceAssociation.eStatus.Active), Status = new OptionSetValue((int)Rarity_SourceAssociation.eStatusReason.Active_Active) } ); } else if (isThisAssocActive && isRarityAlreadyRepresented) { // if this condition is met, its a duplicate and we should deactivate executeMultipleRequest.Requests.Add( new SetStateRequest() { EntityMoniker = raritySourceAssociation.ToEntityReference(), State = new OptionSetValue((int)Rarity_SourceAssociation.eStatus.Inactive), Status = new OptionSetValue((int)Rarity_SourceAssociation.eStatusReason.RemovedByImport_Inactive) } ); } //and add this rarity to the list already processed activeRarityAssocsProcessed.Add(raritySourceAssociation.Rarity); } foreach (var raritySourceAssociation in raritiesToRemove) { executeMultipleRequest.Requests.Add( new SetStateRequest() { EntityMoniker = raritySourceAssociation.ToEntityReference(), State = new OptionSetValue((int)Rarity_SourceAssociation.eStatus.Inactive), Status = new OptionSetValue((int)Rarity_SourceAssociation.eStatusReason.RemovedByImport_Inactive) }); } return(executeMultipleRequest); }
private RareBloodSource GetRareBloodSourceObject( IOrganizationService organisationService, Guid accountId, string headerRow, string dataRow) { const string COLUMN_HEADER_ID = "ID"; const string COLUMN_HEADER_ABO_GROUP = "ABO Group"; const string COLUMN_HEADER_DONOR_COUNT = "Donor Count"; const string COLUMN_HEADER_FROZEN_UNIT_COUNT = "Frozen Unit Count"; var columnHeaderValidation = new List <string>(new string[] { COLUMN_HEADER_ID, COLUMN_HEADER_ABO_GROUP, COLUMN_HEADER_DONOR_COUNT, COLUMN_HEADER_FROZEN_UNIT_COUNT }); var account = new Account(organisationService.Retrieve(Account.LogicalName, accountId, new ColumnSet(new string[] { Account.Properties.OwningTeam }))); var optionSetABO = Helper.GetOptionSet(organisationService, "nhs_abosubtypes"); var accountSources = Helper.GetSourcesForAccount(organisationService, account.Id); string[] columnHeaders = headerRow.Split(','); var columnData = dataRow.Split(','); var contributorCode = columnData[columnHeaderValidation.IndexOf(COLUMN_HEADER_ID)].Trim().Replace(@"\""", "\""); var parsedFileRow = new ParsedFileRow(contributorCode, account.OwningTeam, account.ToEntityReference(), headerRow, dataRow); var matchedAccountSource = (from accountSource in accountSources where accountSource.ContributorCode == parsedFileRow.Source.ContributorCode select accountSource).FirstOrDefault(); //If the Rare Blood Source exists... if (matchedAccountSource != null) { parsedFileRow.Source.Id = matchedAccountSource.Id; } var bloodType = columnData[columnHeaderValidation.IndexOf(COLUMN_HEADER_ABO_GROUP)].Trim(); var bloodTypeOption = (from o in optionSetABO where o.Label.LocalizedLabels[0].Label == bloodType select o).FirstOrDefault(); parsedFileRow.Source.ABOType = (RareBloodSource.eABOSub_types)bloodTypeOption.Value.Value; parsedFileRow.Source.LastReviewedOn = DateTime.Now; var donorCountValue = columnData[columnHeaderValidation.IndexOf(COLUMN_HEADER_DONOR_COUNT)]; int donorCount = 0; if (int.TryParse(donorCountValue, out donorCount) || donorCount < 0) { parsedFileRow.Source.DonorCount = donorCount; parsedFileRow.Source.SourceType = donorCount == 1 ? false : true; } var frozenUnitCountValue = columnData[columnHeaderValidation.IndexOf(COLUMN_HEADER_FROZEN_UNIT_COUNT)]; int frozenUnitCount = 0; if (int.TryParse(frozenUnitCountValue, out frozenUnitCount) || frozenUnitCount < 0) { parsedFileRow.Source.FrozenUnitCount = frozenUnitCount; } //...and return it return(parsedFileRow.Source); }