1 Commits

Author SHA1 Message Date
e020ec8c01 Ready to publish
Added new Email Template and new Modal form for expired TECNs.
Updated Email Template and new Modal form for TECNs.
Added more margin on all modal dialogs
2025-01-22 09:30:59 -07:00
98 changed files with 4125 additions and 7976 deletions

View File

@ -420,6 +420,5 @@
"windowsphone", "windowsphone",
"Winsock", "Winsock",
"worlflow" "worlflow"
], ]
"dotnet.preferCSharpExtension": true
} }

17
.vscode/tasks.json vendored
View File

@ -2,7 +2,7 @@
"version": "2.0.0", "version": "2.0.0",
"tasks": [ "tasks": [
{ {
"label": "MSBuild-Debug", "label": "MSBuild",
"command": "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe", "command": "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe",
"type": "process", "type": "process",
"args": [ "args": [
@ -16,21 +16,6 @@
], ],
"problemMatcher": "$msCompile" "problemMatcher": "$msCompile"
}, },
{
"label": "MSBuild-Release",
"command": "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe",
"type": "process",
"args": [
"/target:Build",
"/restore:True",
"/p:RestoreSources=https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/%3Bhttps://packagemanagement.eu.infineon.com:4430/api/v2/%3Bhttps://api.nuget.org/v3/index.json",
"/detailedsummary",
"/consoleloggerparameters:PerformanceSummary;ErrorsOnly;",
"/property:Configuration=Release;TargetFrameworkVersion=v4.8",
"Fab2ApprovalSystem/Fab2ApprovalSystem.csproj"
],
"problemMatcher": "$msCompile"
},
{ {
"label": "Fab2ApprovalMKLink-User Secrets Init", "label": "Fab2ApprovalMKLink-User Secrets Init",
"command": "dotnet", "command": "dotnet",

View File

@ -367,7 +367,6 @@ dotnet_diagnostic.IDE0065.severity = none # Question -
dotnet_diagnostic.IDE0066.severity = none # Question - Use dotnet_diagnostic.IDE0066.severity = none # Question - Use
dotnet_diagnostic.IDE0078.severity = none # Question - Use pattern matching (may change code meaning) dotnet_diagnostic.IDE0078.severity = none # Question - Use pattern matching (may change code meaning)
dotnet_diagnostic.IDE0090.severity = warning # Question - Simplify new expression dotnet_diagnostic.IDE0090.severity = warning # Question - Simplify new expression
dotnet_diagnostic.IDE0100.severity = error # Question - Remove redundant equality
dotnet_diagnostic.IDE0160.severity = warning # Question - Use block-scoped namespace dotnet_diagnostic.IDE0160.severity = warning # Question - Use block-scoped namespace
dotnet_diagnostic.IDE0161.severity = warning # Question - Namespace declaration preferences dotnet_diagnostic.IDE0161.severity = warning # Question - Namespace declaration preferences
dotnet_diagnostic.IDE0270.severity = none # Question - Null check can be simplified dotnet_diagnostic.IDE0270.severity = none # Question - Null check can be simplified

View File

@ -18,15 +18,9 @@
<PropertyGroup Condition="'$(TargetFramework)' == 'net8.0'"> <PropertyGroup Condition="'$(TargetFramework)' == 'net8.0'">
<DefineConstants>NET8</DefineConstants> <DefineConstants>NET8</DefineConstants>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
<_Parameter1>Fab2ApprovalTests</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Dapper.Contrib" Version="2.0.78" /> <PackageReference Include="Dapper.Contrib" Version="2.0.78" />
<PackageReference Include="Dapper" Version="2.1.44" /> <PackageReference Include="Dapper" Version="2.1.44" />
<PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" />
<PackageReference Include="EntityFramework" Version="6.5.1" /> <PackageReference Include="EntityFramework" Version="6.5.1" />
<PackageReference Include="ExcelDataReader" Version="3.7.0" /> <PackageReference Include="ExcelDataReader" Version="3.7.0" />
<PackageReference Include="jQuery" Version="3.7.1" /> <PackageReference Include="jQuery" Version="3.7.1" />

View File

@ -0,0 +1,105 @@
trigger:
branches:
include:
- Development
paths:
include:
- "Fab2ApprovalSystem/*"
exclude:
- "**/*.yaml"
- "**/*.yml"
- "SQL/*"
- "references/*"
- "packages/*"
- "Kendo/*"
pool:
name: Mesa-IIS
demands: Fab2ApprovalSystem-Development
variables:
# solution: '**/*.sln'
# buildPlatform: 'Any CPU'
buildConfiguration: "Debug"
ASPNETCORE_ENVIRONMENT: "Development"
steps:
- script: |
set assemblyTitle=Fab2ApprovalSystem
echo %assemblyTitle%
echo ##vso[task.setvariable variable=AssemblyTitle;]%assemblyTitle%
echo $(AssemblyTitle)
displayName: AssemblyTitle
- script: |
set targetFrameworkVersion=v4.8
echo %targetFrameworkVersion%
echo ##vso[task.setvariable variable=TargetFrameworkVersion;]%targetFrameworkVersion%
echo $(TargetFrameworkVersion)
displayName: TargetFrameworkVersion
- script: |
set coreVersion=na
echo %coreVersion%
echo ##vso[task.setvariable variable=CoreVersion;]%coreVersion%
echo $(CoreVersion)
displayName: CoreVersion
- script: |
set configuration=Debug
echo %configuration%
echo ##vso[task.setvariable variable=Configuration;]%configuration%
echo $(Configuration)
displayName: Configuration
- script: |
REM set nugetSource=https://messa017.infineon.com/v3/index.json
set nugetSource=https://eaf-prod.mes.infineon.com/v3/index.json
echo %nugetSource%
echo ##vso[task.setvariable variable=NugetSource;]%nugetSource%
echo $(NugetSource)
displayName: NugetSource
- script: |
set gitCommit=$(Build.SourceVersion)
set gitCommitSeven=%gitCommit:~0,7%
echo %gitCommitSeven%
echo ##vso[task.setvariable variable=GitCommitSeven;]%gitCommitSeven%
echo $(GitCommitSeven)
displayName: GitCommitSeven
- script: |
echo $(AssemblyTitle)
echo $(Build.BuildId)
echo $(Build.Reason)
echo $(Build.Repository.Id)
echo $(Build.Repository.Name)
echo $(Build.SourceVersion)
echo $(CoreVersion)
echo $(Configuration)
echo $(NugetSource)
echo $(GitCommitSeven)
echo $(TargetFrameworkVersion)
REM echo $(pipelinePassword)
displayName: "Echo Check"
- script: '"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" /target:Restore /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:RestoreSources=$(NugetSource) $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework Restore"
- script: '"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" /target:Build /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework Build"
- script: '"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:DebugSymbols=false /p:DeleteExistingFiles=true /p:DeployOnBuild=true /p:EnableUpdateAble=true /p:ExcludeApp_Data=true /p:LastUsedBuildConfiguration=$(Configuration) /p:LastUsedPlatform="Any CPU" /p:LaunchSiteAfterPublish=true /p:OutputPath="D:\$(TargetFrameworkVersion)\$(Build.Repository.Name)\$(GitCommitSeven)-$(Build.BuildId)-$(Build.Repository.Name)-$(Configuration)" /p:PreCompileBeforePublish=true /p:PublishProvider=FileSystem /p:PublishUrl="D:/PublishUrl" /p:SiteUrlToLaunchAfterPublish="" /p:WDPMergeOption=DoNotMerge /p:WebPublishMethod=FileSystem $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework Pack"
- script: '"C:/Program Files (x86)/IIS/Microsoft Web Deploy V3/MSDeploy.exe" -AllowUntrusted -dest:auto -disableLink:AppPoolExtension -disableLink:CertificateExtension -disableLink:ContentExtension -setParam:name="IIS Web Application Name",value=$(Build.Repository.Name) -setParamFile:"D:\$(TargetFrameworkVersion)\$(Build.Repository.Name)\$(GitCommitSeven)-$(Build.BuildId)-$(Build.Repository.Name)-$(Configuration)" "/_PublishedWebsites/$(Build.Repository.Name)_Package/$(Build.Repository.Name).SetParameters.xml" -source:package="D:\$(TargetFrameworkVersion)\$(Build.Repository.Name)\$(GitCommitSeven)-$(Build.BuildId)-$(Build.Repository.Name)-$(Configuration)" "/_PublishedWebsites/$(AssemblyTitle)_Package/$(AssemblyTitle).zip" -verb:sync'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework Deploy"
enabled: false
- script: 'echo $(Build.SourceVersion)-$(Build.BuildId)>bin_x_x_\$(Configuration)\$(CoreVersion)\win-x64\$(Build.Repository.Name).txt'
displayName: "Force Fail"
enabled: false

View File

@ -6,9 +6,6 @@ MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fab2ApprovalSystem", "Fab2ApprovalSystem\Fab2ApprovalSystem.csproj", "{AAE52608-4DD1-4732-92BD-CC8915DEC71E}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fab2ApprovalSystem", "Fab2ApprovalSystem\Fab2ApprovalSystem.csproj", "{AAE52608-4DD1-4732-92BD-CC8915DEC71E}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MesaFabApproval.API", "MesaFabApproval.API\MesaFabApproval.API.csproj", "{852E528D-015A-43B5-999D-F281E3359E5E}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MesaFabApproval.API", "MesaFabApproval.API\MesaFabApproval.API.csproj", "{852E528D-015A-43B5-999D-F281E3359E5E}"
ProjectSection(ProjectDependencies) = postProject
{2C16014D-B04E-46AF-AB4C-D2691D44A339} = {2C16014D-B04E-46AF-AB4C-D2691D44A339}
EndProjectSection
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MesaFabApproval.Shared", "MesaFabApproval.Shared\MesaFabApproval.Shared.csproj", "{2C16014D-B04E-46AF-AB4C-D2691D44A339}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MesaFabApproval.Shared", "MesaFabApproval.Shared\MesaFabApproval.Shared.csproj", "{2C16014D-B04E-46AF-AB4C-D2691D44A339}"
EndProject EndProject
@ -17,18 +14,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MesaFabApproval.Client", "M
{2C16014D-B04E-46AF-AB4C-D2691D44A339} = {2C16014D-B04E-46AF-AB4C-D2691D44A339} {2C16014D-B04E-46AF-AB4C-D2691D44A339} = {2C16014D-B04E-46AF-AB4C-D2691D44A339}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MesaFabApproval.API.Test", "MesaFabApproval.API.Test\MesaFabApproval.API.Test.csproj", "{D03AB305-BA29-4EB1-AC66-ABBF76FBF5C1}"
ProjectSection(ProjectDependencies) = postProject
{2C16014D-B04E-46AF-AB4C-D2691D44A339} = {2C16014D-B04E-46AF-AB4C-D2691D44A339}
{852E528D-015A-43B5-999D-F281E3359E5E} = {852E528D-015A-43B5-999D-F281E3359E5E}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MesaFabApproval.Client.Test", "MesaFabApproval.Client.Test\MesaFabApproval.Client.Test.csproj", "{A0E5BD7D-3910-43BD-BBA3-3820AD524423}"
ProjectSection(ProjectDependencies) = postProject
{2C16014D-B04E-46AF-AB4C-D2691D44A339} = {2C16014D-B04E-46AF-AB4C-D2691D44A339}
{34D52F44-A81F-4247-8180-16E204824A07} = {34D52F44-A81F-4247-8180-16E204824A07}
EndProjectSection
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -51,14 +36,6 @@ Global
{34D52F44-A81F-4247-8180-16E204824A07}.Debug|Any CPU.Build.0 = Debug|Any CPU {34D52F44-A81F-4247-8180-16E204824A07}.Debug|Any CPU.Build.0 = Debug|Any CPU
{34D52F44-A81F-4247-8180-16E204824A07}.Release|Any CPU.ActiveCfg = Release|Any CPU {34D52F44-A81F-4247-8180-16E204824A07}.Release|Any CPU.ActiveCfg = Release|Any CPU
{34D52F44-A81F-4247-8180-16E204824A07}.Release|Any CPU.Build.0 = Release|Any CPU {34D52F44-A81F-4247-8180-16E204824A07}.Release|Any CPU.Build.0 = Release|Any CPU
{D03AB305-BA29-4EB1-AC66-ABBF76FBF5C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D03AB305-BA29-4EB1-AC66-ABBF76FBF5C1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D03AB305-BA29-4EB1-AC66-ABBF76FBF5C1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D03AB305-BA29-4EB1-AC66-ABBF76FBF5C1}.Release|Any CPU.Build.0 = Release|Any CPU
{A0E5BD7D-3910-43BD-BBA3-3820AD524423}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A0E5BD7D-3910-43BD-BBA3-3820AD524423}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A0E5BD7D-3910-43BD-BBA3-3820AD524423}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A0E5BD7D-3910-43BD-BBA3-3820AD524423}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -58,7 +58,6 @@ public class AuditController : Controller {
try { try {
bool isAdmin = (bool)Session[GlobalVars.IS_ADMIN]; bool isAdmin = (bool)Session[GlobalVars.IS_ADMIN];
int userId = (int)Session[GlobalVars.SESSION_USERID]; int userId = (int)Session[GlobalVars.SESSION_USERID];
audit = auditDMO.GetAuditItem(issueID, userId);
AuditEdit auditEdit = auditDMO.GetAuditEdit(issueID, audit, isAdmin, userId); AuditEdit auditEdit = auditDMO.GetAuditEdit(issueID, audit, isAdmin, userId);
if (auditEdit.RedirectToAction) if (auditEdit.RedirectToAction)
return RedirectToAction("ReadOnlyAudit", new { auditNo = audit.AuditNo }); return RedirectToAction("ReadOnlyAudit", new { auditNo = audit.AuditNo });

View File

@ -52,7 +52,7 @@ public class ChangeControlController : Controller {
string encodedJwt = System.Net.WebUtility.UrlEncode(jwt); string encodedJwt = System.Net.WebUtility.UrlEncode(jwt);
string refreshToken = Session["RefreshToken"].ToString(); string refreshToken = Session["RefreshToken"].ToString();
string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken);
string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=pcrb/{issueID}"; string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=/pcrb/{issueID}";
return Redirect(mrbUrl); return Redirect(mrbUrl);
} }
@ -62,7 +62,7 @@ public class ChangeControlController : Controller {
string encodedJwt = System.Net.WebUtility.UrlEncode(jwt); string encodedJwt = System.Net.WebUtility.UrlEncode(jwt);
string refreshToken = Session["RefreshToken"].ToString(); string refreshToken = Session["RefreshToken"].ToString();
string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken);
string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=pcrb/{issueID}"; string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=/pcrb/{issueID}";
return Redirect(mrbUrl); return Redirect(mrbUrl);
} }

View File

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Configuration; using System.Configuration;
using System.IO;
using System.Linq; using System.Linq;
using System.Web; using System.Web;
using System.Web.Mvc; using System.Web.Mvc;
@ -22,7 +21,7 @@ namespace Fab2ApprovalSystem.Controllers;
[Authorize] [Authorize]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")] [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
[SessionExpireFilter] [SessionExpireFilter]
public class ECNController : Controller { public class ECNController : PdfViewController {
private const string ECN_PREFIX = "ECN_"; private const string ECN_PREFIX = "ECN_";
private const string TECN_PREFIX = "TECN_"; private const string TECN_PREFIX = "TECN_";
@ -670,6 +669,9 @@ public class ECNController : Controller {
} }
} }
/// <summary>
/// Get a list of Approvers and the status
/// </summary>
public ActionResult GetApproversList([DataSourceRequest] DataSourceRequest request, int issueID, byte step, bool isTECN, bool isEmergrncyTECN) { public ActionResult GetApproversList([DataSourceRequest] DataSourceRequest request, int issueID, byte step, bool isTECN, bool isEmergrncyTECN) {
int isITARCompliant = 0; int isITARCompliant = 0;
ECN ecn = new ECN(); ECN ecn = new ECN();
@ -881,8 +883,6 @@ public class ECNController : Controller {
string outputFileName = ""; string outputFileName = "";
ecn = ecnDMO.GetECNPdf(ecnNumber); ecn = ecnDMO.GetECNPdf(ecnNumber);
ViewBag.Category = ecnDMO.GetCategoryID(ecn);
ViewBag.TrainingNotificationTo = ecnDMO.GetTrainingNotificationTo(ecn, trainingDMO);
outputFileName = ecnNumber.ToString() + ".pdf"; outputFileName = ecnNumber.ToString() + ".pdf";
string ecnFolderPath = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString(); string ecnFolderPath = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString();
@ -891,12 +891,10 @@ public class ECNController : Controller {
if (!di.Exists) if (!di.Exists)
di.Create(); di.Create();
string htmlText; // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This
string pageTitle = string.Empty; // requires the controller to be inherited from MyController instead of MVC's Controller.
htmlText = RenderViewToString("ECNPdf", ecn); SavePdf(ecnFolderPath + "\\ECNForm_" + outputFileName, "ECNPdf", ecn);
StandardPdfRenderer.WritePortableDocumentFormatToFile(pageTitle, htmlText, $"{ecnFolderPath}\\ECNForm_{outputFileName}"); SavePdf(ecnFolderPath + "\\ECNApprovalLog_" + outputFileName, "ECNApprovalPdf", ecn);
htmlText = RenderViewToString("ECNApprovalPdf", ecn);
StandardPdfRenderer.WritePortableDocumentFormatToFile(pageTitle, htmlText, $"{ecnFolderPath}\\ECNApprovalLog_{outputFileName}");
} catch (Exception ex) { } catch (Exception ex) {
EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Generate PDF", Comments = ex.Message }); EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Generate PDF", Comments = ex.Message });
ecn = null; ecn = null;
@ -906,32 +904,12 @@ public class ECNController : Controller {
return true; return true;
} }
private string RenderViewToString(string viewName, ECNPdf ecnPdf) {
string result;
ViewData.Model = ecnPdf;
using (StringWriter writer = new()) {
try {
ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, viewName, string.Empty);
if (viewResult is null)
return $"A view with the name '{viewName}' could not be found";
ViewContext viewContext = new(ControllerContext, viewResult.View, ViewData, TempData, writer);
viewResult.View.Render(viewContext, writer);
result = writer.GetStringBuilder().ToString();
} catch (Exception ex) {
result = $"Failed - {ex.Message}";
}
}
return result;
}
public bool GenerateECNPdfDifferentLocation(int ecnNumber, int folderName) { public bool GenerateECNPdfDifferentLocation(int ecnNumber, int folderName) {
ECNPdf ecn = new ECNPdf(); ECNPdf ecn = new ECNPdf();
try { try {
string outputFileName = ""; string outputFileName = "";
ecn = ecnDMO.GetECNPdf(ecnNumber); ecn = ecnDMO.GetECNPdf(ecnNumber);
ViewBag.Category = ecnDMO.GetCategoryID(ecn);
ViewBag.TrainingNotificationTo = ecnDMO.GetTrainingNotificationTo(ecn, trainingDMO);
outputFileName = ecnNumber.ToString() + ".pdf"; outputFileName = ecnNumber.ToString() + ".pdf";
string ecnFolderPath = _AppSettings.AttachmentFolder + "ECN\\" + folderName.ToString(); string ecnFolderPath = _AppSettings.AttachmentFolder + "ECN\\" + folderName.ToString();
@ -941,9 +919,9 @@ public class ECNController : Controller {
if (!di.Exists) if (!di.Exists)
di.Create(); di.Create();
string pageTitle = string.Empty; // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This
string htmlText = RenderViewToString("ECNPdf", ecn); // requires the controller to be inherited from MyController instead of MVC's Controller.
StandardPdfRenderer.WritePortableDocumentFormatToFile(pageTitle, htmlText, $"{ecnFolderPath}\\ECNForm_{outputFileName}"); SavePdf(ecnFolderPath + "\\ECNForm_" + outputFileName, "ECNPdf", ecn);
} catch (Exception ex) { } catch (Exception ex) {
EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Generate PDF", Comments = ex.Message }); EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Generate PDF", Comments = ex.Message });
ecn = null; ecn = null;
@ -957,20 +935,13 @@ public class ECNController : Controller {
ECNPdf ecn; ECNPdf ecn;
try { try {
ecn = ecnDMO.GetECNPdf(ecnNumber); ecn = ecnDMO.GetECNPdf(ecnNumber);
ViewBag.Category = ecnDMO.GetCategoryID(ecn); // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This
ViewBag.TrainingNotificationTo = ecnDMO.GetTrainingNotificationTo(ecn, trainingDMO); // requires the controller to be inherited from MyController instead of MVC's Controller.
string pageTitle = string.Empty; return this.ViewPdf("", "ECNPdf", ecn);
string htmlText = RenderViewToString("ECNPdf", ecn);
if (System.Diagnostics.Debugger.IsAttached) {
return Content(htmlText, "text/html");
} else {
byte[] buffer = StandardPdfRenderer.GetPortableDocumentFormatBytes(pageTitle, htmlText);
return new BinaryContentResult(buffer, "application/pdf");
}
} catch (Exception ex) { } catch (Exception ex) {
EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Print PDF", Comments = ex.Message }); EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Print PDF", Comments = ex.Message });
ecn = null; ecn = null;
return Content("An unexpected error has occurred!"); return Content("");
} }
} }
@ -1188,8 +1159,8 @@ public class ECNController : Controller {
public ActionResult CancelDocument(int ecnNumber, byte currentStep, int documentType, string ecnTypeString, string comments = "") { public ActionResult CancelDocument(int ecnNumber, byte currentStep, int documentType, string ecnTypeString, string comments = "") {
ECN ecn = ecnDMO.GetECN(ecnNumber); ECN ecn = ecnDMO.GetECN(ecnNumber);
bool lastApproverAndLastStep = false; bool lastApproverAndLastStep = false;
if (ecn.SubmitedDate is not null && currentStep >= 1) if (ecn.IsTECN && ecn.SubmitedDate is not null && currentStep >= 1)
wfDMO.Approve(_AppSettings, ecnNumber, currentStep, comments, out bool lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType, ecn.WorkFlowNumber); Approve(ecnNumber, currentStep, comments, documentType, ecnTypeString);
int appoverCount = ecnDMO.SubmitForCancellation(ecnNumber, (byte)GlobalVars.WorkFLowStepNumber.Step1, (int)Session[GlobalVars.SESSION_USERID], documentType, ecnTypeString, (int)GlobalVars.TECNExpirationCancellation.Cancellation); int appoverCount = ecnDMO.SubmitForCancellation(ecnNumber, (byte)GlobalVars.WorkFLowStepNumber.Step1, (int)Session[GlobalVars.SESSION_USERID], documentType, ecnTypeString, (int)GlobalVars.TECNExpirationCancellation.Cancellation);
if (appoverCount > 0) { if (appoverCount > 0) {
NotifyApproversForCancellation(ecnNumber, ecn, currentStep, documentType, ecnTypeString); NotifyApproversForCancellation(ecnNumber, ecn, currentStep, documentType, ecnTypeString);
@ -1250,12 +1221,6 @@ public class ECNController : Controller {
try { try {
lastApproverAndLastStep = true; lastApproverAndLastStep = true;
ecn.CancellationDate = DateTime.Now;
ecn.CancellationApprovalDate = DateTime.Now;
ecn.CancellationApproved = true;
ecn.Cancelled = true;
ecnDMO.UpdateECN(ecn);
ECNPdf ecnPDF = new ECNPdf(); ECNPdf ecnPDF = new ECNPdf();
GenerateECNPdf(ecnNumber, out ecnPDF); GenerateECNPdf(ecnNumber, out ecnPDF);

View File

@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Configuration; using System.Configuration;
using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Web; using System.Web;
@ -21,7 +20,7 @@ namespace Fab2ApprovalSystem.Controllers;
[Authorize] [Authorize]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")] [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
[SessionExpireFilter] [SessionExpireFilter]
public class LotTravelerController : Controller { public class LotTravelerController : PdfViewController {
LotTravelerDMO LotTravDMO = new LotTravelerDMO(); LotTravelerDMO LotTravDMO = new LotTravelerDMO();
string docTypeString = "LotTraveler"; string docTypeString = "LotTraveler";
@ -200,14 +199,9 @@ public class LotTravelerController : Controller {
try { try {
workRequest = LotTravDMO.GetLTWorkRequestItemPDF(workRequestID); workRequest = LotTravDMO.GetLTWorkRequestItemPDF(workRequestID);
string pageTitle = string.Empty; // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This
string htmlText = RenderViewToString("WorkRequestPDF", workRequest); // requires the controller to be inherited from MyController instead of MVC's Controller.
if (System.Diagnostics.Debugger.IsAttached) { return this.ViewPdf("", "WorkRequestPDF", workRequest);
return Content(htmlText, "text/html");
} else {
byte[] buffer = StandardPdfRenderer.GetPortableDocumentFormatBytes(pageTitle, htmlText);
return new BinaryContentResult(buffer, "application/pdf");
}
} catch (Exception ex) { } catch (Exception ex) {
Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n DisplayWorkRequestPDF - LotTraveler\r\n" + ex.InnerException.ToString(), System.Diagnostics.EventLogEntryType.Error); Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n DisplayWorkRequestPDF - LotTraveler\r\n" + ex.InnerException.ToString(), System.Diagnostics.EventLogEntryType.Error);
EventLogDMO.Add(new WinEventLog() { IssueID = workRequest.SWRNumber, UserID = @User.Identity.Name, DocumentType = "LotTravler", OperationType = "Generate PDF", Comments = ex.Message }); EventLogDMO.Add(new WinEventLog() { IssueID = workRequest.SWRNumber, UserID = @User.Identity.Name, DocumentType = "LotTravler", OperationType = "Generate PDF", Comments = ex.Message });
@ -216,24 +210,6 @@ public class LotTravelerController : Controller {
} }
} }
private string RenderViewToString(string viewName, object model) {
string result;
ViewData.Model = model;
using (StringWriter writer = new()) {
try {
ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, viewName, string.Empty);
if (viewResult is null)
return $"A view with the name '{viewName}' could not be found";
ViewContext viewContext = new(ControllerContext, viewResult.View, ViewData, TempData, writer);
viewResult.View.Render(viewContext, writer);
result = writer.GetStringBuilder().ToString();
} catch (Exception ex) {
result = $"Failed - {ex.Message}";
}
}
return result;
}
public ActionResult WorkRequestRevision(int workRequestID) { public ActionResult WorkRequestRevision(int workRequestID) {
int isITARCompliant = 1; int isITARCompliant = 1;
LTWorkRequest workRequest = new LTWorkRequest(); LTWorkRequest workRequest = new LTWorkRequest();
@ -275,7 +251,9 @@ public class LotTravelerController : Controller {
return Content("Successfully Saved"); return Content("Successfully Saved");
} }
/// <summary>
///
/// </summary>
public JsonResult GetBaseFlowLocations(string baseFlow) { public JsonResult GetBaseFlowLocations(string baseFlow) {
List<BaseFlowLocation> loclist = LotTravDMO.GetBaseFlowLocations(baseFlow); List<BaseFlowLocation> loclist = LotTravDMO.GetBaseFlowLocations(baseFlow);
return Json(loclist, JsonRequestBehavior.AllowGet); return Json(loclist, JsonRequestBehavior.AllowGet);
@ -354,6 +332,9 @@ public class LotTravelerController : Controller {
return Content(newWorkRequestID.ToString()); return Content(newWorkRequestID.ToString());
} }
/// <summary>
/// For the Revison
/// </summary>
public ActionResult UpdateMaterialDetailRevision(LTWorkRequest model) { public ActionResult UpdateMaterialDetailRevision(LTWorkRequest model) {
var modelMaterialDetail = model.LTMaterial; var modelMaterialDetail = model.LTMaterial;
int previousMaterialID = model.LTMaterial.ID; int previousMaterialID = model.LTMaterial.ID;
@ -1251,19 +1232,15 @@ public class LotTravelerController : Controller {
LotTravDMO.DeleteLot(ltLotID); LotTravDMO.DeleteLot(ltLotID);
} }
///
public ActionResult DisplayLotTravlerPdf(int ltLotID, int revisionNumber) { public ActionResult DisplayLotTravlerPdf(int ltLotID, int revisionNumber) {
LotTravelerPdf traveler = new LotTravelerPdf(); LotTravelerPdf traveler = new LotTravelerPdf();
try { try {
traveler = LotTravDMO.GetLotTravlerPdf(ltLotID, revisionNumber); traveler = LotTravDMO.GetLotTravlerPdf(ltLotID, revisionNumber);
string pageTitle = string.Empty; // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This
string htmlText = RenderViewToString("LotTravelerPDF", traveler); // requires the controller to be inherited from MyController instead of MVC's Controller.
if (System.Diagnostics.Debugger.IsAttached) { return this.ViewPdf("", "LotTravelerPDF", traveler);
return Content(htmlText, "text/html");
} else {
byte[] buffer = StandardPdfRenderer.GetPortableDocumentFormatBytes(pageTitle, htmlText);
return new BinaryContentResult(buffer, "application/pdf");
}
} catch (Exception ex) { } catch (Exception ex) {
EventLogDMO.Add(new WinEventLog() { IssueID = traveler.SWRNumber, UserID = @User.Identity.Name, DocumentType = "LotTraveler", OperationType = "Generate PDF", Comments = ex.Message }); EventLogDMO.Add(new WinEventLog() { IssueID = traveler.SWRNumber, UserID = @User.Identity.Name, DocumentType = "LotTraveler", OperationType = "Generate PDF", Comments = ex.Message });
traveler = null; traveler = null;

View File

@ -79,7 +79,7 @@ public class MRBController : Controller {
string encodedJwt = System.Net.WebUtility.UrlEncode(jwt); string encodedJwt = System.Net.WebUtility.UrlEncode(jwt);
string refreshToken = Session["RefreshToken"].ToString(); string refreshToken = Session["RefreshToken"].ToString();
string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken);
string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=mrb/{issueID}"; string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=/mrb/{issueID}";
return Redirect(mrbUrl); return Redirect(mrbUrl);
} }
@ -102,7 +102,7 @@ public class MRBController : Controller {
string encodedJwt = System.Net.WebUtility.UrlEncode(jwt); string encodedJwt = System.Net.WebUtility.UrlEncode(jwt);
string refreshToken = Session["RefreshToken"].ToString(); string refreshToken = Session["RefreshToken"].ToString();
string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken);
string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=mrb/{issueID}"; string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=/mrb/{issueID}";
return Redirect(mrbUrl); return Redirect(mrbUrl);
} }

View File

@ -37,7 +37,7 @@ public class AdminDMO {
foreach (SubRole sr in r.SubRoles) { foreach (SubRole sr in r.SubRoles) {
if (sr.Inactive) { if (sr.Inactive) {
// hide inactive roles unless parameter says otherwise // hide inactive roles unless parameter says otherwise
if (!showInactiveRoles.Equals("true")) if (showInactiveRoles.Equals("true") == false)
continue; continue;
} }

View File

@ -401,6 +401,7 @@ public class AuditDMO {
result.Is8DQA = "true"; result.Is8DQA = "true";
} }
audit = GetAuditItem(issueID, userId);
// transform audit users from string to list, delimited by a comma. // transform audit users from string to list, delimited by a comma.
if (audit.Auditees == null) { if (audit.Auditees == null) {
result.AuditeeNames = new List<string>(); result.AuditeeNames = new List<string>();
@ -413,7 +414,7 @@ public class AuditDMO {
if (audit.OriginatorID == userId) { if (audit.OriginatorID == userId) {
result.IsSubmitter = true; result.IsSubmitter = true;
} }
if (!isAdmin) { if (isAdmin != true) {
result.IsAdmin = false; result.IsAdmin = false;
} else { } else {
result.IsAdmin = true; result.IsAdmin = true;
@ -423,7 +424,7 @@ public class AuditDMO {
{ {
result.RedirectToAction = true; result.RedirectToAction = true;
} }
if (!result.IsAdmin && !result.IsSubmitter) { if (result.IsAdmin == false && result.IsSubmitter == false) {
result.RedirectToAction = true; result.RedirectToAction = true;
} else { } else {
result.UserList = GetUserList(); result.UserList = GetUserList();

View File

@ -324,7 +324,7 @@ public class CorrectiveActionDMO {
bool isAssignee = false; bool isAssignee = false;
int aiIndex = 0; int aiIndex = 0;
List<D5D6CorrectivetAction> actionItems = GetD5D6CorrectivetActions(caId).ToList(); List<D5D6CorrectivetAction> actionItems = GetD5D6CorrectivetActions(caId).ToList();
while (!isAssignee && aiIndex < actionItems.Count) { while (isAssignee == false && aiIndex < actionItems.Count) {
D5D6CorrectivetAction actionItem = actionItems[aiIndex]; D5D6CorrectivetAction actionItem = actionItems[aiIndex];
if (actionItem.ResponsibilityOwnerID == userId && actionItem.ImplementedDate == null && actionItem.Approved) { if (actionItem.ResponsibilityOwnerID == userId && actionItem.ImplementedDate == null && actionItem.Approved) {
isAssignee = true; isAssignee = true;

View File

@ -42,9 +42,6 @@ public class ECN_DMO {
parameters.Add("@ExpirationDate", ecn.ExpirationDate); parameters.Add("@ExpirationDate", ecn.ExpirationDate);
parameters.Add("@ExtensionDate", ecn.ExtensionDate); parameters.Add("@ExtensionDate", ecn.ExtensionDate);
parameters.Add("@CancellationDate", ecn.CancellationDate); parameters.Add("@CancellationDate", ecn.CancellationDate);
parameters.Add("@CancellationApprovalDate", ecn.CancellationApprovalDate);
parameters.Add("@CancellationApproved", ecn.CancellationApproved);
parameters.Add("@Cancelled", ecn.Cancelled);
parameters.Add("@AcknowledgementRequired", ecn.AcknowledgementRequired); parameters.Add("@AcknowledgementRequired", ecn.AcknowledgementRequired);
parameters.Add("@TrainingRequired", ecn.TrainingRequired); parameters.Add("@TrainingRequired", ecn.TrainingRequired);
parameters.Add("@AreaID", ecn.AreaID); parameters.Add("@AreaID", ecn.AreaID);
@ -356,17 +353,14 @@ public class ECN_DMO {
List<string> affectedAreas = multipleResultItems.Read<string>().ToList(); List<string> affectedAreas = multipleResultItems.Read<string>().ToList();
List<string> affectedTechnologies = multipleResultItems.Read<string>().ToList(); List<string> affectedTechnologies = multipleResultItems.Read<string>().ToList();
List<string> acknowledgementBy = multipleResultItems.Read<string>().ToList(); List<string> acknowledgementBy = multipleResultItems.Read<string>().ToList();
List<int> trainingby = multipleResultItems.Read<int>().ToList(); List<string> trainingBy = multipleResultItems.Read<string>().ToList();
if (ecnItem != null && trainingby != null) {
if (trainingby.Count > 0)
ecnItem.TrainingByIDs.AddRange(trainingby);
}
List<string> productfamilies = multipleResultItems.Read<string>().ToList(); List<string> productfamilies = multipleResultItems.Read<string>().ToList();
ecnItem.AffectedModules = string.Join(", ", modules); ecnItem.AffectedModules = string.Join(", ", modules);
ecnItem.AffectedDepartments = string.Join(", ", departments); ecnItem.AffectedDepartments = string.Join(", ", departments);
ecnItem.AffectedAreas = string.Join(",", affectedAreas); ecnItem.AffectedAreas = string.Join(",", affectedAreas);
ecnItem.AffectedTechnologies = string.Join(",", affectedTechnologies); ecnItem.AffectedTechnologies = string.Join(",", affectedTechnologies);
ecnItem.TrainingBy = string.Join(",", trainingBy);
ecnItem.AcknowledgementBy = string.Join(",", acknowledgementBy); ecnItem.AcknowledgementBy = string.Join(",", acknowledgementBy);
ecnItem.AffectedProductFamilies = string.Join(",", productfamilies); ecnItem.AffectedProductFamilies = string.Join(",", productfamilies);
@ -396,7 +390,7 @@ public class ECN_DMO {
internal List<ECNCategory> GetCategories() { internal List<ECNCategory> GetCategories() {
List<ECNCategory> r = db.Query<ECNCategory>("ECNGetCategories", null, commandType: CommandType.StoredProcedure).ToList(); List<ECNCategory> r = db.Query<ECNCategory>("ECNGetCategories", null, commandType: CommandType.StoredProcedure).ToList();
return r.OrderBy(l => l.CategoryName).ToList(); return r;
} }
internal List<ECNArea> GetECNAreas() { internal List<ECNArea> GetECNAreas() {
@ -717,26 +711,4 @@ public class ECN_DMO {
return r; return r;
} }
internal string GetCategoryID(ECNPdf ecn) {
string result;
if (ecn.CategoryID is null) {
result = string.Empty;
} else {
List<ECNCategory> categories = GetCategories();
result = (from l in categories where l.CategoryID == ecn.CategoryID.Value select l.CategoryName).FirstOrDefault();
}
return result;
}
internal string GetTrainingNotificationTo(ECNPdf ecn, TrainingDMO trainingDMO) {
string result;
if (ecn.TrainingByIDs is null) {
result = string.Empty;
} else {
List<TrainingGroup> trainingGroups = trainingDMO.GetTrainingGroups();
result = string.Join(", ", (from l in trainingGroups where ecn.TrainingByIDs.Contains(l.TrainingGroupID) select l.TrainingGroupName).ToArray());
}
return result;
}
} }

View File

@ -266,9 +266,9 @@ public class MRB_DMO {
DateTime? issueStartDate = tempMRBInfo.IssueStartDate; DateTime? issueStartDate = tempMRBInfo.IssueStartDate;
DateTime? issueEndDate = tempMRBInfo.IssueEndDate; DateTime? issueEndDate = tempMRBInfo.IssueEndDate;
if (!issueStartDate.HasValue) if (issueStartDate.HasValue == false)
throw new Exception("MRB Issue Start Date cannot be blank"); throw new Exception("MRB Issue Start Date cannot be blank");
if (!issueEndDate.HasValue) if (issueEndDate.HasValue == false)
throw new Exception("MRB Issue End Date cannot be blank"); throw new Exception("MRB Issue End Date cannot be blank");
MRB mrbData = new() { MRBNumber = mrbNumber, ToolCSV = tempMRBInfo.ToolCSV, IssueStartDate = tempMRBInfo.IssueStartDate, IssueEndDate = tempMRBInfo.IssueEndDate }; MRB mrbData = new() { MRBNumber = mrbNumber, ToolCSV = tempMRBInfo.ToolCSV, IssueStartDate = tempMRBInfo.IssueStartDate, IssueEndDate = tempMRBInfo.IssueEndDate };

View File

@ -166,7 +166,7 @@ public class WorkflowDMO {
sqlString.Append("SELECT COUNT(*) FROM LotDisposition LD INNER JOIN Lot L ON LD.IssueID = L.IssueID "); sqlString.Append("SELECT COUNT(*) FROM LotDisposition LD INNER JOIN Lot L ON LD.IssueID = L.IssueID ");
sqlString.Append("WHERE (PERequired = 1 OR Location = 'QDB' OR Location = 'EDB' ) AND LD.IssueID = @IssueID "); sqlString.Append("WHERE (PERequired = 1 OR Location = 'QDB' OR Location = 'EDB' ) AND LD.IssueID = @IssueID ");
recordCount = db.Query<int>(sqlString.ToString(), new { IssueID = issueID }).Single(); recordCount = db.Query<int>(sqlString.ToString(), new { IssueID = issueID }).Single();
if ((recordCount > 0) && (!allLotsAreScrap)) { if ((recordCount > 0) && (allLotsAreScrap == false)) {
// check if there any IG Medical products // check if there any IG Medical products
if (recordCountForIG_MA > 0) { if (recordCountForIG_MA > 0) {
sqlString = new StringBuilder(); sqlString = new StringBuilder();

View File

@ -2,7 +2,7 @@
*****Please DO NOT reply to this email***** *****Please DO NOT reply to this email*****
<br/><br/> <br/><br/>
{3}# {0} has been Cancelled. Please remove posted TECN from point of use. The cancellation date is {4} {3}# {0} has been Cancelled. Please remove posted TECN from point of use. The cancellation date is {4}
Please review comments below and ensure process has been returned to normal. Please review the cancelled TECN form in the attachment.
<br/><br/> <br/><br/>
https://messa016ec.infineon.com/ECN/Edit?issueID={1} https://messa016ec.infineon.com/ECN/Edit?issueID={1}
<br/><br/> <br/><br/>

View File

@ -2,7 +2,7 @@
*****Please DO NOT reply to this email***** *****Please DO NOT reply to this email*****
<br/><br/> <br/><br/>
{3}# {0} has been returned to process. Please remove posted TECN from point of use. The returned to process date is {4} {3}# {0} has been returned to process. Please remove posted TECN from point of use. The returned to process date is {4}
Please review comments below and ensure process has been returned to normal. Please review the returned to process TECN form in the attachment.
<br/><br/> <br/><br/>
https://messa016ec.infineon.com/ECN/Edit?issueID={1} https://messa016ec.infineon.com/ECN/Edit?issueID={1}
<br/><br/> <br/><br/>

View File

@ -325,6 +325,9 @@
<Compile Include="Models\WinEventLogModel.cs" /> <Compile Include="Models\WinEventLogModel.cs" />
<Compile Include="Models\WorkFlowModels.cs" /> <Compile Include="Models\WorkFlowModels.cs" />
<Compile Include="PdfGenerator\BinaryContentResult.cs" /> <Compile Include="PdfGenerator\BinaryContentResult.cs" />
<Compile Include="PdfGenerator\FakeView.cs" />
<Compile Include="PdfGenerator\HtmlViewRenderer.cs" />
<Compile Include="PdfGenerator\PdfViewController.cs" />
<Compile Include="PdfGenerator\PrintHeaderFooter.cs" /> <Compile Include="PdfGenerator\PrintHeaderFooter.cs" />
<Compile Include="PdfGenerator\StandardPdfRenderer.cs" /> <Compile Include="PdfGenerator\StandardPdfRenderer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />

View File

@ -1,54 +1,53 @@
#if NET8 #if !NET8
using ExcelDataReader;
#else
using Excel; using Excel;
#endif
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Web;
namespace Fab2ApprovalSystem.Misc; namespace Fab2ApprovalSystem.Misc {
public class ExcelData { public class ExcelData {
string _path;
private readonly string _Path;
public ExcelData(string path) { public ExcelData(string path) {
_Path = path; _path = path;
} }
public IExcelDataReader getExcelReader() { public IExcelDataReader getExcelReader() {
FileStream stream = File.Open(_Path, FileMode.Open, FileAccess.Read); // ExcelDataReader works with the binary Excel file, so it needs a FileStream
// to get started. This is how we avoid dependencies on ACE or Interop:
FileStream stream = File.Open(_path, FileMode.Open, FileAccess.Read);
// We return the interface, so that
IExcelDataReader reader = null; IExcelDataReader reader = null;
try { try {
if (_Path.EndsWith(".xls")) { if (_path.EndsWith(".xls")) {
reader = ExcelReaderFactory.CreateBinaryReader(stream); reader = ExcelReaderFactory.CreateBinaryReader(stream);
} }
if (_Path.EndsWith(".xlsx")) { if (_path.EndsWith(".xlsx")) {
reader = ExcelReaderFactory.CreateOpenXmlReader(stream); reader = ExcelReaderFactory.CreateOpenXmlReader(stream);
} }
return reader; return reader;
} catch (Exception) { } catch (Exception) {
throw; throw;
} }
} }
public class ExcelLotInfo { public class ExcelLotInfo {
public string? LotNo { get; set; } public string LotNo { get; set; }
public string? LotDispo { get; set; } public string LotDispo { get; set; }
} }
public IEnumerable<ExcelLotInfo> ReadData() { public IEnumerable<ExcelLotInfo> ReadData() {
List<ExcelLotInfo> r = new(); var r = new List<ExcelLotInfo>();
ExcelData excelData = new(_Path); var excelData = new ExcelData(_path);
List<DataRow> lots = excelData.getData().ToList(); var lots = excelData.getData().ToList();
int lotDispoColumnIndex = -1; int lotDispoColumnIndex = -1;
foreach (DataColumn col in lots[0].Table.Columns) { foreach (DataColumn col in lots[0].Table.Columns) {
@ -58,7 +57,7 @@ public class ExcelData {
} }
} }
foreach (DataRow row in lots) { foreach (var row in lots) {
string temValue = row[0].ToString(); string temValue = row[0].ToString();
if (temValue.Trim().Length > 0 && temValue.Trim().Length <= 10) { if (temValue.Trim().Length > 0 && temValue.Trim().Length <= 10) {
r.Add(new ExcelLotInfo() { r.Add(new ExcelLotInfo() {
@ -72,10 +71,11 @@ public class ExcelData {
} }
public IEnumerable<string> ReadQDBFlagData() { public IEnumerable<string> ReadQDBFlagData() {
List<string> s = new(); List<string> s = new List<string>();
ExcelData excelData = new(_Path); // We return the interface, so that
IEnumerable<DataRow> lotNos = excelData.getData(); var excelData = new ExcelData(_path);
foreach (DataRow row in lotNos) { var lotNos = excelData.getData();
foreach (var row in lotNos) {
string temValue = row[0].ToString(); string temValue = row[0].ToString();
if (temValue.Trim().Length > 0 && temValue.Trim().Length == 9) { if (temValue.Trim().Length > 0 && temValue.Trim().Length == 9) {
if (row[2].ToString().ToUpper() != "YES" && row[2].ToString().ToUpper() != "NO") { if (row[2].ToString().ToUpper() != "YES" && row[2].ToString().ToUpper() != "NO") {
@ -89,21 +89,16 @@ public class ExcelData {
return s; return s;
} }
#if NET8
public IEnumerable<DataRow> getData(bool firstRowIsColumnNames = true) =>
throw new NotImplementedException();
#else
public IEnumerable<DataRow> getData(bool firstRowIsColumnNames = true) { public IEnumerable<DataRow> getData(bool firstRowIsColumnNames = true) {
IExcelDataReader reader = getExcelReader(); var reader = this.getExcelReader();
reader.IsFirstRowAsColumnNames = firstRowIsColumnNames; reader.IsFirstRowAsColumnNames = firstRowIsColumnNames;
var workSheet = reader.AsDataSet().Tables[0]; var workSheet = reader.AsDataSet().Tables[0];
var rows = from DataRow a in workSheet.Rows select a; var rows = from DataRow a in workSheet.Rows select a;
return rows; return rows;
}
}
} }
#endif #endif
}

View File

@ -117,8 +117,8 @@ public class LotDispositionHelper {
public static void AttachSave(AppSettings appSettings, LotDispositionDMO lotDispositionDMO, int issueID, int userId, string fullFileName, Stream stream) { public static void AttachSave(AppSettings appSettings, LotDispositionDMO lotDispositionDMO, int issueID, int userId, string fullFileName, Stream stream) {
// Some browsers send file names with full path. // Some browsers send file names with full path.
// We are only interested in the file name. // We are only interested in the file name.
string fileName = Path.GetFileName(fullFileName); var fileName = Path.GetFileName(fullFileName);
string physicalPath = Path.Combine(appSettings.AttachmentFolder + "LotDisposition", fileName); var physicalPath = Path.Combine(appSettings.AttachmentFolder + "LotDisposition", fileName);
using (FileStream fileStream = new(physicalPath, FileMode.Create, FileAccess.Write)) { using (FileStream fileStream = new(physicalPath, FileMode.Create, FileAccess.Write)) {
stream.CopyTo(fileStream); stream.CopyTo(fileStream);
@ -134,7 +134,7 @@ public class LotDispositionHelper {
public static string ExcelLotOpen(LotDispositionDMO lotDispositionDMO, int issueID, string userIdentityName, string lotTempPipeLine, string fullFileName, Stream stream) { public static string ExcelLotOpen(LotDispositionDMO lotDispositionDMO, int issueID, string userIdentityName, string lotTempPipeLine, string fullFileName, Stream stream) {
string physicalPath; string physicalPath;
string fileExtension = Path.GetExtension(fullFileName); var fileExtension = Path.GetExtension(fullFileName);
string fName = userIdentityName + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString(); string fName = userIdentityName + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString();
physicalPath = Path.Combine(lotTempPipeLine, fName + "." + fileExtension); physicalPath = Path.Combine(lotTempPipeLine, fName + "." + fileExtension);
@ -142,18 +142,20 @@ public class LotDispositionHelper {
stream.CopyTo(fileStream); stream.CopyTo(fileStream);
} }
ExcelData x = new (physicalPath); #if !NET8
IEnumerable<ExcelData.ExcelLotInfo> lotNumbers = x.ReadData(); ExcelData x = new ExcelData(physicalPath);
var lotNumbers = x.ReadData();
foreach (ExcelData.ExcelLotInfo lotInfo in lotNumbers) { foreach (var lotInfo in lotNumbers) {
Lot l = new(); Lot l = new Lot();
l.LotNumber = lotInfo.LotNo ?? string.Empty; l.LotNumber = lotInfo.LotNo;
l.IssueID = issueID; l.IssueID = issueID;
if (l.LotStatusOptionID == 0) if (l.LotStatusOptionID == 0)
l.LotStatusOption.LotStatusOptionID = (int)GlobalVars.LotStatusOption.Release; l.LotStatusOption.LotStatusOptionID = (int)GlobalVars.LotStatusOption.Release;
lotDispositionDMO.InsertLot(l, true); lotDispositionDMO.InsertLot(l, true);
} }
#endif
FileInfo f = new(physicalPath); FileInfo f = new(physicalPath);
if (f.Exists) if (f.Exists)

View File

@ -46,12 +46,14 @@ public class MRBHelper {
stream.CopyTo(fileStream); stream.CopyTo(fileStream);
} }
ExcelData x = new(physicalPath); #if !NET8
ExcelData x = new ExcelData(physicalPath);
lotDataList = x.ReadQDBFlagData(); lotDataList = x.ReadQDBFlagData();
foreach (string lotData in lotDataList) { foreach (string lotData in lotDataList) {
mrbDMO.InsertMRB_QDB_HoldFlag(guid, lotData, operation); mrbDMO.InsertMRB_QDB_HoldFlag(guid, lotData, operation);
} }
#endif
FileInfo f = new(physicalPath); FileInfo f = new(physicalPath);
if (f.Exists) if (f.Exists)
@ -168,12 +170,14 @@ public class MRBHelper {
stream.CopyTo(fileStream); stream.CopyTo(fileStream);
} }
ExcelData x = new(physicalPath); #if !NET8
ExcelData x = new ExcelData(physicalPath);
lotDataList = x.ReadQDBFlagData(); lotDataList = x.ReadQDBFlagData();
foreach (string lotData in lotDataList) { foreach (string lotData in lotDataList) {
mrbDMO.InsertMRB_QDB_HoldFlag(guid, lotData, operation); mrbDMO.InsertMRB_QDB_HoldFlag(guid, lotData, operation);
} }
#endif
FileInfo f = new(physicalPath); FileInfo f = new(physicalPath);
if (f.Exists) if (f.Exists)
@ -242,16 +246,17 @@ public class MRBHelper {
string fName = userIdentityName + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString(); string fName = userIdentityName + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString();
string physicalPath = Path.Combine(lotTempPipeLine, fName + "." + fileExtension); string physicalPath = Path.Combine(lotTempPipeLine, fName + "." + fileExtension);
#if !NET8
IEnumerable<ExcelData.ExcelLotInfo> lotNumbers; IEnumerable<ExcelData.ExcelLotInfo> lotNumbers;
try { try {
using (FileStream fileStream = new(physicalPath, FileMode.Create, FileAccess.Write)) { using (var fileStream = new FileStream(physicalPath, FileMode.Create, FileAccess.Write)) {
stream.CopyTo(fileStream); stream.CopyTo(fileStream);
} }
ExcelData x = new(physicalPath); ExcelData x = new ExcelData(physicalPath);
lotNumbers = x.ReadData(); lotNumbers = x.ReadData();
} catch (Exception ex) { } catch (Exception ex) {
throw new Exception(string.Format("Invalid file format for {0}: {1}", fileName, ex.Message)); throw new Exception(String.Format("Invalid file format for {0}: {1}", fileName, ex.Message));
} }
// Get Tool, Issue Start and End Date // Get Tool, Issue Start and End Date
@ -261,7 +266,7 @@ public class MRBHelper {
foreach (var lotInfo in lotNumbers) { foreach (var lotInfo in lotNumbers) {
if (lotInfo.LotDispo.Length == 1) { if (lotInfo.LotDispo.Length == 1) {
if (dispos.Count(d => d.DispositionType.Trim().ToUpper() == lotInfo.LotDispo.Trim().ToUpper()) == 0) { if (dispos.Count(d => d.DispositionType.Trim().ToUpper() == lotInfo.LotDispo.Trim().ToUpper()) == 0) {
throw new Exception(string.Format("Invalid lot disposition {0} for lot no {1}", throw new Exception(String.Format("Invalid lot disposition {0} for lot no {1}",
lotInfo.LotDispo, lotInfo.LotNo)); lotInfo.LotDispo, lotInfo.LotNo));
} }
} }
@ -271,8 +276,8 @@ public class MRBHelper {
if (!mrbInfo.ToolCSV.ToUpper().Equals("NA")) { if (!mrbInfo.ToolCSV.ToUpper().Equals("NA")) {
foreach (var lotInfo in lotNumbers) { foreach (var lotInfo in lotNumbers) {
bool existingLotUpdated; bool existingLotUpdated;
Lot l = new(); Lot l = new Lot();
l.LotNumber = lotInfo.LotNo ?? string.Empty; l.LotNumber = lotInfo.LotNo;
if (lotInfo.LotDispo.Length == 1) { if (lotInfo.LotDispo.Length == 1) {
l.DispoType = lotInfo.LotDispo[0]; l.DispoType = lotInfo.LotDispo[0];
} }
@ -293,8 +298,8 @@ public class MRBHelper {
// Only find the child Splits when a Tool or a list of Tools is provided // Only find the child Splits when a Tool or a list of Tools is provided
foreach (var lotInfo in lotNumbers) { foreach (var lotInfo in lotNumbers) {
bool existingLotUpdated; bool existingLotUpdated;
Lot l = new(); Lot l = new Lot();
l.LotNumber = lotInfo.LotNo ?? string.Empty; l.LotNumber = lotInfo.LotNo;
if (lotInfo.LotDispo.Length == 1) { if (lotInfo.LotDispo.Length == 1) {
l.DispoType = lotInfo.LotDispo[0]; l.DispoType = lotInfo.LotDispo[0];
} }
@ -303,6 +308,7 @@ public class MRBHelper {
mrbDMO.InsertLot(l, true, out existingLotUpdated); mrbDMO.InsertLot(l, true, out existingLotUpdated);
} }
} }
#endif
FileInfo f = new(physicalPath); FileInfo f = new(physicalPath);
if (f.Exists) if (f.Exists)

View File

@ -0,0 +1,28 @@
#if !NET8
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="FakeView.cs" company="SemanticArchitecture">
// http://www.SemanticArchitecture.net pkalkie@gmail.com
// </copyright>
// <summary>
// Defines the FakeView type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Fab2ApprovalSystem.PdfGenerator {
using System;
using System.IO;
using System.Web.Mvc;
public class FakeView : IView {
#region IView Members
public void Render(ViewContext viewContext, TextWriter writer) {
throw new NotImplementedException();
}
#endregion
}
}
#endif

View File

@ -0,0 +1,49 @@
#if !NET8
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="HtmlViewRenderer.cs" company="SemanticArchitecture">
// http://www.SemanticArchitecture.net pkalkie@gmail.com
// </copyright>
// <summary>
// This class is responsible for rendering a HTML view to a string.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Fab2ApprovalSystem.PdfGenerator {
using System.IO;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
/// <summary>
/// This class is responsible for rendering a HTML view into a string.
/// </summary>
public class HtmlViewRenderer {
public string RenderViewToString(Controller controller, string viewName, object viewData) {
var renderedView = new StringBuilder();
using (var responseWriter = new StringWriter(renderedView)) {
var fakeResponse = new HttpResponse(responseWriter);
var fakeContext = new HttpContext(HttpContext.Current.Request, fakeResponse);
var fakeControllerContext = new ControllerContext(new HttpContextWrapper(fakeContext), controller.ControllerContext.RouteData, controller.ControllerContext.Controller);
var oldContext = HttpContext.Current;
HttpContext.Current = fakeContext;
using (var viewPage = new ViewPage()) {
var html = new HtmlHelper(CreateViewContext(responseWriter, fakeControllerContext), viewPage);
html.RenderPartial(viewName, viewData);
HttpContext.Current = oldContext;
}
}
return renderedView.ToString();
}
private static ViewContext CreateViewContext(TextWriter responseWriter, ControllerContext fakeControllerContext) {
return new ViewContext(fakeControllerContext, new FakeView(), new ViewDataDictionary(), new TempDataDictionary(), responseWriter);
}
}
}
#endif

View File

@ -0,0 +1,54 @@
#if !NET8
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="PdfViewController.cs" company="SemanticArchitecture">
// http://www.SemanticArchitecture.net pkalkie@gmail.com
// </copyright>
// <summary>
// Extends the controller with functionality for rendering PDF views
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Fab2ApprovalSystem.PdfGenerator {
using System.Web.Mvc;
using System.IO;
/// <summary>
/// Extends the controller with functionality for rendering PDF views
/// </summary>
public class PdfViewController : Controller {
private readonly HtmlViewRenderer htmlViewRenderer;
private readonly StandardPdfRenderer standardPdfRenderer;
public PdfViewController() {
this.htmlViewRenderer = new HtmlViewRenderer();
this.standardPdfRenderer = new StandardPdfRenderer();
}
protected ActionResult ViewPdf(string pageTitle, string viewName, object model) {
// Render the view html to a string.
string htmlText = this.htmlViewRenderer.RenderViewToString(this, viewName, model);
// Let the html be rendered into a PDF document through iTextSharp.
byte[] buffer = standardPdfRenderer.Render(htmlText, pageTitle);
// Return the PDF as a binary stream to the client.
return new BinaryContentResult(buffer, "application/pdf");
}
protected void SavePdf(string fileName, string viewName, object model) {
// Render the view html to a string.
string htmlText = this.htmlViewRenderer.RenderViewToString(this, viewName, model);
// Let the html be rendered into a PDF document through iTextSharp.
byte[] buffer = standardPdfRenderer.Render(htmlText, "");
using (FileStream fs = new FileStream(fileName, FileMode.Create)) {
fs.Write(buffer, 0, buffer.Length);
}
}
}
}
#endif

View File

@ -1,38 +1,27 @@
#if !NET8
using iTextSharp.text; using iTextSharp.text;
using iTextSharp.text.html.simpleparser; using iTextSharp.text.html.simpleparser;
using iTextSharp.text.pdf; using iTextSharp.text.pdf;
#endif
using System.IO; using System.IO;
namespace Fab2ApprovalSystem.PdfGenerator; namespace Fab2ApprovalSystem.PdfGenerator;
/// <summary>
/// This class is responsible for rendering a html text string to a PDF document using the html renderer of iTextSharp.
/// </summary>
public class StandardPdfRenderer { public class StandardPdfRenderer {
private const int HorizontalMargin = 40; private const int HorizontalMargin = 40;
private const int VerticalMargin = 40; private const int VerticalMargin = 40;
public static byte[] GetPortableDocumentFormatBytes(string pageTitle, string htmlText) { public byte[] Render(string htmlText, string pageTitle) {
byte[] results; byte[] renderedBuffer;
using (MemoryStream memoryStream = GetPortableDocumentFormat(pageTitle, htmlText)) {
results = new byte[memoryStream.Position];
memoryStream.Position = 0;
memoryStream.Read(results, 0, results.Length);
}
return results;
}
public static void WritePortableDocumentFormatToFile(string pageTitle, string htmlText, string path) { using (MemoryStream outputMemoryStream = new()) {
using (MemoryStream memoryStream = GetPortableDocumentFormat(pageTitle, htmlText)) { #if !NET8
using (FileStream fileStream = new(path, FileMode.Create)) {
memoryStream.CopyTo(fileStream);
}
}
}
public static MemoryStream GetPortableDocumentFormat(string pageTitle, string htmlText) {
MemoryStream result = new();
using (Document pdfDocument = new Document(PageSize.A4, HorizontalMargin, HorizontalMargin, VerticalMargin, VerticalMargin)) { using (Document pdfDocument = new Document(PageSize.A4, HorizontalMargin, HorizontalMargin, VerticalMargin, VerticalMargin)) {
using (PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDocument, result)) { PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDocument, outputMemoryStream);
pdfWriter.CloseStream = false; pdfWriter.CloseStream = false;
pdfWriter.PageEvent = new PrintHeaderFooter { Title = pageTitle }; pdfWriter.PageEvent = new PrintHeaderFooter { Title = pageTitle };
pdfDocument.Open(); pdfDocument.Open();
@ -41,9 +30,15 @@ public class StandardPdfRenderer {
htmlWorker.Parse(htmlViewReader); htmlWorker.Parse(htmlViewReader);
} }
} }
}
}
return result;
}
} }
#endif
renderedBuffer = new byte[outputMemoryStream.Position];
outputMemoryStream.Position = 0;
outputMemoryStream.Read(renderedBuffer, 0, renderedBuffer.Length);
}
return renderedBuffer;
}
}

View File

@ -30,7 +30,7 @@ public class ECNPdf {
public string AffectedDepartments { get; set; } public string AffectedDepartments { get; set; }
public string AffectedAreas { get; set; } public string AffectedAreas { get; set; }
public string AffectedTechnologies { get; set; } public string AffectedTechnologies { get; set; }
public List<int> TrainingByIDs { get; set; } public string TrainingBy { get; set; }
public string AcknowledgementBy { get; set; } public string AcknowledgementBy { get; set; }
public bool IsECN { get; set; } public bool IsECN { get; set; }
public bool IsTECN { get; set; } public bool IsTECN { get; set; }
@ -79,7 +79,6 @@ public class ECNPdf {
public int? ConvertedToNumber { get; set; } public int? ConvertedToNumber { get; set; }
public int? ConvertedFromNumber { get; set; } public int? ConvertedFromNumber { get; set; }
public int WorkFlowNumber { get; set; } public int WorkFlowNumber { get; set; }
public int? CategoryID { get; set; }
public bool FIChangeRequired { get; set; } public bool FIChangeRequired { get; set; }
public string NumberOfLotsAffected { get; set; } public string NumberOfLotsAffected { get; set; }
public string RecipeChange { get; set; } public string RecipeChange { get; set; }
@ -88,7 +87,6 @@ public class ECNPdf {
public ECNPdf() { public ECNPdf() {
Approvalog = new List<ECNApprovalLog>(); Approvalog = new List<ECNApprovalLog>();
Attachments = new List<string>(); Attachments = new List<string>();
TrainingByIDs = new List<int>();
} }
} }

View File

@ -213,7 +213,7 @@
*(DO NOT USE Rev I, O, Q, S, X, and Z) *(DO NOT USE Rev I, O, Q, S, X, and Z)
</div> </div>
<div class="col-sm-6 col-sm-offset-4" style="color: red;"> <div class="col-sm-6 col-sm-offset-4" style="color: red;">
Revision Y is followed by AA-AY, AY is followed by BA-BY etc. YY is followed by AAA Revision Y is followed by AA. YY is followed by AAA
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -1,18 +1,4 @@
@model Fab2ApprovalSystem.ViewModels.ECNPdf @model Fab2ApprovalSystem.ViewModels.ECNPdf
@{
Layout = null;
}
<!DOCTYPE html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
</head>
<body class="navbar-inner">
<table style="width:100%;"> <table style="width:100%;">
<tr> <tr>
<td> <td>
@ -98,16 +84,6 @@
</font> </font>
</td> </td>
</tr> </tr>
<tr>
<td>
<font size="2">
Category:&nbsp;
</font>
<font size="1">
@(ViewBag.Category)
</font>
</td>
</tr>
<tr> <tr>
<td> <td>
<font size="2"> <font size="2">
@ -121,6 +97,7 @@
</table> </table>
</td> </td>
</tr> </tr>
</table> </table>
</td> </td>
</tr> </tr>
@ -240,6 +217,7 @@
</td> </td>
</tr> </tr>
</table> </table>
</td> </td>
</tr> </tr>
@ -266,6 +244,35 @@
</table> </table>
</td> </td>
</tr> </tr>
@*<tr>
<td>
<table border="1">
<tr bgcolor="#c4baba" color="#000000">
<td colspan="3">Training Notification</td>
</tr>
<tr>
<td>
<table border="0">
<tr>
<td>
<font size="1">
Training:
@(Model.TrainingRequired ? "Yes" : "No")
</font>
<font size="1">
@(Model.TrainingBy.Length > 0 ? "(" + Model.TrainingBy + ")" : Model.TrainingBy)
</font>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>*@
<tr> <tr>
<td> <td>
@ -320,35 +327,11 @@
@(Model.SPNChangeRequired ? "Yes" : "No") @(Model.SPNChangeRequired ? "Yes" : "No")
</font> </font>
</td> </td>
<td></td>
</tr> </tr>
</table> </table>
</td>
</tr>
<tr>
<td>
<table border="1">
<tr bgcolor="#c4baba" color="#000000">
<td colspan="1">Training Notification</td>
</tr>
<tr style="display:block;">
<td>
<font size="2">
Training:
</font>
<font size="1">
@(Model.TrainingRequired ? "Yes" : "No")
</font>
</td>
<td>
<font size="2">
Training Notification to: &nbsp;
@(ViewBag.TrainingNotificationTo)
</font>
</td>
</tr>
</table>
</td> </td>
</tr> </tr>
@ -496,11 +479,19 @@
</tr> </tr>
} }
</table> </table>
</td> </td>
</tr> </tr>
</table>
</body>
</html> </table> <!--main table -->

View File

@ -157,7 +157,7 @@
*(DO NOT USE Rev I, O, Q, S, X, and Z) *(DO NOT USE Rev I, O, Q, S, X, and Z)
</div> </div>
<div class="col-sm-6 col-sm-offset-4" style="color: red;"> <div class="col-sm-6 col-sm-offset-4" style="color: red;">
Revision Y is followed by AA-AY, AY is followed by BA-BY etc. YY is followed by AAA Revision Y is followed by AA. YY is followed by AAA
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -263,7 +263,7 @@
*(DO NOT USE Rev I, O, Q, S, X, and Z) *(DO NOT USE Rev I, O, Q, S, X, and Z)
</div> </div>
<div class="col-sm-6 col-sm-offset-4" style="color: red;"> <div class="col-sm-6 col-sm-offset-4" style="color: red;">
Revision Y is followed by AA-AY, AY is followed by BA-BY etc. YY is followed by AAA Revision Y is followed by AA. YY is followed by AAA
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">

View File

@ -90,16 +90,16 @@
string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken);
string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ??
"https://localhost:7255"; "https://localhost:7255";
string mrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=mrb/new"; string mrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=/mrb/new";
<li><a href="@mrbUrl">Create MRB</a></li> <li><a href="@mrbUrl">Create MRB</a></li>
string pcrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=pcrb/new"; string pcrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=/pcrb/new";
<li><a href="@pcrbUrl">Create PCRB</a></li> <li><a href="@pcrbUrl">Create PCRB</a></li>
} else { } else {
string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ??
"https://localhost:7255"; "https://localhost:7255";
string mrbUrl = wasmClientUrl + "/redirect?redirectPath=mrb/new"; string mrbUrl = wasmClientUrl + "/redirect?redirectPath=/mrb/new";
<li><a href="@mrbUrl">Create MRB</a></li> <li><a href="@mrbUrl">Create MRB</a></li>
string pcrbUrl = wasmClientUrl + "/redirect?redirectPath=pcrb/new"; string pcrbUrl = wasmClientUrl + "/redirect?redirectPath=/pcrb/new";
<li><a href="@pcrbUrl">Create PCRB</a></li> <li><a href="@pcrbUrl">Create PCRB</a></li>
} }
@*<li><a href=@Url.Action("CreateWorkRequest", "LotTraveler")>Create Special Work Request</a></li>*@ @*<li><a href=@Url.Action("CreateWorkRequest", "LotTraveler")>Create Special Work Request</a></li>*@
@ -150,9 +150,9 @@
string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken);
string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ??
"https://localhost:7255"; "https://localhost:7255";
string mrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=mrb/all"; string mrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=/mrb/all";
menu.Add().Text("MRB").Url(mrbUrl); menu.Add().Text("MRB").Url(mrbUrl);
string pcrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=pcrb/all"; string pcrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=/pcrb/all";
menu.Add().Text("PCRB").Url(pcrbUrl); menu.Add().Text("PCRB").Url(pcrbUrl);
//menu.Add().Text("Special Work Requests").Action("SpecialWorkRequestList", "Home"); //menu.Add().Text("Special Work Requests").Action("SpecialWorkRequestList", "Home");
//menu.Add().Text("PCRB").Action("ChangeControlList", "Home"); //menu.Add().Text("PCRB").Action("ChangeControlList", "Home");

View File

@ -1,232 +0,0 @@
trigger:
branches:
include:
- master
paths:
include:
- Fab2ApprovalSystem
variables:
coreVersion: "net8.0"
targetFrameworkVersion: "v4.8"
nugetSource: "https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/"
msBuild: "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe"
stages:
- stage: Development
displayName: Development
pool:
name: MesaFabApproval
demands: Fab2ApprovalSystem-Dev
variables:
ASPNETCORE_ENVIRONMENT: "Development"
assemblyTitle: "Fab2ApprovalSystem"
configuration: "Debug"
jobs:
- job: DebugDotnet
steps:
- script: |
echo BuildId: $(Build.BuildId)
echo Build reason: $(Build.Reason)
echo Repo Id: $(Build.Repository.Id)
echo Repo name: $(Build.Repository.Name)
echo Source version: $(Build.SourceVersion)
echo Core version: $(CoreVersion)
echo Configuration: $(Configuration)
echo Target Framework version: $(TargetFrameworkVersion)
echo Assembly title: $(AssemblyTitle)
echo MicrosoftBuildEngine: $(msBuild)
echo NugetSource: $(NugetSource)
displayName: "Echo Check"
- script: |
mklink /J ".vscode\.UserSecrets" "%AppData%\Microsoft\UserSecrets\f2da5035-aba9-4676-9f8d-d6689f84663d"
mklink /J "DMO" "..\Fab2ApprovalSystem\DMO"
mklink /J "Jobs" "..\Fab2ApprovalSystem\Jobs"
mklink /J "JobSchedules" "..\Fab2ApprovalSystem\JobSchedules"
mklink /J "Misc" "..\Fab2ApprovalSystem\Misc"
mklink /J "Models" "..\Fab2ApprovalSystem\Models"
mklink /J "PdfGenerator" "..\Fab2ApprovalSystem\PdfGenerator"
mklink /J "Utilities" "..\Fab2ApprovalSystem\Utilities"
mklink /J "ViewModels" "..\Fab2ApprovalSystem\ViewModels"
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Symbolic Link of Type Junction"
- script: |
dotnet user-secrets init
dotnet user-secrets set BuildNumber $(Build.BuildId)
dotnet user-secrets set "GitCommit" "$(Build.SourceVersion)"
dotnet user-secrets list
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Safe storage of app secrets"
- script: dotnet build --configuration $(Configuration) --source $(NugetSource)
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Build"
- script: dotnet build --configuration $(Configuration) --source $(NugetSource)
workingDirectory: Fab2ApprovalTests
displayName: "Tests - Build"
- script: dotnet test --configuration $(Configuration)
workingDirectory: Fab2ApprovalTests
displayName: "Tests - Test"
- script: dotnet clean --configuration $(Configuration)
workingDirectory: Fab2ApprovalTests
displayName: "Tests - Clean"
- script: dotnet clean --configuration $(Configuration)
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Clean"
- job: DebugMicrosoftBuildEngine
steps:
- script: |
echo BuildId: $(Build.BuildId)
echo Build reason: $(Build.Reason)
echo Repo Id: $(Build.Repository.Id)
echo Repo name: $(Build.Repository.Name)
echo Source version: $(Build.SourceVersion)
echo Core version: $(CoreVersion)
echo Configuration: $(Configuration)
echo Target Framework version: $(TargetFrameworkVersion)
echo Assembly title: $(AssemblyTitle)
echo MicrosoftBuildEngine: $(msBuild)
echo NugetSource: $(NugetSource)
displayName: "Echo Check"
- script: '"$(msBuild)" /target:Restore /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:RestoreSources=$(NugetSource) $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Restore"
- script: '"$(msBuild)" /target:Build /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Build"
- script: '"$(msBuild)" /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:DebugSymbols=false /p:DeleteExistingFiles=true /p:DeployOnBuild=true /p:EnableUpdateAble=true /p:ExcludeApp_Data=true /p:LastUsedconfiguration=$(Configuration) /p:LastUsedPlatform="Any CPU" /p:LaunchSiteAfterPublish=true /p:OutputPath=bin/$(Configuration) /p:PreCompileBeforePublish=true /p:PublishProvider=FileSystem /p:PublishUrl="D:/PublishUrl" /p:SiteUrlToLaunchAfterPublish="" /p:WDPMergeOption=DoNotMerge /p:WebPublishMethod=FileSystem $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Package (.zip for msdeploy.exe)"
- task: CopyFiles@2
displayName: 'Copy Files to: D:\'
inputs:
Contents: "*"
SourceFolder: '$(AssemblyTitle)\bin\$(Configuration)\_PublishedWebsites\$(AssemblyTitle)_Package'
TargetFolder: 'D:\$(TargetFrameworkVersion)\$(Build.Repository.Name)\$(Build.BuildId)\$(Configuration)-$(AssemblyTitle)-Package'
OverWrite: true
- script: '"$(msBuild)" /target:Clean /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Clean"
- stage: Release
displayName: Release
pool:
name: MesaFabApproval
demands: Fab2ApprovalSystem
variables:
ASPNETCORE_ENVIRONMENT: "Production"
assemblyTitle: "Fab2ApprovalSystem"
configuration: "Release"
jobs:
- job: ReleaseDotnet
steps:
- script: |
echo BuildId: $(Build.BuildId)
echo Build reason: $(Build.Reason)
echo Repo Id: $(Build.Repository.Id)
echo Repo name: $(Build.Repository.Name)
echo Source version: $(Build.SourceVersion)
echo Core version: $(CoreVersion)
echo Configuration: $(Configuration)
echo Target Framework version: $(TargetFrameworkVersion)
echo Assembly title: $(AssemblyTitle)
echo MicrosoftBuildEngine: $(msBuild)
echo NugetSource: $(NugetSource)
displayName: "Echo Check"
- script: |
mklink /J ".vscode\.UserSecrets" "%AppData%\Microsoft\UserSecrets\f2da5035-aba9-4676-9f8d-d6689f84663d"
mklink /J "DMO" "..\Fab2ApprovalSystem\DMO"
mklink /J "Jobs" "..\Fab2ApprovalSystem\Jobs"
mklink /J "JobSchedules" "..\Fab2ApprovalSystem\JobSchedules"
mklink /J "Misc" "..\Fab2ApprovalSystem\Misc"
mklink /J "Models" "..\Fab2ApprovalSystem\Models"
mklink /J "PdfGenerator" "..\Fab2ApprovalSystem\PdfGenerator"
mklink /J "Utilities" "..\Fab2ApprovalSystem\Utilities"
mklink /J "ViewModels" "..\Fab2ApprovalSystem\ViewModels"
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Symbolic Link of Type Junction"
- script: |
dotnet user-secrets init
dotnet user-secrets set BuildNumber $(Build.BuildId)
dotnet user-secrets set "GitCommit" "$(Build.SourceVersion)"
dotnet user-secrets list
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Safe storage of app secrets"
- script: dotnet build --configuration $(Configuration) --source $(NugetSource)
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Build"
- script: dotnet build --configuration $(Configuration) --source $(NugetSource)
workingDirectory: Fab2ApprovalTests
displayName: "Tests - Build"
- script: dotnet test --configuration $(Configuration)
workingDirectory: Fab2ApprovalTests
displayName: "Tests - Test"
- script: dotnet clean --configuration $(Configuration)
workingDirectory: Fab2ApprovalTests
displayName: "Tests - Clean"
- script: dotnet clean --configuration $(Configuration)
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Clean"
- job: ReleaseMicrosoftBuildEngine
steps:
- script: |
echo BuildId: $(Build.BuildId)
echo Build reason: $(Build.Reason)
echo Repo Id: $(Build.Repository.Id)
echo Repo name: $(Build.Repository.Name)
echo Source version: $(Build.SourceVersion)
echo Core version: $(CoreVersion)
echo Configuration: $(Configuration)
echo Target Framework version: $(TargetFrameworkVersion)
echo Assembly title: $(AssemblyTitle)
echo MicrosoftBuildEngine: $(msBuild)
echo NugetSource: $(NugetSource)
displayName: "Echo Check"
- script: '"$(msBuild)" /target:Restore /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:RestoreSources=$(NugetSource) $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Restore"
- script: '"$(msBuild)" /target:Build /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Build"
- script: '"$(msBuild)" /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:DebugSymbols=false /p:DeleteExistingFiles=true /p:DeployOnBuild=true /p:EnableUpdateAble=true /p:ExcludeApp_Data=true /p:LastUsedconfiguration=$(Configuration) /p:LastUsedPlatform="Any CPU" /p:LaunchSiteAfterPublish=true /p:OutputPath=bin/$(Configuration) /p:PreCompileBeforePublish=true /p:PublishProvider=FileSystem /p:PublishUrl="D:/PublishUrl" /p:SiteUrlToLaunchAfterPublish="" /p:WDPMergeOption=DoNotMerge /p:WebPublishMethod=FileSystem $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Package (.zip for msdeploy.exe)"
- task: CopyFiles@2
displayName: 'Copy Files to: D:\'
inputs:
Contents: "*"
SourceFolder: '$(AssemblyTitle)\bin\$(Configuration)\_PublishedWebsites\$(AssemblyTitle)_Package'
TargetFolder: 'D:\$(TargetFrameworkVersion)\$(Build.Repository.Name)\$(Build.BuildId)\$(Configuration)-$(AssemblyTitle)-Package'
OverWrite: true
- script: '"$(msBuild)" /target:Clean /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Clean"
- script: 'echo $(Build.BuildId)-$(Build.SourceVersion)-bin_x_x_\$(Configuration)\$(CoreVersion)\win-x64\$(Build.Repository.Name).txt'
displayName: "Force Fail"
enabled: true

View File

@ -1,239 +0,0 @@
trigger:
branches:
include:
- master
paths:
include:
- "Fab2ApprovalSystem/*"
exclude:
- "**/*.yaml"
- "**/*.yml"
- "SQL/*"
- "references/*"
- "packages/*"
- "Kendo/*"
variables:
coreVersion: "net8.0"
targetFrameworkVersion: "v4.8"
nugetSource: "https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/"
msBuild: "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe"
stages:
- stage: Development
displayName: Development
pool:
name: MesaFabApproval
demands: Fab2ApprovalSystem-Dev
variables:
ASPNETCORE_ENVIRONMENT: "Development"
assemblyTitle: "Fab2ApprovalSystem"
configuration: "Debug"
jobs:
- job: DebugDotnet
steps:
- script: |
echo BuildId: $(Build.BuildId)
echo Build reason: $(Build.Reason)
echo Repo Id: $(Build.Repository.Id)
echo Repo name: $(Build.Repository.Name)
echo Source version: $(Build.SourceVersion)
echo Core version: $(CoreVersion)
echo Configuration: $(Configuration)
echo Target Framework version: $(TargetFrameworkVersion)
echo Assembly title: $(AssemblyTitle)
echo MicrosoftBuildEngine: $(msBuild)
echo NugetSource: $(NugetSource)
displayName: "Echo Check"
- script: |
mklink /J ".vscode\.UserSecrets" "%AppData%\Microsoft\UserSecrets\f2da5035-aba9-4676-9f8d-d6689f84663d"
mklink /J "DMO" "..\Fab2ApprovalSystem\DMO"
mklink /J "Jobs" "..\Fab2ApprovalSystem\Jobs"
mklink /J "JobSchedules" "..\Fab2ApprovalSystem\JobSchedules"
mklink /J "Misc" "..\Fab2ApprovalSystem\Misc"
mklink /J "Models" "..\Fab2ApprovalSystem\Models"
mklink /J "PdfGenerator" "..\Fab2ApprovalSystem\PdfGenerator"
mklink /J "Utilities" "..\Fab2ApprovalSystem\Utilities"
mklink /J "ViewModels" "..\Fab2ApprovalSystem\ViewModels"
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Symbolic Link of Type Junction"
- script: |
dotnet user-secrets init
dotnet user-secrets set BuildNumber $(Build.BuildId)
dotnet user-secrets set "GitCommit" "$(Build.SourceVersion)"
dotnet user-secrets list
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Safe storage of app secrets"
- script: dotnet build --configuration $(Configuration) --source $(NugetSource)
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Build"
- script: dotnet build --configuration $(Configuration) --source $(NugetSource)
workingDirectory: Fab2ApprovalTests
displayName: "Tests - Build"
- script: dotnet test --configuration $(Configuration)
workingDirectory: Fab2ApprovalTests
displayName: "Tests - Test"
- script: dotnet clean --configuration $(Configuration)
workingDirectory: Fab2ApprovalTests
displayName: "Tests - Clean"
- script: dotnet clean --configuration $(Configuration)
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Clean"
- job: DebugMicrosoftBuildEngine
steps:
- script: |
echo BuildId: $(Build.BuildId)
echo Build reason: $(Build.Reason)
echo Repo Id: $(Build.Repository.Id)
echo Repo name: $(Build.Repository.Name)
echo Source version: $(Build.SourceVersion)
echo Core version: $(CoreVersion)
echo Configuration: $(Configuration)
echo Target Framework version: $(TargetFrameworkVersion)
echo Assembly title: $(AssemblyTitle)
echo MicrosoftBuildEngine: $(msBuild)
echo NugetSource: $(NugetSource)
displayName: "Echo Check"
- script: '"$(msBuild)" /target:Restore /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:RestoreSources=$(NugetSource) $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Restore"
- script: '"$(msBuild)" /target:Build /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Build"
- script: '"$(msBuild)" /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:DebugSymbols=false /p:DeleteExistingFiles=true /p:DeployOnBuild=true /p:EnableUpdateAble=true /p:ExcludeApp_Data=true /p:LastUsedconfiguration=$(Configuration) /p:LastUsedPlatform="Any CPU" /p:LaunchSiteAfterPublish=true /p:OutputPath=bin/$(Configuration) /p:PreCompileBeforePublish=true /p:PublishProvider=FileSystem /p:PublishUrl="D:/PublishUrl" /p:SiteUrlToLaunchAfterPublish="" /p:WDPMergeOption=DoNotMerge /p:WebPublishMethod=FileSystem $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Package (.zip for msdeploy.exe)"
- task: CopyFiles@2
displayName: 'Copy Files to: D:\'
inputs:
Contents: "*"
SourceFolder: '$(AssemblyTitle)\bin\$(Configuration)\_PublishedWebsites\$(AssemblyTitle)_Package'
TargetFolder: 'D:\$(TargetFrameworkVersion)\$(Build.Repository.Name)\$(Build.BuildId)\$(Configuration)-$(AssemblyTitle)-Package'
OverWrite: true
- script: '"$(msBuild)" /target:Clean /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Clean"
- stage: Release
displayName: Release
pool:
name: MesaFabApproval
demands: Fab2ApprovalSystem
variables:
ASPNETCORE_ENVIRONMENT: "Production"
assemblyTitle: "Fab2ApprovalSystem"
configuration: "Release"
jobs:
- job: ReleaseDotnet
steps:
- script: |
echo BuildId: $(Build.BuildId)
echo Build reason: $(Build.Reason)
echo Repo Id: $(Build.Repository.Id)
echo Repo name: $(Build.Repository.Name)
echo Source version: $(Build.SourceVersion)
echo Core version: $(CoreVersion)
echo Configuration: $(Configuration)
echo Target Framework version: $(TargetFrameworkVersion)
echo Assembly title: $(AssemblyTitle)
echo MicrosoftBuildEngine: $(msBuild)
echo NugetSource: $(NugetSource)
displayName: "Echo Check"
- script: |
mklink /J ".vscode\.UserSecrets" "%AppData%\Microsoft\UserSecrets\f2da5035-aba9-4676-9f8d-d6689f84663d"
mklink /J "DMO" "..\Fab2ApprovalSystem\DMO"
mklink /J "Jobs" "..\Fab2ApprovalSystem\Jobs"
mklink /J "JobSchedules" "..\Fab2ApprovalSystem\JobSchedules"
mklink /J "Misc" "..\Fab2ApprovalSystem\Misc"
mklink /J "Models" "..\Fab2ApprovalSystem\Models"
mklink /J "PdfGenerator" "..\Fab2ApprovalSystem\PdfGenerator"
mklink /J "Utilities" "..\Fab2ApprovalSystem\Utilities"
mklink /J "ViewModels" "..\Fab2ApprovalSystem\ViewModels"
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Symbolic Link of Type Junction"
- script: |
dotnet user-secrets init
dotnet user-secrets set BuildNumber $(Build.BuildId)
dotnet user-secrets set "GitCommit" "$(Build.SourceVersion)"
dotnet user-secrets list
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Safe storage of app secrets"
- script: dotnet build --configuration $(Configuration) --source $(NugetSource)
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Build"
- script: dotnet build --configuration $(Configuration) --source $(NugetSource)
workingDirectory: Fab2ApprovalTests
displayName: "Tests - Build"
- script: dotnet test --configuration $(Configuration)
workingDirectory: Fab2ApprovalTests
displayName: "Tests - Test"
- script: dotnet clean --configuration $(Configuration)
workingDirectory: Fab2ApprovalTests
displayName: "Tests - Clean"
- script: dotnet clean --configuration $(Configuration)
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Clean"
- job: ReleaseMicrosoftBuildEngine
steps:
- script: |
echo BuildId: $(Build.BuildId)
echo Build reason: $(Build.Reason)
echo Repo Id: $(Build.Repository.Id)
echo Repo name: $(Build.Repository.Name)
echo Source version: $(Build.SourceVersion)
echo Core version: $(CoreVersion)
echo Configuration: $(Configuration)
echo Target Framework version: $(TargetFrameworkVersion)
echo Assembly title: $(AssemblyTitle)
echo MicrosoftBuildEngine: $(msBuild)
echo NugetSource: $(NugetSource)
displayName: "Echo Check"
- script: '"$(msBuild)" /target:Restore /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:RestoreSources=$(NugetSource) $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Restore"
- script: '"$(msBuild)" /target:Build /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Build"
- script: '"$(msBuild)" /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:DebugSymbols=false /p:DeleteExistingFiles=true /p:DeployOnBuild=true /p:EnableUpdateAble=true /p:ExcludeApp_Data=true /p:LastUsedconfiguration=$(Configuration) /p:LastUsedPlatform="Any CPU" /p:LaunchSiteAfterPublish=true /p:OutputPath=bin/$(Configuration) /p:PreCompileBeforePublish=true /p:PublishProvider=FileSystem /p:PublishUrl="D:/PublishUrl" /p:SiteUrlToLaunchAfterPublish="" /p:WDPMergeOption=DoNotMerge /p:WebPublishMethod=FileSystem $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Package (.zip for msdeploy.exe)"
- task: CopyFiles@2
displayName: 'Copy Files to: D:\'
inputs:
Contents: "*"
SourceFolder: '$(AssemblyTitle)\bin\$(Configuration)\_PublishedWebsites\$(AssemblyTitle)_Package'
TargetFolder: 'D:\$(TargetFrameworkVersion)\$(Build.Repository.Name)\$(Build.BuildId)\$(Configuration)-$(AssemblyTitle)-Package'
OverWrite: true
- script: '"$(msBuild)" /target:Clean /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Clean"
- script: 'echo $(Build.BuildId)-$(Build.SourceVersion)-bin_x_x_\$(Configuration)\$(CoreVersion)\win-x64\$(Build.Repository.Name).txt'
displayName: "Force Fail"
enabled: true

View File

@ -51,7 +51,7 @@ public class AuditDMOTests {
try { throw new Exception(); } catch (Exception) { } try { throw new Exception(); } catch (Exception) { }
} }
private static void AuditDMO(ILogger? logger, AppSettings appSettings, int auditNo, bool isAdmin) { private static void AuditDMO(ILogger? logger, AppSettings appSettings) {
#pragma warning disable IDE0059 #pragma warning disable IDE0059
SetGlobalVars(logger, appSettings); SetGlobalVars(logger, appSettings);
AuditDMO auditDMO = new(appSettings); AuditDMO auditDMO = new(appSettings);
@ -61,25 +61,25 @@ public class AuditDMOTests {
AuditedArea[] auditedAreas = auditDMO.GetAuditAreaList().ToArray(); AuditedArea[] auditedAreas = auditDMO.GetAuditAreaList().ToArray();
// IEnumerable<int> GetAuditFindingCategoryIdsByFindingId(int auditFindingsID); // IEnumerable<int> GetAuditFindingCategoryIdsByFindingId(int auditFindingsID);
// AuditFindings GetAuditFindingsByID(int auditFindingsID); // AuditFindings GetAuditFindingsByID(int auditFindingsID);
AuditFindings[] auditFindings = auditDMO.GetAuditFindingsList(auditNo).ToArray(); // IEnumerable<AuditFindings> GetAuditFindingsList(int auditNo);
Audit auditB = auditDMO.GetAuditItem(auditNo, appSettings.UserId); // Audit GetAuditItem(int auditNo, appSettings.UserId);
Audit auditC = new(); // Audit GetAuditItemReadOnly(int auditNo, appSettings.UserId);
AuditEdit auditEdit = auditDMO.GetAuditEdit(auditNo, auditC, isAdmin, appSettings.UserId);
Audit auditD = auditDMO.GetAuditItemReadOnly(auditNo, appSettings.UserId);
Auditor[] auditors = auditDMO.GetAuditorList().ToArray(); Auditor[] auditors = auditDMO.GetAuditorList().ToArray();
AuditReportAttachment[] auditReportAttachments = auditDMO.GetAuditReportAttachments(auditNo).ToArray(); // IEnumerable<AuditReportAttachment> GetAuditReportAttachments(int auditNo);
// C_8DAuditedStandard[] c_8DAuditedStandards = auditDMO.GetAuditStandardList().ToArray(); // C_8DAuditedStandard[] c_8DAuditedStandards = auditDMO.GetAuditStandardList().ToArray();
AuditType[] auditTypes = auditDMO.GetAuditTypeList().ToArray(); AuditType[] auditTypes = auditDMO.GetAuditTypeList().ToArray();
// CAFindings GetCAFindingsItem(int caFindingsID); // CAFindings GetCAFindingsItem(int caFindingsID);
// IEnumerable<AuditReportAttachment> GetCAFindingsItemAttachments(int caFindingsID); // IEnumerable<AuditReportAttachment> GetCAFindingsItemAttachments(int caFindingsID);
CAFindings[] caFindings = auditDMO.GetCAFindingsList(auditNo).ToArray(); // IEnumerable<CAFindings> GetCAFindingsList(int auditNo);
CANoList[] cANoLists = auditDMO.GetCorrectiveActionNoList().ToArray(); CANoList[] cANoLists = auditDMO.GetCorrectiveActionNoList().ToArray();
int openCACountByAuditNo = auditDMO.GetOpenCACountByAuditNo(auditNo); // int GetOpenCACountByAuditNo(int auditNo);
CAUserList[] cAUserLists = auditDMO.GetUserList().ToArray(); CAUserList[] cAUserLists = auditDMO.GetUserList().ToArray();
// Audit InsertAudit(Audit audit);
// void InsertAuditReportAttachment(AuditReportAttachment attach); // void InsertAuditReportAttachment(AuditReportAttachment attach);
// void InsertCAFindings(CAFindings model); // void InsertCAFindings(CAFindings model);
// int IsCAAssignedToAudit(int CANo, int auditNo); // int IsCAAssignedToAudit(int CANo, int auditNo);
// void ReleaseLockOnDocument(appSettings.UserId, int issueID); // void ReleaseLockOnDocument(appSettings.UserId, int issueID);
// void UpdateAudit(Audit audit, appSettings.UserId);
// void UpdateCAFindings(CAFindings model); // void UpdateCAFindings(CAFindings model);
if (auditDMO is null) { } if (auditDMO is null) { }
#pragma warning restore IDE0059 #pragma warning restore IDE0059
@ -89,14 +89,13 @@ public class AuditDMOTests {
[Ignore] [Ignore]
#endif #endif
[TestMethod] [TestMethod]
[DataRow(250, true)] public void AuditDMOIsAttachedOnly() {
public void AuditDMOIsAttachedOnly(int auditNo, bool isAdmin) {
_Logger?.LogInformation("Starting Web Application"); _Logger?.LogInformation("Starting Web Application");
IServiceProvider? serviceProvider = _WebApplicationFactory?.Services.CreateScope().ServiceProvider; IServiceProvider? serviceProvider = _WebApplicationFactory?.Services.CreateScope().ServiceProvider;
AppSettings? appSettings = serviceProvider?.GetRequiredService<AppSettings>(); AppSettings? appSettings = serviceProvider?.GetRequiredService<AppSettings>();
Assert.IsTrue(appSettings is not null); Assert.IsTrue(appSettings is not null);
if (System.Diagnostics.Debugger.IsAttached) if (System.Diagnostics.Debugger.IsAttached)
AuditDMO(_Logger, appSettings, auditNo, isAdmin); AuditDMO(_Logger, appSettings);
_Logger?.LogInformation("{TestName} completed", _TestContext?.TestName); _Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
NonThrowTryCatch(); NonThrowTryCatch();
} }

View File

@ -85,18 +85,6 @@ public class EngineeringChangeNoticeDMOTests {
// int SubmitTECNExtensionDocument(int issueID, appSettings.UserId, int documentType, DateTime extensionDate); // int SubmitTECNExtensionDocument(int issueID, appSettings.UserId, int documentType, DateTime extensionDate);
// void TECNExtensionLog(int ecnNumber, DateTime extensionDate); // void TECNExtensionLog(int ecnNumber, DateTime extensionDate);
// void UpdateECNType(int ecnNumber, string ecnType); // void UpdateECNType(int ecnNumber, string ecnType);
// ECN InsertECN(ECN ecn)
// void UpdateECN(ECN ecn)
// ECN GetECN(int ecnNumber, out int isITAR, int userID)
// ECN GetECNForRead(int ecnNumber, out int isITAR, int userID)
// ECNPdf GetECNPdf(int ecnNumber)
ECNAffectedDeparmtent[] departments = ecnDMO.GetDepartments().ToArray();
ECNAffectedModule[] modules = ecnDMO.GetModules().ToArray();
ECNCategory[] categories = ecnDMO.GetCategories().ToArray();
ECNArea[] eCNAreas = ecnDMO.GetECNAreas().ToArray();
ECNTechnology[] eCNTechnologies = ecnDMO.GetECNTechnologies().ToArray();
ECNAcknowledgementTrainingBy[] eCNAcknowledgementTrainingBy = ecnDMO.GetECNAcknowledgementTrainingBy().ToArray();
ProductFamilies[] productFamilies = ecnDMO.GetProductFamilies().ToArray();
if (ecnDMO is null) { } if (ecnDMO is null) { }
#pragma warning restore IDE0059 #pragma warning restore IDE0059
} }

View File

@ -1,55 +0,0 @@
using System;
using System.Threading.Tasks;
using MesaFabApproval.API.Services;
using MesaFabApproval.Shared.Models;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Moq;
using Xunit;
namespace MesaFabApproval.API.Test;
public class ApprovalServiceTests {
private readonly Mock<ILogger<ApprovalService>> _loggerMock;
private readonly Mock<IMemoryCache> _cacheMock;
private readonly Mock<IDalService> _dalServiceMock;
private readonly Mock<IUserService> _userServiceMock;
private readonly ApprovalService _approvalService;
public ApprovalServiceTests() {
_loggerMock = new Mock<ILogger<ApprovalService>>();
_cacheMock = new Mock<IMemoryCache>();
_dalServiceMock = new Mock<IDalService>();
_userServiceMock = new Mock<IUserService>();
_approvalService = new ApprovalService(_loggerMock.Object, _cacheMock.Object, _dalServiceMock.Object, _userServiceMock.Object);
}
[Fact]
public async Task DeleteApproval_ValidApprovalID_DeletesApproval() {
int approvalID = 1;
_dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>())).ReturnsAsync(1);
await _approvalService.DeleteApproval(approvalID);
_dalServiceMock.Verify(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>()), Times.Once);
}
[Fact]
public async Task DeleteApproval_InvalidApprovalID_ThrowsArgumentException() {
int approvalID = 0;
await Assert.ThrowsAsync<ArgumentException>(() => _approvalService.DeleteApproval(approvalID));
}
[Fact]
public async Task DeleteApproval_DeletionFails_ThrowsException() {
int approvalID = 1;
_dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>())).ReturnsAsync(0);
await Assert.ThrowsAsync<Exception>(() => _approvalService.DeleteApproval(approvalID));
}
}

View File

@ -1,32 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MesaFabApproval.Shared\MesaFabApproval.Shared.csproj" />
<ProjectReference Include="..\MesaFabApproval.API\MesaFabApproval.API.csproj" />
</ItemGroup>
</Project>

View File

@ -1,18 +0,0 @@
using Microsoft.Extensions.Caching.Memory;
using Moq;
namespace MesaFabApproval.API.Test;
public static class MockMemoryCacheService {
public static Mock<IMemoryCache> GetMemoryCache(object expectedValue) {
Mock<IMemoryCache> mockMemoryCache = new Mock<IMemoryCache>();
mockMemoryCache
.Setup(x => x.TryGetValue(It.IsAny<object>(), out expectedValue))
.Returns(true);
mockMemoryCache
.Setup(x => x.CreateEntry(It.IsAny<object>()))
.Returns(Mock.Of<ICacheEntry>());
return mockMemoryCache;
}
}

View File

@ -1,63 +0,0 @@
using Moq;
using Microsoft.Extensions.Logging;
using MesaFabApproval.API.Utilities;
using MesaFabApproval.Shared.Models;
using MesaFabApproval.Shared.Services;
namespace MesaFabApproval.API.Test;
public class MonInUtilsTests {
private readonly Mock<IMonInWorkerClient> _mockMonInClient;
private readonly Mock<ILogger<MonInUtils>> _mockLogger;
private readonly MonInUtils _monInUtils;
public MonInUtilsTests() {
_mockMonInClient = new Mock<IMonInWorkerClient>();
_mockMonInClient
.Setup(client => client.PostAverage(It.IsAny<string>(), It.IsAny<double>()))
.Verifiable();
_mockLogger = new Mock<ILogger<MonInUtils>>();
_monInUtils = new MonInUtils(_mockMonInClient.Object, _mockLogger.Object);
}
[Fact]
public void PostMetrics_ShouldPostAverageAndStatusOk_WhenNoErrors() {
string metricName = "TestMetric";
double latency = 100;
bool isArgumentError = false;
bool isInternalError = false;
_monInUtils.PostMetrics(metricName, latency, isArgumentError, isInternalError);
_mockMonInClient.Verify(client => client.PostAverage(metricName + "Latency", latency), Times.Once);
_mockMonInClient.Verify(client => client.PostStatus(metricName, StatusValue.Ok), Times.Once);
}
[Fact]
public void PostMetrics_ShouldPostAverageAndStatusOk_WhenArgumentError() {
string metricName = "TestMetric";
double latency = 100;
bool isArgumentError = true;
bool isInternalError = false;
_monInUtils.PostMetrics(metricName, latency, isArgumentError, isInternalError);
_mockMonInClient.Verify(client => client.PostAverage(metricName + "Latency", latency), Times.Once);
_mockMonInClient.Verify(client => client.PostStatus(metricName, StatusValue.Ok), Times.Once);
}
[Fact]
public void PostMetrics_ShouldPostAverageAndStatusCritical_WhenInternalError() {
string metricName = "TestMetric";
double latency = 100;
bool isArgumentError = false;
bool isInternalError = true;
_monInUtils.PostMetrics(metricName, latency, isArgumentError, isInternalError);
_mockMonInClient.Verify(client => client.PostAverage(metricName + "Latency", latency), Times.Once);
_mockMonInClient.Verify(client => client.PostStatus(metricName, StatusValue.Critical), Times.Once);
}
}

View File

@ -1,196 +0,0 @@
using MesaFabApproval.API.Services;
using MesaFabApproval.Models;
using MesaFabApproval.Shared.Models;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Moq;
namespace MesaFabApproval.API.Test;
public class PCRBFollowUpCommentsTests {
private readonly Mock<ILogger<PCRBService>> _loggerMock;
private readonly Mock<IDalService> _dalServiceMock;
private readonly Mock<IMemoryCache> _cacheMock;
private readonly Mock<IUserService> _userServiceMock;
private readonly Mock<IApprovalService> _approvalServiceMock;
private readonly Mock<ISmtpService> _smtpServiceMock;
private readonly PCRBService _pcrbService;
private readonly AppSettings _appSettings;
private static PCRBFollowUpComment FOLLOW_UP_COMMENT = new PCRBFollowUpComment {
PlanNumber = 1,
FollowUpID = 1,
Comment = "Comment",
UserID = 1
};
private static IEnumerable<PCRBFollowUpComment> FOLLOW_UP_COMMENTS = new List<PCRBFollowUpComment>() { FOLLOW_UP_COMMENT };
public PCRBFollowUpCommentsTests() {
_loggerMock = new Mock<ILogger<PCRBService>>();
_dalServiceMock = new Mock<IDalService>();
_userServiceMock = new Mock<IUserService>();
_approvalServiceMock = new Mock<IApprovalService>();
_smtpServiceMock = new Mock<ISmtpService>();
_cacheMock = MockMemoryCacheService.GetMemoryCache(FOLLOW_UP_COMMENTS);
_appSettings = new AppSettings(
Company: "Infineon",
DbConnectionString: "connectionString",
JwtAudience: "audience",
JwtIssuer: "issuer",
JwtKey: "key",
MrbAttachmentPath: "mrbAttachmentPath",
PcrbAttachmentPath: "pcrbAttachmentPath",
ShouldSendEmail: false,
SiteBaseUrl: "siteBaseUrl",
WorkingDirectoryName: "workingDirectoryName"
);
_pcrbService = new PCRBService(
_loggerMock.Object,
_dalServiceMock.Object,
_cacheMock.Object,
_userServiceMock.Object,
_approvalServiceMock.Object,
_smtpServiceMock.Object,
_appSettings
);
}
[Fact]
public async Task CreateFollowUpComment_WithValidParam_ShouldCreateFollowUp() {
_dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT))
.ReturnsAsync(1);
await _pcrbService.CreateFollowUpComment(FOLLOW_UP_COMMENT);
_dalServiceMock.Verify(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT), Times.Once);
}
[Fact]
public async Task CreateFollowUpComment_WithNullParam_ShouldThrowException() {
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.CreateFollowUpComment(null));
}
[Fact]
public async Task CreateFollowUpComment_WithDatabaseFailure_ShouldThrowException() {
_dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT))
.ReturnsAsync(0);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUpComment(FOLLOW_UP_COMMENT));
}
[Fact]
public async Task CreateFollowUpComment_WithDatabaseException_ShouldThrowException() {
_dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT))
.Throws<Exception>();
await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUpComment(FOLLOW_UP_COMMENT));
}
[Fact]
public async Task GetFollowUpCommentsByPlanNumber_WithCacheBypass_ShouldReturnFollowUps() {
int planNumber = 1;
_dalServiceMock.Setup(d => d.QueryAsync<PCRBFollowUpComment>(It.IsAny<string>(), It.IsAny<object>()))
.ReturnsAsync(FOLLOW_UP_COMMENTS);
IEnumerable<PCRBFollowUpComment> result = await _pcrbService.GetFollowUpCommentsByPlanNumber(planNumber, true);
Assert.NotNull(result);
Assert.Single(result);
Assert.Equal(FOLLOW_UP_COMMENTS, result);
_dalServiceMock.Verify(d => d.QueryAsync<PCRBFollowUpComment>(It.IsAny<string>(), It.IsAny<object>()), Times.Once);
}
[Fact]
public async Task GetFollowUpCommentsByPlanNumber_WithCacheBypass_AndDatabaseException_ShouldThrowException() {
int planNumber = 1;
_dalServiceMock.Setup(d => d.QueryAsync<PCRBFollowUpComment>(It.IsAny<string>(), It.IsAny<object>()))
.Throws<Exception>();
await Assert.ThrowsAsync<Exception>(() => _pcrbService.GetFollowUpCommentsByPlanNumber(planNumber, true));
}
[Fact]
public async Task GetFollowUpCommentsByPlanNumber_WithoutCacheBypass_ShouldReturnFollowUps() {
int planNumber = 1;
IEnumerable<PCRBFollowUpComment> result = await _pcrbService.GetFollowUpCommentsByPlanNumber(planNumber, false);
Assert.NotNull(result);
Assert.Single(result);
Assert.Equal(FOLLOW_UP_COMMENTS, result);
}
[Fact]
public async Task UpdateFollowUpComment_WithValidParam_ShouldUpdateFollowUp() {
_dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT))
.ReturnsAsync(1);
await _pcrbService.UpdateFollowUpComment(FOLLOW_UP_COMMENT);
_dalServiceMock.Verify(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT), Times.Once);
}
[Fact]
public async Task UpdateFollowUpComment_WithNullParam_ShouldThrowException() {
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.UpdateFollowUpComment(null));
}
[Fact]
public async Task UpdateFollowUpComment_WithDatabaseFailure_ShouldThrowException() {
_dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT))
.ReturnsAsync(0);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUpComment(FOLLOW_UP_COMMENT));
}
[Fact]
public async Task UpdateFollowUpComment_WithDatabaseException_ShouldThrowException() {
_dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT))
.Throws<Exception>();
await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUpComment(FOLLOW_UP_COMMENT));
}
[Fact]
public async Task DeleteFollowUpComment_WithValidId_ShouldDeleteFollowUp() {
int commentId = 1;
_dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>()))
.ReturnsAsync(1);
await _pcrbService.DeleteFollowUpComment(commentId);
_dalServiceMock.Verify(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>()), Times.Once);
}
[Fact]
public async Task DeleteFollowUpComment_WithInvalidId_ShouldThrowException() {
await Assert.ThrowsAsync<ArgumentException>(() => _pcrbService.DeleteFollowUpComment(0));
}
[Fact]
public async Task DeleteFollowUpComment_WithDatabaseFailure_ShouldThrowException() {
int commentId = 1;
_dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>()))
.ReturnsAsync(0);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.DeleteFollowUpComment(commentId));
}
[Fact]
public async Task DeleteFollowUpComment_WithDatabaseException_ShouldThrowException() {
int commentId = 1;
_dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>()))
.Throws<Exception>();
await Assert.ThrowsAsync<Exception>(() => _pcrbService.DeleteFollowUpComment(commentId));
}
}

View File

@ -1,198 +0,0 @@
using MesaFabApproval.API.Services;
using MesaFabApproval.Models;
using MesaFabApproval.Shared.Models;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Moq;
namespace MesaFabApproval.API.Test;
public class PCRBFollowUpTests {
private readonly Mock<ILogger<PCRBService>> _loggerMock;
private readonly Mock<IDalService> _dalServiceMock;
private readonly Mock<IMemoryCache> _cacheMock;
private readonly Mock<IUserService> _userServiceMock;
private readonly Mock<IApprovalService> _approvalServiceMock;
private readonly Mock<ISmtpService> _smtpServiceMock;
private readonly PCRBService _pcrbService;
private readonly AppSettings _appSettings;
private static PCRBFollowUp FOLLOW_UP = new PCRBFollowUp {
ID = 1,
PlanNumber = 1,
Step = 1,
FollowUpDate = DateTime.Now
};
private static IEnumerable<PCRBFollowUp> FOLLOW_UPS = new List<PCRBFollowUp>() {
new PCRBFollowUp { ID = 1, PlanNumber = 1, Step = 1, FollowUpDate = DateTime.Now }
};
public PCRBFollowUpTests() {
_loggerMock = new Mock<ILogger<PCRBService>>();
_dalServiceMock = new Mock<IDalService>();
_userServiceMock = new Mock<IUserService>();
_approvalServiceMock = new Mock<IApprovalService>();
_smtpServiceMock = new Mock<ISmtpService>();
_cacheMock = MockMemoryCacheService.GetMemoryCache(FOLLOW_UPS);
_appSettings = new AppSettings(
Company: "Infineon",
DbConnectionString: "connectionString",
JwtAudience: "audience",
JwtIssuer: "issuer",
JwtKey: "key",
MrbAttachmentPath: "mrbAttachmentPath",
PcrbAttachmentPath: "pcrbAttachmentPath",
ShouldSendEmail: false,
SiteBaseUrl: "siteBaseUrl",
WorkingDirectoryName: "workingDirectoryName"
);
_pcrbService = new PCRBService(
_loggerMock.Object,
_dalServiceMock.Object,
_cacheMock.Object,
_userServiceMock.Object,
_approvalServiceMock.Object,
_smtpServiceMock.Object,
_appSettings
);
}
[Fact]
public async Task CreateFollowUp_WithValidParam_ShouldCreateFollowUp() {
_dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP))
.ReturnsAsync(1);
await _pcrbService.CreateFollowUp(FOLLOW_UP);
_dalServiceMock.Verify(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP), Times.Once);
}
[Fact]
public async Task CreateFollowUp_WithNullParam_ShouldThrowException() {
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.CreateFollowUp(null));
}
[Fact]
public async Task CreateFollowUp_WithDatabaseFailure_ShouldThrowException() {
_dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP))
.ReturnsAsync(0);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUp(FOLLOW_UP));
}
[Fact]
public async Task CreateFollowUp_WithDatabaseException_ShouldThrowException() {
_dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP))
.Throws<Exception>();
await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUp(FOLLOW_UP));
}
[Fact]
public async Task GetFollowUpsByPlanNumber_WithCacheBypass_ShouldReturnFollowUps() {
int planNumber = 1;
_dalServiceMock.Setup(d => d.QueryAsync<PCRBFollowUp>(It.IsAny<string>(), It.IsAny<object>()))
.ReturnsAsync(FOLLOW_UPS);
IEnumerable<PCRBFollowUp> result = await _pcrbService.GetFollowUpsByPlanNumber(planNumber, true);
Assert.NotNull(result);
Assert.Single(result);
Assert.Equal(FOLLOW_UPS, result);
_dalServiceMock.Verify(d => d.QueryAsync<PCRBFollowUp>(It.IsAny<string>(), It.IsAny<object>()), Times.Once);
}
[Fact]
public async Task GetFollowUpsByPlanNumber_WithCacheBypass_AndDatabaseException_ShouldThrowException() {
int planNumber = 1;
_dalServiceMock.Setup(d => d.QueryAsync<PCRBFollowUp>(It.IsAny<string>(), It.IsAny<object>()))
.Throws<Exception>();
await Assert.ThrowsAsync<Exception>(() => _pcrbService.GetFollowUpsByPlanNumber(planNumber, true));
}
[Fact]
public async Task GetFollowUpsByPlanNumber_WithoutCacheBypass_ShouldReturnFollowUps() {
int planNumber = 1;
IEnumerable<PCRBFollowUp> result = await _pcrbService.GetFollowUpsByPlanNumber(planNumber, false);
Assert.NotNull(result);
Assert.Single(result);
Assert.Equal(FOLLOW_UPS, result);
}
[Fact]
public async Task UpdateFollowUp_WithValidParam_ShouldUpdateFollowUp() {
_dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP))
.ReturnsAsync(1);
await _pcrbService.UpdateFollowUp(FOLLOW_UP);
_dalServiceMock.Verify(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP), Times.Once);
}
[Fact]
public async Task UpdateFollowUp_WithNullParam_ShouldThrowException() {
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.UpdateFollowUp(null));
}
[Fact]
public async Task UpdateFollowUp_WithDatabaseFailure_ShouldThrowException() {
_dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP))
.ReturnsAsync(0);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUp(FOLLOW_UP));
}
[Fact]
public async Task UpdateFollowUp_WithDatabaseException_ShouldThrowException() {
_dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP))
.Throws<Exception>();
await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUp(FOLLOW_UP));
}
[Fact]
public async Task DeleteFollowUp_WithValidId_ShouldDeleteFollowUp() {
int followUpId = 1;
_dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>()))
.ReturnsAsync(1);
await _pcrbService.DeleteFollowUp(followUpId);
_dalServiceMock.Verify(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>()), Times.Once);
}
[Fact]
public async Task DeleteFollowUp_WithInvalidId_ShouldThrowException() {
await Assert.ThrowsAsync<ArgumentException>(() => _pcrbService.DeleteFollowUp(0));
}
[Fact]
public async Task DeleteFollowUp_WithDatabaseFailure_ShouldThrowException() {
int followUpId = 1;
_dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>()))
.ReturnsAsync(0);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.DeleteFollowUp(followUpId));
}
[Fact]
public async Task DeleteFollowUp_WithDatabaseException_ShouldThrowException() {
int followUpId = 1;
_dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>()))
.Throws<Exception>();
await Assert.ThrowsAsync<Exception>(() => _pcrbService.DeleteFollowUp(followUpId));
}
}

View File

@ -1,328 +0,0 @@
using MesaFabApproval.API.Services;
using MesaFabApproval.Models;
using MesaFabApproval.Shared.Models;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Moq;
using System.Net.Mail;
namespace MesaFabApproval.API.Test;
public class PCRBServiceTests
{
private readonly Mock<ILogger<PCRBService>> _loggerMock;
private readonly Mock<IDalService> _dalServiceMock;
private Mock<IMemoryCache> _cacheMock;
private readonly Mock<IUserService> _userServiceMock;
private readonly Mock<IApprovalService> _approvalServiceMock;
private readonly Mock<ISmtpService> _smtpServiceMock;
private PCRBService _pcrbService;
private static IEnumerable<PCRB> PCRBS = new List<PCRB>() {
new PCRB {
PlanNumber = 1,
OwnerID = 1,
Title = "Test Title",
ChangeLevel = "Level 1",
ReasonForChange = "Test Reason",
ChangeDescription = "Test Description",
IsITAR = false,
CurrentStep = 1,
InsertTimeStamp = DateTime.Now,
LastUpdateDate = DateTime.Now,
Type = "Type 1"
}
};
private static IEnumerable<PCRBFollowUp> FOLLOW_UPS = new List<PCRBFollowUp>() {
new PCRBFollowUp { ID = 1, PlanNumber = 1, Step = 1, FollowUpDate = DateTime.Now }
};
private static AppSettings appSettings = new AppSettings(
Company: "Infineon",
DbConnectionString: "connectionString",
JwtAudience: "audience",
JwtIssuer: "issuer",
JwtKey: "key",
MrbAttachmentPath: "mrbAttachmentPath",
PcrbAttachmentPath: "pcrbAttachmentPath",
ShouldSendEmail: false,
SiteBaseUrl: "siteBaseUrl",
WorkingDirectoryName: "workingDirectoryName"
);
public PCRBServiceTests()
{
_loggerMock = new Mock<ILogger<PCRBService>>();
_dalServiceMock = new Mock<IDalService>();
_userServiceMock = new Mock<IUserService>();
_approvalServiceMock = new Mock<IApprovalService>();
_smtpServiceMock = new Mock<ISmtpService>();
_cacheMock = MockMemoryCacheService.GetMemoryCache(FOLLOW_UPS);
_pcrbService = new PCRBService(
_loggerMock.Object,
_dalServiceMock.Object,
_cacheMock.Object,
_userServiceMock.Object,
_approvalServiceMock.Object,
_smtpServiceMock.Object,
appSettings
);
}
[Fact]
public async Task CreateNewPCRB_WithValidParam_ShouldCreatePCRB()
{
var pcrb = new PCRB
{
OwnerID = 1,
Title = "Test Title",
ChangeLevel = "Level 1",
ReasonForChange = "Test Reason",
ChangeDescription = "Test Description",
IsITAR = false,
CurrentStep = 1,
InsertTimeStamp = DateTime.Now,
LastUpdateDate = DateTime.Now,
Type = "Type 1"
};
_dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb))
.ReturnsAsync(1);
await _pcrbService.CreateNewPCRB(pcrb);
_dalServiceMock.Verify(d => d.ExecuteAsync(It.IsAny<string>(), pcrb), Times.Once);
}
[Fact]
public async Task CreateNewPCRB_WithNullParam_ShouldThrowException()
{
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.CreateNewPCRB(null));
}
[Fact]
public async Task CreateNewPCRB_WithDatabaseFailure_ShouldThrowException()
{
var pcrb = new PCRB
{
OwnerID = 1,
Title = "Test Title",
ChangeLevel = "Level 1",
ReasonForChange = "Test Reason",
ChangeDescription = "Test Description",
IsITAR = false,
CurrentStep = 1,
InsertTimeStamp = DateTime.Now,
LastUpdateDate = DateTime.Now,
Type = "Type 1"
};
_dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb))
.ReturnsAsync(0);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateNewPCRB(pcrb));
}
[Fact]
public async Task CreateNewPCRB_WithDatabaseException_ShouldThrowException()
{
var pcrb = new PCRB
{
OwnerID = 1,
Title = "Test Title",
ChangeLevel = "Level 1",
ReasonForChange = "Test Reason",
ChangeDescription = "Test Description",
IsITAR = false,
CurrentStep = 1,
InsertTimeStamp = DateTime.Now,
LastUpdateDate = DateTime.Now,
Type = "Type 1"
};
_dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb))
.Throws<Exception>();
await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateNewPCRB(pcrb));
}
[Fact]
public async Task UpdatePCRB_WithValidParam_ShouldUpdatePCRB()
{
_cacheMock = MockMemoryCacheService.GetMemoryCache(PCRBS);
_pcrbService = new PCRBService(
_loggerMock.Object,
_dalServiceMock.Object,
_cacheMock.Object,
_userServiceMock.Object,
_approvalServiceMock.Object,
_smtpServiceMock.Object,
appSettings
);
var pcrb = new PCRB
{
PlanNumber = 1,
OwnerID = 1,
Title = "Test Title",
ChangeLevel = "Level 1",
ReasonForChange = "Test Reason",
ChangeDescription = "Test Description",
IsITAR = false,
CurrentStep = 1,
LastUpdateDate = DateTime.Now,
ClosedDate = DateTime.Now,
Type = "Type 1"
};
_dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb))
.ReturnsAsync(1);
await _pcrbService.UpdatePCRB(pcrb);
_dalServiceMock.Verify(d => d.ExecuteAsync(It.IsAny<string>(), pcrb), Times.Once);
}
[Fact]
public async Task UpdatePCRB_WithNullParam_ShouldThrowException()
{
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.UpdatePCRB(null));
}
[Fact]
public async Task UpdatePCRB_WithDatabaseFailure_ShouldThrowException()
{
var pcrb = new PCRB
{
PlanNumber = 1,
OwnerID = 1,
Title = "Test Title",
ChangeLevel = "Level 1",
ReasonForChange = "Test Reason",
ChangeDescription = "Test Description",
IsITAR = false,
CurrentStep = 1,
LastUpdateDate = DateTime.Now,
ClosedDate = DateTime.Now,
Type = "Type 1"
};
_dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb))
.ReturnsAsync(0);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdatePCRB(pcrb));
}
[Fact]
public async Task UpdatePCRB_WithDatabaseException_ShouldThrowException()
{
var pcrb = new PCRB
{
PlanNumber = 1,
OwnerID = 1,
Title = "Test Title",
ChangeLevel = "Level 1",
ReasonForChange = "Test Reason",
ChangeDescription = "Test Description",
IsITAR = false,
CurrentStep = 1,
LastUpdateDate = DateTime.Now,
ClosedDate = DateTime.Now,
Type = "Type 1"
};
_dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb))
.Throws<Exception>();
await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdatePCRB(pcrb));
}
[Fact]
public async Task NotifyApprover_ShouldSendNotification()
{
PCRBNotification notification = new PCRBNotification
{
Message = "Test Message",
PCRB = new PCRB { PlanNumber = 1, Title = "Test PCRB" },
Approval = new Approval
{
UserID = 1,
IssueID = 1,
RoleName = "Role",
SubRole = "SubRole",
SubRoleID = 1,
AssignedDate = DateTime.Now
}
};
_userServiceMock.Setup(s => s.GetUserByUserId(It.IsAny<int>()))
.ReturnsAsync(new User
{
UserID = 1,
LoginID = "testLogin",
FirstName = "Test",
LastName = "User",
Email = "test@example.com"
});
_smtpServiceMock.Setup(s => s.SendEmail(It.IsAny<IEnumerable<MailAddress>>(),
It.IsAny<IEnumerable<MailAddress>>(),
It.IsAny<string>(),
It.IsAny<string>()))
.ReturnsAsync(true);
_approvalServiceMock.Setup(s => s.UpdateApproval(It.IsAny<Approval>()))
.Returns(Task.CompletedTask);
await _pcrbService.NotifyApprover(notification);
_smtpServiceMock.Verify(s => s.SendEmail(It.IsAny<IEnumerable<MailAddress>>(),
It.IsAny<IEnumerable<MailAddress>>(),
It.IsAny<string>(),
It.IsAny<string>()), Times.Once);
_approvalServiceMock.Verify(s => s.UpdateApproval(It.IsAny<Approval>()), Times.Once);
}
[Fact]
public async Task NotifyApprover_ShouldThrowException_WhenNotificationIsNull()
{
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.NotifyApprover(null));
}
[Fact]
public async Task NotifyApprover_ShouldThrowException_WhenPCRBIsNull()
{
PCRBNotification notification = new PCRBNotification
{
Message = "Test Message",
PCRB = null,
Approval = new Approval
{
UserID = 1,
IssueID = 1,
RoleName = "Role",
SubRole = "SubRole",
SubRoleID = 1,
AssignedDate = DateTime.Now
}
};
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.NotifyApprover(notification));
}
[Fact]
public async Task NotifyApprover_ShouldThrowException_WhenApprovalIsNull()
{
PCRBNotification notification = new PCRBNotification
{
Message = "Test Message",
PCRB = new PCRB { PlanNumber = 1, Title = "Test PCRB" },
Approval = null
};
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.NotifyApprover(notification));
}
}

View File

@ -15,8 +15,6 @@ public class SmtpClientWrapper : ISmtpClientWrapper {
} }
public void Send(MailMessage message) { public void Send(MailMessage message) {
message.Subject = message.Subject.Replace('\r', ' ').Replace('\n', ' ');
_client.Send(message); _client.Send(message);
} }
} }

View File

@ -1,5 +1,4 @@
using MesaFabApproval.API.Services; using MesaFabApproval.API.Services;
using MesaFabApproval.API.Utilities;
using MesaFabApproval.Shared.Models; using MesaFabApproval.Shared.Models;
using MesaFabApproval.Shared.Services; using MesaFabApproval.Shared.Services;
@ -12,13 +11,13 @@ namespace MesaFabApproval.API.Controllers;
public class ApprovalController : ControllerBase { public class ApprovalController : ControllerBase {
private readonly ILogger<ApprovalController> _logger; private readonly ILogger<ApprovalController> _logger;
private readonly IApprovalService _approvalService; private readonly IApprovalService _approvalService;
private readonly IMonInUtils _monInUtils; private readonly IMonInWorkerClient _monInClient;
public ApprovalController(ILogger<ApprovalController> logger, IApprovalService approvalService, public ApprovalController(ILogger<ApprovalController> logger, IApprovalService approvalService,
IMonInUtils monInUtils) { IMonInWorkerClient monInClient) {
_logger = logger ?? throw new ArgumentNullException("ILogger not injected"); _logger = logger ?? throw new ArgumentNullException("ILogger not injected");
_approvalService = approvalService ?? throw new ArgumentNullException("IApprovalService not injected"); _approvalService = approvalService ?? throw new ArgumentNullException("IApprovalService not injected");
_monInUtils = monInUtils ?? throw new ArgumentNullException("IMonInUtils not injected"); _monInClient = monInClient ?? throw new ArgumentNullException("IMonInWorkerClient not injected");
} }
[HttpPost] [HttpPost]
@ -40,19 +39,26 @@ public class ApprovalController : ControllerBase {
} catch (ArgumentException ex) { } catch (ArgumentException ex) {
isArgumentError = true; isArgumentError = true;
errorMessage = ex.Message; errorMessage = ex.Message;
_logger.LogWarning($"Argument error when attempting to create approval: {errorMessage}");
return BadRequest(errorMessage); return BadRequest(errorMessage);
} catch (Exception ex) { } catch (Exception ex) {
isInternalError = true; isInternalError = true;
errorMessage = $"Cannot create new approval, because {ex.Message}"; errorMessage = $"Cannot create new approval, because {ex.Message}";
_logger.LogError(errorMessage);
return Problem(errorMessage); return Problem(errorMessage);
} finally { } finally {
string metricName = "CreateApproval"; string metricName = "CreateApproval";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -75,19 +81,26 @@ public class ApprovalController : ControllerBase {
} catch (ArgumentException ex) { } catch (ArgumentException ex) {
isArgumentError = true; isArgumentError = true;
errorMessage = ex.Message; errorMessage = ex.Message;
_logger.LogWarning($"Argument error when getting approvals for issue {issueId}: {errorMessage}");
return BadRequest(errorMessage); return BadRequest(errorMessage);
} catch (Exception ex) { } catch (Exception ex) {
isInternalError = true; isInternalError = true;
errorMessage = $"Cannot get approvals, because {ex.Message}"; errorMessage = $"Cannot get approvals, because {ex.Message}";
_logger.LogError(errorMessage);
return Problem(errorMessage); return Problem(errorMessage);
} finally { } finally {
string metricName = "GetApprovalsForIssueId"; string metricName = "GetApprovalsForIssueId";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -110,19 +123,26 @@ public class ApprovalController : ControllerBase {
} catch (ArgumentException ex) { } catch (ArgumentException ex) {
isArgumentError = true; isArgumentError = true;
errorMessage = ex.Message; errorMessage = ex.Message;
_logger.LogWarning($"Argument error when getting approvals for user {userId}: {errorMessage}");
return BadRequest(errorMessage); return BadRequest(errorMessage);
} catch (Exception ex) { } catch (Exception ex) {
isInternalError = true; isInternalError = true;
errorMessage = $"Cannot get approvals, because {ex.Message}"; errorMessage = $"Cannot get approvals, because {ex.Message}";
_logger.LogError(errorMessage);
return Problem(errorMessage); return Problem(errorMessage);
} finally { } finally {
string metricName = "GetApprovalsForUserId"; string metricName = "GetApprovalsForUserId";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -145,19 +165,26 @@ public class ApprovalController : ControllerBase {
} catch (ArgumentException ex) { } catch (ArgumentException ex) {
isArgumentError = true; isArgumentError = true;
errorMessage = ex.Message; errorMessage = ex.Message;
_logger.LogWarning($"Argument error when getting approval group members for sub role {subRoleId}: {errorMessage}");
return BadRequest(errorMessage); return BadRequest(errorMessage);
} catch (Exception ex) { } catch (Exception ex) {
isInternalError = true; isInternalError = true;
errorMessage = $"Cannot get approval group members, because {ex.Message}"; errorMessage = $"Cannot get approval group members, because {ex.Message}";
_logger.LogError(errorMessage);
return Problem(errorMessage); return Problem(errorMessage);
} finally { } finally {
string metricName = "GetApprovalsGroupMembers"; string metricName = "GetApprovalsGroupMembers";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -170,7 +197,7 @@ public class ApprovalController : ControllerBase {
string errorMessage = ""; string errorMessage = "";
try { try {
_logger.LogInformation("Attempting to update approval"); _logger.LogInformation($"Attempting to update approval");
if (approval is null) throw new ArgumentNullException($"approval cannot be null"); if (approval is null) throw new ArgumentNullException($"approval cannot be null");
@ -180,54 +207,26 @@ public class ApprovalController : ControllerBase {
} catch (ArgumentException ex) { } catch (ArgumentException ex) {
isArgumentError = true; isArgumentError = true;
errorMessage = ex.Message; errorMessage = ex.Message;
_logger.LogWarning($"Argument error when attempting to update approval: {errorMessage}");
return BadRequest(errorMessage); return BadRequest(errorMessage);
} catch (Exception ex) { } catch (Exception ex) {
isInternalError = true; isInternalError = true;
errorMessage = $"Cannot update approval, because {ex.Message}"; errorMessage = $"Cannot update approval, because {ex.Message}";
_logger.LogError(errorMessage);
return Problem(errorMessage); return Problem(errorMessage);
} finally { } finally {
string metricName = "UpdateApproval"; string metricName = "UpdateApproval";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
} _logger.LogWarning(errorMessage);
} _monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
[HttpDelete]
[Route("approval")]
public async Task<IActionResult> DeleteApproval(int approvalID) {
DateTime start = DateTime.Now;
bool isArgumentError = false;
bool isInternalError = false;
string errorMessage = "";
try {
_logger.LogInformation($"Attempting to delete approval {approvalID}");
if (approvalID <= 0) throw new ArgumentException("Invalid approval ID");
await _approvalService.DeleteApproval(approvalID);
return Ok();
} catch (ArgumentException ex) {
isArgumentError = true;
errorMessage = ex.Message;
_logger.LogWarning($"Argument error when attempting to delete approval: {errorMessage}");
return BadRequest(errorMessage);
} catch (Exception ex) {
isInternalError = true;
errorMessage = $"Cannot delete approval, because {ex.Message}";
_logger.LogError(errorMessage); _logger.LogError(errorMessage);
return Problem(errorMessage); _monInClient.PostStatus(metricName, StatusValue.Critical);
} finally { } else {
string metricName = "UpdateApproval"; _monInClient.PostStatus(metricName, StatusValue.Ok);
DateTime end = DateTime.Now; }
double millisecondsDiff = (end - start).TotalMilliseconds;
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
} }
} }
@ -250,19 +249,26 @@ public class ApprovalController : ControllerBase {
} catch (ArgumentException ex) { } catch (ArgumentException ex) {
isArgumentError = true; isArgumentError = true;
errorMessage = ex.Message; errorMessage = ex.Message;
_logger.LogWarning($"Argument error when attempting to approve: {errorMessage}");
return BadRequest(errorMessage); return BadRequest(errorMessage);
} catch (Exception ex) { } catch (Exception ex) {
isInternalError = true; isInternalError = true;
errorMessage = $"Cannot approve, because {ex.Message}"; errorMessage = $"Cannot approve, because {ex.Message}";
_logger.LogError(errorMessage);
return Problem(errorMessage); return Problem(errorMessage);
} finally { } finally {
string metricName = "Approve"; string metricName = "Approve";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -285,19 +291,26 @@ public class ApprovalController : ControllerBase {
} catch (ArgumentException ex) { } catch (ArgumentException ex) {
isArgumentError = true; isArgumentError = true;
errorMessage = ex.Message; errorMessage = ex.Message;
_logger.LogWarning($"Argument error when attempting to deny approval: {errorMessage}");
return BadRequest(errorMessage); return BadRequest(errorMessage);
} catch (Exception ex) { } catch (Exception ex) {
isInternalError = true; isInternalError = true;
errorMessage = $"Approval denial failed, because {ex.Message}"; errorMessage = $"Approval denial failed, because {ex.Message}";
_logger.LogError(errorMessage);
return Problem(errorMessage); return Problem(errorMessage);
} finally { } finally {
string metricName = "Deny"; string metricName = "Deny";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -320,19 +333,26 @@ public class ApprovalController : ControllerBase {
} catch (ArgumentException ex) { } catch (ArgumentException ex) {
isArgumentError = true; isArgumentError = true;
errorMessage = ex.Message; errorMessage = ex.Message;
_logger.LogWarning($"Argument error when attempting to get role ID by role name: {errorMessage}");
return BadRequest(errorMessage); return BadRequest(errorMessage);
} catch (Exception ex) { } catch (Exception ex) {
isInternalError = true; isInternalError = true;
errorMessage = $"Cannot get role ID, because {ex.Message}"; errorMessage = $"Cannot get role ID, because {ex.Message}";
_logger.LogError(errorMessage);
return Problem(errorMessage); return Problem(errorMessage);
} finally { } finally {
string metricName = "GetRoleIdForRoleName"; string metricName = "GetRoleIdForRoleName";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -356,19 +376,26 @@ public class ApprovalController : ControllerBase {
} catch (ArgumentException ex) { } catch (ArgumentException ex) {
isArgumentError = true; isArgumentError = true;
errorMessage = ex.Message; errorMessage = ex.Message;
_logger.LogWarning($"Argument error when attempting to get sub roles by sub role name: {errorMessage}");
return BadRequest(errorMessage); return BadRequest(errorMessage);
} catch (Exception ex) { } catch (Exception ex) {
isInternalError = true; isInternalError = true;
errorMessage = $"Cannot get role ID, because {ex.Message}"; errorMessage = $"Cannot get role ID, because {ex.Message}";
_logger.LogError(errorMessage);
return Problem(errorMessage); return Problem(errorMessage);
} finally { } finally {
string metricName = "GetSubRoleIdForSubRoleName"; string metricName = "GetSubRoleIdForSubRoleName";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
} }

View File

@ -53,36 +53,4 @@ public class ECNController : ControllerBase {
} }
} }
} }
[HttpGet]
[Route("ecn/allNumbers")]
public async Task<IActionResult> GetAllECNNumbers() {
DateTime start = DateTime.Now;
bool isInternalError = false;
string errorMessage = "";
try {
_logger.LogInformation($"Attempting to get all ECN#s");
IEnumerable<int> allEcnNumbers = await _ecnService.GetAllECNNumbers();
return Ok(allEcnNumbers);
} catch (Exception ex) {
isInternalError = true;
errorMessage = $"Cannot get all ECN#s, because {ex.Message}";
return Problem(errorMessage);
} finally {
string metricName = "GetAllECNNumbers";
DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
}
}
} }

View File

@ -1,5 +1,4 @@
using MesaFabApproval.API.Services; using MesaFabApproval.API.Services;
using MesaFabApproval.API.Utilities;
using MesaFabApproval.Shared.Models; using MesaFabApproval.Shared.Models;
using MesaFabApproval.Shared.Services; using MesaFabApproval.Shared.Services;
@ -14,12 +13,12 @@ namespace MesaFabApproval.API.Controllers;
public class PCRBController : ControllerBase { public class PCRBController : ControllerBase {
private readonly ILogger<MRBController> _logger; private readonly ILogger<MRBController> _logger;
private readonly IPCRBService _pcrbService; private readonly IPCRBService _pcrbService;
private readonly IMonInUtils _monInUtils; private readonly IMonInWorkerClient _monInClient;
public PCRBController(ILogger<MRBController> logger, IPCRBService pcrbService, IMonInUtils monInUtils) { public PCRBController(ILogger<MRBController> logger, IPCRBService pcrbService, IMonInWorkerClient monInClient) {
_logger = logger ?? throw new ArgumentNullException("ILogger not injected"); _logger = logger ?? throw new ArgumentNullException("ILogger not injected");
_pcrbService = pcrbService ?? throw new ArgumentNullException("IPCRBService not injected"); _pcrbService = pcrbService ?? throw new ArgumentNullException("IPCRBService not injected");
_monInUtils = monInUtils ?? throw new ArgumentNullException("IMonInUtils not injected"); _monInClient = monInClient ?? throw new ArgumentNullException("IMonInWorkerClient not injected");
} }
[HttpPost] [HttpPost]
@ -50,8 +49,17 @@ public class PCRBController : ControllerBase {
string metricName = "CreateNewPCRB"; string metricName = "CreateNewPCRB";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -76,8 +84,14 @@ public class PCRBController : ControllerBase {
string metricName = "GetAllPCRBs"; string metricName = "GetAllPCRBs";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, false, isInternalError); if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -109,8 +123,17 @@ public class PCRBController : ControllerBase {
string metricName = "GetPCRBbyTitle"; string metricName = "GetPCRBbyTitle";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -142,8 +165,17 @@ public class PCRBController : ControllerBase {
string metricName = "GetPCRBbyPlanNumber"; string metricName = "GetPCRBbyPlanNumber";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -175,8 +207,17 @@ public class PCRBController : ControllerBase {
string metricName = "UpdatePCRB"; string metricName = "UpdatePCRB";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -208,14 +249,22 @@ public class PCRBController : ControllerBase {
string metricName = "DeletePCRB"; string metricName = "DeletePCRB";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
[HttpPost] [HttpPost]
[Route("pcrb/attachment")] [Route("pcrb/attachment")]
[ApiExplorerSettings(IgnoreApi = true)]
public async Task<IActionResult> UploadAttachment([FromForm] IFormFile file, [FromForm] PCRBAttachment attachment) { public async Task<IActionResult> UploadAttachment([FromForm] IFormFile file, [FromForm] PCRBAttachment attachment) {
DateTime start = DateTime.Now; DateTime start = DateTime.Now;
bool isArgumentError = false; bool isArgumentError = false;
@ -244,8 +293,17 @@ public class PCRBController : ControllerBase {
string metricName = "UploadPCRBAttachment"; string metricName = "UploadPCRBAttachment";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -277,8 +335,17 @@ public class PCRBController : ControllerBase {
string metricName = "GetPCRBAttachments"; string metricName = "GetPCRBAttachments";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -323,8 +390,17 @@ public class PCRBController : ControllerBase {
string metricName = "GetPCRBAttachmentFile"; string metricName = "GetPCRBAttachmentFile";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -356,8 +432,17 @@ public class PCRBController : ControllerBase {
string metricName = "UpdatePCRBAttachment"; string metricName = "UpdatePCRBAttachment";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -389,8 +474,17 @@ public class PCRBController : ControllerBase {
string metricName = "DeletePCRBAttachment"; string metricName = "DeletePCRBAttachment";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -422,8 +516,17 @@ public class PCRBController : ControllerBase {
string metricName = "CreatePCRBActionItem"; string metricName = "CreatePCRBActionItem";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -455,8 +558,17 @@ public class PCRBController : ControllerBase {
string metricName = "UpdatePCRBActionItem"; string metricName = "UpdatePCRBActionItem";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -488,8 +600,17 @@ public class PCRBController : ControllerBase {
string metricName = "DeletePCRBActionItem"; string metricName = "DeletePCRBActionItem";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -521,8 +642,17 @@ public class PCRBController : ControllerBase {
string metricName = "GetPCRBActionItems"; string metricName = "GetPCRBActionItems";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -554,8 +684,17 @@ public class PCRBController : ControllerBase {
string metricName = "CreatePCR3Document"; string metricName = "CreatePCR3Document";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -587,8 +726,17 @@ public class PCRBController : ControllerBase {
string metricName = "UpdatePCR3Document"; string metricName = "UpdatePCR3Document";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -620,8 +768,17 @@ public class PCRBController : ControllerBase {
string metricName = "GetPCR3Documents"; string metricName = "GetPCR3Documents";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -653,8 +810,17 @@ public class PCRBController : ControllerBase {
string metricName = "CreatePCRBAttendee"; string metricName = "CreatePCRBAttendee";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -686,8 +852,17 @@ public class PCRBController : ControllerBase {
string metricName = "UpdatePCRBAttendee"; string metricName = "UpdatePCRBAttendee";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -719,8 +894,17 @@ public class PCRBController : ControllerBase {
string metricName = "DeletePCRBAttendee"; string metricName = "DeletePCRBAttendee";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -752,8 +936,17 @@ public class PCRBController : ControllerBase {
string metricName = "GetPCRBAttendees"; string metricName = "GetPCRBAttendees";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -785,45 +978,18 @@ public class PCRBController : ControllerBase {
string metricName = "NotifyNewPCRBApprovers"; string metricName = "NotifyNewPCRBApprovers";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
} }
} }
[HttpPost]
[Route("pcrb/notify/approver")]
public async Task<IActionResult> NotifyApprover(PCRBNotification notification) {
DateTime start = DateTime.Now;
bool isArgumentError = false;
bool isInternalError = false;
string errorMessage = "";
try {
_logger.LogInformation("Attempting to notify an approver");
if (notification is null) throw new ArgumentNullException("notification cannot be null");
if (notification.PCRB is null) throw new ArgumentNullException("PCRB cannot be null");
if (notification.Approval is null) throw new ArgumentNullException("approval cannot be null");
if (string.IsNullOrWhiteSpace(notification.Message)) throw new ArgumentException("message cannot be null or empty");
await _pcrbService.NotifyApprover(notification);
return Ok();
} catch (ArgumentException ex) {
isArgumentError = true;
errorMessage = ex.Message;
return BadRequest(errorMessage);
} catch (Exception ex) {
isInternalError = true;
errorMessage = $"Unable to notify an approver, because {ex.Message}";
return Problem(errorMessage);
} finally {
string metricName = "NotifyPCRBApprover";
DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds;
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
}
} }
[HttpPost] [HttpPost]
@ -856,8 +1022,17 @@ public class PCRBController : ControllerBase {
string metricName = "NotifyPCRBApprovers"; string metricName = "NotifyPCRBApprovers";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -891,8 +1066,17 @@ public class PCRBController : ControllerBase {
string metricName = "NotifyPCRBOriginator"; string metricName = "NotifyPCRBOriginator";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
_logger.LogWarning(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_logger.LogError(errorMessage);
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} }
} }
@ -926,272 +1110,17 @@ public class PCRBController : ControllerBase {
string metricName = "NotifyPCRBResponsiblePerson"; string metricName = "NotifyPCRBResponsiblePerson";
DateTime end = DateTime.Now; DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds; double millisecondsDiff = (end - start).TotalMilliseconds;
_monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); if (isArgumentError) {
} _logger.LogWarning(errorMessage);
} _monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
[HttpPost] _logger.LogError(errorMessage);
[Route("pcrb/followUp")] _monInClient.PostStatus(metricName, StatusValue.Critical);
public async Task<IActionResult> CreateFollowUp(PCRBFollowUp followUp) { } else {
DateTime start = DateTime.Now; _monInClient.PostStatus(metricName, StatusValue.Ok);
bool isArgumentError = false; }
bool isInternalError = false;
string errorMessage = "";
try {
_logger.LogInformation("Attempting to create follow up");
if (followUp is null) throw new ArgumentNullException("follow up cannot be null");
await _pcrbService.CreateFollowUp(followUp);
return Ok();
} catch (ArgumentException ex) {
isArgumentError = true;
errorMessage = ex.Message;
return BadRequest(errorMessage);
} catch (Exception ex) {
isInternalError = true;
errorMessage = $"Unable to create follow up, because {ex.Message}";
return Problem(errorMessage);
} finally {
string metricName = "CreatePCRBFollowUp";
DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds;
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
}
}
[HttpGet]
[Route("pcrb/followUps")]
public async Task<IActionResult> GetFollowUpsByPlanNumber(int planNumber, bool bypassCache) {
DateTime start = DateTime.Now;
bool isArgumentError = false;
bool isInternalError = false;
string errorMessage = "";
try {
_logger.LogInformation($"Attempting to get follow ups for plan# {planNumber}");
if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#");
List<PCRBFollowUp> attendees = (await _pcrbService.GetFollowUpsByPlanNumber(planNumber, bypassCache)).ToList();
return Ok(attendees);
} catch (ArgumentException ex) {
isArgumentError = true;
errorMessage = ex.Message;
return BadRequest(errorMessage);
} catch (Exception ex) {
isInternalError = true;
errorMessage = $"Cannot get follow ups for plan# {planNumber}, because {ex.Message}";
return Problem(errorMessage);
} finally {
string metricName = "GetPCRBFollowUps";
DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds;
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
}
}
[HttpPut]
[Route("pcrb/followUp")]
public async Task<IActionResult> UpdateFollowUp(PCRBFollowUp followUp) {
DateTime start = DateTime.Now;
bool isArgumentError = false;
bool isInternalError = false;
string errorMessage = "";
try {
_logger.LogInformation("Attempting to update follow up");
if (followUp is null) throw new ArgumentNullException("follow up cannot be null");
await _pcrbService.UpdateFollowUp(followUp);
return Ok();
} catch (ArgumentException ex) {
isArgumentError = true;
errorMessage = ex.Message;
return BadRequest(errorMessage);
} catch (Exception ex) {
isInternalError = true;
errorMessage = $"Unable to update follow up, because {ex.Message}";
return Problem(errorMessage);
} finally {
string metricName = "UpdatePCRBFollowUp";
DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds;
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
}
}
[HttpDelete]
[Route("pcrb/followUp")]
public async Task<IActionResult> DeleteFollowUp(int id) {
DateTime start = DateTime.Now;
bool isArgumentError = false;
bool isInternalError = false;
string errorMessage = "";
try {
_logger.LogInformation("Attempting to delete follow up");
if (id <= 0) throw new ArgumentException($"{id} is not a valid PCRB follow up ID");
await _pcrbService.DeleteFollowUp(id);
return Ok();
} catch (ArgumentException ex) {
isArgumentError = true;
errorMessage = ex.Message;
return BadRequest(errorMessage);
} catch (Exception ex) {
isInternalError = true;
errorMessage = $"Unable to delete follow up, because {ex.Message}";
return Problem(errorMessage);
} finally {
string metricName = "DeletePCRBFollowUp";
DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds;
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
}
}
[HttpPost]
[Route("pcrb/followUpComment")]
public async Task<IActionResult> CreateFollowUpComment(PCRBFollowUpComment comment) {
DateTime start = DateTime.Now;
bool isArgumentError = false;
bool isInternalError = false;
string errorMessage = "";
try {
_logger.LogInformation("Attempting to create follow up comment");
if (comment is null) throw new ArgumentNullException("comment cannot be null");
await _pcrbService.CreateFollowUpComment(comment);
return Ok();
} catch (ArgumentException ex) {
isArgumentError = true;
errorMessage = ex.Message;
return BadRequest(errorMessage);
} catch (Exception ex) {
isInternalError = true;
errorMessage = $"Unable to create follow up comment, because {ex.Message}";
return Problem(errorMessage);
} finally {
string metricName = "CreatePCRBFollowUpComment";
DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds;
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
}
}
[HttpGet]
[Route("pcrb/followUpComments")]
public async Task<IActionResult> GetFollowUpCommentsByPlanNumber(int planNumber, bool bypassCache) {
DateTime start = DateTime.Now;
bool isArgumentError = false;
bool isInternalError = false;
string errorMessage = "";
try {
_logger.LogInformation($"Attempting to get follow up comments for plan# {planNumber}");
if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#");
List<PCRBFollowUpComment> comments = (await _pcrbService.GetFollowUpCommentsByPlanNumber(planNumber, bypassCache)).ToList();
return Ok(comments);
} catch (ArgumentException ex) {
isArgumentError = true;
errorMessage = ex.Message;
return BadRequest(errorMessage);
} catch (Exception ex) {
isInternalError = true;
errorMessage = $"Cannot get follow up comments for plan# {planNumber}, because {ex.Message}";
return Problem(errorMessage);
} finally {
string metricName = "GetPCRBFollowUpComments";
DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds;
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
}
}
[HttpPut]
[Route("pcrb/followUpComment")]
public async Task<IActionResult> UpdateFollowUpComment(PCRBFollowUpComment comment) {
DateTime start = DateTime.Now;
bool isArgumentError = false;
bool isInternalError = false;
string errorMessage = "";
try {
_logger.LogInformation("Attempting to update follow up comment");
if (comment is null) throw new ArgumentNullException("comment cannot be null");
await _pcrbService.UpdateFollowUpComment(comment);
return Ok();
} catch (ArgumentException ex) {
isArgumentError = true;
errorMessage = ex.Message;
return BadRequest(errorMessage);
} catch (Exception ex) {
isInternalError = true;
errorMessage = $"Unable to update follow up comment, because {ex.Message}";
return Problem(errorMessage);
} finally {
string metricName = "UpdatePCRBFollowUpComment";
DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds;
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
}
}
[HttpDelete]
[Route("pcrb/followUpComment")]
public async Task<IActionResult> DeleteFollowUpComment(int id) {
DateTime start = DateTime.Now;
bool isArgumentError = false;
bool isInternalError = false;
string errorMessage = "";
try {
_logger.LogInformation("Attempting to delete follow up comment");
if (id <= 0) throw new ArgumentException($"{id} is not a valid PCRB follow up comment ID");
await _pcrbService.DeleteFollowUpComment(id);
return Ok();
} catch (ArgumentException ex) {
isArgumentError = true;
errorMessage = ex.Message;
return BadRequest(errorMessage);
} catch (Exception ex) {
isInternalError = true;
errorMessage = $"Unable to delete follow up comment, because {ex.Message}";
return Problem(errorMessage);
} finally {
string metricName = "DeletePCRBFollowUpComment";
DateTime end = DateTime.Now;
double millisecondsDiff = (end - start).TotalMilliseconds;
_monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
} }
} }
} }

View File

@ -6,7 +6,6 @@ using dotenv.net;
using MesaFabApproval.API.Clients; using MesaFabApproval.API.Clients;
using MesaFabApproval.API.Services; using MesaFabApproval.API.Services;
using MesaFabApproval.API.Utilities;
using MesaFabApproval.Models; using MesaFabApproval.Models;
using MesaFabApproval.Shared.Services; using MesaFabApproval.Shared.Services;
@ -95,7 +94,6 @@ builder.Services.AddScoped<IECNService, ECNService>();
builder.Services.AddScoped<ISmtpService, SmtpService>(); builder.Services.AddScoped<ISmtpService, SmtpService>();
builder.Services.AddScoped<IUserService, UserService>(); builder.Services.AddScoped<IUserService, UserService>();
builder.Services.AddScoped<IMonInWorkerClient, MonInWorkerClient>(); builder.Services.AddScoped<IMonInWorkerClient, MonInWorkerClient>();
builder.Services.AddScoped<IMonInUtils, MonInUtils>();
builder.Services.AddScoped<IAuthenticationService, AuthenticationService>(); builder.Services.AddScoped<IAuthenticationService, AuthenticationService>();
builder.Services.AddScoped<IMRBService, MRBService>(); builder.Services.AddScoped<IMRBService, MRBService>();
builder.Services.AddScoped<IPCRBService, PCRBService>(); builder.Services.AddScoped<IPCRBService, PCRBService>();
@ -103,6 +101,7 @@ builder.Services.AddScoped<IApprovalService, ApprovalService>();
builder.Services.AddControllers(); builder.Services.AddControllers();
#if DEBUG
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c => { builder.Services.AddSwaggerGen(c => {
c.SwaggerDoc("v1", new OpenApiInfo { c.SwaggerDoc("v1", new OpenApiInfo {
@ -129,9 +128,13 @@ builder.Services.AddSwaggerGen(c => {
} }
}); });
}); });
#endif
WebApplication app = builder.Build(); WebApplication app = builder.Build();
if (Debugger.IsAttached)
app.Services.GetRequiredService<IApprovalService>();
app.UseCors(); app.UseCors();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.

View File

@ -13,7 +13,6 @@ public interface IApprovalService {
Task<IEnumerable<User>> GetApprovalGroupMembers(int subRoleId); Task<IEnumerable<User>> GetApprovalGroupMembers(int subRoleId);
Task CreateApproval(Approval approval); Task CreateApproval(Approval approval);
Task UpdateApproval(Approval approval); Task UpdateApproval(Approval approval);
Task DeleteApproval(int approvalID);
Task Approve(Approval approval); Task Approve(Approval approval);
Task Deny(Approval approval); Task Deny(Approval approval);
Task<IEnumerable<Approval>> GetApprovalsForIssueId(int issueId, bool bypassCache); Task<IEnumerable<Approval>> GetApprovalsForIssueId(int issueId, bool bypassCache);
@ -41,11 +40,12 @@ public class ApprovalService : IApprovalService {
StringBuilder queryBuilder = new(); StringBuilder queryBuilder = new();
queryBuilder.Append("insert into Approval (IssueID, RoleName, SubRole, UserID, SubRoleID, ItemStatus, "); queryBuilder.Append("insert into Approval (IssueID, RoleName, SubRole, UserID, SubRoleID, ItemStatus, ");
queryBuilder.Append("AssignedDate, DocumentTypeID, DisplayDeniedDocument, Step, TaskID, CompletedDate) "); queryBuilder.Append("AssignedDate, DocumentTypeID, DisplayDeniedDocument, Step, TaskID) ");
queryBuilder.Append("values (@IssueID, @RoleName, @SubRole, @UserID, @SubRoleID, 0, @AssignedDate, 3, 0, @Step, "); queryBuilder.Append($"values ({approval.IssueID}, '{approval.RoleName}', '{approval.SubRole}', {approval.UserID}, ");
queryBuilder.Append("@TaskID, @CompletedDate)"); queryBuilder.Append($"{approval.SubRoleID}, 0, '{approval.AssignedDate.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"3, 0, {approval.Step}, {approval.TaskID});");
int rowsCreated = await _dalService.ExecuteAsync(queryBuilder.ToString(), approval); int rowsCreated = await _dalService.ExecuteAsync(queryBuilder.ToString());
if (rowsCreated <= 0) throw new Exception("Unable to insert approval in database"); if (rowsCreated <= 0) throw new Exception("Unable to insert approval in database");
@ -70,16 +70,19 @@ public class ApprovalService : IApprovalService {
if (approvals is null || approvals.Count() == 0) { if (approvals is null || approvals.Count() == 0) {
StringBuilder queryBuilder = new(); StringBuilder queryBuilder = new();
queryBuilder.Append("select a.*, src.SubRoleCategoryItem from Approval a "); queryBuilder.Append("select a.*, src.SubRoleCategoryItem from Approval a ");
queryBuilder.Append("left outer join SubRole sr on a.SubRoleID=sr.SubRoleID "); queryBuilder.Append("join SubRole sr on a.SubRoleID=sr.SubRoleID ");
queryBuilder.Append("left outer join SubRoleCategory src on sr.SubRoleCategoryID=src.SubRoleCategoryID "); queryBuilder.Append("join SubRoleCategory src on sr.SubRoleCategoryID=src.SubRoleCategoryID ");
queryBuilder.Append($"where a.IssueID={issueId}"); queryBuilder.Append($"where a.IssueID={issueId}");
approvals = (await _dalService.QueryAsync<Approval>(queryBuilder.ToString())).ToList(); approvals = (await _dalService.QueryAsync<Approval>(queryBuilder.ToString())).ToList();
foreach (Approval approval in approvals) { foreach (Approval approval in approvals) {
int successfulUpdates = 0;
User? user = await _userService.GetUserByUserId(approval.UserID); User? user = await _userService.GetUserByUserId(approval.UserID);
if (user is not null) { if (user is not null) {
approval.User = user; approval.User = user;
successfulUpdates++;
} }
if (approval.ItemStatus < 0) if (approval.ItemStatus < 0)
@ -88,9 +91,6 @@ public class ApprovalService : IApprovalService {
approval.StatusMessage = "Assigned"; approval.StatusMessage = "Assigned";
if (approval.ItemStatus > 0) if (approval.ItemStatus > 0)
approval.StatusMessage = "Approved"; approval.StatusMessage = "Approved";
if (string.IsNullOrWhiteSpace(approval.SubRoleCategoryItem))
approval.SubRoleCategoryItem = approval.RoleName;
} }
_cache.Set($"approvals{issueId}", approvals, DateTimeOffset.Now.AddMinutes(5)); _cache.Set($"approvals{issueId}", approvals, DateTimeOffset.Now.AddMinutes(5));
@ -217,12 +217,9 @@ public class ApprovalService : IApprovalService {
if (approvals is null) { if (approvals is null) {
StringBuilder queryBuilder = new(); StringBuilder queryBuilder = new();
queryBuilder.Append($"select a.*, src.SubRoleCategoryItem from Approval a "); queryBuilder.Append($"select a.*, src.SubRoleCategoryItem from Approval a ");
queryBuilder.Append("left outer join SubRole sr on a.SubRoleID=sr.SubRoleID "); queryBuilder.Append("join SubRole sr on a.SubRoleID=sr.SubRoleID ");
queryBuilder.Append("left outer join SubRoleCategory src on sr.SubRoleCategoryID=src.SubRoleCategoryID "); queryBuilder.Append("join SubRoleCategory src on sr.SubRoleCategoryID=src.SubRoleCategoryID ");
queryBuilder.Append($"where UserID={userId} and ItemStatus=0 and "); queryBuilder.Append($"where UserID={userId} and ");
queryBuilder.Append($"(AssignedDate is not null and ");
queryBuilder.Append($"AssignedDate <= '{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}' and ");
queryBuilder.Append($"AssignedDate > '{DateTimeOffset.Now.AddYears(-2).DateTime.ToString("yyyy-MM-dd HH:mm:ss")}') and ");
queryBuilder.Append($"((CompletedDate >= '{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}') or "); queryBuilder.Append($"((CompletedDate >= '{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}') or ");
queryBuilder.Append($"(CompletedDate is null));"); queryBuilder.Append($"(CompletedDate is null));");
string sql = queryBuilder.ToString(); string sql = queryBuilder.ToString();
@ -265,23 +262,6 @@ public class ApprovalService : IApprovalService {
} }
} }
public async Task DeleteApproval(int approvalID) {
try {
_logger.LogInformation($"Attempting to delete approval with ID: {approvalID}");
if (approvalID <= 0) throw new ArgumentException("Invalid approval ID");
string sql = "delete from Approval where ApprovalID=@ApprovalID";
int rowsDeleted = await _dalService.ExecuteAsync(sql, new { ApprovalID = approvalID });
if (rowsDeleted <= 0) throw new Exception("unable to delete approval from database");
} catch (Exception ex) {
_logger.LogError($"Unable to delete approval with ID: {approvalID}, because {ex.Message}");
throw;
}
}
public async Task Approve(Approval approval) { public async Task Approve(Approval approval) {
try { try {
_logger.LogInformation("Attempting to submit approval"); _logger.LogInformation("Attempting to submit approval");

View File

@ -144,7 +144,7 @@ public class AuthenticationService : IAuthenticationService {
Audience = _jwtAudience, Audience = _jwtAudience,
Subject = identity, Subject = identity,
NotBefore = DateTime.Now, NotBefore = DateTime.Now,
Expires = DateTime.Now.AddDays(1), Expires = DateTime.Now.AddHours(8),
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
}; };

View File

@ -1,5 +1,4 @@
using System.Data; using System.Data;
using System.Text;
using Dapper; using Dapper;
@ -7,9 +6,7 @@ namespace MesaFabApproval.API.Services;
public interface IDalService { public interface IDalService {
Task<IEnumerable<T>> QueryAsync<T>(string sql); Task<IEnumerable<T>> QueryAsync<T>(string sql);
Task<IEnumerable<T>> QueryAsync<T>(string sql, object paramaters);
Task<int> ExecuteAsync(string sql); Task<int> ExecuteAsync(string sql);
Task<int> ExecuteAsync<T>(string sql, T paramaters);
} }
public class DalService : IDalService { public class DalService : IDalService {
@ -58,45 +55,6 @@ public class DalService : IDalService {
return result; return result;
} }
public async Task<IEnumerable<T>> QueryAsync<T>(string sql, object parameters) {
if (sql is null) throw new ArgumentNullException("sql cannot be null");
if (parameters is null) throw new ArgumentNullException("parameters cannot be null");
StringBuilder logBuilder = new();
int remainingRetries = RETRIES;
bool queryWasSuccessful = false;
Exception exception = null;
IEnumerable<T> result = new List<T>();
while (!queryWasSuccessful && remainingRetries > 0) {
int backoffSeconds = (RETRIES - remainingRetries--) * BACKOFF_SECONDS_INTERVAL;
Task.Delay(backoffSeconds * 1000).Wait();
try {
logBuilder.Clear();
logBuilder.Append($"Attempting to perform query with {sql} ");
logBuilder.Append($"and parameters {parameters.ToString()}. ");
logBuilder.Append($"Remaining retries: {remainingRetries}");
_logger.LogInformation(logBuilder.ToString());
using (IDbConnection conn = _dbConnectionService.GetConnection()) {
result = await conn.QueryAsync<T>(sql, parameters);
}
queryWasSuccessful = true;
} catch (Exception ex) {
_logger.LogError($"An exception occurred while attempting to perform a query. Exception: {ex.Message}");
exception = ex;
}
}
if (!queryWasSuccessful && exception is not null) {
throw exception;
}
return result;
}
public async Task<int> ExecuteAsync(string sql) { public async Task<int> ExecuteAsync(string sql) {
if (sql is null) throw new ArgumentNullException("sql cannot be null"); if (sql is null) throw new ArgumentNullException("sql cannot be null");
@ -128,36 +86,4 @@ public class DalService : IDalService {
return rowsAffected; return rowsAffected;
} }
public async Task<int> ExecuteAsync<T>(string sql, T parameters) {
if (sql is null) throw new ArgumentNullException("sql cannot be null");
int remainingRetries = RETRIES;
bool queryWasSuccessful = false;
Exception exception = null;
int rowsAffected = 0;
while (!queryWasSuccessful && remainingRetries > 0) {
int backoffSeconds = (RETRIES - remainingRetries--) * BACKOFF_SECONDS_INTERVAL;
Task.Delay(backoffSeconds * 1000).Wait();
try {
_logger.LogInformation($"Attempting to execute {sql} with parameters. Remaining retries: {remainingRetries}");
using (IDbConnection conn = _dbConnectionService.GetConnection()) {
rowsAffected = await conn.ExecuteAsync(sql, parameters);
}
queryWasSuccessful = true;
} catch (Exception ex) {
_logger.LogError($"An exception occurred while attempting to execute a query. Exception: {ex.Message}");
exception = ex;
}
}
if (!queryWasSuccessful && exception is not null) {
throw exception;
}
return rowsAffected;
}
} }

View File

@ -4,7 +4,6 @@ namespace MesaFabApproval.API.Services;
public interface IECNService { public interface IECNService {
Task<bool> IsValidECNNumber(int number); Task<bool> IsValidECNNumber(int number);
Task<IEnumerable<int>> GetAllECNNumbers();
} }
public class ECNService : IECNService { public class ECNService : IECNService {
@ -44,19 +43,4 @@ public class ECNService : IECNService {
throw; throw;
} }
} }
public async Task<IEnumerable<int>> GetAllECNNumbers() {
try {
_logger.LogInformation("Attempting to get all ECN#s");
string sql = "select ECNNumber from ECN where Deleted=0 and Cancelled=0";
IEnumerable<int> allEcnNumbers = await _dalService.QueryAsync<int>(sql);
return allEcnNumbers;
} catch (Exception ex) {
_logger.LogError($"Unable to get all ECN#s, because {ex.Message}");
throw;
}
}
} }

View File

@ -212,9 +212,9 @@ public class MRBService : IMRBService {
StringBuilder queryBuilder = new(); StringBuilder queryBuilder = new();
queryBuilder.Append("select (u.FirstName + ' ' + u.LastName) as OriginatorName, m.* "); queryBuilder.Append("select (u.FirstName + ' ' + u.LastName) as OriginatorName, m.* ");
queryBuilder.Append("from MRB m join Users u on m.OriginatorID = u.UserID "); queryBuilder.Append("from MRB m join Users u on m.OriginatorID = u.UserID ");
queryBuilder.Append("where m.Title = @Title"); queryBuilder.Append($"where m.Title = '{title}'");
mrb = (await _dalService.QueryAsync<MRB>(queryBuilder.ToString(), new { Title=title })).FirstOrDefault(); mrb = (await _dalService.QueryAsync<MRB>(queryBuilder.ToString())).FirstOrDefault();
_cache.Set($"mrb{title}", mrb, DateTimeOffset.Now.AddHours(1)); _cache.Set($"mrb{title}", mrb, DateTimeOffset.Now.AddHours(1));
} }
@ -852,8 +852,8 @@ public class MRBService : IMRBService {
convertToPart += partStr; convertToPart += partStr;
} }
dt.Rows.Add(action.Action, convertFromCustomer, convertFromPart, action.LotNumber, dt.Rows.Add(action.Action, convertFromCustomer, convertFromPart, action.Quantity.ToString(),
action.Quantity.ToString(), convertToCustomer, convertToPart, convertToCustomer, convertToPart,
DateTimeUtilities.GetDateAsStringMinDefault(action.AssignedDate), DateTimeUtilities.GetDateAsStringMinDefault(action.AssignedDate),
DateTimeUtilities.GetDateAsStringMaxDefault(action.CompletedDate), DateTimeUtilities.GetDateAsStringMaxDefault(action.CompletedDate),
action.CompletedByUser is null ? "" : action.CompletedByUser.GetFullName()); action.CompletedByUser is null ? "" : action.CompletedByUser.GetFullName());

View File

@ -34,18 +34,9 @@ public interface IPCRBService {
Task UpdatePCR3Document(PCR3Document document); Task UpdatePCR3Document(PCR3Document document);
Task<IEnumerable<PCR3Document>> GetPCR3DocumentsForPlanNumber(int planNumber, bool bypassCache); Task<IEnumerable<PCR3Document>> GetPCR3DocumentsForPlanNumber(int planNumber, bool bypassCache);
Task NotifyNewApprovals(PCRB pcrb); Task NotifyNewApprovals(PCRB pcrb);
Task NotifyApprover(PCRBNotification notification);
Task NotifyApprovers(PCRBNotification notification); Task NotifyApprovers(PCRBNotification notification);
Task NotifyOriginator(PCRBNotification notification); Task NotifyOriginator(PCRBNotification notification);
Task NotifyResponsiblePerson(PCRBActionItemNotification notification); Task NotifyResponsiblePerson(PCRBActionItemNotification notification);
Task CreateFollowUp(PCRBFollowUp followUp);
Task<IEnumerable<PCRBFollowUp>> GetFollowUpsByPlanNumber(int planNumber, bool bypassCache);
Task UpdateFollowUp(PCRBFollowUp followUp);
Task DeleteFollowUp(int id);
Task CreateFollowUpComment(PCRBFollowUpComment comment);
Task<IEnumerable<PCRBFollowUpComment>> GetFollowUpCommentsByPlanNumber(int planNumber, bool bypassCache);
Task UpdateFollowUpComment(PCRBFollowUpComment comment);
Task DeleteFollowUpComment(int id);
} }
public class PCRBService : IPCRBService { public class PCRBService : IPCRBService {
@ -83,15 +74,16 @@ public class PCRBService : IPCRBService {
if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null"); if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null");
pcrb.LastUpdateDate = DateTime.Now;
StringBuilder queryBuilder = new(); StringBuilder queryBuilder = new();
queryBuilder.Append("insert into CCChangeControl (OwnerID, Title, ChangeLevel, ReasonForChange, "); queryBuilder.Append("insert into CCChangeControl (OwnerID, Title, ChangeLevel, ReasonForChange, ");
queryBuilder.Append("ChangeDescription, IsITAR, CurrentStep, InsertTimeStamp, LastUpdateDate, Type) "); queryBuilder.Append("ChangeDescription, IsITAR, CurrentStep, InsertTimeStamp, LastUpdateDate) ");
queryBuilder.Append("values (@OwnerID, @Title, @ChangeLevel, @ReasonForChange, @ChangeDescription, "); queryBuilder.Append($"values ({pcrb.OwnerID}, '{pcrb.Title}', '{pcrb.ChangeLevel}', ");
queryBuilder.Append("@IsITAR, @CurrentStep, @InsertTimeStamp, @LastUpdateDate, @Type)"); queryBuilder.Append($"'{pcrb.ReasonForChange}', '{pcrb.ChangeDescription}', ");
queryBuilder.Append($"{Convert.ToInt32(pcrb.IsITAR)}, {pcrb.CurrentStep}, ");
queryBuilder.Append($"'{pcrb.InsertTimeStamp.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"'{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}')");
int rowsCreated = await _dalService.ExecuteAsync(queryBuilder.ToString(), pcrb); int rowsCreated = await _dalService.ExecuteAsync(queryBuilder.ToString());
if (rowsCreated <= 0) throw new Exception("unable to insert new PCRB in the database"); if (rowsCreated <= 0) throw new Exception("unable to insert new PCRB in the database");
} catch (Exception ex) { } catch (Exception ex) {
@ -115,7 +107,6 @@ public class PCRBService : IPCRBService {
foreach (PCRB pcrb in allPCRBs) { foreach (PCRB pcrb in allPCRBs) {
if (string.IsNullOrWhiteSpace(pcrb.OwnerName) && pcrb.OwnerID > 0) if (string.IsNullOrWhiteSpace(pcrb.OwnerName) && pcrb.OwnerID > 0)
pcrb.OwnerName = (await _userService.GetUserByUserId(pcrb.OwnerID)).GetFullName(); pcrb.OwnerName = (await _userService.GetUserByUserId(pcrb.OwnerID)).GetFullName();
pcrb.FollowUps = await GetFollowUpsByPlanNumber(pcrb.PlanNumber, bypassCache);
} }
_cache.Set("allPCRBs", allPCRBs, DateTimeOffset.Now.AddHours(1)); _cache.Set("allPCRBs", allPCRBs, DateTimeOffset.Now.AddHours(1));
@ -150,8 +141,6 @@ public class PCRBService : IPCRBService {
if (string.IsNullOrWhiteSpace(pcrb.OwnerName) && pcrb.OwnerID > 0) if (string.IsNullOrWhiteSpace(pcrb.OwnerName) && pcrb.OwnerID > 0)
pcrb.OwnerName = (await _userService.GetUserByUserId(pcrb.OwnerID)).GetFullName(); pcrb.OwnerName = (await _userService.GetUserByUserId(pcrb.OwnerID)).GetFullName();
pcrb.FollowUps = await GetFollowUpsByPlanNumber(pcrb.PlanNumber, bypassCache);
_cache.Set($"pcrb{planNumber}", pcrb, DateTimeOffset.Now.AddHours(1)); _cache.Set($"pcrb{planNumber}", pcrb, DateTimeOffset.Now.AddHours(1));
_cache.Set($"pcrb{pcrb.Title}", pcrb, DateTimeOffset.Now.AddHours(1)); _cache.Set($"pcrb{pcrb.Title}", pcrb, DateTimeOffset.Now.AddHours(1));
} }
@ -177,9 +166,9 @@ public class PCRBService : IPCRBService {
if (!bypassCache) pcrb = _cache.Get<PCRB>($"pcrb{title}"); if (!bypassCache) pcrb = _cache.Get<PCRB>($"pcrb{title}");
if (pcrb is null) { if (pcrb is null) {
string sql = "select * from CCChangeControl where Title=@Title"; string sql = $"select * from CCChangeControl where Title='{title}'";
pcrb = (await _dalService.QueryAsync<PCRB>(sql, new { Title = title })).FirstOrDefault(); pcrb = (await _dalService.QueryAsync<PCRB>(sql)).FirstOrDefault();
if (pcrb is not null) { if (pcrb is not null) {
if (string.IsNullOrWhiteSpace(pcrb.OwnerName) && pcrb.OwnerID > 0) if (string.IsNullOrWhiteSpace(pcrb.OwnerName) && pcrb.OwnerID > 0)
@ -205,16 +194,18 @@ public class PCRBService : IPCRBService {
if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null"); if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null");
pcrb.LastUpdateDate = DateTime.Now;
StringBuilder queryBuilder = new(); StringBuilder queryBuilder = new();
queryBuilder.Append("update CCChangeControl set OwnerID=@OwnerID, Title=@Title, ChangeLevel=@ChangeLevel, "); queryBuilder.Append($"update CCChangeControl set OwnerID={pcrb.OwnerID}, ");
queryBuilder.Append("Type=@Type, CurrentStep=@CurrentStep, ReasonForChange=@ReasonForChange, "); queryBuilder.Append($"Title='{pcrb.Title.Replace("'", "''")}', ChangeLevel='{pcrb.ChangeLevel}', ");
queryBuilder.Append("ChangeDescription=@ChangeDescription, IsITAR=@IsITAR, ClosedDate=@ClosedDate, "); queryBuilder.Append($"CurrentStep={pcrb.CurrentStep}, ReasonForChange='{pcrb.ReasonForChange.Replace("'", "''")}', ");
queryBuilder.Append("LastUpdateDate=@LastUpdateDate "); queryBuilder.Append($"ChangeDescription='{pcrb.ChangeDescription.Replace("'", "''")}', ");
queryBuilder.Append($"where PlanNumber=@PlanNumber"); queryBuilder.Append($"IsITAR={Convert.ToInt32(pcrb.IsITAR)}, ");
queryBuilder.Append($"InsertTimeStamp='{pcrb.InsertTimeStamp.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"ClosedDate='{pcrb.ClosedDate.ToString("yyyy-MM-dd HH:mm:ss")}', ");
queryBuilder.Append($"LastUpdateDate='{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}' ");
queryBuilder.Append($"where PlanNumber={pcrb.PlanNumber}");
int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString(), pcrb); int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString());
if (rowsAffected <= 0) throw new Exception("unable to perform update in database"); if (rowsAffected <= 0) throw new Exception("unable to perform update in database");
@ -494,20 +485,6 @@ public class PCRBService : IPCRBService {
int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString()); int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString());
if (rowsAffected <= 0) throw new Exception("update failed in database"); if (rowsAffected <= 0) throw new Exception("update failed in database");
IEnumerable<PCRBAttendee>? attendees = _cache.Get<IEnumerable<PCRBAttendee>>($"pcrbAttendees{attendee.PlanNumber}");
if (attendees is not null) {
foreach (PCRBAttendee cachedAttendee in attendees) {
if (cachedAttendee.ID == attendee.ID) {
cachedAttendee.Location = attendee.Location;
cachedAttendee.Attended = attendee.Attended;
cachedAttendee.JobTitle = attendee.JobTitle;
cachedAttendee.AttendeeID = attendee.AttendeeID;
cachedAttendee.Step = attendee.Step;
}
}
_cache.Set($"pcrbAttendees{attendee.PlanNumber}", attendees, DateTimeOffset.Now.AddMinutes(15));
}
} catch (Exception ex) { } catch (Exception ex) {
_logger.LogError($"Unable to update attendee, because {ex.Message}"); _logger.LogError($"Unable to update attendee, because {ex.Message}");
throw; throw;
@ -667,62 +644,6 @@ public class PCRBService : IPCRBService {
} }
} }
public async Task NotifyApprover(PCRBNotification notification) {
try {
_logger.LogInformation("Attempting to send a notification to an approver");
if (notification is null) throw new ArgumentNullException("notification cannot be null");
if (notification.PCRB is null) throw new ArgumentNullException("PCRB cannot be null");
if (notification.Approval is null) throw new ArgumentNullException("approval cannot be null");
User user = await _userService.GetUserByUserId(notification.Approval.UserID);
List<MailAddress> toAddresses = new();
toAddresses.Add(new MailAddress(user.Email));
List<string> ccEmails = new List<string>();
if (notification.NotifyQaPreApprover) {
IEnumerable<User> qaPreApprovers = await GetQAPreApprovers();
foreach (User qaPreApprover in qaPreApprovers) {
if (!ccEmails.Contains(qaPreApprover.Email))
ccEmails.Add(qaPreApprover.Email);
}
}
List<MailAddress> ccAddresses = new();
foreach (string email in ccEmails) {
ccAddresses.Add(new MailAddress(email));
}
StringBuilder sb = new();
string subject = string.Empty;
if (!string.IsNullOrWhiteSpace(notification.Subject)) {
subject = notification.Subject;
} else {
sb.Append($"[Approval Update] Mesa Fab Approval - PCRB# {notification.PCRB.PlanNumber} - ");
sb.Append($"{notification.PCRB.Title}");
subject = sb.ToString();
}
sb.Clear();
sb.Append($"{notification.Message} <br /> <br />");
sb.Append($"Click {_siteBaseUrl}/redirect?redirectPath=pcrb/{notification.PCRB.PlanNumber} ");
sb.Append("to view the PCRB.");
await _smtpService.SendEmail(toAddresses, ccAddresses, subject, sb.ToString());
notification.Approval.NotifyDate = DateTime.Now;
await _approvalService.UpdateApproval(notification.Approval);
} catch (Exception ex) {
_logger.LogError($"Unable to send notification to approver, because {ex.Message}");
throw;
}
}
public async Task NotifyApprovers(PCRBNotification notification) { public async Task NotifyApprovers(PCRBNotification notification) {
try { try {
_logger.LogInformation("Attempting to send notification to approvers"); _logger.LogInformation("Attempting to send notification to approvers");
@ -776,28 +697,9 @@ public class PCRBService : IPCRBService {
List<MailAddress> toAddresses = new(); List<MailAddress> toAddresses = new();
toAddresses.Add(new MailAddress(user.Email)); toAddresses.Add(new MailAddress(user.Email));
List<string> ccEmails = new List<string>();
if (notification.NotifyQaPreApprover) {
IEnumerable<User> qaPreApprovers = await GetQAPreApprovers();
foreach (User qaPreApprover in qaPreApprovers) {
if (!ccEmails.Contains(qaPreApprover.Email))
ccEmails.Add(qaPreApprover.Email);
}
}
List<MailAddress> ccAddresses = new(); List<MailAddress> ccAddresses = new();
foreach (string email in ccEmails) {
ccAddresses.Add(new MailAddress(email));
}
string subject = string.Empty; string subject = $"[Update] Mesa Fab Approval - PCRB# {notification.PCRB.PlanNumber} - {notification.PCRB.Title}";
if (!string.IsNullOrWhiteSpace(notification.Subject)) {
subject = notification.Subject;
} else {
subject = $"[Update] Mesa Fab Approval - PCRB# {notification.PCRB.PlanNumber} - {notification.PCRB.Title}";
}
StringBuilder bodyBuilder = new(); StringBuilder bodyBuilder = new();
bodyBuilder.Append($"{notification.Message} <br /> <br />"); bodyBuilder.Append($"{notification.Message} <br /> <br />");
@ -839,174 +741,6 @@ public class PCRBService : IPCRBService {
} }
} }
public async Task CreateFollowUp(PCRBFollowUp followUp) {
try {
_logger.LogInformation("Attempting to create PCRB follow up");
if (followUp is null) throw new ArgumentNullException("follow up cannot be null");
StringBuilder queryBuilder = new();
queryBuilder.Append("insert into CCPCRBFollowUp (PlanNumber, Step, FollowUpDate, CompletedDate, UpdateDate) ");
queryBuilder.Append("values (@PlanNumber, @Step, @FollowUpDate, @CompletedDate, @UpdateDate)");
int rowsReturned = await _dalService.ExecuteAsync<PCRBFollowUp>(queryBuilder.ToString(), followUp);
if (rowsReturned <= 0) throw new Exception("unable to insert new follow up in the database");
} catch (Exception ex) {
_logger.LogError($"Unable to create new follow up, because {ex.Message}");
throw;
}
}
public async Task<IEnumerable<PCRBFollowUp>> GetFollowUpsByPlanNumber(int planNumber, bool bypassCache) {
try {
_logger.LogInformation($"Attempting to fetch follow ups for PCRB {planNumber}");
if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#");
IEnumerable<PCRBFollowUp>? followUps = new List<PCRBFollowUp>();
if (!bypassCache)
followUps = _cache.Get<IEnumerable<PCRBFollowUp>>($"pcrbFollowUps{planNumber}");
if (followUps is null || followUps.Count() == 0) {
string sql = "select * from CCPCRBFollowUp where PlanNumber=@PlanNumber";
followUps = await _dalService.QueryAsync<PCRBFollowUp>(sql, new { PlanNumber = planNumber });
if (followUps is not null)
_cache.Set($"pcrbFollowUps{planNumber}", followUps, DateTimeOffset.Now.AddHours(1));
}
return followUps ?? new List<PCRBFollowUp>();
} catch (Exception ex) {
_logger.LogError($"Unable to fetch follow ups for PCRB {planNumber}, because {ex.Message}");
throw;
}
}
public async Task UpdateFollowUp(PCRBFollowUp followUp) {
try {
_logger.LogInformation("Attempting to update a follow up");
if (followUp is null)
throw new ArgumentNullException("follow up cannot be null");
StringBuilder queryBuilder = new();
queryBuilder.Append("update CCPCRBFollowUp set Step=@Step, FollowUpDate=@FollowUpDate, IsComplete=@IsComplete, ");
queryBuilder.Append("IsDeleted=@IsDeleted, CompletedDate=@CompletedDate, IsPendingApproval=@IsPendingApproval, ");
queryBuilder.Append("UpdateDate=@UpdateDate ");
queryBuilder.Append("where ID=@ID");
int rowsAffected = await _dalService.ExecuteAsync<PCRBFollowUp>(queryBuilder.ToString(), followUp);
if (rowsAffected <= 0) throw new Exception("update failed in database");
} catch (Exception ex) {
_logger.LogError($"Unable to update follow up, because {ex.Message}");
throw;
}
}
public async Task DeleteFollowUp(int id) {
try {
_logger.LogInformation($"Attempting to delete follow up {id}");
if (id <= 0) throw new ArgumentException($"{id} is not a valid follow up ID");
string sql = "delete from CCPCRBFollowUp where ID=@ID";
int rowsAffected = await _dalService.ExecuteAsync(sql, new { ID = id });
if (rowsAffected <= 0) throw new Exception("delete operation failed in database");
} catch (Exception ex) {
_logger.LogError($"Unable to delete follow up {id}, because {ex.Message}");
throw;
}
}
public async Task CreateFollowUpComment(PCRBFollowUpComment comment) {
try {
_logger.LogInformation("Attempting to create PCRB follow up");
if (comment is null) throw new ArgumentNullException("comment cannot be null");
StringBuilder queryBuilder = new();
queryBuilder.Append("insert into CCPCRBFollowUpComments (PlanNumber, FollowUpID, Comment, CommentDate, UserID) ");
queryBuilder.Append("values (@PlanNumber, @FollowUpID, @Comment, @CommentDate, @UserID)");
int rowsReturned = await _dalService.ExecuteAsync<PCRBFollowUpComment>(queryBuilder.ToString(), comment);
if (rowsReturned <= 0) throw new Exception("unable to insert new follow up comment in the database");
} catch (Exception ex) {
_logger.LogError($"Unable to create new follow up comment, because {ex.Message}");
throw;
}
}
public async Task<IEnumerable<PCRBFollowUpComment>> GetFollowUpCommentsByPlanNumber(int planNumber, bool bypassCache) {
try {
_logger.LogInformation($"Attempting to fetch follow up comments for PCRB {planNumber}");
if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#");
IEnumerable<PCRBFollowUpComment>? comments = new List<PCRBFollowUpComment>();
if (!bypassCache)
comments = _cache.Get<IEnumerable<PCRBFollowUpComment>>($"pcrbFollowUpComments{planNumber}");
if (comments is null || comments.Count() == 0) {
string sql = "select * from CCPCRBFollowUpComments where PlanNumber=@PlanNumber";
comments = await _dalService.QueryAsync<PCRBFollowUpComment>(sql, new { PlanNumber = planNumber });
if (comments is not null)
_cache.Set($"pcrbFollowUpComments{planNumber}", comments, DateTimeOffset.Now.AddHours(1));
}
return comments ?? new List<PCRBFollowUpComment>();
} catch (Exception ex) {
_logger.LogError($"Unable to fetch follow up comments for PCRB {planNumber}, because {ex.Message}");
throw;
}
}
public async Task UpdateFollowUpComment(PCRBFollowUpComment comment) {
try {
_logger.LogInformation("Attempting to update a follow up");
if (comment is null)
throw new ArgumentNullException("comment cannot be null");
StringBuilder queryBuilder = new();
queryBuilder.Append("update CCPCRBFollowUpComments set Comment=@Comment, CommentDate=@CommentDate, ");
queryBuilder.Append("UserID=@UserID where ID=@ID");
int rowsAffected = await _dalService.ExecuteAsync<PCRBFollowUpComment>(queryBuilder.ToString(), comment);
if (rowsAffected <= 0) throw new Exception("update failed in database");
} catch (Exception ex) {
_logger.LogError($"Unable to update follow up comment, because {ex.Message}");
throw;
}
}
public async Task DeleteFollowUpComment(int id) {
try {
_logger.LogInformation($"Attempting to delete follow up comment {id}");
if (id <= 0) throw new ArgumentException($"{id} is not a valid follow up ID");
string sql = "delete from CCPCRBFollowUpComments where ID=@ID";
int rowsAffected = await _dalService.ExecuteAsync(sql, new { ID = id });
if (rowsAffected <= 0) throw new Exception("delete operation failed in database");
} catch (Exception ex) {
_logger.LogError($"Unable to delete follow up comment {id}, because {ex.Message}");
throw;
}
}
private async Task SaveAttachmentInDb(IFormFile file, PCRBAttachment attachment) { private async Task SaveAttachmentInDb(IFormFile file, PCRBAttachment attachment) {
try { try {
_logger.LogInformation($"Attempting to save attachment to database"); _logger.LogInformation($"Attempting to save attachment to database");
@ -1030,34 +764,4 @@ public class PCRBService : IPCRBService {
throw; throw;
} }
} }
private async Task<IEnumerable<User>> GetQAPreApprovers() {
try {
_logger.LogInformation("Attempting to fetch QA Pre-Approvers");
IEnumerable<User> qaPreApprovers = new List<User>();
int qaPreApproverRoleId = await _approvalService.GetRoleIdForRoleName("QA_PRE_APPROVAL");
if (qaPreApproverRoleId > 0) {
IEnumerable<SubRole> qaPreApproverSubRoles =
await _approvalService.GetSubRolesForSubRoleName("QA_PRE_APPROVAL", qaPreApproverRoleId);
foreach (SubRole subRole in qaPreApproverSubRoles) {
IEnumerable<User> members =
await _approvalService.GetApprovalGroupMembers(subRole.SubRoleID);
foreach (User member in members) {
if (!qaPreApprovers.Any(u => u.UserID == member.UserID))
qaPreApprovers = qaPreApprovers.Append(member);
}
}
}
return qaPreApprovers;
} catch (Exception ex) {
_logger.LogError($"Unable to fetch QA Pre-Approvers, because {ex.Message}");
throw;
}
}
} }

View File

@ -1,48 +0,0 @@
using MesaFabApproval;
using MesaFabApproval.API;
using MesaFabApproval.API.Services;
using MesaFabApproval.API.Utilities;
using MesaFabApproval.Shared.Models;
using MesaFabApproval.Shared.Services;
namespace MesaFabApproval.API.Utilities;
public interface IMonInUtils {
public void PostMetrics(string metricName,
double latency,
bool isArgumentError,
bool isInternalError);
}
public class MonInUtils : IMonInUtils {
private readonly IMonInWorkerClient _monInClient;
private readonly ILogger<MonInUtils> _logger;
public MonInUtils(IMonInWorkerClient monInClient, ILogger<MonInUtils> logger) {
_monInClient = monInClient ??
throw new ArgumentNullException("IMonInWorkerClient not injected");
_logger = logger ??
throw new ArgumentNullException("ILogger not injected");
}
public void PostMetrics(string metricName,
double latency,
bool isArgumentError,
bool isInternalError) {
try {
_logger.LogInformation("Attempting to post metrics to MonIn");
_monInClient.PostAverage(metricName + "Latency", latency);
if (isArgumentError) {
_monInClient.PostStatus(metricName, StatusValue.Ok);
} else if (isInternalError) {
_monInClient.PostStatus(metricName, StatusValue.Critical);
} else {
_monInClient.PostStatus(metricName, StatusValue.Ok);
}
} catch (Exception ex) {
_logger.LogError($"Unable to post metrics to MonIn, because {ex.Message}");
}
}
}

View File

@ -1,100 +0,0 @@
trigger:
branches:
include:
- master
paths:
include:
- MesaFabApproval.API
- MesaFabApproval.Shared
variables:
buildConfiguration: "Release"
stages:
- stage: Test
displayName: "Test"
pool:
name: MesaFabApproval
demands: Fab2ApprovalSystem-Dev
jobs:
- job: BuildPublish
steps:
- script: |
echo build configuration: $(BuildConfiguration)
displayName: "Echo Check"
- task: DotNetCoreCLI@2
displayName: "Build"
inputs:
command: "build"
configuration: $(BuildConfiguration)
projects: MesaFabApproval.API
- task: DotNetCoreCLI@2
displayName: "Test"
inputs:
command: "test"
configuration: $(BuildConfiguration)
publishTestResults: true
projects: MesaFabApproval.API.Test
- task: DotNetCoreCLI@2
displayName: "Publish"
inputs:
command: "publish"
publishWebProjects: false
projects: MesaFabApproval.API
zipAfterPublish: true
arguments: "-c $(BuildConfiguration) -o $(Build.ArtifactStagingDirectory) -r win-x64 --self-contained"
- task: CopyFiles@2
displayName: "Copy Files"
inputs:
SourceFolder: "$(Build.ArtifactStagingDirectory)"
TargetFolder: 'D:\$(Build.Repository.Name)\API\$(Build.BuildId)\$(BuildConfiguration)'
CleanTargetFolder: true
retryCount: "3"
- stage: Prod
displayName: "Prod"
pool:
name: MesaFabApproval
demands: Fab2ApprovalSystem
jobs:
- job: BuildPublish
steps:
- script: |
echo build configuration: $(BuildConfiguration)
displayName: "Echo Check"
- task: DotNetCoreCLI@2
displayName: "Build"
inputs:
command: "build"
configuration: $(BuildConfiguration)
projects: MesaFabApproval.API
- task: DotNetCoreCLI@2
displayName: "Test"
inputs:
command: "test"
configuration: $(BuildConfiguration)
publishTestResults: true
projects: MesaFabApproval.API.Test
- task: DotNetCoreCLI@2
displayName: "Publish"
inputs:
command: "publish"
publishWebProjects: false
projects: MesaFabApproval.API
zipAfterPublish: true
arguments: "-c $(BuildConfiguration) -o $(Build.ArtifactStagingDirectory) -r win-x64 --self-contained"
- task: CopyFiles@2
displayName: "Copy Files"
inputs:
SourceFolder: "$(Build.ArtifactStagingDirectory)"
TargetFolder: 'D:\$(Build.Repository.Name)\API\$(Build.BuildId)\$(BuildConfiguration)'
CleanTargetFolder: true
retryCount: "3"

View File

@ -1,95 +0,0 @@
using System;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using MesaFabApproval.Client.Services;
using MesaFabApproval.Shared.Models;
using Microsoft.Extensions.Caching.Memory;
using Moq;
using Moq.Protected;
using Xunit;
namespace MesaFabApproval.Client.Test;
public class ApprovalServiceTests {
private readonly Mock<IMemoryCache> _cacheMock;
private readonly Mock<IHttpClientFactory> _httpClientFactoryMock;
private readonly ApprovalService _approvalService;
public ApprovalServiceTests() {
_cacheMock = new Mock<IMemoryCache>();
_httpClientFactoryMock = new Mock<IHttpClientFactory>();
_approvalService = new ApprovalService(_cacheMock.Object, _httpClientFactoryMock.Object);
}
[Fact]
public async Task DeleteApproval_ValidApprovalID_DeletesApproval() {
int approvalID = 1;
Mock<HttpMessageHandler> handlerMock = new Mock<HttpMessageHandler>();
handlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(req => req.Method == HttpMethod.Delete),
ItExpr.IsAny<CancellationToken>()
)
.ReturnsAsync(new HttpResponseMessage {
StatusCode = HttpStatusCode.OK,
});
HttpClient httpClient = new HttpClient(handlerMock.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_httpClientFactoryMock.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await _approvalService.DeleteApproval(approvalID);
handlerMock.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(req => req.Method == HttpMethod.Delete),
ItExpr.IsAny<CancellationToken>()
);
}
[Fact]
public async Task DeleteApproval_InvalidApprovalID_ThrowsArgumentException() {
int approvalID = 0;
await Assert.ThrowsAsync<ArgumentException>(() => _approvalService.DeleteApproval(approvalID));
}
[Fact]
public async Task DeleteApproval_DeletionFails_ThrowsException() {
int approvalID = 1;
Mock<HttpMessageHandler> handlerMock = new Mock<HttpMessageHandler>();
handlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(req => req.Method == HttpMethod.Delete),
ItExpr.IsAny<CancellationToken>()
)
.ReturnsAsync(new HttpResponseMessage {
StatusCode = HttpStatusCode.BadRequest,
ReasonPhrase = "Bad Request"
});
HttpClient httpClient = new HttpClient(handlerMock.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_httpClientFactoryMock.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await Assert.ThrowsAsync<Exception>(() => _approvalService.DeleteApproval(approvalID));
}
}

View File

@ -1,31 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="MudBlazor" Version="8.3.0" />
<PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\MesaFabApproval.Client\MesaFabApproval.Client.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
</ItemGroup>
</Project>

View File

@ -1,18 +0,0 @@
using Microsoft.Extensions.Caching.Memory;
using Moq;
namespace MesaFabApproval.Client.Test;
public static class MockMemoryCacheService {
public static Mock<IMemoryCache> GetMemoryCache(object expectedValue) {
Mock<IMemoryCache> mockMemoryCache = new Mock<IMemoryCache>();
mockMemoryCache
.Setup(x => x.TryGetValue(It.IsAny<object>(), out expectedValue))
.Returns(true);
mockMemoryCache
.Setup(x => x.CreateEntry(It.IsAny<object>()))
.Returns(Mock.Of<ICacheEntry>());
return mockMemoryCache;
}
}

View File

@ -1,320 +0,0 @@
using System.Net;
using System.Text.Json;
using MesaFabApproval.Client.Services;
using MesaFabApproval.Shared.Models;
using Microsoft.Extensions.Caching.Memory;
using Moq;
using Moq.Protected;
using MudBlazor;
namespace MesaFabApproval.Client.Test;
public class PCRBFollowUpCommentTests {
private readonly Mock<IMemoryCache> _mockCache;
private readonly Mock<IHttpClientFactory> _mockHttpClientFactory;
private readonly Mock<ISnackbar> _mockSnackbar;
private readonly Mock<IUserService> _mockUserService;
private readonly PCRBService _pcrbService;
private static PCRBFollowUpComment FOLLOW_UP_COMMENT = new PCRBFollowUpComment {
ID = 1,
PlanNumber = 123,
FollowUpID = 1,
Comment = "Test Comment",
UserID = 1
};
private static HttpResponseMessage GET_RESPONSE = new HttpResponseMessage {
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(new List<PCRBFollowUpComment> { FOLLOW_UP_COMMENT }))
};
private static IEnumerable<PCRBFollowUpComment> FOLLOW_UPS_COMMENTS = new List<PCRBFollowUpComment>() { FOLLOW_UP_COMMENT };
private static HttpResponseMessage SUCCESSFUL_RESPONSE = new HttpResponseMessage(HttpStatusCode.OK);
private static HttpResponseMessage UNSUCCESSFUL_RESPONSE = new HttpResponseMessage(HttpStatusCode.InternalServerError);
public PCRBFollowUpCommentTests() {
_mockCache = MockMemoryCacheService.GetMemoryCache(FOLLOW_UPS_COMMENTS);
_mockHttpClientFactory = new Mock<IHttpClientFactory>();
_mockSnackbar = new Mock<ISnackbar>();
_mockUserService = new Mock<IUserService>();
_pcrbService = new PCRBService(
_mockCache.Object,
_mockHttpClientFactory.Object,
_mockSnackbar.Object,
_mockUserService.Object);
}
[Fact]
public async Task CreateFollowUpComment_WithValidParams_ShouldCallHttpPost_AndRefreshCache() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Post),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(SUCCESSFUL_RESPONSE)
.Verifiable();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(GET_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await _pcrbService.CreateFollowUpComment(FOLLOW_UP_COMMENT);
mockHttpMessageHandler.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(
req =>
req.Method == HttpMethod.Post &&
req.RequestUri != null &&
req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUpComment")),
ItExpr.IsAny<CancellationToken>());
mockHttpMessageHandler.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(
req =>
req.Method == HttpMethod.Get &&
req.RequestUri != null &&
req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUpComments?planNumber=123&bypassCache=True")),
ItExpr.IsAny<CancellationToken>());
}
[Fact]
public async Task CreateFollowUpComment_WithBadResponse_ShouldThrowException() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Post),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(UNSUCCESSFUL_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUpComment(FOLLOW_UP_COMMENT));
}
[Fact]
public async Task CreateFollowUpComment_WithNullParam_ShouldThrowException() {
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.CreateFollowUpComment(null));
}
[Fact]
public async Task GetFollowUpCommentsByPlanNumber_WithBypassCache_ShouldCallHttpGetAndReturnFollowUps() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(GET_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
IEnumerable<PCRBFollowUpComment> comments = await _pcrbService.GetFollowUpCommentsByPlanNumber(123, true);
mockHttpMessageHandler.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(
req =>
req.Method == HttpMethod.Get &&
req.RequestUri != null &&
req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUpComments?planNumber=123&bypassCache=True")),
ItExpr.IsAny<CancellationToken>());
Assert.Single(comments);
}
[Fact]
public async Task GetFollowUpCommentsByPlanNumber_WithoutBypassCache_ShouldReturnFollowUpsFromCache() {
IEnumerable<PCRBFollowUpComment> comments = await _pcrbService.GetFollowUpCommentsByPlanNumber(1, false);
Assert.Single(comments);
}
[Fact]
public async Task GetFollowUpCommentsByPlanNumber_WithBadResponse_ShouldThrowException() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(UNSUCCESSFUL_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.GetFollowUpCommentsByPlanNumber(1, true));
}
[Fact]
public async Task UpdateFollowUpComment_WithValidParams_ShouldCallHttpPut() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Put),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(SUCCESSFUL_RESPONSE)
.Verifiable();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(GET_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await _pcrbService.UpdateFollowUpComment(FOLLOW_UP_COMMENT);
mockHttpMessageHandler.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(
req =>
req.Method == HttpMethod.Put &&
req.RequestUri != null &&
req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUpComment")),
ItExpr.IsAny<CancellationToken>());
mockHttpMessageHandler.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(
req =>
req.Method == HttpMethod.Get &&
req.RequestUri != null &&
req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUpComments?planNumber=123&bypassCache=True")),
ItExpr.IsAny<CancellationToken>());
}
[Fact]
public async Task UpdateFollowUpComment_WithNullParam_ShouldThrowException() {
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.UpdateFollowUpComment(null));
}
[Fact]
public async Task UpdateFollowUpComment_WithBadResponse_ShouldThrowException() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Put),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(UNSUCCESSFUL_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUpComment(FOLLOW_UP_COMMENT));
}
[Fact]
public async Task DeleteFollowUpComment_WithValidParams_ShouldCallHttpDelete() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Delete),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(SUCCESSFUL_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await _pcrbService.DeleteFollowUpComment(1);
mockHttpMessageHandler.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(
req =>
req.Method == HttpMethod.Delete &&
req.RequestUri != null &&
req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUpComment?id=1")),
ItExpr.IsAny<CancellationToken>());
}
[Fact]
public async Task DeleteFollowUpComment_WithBadId_ShouldThrowException() {
await Assert.ThrowsAsync<ArgumentException>(() => _pcrbService.DeleteFollowUpComment(0));
}
[Fact]
public async Task DeleteFollowUpComment_WithBadResponse_ShouldThrowException() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Delete),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(UNSUCCESSFUL_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.DeleteFollowUpComment(1));
}
}

View File

@ -1,321 +0,0 @@
using System.Net;
using System.Text.Json;
using MesaFabApproval.Client.Services;
using MesaFabApproval.Shared.Models;
using Microsoft.Extensions.Caching.Memory;
using Moq;
using Moq.Protected;
using MudBlazor;
namespace MesaFabApproval.Client.Test;
public partial class PCRBFollowUpTests {
private readonly Mock<IMemoryCache> _mockCache;
private readonly Mock<IHttpClientFactory> _mockHttpClientFactory;
private readonly Mock<ISnackbar> _mockSnackbar;
private readonly Mock<IUserService> _mockUserService;
private readonly PCRBService _pcrbService;
private static PCRBFollowUp FOLLOW_UP = new PCRBFollowUp {
ID = 1,
PlanNumber = 123,
Step = 1,
FollowUpDate = DateTime.Now
};
private static HttpResponseMessage GET_RESPONSE = new HttpResponseMessage {
StatusCode = HttpStatusCode.OK,
Content = new StringContent(JsonSerializer.Serialize(new List<PCRBFollowUp> { FOLLOW_UP }))
};
private static IEnumerable<PCRBFollowUp> FOLLOW_UPS = new List<PCRBFollowUp>() {
new PCRBFollowUp { ID = 1, PlanNumber = 1, Step = 1, FollowUpDate = DateTime.Now }
};
private static HttpResponseMessage SUCCESSFUL_RESPONSE = new HttpResponseMessage(HttpStatusCode.OK);
private static HttpResponseMessage UNSUCCESSFUL_RESPONSE = new HttpResponseMessage(HttpStatusCode.InternalServerError);
public PCRBFollowUpTests() {
_mockCache = MockMemoryCacheService.GetMemoryCache(FOLLOW_UPS);
_mockHttpClientFactory = new Mock<IHttpClientFactory>();
_mockSnackbar = new Mock<ISnackbar>();
_mockUserService = new Mock<IUserService>();
_pcrbService = new PCRBService(
_mockCache.Object,
_mockHttpClientFactory.Object,
_mockSnackbar.Object,
_mockUserService.Object);
}
[Fact]
public async Task CreateFollowUp_WithValidParams_ShouldCallHttpPost_AndRefreshCache() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Post),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(SUCCESSFUL_RESPONSE)
.Verifiable();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(GET_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await _pcrbService.CreateFollowUp(FOLLOW_UP);
mockHttpMessageHandler.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(
req =>
req.Method == HttpMethod.Post &&
req.RequestUri != null &&
req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUp")),
ItExpr.IsAny<CancellationToken>());
mockHttpMessageHandler.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(
req =>
req.Method == HttpMethod.Get &&
req.RequestUri != null &&
req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUps?planNumber=123&bypassCache=True")),
ItExpr.IsAny<CancellationToken>());
}
[Fact]
public async Task CreateFollowUp_WithBadResponse_ShouldThrowException() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Post),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(UNSUCCESSFUL_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUp(FOLLOW_UP));
}
[Fact]
public async Task CreateFollowUp_WithNullParam_ShouldThrowException() {
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.CreateFollowUp(null));
}
[Fact]
public async Task GetFollowUpsByPlanNumber_WithBypassCache_ShouldCallHttpGetAndReturnFollowUps() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(GET_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
IEnumerable<PCRBFollowUp> followUps = await _pcrbService.GetFollowUpsByPlanNumber(123, true);
mockHttpMessageHandler.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(
req =>
req.Method == HttpMethod.Get &&
req.RequestUri != null &&
req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUps?planNumber=123&bypassCache=True")),
ItExpr.IsAny<CancellationToken>());
Assert.Single(followUps);
}
[Fact]
public async Task GetFollowUpsByPlanNumber_WithoutBypassCache_ShouldReturnFollowUpsFromCache() {
IEnumerable<PCRBFollowUp> followUps = await _pcrbService.GetFollowUpsByPlanNumber(1, false);
Assert.Single(followUps);
}
[Fact]
public async Task GetFollowUpsByPlanNumber_WithBadResponse_ShouldThrowException() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(UNSUCCESSFUL_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.GetFollowUpsByPlanNumber(1, true));
}
[Fact]
public async Task UpdateFollowUp_WithValidParams_ShouldCallHttpPut() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Put),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(SUCCESSFUL_RESPONSE)
.Verifiable();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(GET_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await _pcrbService.UpdateFollowUp(FOLLOW_UP);
mockHttpMessageHandler.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(
req =>
req.Method == HttpMethod.Put &&
req.RequestUri != null &&
req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUp")),
ItExpr.IsAny<CancellationToken>());
mockHttpMessageHandler.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(
req =>
req.Method == HttpMethod.Get &&
req.RequestUri != null &&
req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUps?planNumber=123&bypassCache=True")),
ItExpr.IsAny<CancellationToken>());
}
[Fact]
public async Task UpdateFollowUp_WithNullParam_ShouldThrowException() {
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.UpdateFollowUp(null));
}
[Fact]
public async Task UpdateFollowUp_WithBadResponse_ShouldThrowException() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Put),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(UNSUCCESSFUL_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUp(FOLLOW_UP));
}
[Fact]
public async Task DeleteFollowUp_WithValidParams_ShouldCallHttpDelete() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Delete),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(SUCCESSFUL_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await _pcrbService.DeleteFollowUp(1);
mockHttpMessageHandler.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(
req =>
req.Method == HttpMethod.Delete &&
req.RequestUri != null &&
req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUp?id=1")),
ItExpr.IsAny<CancellationToken>());
}
[Fact]
public async Task DeleteFollowUp_WithBadId_ShouldThrowException() {
await Assert.ThrowsAsync<ArgumentException>(() => _pcrbService.DeleteFollowUp(0));
}
[Fact]
public async Task DeleteFollowUp_WithBadResponse_ShouldThrowException() {
Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>();
mockHttpMessageHandler.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Delete),
ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(UNSUCCESSFUL_RESPONSE)
.Verifiable();
HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await Assert.ThrowsAsync<Exception>(() => _pcrbService.DeleteFollowUp(1));
}
}

View File

@ -1,156 +0,0 @@
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using MesaFabApproval.Client.Services;
using MesaFabApproval.Shared.Models;
using Microsoft.Extensions.Caching.Memory;
using Moq;
using Moq.Protected;
using MudBlazor;
using Xunit;
namespace MesaFabApproval.Client.Test;
public class PCRBServiceTests {
private readonly Mock<IMemoryCache> _mockCache;
private readonly Mock<IHttpClientFactory> _mockHttpClientFactory;
private readonly Mock<ISnackbar> _mockSnackbar;
private readonly Mock<IUserService> _mockUserService;
private readonly Mock<PCRB> _mockPCRB;
private readonly Mock<Approval> _mockApproval;
private readonly PCRBService _pcrbService;
public PCRBServiceTests() {
_mockCache = new Mock<IMemoryCache>();
_mockHttpClientFactory = new Mock<IHttpClientFactory>();
_mockSnackbar = new Mock<ISnackbar>();
_mockUserService = new Mock<IUserService>();
_mockPCRB = new Mock<PCRB>();
_mockApproval = new Mock<Approval>();
_pcrbService = new PCRBService(
_mockCache.Object,
_mockHttpClientFactory.Object,
_mockSnackbar.Object,
_mockUserService.Object
);
}
[Fact]
public async Task NotifyApprover_ShouldSendNotification() {
PCRBNotification notification = new PCRBNotification {
Message = "Test Message",
PCRB = _mockPCRB.Object,
Approval = _mockApproval.Object
};
Mock<HttpMessageHandler> handlerMock = new Mock<HttpMessageHandler>();
handlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Post),
ItExpr.IsAny<CancellationToken>()
)
.ReturnsAsync(new HttpResponseMessage {
StatusCode = HttpStatusCode.OK
})
.Verifiable();
HttpClient httpClient = new HttpClient(handlerMock.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
await _pcrbService.NotifyApprover(notification);
handlerMock.Protected().Verify(
"SendAsync",
Times.Once(),
ItExpr.Is<HttpRequestMessage>(req =>
req.Method == HttpMethod.Post &&
req.RequestUri == new Uri("https://localhost:5000/pcrb/notify/approver")
),
ItExpr.IsAny<CancellationToken>()
);
}
[Fact]
public async Task NotifyApprover_ShouldThrowException_WhenResponseIsNotSuccess() {
PCRBNotification notification = new PCRBNotification {
Message = "Test Message",
PCRB = _mockPCRB.Object,
Approval = _mockApproval.Object
};
var handlerMock = new Mock<HttpMessageHandler>();
handlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>(
"SendAsync",
ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Post),
ItExpr.IsAny<CancellationToken>()
)
.ReturnsAsync(new HttpResponseMessage {
StatusCode = HttpStatusCode.BadRequest,
ReasonPhrase = "Bad Request"
});
HttpClient httpClient = new HttpClient(handlerMock.Object) {
BaseAddress = new Uri("https://localhost:5000")
};
_mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
Exception exception = await Assert.ThrowsAsync<Exception>(() => _pcrbService.NotifyApprover(notification));
Assert.Equal("Unable to notify PCRB approver, because Bad Request", exception.Message);
}
[Fact]
public async Task NotifyApprover_ShouldThrowException_WhenNotificationIsNull() {
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.NotifyApprover(null));
}
[Fact]
public async Task NotifyApprover_ShouldThrowException_WhenPCRBIsNull() {
PCRBNotification notification = new PCRBNotification {
Message = "Test Message",
PCRB = null,
Approval = _mockApproval.Object
};
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.NotifyApprover(notification));
}
[Fact]
public async Task NotifyApprover_ShouldThrowException_WhenApprovalIsNull() {
PCRBNotification notification = new PCRBNotification {
Message = "Test Message",
PCRB = _mockPCRB.Object,
Approval = null
};
await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.NotifyApprover(notification));
}
[Fact]
public async Task NotifyApprover_ShouldThrowException_WhenMessageIsNullOrEmpty() {
PCRBNotification notification = new PCRBNotification {
Message = null,
PCRB = _mockPCRB.Object,
Approval = _mockApproval.Object
};
await Assert.ThrowsAsync<ArgumentException>(() => _pcrbService.NotifyApprover(notification));
notification.Message = string.Empty;
await Assert.ThrowsAsync<ArgumentException>(() => _pcrbService.NotifyApprover(notification));
}
}

View File

@ -15,15 +15,15 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.14" /> <PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.8" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.14" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.8" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.14" PrivateAssets="all" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.8" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.3.0" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.3.0" /> <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="8.0.14" /> <PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="8.0.8" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" /> <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" />
<PackageReference Include="MudBlazor" Version="8.3.0" /> <PackageReference Include="MudBlazor" Version="7.6.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.6.1" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,2 +1,65 @@
@page "/redirect" @page "/redirect"
@attribute [AllowAnonymous] @attribute [AllowAnonymous]
@inject MesaFabApprovalAuthStateProvider authStateProvider
@inject IAuthenticationService authService
@inject IUserService userService
@inject ISnackbar snackbar
@inject MesaFabApprovalAuthStateProvider authStateProvider
@inject NavigationManager navigationManager
@code {
private string? _jwt;
private string? _refreshToken;
private string? _redirectPath;
protected override async Task OnParametersSetAsync() {
try {
Uri uri = navigationManager.ToAbsoluteUri(navigationManager.Uri);
if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("jwt", out var jwt)) {
_jwt = System.Net.WebUtility.UrlDecode(jwt);
}
if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("refreshToken", out var refreshToken)) {
_refreshToken = System.Net.WebUtility.UrlDecode(refreshToken);
}
if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("redirectPath", out var redirectPath)) {
_redirectPath = redirectPath.ToString();
}
if (!string.IsNullOrWhiteSpace(_jwt) && !string.IsNullOrWhiteSpace(_refreshToken)) {
await authService.SetTokens(_jwt, _refreshToken);
ClaimsPrincipal principal = authService.GetClaimsPrincipalFromJwt(_jwt);
string loginId = userService.GetLoginIdFromClaimsPrincipal(principal);
await authService.ClearCurrentUser();
await authService.ClearTokens();
await authService.SetLoginId(loginId);
await authService.SetTokens(_jwt, _refreshToken);
await authService.SetCurrentUser(null);
await authStateProvider.StateHasChanged(principal);
}
if (authStateProvider.CurrentUser is not null && !string.IsNullOrWhiteSpace(_redirectPath)) {
navigationManager.NavigateTo(_redirectPath);
} else {
await authStateProvider.Logout();
if (!string.IsNullOrWhiteSpace(_redirectPath)) {
navigationManager.NavigateTo($"login/{_redirectPath}");
} else {
navigationManager.NavigateTo("login");
}
}
} catch (Exception ex) {
snackbar.Add($"Redirect failed, because {ex.Message}", Severity.Error);
navigationManager.NavigateTo("login");
}
}
}

View File

@ -1,83 +0,0 @@
using MesaFabApproval.Client.Services;
using MesaFabApproval.Shared.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Caching.Memory;
using MudBlazor;
using System.Security.Claims;
namespace MesaFabApproval.Client.Pages;
public partial class AuthenticatedRedirect {
[Inject] MesaFabApprovalAuthStateProvider authStateProvider { get; set; }
[Inject] IAuthenticationService authService { get; set; }
[Inject] IUserService userService { get; set; }
[Inject] NavigationManager navigationManager { get; set; }
[Inject] IMemoryCache cache { get; set; }
private string? _jwt;
private string? _refreshToken;
private string? _redirectPath;
protected override async Task OnParametersSetAsync() {
try {
Uri uri = navigationManager.ToAbsoluteUri(navigationManager.Uri);
if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("jwt", out var jwt)) {
_jwt = System.Net.WebUtility.UrlDecode(jwt);
}
if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("refreshToken", out var refreshToken)) {
_refreshToken = System.Net.WebUtility.UrlDecode(refreshToken);
}
if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("redirectPath", out var redirectPath)) {
_redirectPath = redirectPath.ToString();
}
if (!string.IsNullOrWhiteSpace(_jwt) && !string.IsNullOrWhiteSpace(_refreshToken)) {
await authService.SetTokens(_jwt, _refreshToken);
ClaimsPrincipal principal = authService.GetClaimsPrincipalFromJwt(_jwt);
string loginId = userService.GetLoginIdFromClaimsPrincipal(principal);
await authService.ClearCurrentUser();
await authService.ClearTokens();
await authService.SetLoginId(loginId);
await authService.SetTokens(_jwt, _refreshToken);
await authService.SetCurrentUser(null);
await authStateProvider.StateHasChanged(principal);
}
AuthTokens authTokens = await authService.GetAuthTokens();
if (authStateProvider.CurrentUser is not null && !string.IsNullOrWhiteSpace(_redirectPath)) {
navigationManager.NavigateTo(_redirectPath);
} else {
await authStateProvider.Logout();
if (!string.IsNullOrWhiteSpace(_redirectPath)) {
cache.Set("redirectUrl", _redirectPath);
navigationManager.NavigateTo($"login?redirectPath={_redirectPath}");
} else {
navigationManager.NavigateTo("login");
}
}
} catch (Exception ex) {
await authStateProvider.Logout();
if (!string.IsNullOrWhiteSpace(_redirectPath)) {
cache.Set("redirectUrl", _redirectPath);
navigationManager.NavigateTo($"login?redirectPath={_redirectPath}");
} else {
navigationManager.NavigateTo("login");
}
}
}
}

View File

@ -37,7 +37,7 @@
</MudDialog> </MudDialog>
@code { @code {
[CascadingParameter] IMudDialogInstance MudDialog { get; set; } [CascadingParameter] MudDialogInstance MudDialog { get; set; }
[Parameter] [Parameter]
public string comments { get; set; } = ""; public string comments { get; set; } = "";

View File

@ -54,7 +54,7 @@
</MudDialog> </MudDialog>
@code { @code {
[CascadingParameter] IMudDialogInstance MudDialog { get; set; } [CascadingParameter] MudDialogInstance MudDialog { get; set; }
[Parameter] [Parameter]
public string comments { get; set; } = ""; public string comments { get; set; } = "";

View File

@ -143,7 +143,7 @@
</MudDialog> </MudDialog>
@code { @code {
[CascadingParameter] IMudDialogInstance MudDialog { get; set; } [CascadingParameter] MudDialogInstance MudDialog { get; set; }
[Parameter] [Parameter]
public MRBAction mrbAction { get; set; } public MRBAction mrbAction { get; set; }
@ -215,7 +215,9 @@
bool actionIsValid = mrbAction.Action.Equals("Block") || mrbAction.Action.Equals("Convert") || bool actionIsValid = mrbAction.Action.Equals("Block") || mrbAction.Action.Equals("Convert") ||
mrbAction.Action.Equals("Other") || mrbAction.Action.Equals("Recall") || mrbAction.Action.Equals("Scrap") || mrbAction.Action.Equals("Other") || mrbAction.Action.Equals("Recall") || mrbAction.Action.Equals("Scrap") ||
mrbAction.Action.Equals("Unblock") || mrbAction.Action.Equals("Waiver"); mrbAction.Action.Equals("Unblock") || mrbAction.Action.Equals("Waiver");
actionIsValid = actionIsValid && !string.IsNullOrWhiteSpace(mrbAction.LotNumber); actionIsValid = actionIsValid && !string.IsNullOrWhiteSpace(mrbAction.Customer) &&
!string.IsNullOrWhiteSpace(mrbAction.PartNumber) &&
!string.IsNullOrWhiteSpace(mrbAction.LotNumber);
actionIsValid = actionIsValid && mrbAction.Quantity > 0; actionIsValid = actionIsValid && mrbAction.Quantity > 0;
if (mrbAction.Action.Equals("Convert", StringComparison.InvariantCultureIgnoreCase)) { if (mrbAction.Action.Equals("Convert", StringComparison.InvariantCultureIgnoreCase)) {
@ -223,9 +225,6 @@
!string.IsNullOrWhiteSpace(convertFromPart) && !string.IsNullOrWhiteSpace(convertFromPart) &&
!string.IsNullOrWhiteSpace(convertToCustomer) && !string.IsNullOrWhiteSpace(convertToCustomer) &&
!string.IsNullOrWhiteSpace(convertToPart); !string.IsNullOrWhiteSpace(convertToPart);
} else {
actionIsValid = actionIsValid && !string.IsNullOrWhiteSpace(mrbAction.Customer) &&
!string.IsNullOrWhiteSpace(mrbAction.PartNumber);
} }
if (mrbAction.Action.Equals("Scrap", StringComparison.InvariantCultureIgnoreCase)) if (mrbAction.Action.Equals("Scrap", StringComparison.InvariantCultureIgnoreCase))

View File

@ -43,7 +43,7 @@
</MudOverlay> </MudOverlay>
@code { @code {
[CascadingParameter] IMudDialogInstance MudDialog { get; set; } [CascadingParameter] MudDialogInstance MudDialog { get; set; }
[Parameter] [Parameter]
public User selectedUser { get; set; } public User selectedUser { get; set; }

View File

@ -31,16 +31,16 @@
Immediate Immediate
AutoGrow /> AutoGrow />
} else { } else {
<MudAutocomplete @bind-Value="@document.ECNNumber" <MudTextField @bind-Value="@document.ECNNumber"
T="int"
SearchFunc="Search"
Required Required
Clearable
RequiredError="You must provide a valid ECN#" RequiredError="You must provide a valid ECN#"
Clearable
Variant="Variant.Outlined" Variant="Variant.Outlined"
InputType="@InputType.Number"
Validation="@(new Func<int, Task<string>>(ECNNoIsValid))" Validation="@(new Func<int, Task<string>>(ECNNoIsValid))"
Label="ECN#" Label="ECN#"
Immediate /> Immediate
AutoGrow />
} }
<MudCheckBox Label="Complete" <MudCheckBox Label="Complete"
Color="Color.Tertiary" Color="Color.Tertiary"
@ -74,13 +74,11 @@
@code { @code {
[CascadingParameter] [CascadingParameter]
IMudDialogInstance MudDialog { get; set; } MudDialogInstance MudDialog { get; set; }
[Parameter] [Parameter]
public required PCR3Document document { get; set; } public required PCR3Document document { get; set; }
private IEnumerable<int> allEcnNumbers = new List<int>();
private string[] errors = { }; private string[] errors = { };
private bool complete = false; private bool complete = false;
@ -91,8 +89,6 @@
protected override async Task OnParametersSetAsync() { protected override async Task OnParametersSetAsync() {
complete = document.CompletedByID > 0; complete = document.CompletedByID > 0;
allEcnNumbers = await ecnService.GetAllECNNumbers();
} }
private async Task Save() { private async Task Save() {
@ -147,8 +143,6 @@
document.DocNumbers.ToLower().Equals("n/a") || document.DocNumbers.ToLower().Equals("n/a") ||
document.DocNumbers.ToLower().Equals("n a") || document.DocNumbers.ToLower().Equals("n a") ||
document.DocNumbers.ToLower().Equals("not applicable")) { document.DocNumbers.ToLower().Equals("not applicable")) {
if (string.IsNullOrWhiteSpace(document.Comment))
document.Comment = "Not required";
return true; return true;
} }
return false; return false;
@ -161,13 +155,4 @@
StateHasChanged(); StateHasChanged();
return result; return result;
} }
private async Task<IEnumerable<int>> Search(string searchValue, CancellationToken token) {
if (string.IsNullOrWhiteSpace(searchValue))
return allEcnNumbers;
return allEcnNumbers
.Where(x => x.ToString().StartsWith(searchValue, StringComparison.InvariantCultureIgnoreCase))
.Order();
}
} }

View File

@ -73,7 +73,7 @@
@code { @code {
[CascadingParameter] [CascadingParameter]
IMudDialogInstance MudDialog { get; set; } MudDialogInstance MudDialog { get; set; }
[Parameter] [Parameter]
public int planNumber { get; set; } = 0; public int planNumber { get; set; } = 0;

View File

@ -61,7 +61,7 @@
@code { @code {
[CascadingParameter] [CascadingParameter]
IMudDialogInstance MudDialog { get; set; } MudDialogInstance MudDialog { get; set; }
[Parameter] [Parameter]
public int planNumber { get; set; } = 0; public int planNumber { get; set; } = 0;

View File

@ -58,7 +58,7 @@
</MudDialog> </MudDialog>
@code { @code {
[CascadingParameter] IMudDialogInstance MudDialog { get; set; } [CascadingParameter] MudDialogInstance MudDialog { get; set; }
[Parameter] [Parameter]
public int planNumber { get; set; } = 0; public int planNumber { get; set; } = 0;

View File

@ -43,7 +43,7 @@
</MudOverlay> </MudOverlay>
@code { @code {
[CascadingParameter] IMudDialogInstance MudDialog { get; set; } [CascadingParameter] MudDialogInstance MudDialog { get; set; }
[Parameter] [Parameter]
public User selectedUser { get; set; } public User selectedUser { get; set; }

View File

@ -1,5 +1,16 @@
@page "/" @page "/"
@page "/Dashboard" @page "/Dashboard"
@inject IConfiguration Configuration
@inject MesaFabApprovalAuthStateProvider stateProvider
@inject IApprovalService approvalService
@inject IMemoryCache cache
@inject NavigationManager navigationManager
@inject ISnackbar snackbar
@inject IMRBService mrbService
@inject IPCRBService pcrbService
@inject IECNService ecnService
@inject ICAService caService
@inject IJSRuntime jsRuntime
<PageTitle>Dashboard</PageTitle> <PageTitle>Dashboard</PageTitle>
@ -26,7 +37,7 @@
</MudTableSortLabel> </MudTableSortLabel>
</MudTh> </MudTh>
<MudTh> <MudTh>
<MudTableSortLabel SortBy="new Func<Approval,object>(x=>GetRoleName(x))"> <MudTableSortLabel SortBy="new Func<Approval,object>(x=>x.SubRoleCategoryItem)">
Role Role
</MudTableSortLabel> </MudTableSortLabel>
</MudTh> </MudTh>
@ -47,7 +58,7 @@
<MudLink OnClick="@(() => FollowLink(context.IssueID))">@context.IssueID</MudLink> <MudLink OnClick="@(() => FollowLink(context.IssueID))">@context.IssueID</MudLink>
} }
</MudTd> </MudTd>
<MudTd DataLabel="Role">@(GetRoleName(context))</MudTd> <MudTd DataLabel="Role">@context.SubRoleCategoryItem</MudTd>
<MudTd DataLabel="Assigned Date">@DateTimeUtilities.GetDateAsStringMinDefault(context.AssignedDate)</MudTd> <MudTd DataLabel="Assigned Date">@DateTimeUtilities.GetDateAsStringMinDefault(context.AssignedDate)</MudTd>
<MudTd DataLabel="Step">@context.Step</MudTd> <MudTd DataLabel="Step">@context.Step</MudTd>
</RowTemplate> </RowTemplate>
@ -215,3 +226,138 @@
</MudTabPanel> </MudTabPanel>
</MudTabs> </MudTabs>
</MudPaper> </MudPaper>
@code {
private IEnumerable<Approval> approvalList = new List<Approval>();
private IEnumerable<MRB> myMRBs = new List<MRB>();
private IEnumerable<PCRB> myPCRBs = new List<PCRB>();
private IEnumerable<int> ecnNumbers = new HashSet<int>();
private IEnumerable<int> caNumbers = new HashSet<int>();
private IEnumerable<int> mrbNumbers = new HashSet<int>();
private IEnumerable<int> pcrbNumbers = new HashSet<int>();
private bool myApprovalsProcessing = false;
private bool myMrbsProcessing = false;
private bool myPcrbsProcessing = false;
private string mrbSearchString = "";
private string pcrbSearchString = "";
protected async override Task OnParametersSetAsync() {
try {
if (stateProvider.CurrentUser is not null) {
myApprovalsProcessing = true;
approvalList = (await approvalService.GetApprovalsForUserId(stateProvider.CurrentUser.UserID, true))
.Where(a => a.CompletedDate > DateTime.Now && a.ItemStatus == 0)
.ToList()
.OrderByDescending(x => x.AssignedDate);
myApprovalsProcessing = false;
myMrbsProcessing = true;
myMRBs = (await mrbService.GetAllMRBs(false)).Where(m => m.OriginatorID == stateProvider.CurrentUser.UserID)
.ToList()
.OrderByDescending(x => x.SubmittedDate);
myMrbsProcessing = false;
myPcrbsProcessing = true;
myPCRBs = (await pcrbService.GetAllPCRBs(false)).Where(p => p.OwnerID == stateProvider.CurrentUser.UserID)
.ToList()
.OrderByDescending(p => p.InsertTimeStamp);
myPcrbsProcessing = false;
}
} catch (Exception ex) {
myApprovalsProcessing = false;
myMrbsProcessing = false;
myPcrbsProcessing = false;
snackbar.Add($"Unable to load the dashboard, because {ex.Message}", Severity.Error);
}
}
private async Task FollowLink(int issueId) {
HashSet<Task> tasks = new();
bool isEcn = false;
bool isCa = false;
bool isMrb = false;
bool isPcrb = false;
if (ecnNumbers.Contains(issueId))
isEcn = true;
if (caNumbers.Contains(issueId))
isCa = true;
if (mrbNumbers.Contains(issueId))
isMrb = true;
if (pcrbNumbers.Contains(issueId))
isPcrb = true;
if (!isEcn && !isCa && !isMrb) {
Task<bool> isEcnTask = ecnService.ECNNumberIsValid(issueId);
tasks.Add(isEcnTask);
Task<bool> isCaTask = caService.CANumberIsValid(issueId);
tasks.Add(isCaTask);
Task<bool> isMrbTask = mrbService.NumberIsValid(issueId);
tasks.Add(isMrbTask);
Task<bool> isPcrbTask = pcrbService.IdIsValid(issueId);
tasks.Add(isPcrbTask);
await Task.WhenAll(tasks);
if (isEcnTask.Result) {
isEcn = true;
} else if (isCaTask.Result) {
isCa = true;
} else if (isMrbTask.Result) {
isMrb = true;
} else if (isPcrbTask.Result) {
isPcrb = true;
}
}
if (isEcn) await GoToExternal($"{Configuration["OldFabApprovalUrl"]}/ECN/Edit?IssueID={issueId}", "");
if (isCa) await GoToExternal($"{Configuration["OldFabApprovalUrl"]}/CorrectiveAction/Edit?IssueID={issueId}", "");
if (isMrb) GoTo($"mrb/{issueId}");
if (isPcrb) GoTo($"pcrb/{issueId}");
}
private void GoTo(string page) {
cache.Set("redirectUrl", page);
navigationManager.NavigateTo("/" + page);
}
private async Task GoToExternal(string url, string content) {
IJSObjectReference windowModule = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "./js/OpenInNewWindow.js");
await windowModule.InvokeAsync<object>("OpenInNewWindow", url, content);
}
private bool FilterFuncForMRBTable(MRB mrb) => MRBFilterFunc(mrb, mrbSearchString);
private bool MRBFilterFunc(MRB mrb, string searchString) {
if (string.IsNullOrWhiteSpace(searchString))
return true;
if (mrb.Title.ToLower().Contains(searchString.Trim().ToLower()))
return true;
if (mrb.MRBNumber.ToString().Contains(searchString.Trim()))
return true;
return false;
}
private bool FilterFuncForPCRBTable(PCRB pcrb) => PCRBFilterFunc(pcrb, pcrbSearchString);
private bool PCRBFilterFunc(PCRB pcrb, string searchString) {
if (string.IsNullOrWhiteSpace(searchString))
return true;
if (pcrb.Title.ToLower().Contains(searchString.Trim().ToLower()))
return true;
if (pcrb.PlanNumber.ToString().Contains(searchString.Trim()))
return true;
return false;
}
private string GetCurrentPCRBStep(int step) {
if (step < 0 || step > (PCRB.Stages.Length - 1)) return string.Empty;
else return PCRB.Stages[step];
}
}

View File

@ -1,165 +0,0 @@
using MesaFabApproval.Client.Services;
using MesaFabApproval.Shared.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.JSInterop;
using MudBlazor;
namespace MesaFabApproval.Client.Pages;
public partial class Dashboard {
[Inject] IConfiguration Configuration { get; set; }
[Inject] MesaFabApprovalAuthStateProvider stateProvider { get; set; }
[Inject] IApprovalService approvalService { get; set; }
[Inject] IMemoryCache cache { get; set; }
[Inject] NavigationManager navigationManager { get; set; }
[Inject] ISnackbar snackbar { get; set; }
[Inject] IMRBService mrbService { get; set; }
[Inject] IPCRBService pcrbService { get; set; }
[Inject] IECNService ecnService { get; set; }
[Inject] ICAService caService { get; set; }
[Inject] IJSRuntime jsRuntime { get; set; }
private IEnumerable<Approval> approvalList = new List<Approval>();
private IEnumerable<MRB> myMRBs = new List<MRB>();
private IEnumerable<PCRB> myPCRBs = new List<PCRB>();
private IEnumerable<int> ecnNumbers = new HashSet<int>();
private IEnumerable<int> caNumbers = new HashSet<int>();
private IEnumerable<int> mrbNumbers = new HashSet<int>();
private IEnumerable<int> pcrbNumbers = new HashSet<int>();
private bool myApprovalsProcessing = false;
private bool myMrbsProcessing = false;
private bool myPcrbsProcessing = false;
private string mrbSearchString = "";
private string pcrbSearchString = "";
protected async override Task OnParametersSetAsync() {
try {
if (stateProvider.CurrentUser is not null) {
myApprovalsProcessing = true;
approvalList = (await approvalService.GetApprovalsForUserId(stateProvider.CurrentUser.UserID, true))
.Where(a => a.CompletedDate > DateTime.Now && a.ItemStatus == 0)
.ToList()
.OrderByDescending(x => x.AssignedDate);
myApprovalsProcessing = false;
myMrbsProcessing = true;
myMRBs = (await mrbService.GetAllMRBs(false)).Where(m => m.OriginatorID == stateProvider.CurrentUser.UserID)
.ToList()
.OrderByDescending(x => x.SubmittedDate);
myMrbsProcessing = false;
myPcrbsProcessing = true;
myPCRBs = (await pcrbService.GetAllPCRBs(false)).Where(p => p.OwnerID == stateProvider.CurrentUser.UserID)
.ToList()
.OrderByDescending(p => p.InsertTimeStamp);
myPcrbsProcessing = false;
}
} catch (Exception ex) {
myApprovalsProcessing = false;
myMrbsProcessing = false;
myPcrbsProcessing = false;
snackbar.Add(ex.Message, Severity.Error);
}
}
private async Task FollowLink(int issueId) {
HashSet<Task> tasks = new();
bool isEcn = false;
bool isCa = false;
bool isMrb = false;
bool isPcrb = false;
if (ecnNumbers.Contains(issueId))
isEcn = true;
if (caNumbers.Contains(issueId))
isCa = true;
if (mrbNumbers.Contains(issueId))
isMrb = true;
if (pcrbNumbers.Contains(issueId))
isPcrb = true;
if (!isEcn && !isCa && !isMrb) {
Task<bool> isEcnTask = ecnService.ECNNumberIsValid(issueId);
tasks.Add(isEcnTask);
Task<bool> isCaTask = caService.CANumberIsValid(issueId);
tasks.Add(isCaTask);
Task<bool> isMrbTask = mrbService.NumberIsValid(issueId);
tasks.Add(isMrbTask);
Task<bool> isPcrbTask = pcrbService.IdIsValid(issueId);
tasks.Add(isPcrbTask);
await Task.WhenAll(tasks);
if (isEcnTask.Result) {
isEcn = true;
} else if (isCaTask.Result) {
isCa = true;
} else if (isMrbTask.Result) {
isMrb = true;
} else if (isPcrbTask.Result) {
isPcrb = true;
}
}
if (isEcn) await GoToExternal($"{Configuration["OldFabApprovalUrl"]}/ECN/Edit?IssueID={issueId}", "");
if (isCa) await GoToExternal($"{Configuration["OldFabApprovalUrl"]}/CorrectiveAction/Edit?IssueID={issueId}", "");
if (isMrb) GoTo($"mrb/{issueId}");
if (isPcrb) GoTo($"pcrb/{issueId}");
}
private void GoTo(string page) {
cache.Set("redirectUrl", page);
navigationManager.NavigateTo(page);
}
private async Task GoToExternal(string url, string content) {
IJSObjectReference windowModule = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "./js/OpenInNewWindow.js");
await windowModule.InvokeAsync<object>("OpenInNewWindow", url, content);
}
private bool FilterFuncForMRBTable(MRB mrb) => MRBFilterFunc(mrb, mrbSearchString);
private bool MRBFilterFunc(MRB mrb, string searchString) {
if (string.IsNullOrWhiteSpace(searchString))
return true;
if (mrb.Title.ToLower().Contains(searchString.Trim().ToLower()))
return true;
if (mrb.MRBNumber.ToString().Contains(searchString.Trim()))
return true;
return false;
}
private bool FilterFuncForPCRBTable(PCRB pcrb) => PCRBFilterFunc(pcrb, pcrbSearchString);
private bool PCRBFilterFunc(PCRB pcrb, string searchString) {
if (string.IsNullOrWhiteSpace(searchString))
return true;
if (pcrb.Title.ToLower().Contains(searchString.Trim().ToLower()))
return true;
if (pcrb.PlanNumber.ToString().Contains(searchString.Trim()))
return true;
return false;
}
private string GetCurrentPCRBStep(int step) {
if (step < 0 || step > (PCRB.Stages.Length - 1)) return string.Empty;
else return PCRB.Stages[step];
}
private string GetRoleName(Approval approval) {
string roleName = approval.SubRoleCategoryItem;
if (string.IsNullOrWhiteSpace(roleName)) {
roleName = approval.RoleName;
}
return roleName;
}
}

View File

@ -1,4 +1,6 @@
@page "/login" @page "/login"
@page "/login/{redirectUrl}"
@page "/login/{redirectUrl}/{redirectUrlSub}"
@attribute [AllowAnonymous] @attribute [AllowAnonymous]
@inject MesaFabApprovalAuthStateProvider authStateProvider @inject MesaFabApprovalAuthStateProvider authStateProvider
@inject NavigationManager navManager @inject NavigationManager navManager
@ -44,5 +46,68 @@
} }
</MudButton> </MudButton>
<MudDivider /> <MudDivider />
@* <MudButton
Variant="Variant.Filled"
Color="Color.Tertiary"
Class="m-1"
OnClick="LoginLocal" >
@if (processingLocal) {
<MudProgressCircular Class="m-1" Size="Size.Small" Indeterminate="true" />
<MudText>Processing</MudText>
} else {
<MudText>Log In (SSO)</MudText>
}
</MudButton> *@
</MudForm> </MudForm>
</MudPaper> </MudPaper>
@code {
[Parameter]
public string? redirectUrl { get; set; }
[Parameter]
public string? redirectUrlSub { get; set; }
private bool success;
private bool processing = false;
private bool processingLocal = false;
private string[] errors = { };
private string? username;
private string? password;
private async Task SubmitLogin() {
processing = true;
if (string.IsNullOrWhiteSpace(username)) snackbar.Add("Username is required!", Severity.Error);
else if (string.IsNullOrWhiteSpace(password)) snackbar.Add("Password is required!", Severity.Error);
else {
await authStateProvider.LoginAsync(username, password);
if (!string.IsNullOrWhiteSpace(redirectUrl) && !string.IsNullOrWhiteSpace(redirectUrlSub)) {
navManager.NavigateTo($"{redirectUrl}/{redirectUrlSub}");
} else if (!string.IsNullOrWhiteSpace(redirectUrl)) {
navManager.NavigateTo(redirectUrl);
} else {
navManager.NavigateTo("dashboard");
}
}
processing = false;
}
private async Task SubmitIfEnter(KeyboardEventArgs e) {
if (e.Key == "Enter" && success) {
SubmitLogin();
}
}
private async Task LoginLocal() {
processingLocal = true;
await authStateProvider.LoginLocal();
if (!string.IsNullOrWhiteSpace(redirectUrl) && !string.IsNullOrWhiteSpace(redirectUrlSub)) {
navManager.NavigateTo($"{redirectUrl}/{redirectUrlSub}");
} else if (!string.IsNullOrWhiteSpace(redirectUrl)) {
navManager.NavigateTo(redirectUrl);
} else {
navManager.NavigateTo("dashboard");
}
processingLocal = false;
}
}

View File

@ -1,53 +0,0 @@
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.Caching.Memory;
using MudBlazor;
namespace MesaFabApproval.Client.Pages;
public partial class Login {
[Inject] NavigationManager navigationManager { get; set; }
[Inject] IMemoryCache cache { get; set; }
public string? _redirectPath { get; set; }
private bool success;
private bool processing = false;
private string[] errors = { };
private string? username;
private string? password;
protected override async Task OnParametersSetAsync() {
Uri uri = navigationManager.ToAbsoluteUri(navigationManager.Uri);
if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("redirectPath", out var redirectPath)) {
_redirectPath = System.Net.WebUtility.UrlDecode(redirectPath);
}
if (string.IsNullOrWhiteSpace(_redirectPath)) {
_redirectPath = cache.Get<string>("redirectUrl");
}
}
private async Task SubmitLogin() {
processing = true;
if (string.IsNullOrWhiteSpace(username)) snackbar.Add("Username is required!", Severity.Error);
else if (string.IsNullOrWhiteSpace(password)) snackbar.Add("Password is required!", Severity.Error);
else {
await authStateProvider.LoginAsync(username, password);
if (!string.IsNullOrWhiteSpace(_redirectPath)) {
navManager.NavigateTo(_redirectPath);
} else {
navManager.NavigateTo("dashboard");
}
}
processing = false;
}
private async Task SubmitIfEnter(KeyboardEventArgs e) {
if (e.Key == "Enter" && success) {
SubmitLogin();
}
}
}

View File

@ -1,4 +1,9 @@
@page "/mrb/all" @page "/mrb/all"
@using System.Globalization
@inject IMRBService mrbService
@inject ISnackbar snackbar
@inject IMemoryCache cache
@inject NavigationManager navigationManager
<PageTitle>MRB</PageTitle> <PageTitle>MRB</PageTitle>
@ -73,3 +78,42 @@
<MudOverlay @bind-Visible=inProcess DarkBackground="true" AutoClose="false"> <MudOverlay @bind-Visible=inProcess DarkBackground="true" AutoClose="false">
<MudProgressCircular Color="Color.Info" Size="Size.Large" Indeterminate="true" /> <MudProgressCircular Color="Color.Info" Size="Size.Large" Indeterminate="true" />
</MudOverlay> </MudOverlay>
@code {
private bool inProcess = false;
private string searchString = "";
private IEnumerable<MRB> allMrbs = new List<MRB>();
protected override async Task OnParametersSetAsync() {
inProcess = true;
try {
if (mrbService is null) {
throw new Exception("MRB service not injected!");
} else {
allMrbs = await mrbService.GetAllMRBs(false);
}
} catch (Exception ex) {
snackbar.Add(ex.Message, Severity.Error);
}
inProcess = false;
}
private bool FilterFuncForTable(MRB mrb) => FilterFunc(mrb, searchString);
private bool FilterFunc(MRB mrb, string searchString) {
if (string.IsNullOrWhiteSpace(searchString))
return true;
if (mrb.Title.ToLower().Contains(searchString.Trim().ToLower()))
return true;
if (mrb.OriginatorName.ToLower().Contains(searchString.Trim().ToLower()))
return true;
if (mrb.MRBNumber.ToString().Contains(searchString.Trim()))
return true;
return false;
}
private void GoTo(string page) {
cache.Set("redirectUrl", page);
navigationManager.NavigateTo(page);
}
}

View File

@ -1,55 +0,0 @@
using MesaFabApproval.Client.Services;
using MesaFabApproval.Shared.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Caching.Memory;
using MudBlazor;
namespace MesaFabApproval.Client.Pages;
public partial class MRBAll {
[Inject] IMRBService mrbService { get; set; }
[Inject] ISnackbar snackbar { get; set; }
[Inject] IMemoryCache cache { get; set; }
[Inject] NavigationManager navigationManager { get; set; }
private bool inProcess = false;
private string searchString = "";
private IEnumerable<MRB> allMrbs = new List<MRB>();
protected override async Task OnParametersSetAsync() {
inProcess = true;
try {
cache.Set("redirectUrl", "mrb/all");
if (mrbService is null) {
throw new Exception("MRB service not injected!");
} else {
allMrbs = await mrbService.GetAllMRBs(false);
}
} catch (Exception ex) {
snackbar.Add(ex.Message, Severity.Error);
}
inProcess = false;
}
private bool FilterFuncForTable(MRB mrb) => FilterFunc(mrb, searchString);
private bool FilterFunc(MRB mrb, string searchString) {
if (string.IsNullOrWhiteSpace(searchString))
return true;
if (mrb.Title.ToLower().Contains(searchString.Trim().ToLower()))
return true;
if (mrb.OriginatorName.ToLower().Contains(searchString.Trim().ToLower()))
return true;
if (mrb.MRBNumber.ToString().Contains(searchString.Trim()))
return true;
return false;
}
private void GoTo(string page) {
cache.Set("redirectUrl", page);
navigationManager.NavigateTo(page);
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,9 @@
@page "/pcrb/all" @page "/pcrb/all"
@using System.Globalization
@inject IPCRBService pcrbService
@inject ISnackbar snackbar
@inject IMemoryCache cache
@inject NavigationManager navigationManager
<PageTitle>PCRB</PageTitle> <PageTitle>PCRB</PageTitle>
@ -20,7 +25,6 @@
Adornment="Adornment.Start" Adornment="Adornment.Start"
AdornmentIcon="@Icons.Material.Filled.Search" AdornmentIcon="@Icons.Material.Filled.Search"
IconSize="Size.Medium" IconSize="Size.Medium"
Immediate
Class="mt-0" /> Class="mt-0" />
</ToolBarContent> </ToolBarContent>
<HeaderContent> <HeaderContent>
@ -39,37 +43,19 @@
Owner Owner
</MudTableSortLabel> </MudTableSortLabel>
</MudTh> </MudTh>
<MudTh> <MudTh>Stage</MudTh>
<MudTableSortLabel SortBy="new Func<PCRB,object>(x=>x.Type)">
Type
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel SortBy="new Func<PCRB, object>(x=>GetStageName(x.CurrentStep))">
Stage
</MudTableSortLabel>
</MudTh>
<MudTh> <MudTh>
<MudTableSortLabel SortBy="new Func<PCRB,object>(x=>x.InsertTimeStamp)"> <MudTableSortLabel SortBy="new Func<PCRB,object>(x=>x.InsertTimeStamp)">
Submitted Date Submitted Date
</MudTableSortLabel> </MudTableSortLabel>
</MudTh> </MudTh>
<MudTh>
<MudTableSortLabel SortBy="new Func<PCRB,object>(x=>x.LastUpdateDate)">
Last Updated
</MudTableSortLabel>
</MudTh>
<MudTh> <MudTh>
<MudTableSortLabel SortBy="new Func<PCRB,object>(x=>x.ClosedDate)"> <MudTableSortLabel SortBy="new Func<PCRB,object>(x=>x.ClosedDate)">
Completed Date
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel SortBy="new Func<PCRB, object>(x=>(x.FollowUps.FirstOrDefault() is null ?
DateTimeUtilities.MIN_DT:
x.FollowUps.First().FollowUpDate))">
Follow Up Date
</MudTableSortLabel>
</MudTh>
<MudTh>
<MudTableSortLabel SortBy="new Func<PCRB, object>(x=>(x.FollowUps.FirstOrDefault() is null ?
DateTimeUtilities.MIN_DT:
x.FollowUps.First().CompletedDate))">
Closed Date Closed Date
</MudTableSortLabel> </MudTableSortLabel>
</MudTh> </MudTh>
@ -80,20 +66,10 @@
</MudTd> </MudTd>
<MudTd DataLabel="Title">@context.Title</MudTd> <MudTd DataLabel="Title">@context.Title</MudTd>
<MudTd DataLabel="Owner">@context.OwnerName</MudTd> <MudTd DataLabel="Owner">@context.OwnerName</MudTd>
<MudTd DataLabel="Type">@context.Type</MudTd>
<MudTd DataLabel="Stage">@(GetStageName(context.CurrentStep))</MudTd> <MudTd DataLabel="Stage">@(GetStageName(context.CurrentStep))</MudTd>
<MudTd DataLabel="Submitted Date">@DateTimeUtilities.GetDateAsStringMinDefault(context.InsertTimeStamp)</MudTd> <MudTd DataLabel="Submitted Date">@DateTimeUtilities.GetDateAsStringMinDefault(context.InsertTimeStamp)</MudTd>
<MudTd DataLabel="Completed Date">@DateTimeUtilities.GetDateAsStringMaxDefault(context.ClosedDate)</MudTd> <MudTd DataLabel="Last Updated">@DateTimeUtilities.GetDateAsStringMinDefault(context.LastUpdateDate)</MudTd>
<MudTd DataLabel="Follow Up Date">@(DateTimeUtilities.GetDateAsStringMaxDefault(context.FollowUps <MudTd DataLabel="Closed Date">@DateTimeUtilities.GetDateAsStringMaxDefault(context.ClosedDate)</MudTd>
.FirstOrDefault()?.FollowUpDate
)
)
</MudTd>
<MudTd DataLabel="Closed Date">@(DateTimeUtilities.GetDateAsStringMaxDefault(context.FollowUps
.FirstOrDefault()?.CompletedDate
)
)
</MudTd>
</RowTemplate> </RowTemplate>
<PagerContent> <PagerContent>
<MudTablePager /> <MudTablePager />
@ -104,3 +80,47 @@
<MudOverlay @bind-Visible=inProcess DarkBackground="true" AutoClose="false"> <MudOverlay @bind-Visible=inProcess DarkBackground="true" AutoClose="false">
<MudProgressCircular Color="Color.Info" Size="Size.Large" Indeterminate="true" /> <MudProgressCircular Color="Color.Info" Size="Size.Large" Indeterminate="true" />
</MudOverlay> </MudOverlay>
@code {
private bool inProcess = false;
private string searchString = "";
private IEnumerable<PCRB> allPCRBs = new List<PCRB>();
protected override async Task OnParametersSetAsync() {
inProcess = true;
try {
if (pcrbService is null) {
throw new Exception("PCRB service not injected!");
} else {
allPCRBs = await pcrbService.GetAllPCRBs(false);
}
} catch (Exception ex) {
snackbar.Add(ex.Message, Severity.Error);
}
inProcess = false;
}
private bool FilterFuncForTable(PCRB pcrb) => FilterFunc(pcrb, searchString);
private bool FilterFunc(PCRB pcrb, string searchString) {
if (string.IsNullOrWhiteSpace(searchString))
return true;
if (pcrb.Title.ToLower().Contains(searchString.Trim().ToLower()))
return true;
if (pcrb.OwnerName.ToLower().Contains(searchString.Trim().ToLower()))
return true;
if (pcrb.PlanNumber.ToString().Contains(searchString.Trim()))
return true;
return false;
}
private void GoTo(string page) {
cache.Set("redirectUrl", page);
navigationManager.NavigateTo(page);
}
private string GetStageName(int step) {
if (step >= PCRB.Stages.Length || step < 0) return "";
return PCRB.Stages[step];
}
}

View File

@ -1,64 +0,0 @@
using MesaFabApproval.Client.Services;
using MesaFabApproval.Shared.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Caching.Memory;
using MudBlazor;
namespace MesaFabApproval.Client.Pages;
public partial class PCRBAll {
[Inject] IPCRBService pcrbService { get; set; }
[Inject] ISnackbar snackbar { get; set; }
[Inject] IMemoryCache cache { get; set; }
[Inject] NavigationManager navigationManager { get; set; }
private bool inProcess = false;
private string searchString = "";
private IEnumerable<PCRB> allPCRBs = new List<PCRB>();
protected override async Task OnParametersSetAsync() {
inProcess = true;
try {
cache.Set("redirectUrl", "pcrb/all");
if (pcrbService is null) {
throw new Exception("PCRB service not injected!");
} else {
allPCRBs = await pcrbService.GetAllPCRBs(false);
}
} catch (Exception ex) {
snackbar.Add(ex.Message, Severity.Error);
}
inProcess = false;
}
private bool FilterFuncForTable(PCRB pcrb) => FilterFunc(pcrb, searchString);
private bool FilterFunc(PCRB pcrb, string searchString) {
if (string.IsNullOrWhiteSpace(searchString))
return true;
if (pcrb.Title.ToLower().Contains(searchString.Trim().ToLower()))
return true;
if (pcrb.OwnerName.ToLower().Contains(searchString.Trim().ToLower()))
return true;
if (pcrb.Type.ToLower().Contains(searchString.Trim().ToLower()))
return true;
if (GetStageName(pcrb.CurrentStep).ToLower().Contains(searchString.Trim().ToLower()))
return true;
if (pcrb.PlanNumber.ToString().Contains(searchString.Trim()))
return true;
return false;
}
private void GoTo(string page) {
cache.Set("redirectUrl", page);
navigationManager.NavigateTo(page);
}
private string GetStageName(int step) {
if (step >= PCRB.Stages.Length || step < 0) return "";
return PCRB.Stages[step];
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,6 @@ public interface IApprovalService {
Task<IEnumerable<User>> GetApprovalGroupMembers(int subRoleId); Task<IEnumerable<User>> GetApprovalGroupMembers(int subRoleId);
Task CreateApproval(Approval approval); Task CreateApproval(Approval approval);
Task UpdateApproval(Approval approval); Task UpdateApproval(Approval approval);
Task DeleteApproval(int approvalID);
Task Approve(Approval approval); Task Approve(Approval approval);
Task Deny(Approval approval); Task Deny(Approval approval);
Task<IEnumerable<Approval>> GetApprovalsForIssueId(int issueId, bool bypassCache); Task<IEnumerable<Approval>> GetApprovalsForIssueId(int issueId, bool bypassCache);
@ -157,20 +156,6 @@ public class ApprovalService : IApprovalService {
await GetApprovalsForUserId(approval.UserID, true); await GetApprovalsForUserId(approval.UserID, true);
} }
public async Task DeleteApproval(int approvalID) {
if (approvalID <= 0) throw new ArgumentException("Invalid approval ID");
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Delete, $"approval?approvalID={approvalID}");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (!responseMessage.IsSuccessStatusCode) {
throw new Exception($"Unable to delete approval, because {responseMessage.ReasonPhrase}");
}
}
public async Task Approve(Approval approval) { public async Task Approve(Approval approval) {
if (approval is null) throw new ArgumentNullException("approval cannot be null"); if (approval is null) throw new ArgumentNullException("approval cannot be null");

View File

@ -5,7 +5,6 @@ namespace MesaFabApproval.Client.Services;
public interface IECNService { public interface IECNService {
Task<string> ECNNumberIsValidStr(int ecnNumber); Task<string> ECNNumberIsValidStr(int ecnNumber);
Task<bool> ECNNumberIsValid(int number); Task<bool> ECNNumberIsValid(int number);
Task<IEnumerable<int>> GetAllECNNumbers();
} }
public class ECNService : IECNService { public class ECNService : IECNService {
@ -50,32 +49,4 @@ public class ECNService : IECNService {
throw new Exception($"Unable to determine if {number} is a valid ECN#, because {ex.Message}"); throw new Exception($"Unable to determine if {number} is a valid ECN#, because {ex.Message}");
} }
} }
public async Task<IEnumerable<int>> GetAllECNNumbers() {
try {
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"ecn/allNumbers");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (responseMessage.IsSuccessStatusCode) {
string responseContent = await responseMessage.Content.ReadAsStringAsync();
JsonSerializerOptions jsonSerializerOptions = new() {
PropertyNameCaseInsensitive = true
};
IEnumerable<int> allEcnNumbers =
JsonSerializer.Deserialize<IEnumerable<int>>(responseContent, jsonSerializerOptions) ??
new List<int>();
return allEcnNumbers;
} else {
throw new Exception(responseMessage.ReasonPhrase);
}
} catch (Exception ex) {
throw new Exception($"Unable to get all ECN#s, because {ex.Message}");
}
}
} }

View File

@ -2,7 +2,6 @@
using MesaFabApproval.Shared.Models; using MesaFabApproval.Shared.Models;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization; using Microsoft.AspNetCore.Components.Authorization;
using MudBlazor; using MudBlazor;
@ -13,22 +12,18 @@ public class MesaFabApprovalAuthStateProvider : AuthenticationStateProvider, IDi
private readonly IAuthenticationService _authService; private readonly IAuthenticationService _authService;
private readonly IUserService _userService; private readonly IUserService _userService;
private readonly ISnackbar _snackbar; private readonly ISnackbar _snackbar;
private readonly NavigationManager _navigationManager;
public User? CurrentUser { get; private set; } public User? CurrentUser { get; private set; }
public MesaFabApprovalAuthStateProvider(IAuthenticationService authService, public MesaFabApprovalAuthStateProvider(IAuthenticationService authService,
ISnackbar snackbar, ISnackbar snackbar,
IUserService userService, IUserService userService) {
NavigationManager navigationManager) {
_authService = authService ?? _authService = authService ??
throw new ArgumentNullException("IAuthenticationService not injected"); throw new ArgumentNullException("IAuthenticationService not injected");
_snackbar = snackbar ?? _snackbar = snackbar ??
throw new ArgumentNullException("ISnackbar not injected"); throw new ArgumentNullException("ISnackbar not injected");
_userService = userService ?? _userService = userService ??
throw new ArgumentNullException("IUserService not injected"); throw new ArgumentNullException("IUserService not injected");
_navigationManager = navigationManager ??
throw new ArgumentNullException("NavigationManager not injected");
AuthenticationStateChanged += OnAuthenticationStateChangedAsync; AuthenticationStateChanged += OnAuthenticationStateChangedAsync;
} }

View File

@ -4,6 +4,7 @@ using System.Text.Json;
using MesaFabApproval.Shared.Models; using MesaFabApproval.Shared.Models;
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.StaticFiles; using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
@ -36,18 +37,9 @@ public interface IPCRBService {
Task UpdatePCR3Document(PCR3Document document); Task UpdatePCR3Document(PCR3Document document);
Task<IEnumerable<PCR3Document>> GetPCR3DocumentsForPlanNumber(int planNumber, bool bypassCache); Task<IEnumerable<PCR3Document>> GetPCR3DocumentsForPlanNumber(int planNumber, bool bypassCache);
Task NotifyNewApprovals(PCRB pcrb); Task NotifyNewApprovals(PCRB pcrb);
Task NotifyApprover(PCRBNotification notification);
Task NotifyApprovers(PCRBNotification notification); Task NotifyApprovers(PCRBNotification notification);
Task NotifyOriginator(PCRBNotification notification); Task NotifyOriginator(PCRBNotification notification);
Task NotifyResponsiblePerson(PCRBActionItemNotification notification); Task NotifyResponsiblePerson(PCRBActionItemNotification notification);
Task CreateFollowUp(PCRBFollowUp followUp);
Task<IEnumerable<PCRBFollowUp>> GetFollowUpsByPlanNumber(int planNumber, bool bypassCache);
Task UpdateFollowUp(PCRBFollowUp followUp);
Task DeleteFollowUp(int id);
Task CreateFollowUpComment(PCRBFollowUpComment comment);
Task<IEnumerable<PCRBFollowUpComment>> GetFollowUpCommentsByPlanNumber(int planNumber, bool bypassCache);
Task UpdateFollowUpComment(PCRBFollowUpComment comment);
Task DeleteFollowUpComment(int id);
} }
public class PCRBService : IPCRBService { public class PCRBService : IPCRBService {
@ -717,26 +709,6 @@ public class PCRBService : IPCRBService {
throw new Exception($"Unable to notify new PCRB approvers, because {responseMessage.ReasonPhrase}"); throw new Exception($"Unable to notify new PCRB approvers, because {responseMessage.ReasonPhrase}");
} }
public async Task NotifyApprover(PCRBNotification notification) {
if (notification is null) throw new ArgumentNullException("notification cannot be null");
if (notification.PCRB is null) throw new ArgumentNullException("PCRB cannot be null");
if (notification.Approval is null) throw new ArgumentNullException("approval cannot be null");
if (string.IsNullOrWhiteSpace(notification.Message)) throw new ArgumentException("message cannot be null or empty");
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"pcrb/notify/approver") {
Content = new StringContent(JsonSerializer.Serialize(notification),
Encoding.UTF8,
"application/json")
};
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (!responseMessage.IsSuccessStatusCode)
throw new Exception($"Unable to notify PCRB approver, because {responseMessage.ReasonPhrase}");
}
public async Task NotifyApprovers(PCRBNotification notification) { public async Task NotifyApprovers(PCRBNotification notification) {
if (notification is null) throw new ArgumentNullException("notification cannot be null"); if (notification is null) throw new ArgumentNullException("notification cannot be null");
if (notification.PCRB is null) throw new ArgumentNullException("PCRB cannot be null"); if (notification.PCRB is null) throw new ArgumentNullException("PCRB cannot be null");
@ -792,177 +764,4 @@ public class PCRBService : IPCRBService {
if (!responseMessage.IsSuccessStatusCode) if (!responseMessage.IsSuccessStatusCode)
throw new Exception($"Unable to notify PCRB responsible person, because {responseMessage.ReasonPhrase}"); throw new Exception($"Unable to notify PCRB responsible person, because {responseMessage.ReasonPhrase}");
} }
public async Task CreateFollowUp(PCRBFollowUp followUp) {
if (followUp is null) throw new ArgumentNullException("follow up cannot be null");
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"pcrb/followUp") {
Content = new StringContent(JsonSerializer.Serialize(followUp),
Encoding.UTF8,
"application/json")
};
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (!responseMessage.IsSuccessStatusCode)
throw new Exception(responseMessage.ReasonPhrase);
await GetFollowUpsByPlanNumber(followUp.PlanNumber, true);
}
public async Task<IEnumerable<PCRBFollowUp>> GetFollowUpsByPlanNumber(int planNumber, bool bypassCache) {
if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#");
IEnumerable<PCRBFollowUp>? followUps = null;
if (!bypassCache)
followUps = _cache.Get<IEnumerable<PCRBFollowUp>>($"pcrbFollowUps{planNumber}");
if (followUps is null) {
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Get, $"pcrb/followUps?planNumber={planNumber}&bypassCache={bypassCache}");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (responseMessage.IsSuccessStatusCode) {
string responseContent = await responseMessage.Content.ReadAsStringAsync();
JsonSerializerOptions jsonSerializerOptions = new() {
PropertyNameCaseInsensitive = true
};
followUps = JsonSerializer.Deserialize<IEnumerable<PCRBFollowUp>>(responseContent, jsonSerializerOptions) ??
new List<PCRBFollowUp>();
if (followUps.Count() > 0)
_cache.Set($"pcrbFollowUps{planNumber}", followUps, DateTimeOffset.Now.AddHours(1));
} else {
throw new Exception(responseMessage.ReasonPhrase);
}
}
return followUps;
}
public async Task UpdateFollowUp(PCRBFollowUp followUp) {
if (followUp is null) throw new ArgumentNullException("follow up cannot be null");
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Put, $"pcrb/followUp") {
Content = new StringContent(JsonSerializer.Serialize(followUp),
Encoding.UTF8,
"application/json")
};
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (!responseMessage.IsSuccessStatusCode)
throw new Exception(responseMessage.ReasonPhrase);
await GetFollowUpsByPlanNumber(followUp.PlanNumber, true);
}
public async Task DeleteFollowUp(int id) {
if (id <= 0) throw new ArgumentException($"{id} is not a valid PCRB follow up ID");
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Delete, $"pcrb/followUp?id={id}");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (!responseMessage.IsSuccessStatusCode) throw new Exception(responseMessage.ReasonPhrase);
}
public async Task CreateFollowUpComment(PCRBFollowUpComment comment) {
if (comment is null) throw new ArgumentNullException("comment up cannot be null");
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Post, $"pcrb/followUpComment") {
Content = new StringContent(JsonSerializer.Serialize(comment),
Encoding.UTF8,
"application/json")
};
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (!responseMessage.IsSuccessStatusCode)
throw new Exception(responseMessage.ReasonPhrase);
await GetFollowUpCommentsByPlanNumber(comment.PlanNumber, true);
}
public async Task<IEnumerable<PCRBFollowUpComment>> GetFollowUpCommentsByPlanNumber(int planNumber, bool bypassCache) {
if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#");
IEnumerable<PCRBFollowUpComment>? comments = null;
if (!bypassCache)
comments = _cache.Get<IEnumerable<PCRBFollowUpComment>>($"pcrbFollowUpComments{planNumber}");
if (comments is null) {
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage =
new(HttpMethod.Get, $"pcrb/followUpComments?planNumber={planNumber}&bypassCache={bypassCache}");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (responseMessage.IsSuccessStatusCode) {
string responseContent = await responseMessage.Content.ReadAsStringAsync();
JsonSerializerOptions jsonSerializerOptions = new() {
PropertyNameCaseInsensitive = true
};
comments = JsonSerializer.Deserialize<IEnumerable<PCRBFollowUpComment>>(responseContent, jsonSerializerOptions) ??
new List<PCRBFollowUpComment>();
if (comments.Count() > 0) {
foreach (PCRBFollowUpComment comment in comments)
comment.User = await _userService.GetUserByUserId(comment.UserID);
_cache.Set($"pcrbFollowUpComments{planNumber}", comments, DateTimeOffset.Now.AddHours(1));
}
} else {
throw new Exception(responseMessage.ReasonPhrase);
}
}
return comments;
}
public async Task UpdateFollowUpComment(PCRBFollowUpComment comment) {
if (comment is null) throw new ArgumentNullException("comment up cannot be null");
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Put, $"pcrb/followUpComment") {
Content = new StringContent(JsonSerializer.Serialize(comment),
Encoding.UTF8,
"application/json")
};
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (!responseMessage.IsSuccessStatusCode)
throw new Exception(responseMessage.ReasonPhrase);
await GetFollowUpCommentsByPlanNumber(comment.PlanNumber, true);
}
public async Task DeleteFollowUpComment(int id) {
if (id <= 0) throw new ArgumentException($"{id} is not a valid PCRB follow up comment ID");
HttpClient httpClient = _httpClientFactory.CreateClient("API");
HttpRequestMessage requestMessage = new(HttpMethod.Delete, $"pcrb/followUpComment?id={id}");
HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage);
if (!responseMessage.IsSuccessStatusCode) throw new Exception(responseMessage.ReasonPhrase);
}
} }

View File

@ -111,7 +111,7 @@ public class ApiHttpClientHandler : DelegatingHandler {
string? redirectUrl = _cache.Get<string>("redirectUrl"); string? redirectUrl = _cache.Get<string>("redirectUrl");
if (!string.IsNullOrWhiteSpace(redirectUrl)) { if (!string.IsNullOrWhiteSpace(redirectUrl)) {
_navigationManager.NavigateTo($"login?redirectPath={redirectUrl}"); _navigationManager.NavigateTo($"login/{redirectUrl}");
} else { } else {
_navigationManager.NavigateTo("login"); _navigationManager.NavigateTo("login");
} }

View File

@ -1,100 +0,0 @@
trigger:
branches:
include:
- master
paths:
include:
- MesaFabApproval.Client
- MesaFabApproval.Shared
variables:
buildConfiguration: "Release"
stages:
- stage: Test
displayName: "Test"
pool:
name: MesaFabApproval
demands: Fab2ApprovalSystem-Dev
jobs:
- job: BuildPublish
steps:
- script: |
echo build configuration: $(BuildConfiguration)
displayName: "Echo Check"
- task: DotNetCoreCLI@2
displayName: "Build"
inputs:
command: "build"
configuration: $(BuildConfiguration)
projects: MesaFabApproval.Client
- task: DotNetCoreCLI@2
displayName: "Test"
inputs:
command: "test"
configuration: $(BuildConfiguration)
publishTestResults: true
projects: MesaFabApproval.Client.Test
- task: DotNetCoreCLI@2
displayName: "Publish"
inputs:
command: "publish"
publishWebProjects: false
projects: MesaFabApproval.Client
zipAfterPublish: true
arguments: "-c $(BuildConfiguration) -o $(Build.ArtifactStagingDirectory) -r win-x64 --self-contained"
- task: CopyFiles@2
displayName: "Copy Files"
inputs:
SourceFolder: "$(Build.ArtifactStagingDirectory)"
TargetFolder: 'D:\$(Build.Repository.Name)\Client\$(Build.BuildId)\$(BuildConfiguration)'
CleanTargetFolder: true
retryCount: "3"
- stage: Prod
displayName: "Prod"
pool:
name: MesaFabApproval
demands: Fab2ApprovalSystem
jobs:
- job: BuildPublish
steps:
- script: |
echo build configuration: $(BuildConfiguration)
displayName: "Echo Check"
- task: DotNetCoreCLI@2
displayName: "Build"
inputs:
command: "build"
configuration: $(BuildConfiguration)
projects: MesaFabApproval.Client
- task: DotNetCoreCLI@2
displayName: "Test"
inputs:
command: "test"
configuration: $(BuildConfiguration)
publishTestResults: true
projects: MesaFabApproval.Client.Test
- task: DotNetCoreCLI@2
displayName: "Publish"
inputs:
command: "publish"
publishWebProjects: false
projects: MesaFabApproval.Client
zipAfterPublish: true
arguments: "-c $(BuildConfiguration) -o $(Build.ArtifactStagingDirectory) -r win-x64 --self-contained"
- task: CopyFiles@2
displayName: "Copy Files"
inputs:
SourceFolder: "$(Build.ArtifactStagingDirectory)"
TargetFolder: 'D:\$(Build.Repository.Name)\Client\$(Build.BuildId)\$(BuildConfiguration)'
CleanTargetFolder: true
retryCount: "3"

View File

@ -8,21 +8,9 @@ public class PCRB {
"PCR1", "PCR1",
"PCR2", "PCR2",
"PCR3", "PCR3",
"Complete", "Complete"
"Follow Up",
"Closed"
]; ];
public enum StagesEnum {
Draft = 0,
PCR1 = 1,
PCR2 = 2,
PCR3 = 3,
Complete = 4,
FollowUp = 5,
Closed = 6
}
public int PlanNumber { get; set; } public int PlanNumber { get; set; }
public int OwnerID { get; set; } public int OwnerID { get; set; }
public string OwnerName { get; set; } = ""; public string OwnerName { get; set; } = "";
@ -35,6 +23,4 @@ public class PCRB {
public DateTime InsertTimeStamp { get; set; } = DateTimeUtilities.MIN_DT; public DateTime InsertTimeStamp { get; set; } = DateTimeUtilities.MIN_DT;
public DateTime LastUpdateDate { get; set; } = DateTimeUtilities.MIN_DT; public DateTime LastUpdateDate { get; set; } = DateTimeUtilities.MIN_DT;
public DateTime ClosedDate { get; set; } = DateTimeUtilities.MAX_DT; public DateTime ClosedDate { get; set; } = DateTimeUtilities.MAX_DT;
public string Type { get; set; } = "";
public IEnumerable<PCRBFollowUp> FollowUps { get; set; } = new List<PCRBFollowUp>();
} }

View File

@ -1,15 +0,0 @@
using MesaFabApproval.Shared.Utilities;
namespace MesaFabApproval.Shared.Models;
public class PCRBFollowUp {
public int ID { get; set; }
public required int PlanNumber { get; set; }
public required int Step { get; set; }
public required DateTime FollowUpDate { get; set; }
public bool IsComplete { get; set; } = false;
public bool IsDeleted { get; set; } = false;
public bool IsPendingApproval { get; set; } = false;
public DateTime CompletedDate { get; set; } = DateTimeUtilities.MAX_DT;
public DateTime UpdateDate { get; set; } = DateTime.Now;
}

View File

@ -1,13 +0,0 @@
using MesaFabApproval.Shared.Utilities;
namespace MesaFabApproval.Shared.Models;
public class PCRBFollowUpComment {
public int ID { get; set; }
public required int PlanNumber { get; set; }
public required int FollowUpID { get; set; }
public DateTime CommentDate { get; set; } = DateTime.Now;
public required int UserID { get; set; }
public User? User { get; set; }
public string Comment { get; set; } = string.Empty;
}

View File

@ -2,8 +2,5 @@
public class PCRBNotification { public class PCRBNotification {
public required string Message { get; set; } public required string Message { get; set; }
public string? Subject { get; set; }
public required PCRB PCRB { get; set; } public required PCRB PCRB { get; set; }
public Approval? Approval { get; set; }
public bool NotifyQaPreApprover { get; set; } = false;
} }

114
azure-pipelines.yml Normal file
View File

@ -0,0 +1,114 @@
trigger:
branches:
include:
- master
paths:
include:
- "Fab2ApprovalSystem/*"
exclude:
- "**/*.yaml"
- "**/*.yml"
- "SQL/*"
- "references/*"
- "packages/*"
- "Kendo/*"
variables:
buildConfiguration: "Release"
targetFrameworkVersion: "v4.8"
coreVersion: "na"
assemblyTitle: "Fab2ApprovalSystem"
architecture: "x64"
msBuild: "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe"
stages:
- stage: Development
displayName: Development
pool:
name: Mesa-FabApproval
demands: Fab2ApprovalSystem-Dev
variables:
ASPNETCORE_ENVIRONMENT: "Development"
configuration: "Debug"
jobs:
- job: Debug
steps:
- script: |
set gitCommit=$(Build.SourceVersion)
set gitCommitSeven=%gitCommit:~0,7%
echo %gitCommitSeven%
echo ##vso[task.setvariable variable=GitCommitSeven;]%gitCommitSeven%
echo $(GitCommitSeven)
displayName: GitCommitSeven
- script: |
echo BuildId: $(Build.BuildId)
echo Build reason: $(Build.Reason)
echo Repo Id: $(Build.Repository.Id)
echo Repo name: $(Build.Repository.Name)
echo Source version: $(Build.SourceVersion)
echo Core version: $(CoreVersion)
echo Build configuration: $(BuildConfiguration)
echo Configuration: $(Configuration)
echo Target Framework version: $(TargetFrameworkVersion)
echo Assembly title: $(AssemblyTitle)
echo MSBuild: $(msBuild)
displayName: "Echo Check"
- script: |
mklink /J ".vscode\.UserSecrets" "%AppData%\Microsoft\UserSecrets\f2da5035-aba9-4676-9f8d-d6689f84663d"
mklink /J "DMO" "..\Fab2ApprovalSystem\DMO"
mklink /J "Jobs" "..\Fab2ApprovalSystem\Jobs"
mklink /J "JobSchedules" "..\Fab2ApprovalSystem\JobSchedules"
mklink /J "Misc" "..\Fab2ApprovalSystem\Misc"
mklink /J "Models" "..\Fab2ApprovalSystem\Models"
mklink /J "PdfGenerator" "..\Fab2ApprovalSystem\PdfGenerator"
mklink /J "Utilities" "..\Fab2ApprovalSystem\Utilities"
mklink /J "ViewModels" "..\Fab2ApprovalSystem\ViewModels"
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Symbolic Link of Type Junction"
- script: |
dotnet user-secrets init
dotnet user-secrets set BuildNumber $(Build.BuildId)
dotnet user-secrets set GitCommitSeven $(GitCommitSeven)
dotnet user-secrets list
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Safe storage of app secrets"
- script: dotnet build --configuration $(buildConfiguration)
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Build"
- script: dotnet build --configuration $(buildConfiguration)
workingDirectory: Fab2ApprovalTests
displayName: "Tests - Build"
- script: dotnet test --configuration $(buildConfiguration)
workingDirectory: Fab2ApprovalTests
displayName: "Tests - Test"
- script: dotnet clean --configuration $(buildConfiguration)
workingDirectory: Fab2ApprovalTests
displayName: "Tests - Clean"
- script: dotnet clean --configuration $(buildConfiguration)
workingDirectory: Fab2ApprovalMKLink
displayName: "MKLink - Clean"
- script: echo $(Build.SourceVersion)-$(Build.BuildId)>bin_x_x_\$(Configuration)\$(CoreVersion)\win-x64\$(Build.Repository.Name).txt
workingDirectory: Fab2ApprovalMKLink
displayName: "Force Fail"
enabled: "false"
- script: '"$(msBuild)" /target:Restore /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(BuildConfiguration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:RestoreSources=D:/nupkg $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Restore"
- script: '"$(msBuild)" /target:Build /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(BuildConfiguration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Build"
- script: '"$(msBuild)" /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:DebugSymbols=false /p:DeleteExistingFiles=true /p:DeployOnBuild=true /p:EnableUpdateAble=true /p:ExcludeApp_Data=true /p:LastUsedBuildConfiguration=$(BuildConfiguration) /p:LastUsedPlatform="Any CPU" /p:LaunchSiteAfterPublish=true /p:OutputPath="D:\$(TargetFrameworkVersion)\$(Build.Repository.Name)\$(Build.BuildId)\$(Configuration)" /p:PreCompileBeforePublish=true /p:PublishProvider=FileSystem /p:PublishUrl="D:/PublishUrl" /p:SiteUrlToLaunchAfterPublish="" /p:WDPMergeOption=DoNotMerge /p:WebPublishMethod=FileSystem $(AssemblyTitle).csproj'
workingDirectory: Fab2ApprovalSystem
displayName: "Framework - Pack"