/// <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 = OpportunityState.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}");
         }
     }
 }
Exemplo n.º 2
0
        internal static void CloseOpportunity(Core core, OpportunityState state, OptionSetValue status, Entity opportunityClose, EntityReference userRef)
        {
            var setStateHandler = core.RequestHandlers.Find(x => x is SetStateRequestHandler);
            var req             = new SetStateRequest()
            {
                EntityMoniker = opportunityClose.GetAttributeValue <EntityReference>("opportunityid"),
                State         = new OptionSetValue((int)state),
                Status        = status
            };

            setStateHandler.Execute(req, userRef);

            var create = new CreateRequest {
                Target = opportunityClose
            };

            core.Execute(create as OrganizationRequest, userRef);
        }
Exemplo n.º 3
0
        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() == "customerfeedbacktab")
                        {
                            entity = await _customerFeedbackProcessService.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
                        });
                    }
                }

                //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;

                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}");
            }
        }
Exemplo n.º 5
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}");
            }
        }