Ejemplo n.º 1
0
        public async Task <IList <RoleMappingModel> > GetAllAsync(string requestId = "")
        {
            _logger.LogInformation($"RequestId: {requestId} - RoleMappingSvc_GetAllAsync called.");

            try
            {
                var listItems = (await _roleMappingRepository.GetAllAsync(requestId)).ToList();
                Guard.Against.Null(listItems, nameof(listItems), requestId);

                var modelListItems = new List <RoleMappingModel>();
                foreach (var item in listItems)
                {
                    modelListItems.Add(MapToModel(item));
                }

                if (modelListItems.Count == 0)
                {
                    _logger.LogWarning($"RequestId: {requestId} - RoleMappingSvc_GetAllAsync no items found");
                    throw new NoItemsFound($"RequestId: {requestId} - Method name: RoleMappingSvc_GetAllAsync - No Items Found");
                }

                return(modelListItems);
            }
            catch (Exception ex)
            {
                _logger.LogError($"RequestId: {requestId} - RoleMappingSvc_GetAllAsync error: " + ex);
                throw;
            }
        }
        private async Task <List <UserProfile> > GetUsersListAsync(string requestId = "")
        {
            try
            {
                if (_usersList?.Count == 0)
                {
                    var roleMappings = await _roleMappingRepository.GetAllAsync(requestId);

                    foreach (var role in roleMappings)
                    {
                        var userRole = Role.Empty;
                        userRole.DisplayName = role.RoleName;
                        userRole.AdGroupName = role.AdGroupName;

                        var options = new List <QueryParam>();
                        options.Add(new QueryParam("filter", $"startswith(displayName,'{userRole.AdGroupName}')"));
                        var groupIdJson = await _graphUserAppService.GetGroupAsync(options, "", requestId);

                        dynamic jsonDyn = groupIdJson;
                        if (jsonDyn.value.HasValues)
                        {
                            userRole.Id = jsonDyn.value[0].id.ToString();

                            var groupMembersJson = await _graphUserAppService.GetGroupMembersAsync(userRole.Id, requestId);

                            JArray membersJsonArray = JArray.Parse(groupMembersJson["value"].ToString());

                            foreach (var member in membersJsonArray)
                            {
                                var user = UserProfile.Empty;
                                user = _usersList.Find(x => x.Id == member["id"].ToString());

                                if (user != null)
                                {
                                    _usersList.Remove(user);
                                }
                                else
                                {
                                    user    = UserProfile.Empty;
                                    user.Id = member["id"].ToString();
                                }

                                user.DisplayName = member["displayName"].ToString();
                                if (user.Fields == null)
                                {
                                    user.Fields = UserProfileFields.Empty;
                                }
                                user.Fields.Mail = member["mail"].ToString();
                                user.Fields.UserPrincipalName = member["userPrincipalName"].ToString();
                                user.Fields.Title             = member["jobTitle"].ToString() ?? String.Empty;

                                // Check if user already has the role
                                var existingRole = user.Fields.UserRoles.Find(x => x.Id == userRole.Id);
                                if (existingRole == null)
                                {
                                    user.Fields.UserRoles.Add(userRole);
                                }

                                _usersList.Add(user);
                            }
                        }
                    }
                }

                return(_usersList);
            }
            catch (Exception ex)
            {
                _logger.LogError($"RequestId: {requestId} - GetUsersListAsync Service Exception: {ex}");
                throw new ResponseException($"RequestId: {requestId} - GetUsersListAsync Service Exception: {ex}");
            }
        }
Ejemplo n.º 3
0
        public async Task <StatusCodes> CheckAdminAccsessAsync(string requestId = "")
        {
            _logger.LogInformation($"RequestId: {requestId} - AuthorizationService_CheckAdminAccessAsync called.");

            //var currentUserScope = (_userContext.User.Claims).ToList().Find(x => x.Type == "http://schemas.microsoft.com/identity/claims/scope")?.Value;

            //if (currentUserScope != "access_as_user")
            //{
            //    var app_permission = false;
            //    app_permission = (await _permissionRepository.GetAllAsync(requestId)).ToList().Any(x => x.Name.ToLower() == currentUserScope.ToString().ToLower());
            //    if (app_permission)
            //        return StatusCodes.Status200OK;
            //    else
            //        return StatusCodes.Status401Unauthorized;
            //}
            //var currentUser = (_userContext.User.Claims).ToList().Find(x => x.Type == "preferred_username")?.Value;
            //var selectedUserProfile = await _userProfileRepository.GetItemByUpnAsync(currentUser, requestId);

            //var currentUserPermissionList = new List<Permission>();
            //var rolemappinglist = new List<RoleMapping>();
            //rolemappinglist = (await _roleMappingRepository.GetAllAsync(requestId)).ToList();
            //currentUserPermissionList = (from curroles in selectedUserProfile.Fields.UserRoles
            //                             from roles in rolemappinglist
            //                             where curroles.DisplayName == roles.Role.DisplayName
            //                             select roles.Permissions).SelectMany(x => x).ToList();
            var currentUserPermissionList = new List <Permission>();
            var rolemappinglist           = new List <RoleMapping>();

            var currentUser = (_userContext.User.Claims).ToList().Find(x => x.Type == "preferred_username")?.Value;

            if (!(string.IsNullOrEmpty(currentUser)))
            {
                var selectedUserProfile = await _userProfileRepository.GetItemByUpnAsync(currentUser, requestId);

                rolemappinglist           = (await _roleMappingRepository.GetAllAsync(requestId)).ToList();
                currentUserPermissionList = (from curroles in selectedUserProfile.Fields.UserRoles
                                             from roles in rolemappinglist
                                             where curroles.DisplayName == roles.Role.DisplayName
                                             select roles.Permissions).SelectMany(x => x).ToList();
            }
            else
            {
                var aud = (_userContext.User.Claims).ToList().Find(x => x.Type == "aud")?.Value;
                var azp = (_userContext.User.Claims).ToList().Find(x => x.Type == "azp")?.Value;

                if (azp == _clientId)
                {
                    rolemappinglist = (await _roleMappingRepository.GetAllAsync(requestId)).
                                      Where(x => x.AdGroupName == $"aud_{aud}").ToList();
                    currentUserPermissionList = (from rolemapping in rolemappinglist
                                                 select rolemapping.Permissions).SelectMany(x => x).ToList();
                }
                else
                {
                    return(StatusCodes.Status401Unauthorized);
                }
            }
            bool check = false;

            foreach (var userPermission in currentUserPermissionList)
            {
                if (userPermission.Name == Access.Administrator.ToString())
                {
                    check = true;
                }
            }

            //throw an exception if the user doesnt have admin access.
            if (!check)
            {
                _logger.LogInformation($"RequestId: {requestId} - AuthorizationService_CheckAdminAccessAsync admin access exception.");
                throw new AccessDeniedException("Admin Access Required");
            }
            else
            {
                return(StatusCodes.Status200OK);
            }
        }
Ejemplo n.º 4
0
        public async Task <Opportunity> UpdateWorkflowAsync(Opportunity opportunity, string requestId = "")
        {
            try
            {
                var initialState = opportunity.Metadata.OpportunityState;

                if (opportunity.Metadata.OpportunityState != OpportunityState.Creating)
                {
                    if (opportunity.Content.CustomerDecision.Approved)
                    {
                        opportunity.Metadata.OpportunityState = OpportunityState.Accepted;
                    }

                    try
                    {
                        opportunity = await MoveTempFileToTeamAsync(opportunity, requestId);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError($"RequestId: {requestId} - UpdateWorkflowAsync_MoveTempFileToTeam Service Exception: {ex}");
                    }

                    // Add / update members
                    // Get Group id
                    //var opportunityName = opportunity.DisplayName.Replace(" ", "");
                    var opportunityName = WebUtility.UrlEncode(opportunity.DisplayName);
                    var options         = new List <QueryParam>();

                    options.Add(new QueryParam("filter", $"startswith(displayName,'{opportunityName}')"));

                    var groupIdJson = await _graphUserAppService.GetGroupAsync(options, "", requestId);

                    dynamic jsonDyn = groupIdJson;

                    var group = String.Empty;
                    if (groupIdJson.HasValues)
                    {
                        group = jsonDyn.value[0].id.ToString();
                    }

                    // add to team group
                    var teamMembersComplete   = 0;
                    var isLoanOfficerSelected = false;
                    foreach (var item in opportunity.Content.TeamMembers)
                    {
                        var groupID = group;
                        var userId  = item.Id;
                        var oItem   = item;

                        if (item.AssignedRole.DisplayName == "RelationshipManager")
                        {
                            // In case an admin or background workflow will trigger this update after team/channels are created, relationship manager should also be added as owner
                            try
                            {
                                Guard.Against.NullOrEmpty(item.Id, $"UpdateWorkflowAsync_{item.AssignedRole.DisplayName} Id NullOrEmpty", requestId);
                                var responseJson = await _graphUserAppService.AddGroupOwnerAsync(userId, groupID, requestId);
                            }
                            catch (Exception ex)
                            {
                                _logger.LogError($"RequestId: {requestId} - userId: {userId} - UpdateWorkflowAsync_AddGroupOwnerAsync_{item.AssignedRole.DisplayName} error in CreateWorkflowAsync: {ex}");
                            }
                        }
                        else if (item.AssignedRole.DisplayName == "LoanOfficer")
                        {
                            if (!String.IsNullOrEmpty(item.Id))
                            {
                                isLoanOfficerSelected = true;                                 //Reltionship manager should be set to complete if loan officer is selected
                            }
                            try
                            {
                                Guard.Against.NullOrEmpty(item.Id, $"UpdateWorkflowAsync_{item.AssignedRole.DisplayName} Id NullOrEmpty", requestId);
                                var responseJson = await _graphUserAppService.AddGroupOwnerAsync(userId, groupID, requestId);
                            }
                            catch (Exception ex)
                            {
                                _logger.LogError($"RequestId: {requestId} - userId: {userId} - UpdateWorkflowAsync_AddGroupOwnerAsync_{item.AssignedRole.DisplayName} error in CreateWorkflowAsync: {ex}");
                            }
                        }
                        else
                        {
                            if (!String.IsNullOrEmpty(item.Fields.UserPrincipalName))
                            {
                                teamMembersComplete = teamMembersComplete + 1;
                                try
                                {
                                    Guard.Against.NullOrEmpty(item.Id, $"UpdateWorkflowAsync_{item.AssignedRole.DisplayName} Id NullOrEmpty", requestId);
                                    var responseJson = await _graphUserAppService.AddGroupMemberAsync(userId, groupID, requestId);
                                }
                                catch (Exception ex)
                                {
                                    _logger.LogError($"RequestId: {requestId} - userId: {userId} - UpdateWorkflowAsync_AddGroupMemberAsync_{item.AssignedRole.DisplayName} error in CreateWorkflowAsync: {ex}");
                                }
                            }
                        }
                    }

                    //Update status of team members
                    var oppCheckLists = opportunity.Content.Checklists.ToList();
                    var roleMappings  = (await _roleMappingRepository.GetAllAsync(requestId)).ToList();

                    //TODO: LinQ
                    var updatedTeamlist = new List <TeamMember>();
                    foreach (var item in opportunity.Content.TeamMembers)
                    {
                        var oItem = item;
                        oItem.Status = ActionStatus.NotStarted;

                        if (opportunity.Content.CustomerDecision.Approved)
                        {
                            oItem.Status = ActionStatus.Completed;
                        }
                        else
                        {
                            var roleMap = roleMappings.Find(x => x.RoleName == item.AssignedRole.DisplayName);

                            if (item.AssignedRole.DisplayName != "LoanOfficer" && item.AssignedRole.DisplayName != "RelationshipManager")
                            {
                                if (roleMap != null)
                                {
                                    _logger.LogInformation($"RequestId: {requestId} - UpdateOpportunityAsync teamMember status sync with checklist status RoleName: {roleMap.RoleName}");

                                    var checklistItm = oppCheckLists.Find(x => x.ChecklistChannel == roleMap.Channel);
                                    if (checklistItm != null)
                                    {
                                        _logger.LogInformation($"RequestId: {requestId} - UpdateOpportunityAsync teamMember status sync with checklist status: {checklistItm.ChecklistStatus.Name}");
                                        oItem.Status = checklistItm.ChecklistStatus;
                                    }
                                }
                            }
                            else if (item.AssignedRole.DisplayName == "RelationshipManager")
                            {
                                var exisitngLoanOfficers = ((opportunity.Content.TeamMembers).ToList()).Find(x => x.AssignedRole.DisplayName == "LoanOfficer");
                                if (exisitngLoanOfficers == null)
                                {
                                    oItem.Status = ActionStatus.InProgress;
                                }
                                else
                                {
                                    oItem.Status = ActionStatus.Completed;
                                }
                            }
                            else if (item.AssignedRole.DisplayName == "LoanOfficer")
                            {
                                var teamList = ((opportunity.Content.TeamMembers).ToList()).FindAll(x => x.AssignedRole.DisplayName != "LoanOfficer" && x.AssignedRole.DisplayName != "RelationshipManager");
                                if (teamList != null)
                                {
                                    var expectedTeam = roleMappings.FindAll(x => x.RoleName != "LoanOfficer" && x.RoleName != "RelationshipManager" && x.RoleName != "Administrator");
                                    if (expectedTeam != null)
                                    {
                                        if (teamList.Count != 0)
                                        {
                                            oItem.Status = ActionStatus.InProgress;
                                        }
                                        if (teamList.Count >= expectedTeam.Count)
                                        {
                                            oItem.Status = ActionStatus.Completed;
                                        }
                                    }
                                }
                            }
                        }

                        updatedTeamlist.Add(oItem);
                    }

                    opportunity.Content.TeamMembers = updatedTeamlist;
                }

                // Send notification
                _logger.LogInformation($"RequestId: {requestId} - UpdateWorkflowAsync initialState: {initialState.Name} - {opportunity.Metadata.OpportunityState.Name}");
                if (initialState.Value != opportunity.Metadata.OpportunityState.Value)
                {
                    try
                    {
                        _logger.LogInformation($"RequestId: {requestId} - CreateWorkflowAsync sendNotificationCardAsync opportunity state change notification.");
                        var sendTo = UserProfile.Empty;
                        var sendNotificationCard = await _cardNotificationService.sendNotificationCardAsync(opportunity, sendTo, $"Opportunity state for {opportunity.DisplayName} has been changed to {opportunity.Metadata.OpportunityState.Name}", requestId);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError($"RequestId: {requestId} - CreateWorkflowAsync sendNotificationCardAsync OpportunityState error: {ex}");
                    }
                }

                // Delete empty ChecklistItems
                //opportunity.Content.Checklists = await RemoveEmptyFromChecklist(opportunity.Content.Checklists, requestId);

                return(opportunity);
            }
            catch (Exception ex)
            {
                _logger.LogError($"RequestId: {requestId} - UpdateWorkflowAsync Service Exception: {ex}");
                throw new ResponseException($"RequestId: {requestId} - UpdateWorkflowAsync Service Exception: {ex}");
            }
        }
        public async Task <Opportunity> UpdateWorkflowAsync(Opportunity opportunity, string requestId = "")
        {
            try
            {
                //create team and channels
                if (opportunity.Content.DealType.ProcessList != null && opportunity.Metadata.OpportunityState == OpportunityState.Creating)
                {
                    if (await GroupIdCheckAsync(opportunity.DisplayName, requestId))
                    {
                        await CreateTeamAndChannelsAsync(opportunity, requestId);

                        //Temperary change, will revert to back after implementing "add app"
                        opportunity.Metadata.OpportunityState = OpportunityState.InProgress;
                    }
                }

                var  initialState  = opportunity.Metadata.OpportunityState;
                bool checklistPass = false;

                if (opportunity.Metadata.OpportunityState != OpportunityState.Creating)
                {
                    try
                    {
                        opportunity = await MoveTempFileToTeamAsync(opportunity, requestId);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError($"RequestId: {requestId} - UpdateWorkflowAsync_MoveTempFileToTeam Service Exception: {ex}");
                    }

                    if (opportunity.Content.DealType.ProcessList != null)
                    {
                        foreach (var item in opportunity.Content.DealType.ProcessList)
                        {
                            if (item.ProcessType.ToLower() == "checklisttab" && checklistPass == false)
                            {
                                //DashBoard Create call Start.
                                await UpdateDashBoardEntryAsync(opportunity, requestId);

                                //DashBoard Create call End.
                                opportunity = await _checkListProcessService.UpdateWorkflowAsync(opportunity, requestId);

                                checklistPass = true;
                            }
                            else if (item.ProcessType.ToLower() == "feedbacktab")
                            {
                                opportunity = await customerFeedbackProcessService.UpdateWorkflowAsync(opportunity, requestId);
                            }
                            else if (item.ProcessType.ToLower() == "customerdecisiontab")
                            {
                                opportunity = await _customerDecisionProcessService.UpdateWorkflowAsync(opportunity, requestId);
                            }
                            else if (item.ProcessType.ToLower() == "proposalstatustab")
                            {
                                opportunity = await _proposalStatusProcessService.UpdateWorkflowAsync(opportunity, requestId);
                            }
                            else if (item.ProcessStep.ToLower() == "start process")
                            {
                                opportunity = await _startProcessService.UpdateWorkflowAsync(opportunity, requestId);
                            }
                            else if (item.ProcessStep.ToLower() == "new opportunity")
                            {
                                opportunity = await _newOpportunityProcessService.UpdateWorkflowAsync(opportunity, requestId);
                            }
                        }
                    }


                    var roleMappings = (await _roleMappingRepository.GetAllAsync(requestId)).ToList();
                }

                // Send notification
                _logger.LogInformation($"RequestId: {requestId} - UpdateWorkflowAsync initialState: {initialState.Name} - {opportunity.Metadata.OpportunityState.Name}");
                if (initialState.Value != opportunity.Metadata.OpportunityState.Value)
                {
                    try
                    {
                        _logger.LogInformation($"RequestId: {requestId} - CreateWorkflowAsync sendNotificationCardAsync opportunity state change notification.");
                        var sendTo = UserProfile.Empty;
                        var sendNotificationCard = await _cardNotificationService.sendNotificationCardAsync(opportunity, sendTo, $"Opportunity state for {opportunity.DisplayName} has been changed to {opportunity.Metadata.OpportunityState.Name}", requestId);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError($"RequestId: {requestId} - CreateWorkflowAsync sendNotificationCardAsync OpportunityState error: {ex}");
                    }
                }

                //Adding RelationShipManager and LoanOfficer into ProposalManager Team
                foreach (var item in opportunity.Content.TeamMembers)
                {
                    try
                    {
                        if (item.AssignedRole.DisplayName == "LoanOfficer" || item.AssignedRole.DisplayName == "RelationshipManager")
                        {
                            dynamic jsonDyn = null;
                            var     options = new List <QueryParam>();
                            options.Add(new QueryParam("filter", $"startswith(displayName,'Proposal Manager Team')"));
                            var groupIdJson = await _graphUserAppService.GetGroupAsync(options, "", requestId);

                            jsonDyn = groupIdJson;
                            if (!String.IsNullOrEmpty(jsonDyn.value[0].id.ToString()))
                            {
                                var groupID = jsonDyn.value[0].id.ToString();
                                if (!String.IsNullOrEmpty(item.Fields.UserPrincipalName))
                                {
                                    try
                                    {
                                        Guard.Against.NullOrEmpty(item.Id, $"OpportunityFactorty_{item.AssignedRole.DisplayName} Id NullOrEmpty", requestId);
                                        var responseJson = await _graphUserAppService.AddGroupMemberAsync(item.Id, groupID, requestId);
                                    }
                                    catch (Exception ex)
                                    {
                                        _logger.LogError($"RequestId: {requestId} - userId: {item.Id} - OpportunityFactorty_AddGroupMemberAsync_{item.AssignedRole.DisplayName} error in CreateWorkflowAsync: {ex}");
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError($"RequestId: {requestId} - userId: {item.Id} - OpportunityFactorty_AddGroupMemberAsync_{item.AssignedRole.DisplayName} error in CreateWorkflowAsync: {ex}");
                    }
                }
                //Adding RelationShipManager and LoanOfficer into ProposalManager Team

                return(opportunity);
            }
            catch (Exception ex)
            {
                _logger.LogError($"RequestId: {requestId} - UpdateWorkflowAsync Service Exception: {ex}");
                throw new ResponseException($"RequestId: {requestId} - UpdateWorkflowAsync Service Exception: {ex}");
            }
        }
Ejemplo n.º 6
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}");
            }
        }