private async Task <Opportunity> OpportunityToEntityAsync(OpportunityViewModel viewModel, Opportunity opportunity, string requestId = "") { var oppId = viewModel.Id; try { var entity = opportunity; 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; } // Proposal Document if (viewModel.ProposalDocument != null) { entity = await _proposalStatusProcessService.MapToEntityAsync(entity, viewModel, requestId); } //DealType if (viewModel.DealType != null) { entity.Content.DealType = await _templateHelpers.MapToEntity(viewModel.DealType); //DealType Processes var checklistPass = false; foreach (var item in viewModel.DealType.ProcessList) { if (item.ProcessType.ToLower() == "checklisttab" && checklistPass == false) { entity = await _checkListProcessService.MapToEntityAsync(entity, viewModel, requestId); checklistPass = true; } if (item.ProcessType.ToLower() == "feedbacktab") { entity = await customerFeedbackProcessService.MapToEntityAsync(entity, viewModel, requestId); } if (item.ProcessType.ToLower() == "customerdecisiontab") { entity = await _customerDecisionProcessService.MapToEntityAsync(entity, viewModel, requestId); } if (item.ProcessType.ToLower() == "proposalstatustab") { entity = await _proposalStatusProcessService.MapToEntityAsync(entity, viewModel, requestId); } } } // 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; } //Granular Access Start //Team creation var permissionsNeeded = new List <ApplicationCore.Entities.Permission>(); List <string> list = new List <string>(); var access = true; //going for super access list.AddRange(new List <string> { Access.Opportunities_ReadWrite_All.ToString() }); permissionsNeeded = (await _permissionRepository.GetAllAsync(requestId)).ToList().Where(x => list.Any(x.Name.Contains)).ToList(); if (!(StatusCodes.Status200OK == await _authorizationService.CheckAccessAsync(permissionsNeeded, requestId))) { //going for opportunity access list.Clear(); list.AddRange(new List <string> { Access.Opportunity_ReadWrite_All.ToString(), Access.Opportunity_ReadWrite_Partial.ToString() }); permissionsNeeded = (await _permissionRepository.GetAllAsync(requestId)).ToList().Where(x => list.Any(x.Name.Contains)).ToList(); if (!(StatusCodes.Status200OK == await _authorizationService.CheckAccessAsync(permissionsNeeded, requestId))) { //going for partial accesss list.Clear(); list.AddRange(new List <string> { "Opportunity_ReadWrite_Team" }); permissionsNeeded = (await _permissionRepository.GetAllAsync(requestId)).ToList().Where(x => list.Any(x.Name.ToLower().Contains)).ToList(); access = StatusCodes.Status200OK == await _authorizationService.CheckAccessAsync(permissionsNeeded, requestId) ? true : false; } else { var currentUser = (_userContext.User.Claims).ToList().Find(x => x.Type == "preferred_username")?.Value; if (!(viewModel.TeamMembers).ToList().Any(teamMember => teamMember.UserPrincipalName == currentUser)) { access = false; } } } if (access) { // 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; } } //Granular Access end // 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; } //For Dashboard --TargetDate if (entity.Metadata.TargetDate == null) { entity.Metadata.TargetDate = DateTimeOffset.MinValue; } if (viewModel.TargetDate != null) { entity.Metadata.TargetDate = viewModel.TargetDate; } 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}"); } }
private async Task <Opportunity> OpportunityToEntityAsync(OpportunityViewModel viewModel, Opportunity opportunity, string requestId = "") { var oppId = viewModel.Id; try { var entity = opportunity; entity.Id = viewModel.Id ?? String.Empty; entity.DisplayName = viewModel.DisplayName ?? String.Empty; entity.Reference = viewModel.Reference ?? String.Empty; entity.Version = viewModel.Version ?? _appOptions.Version; //TODO entity.TemplateLoaded = viewModel.TemplateLoaded; // DocumentAttachments//TODO 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; } // Proposal Document if (viewModel.ProposalDocument != null) { entity = await _proposalStatusProcessService.MapToEntityAsync(entity, viewModel, requestId); } //DealType if (viewModel.Template != null) { entity.Content.Template = await _templateHelpers.MapToEntity(viewModel.Template); //DealType Processes var checklistPass = false; foreach (var item in viewModel.Template.ProcessList) { if (item.ProcessType.ToLower() == "checklisttab" && checklistPass == false) { entity = await _checkListProcessService.MapToEntityAsync(entity, viewModel, requestId); checklistPass = true; } if (item.ProcessType.ToLower() == "customerdecisiontab") { entity = await _customerDecisionProcessService.MapToEntityAsync(entity, viewModel, requestId); } if (item.ProcessType.ToLower() == "proposalstatustab") { entity = await _proposalStatusProcessService.MapToEntityAsync(entity, viewModel, requestId); } } } // 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; } //Granular Access Start //Team creation var permissionsNeeded = new List <ApplicationCore.Entities.Permission>(); List <string> list = new List <string>(); var access = true; //going for super access list.AddRange(new List <string> { Access.Opportunities_ReadWrite_All.ToString() }); permissionsNeeded = (await _permissionRepository.GetAllAsync(requestId)).ToList().Where(x => list.Any(x.Name.Contains)).ToList(); if (!(StatusCodes.Status200OK == await _authorizationService.CheckAccessAsync(permissionsNeeded, requestId))) { //going for opportunity access list.Clear(); list.AddRange(new List <string> { Access.Opportunity_ReadWrite_All.ToString(), Access.Opportunity_ReadWrite_Partial.ToString() }); permissionsNeeded = (await _permissionRepository.GetAllAsync(requestId)).ToList().Where(x => list.Any(x.Name.Contains)).ToList(); if (!(StatusCodes.Status200OK == await _authorizationService.CheckAccessAsync(permissionsNeeded, requestId))) { //going for partial accesss list.Clear(); list.AddRange(new List <string> { "Opportunity_ReadWrite_Team" }); permissionsNeeded = (await _permissionRepository.GetAllAsync(requestId)).ToList().Where(x => list.Any(x.Name.ToLower().Contains)).ToList(); access = StatusCodes.Status200OK == await _authorizationService.CheckAccessAsync(permissionsNeeded, requestId) ? true : false; } else { var currentUser = (_userContext.User.Claims).ToList().Find(x => x.Type == "preferred_username")?.Value; if (!(viewModel.TeamMembers).ToList().Any(teamMember => teamMember.UserPrincipalName == currentUser)) { access = false; } } } if (access) { // 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(TeamMemberToEntityAsync(item)); } entity.Content.TeamMembers = updatedTeamMembers; } } //Granular Access end //TODO : WAVE-4 GENERIC ACCELERATOR Change : start // Metadata if (entity.Metadata == null) { entity.Metadata = OpportunityMetadata.Empty; } 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.OpportunityChannelId = viewModel.OpportunityChannelId; if (entity.Metadata.OpportunityState == null) { entity.Metadata.OpportunityState = OpportunityState.Creating; } if (viewModel.OpportunityState != null) { entity.Metadata.OpportunityState = OpportunityState.FromValue(viewModel.OpportunityState.Value); } if (entity.Metadata.Fields == null) { entity.Metadata.Fields = new List <OpportunityMetaDataFields>(); } foreach (var field in viewModel.MetaDataFields.ToList()) { var obj = entity.Metadata.Fields.ToList().FirstOrDefault(x => x.DisplayName == field.DisplayName); if (obj != null) { obj.Values = field.Values; } else { entity.Metadata.Fields.Add(new OpportunityMetaDataFields() { DisplayName = field.DisplayName ?? String.Empty, FieldType = field.FieldType ?? FieldType.None, Screen = field.Screen ?? String.Empty, Values = field.Values ?? String.Empty, UniqueId = field.UniqueId, Required = field.Required }); } } //TODO : WAVE-4 GENERIC ACCELERATOR Change : end return(entity); } catch (Exception ex) { //_logger.LogError("MapFromViewModelAsync error: " + ex); throw new ResponseException($"RequestId: {requestId} - OpportunityToEntityAsync oppId: {oppId} - 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}"); } }