2024-07-11 09:11:01 -07:00

996 lines
43 KiB
Plaintext

@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
@if (mrbNumber is not null) {
<PageTitle>MRB @mrbNumber</PageTitle>
<MudPaper Class="p-2 m-2 d-flex flex-row justify-content-between">
<MudIconButton Icon="@Icons.Material.Filled.ChevronLeft"
Variant="Variant.Outlined"
Color="Color.Dark"
OnClick="@ReturnToAllMrbs"
Size="Size.Large" />
<MudText Typo="Typo.h3" Align="Align.Center">MRB @mrbNumber</MudText>
<MudPaper Height="100%" Width="0.1%" Square="true" />
</MudPaper>
}
@if (mrb is not null) {
<MudTimeline Class="mt-2 pt-2" TimelineOrientation="TimelineOrientation.Horizontal"
TimelinePosition="TimelinePosition.Bottom">
@for (int i = 0; i < MRB.Stages.Length; i++) {
Color color;
if (mrb.StageNo > i || mrb.StageNo == (MRB.Stages.Length - 1)) {
color = Color.Success;
} else if (mrb.StageNo == i) {
color = Color.Info;
} else {
color = Color.Dark;
}
string stageName = MRB.Stages[i];
<MudTimelineItem Color="@color" Variant="Variant.Filled">
<MudText Align="Align.Center" Color="@color">@stageName</MudText>
</MudTimelineItem>
}
</MudTimeline>
bool mrbIsSubmitted = mrb.SubmittedDate > DateTime.MinValue;
bool mrbReadyToSubmit = mrbIsReadyToSubmit();
bool userIsApprover = currentUserIsApprover();
if (!mrbIsSubmitted || (!mrbIsSubmitted && mrbReadyToSubmit) || (mrbIsSubmitted && userIsApprover))
{
<MudPaper Outlined="true"
Class="p-2 m-2 d-flex flex-wrap gap-3 justify-content-center align-content-center"
Elevation="10">
@if (!mrbIsSubmitted)
{
<MudButton Variant="Variant.Filled"
Color="Color.Tertiary"
OnClick=SaveMRB>
@if (saveInProcess)
{
<MudProgressCircular Class="m-1" Size="Size.Small" Indeterminate="true" />
<MudText>Processing</MudText>
}
else
{
<MudText>Save</MudText>
}
</MudButton>
}
@if (!mrbIsSubmitted && mrbReadyToSubmit)
{
<MudButton Variant="Variant.Filled"
Color="Color.Tertiary"
OnClick=SubmitMRBForApproval>
@if (submitInProcess)
{
<MudProgressCircular Class="m-1" Size="Size.Small" Indeterminate="true" />
<MudText>Processing</MudText>
}
else
{
<MudText>Submit for Approval</MudText>
}
</MudButton>
}
@if (mrbIsSubmitted && userIsApprover)
{
<MudButton Variant="Variant.Filled"
Color="Color.Tertiary"
OnClick=ApproveMRB>
Approve
</MudButton>
<MudButton Variant="Variant.Filled"
Color="Color.Tertiary"
OnClick=DenyMRB>
Deny
</MudButton>
}
</MudPaper>
}
<MudPaper Outlined="true"
Class="p-2 m-2 d-flex flex-wrap gap-3 justify-content-center align-content-start"
Elevation="10">
<MudTextField @bind-Value=mrb.MRBNumber
Text="@mrb.MRBNumber.ToString()"
T="int"
Disabled="true"
Label="MRB#"
Variant="Variant.Outlined" />
<MudTextField @bind-Value=mrb.Title
Text="@mrb.Title"
Disabled="@(mrb.SubmittedDate > DateTime.MinValue)"
T="string"
AutoGrow
Variant="Variant.Outlined"
Label="Title" />
<MudTextField Disabled="true"
T="string"
Value="@DateTimeUtilities.GetDateAsStringMinDefault(mrb.SubmittedDate)"
Label="Submit Date"
Variant="Variant.Outlined" />
<MudTextField Disabled="true"
Label="Approval Date"
Variant="Variant.Outlined"
Value="@DateTimeUtilities.GetDateAsStringMaxDefault(mrb.ApprovalDate)"
T="string" />
<MudTextField Disabled="true"
Label="Closed Date"
Variant="Variant.Outlined"
Value="@DateTimeUtilities.GetDateAsStringMaxDefault(mrb.CloseDate)"
T="string" />
@if (mrb is not null && mrb.CancelDate < DateTime.MaxValue) {
<MudTextField Disabled="true"
Label="Canceled Date"
Variant="Variant.Outlined"
Value="@DateTimeUtilities.GetDateAsStringMaxDefault(mrb.CancelDate)"
T="string" />
}
<MudTextField Disabled="@(mrb.SubmittedDate > DateTime.MinValue)"
@bind-Value=mrb.IssueDescription
Text="@mrb.IssueDescription"
AutoGrow
Variant="Variant.Outlined"
Label="Description" />
<MudSelect T="string"
Label="Originator"
Variant="Variant.Outlined"
AnchorOrigin="Origin.BottomCenter"
Disabled=@(mrb.SubmittedDate > DateTime.MinValue)
@bind-Value=mrb.OriginatorName
Text="@mrb.OriginatorName">
@foreach (User user in allActiveUsers) {
<MudSelectItem T="string" Value="@($"{user.FirstName} {user.LastName}")" />
}
</MudSelect>
<MudSelect T="string"
Label="Department"
Variant="Variant.Outlined"
AnchorOrigin="Origin.BottomCenter"
Disabled=@(mrb.SubmittedDate > DateTime.MinValue)
@bind-Value=mrb.Department
Text="@mrb.Department">
<MudSelectItem Value="@("Production")" />
<MudSelectItem Value="@("Engineering")" />
<MudSelectItem Value="@("Materials")" />
<MudSelectItem Value="@("Facilities")" />
<MudSelectItem Value="@("Maintenance")" />
<MudSelectItem Value="@("Quality")" />
</MudSelect>
<MudSelect T="string"
Label="Process"
Variant="Variant.Outlined"
AnchorOrigin="Origin.BottomCenter"
Disabled=@(mrb.SubmittedDate > DateTime.MinValue)
@bind-Value=mrb.Process
Text="@mrb.Process">
<MudSelectItem Value="@("Receiving")" />
<MudSelectItem Value="@("Kitting")" />
<MudSelectItem Value="@("Cleans")" />
<MudSelectItem Value="@("Reactor")" />
<MudSelectItem Value="@("Metrology")" />
<MudSelectItem Value="@("Final QA")" />
<MudSelectItem Value="@("Packaging")" />
<MudSelectItem Value="@("Shipping")" />
<MudSelectItem Value="@("N/A")" />
</MudSelect>
<MudTextField Disabled="@(mrb.SubmittedDate > DateTime.MinValue)"
@bind-Value=mrb.NumberOfLotsAffected
Text="@mrb.NumberOfLotsAffected.ToString()"
Variant="Variant.Outlined"
Label="Total Quantity" />
<MudTextField Disabled="@(mrb.SubmittedDate > DateTime.MinValue)"
@bind-Value=mrb.Val
Text="@mrb.Val"
Variant="Variant.Outlined"
Label="Value" />
<MudTextField Disabled="@(mrb.SubmittedDate > DateTime.MinValue)"
@bind-Value=mrb.RMANo
Text="@mrb.RMANo.ToString()"
Variant="Variant.Outlined"
Label="RMA#" />
<MudPaper Outlined="true" Class="p-2">
<MudCheckBox Disabled="@(mrb.SubmittedDate > DateTime.MinValue)"
@bind-Value=mrb.CustomerImpacted
Color="Color.Tertiary"
Label="Customer Impacted?"
LabelPosition="LabelPosition.Start" />
</MudPaper>
<MudTextField Disabled="@(mrb.SubmittedDate > DateTime.MinValue)"
@bind-Value=mrb.PCRBNo
Text="@mrb.PCRBNo.ToString()"
Variant="Variant.Outlined"
Label="PCRB#" />
<MudPaper Outlined="true" Class="p-2">
<MudCheckBox Disabled="@(mrb.SubmittedDate > DateTime.MinValue)"
@bind-Value=mrb.SpecsImpacted
Color="Color.Tertiary"
Label="Specs Impacted?"
LabelPosition="LabelPosition.Start" />
</MudPaper>
</MudPaper>
}
@if (mrb is not null && mrb.MRBNumber > 0) {
<MudPaper Outlined="true"
Class="p-2 m-2 d-flex flex-column justify-center">
<MudText Typo="Typo.h4" Align="Align.Center">Supporting Documents</MudText>
<MudDivider DividerType="DividerType.Middle" Class="my-2" />
@if (!(mrb.SubmittedDate > DateTime.MinValue)) {
<MudFileUpload T="IBrowserFile" OnFilesChanged="AddAttachments" Class="centered-upload">
<ButtonTemplate>
<MudButton HtmlTag="label"
Variant="Variant.Filled"
Color="Color.Tertiary"
style="margin: auto;"
StartIcon="@Icons.Material.Filled.AttachFile"
for="@context.Id">
Upload Document
</MudButton>
</ButtonTemplate>
</MudFileUpload>
}
@if (mrbAttachments is not null) {
<MudTable Items="@mrbAttachments"
Class="m-2"
Striped="true"
Filter="new Func<MRBAttachment, bool>(FilterFuncForMRBAttachmentTable)"
SortLabel="Sort By"
Hover="true">
<ToolBarContent>
<MudSpacer />
<MudTextField @bind-Value="attachmentSearchString"
Placeholder="Search"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.Search"
IconSize="Size.Medium"
Class="mt-0" />
</ToolBarContent>
<HeaderContent>
<MudTh>
<MudTableSortLabel SortBy="new Func<MRBAttachment, object>(x=>x.FileName)">
Name
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel InitialDirection="SortDirection.Descending" SortBy="new Func<MRBAttachment,object>(x=>x.UploadDate)">
Upload Date
</MudTableSortLabel>
</MudTh>
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="Name">
<a href="@(@$"{config["FabApprovalApiBaseUrl"]}/mrb/attachmentFile?path={context.Path}&fileName={context.FileName}")"
download="@(context.FileName)"
target="_top">
@context.FileName
</a>
</MudTd>
<MudTd DataLabel="Upload Date">@context.UploadDate.ToString("yyyy-MM-dd HH:mm")</MudTd>
@if (mrb is not null && !(mrb.SubmittedDate > DateTime.MinValue)) {
<MudTd>
<MudButton Color="Color.Secondary"
Variant="Variant.Filled"
OnClick="@((e) => DeleteAttachment(context))">
@if (deleteActionInProcess) {
<MudProgressCircular Class="m-1" Size="Size.Small" Indeterminate="true" />
<MudText>Deleting</MudText>
} else {
<MudText>Delete</MudText>
}
</MudButton>
</MudTd>
}
</RowTemplate>
</MudTable>
}
<MudPaper Outlined="true"
Class="p-2 m-2 d-flex flex-column justify-center">
<MudText Typo="Typo.h4" Align="Align.Center">Actions</MudText>
<MudDivider DividerType="DividerType.Middle" Class="my-2" />
@if (!(mrb.SubmittedDate > DateTime.MinValue)) {
<MudButton Variant="Variant.Filled"
Color="Color.Tertiary"
Class="object-center flex-grow-0"
Style="max-width: 200px; margin: auto;"
OnClick="@((e) => CreateNewAction())">
Create New Action
</MudButton>
}
@if (mrbActions is not null) {
<MudTable Items="@mrbActions"
Class="m-2"
Striped="true"
Filter="new Func<MRBAction, bool>(FilterFuncForMRBActionTable)"
SortLabel="Sort By"
Hover="true">
<ToolBarContent>
<MudSpacer />
<MudTextField @bind-Value="actionSearchString"
Placeholder="Search"
Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.Search"
IconSize="Size.Medium"
Class="mt-0" />
</ToolBarContent>
<HeaderContent>
<MudTh>
<MudTableSortLabel InitialDirection="SortDirection.Ascending" SortBy="new Func<MRBAction,object>(x=>x.Action)">
Action
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel SortBy="new Func<MRBAction,object>(x=>x.Customer)">
Customer
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel SortBy="new Func<MRBAction,object>(x=>x.Quantity)">
Qty
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel SortBy="new Func<MRBAction,object>(x=>x.PartNumber)">
Part Number
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel SortBy="new Func<MRBAction,object>(x=>x.LotNumber)">
Batch Number / Lot Number
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel SortBy="new Func<MRBAction, object>(x=>x.AssignedDate)">
Assigned Date
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel SortBy="new Func<MRBAction, object>(x=>x.CompletedDate)">
Completed Date
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel InitialDirection="SortDirection.Ascending" SortBy="new Func<MRBAction,object>(x=>x.CompletedByUser?.GetFullName() ??
x.CompletedByUserID.ToString())">
Completed By
</MudTableSortLabel>
</MudTh>
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="Action">@context.Action</MudTd>
<MudTd DataLabel="Customer">@context.Customer</MudTd>
<MudTd DataLabel="Qty">@context.Quantity</MudTd>
<MudTd DataLabel="Part Number">@context.PartNumber</MudTd>
<MudTd DataLabel="Batch Number / Lot Number">@context.LotNumber</MudTd>
<MudTd DataLabel="Assigned Date">@DateTimeUtilities.GetDateAsStringMinDefault(context.AssignedDate)</MudTd>
<MudTd DataLabel="Completed Date">@DateTimeUtilities.GetDateAsStringMaxDefault(context.CompletedDate)</MudTd>
<MudTd DataLabel="Completed By">@context.CompletedByUser?.GetFullName()</MudTd>
@if (mrb is not null && !(mrb.SubmittedDate > DateTime.MinValue)) {
<MudTd>
<MudButton Variant="Variant.Filled"
Color="Color.Tertiary"
OnClick="@((e) => EditAction(context))">
Edit
</MudButton>
<MudButton Color="Color.Secondary"
Variant="Variant.Filled"
OnClick="@((e) => DeleteAction(context))">
@if (deleteActionInProcess) {
<MudProgressCircular Class="m-1" Size="Size.Small" Indeterminate="true" />
<MudText>Deleting</MudText>
} else {
<MudText>Delete</MudText>
}
</MudButton>
</MudTd>
}
@if (currentUser is not null && taskApprovals.Where(t => t.UserID == currentUser.UserID && t.TaskID == context.ActionID).ToList().Count() > 0 &&
context.CompletedDate >= DateTime.MaxValue) {
<MudTd>
<MudButton Variant="Variant.Filled"
Color="Color.Tertiary"
OnClick="@((e) => CompleteAction(context))">
Mark Complete
</MudButton>
</MudTd>
}
</RowTemplate>
<PagerContent>
<MudTablePager />
</PagerContent>
</MudTable>
}
</MudPaper>
<MudPaper Outlined="true"
Class="p-2 m-2 d-flex flex-column justify-center">
<MudText Typo="Typo.h4" Align="Align.Center">Approvals</MudText>
@if (nonTaskApprovals is not null) {
<MudTable Items="@nonTaskApprovals"
Class="m-2"
Striped="true">
<HeaderContent>
<MudTh>Role</MudTh>
<MudTh>Approver Name</MudTh>
<MudTh>Status</MudTh>
<MudTh>Disposition Date</MudTh>
<MudTh>Comments</MudTh>
</HeaderContent>
<RowTemplate>
<MudTd DataLabel="Role">@context.SubRoleCategoryItem</MudTd>
<MudTd DataLabel="Approver Name">@context.User?.GetFullName()</MudTd>
<MudTd DataLabel="Status">@context.StatusMessage</MudTd>
<MudTd DataLabel="Disposition Date">@DateTimeUtilities.GetDateAsStringMaxDefault(context.CompletedDate)</MudTd>
<MudTd DataLabel="Comments">@context.Comments</MudTd>
</RowTemplate>
</MudTable>
}
</MudPaper>
</MudPaper>
}
<MudOverlay Visible=processing DarkBackground="true" AutoClose="false">
<MudProgressCircular Color="Color.Info" Size="Size.Large" Indeterminate="true" />
</MudOverlay>
@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<User> allActiveUsers = new List<User>();
private IEnumerable<MRBAction> mrbActions = new List<MRBAction>();
private IEnumerable<MRBAttachment> mrbAttachments = new List<MRBAttachment>();
private IEnumerable<Approval> mrbApprovals = new List<Approval>();
private IEnumerable<Approval> nonTaskApprovals = new List<Approval>();
private IEnumerable<Approval> taskApprovals = new List<Approval>();
private bool processing = false;
private bool saveInProcess = false;
private bool submitInProcess = false;
private bool approvalInProcess = false;
private bool taskApprovalInProcess = false;
private bool denialInProcess = false;
private bool deleteActionInProcess = false;
private bool deleteAttachmentInProcess = false;
private string actionSearchString = "";
private string attachmentSearchString = "";
private string currentUrl = "";
protected override async Task OnParametersSetAsync() {
processing = true;
try {
if (allActiveUsers is null) allActiveUsers = await userService.GetAllActiveUsers();
if (authStateProvider is not null) currentUser = authStateProvider.CurrentUser;
if (navigationManager is not null) currentUrl = navigationManager.Uri;
if (!string.IsNullOrWhiteSpace(mrbNumber) && Int32.TryParse(mrbNumber, out mrbNumberInt)) {
mrb = await mrbService.GetMRBById(mrbNumberInt);
mrbActions = await mrbService.GetMRBActionsForMRB(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<MRBAction>();
mrbAttachments = new List<MRBAttachment>();
mrbApprovals = new List<Approval>();
nonTaskApprovals = new List<Approval>();
taskApprovals = new List<Approval>();
if (authStateProvider is not null && authStateProvider.CurrentUser is not null) {
mrb.OriginatorID = authStateProvider.CurrentUser.UserID;
mrb.OriginatorName = $"{authStateProvider.CurrentUser.FirstName} {authStateProvider.CurrentUser.LastName}";
}
}
} 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() {
try {
saveInProcess = true;
MRB initialMrb = new MRB() {
MRBNumber = mrb.MRBNumber,
Status = mrb.Status,
StageNo = 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}");
} else {
await mrbService.UpdateMRB(mrb);
}
mrbNumber = mrb.MRBNumber.ToString();
mrbNumberInt = mrb.MRBNumber;
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);
}
}
}
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 SubmitMRBForApproval() {
submitInProcess = 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;
await mrbService.UpdateMRB(mrb);
}
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);
}
}
}
mrbActions = await mrbService.GetMRBActionsForMRB(mrbNumberInt, true);
await mrbService.SubmitForApproval(mrb);
await mrbService.NotifyNewApprovals(mrb);
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;
snackbar.Add("MRB submitted for approval", Severity.Success);
} catch (Exception ex) {
submitInProcess = false;
snackbar.Add($"Unable to submit MRB for approval, because {ex.Message}", Severity.Error);
}
StateHasChanged();
}
private async void ApproveMRB() {
approvalInProcess = true;
try {
if (mrbApprovals is null || mrbApprovals.Count() <= 0)
throw new Exception("there are no approvals to approval");
if (authStateProvider.CurrentUser is null) {
navigationManager.NavigateTo("login");
return;
}
if (mrb is null) throw new Exception("MRB is null");
string? comments = "";
DialogParameters<Comments> parameters = new DialogParameters<Comments> { { x => x.comments, comments } };
var dialog = dialogService.Show<Comments>($"Approval Comments", parameters);
var result = await dialog.Result;
comments = result.Data.ToString();
if (result.Canceled) throw new Exception("you must provide your approval comments");
IEnumerable<Approval> approvals = mrbApprovals.Where(a => a.UserID == authStateProvider.CurrentUser.UserID &&
!(a.CompletedDate < DateTime.MaxValue) &&
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<Approval> remainingApprovalsInKind = approvals.Where(a => a.Step == mrb.StageNo &&
a.UserID != authStateProvider.CurrentUser.UserID &&
!(a.CompletedDate < DateTime.MaxValue));
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();
string body = $"Your MRB ({mrb.MRBNumber}) has been approved.";
MRBNotification notification = new() {
MRB = mrb,
Message = body
};
await mrbService.NotifyOriginator(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();
approvalInProcess = false;
StateHasChanged();
snackbar.Add("Successfully approved", Severity.Success);
} catch (Exception ex) {
approvalInProcess = false;
snackbar.Add($"Unable to approve, because {ex.Message}", Severity.Error);
}
}
private async void DenyMRB() {
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<Comments> parameters = new DialogParameters<Comments> { { x => x.comments, comments } };
var dialog = dialogService.Show<Comments>($"Denial Comments", parameters);
var result = await dialog.Result;
comments = result.Data.ToString();
if (result.Canceled) throw new Exception("you must provide your denial comments");
IEnumerable<Approval> approvals = mrbApprovals.Where(a => a.UserID == authStateProvider.CurrentUser.UserID &&
!(a.CompletedDate < DateTime.MaxValue) &&
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);
}
if (mrb.StageNo < 2) {
mrb.StageNo = 0;
mrb.SubmittedDate = DateTime.MinValue;
} else {
IEnumerable<Approval> remainingApprovalsInKind = approvals.Where(a => a.Step == mrb.StageNo &&
a.UserID != authStateProvider.CurrentUser.UserID &&
!(a.CompletedDate < DateTime.MaxValue));
if (remainingApprovalsInKind is null || remainingApprovalsInKind.Count() <= 0) {
mrb.CloseDate = DateTime.Now;
}
}
await mrbService.UpdateMRB(mrb);
mrbApprovals = await approvalService.GetApprovalsForIssueId(mrb.MRBNumber, true);
nonTaskApprovals = mrbApprovals.Where(a => a.Step < 3).ToList();
string body = $"Your MRB ({mrb.MRBNumber}) has been denied.";
MRBNotification notification = new() {
MRB = mrb,
Message = body
};
await mrbService.NotifyOriginator(notification);
denialInProcess = false;
StateHasChanged();
snackbar.Add("Successfully approved", Severity.Success);
} catch (Exception ex) {
denialInProcess = false;
snackbar.Add($"Unable to approve, 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) {
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");
action.CompletedDate = DateTime.Now;
action.CompletedByUserID = authStateProvider.CurrentUser.UserID;
action.CompletedByUser = authStateProvider.CurrentUser;
await mrbService.UpdateMRBAction(action);
mrbActions = await mrbService.GetMRBActionsForMRB(action.MRBNumber, true);
string role = "";
foreach (Approval approval in taskApprovals) {
bool approved = false;
if (approval.UserID == action.CompletedByUserID && approval.ItemStatus == 0 && approval.TaskID == action.ActionID) {
approved = true;
role = approval.SubRoleCategoryItem;
await approvalService.Approve(approval);
}
if (!approved && approval.SubRoleCategoryItem.Equals(role))
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 >= DateTime.MaxValue).Count();
if (outStandingTaskCount == 0) {
mrb.StageNo++;
mrb.CloseDate = DateTime.Now;
await mrbService.UpdateMRB(mrb);
string body = $"Your MRB ({mrb.MRBNumber}) is complete.";
MRBNotification notification = new() {
MRB = mrb,
Message = body
};
await mrbService.NotifyOriginator(notification);
}
StateHasChanged();
} catch (Exception ex) {
snackbar.Add($"Unable to mark action complete, because {ex.Message}", Severity.Error);
}
}
private bool mrbIsReadyToSubmit() {
return mrb is not null && !(mrb.SubmittedDate > DateTime.MinValue) && mrb.MRBNumber > 0 && mrb.OriginatorID > 0 && !mrb.OriginatorName.Equals("") &&
!mrb.Title.Equals("") && !mrb.IssueDescription.Equals("") && !mrb.Department.Equals("") && !mrb.Process.Equals("");
}
private bool currentUserIsApprover() {
if (mrbApprovals is null || authStateProvider is null) return false;
if (authStateProvider.CurrentUser is null) return false;
IEnumerable<Approval> 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<MRBActionForm> parameters = new DialogParameters<MRBActionForm> { { x => x.mrbAction, mrbAction } };
var dialog = dialogService.Show<MRBActionForm>($"New MRB Action", parameters);
var result = await dialog.Result;
if (!result.Canceled) {
if (mrbNumberInt > 0) {
mrbActions = await mrbService.GetMRBActionsForMRB(mrbNumberInt, true);
} else {
List<MRBAction> 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<MRBActionForm> { { x => x.mrbAction, mrbAction } };
var dialog = dialogService.Show<MRBActionForm>($"MRB Action {mrbAction.ActionID}", parameters);
var result = await dialog.Result;
if (!result.Canceled) {
if (mrbNumberInt > 0) {
mrbActions = await mrbService.GetMRBActionsForMRB(mrbNumberInt, true);
} else {
List<MRBAction> actionList = mrbActions.ToList();
actionList.Add(mrbAction);
mrbActions = actionList;
}
StateHasChanged();
}
} catch (Exception ex) {
snackbar.Add(ex.Message, Severity.Error);
}
}
private async void DeleteAction(MRBAction mrbAction) {
deleteActionInProcess = true;
try {
if (mrbAction is null)
throw new ArgumentNullException("Action cannot be null");
await mrbService.DeleteMRBAction(mrbAction);
List<MRBAction> 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) {
List<IBrowserFile> attachments = new() { args.File };
if (authStateProvider.CurrentUser is not null) {
await mrbService.UploadAttachments(attachments, mrbNumberInt);
mrbAttachments = await mrbService.GetAllAttachmentsForMRB(mrbNumberInt, true);
StateHasChanged();
}
}
private async void DeleteAttachment(MRBAttachment mrbAttachment) {
deleteAttachmentInProcess = true;
try {
if (mrbAttachment is null)
throw new ArgumentNullException("Attachment cannot be null");
await mrbService.DeleteAttachment(mrbAttachment);
List<MRBAttachment> 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 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;
}
}