/// <summary> /// Reads the JSON representation of the object. /// </summary> /// <param name="reader">The <see cref="JsonReader"/> to read from.</param> /// <param name="objectType">Type of the object.</param> /// <param name="existingValue">The existing property value of the JSON that is being converted.</param> /// <param name="serializer">The calling serializer.</param> /// <returns>The object value.</returns> public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.TokenType == JsonToken.Null) { return(null); } else { if (reader.TokenType == JsonToken.Integer) { try { var v = ActionStatus.FromValue(Convert.ToInt32(reader.Value)); return(v); } catch (Exception ex) { //throw JsonSerializationException(reader, "Error parsing version string: {0}".FormatWith(CultureInfo.InvariantCulture, reader.Value), ex); throw new JsonSerializationException($"Error parsing version string: {ex.Message}"); } } else { //throw JsonSerializationException.Create(reader, "Unexpected token or value when parsing version. Token: {0}, Value: {1}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType, reader.Value)); throw new JsonSerializationException($"Unexpected token or value when parsing version. Token: {reader.TokenType}, Value: {reader.Value}"); } } }
private async Task <TeamMember> TeamMemberToEntityAsync(TeamMemberModel model, string requestId = "") { var teamMember = TeamMember.Empty; teamMember.Id = model.Id; teamMember.DisplayName = model.DisplayName; teamMember.Status = ActionStatus.FromValue(model.Status.Value); teamMember.AssignedRole = await _userProfileHelpers.RoleModelToEntityAsync(model.AssignedRole, requestId); teamMember.Fields = TeamMemberFields.Empty; teamMember.Fields.Mail = model.Mail; teamMember.Fields.Title = model.Title; teamMember.Fields.UserPrincipalName = model.UserPrincipalName; return(teamMember); }
private async Task <ProposalDocument> ProposalDocumentToEntityAsync(OpportunityViewModel viewModel, ProposalDocument proposalDocument, string requestId = "") { try { Guard.Against.Null(proposalDocument, "ProposalDocumentToEntityAsync", requestId); var entity = proposalDocument; var model = viewModel.ProposalDocument; entity.Id = model.Id ?? String.Empty; entity.DisplayName = model.DisplayName ?? String.Empty; entity.Reference = model.Reference ?? String.Empty; entity.Version = model.Version ?? String.Empty; if (entity.Content == null) { entity.Content = ProposalDocumentContent.Empty; } // Storing previous section lists to compare and trigger notification if assigment changes var currProposalSectionList = entity.Content.ProposalSectionList.ToList(); // Proposal sections are always overwritten entity.Content.ProposalSectionList = new List <DocumentSection>(); if (model.Content.ProposalSectionList != null) { var OwnerSendList = new List <UserProfile>(); //receipients list for notifications var AssignedToSendList = new List <UserProfile>(); //receipients list for notifications // LIST: ProposalSectionList foreach (var item in model.Content.ProposalSectionList) { var documentSection = new DocumentSection(); documentSection.DisplayName = item.DisplayName ?? String.Empty; documentSection.Id = item.Id ?? String.Empty; documentSection.LastModifiedDateTime = item.LastModifiedDateTime; documentSection.Owner = await _userProfileHelpers.UserProfileToEntityAsync(item.Owner ?? new UserProfileViewModel(), requestId); documentSection.SectionStatus = ActionStatus.FromValue(item.SectionStatus.Value); documentSection.SubSectionId = item.SubSectionId ?? String.Empty; documentSection.AssignedTo = await _userProfileHelpers.UserProfileToEntityAsync(item.AssignedTo ?? new UserProfileViewModel(), requestId); documentSection.Task = item.Task ?? String.Empty; // Check values to see if notification trigger is needed var prevSectionList = currProposalSectionList.Find(x => x.Id == documentSection.Id); if (prevSectionList != null) { if (prevSectionList.Owner.Id != documentSection.Owner.Id) { OwnerSendList.Add(documentSection.Owner); } if (prevSectionList.AssignedTo.Id != documentSection.AssignedTo.Id) { AssignedToSendList.Add(documentSection.AssignedTo); } } entity.Content.ProposalSectionList.Add(documentSection); } // AssignedToSendList notifications // Section owner changed / assigned try { if (OwnerSendList.Count > 0) { _logger.LogInformation($"RequestId: {requestId} - ProposalDocumentToEntityAsync sendNotificationCardAsync for owner changed notification."); var notificationOwner = await _cardNotificationService.sendNotificationCardAsync( viewModel.DisplayName, viewModel.OpportunityChannelId, OwnerSendList, $"Section(s) in the proposal document for opportunity {viewModel.DisplayName} has new/updated owners ", requestId); } } catch (Exception ex) { _logger.LogError($"RequestId: {requestId} - ProposalDocumentToEntityAsync sendNotificationCardAsync for owner error: {ex}"); } // Section AssignedTo changed / assigned try { if (AssignedToSendList.Count > 0) { _logger.LogInformation($"RequestId: {requestId} - ProposalDocumentToEntityAsync sendNotificationCardAsync for AssigedTo changed notification."); var notificationAssignedTo = await _cardNotificationService.sendNotificationCardAsync( viewModel.DisplayName, viewModel.OpportunityChannelId, AssignedToSendList, $"Task(s) in the proposal document for opportunity {viewModel.DisplayName} has new/updated assigments ", requestId); } } catch (Exception ex) { _logger.LogError($"RequestId: {requestId} - ProposalDocumentToEntityAsync sendNotificationCardAsync for AssignedTo error: {ex}"); } } // Metadata if (entity.Metadata == null) { entity.Metadata = DocumentMetadata.Empty; } entity.Metadata.DocumentUri = model.DocumentUri; entity.Metadata.Tags = model.Tags; if (entity.Metadata.Category == null) { entity.Metadata.Category = new Category(); } entity.Metadata.Category.Id = model.Category.Id ?? String.Empty; entity.Metadata.Category.Name = model.Category.Name ?? String.Empty; if (entity.Metadata.Notes == null) { entity.Metadata.Notes = new List <Note>(); } if (model.Notes != null) { // LIST: Notes foreach (var item in model.Notes) { entity.Metadata.Notes.Add(await NoteToEntityAsync(item, requestId)); } } return(entity); } catch (Exception ex) { //_logger.LogError(ex.Message); throw ex; } }
public async Task <Opportunity> MapToEntityAsync(Opportunity entity, OpportunityViewModel viewModel, string requestId = "") { try { var entityIsEmpty = true; if (!String.IsNullOrEmpty(entity.DisplayName)) { entityIsEmpty = false; // If empty we should not send any notifications since it is just a reference opportunity schema } if (entity.Content.Checklists == null) { entity.Content.Checklists = new List <Checklist>(); } if (viewModel.Checklists != null) { // List of checklists that status changed thus team members need to be sent with a notification var statusChangedChecklists = new List <Checklist>(); var updatedList = new List <Checklist>(); // LIST: Content/CheckList/ChecklistTaskList foreach (var item in viewModel.Checklists) { var checklist = Checklist.Empty; var existinglist = entity.Content.Checklists.ToList().Find(x => x.Id == item.Id); if (existinglist != null) { checklist = existinglist; } var addToChangedList = false; if (checklist.ChecklistStatus.Value != item.ChecklistStatus.Value) { addToChangedList = true; } checklist.Id = item.Id ?? String.Empty; checklist.ChecklistStatus = ActionStatus.FromValue(item.ChecklistStatus.Value); checklist.ChecklistTaskList = new List <ChecklistTask>(); checklist.ChecklistChannel = item.ChecklistChannel ?? String.Empty; foreach (var subitem in item.ChecklistTaskList) { var checklistTask = new ChecklistTask { Id = subitem.Id ?? String.Empty, ChecklistItem = subitem.ChecklistItem ?? String.Empty, Completed = subitem.Completed, FileUri = subitem.FileUri ?? String.Empty }; checklist.ChecklistTaskList.Add(checklistTask); } // Add checklist for notifications, notification is sent below during teamMembers iterations if (addToChangedList) { statusChangedChecklists.Add(checklist); } updatedList.Add(checklist); } // Send notifications for changed checklists if (statusChangedChecklists.Count > 0 && !entityIsEmpty) { try { if (statusChangedChecklists.Count > 0) { var sb = new StringBuilder(); foreach (var chkItm in statusChangedChecklists) { sb.Append($"'{chkItm.ChecklistChannel}' "); } var checkLists = sb.ToString(); var sendToList = new List <UserProfile>(); //WAVE-4 GENERIC ACCELERATOR Change : start var opportunityChannelId = viewModel.OpportunityChannelId ?? String.Empty; if (!String.IsNullOrEmpty(opportunityChannelId)) { entity.Metadata.OpportunityChannelId = opportunityChannelId; } //WAVE-4 GENERIC ACCELERATOR Change : end _logger.LogInformation($"RequestId: {requestId} - UpdateWorkflowAsync sendNotificationCardAsync checklist status changed notification. Number of hecklists: {statusChangedChecklists.Count}"); var sendNotificationCard = await _cardNotificationService.sendNotificationCardAsync(entity, sendToList, $"Status updated for opportunity checklist(s): {checkLists} ", requestId); } } catch (Exception ex) { _logger.LogError($"RequestId: {requestId} - UpdateWorkflowAsync sendNotificationCardAsync checklist status change error: {ex}"); } //Granular bug fix: end } try { if (entity.Content.Checklists.Count > 0 && updatedList.Count > 0) { var items = entity.Content.Checklists.Where(x => !updatedList.Any(y => y.ChecklistChannel == x.ChecklistChannel)); foreach (var item in items) { updatedList.Add(item); } } } catch (Exception ex) { _logger.LogError($"RequestId: {requestId} - UpdateWorkflowAsync Bug fix checklist error: {ex}"); } //Granular bug fix: start entity.Content.Checklists = updatedList; } if (entity.Content.Checklists.Count == 0) { // Checklist empty create a default set foreach (var item in viewModel.Template.ProcessList) { if (item.ProcessType.ToLower() == "checklisttab") { var checklist = new Checklist { Id = item.ProcessStep, ChecklistChannel = item.Channel, ChecklistStatus = ActionStatus.NotStarted, ChecklistTaskList = new List <ChecklistTask>() }; entity.Content.Checklists.Add(checklist); } } } return(entity); } catch (Exception ex) { throw new ResponseException($"RequestId: {requestId} - CheckListProcessService MapToEntity oppId: {entity.Id} - failed to map opportunity: {ex}"); } }
private async Task <Opportunity> OpportunityToEntityAsync(OpportunityViewModel viewModel, Opportunity opportunity, string requestId = "") { var oppId = viewModel.Id; try { var entity = opportunity; var entityIsEmpty = true; if (!String.IsNullOrEmpty(entity.DisplayName)) { entityIsEmpty = false; // If empty we should not send any notifications since it is just a reference opportunity schema } entity.Id = viewModel.Id ?? String.Empty; entity.DisplayName = viewModel.DisplayName ?? String.Empty; entity.Reference = viewModel.Reference ?? String.Empty; entity.Version = viewModel.Version ?? String.Empty; // DocumentAttachments if (entity.DocumentAttachments == null) { entity.DocumentAttachments = new List <DocumentAttachment>(); } if (viewModel.DocumentAttachments != null) { var newDocumentAttachments = new List <DocumentAttachment>(); foreach (var itm in viewModel.DocumentAttachments) { var doc = entity.DocumentAttachments.ToList().Find(x => x.Id == itm.Id); if (doc == null) { doc = DocumentAttachment.Empty; } doc.Id = itm.Id; doc.FileName = itm.FileName ?? String.Empty; doc.DocumentUri = itm.DocumentUri ?? String.Empty; doc.Category = Category.Empty; doc.Category.Id = itm.Category.Id ?? String.Empty; doc.Category.Name = itm.Category.Name ?? String.Empty; doc.Tags = itm.Tags ?? String.Empty; doc.Note = itm.Note ?? String.Empty; newDocumentAttachments.Add(doc); } // TODO: P2 create logic for replace and support for other artifact types for now we replace the whole list entity.DocumentAttachments = newDocumentAttachments; } // Content if (entity.Content == null) { entity.Content = OpportunityContent.Empty; } // Checklists if (entity.Content.Checklists == null) { entity.Content.Checklists = new List <Checklist>(); } if (viewModel.Checklists != null) { // List of checklists that status changed thus team members need to be sent with a notification var statusChangedChecklists = new List <Checklist>(); var updatedList = new List <Checklist>(); // LIST: Content/CheckList/ChecklistTaskList foreach (var item in viewModel.Checklists) { var checklist = Checklist.Empty; var existinglist = entity.Content.Checklists.ToList().Find(x => x.Id == item.Id); if (existinglist != null) { checklist = existinglist; } var addToChangedList = false; if (checklist.ChecklistStatus.Value != item.ChecklistStatus.Value) { addToChangedList = true; } checklist.Id = item.Id ?? String.Empty; checklist.ChecklistStatus = ActionStatus.FromValue(item.ChecklistStatus.Value); checklist.ChecklistTaskList = new List <ChecklistTask>(); checklist.ChecklistChannel = item.ChecklistChannel ?? String.Empty; foreach (var subitem in item.ChecklistTaskList) { var checklistTask = new ChecklistTask { Id = subitem.Id ?? String.Empty, ChecklistItem = subitem.ChecklistItem ?? String.Empty, Completed = subitem.Completed, FileUri = subitem.FileUri ?? String.Empty }; checklist.ChecklistTaskList.Add(checklistTask); } // Add checklist for notifications, notification is sent below during teamMembers iterations if (addToChangedList) { statusChangedChecklists.Add(checklist); } updatedList.Add(checklist); } // Send notifications for changed checklists if (statusChangedChecklists.Count > 0 && !entityIsEmpty) { try { if (statusChangedChecklists.Count > 0) { var checkLists = String.Empty; foreach (var chkItm in statusChangedChecklists) { checkLists = checkLists + $"'{chkItm.ChecklistChannel}' "; } var sendToList = new List <UserProfile>(); if (!String.IsNullOrEmpty(viewModel.OpportunityChannelId)) { entity.Metadata.OpportunityChannelId = viewModel.OpportunityChannelId; } _logger.LogInformation($"RequestId: {requestId} - UpdateWorkflowAsync sendNotificationCardAsync checklist status changed notification. Number of hecklists: {statusChangedChecklists.Count}"); var sendNotificationCard = await _cardNotificationService.sendNotificationCardAsync(entity, sendToList, $"Status updated for opportunity checklist(s): {checkLists} ", requestId); } } catch (Exception ex) { _logger.LogError($"RequestId: {requestId} - UpdateWorkflowAsync sendNotificationCardAsync checklist status change error: {ex}"); } } entity.Content.Checklists = updatedList; } if (entity.Content.Checklists.Count == 0) { // Checklist empty create a default set var roleMappingList = (await _roleMappingRepository.GetAllAsync(requestId)).ToList(); foreach (var item in roleMappingList) { if (item.ProcessType.ToLower() == "checklisttab") { var checklist = new Checklist { Id = item.ProcessStep, ChecklistChannel = item.Channel, ChecklistStatus = ActionStatus.NotStarted, ChecklistTaskList = new List <ChecklistTask>() }; entity.Content.Checklists.Add(checklist); } } } // CustomerDecision if (entity.Content.CustomerDecision == null) { entity.Content.CustomerDecision = CustomerDecision.Empty; } if (viewModel.CustomerDecision != null) { entity.Content.CustomerDecision.Id = viewModel.CustomerDecision.Id ?? String.Empty; entity.Content.CustomerDecision.Approved = viewModel.CustomerDecision.Approved; if (viewModel.CustomerDecision.ApprovedDate != null) { entity.Content.CustomerDecision.ApprovedDate = viewModel.CustomerDecision.ApprovedDate; } if (viewModel.CustomerDecision.LoanDisbursed != null) { entity.Content.CustomerDecision.LoanDisbursed = viewModel.CustomerDecision.LoanDisbursed; } } // LIST: Content/Notes if (entity.Content.Notes == null) { entity.Content.Notes = new List <Note>(); } if (viewModel.Notes != null) { var updatedNotes = entity.Content.Notes.ToList(); foreach (var item in viewModel.Notes) { var note = updatedNotes.Find(itm => itm.Id == item.Id); if (note != null) { updatedNotes.Remove(note); } updatedNotes.Add(await NoteToEntityAsync(item, requestId)); } entity.Content.Notes = updatedNotes; } // TeamMembers if (entity.Content.TeamMembers == null) { entity.Content.TeamMembers = new List <TeamMember>(); } if (viewModel.TeamMembers != null) { var updatedTeamMembers = new List <TeamMember>(); // Update team members foreach (var item in viewModel.TeamMembers) { updatedTeamMembers.Add(await TeamMemberToEntityAsync(item)); } entity.Content.TeamMembers = updatedTeamMembers; } // ProposalDocument if (entity.Content.ProposalDocument == null) { entity.Content.ProposalDocument = ProposalDocument.Empty; } if (viewModel.ProposalDocument != null) { entity.Content.ProposalDocument = await ProposalDocumentToEntityAsync(viewModel, entity.Content.ProposalDocument, requestId); } // Metadata if (entity.Metadata == null) { entity.Metadata = OpportunityMetadata.Empty; } entity.Metadata.AnnualRevenue = viewModel.AnnualRevenue; entity.Metadata.CollateralAmount = viewModel.CollateralAmount; if (entity.Metadata.Customer == null) { entity.Metadata.Customer = Customer.Empty; } entity.Metadata.Customer.DisplayName = viewModel.Customer.DisplayName ?? String.Empty; entity.Metadata.Customer.Id = viewModel.Customer.Id ?? String.Empty; entity.Metadata.Customer.ReferenceId = viewModel.Customer.ReferenceId ?? String.Empty; entity.Metadata.DealSize = viewModel.DealSize; entity.Metadata.DebtRatio = viewModel.DebtRatio; entity.Metadata.DisbursementSchedule = viewModel.DisbursementSchedule ?? String.Empty; entity.Metadata.Guarantees = viewModel.Guarantees ?? String.Empty; if (entity.Metadata.Industry == null) { entity.Metadata.Industry = new Industry(); } if (viewModel.Industry != null) { entity.Metadata.Industry = await IndustryToEntityAsync(viewModel.Industry); } entity.Metadata.Margin = viewModel.Margin; if (entity.Metadata.OpenedDate == null) { entity.Metadata.OpenedDate = DateTimeOffset.MinValue; } if (viewModel.OpenedDate != null) { entity.Metadata.OpenedDate = viewModel.OpenedDate; } if (entity.Metadata.OpportunityState == null) { entity.Metadata.OpportunityState = OpportunityState.Creating; } if (viewModel.OpportunityState != null) { entity.Metadata.OpportunityState = OpportunityState.FromValue(viewModel.OpportunityState.Value); } entity.Metadata.Purpose = viewModel.Purpose ?? String.Empty; entity.Metadata.Rate = viewModel.Rate; if (entity.Metadata.Region == null) { entity.Metadata.Region = Region.Empty; } if (viewModel.Region != null) { entity.Metadata.Region = await RegionToEntityAsync(viewModel.Region); } entity.Metadata.RiskRating = viewModel.RiskRating; // if to avoid deleting channelId if vieModel passes empty and a value was already in opportunity if (!String.IsNullOrEmpty(viewModel.OpportunityChannelId)) { entity.Metadata.OpportunityChannelId = viewModel.OpportunityChannelId; } return(entity); } catch (Exception ex) { //_logger.LogError("MapFromViewModelAsync error: " + ex); throw new ResponseException($"RequestId: {requestId} - OpportunityToEntityAsync oppId: {oppId} - failed to map opportunity: {ex}"); } }