예제 #1
0
        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}");
            }
        }
        public async Task <JObject> UploadDocumentTeamAsync(string opportunityName, string docType, IFormFile file, string requestId = "")
        {
            _logger.LogInformation($"RequestId: {requestId} - UploadDocumentTeamAsync called.");

            try
            {
                Guard.Against.NullOrEmpty(opportunityName, nameof(opportunityName), requestId);
                Guard.Against.NullOrEmpty(docType, nameof(docType), requestId);
                Guard.Against.Null(file, nameof(file), requestId);

                var sections     = new List <DocumentSection>();
                var folder       = String.Empty;
                var docTypeParts = docType.Split(new char[] { ',', '=' }); //0 = ChecklistDocument, 1 = channle name, 2 = Checklist item Id


                if (docType == DocumentContext.ProposalTemplate.Name)
                {
                    // If docType is proposal document template, try to extract sections before upload so if fails, upload is skipped
                    sections = (ExtractSections(file.OpenReadStream(), file.FileName, requestId)).ToList();
                    Guard.Against.Null(sections, "UploadDocumentTeamAsync_sections", requestId);

                    folder = "Formal Proposal";
                }
                else if (docType == DocumentContext.Attachment.Name)
                {
                    folder = "TempFolder";
                }
                else
                {
                    folder = docTypeParts[1].Replace(" ", "");
                }


                // Get opportunity to update the associated docUri
                //var opportunity = Opportunity.Empty;
                var opportunity = await _opportunityRepository.GetItemByNameAsync($"'{opportunityName}'", false, requestId);

                Guard.Against.Null(opportunity, "UploadDocumentTeamAsync_GetItemByNameAsync", requestId);

                // Start a simple retry
                var retryGetOpTimes = 1;
                while ((String.IsNullOrEmpty(opportunity.Id)) && retryGetOpTimes < 7)
                {
                    _logger.LogInformation($"RequestId: {requestId} - UploadDocumentTeamAsync get opportunity delay started: {retryGetOpTimes} at {DateTime.Now}.");
                    await Task.Delay(4000 + (retryGetOpTimes * 1000));

                    opportunity = await _opportunityRepository.GetItemByNameAsync($"'{opportunityName}'", false, requestId);

                    retryGetOpTimes = retryGetOpTimes + 1;
                }

                Guard.Against.NullOrEmpty(opportunity.Id, "UploadDocumentTeamAsync_opportunity_GetItemByNameAsync", requestId);

                if (opportunity.DisplayName != opportunityName)
                {
                    throw new ResponseException($"RequestId: {requestId} - UploadDocumentTeamAsync GetItemByNameAsync mistmatch for opportunity: {opportunityName}");
                }

                var siteName       = opportunityName.Replace(" ", "");
                var siteIdResponse = new JObject();
                var siteId         = String.Empty;

                if (folder == "TempFolder")
                {
                    // Initial attachment is uploaded to private site for proposal mnagement
                    siteName = "ProposlManagement";
                    siteId   = _appOptions.ProposalManagementRootSiteId;
                }
                else
                {
                    try
                    {
                        siteIdResponse = await _graphSharePointAppService.GetSiteIdAsync(_appOptions.SharePointHostName, siteName, requestId);

                        dynamic responseDyn = siteIdResponse;
                        siteId = responseDyn.id.ToString();
                    }
                    catch (Exception ex)
                    {
                        _logger.LogInformation($"RequestId: {requestId} - UploadDocumentTeamAsync get site id error: {ex}");
                    }
                }

                var retryGetSiteTimes = 1;
                while ((String.IsNullOrEmpty(siteId)) && retryGetSiteTimes < 4)
                {
                    _logger.LogInformation($"RequestId: {requestId} - UploadDocumentTeamAsync get site id delay started: {retryGetOpTimes} at {DateTime.Now}.");
                    await Task.Delay(4000 + (retryGetSiteTimes * 1000));

                    siteIdResponse = await _graphSharePointAppService.GetSiteIdAsync(_appOptions.SharePointHostName, siteName, requestId);

                    dynamic responseDyn = siteIdResponse;
                    siteId            = responseDyn.id.ToString();
                    retryGetSiteTimes = retryGetSiteTimes + 1;
                }

                Guard.Against.NullOrEmpty(siteId, "UploadDocumentTeamAsync_GetSiteIdAsync", requestId);

                if (docType == DocumentContext.Attachment.Name)
                {
                    // Create folder with opportunity name in internal sharepoint under root\TempFolder TODO: Get name form app settings P2
                    try
                    {
                        var respFolder = await CreateFolderAsync(siteId, opportunity.DisplayName, folder, requestId);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogWarning($"RequestId: {requestId} - UploadDocumentTeamAsync CreateFolderAsync Exception: {ex}");
                    }

                    folder = folder + $"/{opportunity.DisplayName}";
                }

                var respUpload = await UploadDocumentAsync(siteId, folder, file, requestId);

                dynamic respUploadDyn = respUpload;
                string  webUrl        = respUploadDyn.webUrl.ToString();
                string  docId         = respUploadDyn.id.ToString();

                //Todo: Granular Premission
                if (docType == DocumentContext.ProposalTemplate.Name)
                {
                    // If docType is proposal document template, update sections & documentUri
                    opportunity.Content.ProposalDocument.Content.ProposalSectionList = sections;
                    opportunity.Content.ProposalDocument.Id = docId;
                    opportunity.Content.ProposalDocument.Metadata.DocumentUri = webUrl;
                }
                else if (docType == DocumentContext.Attachment.Name)
                {
                    if (opportunity.DocumentAttachments == null)
                    {
                        opportunity.DocumentAttachments = new List <DocumentAttachment>();
                    }
                    var updDocumentAttachments = new List <DocumentAttachment>();
                    foreach (var itm in opportunity.DocumentAttachments)
                    {
                        var doc = itm;
                        if (itm.FileName == file.FileName)
                        {
                            doc.Id            = docId;
                            doc.FileName      = file.FileName;
                            doc.Note          = itm.Note ?? String.Empty;
                            doc.Tags          = itm.Tags ?? String.Empty;
                            doc.DocumentUri   = "TempFolder";
                            doc.Category      = Category.Empty;
                            doc.Category.Id   = itm.Category.Id;
                            doc.Category.Name = itm.Category.Name;
                        }
                        updDocumentAttachments.Add(doc);
                    }
                    opportunity.DocumentAttachments = updDocumentAttachments;
                }
                else if (docType.StartsWith($"{DocumentContext.ChecklistDocument.Name}="))
                {
                    var checklistTaskId = docTypeParts[2];
                    var channel         = docTypeParts[1];

                    var newChecklists = new List <Checklist>();
                    foreach (var item in opportunity.Content.Checklists.ToList())
                    {
                        var newChecklist = new Checklist();
                        newChecklist.ChecklistTaskList = new List <ChecklistTask>();
                        newChecklist.ChecklistChannel  = item.ChecklistChannel;
                        newChecklist.ChecklistStatus   = item.ChecklistStatus;
                        newChecklist.Id = item.Id;

                        if (channel != item.ChecklistChannel)
                        {
                            newChecklist.ChecklistTaskList = item.ChecklistTaskList;
                        }
                        else
                        {
                            var newChecklistTask = new ChecklistTask();
                            foreach (var sItem in item.ChecklistTaskList)
                            {
                                if (sItem.Id == checklistTaskId)
                                {
                                    newChecklistTask.Id            = sItem.Id;
                                    newChecklistTask.ChecklistItem = sItem.ChecklistItem;
                                    newChecklistTask.Completed     = sItem.Completed;
                                    newChecklistTask.FileUri       = webUrl;
                                    newChecklist.ChecklistTaskList.Add(newChecklistTask);
                                }
                                else
                                {
                                    newChecklist.ChecklistTaskList.Add(sItem);
                                }
                            }
                        }

                        newChecklists.Add(newChecklist);
                    }
                    opportunity.Content.Checklists = newChecklists;
                }

                // Update the opportunity
                var respUpdate = await _opportunityRepository.UpdateItemAsync(opportunity, requestId);

                Guard.Against.NotStatus200OK(respUpdate, "UploadDocumentTeamAsync_UpdateItemAsync", requestId);

                return(respUpload);
            }
            catch (Exception ex)
            {
                _logger.LogError($"RequestId: {requestId} - UploadDocumentTeamAsync Service Exception: {ex}");
                throw new ResponseException($"RequestId: {requestId} - UploadDocumentTeamAsync Service Exception: {ex}");
            }
        }
예제 #3
0
 public void Attach(ChecklistTask checklistTask)
 {
     context.ChecklistTasks.Attach(checklistTask);
 }
예제 #4
0
 public DbEntityEntry <ChecklistTask> Entry(ChecklistTask checklistTask)
 {
     return(Context.Entry(checklistTask));
 }
예제 #5
0
 public void Add(ChecklistTask checklistTask)
 {
     context.ChecklistTasks.Add(checklistTask);
 }