diff --git a/MesaFabApproval.Client/Pages/MRBSingle.razor b/MesaFabApproval.Client/Pages/MRBSingle.razor index 1af5ad3..3165f37 100644 --- a/MesaFabApproval.Client/Pages/MRBSingle.razor +++ b/MesaFabApproval.Client/Pages/MRBSingle.razor @@ -1,19 +1,6 @@ @page "/mrb/{mrbNumber}" @page "/mrb/new" @using System.Text -@inject IMRBService mrbService -@inject ISnackbar snackbar -@inject IDialogService dialogService -@inject NavigationManager navigationManager -@inject MesaFabApprovalAuthStateProvider authStateProvider -@inject IUserService userService -@inject IMemoryCache cache -@inject IConfiguration config -@inject IApprovalService approvalService -@inject IDialogService dialogService -@inject IPCRBService pcrbService -@inject IECNService ecnService -@inject ICustomerService customerService @if (mrbNumber is not null) { MRB @mrbNumber @@ -742,995 +729,4 @@ - - -@code { - [Parameter] - public string? mrbNumber { get; set; } - private int mrbNumberInt = 0; - private MRB? mrb { get; set; } - private User? currentUser = null; - private int currentUserId = 0; - private IEnumerable allActiveUsers = new List(); - private IEnumerable mrbActions = new List(); - private IEnumerable mrbActionAttachments = new List(); - private IEnumerable mrbAttachments = new List(); - private IEnumerable mrbApprovals = new List(); - private IEnumerable nonTaskApprovals = new List(); - private IEnumerable taskApprovals = new List(); - private IEnumerable customerNames = new List(); - private IEnumerable partNumbers = new List(); - private IEnumerable lotNumbers = new List(); - private bool processing = false; - private bool saveInProcess = false; - private bool submitInProcess = false; - private bool deleteInProcess = false; - private bool recallInProcess = false; - private bool approvalInProcess = false; - private bool taskApprovalInProcess = false; - private bool denialInProcess = false; - private bool completeAllActionsInProcess = false; - private bool deleteActionInProcess = false; - private bool attachmentUploadInProcess = false; - private bool deleteAttachmentInProcess = false; - private string actionSearchString = ""; - private string attachmentSearchString = ""; - private string currentUrl = ""; - private MudTextField? processEcnField; - private bool processEcnIsValid = false; - private MudTextField? pcrbNoField; - private bool pcrbNoIsValid = false; - - protected override async Task OnParametersSetAsync() { - processing = true; - try { - allActiveUsers = await userService.GetAllActiveUsers(); - currentUser = authStateProvider.CurrentUser; - currentUrl = navigationManager.Uri; - - if (!string.IsNullOrWhiteSpace(mrbNumber) && Int32.TryParse(mrbNumber, out mrbNumberInt)) { - mrb = await mrbService.GetMRBById(mrbNumberInt); - if (mrb.ProcessECNNumber > 0) await ECNNoIsValid(mrb.ProcessECNNumber); - if (!string.IsNullOrWhiteSpace(mrb.PCRBNo)) await PCRBNoIsValid(mrb.PCRBNo); - mrbActions = await mrbService.GetMRBActionsForMRB(mrbNumberInt, false); - partNumbers = GetPartNumbers(); - lotNumbers = GetLotNumbers(); - mrb.NumberOfLotsAffected = GetTotalActionQuantities(); - mrbActionAttachments = await mrbService.GetAllActionAttachmentsForMRB(mrbNumberInt, false); - mrbAttachments = await mrbService.GetAllAttachmentsForMRB(mrbNumberInt, false); - - mrbApprovals = await approvalService.GetApprovalsForIssueId(mrbNumberInt, false); - - nonTaskApprovals = mrbApprovals.Where(a => a.Step < 3).ToList(); - taskApprovals = mrbApprovals.Where(a => a.Step >= 3).ToList(); - } else { - mrbNumberInt = 0; - mrbNumber = ""; - mrb = new() { Status = "Draft", StageNo = 0 }; - mrbActions = new List(); - mrbAttachments = new List(); - mrbApprovals = new List(); - nonTaskApprovals = new List(); - taskApprovals = new List(); - if (authStateProvider is not null && authStateProvider.CurrentUser is not null) { - mrb.OriginatorID = authStateProvider.CurrentUser.UserID; - mrb.OriginatorName = $"{authStateProvider.CurrentUser.FirstName} {authStateProvider.CurrentUser.LastName}"; - } - } - - if (customerNames is null || customerNames.Count() <= 0) - customerNames = (await customerService.GetAllCustomerNames()).OrderBy(c => c); - - StateHasChanged(); - } catch (Exception ex) { - snackbar.Add(ex.Message, Severity.Error); - } - processing = false; - } - - private void ReturnToAllMrbs() { - cache.Set("redirectUrl", $"mrb/all"); - navigationManager.NavigateTo("mrb/all"); - } - - private async void SaveMRB() { - if (!saveInProcess) { - try { - saveInProcess = true; - MRB initialMrb = new MRB() { - MRBNumber = mrb.MRBNumber, - Status = mrb.Status, - StageNo = 0, - NumberOfLotsAffected = 0 - }; - if (mrb is not null) { - User? originator = allActiveUsers.Where(u => $"{u.FirstName} {u.LastName}".Equals(mrb.OriginatorName)).FirstOrDefault(); - if (originator is not null) mrb.OriginatorID = originator.UserID; - - if (mrb.MRBNumber <= 0) { - await mrbService.CreateNewMRB(mrb); - mrb = await mrbService.GetMRBByTitle(mrb.Title, true); - cache.Set("redirectUrl", $"mrb/{mrb.MRBNumber}"); - } - - mrb.NumberOfLotsAffected = 0; - foreach (MRBAction action in mrbActions) { - if (action is not null) { - action.MRBNumber = mrbNumberInt; - if (action.ActionID > 0) { - await mrbService.UpdateMRBAction(action); - } else { - await mrbService.CreateMRBAction(action); - } - - mrb.NumberOfLotsAffected += action.Quantity; - } - } - - if (mrb.MRBNumber > 0) await mrbService.UpdateMRB(mrb); - - mrbNumber = mrb.MRBNumber.ToString(); - mrbNumberInt = mrb.MRBNumber; - - mrbActions = await mrbService.GetMRBActionsForMRB(mrbNumberInt, true); - } - saveInProcess = false; - StateHasChanged(); - snackbar.Add($"MRB {mrb.MRBNumber} successfully saved", Severity.Success); - - if (initialMrb.MRBNumber <= 0) - navigationManager.NavigateTo($"mrb/{mrb.MRBNumber}"); - } catch (Exception ex) { - saveInProcess = false; - snackbar.Add(ex.Message, Severity.Error); - } - saveInProcess = false; - } - } - - private async void DeleteMRB() { - if (!deleteInProcess) { - try { - bool? result = await dialogService.ShowMessageBox( - "Warning", - $"Are you sure you want to delete MRB# {mrb.MRBNumber}?", - yesText: "Yes", noText: "No" - ); - - if (result == true) { - deleteInProcess = true; - - await mrbService.DeleteMRB(mrb.MRBNumber); - - deleteInProcess = false; - - snackbar.Add("MRB successfully deleted", Severity.Success); - - navigationManager.NavigateTo("mrb/all"); - } - } catch (Exception ex) { - deleteInProcess = false; - - snackbar.Add($"Unable to delete MRB, because {ex.Message}", Severity.Error); - } - } - } - - private async void SubmitMRBForApproval() { - if (!submitInProcess && !processing) { - submitInProcess = true; - processing = true; - try { - if (mrb is null) throw new Exception("MRB cannot be null"); - - User? originator = allActiveUsers.Where(u => $"{u.FirstName} {u.LastName}".Equals(mrb.OriginatorName)).FirstOrDefault(); - if (originator is not null) mrb.OriginatorID = originator.UserID; - - if (mrb.StageNo == 0) { - mrb.StageNo++; - mrb.SubmittedDate = DateTime.Now; - } - - mrb.NumberOfLotsAffected = 0; - foreach (MRBAction action in mrbActions) { - if (action is not null) { - action.MRBNumber = mrb.MRBNumber; - if (action.ActionID > 0) { - await mrbService.UpdateMRBAction(action); - } else { - await mrbService.CreateMRBAction(action); - } - - mrb.NumberOfLotsAffected += action.Quantity; - } - } - - mrbActions = await mrbService.GetMRBActionsForMRB(mrbNumberInt, true); - - await mrbService.UpdateMRB(mrb); - - await mrbService.SubmitForApproval(mrb); - - await mrbService.NotifyNewApprovals(mrb); - - if (mrb.StageNo == 1) { - StringBuilder messageBuilder = new(); - messageBuilder.Append($"MRB# {mrb.MRBNumber} [{mrb.Title}] has been submitted for approval. "); - messageBuilder.Append("You will receive an email after it has been approved."); - - MRBNotification notification = new() { - MRB = mrb, - Message = messageBuilder.ToString() - }; - - await mrbService.NotifyOriginator(notification); - } - - mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); - - nonTaskApprovals = mrbApprovals.Where(a => a.Step < 3).ToList(); - taskApprovals = mrbApprovals.Where(a => a.Step >= 3).ToList(); - - submitInProcess = false; - processing = false; - - snackbar.Add("MRB submitted for approval", Severity.Success); - } catch (Exception ex) { - submitInProcess = false; - processing = false; - snackbar.Add($"Unable to submit MRB for approval, because {ex.Message}", Severity.Error); - } - - StateHasChanged(); - } - } - - private async void ApproveMRB() { - if (!approvalInProcess && !processing) { - approvalInProcess = true; - processing = true; - try { - if (mrb is null) throw new Exception("MRB is null"); - - mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); - - if (mrbApprovals is null || mrbApprovals.Count() <= 0) - throw new Exception("there are no approvals to approve"); - if (authStateProvider.CurrentUser is null) { - navigationManager.NavigateTo("login"); - return; - } - - string? comments = ""; - - DialogParameters parameters = new DialogParameters { { x => x.comments, comments } }; - var dialog = dialogService.Show($"Approval Comments", parameters); - - var result = await dialog.Result; - - if (result.Canceled) throw new Exception("you must provide approval comments"); - - comments = result.Data.ToString(); - - IEnumerable approvals = mrbApprovals.Where(a => a.UserID == authStateProvider.CurrentUser.UserID && - a.ItemStatus == 0 && - !(a.CompletedDate < DateTimeUtilities.MAX_DT) && - a.Step == mrb.StageNo); - - foreach (Approval approval in approvals) { - approval.CompletedDate = DateTime.Now; - approval.Comments = comments is null ? "" : comments; - approval.ItemStatus = 1; - await approvalService.Approve(approval); - - IEnumerable sameRoleApprovals = mrbApprovals.Where(a => a.Step == mrb.StageNo && - !(a.UserID == authStateProvider.CurrentUser.UserID) && - a.ItemStatus == 0 && - a.SubRoleCategoryItem.ToLower().Equals(approval.SubRoleCategoryItem.ToLower()) && - !(a.CompletedDate < DateTimeUtilities.MAX_DT)); - foreach (Approval sameApp in sameRoleApprovals) { - sameApp.CompletedDate = DateTime.Now; - sameApp.Comments = comments is null ? "" : comments; - sameApp.ItemStatus = 1; - await approvalService.Approve(sameApp); - } - } - - IEnumerable remainingApprovalsInKind = mrbApprovals.Where(a => a.Step == mrb.StageNo && - a.ItemStatus == 0 && - !(a.CompletedDate < DateTimeUtilities.MAX_DT)); - - if (remainingApprovalsInKind is null || remainingApprovalsInKind.Count() <= 0) { - mrb.StageNo++; - if (mrb.StageNo == 3) mrb.ApprovalDate = DateTime.Now; - await mrbService.UpdateMRB(mrb); - - if (mrb.StageNo < 3) - SubmitMRBForApproval(); - - if (mrb.StageNo == 3) { - GenerateActionTasks(); - - StringBuilder messageBuilder = new(); - messageBuilder.Append($"MRB# {mrb.MRBNumber} [{mrb.Title}] has been approved. "); - messageBuilder.Append("You will receive an email when all actions are complete."); - - MRBNotification notification = new() { - MRB = mrb, - Message = messageBuilder.ToString() - }; - - await mrbService.NotifyOriginator(notification); - - string msg = $"MRB# {mrb.MRBNumber} [{mrb.Title}] has been approved."; - - notification = new() { - MRB = mrb, - Message = msg - }; - - await mrbService.NotifyQAPreApprover(notification); - } - } - - mrbActions = await mrbService.GetMRBActionsForMRB(mrb.MRBNumber, true); - - mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); - taskApprovals = mrbApprovals.Where(a => a.Step >= 3).ToList(); - nonTaskApprovals = mrbApprovals.Where(a => a.Step < 3).ToList(); - - if (mrb.StageNo == 3 && taskApprovals.Count() <= 0) { - mrb.StageNo++; - mrb.CloseDate = DateTime.Now; - await mrbService.UpdateMRB(mrb); - - string body = $"MRB# {mrb.MRBNumber} [{mrb.Title}] is complete."; - - MRBNotification notification = new() { - MRB = mrb, - Message = body - }; - - await mrbService.NotifyOriginator(notification); - await mrbService.NotifyQAPreApprover(notification); - - snackbar.Add("MRB complete", Severity.Success); - } - - approvalInProcess = false; - processing = false; - - StateHasChanged(); - - snackbar.Add("Successfully approved", Severity.Success); - } catch (Exception ex) { - approvalInProcess = false; - processing = false; - - snackbar.Add($"Unable to approve, because {ex.Message}", Severity.Error); - } - } - } - - private async void RecallMRB() { - if (!recallInProcess) { - recallInProcess = true; - try { - if (mrb is null) - throw new Exception("MRB cannot be null"); - - User? currentUser = authStateProvider.CurrentUser; - if (currentUser is null) { - recallInProcess = false; - snackbar.Add("You must be logged in to recall this MRB", Severity.Error); - navigationManager.NavigateTo($"login/mrb/{mrb.MRBNumber}"); - } else { - await mrbService.RecallMRB(mrb, currentUser); - mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); - nonTaskApprovals = mrbApprovals.Where(a => a.Step < 3).ToList(); - taskApprovals = mrbApprovals.Where(a => a.Step >= 3).ToList(); - } - - recallInProcess = false; - - StateHasChanged(); - - snackbar.Add("MRB successfully recalled", Severity.Success); - } catch (Exception ex) { - recallInProcess = false; - snackbar.Add($"Unable to recall MRB, because {ex.Message}", Severity.Error); - throw; - } - } - } - - private async void DenyMRB() { - if (!denialInProcess) { - denialInProcess = true; - try { - if (mrbApprovals is null || mrbApprovals.Count() <= 0) - throw new Exception("there are no approvals to deny"); - if (authStateProvider.CurrentUser is null) { - navigationManager.NavigateTo("login"); - return; - } - if (mrb is null) throw new Exception("MRB is null"); - - string? comments = ""; - - DialogParameters parameters = new DialogParameters { { x => x.comments, comments } }; - var dialog = dialogService.Show($"Denial Comments", parameters); - - var result = await dialog.Result; - - if (result.Canceled) throw new Exception("you must provide your denial comments"); - - comments = result.Data.ToString(); - - if (string.IsNullOrWhiteSpace(comments)) throw new Exception("you must provide your denial comments"); - - IEnumerable approvals = mrbApprovals.Where(a => !(a.CompletedDate < DateTimeUtilities.MAX_DT) && - a.Step == mrb.StageNo); - - foreach (Approval approval in approvals) { - approval.CompletedDate = DateTime.Now; - approval.Comments = comments is null ? "" : comments; - approval.ItemStatus = -1; - await approvalService.Deny(approval); - } - - mrb.StageNo = 0; - mrb.SubmittedDate = DateTimeUtilities.MIN_DT; - - await mrbService.UpdateMRB(mrb); - - mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); - nonTaskApprovals = mrbApprovals.Where(a => a.Step < 3).ToList(); - - StringBuilder messageBuilder = new(); - messageBuilder.AppendLine($"MRB# {mrb.MRBNumber} [{mrb.Title}] has been denied by {authStateProvider.CurrentUser.GetFullName()}. "); - messageBuilder.AppendLine(""); - messageBuilder.Append($"Comments: {comments}"); - - MRBNotification notification = new() { - MRB = mrb, - Message = messageBuilder.ToString() - }; - - await mrbService.NotifyOriginator(notification); - - mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); - - denialInProcess = false; - - StateHasChanged(); - - snackbar.Add("Successfully denied", Severity.Success); - } catch (Exception ex) { - denialInProcess = false; - - snackbar.Add($"Unable to process denial, because {ex.Message}", Severity.Error); - } - } - } - - private async void GenerateActionTasks() { - try { - if (mrb is null) throw new Exception("MRB cannot be null"); - - foreach (MRBAction action in mrbActions) { - if (action.CompletedDate == DateTimeUtilities.MAX_DT) { - action.AssignedDate = DateTime.Now; - await mrbService.UpdateMRBAction(action); - - await mrbService.GenerateActionTasks(mrb, action); - } - } - - await mrbService.NotifyNewApprovals(mrb); - } catch (Exception ex) { - snackbar.Add($"Unable to generate action tasks, because {ex.Message}", Severity.Error); - } - } - - private async void CompleteAction(MRBAction action) { - try { - if (action is null) throw new Exception("MRB action cannot be null"); - if (authStateProvider.CurrentUser is null) - throw new Exception("you must be logged in to complete this action"); - if (mrb is null) throw new Exception("MRB cannot be null"); - - string? comments = ""; - - DialogParameters parameters = new DialogParameters { - { x => x.comments, comments }, - { x => x.actionId, action.ActionID} }; - var dialog = dialogService.Show($"Completion Comments", parameters); - - var result = await dialog.Result; - - if (result.Canceled) - throw new Exception("you must provide your completion comments"); - - comments = result.Data.ToString(); - - if (string.IsNullOrWhiteSpace(comments)) - throw new Exception("you must provide your completion comments"); - - action.CompletedDate = DateTime.Now; - action.CompletedByUserID = authStateProvider.CurrentUser.UserID; - action.CompletedByUser = authStateProvider.CurrentUser; - - await mrbService.UpdateMRBAction(action); - - mrbActions = await mrbService.GetMRBActionsForMRB(action.MRBNumber, true); - - foreach (Approval approval in taskApprovals) { - if (approval.ItemStatus == 0 && approval.TaskID == action.ActionID) { - approval.Comments = comments; - await approvalService.Approve(approval); - } - } - - mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); - taskApprovals = mrbApprovals.Where(a => a.Step >= 3).ToList(); - - int outStandingTaskCount = taskApprovals.Where(a => a.CompletedDate >= DateTimeUtilities.MAX_DT).Count(); - - if (outStandingTaskCount == 0) { - mrb.StageNo++; - mrb.CloseDate = DateTime.Now; - await mrbService.UpdateMRB(mrb); - - string body = $"MRB# {mrb.MRBNumber} [{mrb.Title}] is complete."; - - MRBNotification notification = new() { - MRB = mrb, - Message = body - }; - - await mrbService.NotifyOriginator(notification); - await mrbService.NotifyQAPreApprover(notification); - - snackbar.Add("All MRB actions complete", Severity.Success); - } - - mrbActionAttachments = await mrbService.GetAllActionAttachmentsForMRB(action.MRBNumber, true); - - StateHasChanged(); - } catch (Exception ex) { - snackbar.Add($"Unable to mark action complete, because {ex.Message}", Severity.Error); - } - } - - private async void CompleteAllActions() { - if (!completeAllActionsInProcess) { - try { - completeAllActionsInProcess = true; - - if (mrbActions is null) throw new Exception("MRB actions cannot be null"); - if (authStateProvider.CurrentUser is null) - throw new Exception("you must be logged in to complete this action"); - if (mrb is null) throw new Exception("MRB cannot be null"); - - string? comments = ""; - - MRBAction? firstAction = mrbActions.FirstOrDefault(); - - if (firstAction is null) throw new Exception("there are actions to complete"); - - DialogParameters parameters = new DialogParameters { - { x => x.comments, comments }, - { x => x.actionId, firstAction.ActionID} }; - var dialog = dialogService.Show($"Completion Comments", parameters); - - var result = await dialog.Result; - - if (result.Canceled) - throw new Exception("you must provide your completion comments"); - - comments = result.Data.ToString(); - - if (string.IsNullOrWhiteSpace(comments)) - throw new Exception("you must provide your completion comments"); - - foreach (MRBAction action in mrbActions) { - action.CompletedDate = DateTime.Now; - action.CompletedByUserID = authStateProvider.CurrentUser.UserID; - action.CompletedByUser = authStateProvider.CurrentUser; - - await mrbService.UpdateMRBAction(action); - - mrbActions = await mrbService.GetMRBActionsForMRB(action.MRBNumber, true); - - mrbActionAttachments = await mrbService.GetAllActionAttachmentsForMRB(action.MRBNumber, true); - } - - foreach (Approval approval in taskApprovals) { - if (approval.ItemStatus == 0) { - approval.Comments = comments; - await approvalService.Approve(approval); - } - } - - mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); - taskApprovals = mrbApprovals.Where(a => a.Step >= 3).ToList(); - - int outStandingTaskCount = taskApprovals.Where(a => a.CompletedDate >= DateTimeUtilities.MAX_DT).Count(); - - if (outStandingTaskCount == 0) { - mrb.StageNo++; - mrb.CloseDate = DateTime.Now; - await mrbService.UpdateMRB(mrb); - - string body = $"MRB# {mrb.MRBNumber} [{mrb.Title}] is complete."; - - MRBNotification notification = new() { - MRB = mrb, - Message = body - }; - - await mrbService.NotifyOriginator(notification); - await mrbService.NotifyQAPreApprover(notification); - - snackbar.Add("All MRB actions complete", Severity.Success); - } - - completeAllActionsInProcess = false; - - StateHasChanged(); - } catch (Exception ex) { - completeAllActionsInProcess = false; - snackbar.Add($"Unable to mark action complete, because {ex.Message}", Severity.Error); - } - } - } - - private bool mrbIsReadyToSubmit() { - bool isReadyToSubmit = mrb is not null && - !(mrb.SubmittedDate > DateTimeUtilities.MIN_DT) && - mrb.MRBNumber > 0 && mrb.OriginatorID > 0 && - !string.IsNullOrWhiteSpace(mrb.OriginatorName) && - !string.IsNullOrWhiteSpace(mrb.Title) && - !string.IsNullOrWhiteSpace(mrb.Category) && - mrb.Val > 0 && - !string.IsNullOrWhiteSpace(mrb.IssueDescription) && - !string.IsNullOrWhiteSpace(mrb.Department) && - !string.IsNullOrWhiteSpace(mrb.Process) && - (!mrb.CustomerImpacted || !string.IsNullOrWhiteSpace(mrb.CustomerImpactedName)) && - (!mrb.SpecsImpacted || processEcnIsValid) && - (string.IsNullOrWhiteSpace(mrb.PCRBNo) || pcrbNoIsValid); - - if (mrb is not null && !mrb.Category.Equals("Material Transfer")) { - isReadyToSubmit = isReadyToSubmit && mrbActions is not null && mrbActions.Count() > 0; - isReadyToSubmit = isReadyToSubmit && mrb.NumberOfLotsAffected > 0; - } - - isReadyToSubmit = isReadyToSubmit && mrbAttachments is not null && mrbAttachments.Count() > 0; - - return isReadyToSubmit; - } - - private IEnumerable GetIncompleteFields() { - List incompleteFields = new(); - - if (string.IsNullOrWhiteSpace(mrb.Title)) - incompleteFields.Add("Title"); - if (string.IsNullOrWhiteSpace(mrb.IssueDescription)) - incompleteFields.Add("Description"); - if (string.IsNullOrWhiteSpace(mrb.OriginatorName)) - incompleteFields.Add("Originator"); - if (string.IsNullOrWhiteSpace(mrb.Category)) - incompleteFields.Add("Category"); - if (string.IsNullOrWhiteSpace(mrb.Department)) - incompleteFields.Add("Department"); - if (string.IsNullOrWhiteSpace(mrb.Process)) - incompleteFields.Add("Process"); - if (mrb.Val <= 0) incompleteFields.Add("Value"); - if (mrb.SpecsImpacted && (processEcnField is null || processEcnField.HasErrors)) - incompleteFields.Add("Process ECN#"); - if (mrb.CustomerImpacted && string.IsNullOrWhiteSpace(mrb.CustomerImpactedName)) - incompleteFields.Add("Affected Customer"); - - return incompleteFields; - } - - private bool currentUserIsApprover() { - if (mrbApprovals is null || authStateProvider is null) return false; - if (authStateProvider.CurrentUser is null) return false; - - IEnumerable approvalsForCurrentUser = mrbApprovals.Where(a => mrb is not null && - mrb.StageNo < 3 && - a.UserID == authStateProvider.CurrentUser.UserID && - a.ItemStatus == 0); - - if (approvalsForCurrentUser is not null && approvalsForCurrentUser.Count() > 0) return true; - - return false; - } - - private async void CreateNewAction() { - try { - MRBAction mrbAction = new() { - Action = "", - Customer = "", - LotNumber = "", - PartNumber = "", - MRBNumber = mrbNumberInt, - Quantity = 0 - }; - - DialogParameters parameters = new DialogParameters { { x => x.mrbAction, mrbAction } }; - var dialog = dialogService.Show($"New MRB Action", parameters); - - var result = await dialog.Result; - - if (!result.Canceled) { - if (mrbNumberInt > 0) { - mrbActions = await mrbService.GetMRBActionsForMRB(mrbNumberInt, true); - } else { - List actionList = mrbActions.ToList(); - actionList.Add(mrbAction); - mrbActions = actionList; - } - StateHasChanged(); - } - } catch (Exception ex) { - snackbar.Add(ex.Message, Severity.Error); - } - } - - private async void EditAction(MRBAction mrbAction) { - try { - if (mrbAction is null) - throw new ArgumentNullException("Action cannot be null"); - - var parameters = new DialogParameters { { x => x.mrbAction, mrbAction } }; - var dialog = dialogService.Show($"MRB Action {mrbAction.ActionID}", parameters); - - var result = await dialog.Result; - - if (!result.Canceled) { - if (mrbNumberInt > 0) { - mrbActions = await mrbService.GetMRBActionsForMRB(mrbNumberInt, true); - } else { - List actionList = mrbActions.ToList(); - actionList.Add(mrbAction); - mrbActions = actionList; - } - StateHasChanged(); - } - } catch (Exception ex) { - snackbar.Add(ex.Message, Severity.Error); - } - } - - private async void DeleteAction(MRBAction mrbAction) { - if (!deleteActionInProcess) { - deleteActionInProcess = true; - try { - if (mrbAction is null) - throw new ArgumentNullException("Action cannot be null"); - - await mrbService.DeleteMRBAction(mrbAction); - - List mrbActionList = mrbActions.ToList(); - mrbActionList.RemoveAll(x => x.ActionID == mrbAction.ActionID); - mrbActions = mrbActionList; - - snackbar.Add("Action successfully deleted", Severity.Success); - } catch (Exception ex) { - snackbar.Add(ex.Message, Severity.Error); - } - deleteActionInProcess = false; - StateHasChanged(); - } - } - - private bool FilterFuncForMRBActionTable(MRBAction action) => MRBActionFilterFunc(action, actionSearchString); - - private bool MRBActionFilterFunc(MRBAction action, string searchString) { - if (string.IsNullOrWhiteSpace(searchString)) - return true; - - string search = searchString.ToLower(); - if (action.Customer.ToLower().Contains(search)) - return true; - if (action.Action.ToLower().Contains(search)) - return true; - if (action.PartNumber.ToLower().Contains(search)) - return true; - if (action.LotNumber.ToLower().Contains(search)) - return true; - - return false; - } - - private async Task AddAttachments(InputFileChangeEventArgs args) { - if (!attachmentUploadInProcess) { - attachmentUploadInProcess = true; - try { - IReadOnlyList attachments = args.GetMultipleFiles(); - - if (authStateProvider.CurrentUser is not null) { - await mrbService.UploadAttachments(attachments, mrbNumberInt); - - mrbAttachments = await mrbService.GetAllAttachmentsForMRB(mrbNumberInt, true); - - attachmentUploadInProcess = false; - - StateHasChanged(); - } - } catch (Exception ex) { - attachmentUploadInProcess = false; - snackbar.Add($"Unable to upload attachments, because {ex.Message}", Severity.Error); - } - } - } - - private async void DeleteAttachment(MRBAttachment mrbAttachment) { - if (!deleteAttachmentInProcess) { - deleteAttachmentInProcess = true; - try { - if (mrbAttachment is null) - throw new ArgumentNullException("Attachment cannot be null"); - - await mrbService.DeleteAttachment(mrbAttachment); - - List mrbAttachmentList = mrbAttachments.ToList(); - mrbAttachmentList.RemoveAll(x => x.AttachmentID == mrbAttachment.AttachmentID); - mrbAttachments = mrbAttachmentList; - - snackbar.Add("Attachment successfully deleted", Severity.Success); - } catch (Exception ex) { - snackbar.Add(ex.Message, Severity.Error); - } - deleteAttachmentInProcess = false; - StateHasChanged(); - } - } - - private async Task SpecsImpactedChanged(bool newValue) { - if (mrb is not null) { - mrb.SpecsImpacted = newValue; - if (!newValue) mrb.ProcessECNNumber = 0; - StateHasChanged(); - } - } - - private async Task CustomerImpactedChanged(bool newValue) { - if (mrb is not null) { - mrb.CustomerImpacted = newValue; - if (!newValue) mrb.CustomerImpactedName = ""; - StateHasChanged(); - } - } - - private bool FilterFuncForMRBAttachmentTable(MRBAttachment attachment) => MRBAttachmentFilterFunc(attachment, attachmentSearchString); - - private bool MRBAttachmentFilterFunc(MRBAttachment attachment, string searchString) { - if (string.IsNullOrWhiteSpace(searchString)) - return true; - - string search = searchString.ToLower(); - if (attachment.FileName.ToLower().Contains(search)) - return true; - - return false; - } - - private async Task PCRBNoIsValid(string id) { - string? result = await pcrbService.IdIsValid(id); - if (result is null) pcrbNoIsValid = true; - else pcrbNoIsValid = false; - StateHasChanged(); - return result; - } - - private async Task ECNNoIsValid(int ecnNumber) { - string? result = await ecnService.ECNNumberIsValidStr(ecnNumber); - if (result is null) processEcnIsValid = true; - else processEcnIsValid = false; - StateHasChanged(); - return result; - } - - private async Task ReassignApproval(Approval approval) { - try { - if (approval is null) throw new ArgumentNullException("approval cannot be null"); - - if (approval.CompletedDate < DateTimeUtilities.MAX_DT || approval.ItemStatus != 0) - throw new ArgumentException("cannot reassign a complete approval"); - - User? selectedUser = null; - DialogParameters parameters = new DialogParameters { { x => x.selectedUser, selectedUser } }; - var dialog = dialogService.Show($"Select a new approver", parameters); - - var result = await dialog.Result; - - if (!result.Canceled) { - selectedUser = (User)result.Data; - } - - if (selectedUser is null) throw new Exception("you must select a new approver"); - - if (selectedUser.UserID == approval.UserID) - throw new Exception("new approver must be different from current approver"); - - await SetUserForApproval(approval, selectedUser); - - snackbar.Add($"Successfully reassigned approval", Severity.Success); - } catch (Exception ex) { - snackbar.Add($"Unable to reassign approval, because {ex.Message}", Severity.Error); - } - } - - private async Task SetUserForApproval(Approval approval, User user) { - if (approval is null) throw new ArgumentNullException("approval cannot be null"); - if (user is null) throw new ArgumentNullException("user cannot be null"); - - if (approval.CompletedDate < DateTimeUtilities.MAX_DT || approval.ItemStatus != 0) - throw new ArgumentException("cannot reassign a complete approval"); - - approval.UserID = user.UserID; - approval.User = user; - approval.NotifyDate = DateTimeUtilities.MIN_DT; - - await approvalService.UpdateApproval(approval); - await approvalService.GetApprovalsForIssueId(approval.IssueID, true); - - MRB mrb = await mrbService.GetMRBById(approval.IssueID, true); - await mrbService.NotifyNewApprovals(mrb); - } - - private int GetTotalActionQuantities() { - int total = 0; - foreach (MRBAction action in mrbActions) { - total += action.Quantity; - } - return total; - } - - private IEnumerable GetPartNumbers() { - HashSet partNumbers = new(); - foreach (MRBAction action in mrbActions) { - partNumbers.Add(action.PartNumber); - } - return partNumbers; - } - - private IEnumerable GetLotNumbers() { - HashSet lotNumbers = new(); - foreach (MRBAction action in mrbActions) { - lotNumbers.Add(action.LotNumber); - } - return lotNumbers; - } - - private async Task> ToolSearch(string value, CancellationToken token) { - IEnumerable matchingTools = - Tool.FqaTools.Where(t => t.Name.Contains(value, StringComparison.InvariantCultureIgnoreCase)); - HashSet toolNames = new(); - foreach (Tool tool in matchingTools) - toolNames.Add(tool.Name); - return toolNames; - } - - private void ProcessChanged(string selectedProcess) { - if (!selectedProcess.Equals(mrb.Process)) - mrb.Tool = ""; - - mrb.Process = selectedProcess; - - StateHasChanged(); - } - - private void DepartmentChanged(string selectedDepartment) { - if (!selectedDepartment.Equals(mrb.Department)) - mrb.Process = ""; - - mrb.Department = selectedDepartment; - - StateHasChanged(); - } -} \ No newline at end of file + \ No newline at end of file diff --git a/MesaFabApproval.Client/Pages/MRBSingle.razor.cs b/MesaFabApproval.Client/Pages/MRBSingle.razor.cs new file mode 100644 index 0000000..e6c6535 --- /dev/null +++ b/MesaFabApproval.Client/Pages/MRBSingle.razor.cs @@ -0,0 +1,1025 @@ +using MesaFabApproval.Client.Pages.Components; +using MesaFabApproval.Client.Services; +using MesaFabApproval.Shared.Models; +using MesaFabApproval.Shared.Utilities; + +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Forms; +using Microsoft.Extensions.Caching.Memory; + +using MudBlazor; + +using System.Text; + +namespace MesaFabApproval.Client.Pages; + +public partial class MRBSingle { + [Parameter] + public string? mrbNumber { get; set; } + [Inject] IMRBService mrbService { get; set; } + [Inject] ISnackbar snackbar { get; set; } + [Inject] IDialogService dialogService { get; set; } + [Inject] NavigationManager navigationManager { get; set; } + [Inject] MesaFabApprovalAuthStateProvider authStateProvider { get; set; } + [Inject] IUserService userService { get; set; } + [Inject] IConfiguration config { get; set; } + [Inject] IApprovalService approvalService { get; set; } + [Inject] IPCRBService pcrbService { get; set; } + [Inject] IECNService ecnService { get; set; } + [Inject] ICustomerService customerService { get; set; } + [Inject] IMemoryCache cache { get; set; } + private int mrbNumberInt = 0; + private MRB? mrb { get; set; } + private User? currentUser = null; + private int currentUserId = 0; + private IEnumerable allActiveUsers = new List(); + private IEnumerable mrbActions = new List(); + private IEnumerable mrbActionAttachments = new List(); + private IEnumerable mrbAttachments = new List(); + private IEnumerable mrbApprovals = new List(); + private IEnumerable nonTaskApprovals = new List(); + private IEnumerable taskApprovals = new List(); + private IEnumerable customerNames = new List(); + private IEnumerable partNumbers = new List(); + private IEnumerable lotNumbers = new List(); + private bool processing = false; + private bool saveInProcess = false; + private bool submitInProcess = false; + private bool deleteInProcess = false; + private bool recallInProcess = false; + private bool approvalInProcess = false; + private bool taskApprovalInProcess = false; + private bool denialInProcess = false; + private bool completeAllActionsInProcess = false; + private bool deleteActionInProcess = false; + private bool attachmentUploadInProcess = false; + private bool deleteAttachmentInProcess = false; + private string actionSearchString = ""; + private string attachmentSearchString = ""; + private string currentUrl = ""; + private MudTextField? processEcnField; + private bool processEcnIsValid = false; + private MudTextField? pcrbNoField; + private bool pcrbNoIsValid = false; + + protected override async Task OnParametersSetAsync() { + processing = true; + try { + allActiveUsers = await userService.GetAllActiveUsers(); + currentUser = authStateProvider.CurrentUser; + currentUrl = navigationManager.Uri; + + if (!string.IsNullOrWhiteSpace(mrbNumber) && Int32.TryParse(mrbNumber, out mrbNumberInt)) { + mrb = await mrbService.GetMRBById(mrbNumberInt); + if (mrb.ProcessECNNumber > 0) await ECNNoIsValid(mrb.ProcessECNNumber); + if (!string.IsNullOrWhiteSpace(mrb.PCRBNo)) await PCRBNoIsValid(mrb.PCRBNo); + mrbActions = await mrbService.GetMRBActionsForMRB(mrbNumberInt, false); + partNumbers = GetPartNumbers(); + lotNumbers = GetLotNumbers(); + mrb.NumberOfLotsAffected = GetTotalActionQuantities(); + mrbActionAttachments = await mrbService.GetAllActionAttachmentsForMRB(mrbNumberInt, false); + mrbAttachments = await mrbService.GetAllAttachmentsForMRB(mrbNumberInt, false); + + mrbApprovals = await approvalService.GetApprovalsForIssueId(mrbNumberInt, false); + + nonTaskApprovals = mrbApprovals.Where(a => a.Step < 3).ToList(); + taskApprovals = mrbApprovals.Where(a => a.Step >= 3).ToList(); + } else { + mrbNumberInt = 0; + mrbNumber = ""; + mrb = new() { Status = "Draft", StageNo = 0 }; + mrbActions = new List(); + mrbAttachments = new List(); + mrbApprovals = new List(); + nonTaskApprovals = new List(); + taskApprovals = new List(); + if (authStateProvider is not null && authStateProvider.CurrentUser is not null) { + mrb.OriginatorID = authStateProvider.CurrentUser.UserID; + mrb.OriginatorName = $"{authStateProvider.CurrentUser.FirstName} {authStateProvider.CurrentUser.LastName}"; + } + } + + if (customerNames is null || customerNames.Count() <= 0) + customerNames = (await customerService.GetAllCustomerNames()).OrderBy(c => c); + + StateHasChanged(); + } catch (Exception ex) { + snackbar.Add(ex.Message, Severity.Error); + } + processing = false; + } + + private void ReturnToAllMrbs() { + cache.Set("redirectUrl", $"mrb/all"); + navigationManager.NavigateTo("mrb/all"); + } + + private async void SaveMRB() { + if (!saveInProcess) { + try { + saveInProcess = true; + MRB initialMrb = new MRB() { + MRBNumber = mrb.MRBNumber, + Status = mrb.Status, + StageNo = 0, + NumberOfLotsAffected = 0 + }; + if (mrb is not null) { + User? originator = allActiveUsers.Where(u => $"{u.FirstName} {u.LastName}".Equals(mrb.OriginatorName)).FirstOrDefault(); + if (originator is not null) mrb.OriginatorID = originator.UserID; + + if (mrb.MRBNumber <= 0) { + await mrbService.CreateNewMRB(mrb); + mrb = await mrbService.GetMRBByTitle(mrb.Title, true); + cache.Set("redirectUrl", $"mrb/{mrb.MRBNumber}"); + } + + mrb.NumberOfLotsAffected = 0; + foreach (MRBAction action in mrbActions) { + if (action is not null) { + action.MRBNumber = mrbNumberInt; + if (action.ActionID > 0) { + await mrbService.UpdateMRBAction(action); + } else { + await mrbService.CreateMRBAction(action); + } + + mrb.NumberOfLotsAffected += action.Quantity; + } + } + + if (mrb.MRBNumber > 0) await mrbService.UpdateMRB(mrb); + + mrbNumber = mrb.MRBNumber.ToString(); + mrbNumberInt = mrb.MRBNumber; + + mrbActions = await mrbService.GetMRBActionsForMRB(mrbNumberInt, true); + } + saveInProcess = false; + StateHasChanged(); + snackbar.Add($"MRB {mrb.MRBNumber} successfully saved", Severity.Success); + + if (initialMrb.MRBNumber <= 0) + navigationManager.NavigateTo($"mrb/{mrb.MRBNumber}"); + } catch (Exception ex) { + saveInProcess = false; + snackbar.Add(ex.Message, Severity.Error); + } + saveInProcess = false; + } + } + + private async void DeleteMRB() { + if (!deleteInProcess) { + try { + bool? result = await dialogService.ShowMessageBox( + "Warning", + $"Are you sure you want to delete MRB# {mrb.MRBNumber}?", + yesText: "Yes", noText: "No" + ); + + if (result == true) { + deleteInProcess = true; + + await mrbService.DeleteMRB(mrb.MRBNumber); + + deleteInProcess = false; + + snackbar.Add("MRB successfully deleted", Severity.Success); + + navigationManager.NavigateTo("mrb/all"); + } + } catch (Exception ex) { + deleteInProcess = false; + + snackbar.Add($"Unable to delete MRB, because {ex.Message}", Severity.Error); + } + } + } + + private async void SubmitMRBForApproval() { + if (!submitInProcess && !processing) { + submitInProcess = true; + processing = true; + try { + if (mrb is null) throw new Exception("MRB cannot be null"); + + User? originator = allActiveUsers.Where(u => $"{u.FirstName} {u.LastName}".Equals(mrb.OriginatorName)).FirstOrDefault(); + if (originator is not null) mrb.OriginatorID = originator.UserID; + + if (mrb.StageNo == 0) { + mrb.StageNo++; + mrb.SubmittedDate = DateTime.Now; + } + + mrb.NumberOfLotsAffected = 0; + foreach (MRBAction action in mrbActions) { + if (action is not null) { + action.MRBNumber = mrb.MRBNumber; + if (action.ActionID > 0) { + await mrbService.UpdateMRBAction(action); + } else { + await mrbService.CreateMRBAction(action); + } + + mrb.NumberOfLotsAffected += action.Quantity; + } + } + + mrbActions = await mrbService.GetMRBActionsForMRB(mrbNumberInt, true); + + await mrbService.UpdateMRB(mrb); + + await mrbService.SubmitForApproval(mrb); + + await mrbService.NotifyNewApprovals(mrb); + + if (mrb.StageNo == 1) { + StringBuilder messageBuilder = new(); + messageBuilder.Append($"MRB# {mrb.MRBNumber} [{mrb.Title}] has been submitted for approval. "); + messageBuilder.Append("You will receive an email after it has been approved."); + + MRBNotification notification = new() { + MRB = mrb, + Message = messageBuilder.ToString() + }; + + await mrbService.NotifyOriginator(notification); + } + + mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); + + nonTaskApprovals = mrbApprovals.Where(a => a.Step < 3).ToList(); + taskApprovals = mrbApprovals.Where(a => a.Step >= 3).ToList(); + + submitInProcess = false; + processing = false; + + snackbar.Add("MRB submitted for approval", Severity.Success); + } catch (Exception ex) { + submitInProcess = false; + processing = false; + snackbar.Add($"Unable to submit MRB for approval, because {ex.Message}", Severity.Error); + } + + StateHasChanged(); + } + } + + private async void ApproveMRB() { + if (!approvalInProcess && !processing) { + approvalInProcess = true; + processing = true; + try { + if (mrb is null) throw new Exception("MRB is null"); + + mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); + + if (mrbApprovals is null || mrbApprovals.Count() <= 0) + throw new Exception("there are no approvals to approve"); + if (authStateProvider.CurrentUser is null) { + navigationManager.NavigateTo("login"); + return; + } + + string? comments = ""; + + DialogParameters parameters = new DialogParameters { { x => x.comments, comments } }; + var dialog = dialogService.Show($"Approval Comments", parameters); + + var result = await dialog.Result; + + if (result.Canceled) throw new Exception("you must provide approval comments"); + + comments = result.Data.ToString(); + + IEnumerable approvals = mrbApprovals.Where(a => a.UserID == authStateProvider.CurrentUser.UserID && + a.ItemStatus == 0 && + !(a.CompletedDate < DateTimeUtilities.MAX_DT) && + a.Step == mrb.StageNo); + + foreach (Approval approval in approvals) { + approval.CompletedDate = DateTime.Now; + approval.Comments = comments is null ? "" : comments; + approval.ItemStatus = 1; + await approvalService.Approve(approval); + + IEnumerable sameRoleApprovals = mrbApprovals.Where(a => a.Step == mrb.StageNo && + !(a.UserID == authStateProvider.CurrentUser.UserID) && + a.ItemStatus == 0 && + a.SubRoleCategoryItem.ToLower().Equals(approval.SubRoleCategoryItem.ToLower()) && + !(a.CompletedDate < DateTimeUtilities.MAX_DT)); + foreach (Approval sameApp in sameRoleApprovals) { + sameApp.CompletedDate = DateTime.Now; + sameApp.Comments = comments is null ? "" : comments; + sameApp.ItemStatus = 1; + await approvalService.Approve(sameApp); + } + } + + IEnumerable remainingApprovalsInKind = mrbApprovals.Where(a => a.Step == mrb.StageNo && + a.ItemStatus == 0 && + !(a.CompletedDate < DateTimeUtilities.MAX_DT)); + + if (remainingApprovalsInKind is null || remainingApprovalsInKind.Count() <= 0) { + mrb.StageNo++; + if (mrb.StageNo == 3) mrb.ApprovalDate = DateTime.Now; + await mrbService.UpdateMRB(mrb); + + if (mrb.StageNo < 3) { + processing = false; + SubmitMRBForApproval(); + processing = true; + } + + + processing = true; + + if (mrb.StageNo == 3) { + processing = false; + GenerateActionTasks(); + processing = true; + + StringBuilder messageBuilder = new(); + messageBuilder.Append($"MRB# {mrb.MRBNumber} [{mrb.Title}] has been approved. "); + messageBuilder.Append("You will receive an email when all actions are complete."); + + MRBNotification notification = new() { + MRB = mrb, + Message = messageBuilder.ToString() + }; + + await mrbService.NotifyOriginator(notification); + + string msg = $"MRB# {mrb.MRBNumber} [{mrb.Title}] has been approved."; + + notification = new() { + MRB = mrb, + Message = msg + }; + + await mrbService.NotifyQAPreApprover(notification); + } + } + + mrbActions = await mrbService.GetMRBActionsForMRB(mrb.MRBNumber, true); + + mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); + taskApprovals = mrbApprovals.Where(a => a.Step >= 3).ToList(); + nonTaskApprovals = mrbApprovals.Where(a => a.Step < 3).ToList(); + + if (mrb.StageNo == 3 && taskApprovals.Count() <= 0) { + mrb.StageNo++; + mrb.CloseDate = DateTime.Now; + await mrbService.UpdateMRB(mrb); + + string body = $"MRB# {mrb.MRBNumber} [{mrb.Title}] is complete."; + + MRBNotification notification = new() { + MRB = mrb, + Message = body + }; + + await mrbService.NotifyOriginator(notification); + await mrbService.NotifyQAPreApprover(notification); + + snackbar.Add("MRB complete", Severity.Success); + } + + approvalInProcess = false; + processing = false; + + StateHasChanged(); + + snackbar.Add("Successfully approved", Severity.Success); + } catch (Exception ex) { + approvalInProcess = false; + processing = false; + + snackbar.Add($"Unable to approve, because {ex.Message}", Severity.Error); + } + } + } + + private async void RecallMRB() { + if (!recallInProcess) { + recallInProcess = true; + try { + if (mrb is null) + throw new Exception("MRB cannot be null"); + + User? currentUser = authStateProvider.CurrentUser; + if (currentUser is null) { + recallInProcess = false; + snackbar.Add("You must be logged in to recall this MRB", Severity.Error); + navigationManager.NavigateTo($"login/mrb/{mrb.MRBNumber}"); + } else { + await mrbService.RecallMRB(mrb, currentUser); + mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); + nonTaskApprovals = mrbApprovals.Where(a => a.Step < 3).ToList(); + taskApprovals = mrbApprovals.Where(a => a.Step >= 3).ToList(); + } + + recallInProcess = false; + + StateHasChanged(); + + snackbar.Add("MRB successfully recalled", Severity.Success); + } catch (Exception ex) { + recallInProcess = false; + snackbar.Add($"Unable to recall MRB, because {ex.Message}", Severity.Error); + throw; + } + } + } + + private async void DenyMRB() { + if (!denialInProcess) { + denialInProcess = true; + try { + if (mrbApprovals is null || mrbApprovals.Count() <= 0) + throw new Exception("there are no approvals to deny"); + if (authStateProvider.CurrentUser is null) { + navigationManager.NavigateTo("login"); + return; + } + if (mrb is null) throw new Exception("MRB is null"); + + string? comments = ""; + + DialogParameters parameters = new DialogParameters { { x => x.comments, comments } }; + var dialog = dialogService.Show($"Denial Comments", parameters); + + var result = await dialog.Result; + + if (result.Canceled) throw new Exception("you must provide your denial comments"); + + comments = result.Data.ToString(); + + if (string.IsNullOrWhiteSpace(comments)) throw new Exception("you must provide your denial comments"); + + IEnumerable approvals = mrbApprovals.Where(a => !(a.CompletedDate < DateTimeUtilities.MAX_DT) && + a.Step == mrb.StageNo); + + foreach (Approval approval in approvals) { + approval.CompletedDate = DateTime.Now; + approval.Comments = comments is null ? "" : comments; + approval.ItemStatus = -1; + await approvalService.Deny(approval); + } + + mrb.StageNo = 0; + mrb.SubmittedDate = DateTimeUtilities.MIN_DT; + + await mrbService.UpdateMRB(mrb); + + mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); + nonTaskApprovals = mrbApprovals.Where(a => a.Step < 3).ToList(); + + StringBuilder messageBuilder = new(); + messageBuilder.AppendLine($"MRB# {mrb.MRBNumber} [{mrb.Title}] has been denied by {authStateProvider.CurrentUser.GetFullName()}. "); + messageBuilder.AppendLine(""); + messageBuilder.Append($"Comments: {comments}"); + + MRBNotification notification = new() { + MRB = mrb, + Message = messageBuilder.ToString() + }; + + await mrbService.NotifyOriginator(notification); + + mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); + + denialInProcess = false; + + StateHasChanged(); + + snackbar.Add("Successfully denied", Severity.Success); + } catch (Exception ex) { + denialInProcess = false; + + snackbar.Add($"Unable to process denial, because {ex.Message}", Severity.Error); + } + } + } + + private async void GenerateActionTasks() { + try { + if (mrb is null) throw new Exception("MRB cannot be null"); + + foreach (MRBAction action in mrbActions) { + if (action.CompletedDate == DateTimeUtilities.MAX_DT) { + action.AssignedDate = DateTime.Now; + await mrbService.UpdateMRBAction(action); + + await mrbService.GenerateActionTasks(mrb, action); + } + } + + await mrbService.NotifyNewApprovals(mrb); + } catch (Exception ex) { + snackbar.Add($"Unable to generate action tasks, because {ex.Message}", Severity.Error); + } + } + + private async void CompleteAction(MRBAction action) { + try { + if (action is null) throw new Exception("MRB action cannot be null"); + if (authStateProvider.CurrentUser is null) + throw new Exception("you must be logged in to complete this action"); + if (mrb is null) throw new Exception("MRB cannot be null"); + + string? comments = ""; + + DialogParameters parameters = new DialogParameters { + { x => x.comments, comments }, + { x => x.actionId, action.ActionID} }; + var dialog = dialogService.Show($"Completion Comments", parameters); + + var result = await dialog.Result; + + if (result.Canceled) + throw new Exception("you must provide your completion comments"); + + comments = result.Data.ToString(); + + if (string.IsNullOrWhiteSpace(comments)) + throw new Exception("you must provide your completion comments"); + + action.CompletedDate = DateTime.Now; + action.CompletedByUserID = authStateProvider.CurrentUser.UserID; + action.CompletedByUser = authStateProvider.CurrentUser; + + await mrbService.UpdateMRBAction(action); + + mrbActions = await mrbService.GetMRBActionsForMRB(action.MRBNumber, true); + + foreach (Approval approval in taskApprovals) { + if (approval.ItemStatus == 0 && approval.TaskID == action.ActionID) { + approval.Comments = comments; + await approvalService.Approve(approval); + } + } + + mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); + taskApprovals = mrbApprovals.Where(a => a.Step >= 3).ToList(); + + int outStandingTaskCount = taskApprovals.Where(a => a.CompletedDate >= DateTimeUtilities.MAX_DT).Count(); + + if (outStandingTaskCount == 0) { + mrb.StageNo++; + mrb.CloseDate = DateTime.Now; + await mrbService.UpdateMRB(mrb); + + string body = $"MRB# {mrb.MRBNumber} [{mrb.Title}] is complete."; + + MRBNotification notification = new() { + MRB = mrb, + Message = body + }; + + await mrbService.NotifyOriginator(notification); + await mrbService.NotifyQAPreApprover(notification); + + snackbar.Add("All MRB actions complete", Severity.Success); + } + + mrbActionAttachments = await mrbService.GetAllActionAttachmentsForMRB(action.MRBNumber, true); + + StateHasChanged(); + } catch (Exception ex) { + snackbar.Add($"Unable to mark action complete, because {ex.Message}", Severity.Error); + } + } + + private async void CompleteAllActions() { + if (!completeAllActionsInProcess) { + try { + completeAllActionsInProcess = true; + + if (mrbActions is null) throw new Exception("MRB actions cannot be null"); + if (authStateProvider.CurrentUser is null) + throw new Exception("you must be logged in to complete this action"); + if (mrb is null) throw new Exception("MRB cannot be null"); + + string? comments = ""; + + MRBAction? firstAction = mrbActions.FirstOrDefault(); + + if (firstAction is null) throw new Exception("there are actions to complete"); + + DialogParameters parameters = new DialogParameters { + { x => x.comments, comments }, + { x => x.actionId, firstAction.ActionID} }; + var dialog = dialogService.Show($"Completion Comments", parameters); + + var result = await dialog.Result; + + if (result.Canceled) + throw new Exception("you must provide your completion comments"); + + comments = result.Data.ToString(); + + if (string.IsNullOrWhiteSpace(comments)) + throw new Exception("you must provide your completion comments"); + + foreach (MRBAction action in mrbActions) { + action.CompletedDate = DateTime.Now; + action.CompletedByUserID = authStateProvider.CurrentUser.UserID; + action.CompletedByUser = authStateProvider.CurrentUser; + + await mrbService.UpdateMRBAction(action); + + mrbActions = await mrbService.GetMRBActionsForMRB(action.MRBNumber, true); + + mrbActionAttachments = await mrbService.GetAllActionAttachmentsForMRB(action.MRBNumber, true); + } + + foreach (Approval approval in taskApprovals) { + if (approval.ItemStatus == 0) { + approval.Comments = comments; + await approvalService.Approve(approval); + } + } + + mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true); + taskApprovals = mrbApprovals.Where(a => a.Step >= 3).ToList(); + + int outStandingTaskCount = taskApprovals.Where(a => a.CompletedDate >= DateTimeUtilities.MAX_DT).Count(); + + if (outStandingTaskCount == 0) { + mrb.StageNo++; + mrb.CloseDate = DateTime.Now; + await mrbService.UpdateMRB(mrb); + + string body = $"MRB# {mrb.MRBNumber} [{mrb.Title}] is complete."; + + MRBNotification notification = new() { + MRB = mrb, + Message = body + }; + + await mrbService.NotifyOriginator(notification); + await mrbService.NotifyQAPreApprover(notification); + + snackbar.Add("All MRB actions complete", Severity.Success); + } + + completeAllActionsInProcess = false; + + StateHasChanged(); + } catch (Exception ex) { + completeAllActionsInProcess = false; + snackbar.Add($"Unable to mark action complete, because {ex.Message}", Severity.Error); + } + } + } + + private bool mrbIsReadyToSubmit() { + bool isReadyToSubmit = mrb is not null && + !(mrb.SubmittedDate > DateTimeUtilities.MIN_DT) && + mrb.MRBNumber > 0 && mrb.OriginatorID > 0 && + !string.IsNullOrWhiteSpace(mrb.OriginatorName) && + !string.IsNullOrWhiteSpace(mrb.Title) && + !string.IsNullOrWhiteSpace(mrb.Category) && + mrb.Val > 0 && + !string.IsNullOrWhiteSpace(mrb.IssueDescription) && + !string.IsNullOrWhiteSpace(mrb.Department) && + !string.IsNullOrWhiteSpace(mrb.Process) && + (!mrb.CustomerImpacted || !string.IsNullOrWhiteSpace(mrb.CustomerImpactedName)) && + (!mrb.SpecsImpacted || processEcnIsValid) && + (string.IsNullOrWhiteSpace(mrb.PCRBNo) || pcrbNoIsValid); + + if (mrb is not null && !mrb.Category.Equals("Material Transfer")) { + isReadyToSubmit = isReadyToSubmit && mrbActions is not null && mrbActions.Count() > 0; + isReadyToSubmit = isReadyToSubmit && mrb.NumberOfLotsAffected > 0; + } + + isReadyToSubmit = isReadyToSubmit && mrbAttachments is not null && mrbAttachments.Count() > 0; + + return isReadyToSubmit; + } + + private IEnumerable GetIncompleteFields() { + List incompleteFields = new(); + + if (string.IsNullOrWhiteSpace(mrb.Title)) + incompleteFields.Add("Title"); + if (string.IsNullOrWhiteSpace(mrb.IssueDescription)) + incompleteFields.Add("Description"); + if (string.IsNullOrWhiteSpace(mrb.OriginatorName)) + incompleteFields.Add("Originator"); + if (string.IsNullOrWhiteSpace(mrb.Category)) + incompleteFields.Add("Category"); + if (string.IsNullOrWhiteSpace(mrb.Department)) + incompleteFields.Add("Department"); + if (string.IsNullOrWhiteSpace(mrb.Process)) + incompleteFields.Add("Process"); + if (mrb.Val <= 0) incompleteFields.Add("Value"); + if (mrb.SpecsImpacted && (processEcnField is null || processEcnField.HasErrors)) + incompleteFields.Add("Process ECN#"); + if (mrb.CustomerImpacted && string.IsNullOrWhiteSpace(mrb.CustomerImpactedName)) + incompleteFields.Add("Affected Customer"); + + return incompleteFields; + } + + private bool currentUserIsApprover() { + if (mrbApprovals is null || authStateProvider is null) return false; + if (authStateProvider.CurrentUser is null) return false; + + IEnumerable approvalsForCurrentUser = mrbApprovals.Where(a => mrb is not null && + mrb.StageNo < 3 && + a.UserID == authStateProvider.CurrentUser.UserID && + a.ItemStatus == 0); + + if (approvalsForCurrentUser is not null && approvalsForCurrentUser.Count() > 0) return true; + + return false; + } + + private async void CreateNewAction() { + try { + MRBAction mrbAction = new() { + Action = "", + Customer = "", + LotNumber = "", + PartNumber = "", + MRBNumber = mrbNumberInt, + Quantity = 0 + }; + + DialogParameters parameters = new DialogParameters { { x => x.mrbAction, mrbAction } }; + var dialog = dialogService.Show($"New MRB Action", parameters); + + var result = await dialog.Result; + + if (!result.Canceled) { + if (mrbNumberInt > 0) { + mrbActions = await mrbService.GetMRBActionsForMRB(mrbNumberInt, true); + } else { + List actionList = mrbActions.ToList(); + actionList.Add(mrbAction); + mrbActions = actionList; + } + StateHasChanged(); + } + } catch (Exception ex) { + snackbar.Add(ex.Message, Severity.Error); + } + } + + private async void EditAction(MRBAction mrbAction) { + try { + if (mrbAction is null) + throw new ArgumentNullException("Action cannot be null"); + + var parameters = new DialogParameters { { x => x.mrbAction, mrbAction } }; + var dialog = dialogService.Show($"MRB Action {mrbAction.ActionID}", parameters); + + var result = await dialog.Result; + + if (!result.Canceled) { + if (mrbNumberInt > 0) { + mrbActions = await mrbService.GetMRBActionsForMRB(mrbNumberInt, true); + } else { + List actionList = mrbActions.ToList(); + actionList.Add(mrbAction); + mrbActions = actionList; + } + StateHasChanged(); + } + } catch (Exception ex) { + snackbar.Add(ex.Message, Severity.Error); + } + } + + private async void DeleteAction(MRBAction mrbAction) { + if (!deleteActionInProcess) { + deleteActionInProcess = true; + try { + if (mrbAction is null) + throw new ArgumentNullException("Action cannot be null"); + + await mrbService.DeleteMRBAction(mrbAction); + + List mrbActionList = mrbActions.ToList(); + mrbActionList.RemoveAll(x => x.ActionID == mrbAction.ActionID); + mrbActions = mrbActionList; + + snackbar.Add("Action successfully deleted", Severity.Success); + } catch (Exception ex) { + snackbar.Add(ex.Message, Severity.Error); + } + deleteActionInProcess = false; + StateHasChanged(); + } + } + + private bool FilterFuncForMRBActionTable(MRBAction action) => MRBActionFilterFunc(action, actionSearchString); + + private bool MRBActionFilterFunc(MRBAction action, string searchString) { + if (string.IsNullOrWhiteSpace(searchString)) + return true; + + string search = searchString.ToLower(); + if (action.Customer.ToLower().Contains(search)) + return true; + if (action.Action.ToLower().Contains(search)) + return true; + if (action.PartNumber.ToLower().Contains(search)) + return true; + if (action.LotNumber.ToLower().Contains(search)) + return true; + + return false; + } + + private async Task AddAttachments(InputFileChangeEventArgs args) { + if (!attachmentUploadInProcess) { + attachmentUploadInProcess = true; + try { + IReadOnlyList attachments = args.GetMultipleFiles(); + + if (authStateProvider.CurrentUser is not null) { + await mrbService.UploadAttachments(attachments, mrbNumberInt); + + mrbAttachments = await mrbService.GetAllAttachmentsForMRB(mrbNumberInt, true); + + attachmentUploadInProcess = false; + + StateHasChanged(); + } + } catch (Exception ex) { + attachmentUploadInProcess = false; + snackbar.Add($"Unable to upload attachments, because {ex.Message}", Severity.Error); + } + } + } + + private async void DeleteAttachment(MRBAttachment mrbAttachment) { + if (!deleteAttachmentInProcess) { + deleteAttachmentInProcess = true; + try { + if (mrbAttachment is null) + throw new ArgumentNullException("Attachment cannot be null"); + + await mrbService.DeleteAttachment(mrbAttachment); + + List mrbAttachmentList = mrbAttachments.ToList(); + mrbAttachmentList.RemoveAll(x => x.AttachmentID == mrbAttachment.AttachmentID); + mrbAttachments = mrbAttachmentList; + + snackbar.Add("Attachment successfully deleted", Severity.Success); + } catch (Exception ex) { + snackbar.Add(ex.Message, Severity.Error); + } + deleteAttachmentInProcess = false; + StateHasChanged(); + } + } + + private async Task SpecsImpactedChanged(bool newValue) { + if (mrb is not null) { + mrb.SpecsImpacted = newValue; + if (!newValue) mrb.ProcessECNNumber = 0; + StateHasChanged(); + } + } + + private async Task CustomerImpactedChanged(bool newValue) { + if (mrb is not null) { + mrb.CustomerImpacted = newValue; + if (!newValue) mrb.CustomerImpactedName = ""; + StateHasChanged(); + } + } + + private bool FilterFuncForMRBAttachmentTable(MRBAttachment attachment) => MRBAttachmentFilterFunc(attachment, attachmentSearchString); + + private bool MRBAttachmentFilterFunc(MRBAttachment attachment, string searchString) { + if (string.IsNullOrWhiteSpace(searchString)) + return true; + + string search = searchString.ToLower(); + if (attachment.FileName.ToLower().Contains(search)) + return true; + + return false; + } + + private async Task PCRBNoIsValid(string id) { + string? result = await pcrbService.IdIsValid(id); + if (result is null) pcrbNoIsValid = true; + else pcrbNoIsValid = false; + StateHasChanged(); + return result; + } + + private async Task ECNNoIsValid(int ecnNumber) { + string? result = await ecnService.ECNNumberIsValidStr(ecnNumber); + if (result is null) processEcnIsValid = true; + else processEcnIsValid = false; + StateHasChanged(); + return result; + } + + private async Task ReassignApproval(Approval approval) { + try { + if (approval is null) throw new ArgumentNullException("approval cannot be null"); + + if (approval.CompletedDate < DateTimeUtilities.MAX_DT || approval.ItemStatus != 0) + throw new ArgumentException("cannot reassign a complete approval"); + + User? selectedUser = null; + DialogParameters parameters = new DialogParameters { { x => x.selectedUser, selectedUser } }; + var dialog = dialogService.Show($"Select a new approver", parameters); + + var result = await dialog.Result; + + if (!result.Canceled) { + selectedUser = (User)result.Data; + } + + if (selectedUser is null) throw new Exception("you must select a new approver"); + + if (selectedUser.UserID == approval.UserID) + throw new Exception("new approver must be different from current approver"); + + await SetUserForApproval(approval, selectedUser); + + snackbar.Add($"Successfully reassigned approval", Severity.Success); + } catch (Exception ex) { + snackbar.Add($"Unable to reassign approval, because {ex.Message}", Severity.Error); + } + } + + private async Task SetUserForApproval(Approval approval, User user) { + if (approval is null) throw new ArgumentNullException("approval cannot be null"); + if (user is null) throw new ArgumentNullException("user cannot be null"); + + if (approval.CompletedDate < DateTimeUtilities.MAX_DT || approval.ItemStatus != 0) + throw new ArgumentException("cannot reassign a complete approval"); + + approval.UserID = user.UserID; + approval.User = user; + approval.NotifyDate = DateTimeUtilities.MIN_DT; + + await approvalService.UpdateApproval(approval); + await approvalService.GetApprovalsForIssueId(approval.IssueID, true); + + MRB mrb = await mrbService.GetMRBById(approval.IssueID, true); + await mrbService.NotifyNewApprovals(mrb); + } + + private int GetTotalActionQuantities() { + int total = 0; + foreach (MRBAction action in mrbActions) { + total += action.Quantity; + } + return total; + } + + private IEnumerable GetPartNumbers() { + HashSet partNumbers = new(); + foreach (MRBAction action in mrbActions) { + partNumbers.Add(action.PartNumber); + } + return partNumbers; + } + + private IEnumerable GetLotNumbers() { + HashSet lotNumbers = new(); + foreach (MRBAction action in mrbActions) { + lotNumbers.Add(action.LotNumber); + } + return lotNumbers; + } + + private async Task> ToolSearch(string value) { + IEnumerable matchingTools = + Tool.FqaTools.Where(t => t.Name.Contains(value, StringComparison.InvariantCultureIgnoreCase)); + HashSet toolNames = new(); + foreach (Tool tool in matchingTools) + toolNames.Add(tool.Name); + return toolNames; + } + + private void ProcessChanged(string selectedProcess) { + if (!selectedProcess.Equals(mrb.Process)) + mrb.Tool = ""; + + mrb.Process = selectedProcess; + + StateHasChanged(); + } + + private void DepartmentChanged(string selectedDepartment) { + if (!selectedDepartment.Equals(mrb.Department)) + mrb.Process = ""; + + mrb.Department = selectedDepartment; + + StateHasChanged(); + } +}