Compare commits
	
		
			22 Commits
		
	
	
		
			feature-13
			...
			704df4fa8c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 704df4fa8c | |||
| e452047dfb | |||
| bf3e46a784 | |||
| 909f358356 | |||
| b3fb328b98 | |||
| f110fba4cd | |||
| c4d29dad4e | |||
| 2dbde5d70c | |||
| 2119b31764 | |||
| 55d3a96228 | |||
| aa38d17daf | |||
| d4fcbe0dc6 | |||
| 6a7bc39ff8 | |||
| b3a2ee7285 | |||
| a2326315a6 | |||
| 8684e97db7 | |||
| 1946623c9e | |||
| 40e7a3f8e0 | |||
| f0df620dc9 | |||
| 6a2bc0b4ab | |||
| c4036471f7 | |||
| e19cb5fcda | 
							
								
								
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							@ -420,5 +420,6 @@
 | 
			
		||||
    "windowsphone",
 | 
			
		||||
    "Winsock",
 | 
			
		||||
    "worlflow"
 | 
			
		||||
  ]
 | 
			
		||||
  ],
 | 
			
		||||
  "dotnet.preferCSharpExtension": true
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										17
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							@ -2,7 +2,7 @@
 | 
			
		||||
    "version": "2.0.0",
 | 
			
		||||
    "tasks": [
 | 
			
		||||
        {
 | 
			
		||||
            "label": "MSBuild",
 | 
			
		||||
            "label": "MSBuild-Debug",
 | 
			
		||||
            "command": "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe",
 | 
			
		||||
            "type": "process",
 | 
			
		||||
            "args": [
 | 
			
		||||
@ -16,6 +16,21 @@
 | 
			
		||||
            ],
 | 
			
		||||
            "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",
 | 
			
		||||
            "command": "dotnet",
 | 
			
		||||
 | 
			
		||||
@ -367,6 +367,7 @@ dotnet_diagnostic.IDE0065.severity = none # Question -
 | 
			
		||||
dotnet_diagnostic.IDE0066.severity = none # Question - Use 
 | 
			
		||||
dotnet_diagnostic.IDE0078.severity = none # Question - Use pattern matching (may change code meaning)
 | 
			
		||||
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.IDE0161.severity = warning # Question - Namespace declaration preferences
 | 
			
		||||
dotnet_diagnostic.IDE0270.severity = none # Question - Null check can be simplified
 | 
			
		||||
 | 
			
		||||
@ -18,9 +18,15 @@
 | 
			
		||||
  <PropertyGroup Condition="'$(TargetFramework)' == 'net8.0'">
 | 
			
		||||
    <DefineConstants>NET8</DefineConstants>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
 | 
			
		||||
      <_Parameter1>Fab2ApprovalTests</_Parameter1>
 | 
			
		||||
    </AssemblyAttribute>
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="Dapper.Contrib" Version="2.0.78" />
 | 
			
		||||
    <PackageReference Include="Dapper" Version="2.1.44" />
 | 
			
		||||
    <PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" />
 | 
			
		||||
    <PackageReference Include="EntityFramework" Version="6.5.1" />
 | 
			
		||||
    <PackageReference Include="ExcelDataReader" Version="3.7.0" />
 | 
			
		||||
    <PackageReference Include="jQuery" Version="3.7.1" />
 | 
			
		||||
 | 
			
		||||
@ -1,105 +0,0 @@
 | 
			
		||||
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
 | 
			
		||||
@ -6,6 +6,9 @@ MinimumVisualStudioVersion = 10.0.40219.1
 | 
			
		||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fab2ApprovalSystem", "Fab2ApprovalSystem\Fab2ApprovalSystem.csproj", "{AAE52608-4DD1-4732-92BD-CC8915DEC71E}"
 | 
			
		||||
EndProject
 | 
			
		||||
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
 | 
			
		||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MesaFabApproval.Shared", "MesaFabApproval.Shared\MesaFabApproval.Shared.csproj", "{2C16014D-B04E-46AF-AB4C-D2691D44A339}"
 | 
			
		||||
EndProject
 | 
			
		||||
@ -14,6 +17,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MesaFabApproval.Client", "M
 | 
			
		||||
		{2C16014D-B04E-46AF-AB4C-D2691D44A339} = {2C16014D-B04E-46AF-AB4C-D2691D44A339}
 | 
			
		||||
	EndProjectSection
 | 
			
		||||
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
 | 
			
		||||
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
			
		||||
		Debug|Any CPU = Debug|Any CPU
 | 
			
		||||
@ -36,6 +51,14 @@ Global
 | 
			
		||||
		{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.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
 | 
			
		||||
	GlobalSection(SolutionProperties) = preSolution
 | 
			
		||||
		HideSolutionNode = FALSE
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,9 @@
 | 
			
		||||
    /*vertical height between form-groups*/
 | 
			
		||||
    .my-form .form-group {
 | 
			
		||||
/*vertical height between form-groups*/
 | 
			
		||||
.my-form .form-group {
 | 
			
		||||
    margin-bottom: 4px;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    @media (min-width:768px) {
 | 
			
		||||
@media (min-width:768px) {
 | 
			
		||||
    .my-form .row {
 | 
			
		||||
        margin-left: -1px;
 | 
			
		||||
        margin-right: -1px;
 | 
			
		||||
@ -12,7 +12,8 @@
 | 
			
		||||
    .my-form [class*="col-"] {
 | 
			
		||||
        padding: 0 2px;
 | 
			
		||||
    }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
body {
 | 
			
		||||
    padding-top: 50px;
 | 
			
		||||
    padding-bottom: 20px;
 | 
			
		||||
@ -29,10 +30,10 @@ body {
 | 
			
		||||
/*input,
 | 
			
		||||
select
 | 
			
		||||
{
 | 
			
		||||
    max-width: 280px;
 | 
			
		||||
max-width: 280px;
 | 
			
		||||
}*/
 | 
			
		||||
 | 
			
		||||
.row{
 | 
			
		||||
.row {
 | 
			
		||||
    margin-top: 2px;
 | 
			
		||||
    margin-bottom: 2px
 | 
			
		||||
}
 | 
			
		||||
@ -71,10 +72,10 @@ input[type="checkbox"].input-validation-error {
 | 
			
		||||
    padding-left: 20px;
 | 
			
		||||
    padding-right: 20px;
 | 
			
		||||
    background-color: #87b3de;
 | 
			
		||||
  background-image: -moz-linear-gradient(top,#87b3de, #4d79a5);
 | 
			
		||||
  background-image: -ms-linear-gradient(top,#87b3de, #4d79a5);
 | 
			
		||||
  background-image: -webkit-gradient(linear, 0 0, 0 50%, from( #87b3de), to(#4d79a5));
 | 
			
		||||
  background-image: -webkit-linear-gradient(top,#87b3de, #4d79a5);
 | 
			
		||||
    background-image: -moz-linear-gradient(top, #87b3de, #4d79a5);
 | 
			
		||||
    background-image: -ms-linear-gradient(top, #87b3de, #4d79a5);
 | 
			
		||||
    background-image: -webkit-gradient(linear, 0 0, 0 50%, from(#87b3de), to(#4d79a5));
 | 
			
		||||
    background-image: -webkit-linear-gradient(top, #87b3de, #4d79a5);
 | 
			
		||||
    background-image: -o-linear-gradient(top, #87b3de, #4d79a5);
 | 
			
		||||
    background-image: linear-gradient(top, #87b3de, #4d79a5);
 | 
			
		||||
    background-repeat: repeat-x;
 | 
			
		||||
@ -89,7 +90,7 @@ input[type="checkbox"].input-validation-error {
 | 
			
		||||
 | 
			
		||||
.label-color {
 | 
			
		||||
    background-color: #e5e0e0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.linkbutton {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
@ -101,6 +102,17 @@ input[type="checkbox"].input-validation-error {
 | 
			
		||||
    border: 0;
 | 
			
		||||
    vertical-align: middle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.linkbutton.edit {
 | 
			
		||||
    background: url('/Content/icons/edit.gif');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.modal-dialog {
 | 
			
		||||
    margin-top: 80px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.affix {
 | 
			
		||||
  position: fixed;
 | 
			
		||||
  top: 55px;
 | 
			
		||||
  left: 25px;
 | 
			
		||||
}
 | 
			
		||||
@ -58,6 +58,7 @@ public class AuditController : Controller {
 | 
			
		||||
        try {
 | 
			
		||||
            bool isAdmin = (bool)Session[GlobalVars.IS_ADMIN];
 | 
			
		||||
            int userId = (int)Session[GlobalVars.SESSION_USERID];
 | 
			
		||||
            audit = auditDMO.GetAuditItem(issueID, userId);
 | 
			
		||||
            AuditEdit auditEdit = auditDMO.GetAuditEdit(issueID, audit, isAdmin, userId);
 | 
			
		||||
            if (auditEdit.RedirectToAction)
 | 
			
		||||
                return RedirectToAction("ReadOnlyAudit", new { auditNo = audit.AuditNo });
 | 
			
		||||
 | 
			
		||||
@ -52,7 +52,7 @@ public class ChangeControlController : Controller {
 | 
			
		||||
        string encodedJwt = System.Net.WebUtility.UrlEncode(jwt);
 | 
			
		||||
        string refreshToken = Session["RefreshToken"].ToString();
 | 
			
		||||
        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);
 | 
			
		||||
    }
 | 
			
		||||
@ -62,7 +62,7 @@ public class ChangeControlController : Controller {
 | 
			
		||||
        string encodedJwt = System.Net.WebUtility.UrlEncode(jwt);
 | 
			
		||||
        string refreshToken = Session["RefreshToken"].ToString();
 | 
			
		||||
        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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -953,8 +953,7 @@ public class ECNController : PdfViewController {
 | 
			
		||||
        } catch { }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void NotifyApproversForCancellation(int ecnNumber, byte currentStep, int documentType, string ecnTypeString) {
 | 
			
		||||
        ECN ecn = ecnDMO.GetECN(ecnNumber);
 | 
			
		||||
    public void NotifyApproversForCancellation(int ecnNumber, ECN ecn, byte currentStep, int documentType, string ecnTypeString) {
 | 
			
		||||
        string emailSentList = ECNHelper.NotifyApproversForCancellation(_AppSettings, ecnNumber, currentStep, documentType, ecnTypeString, ecn);
 | 
			
		||||
        try {
 | 
			
		||||
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + currentStep.ToString() + ":" + emailSentList });
 | 
			
		||||
@ -977,10 +976,10 @@ public class ECNController : PdfViewController {
 | 
			
		||||
        } catch { }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void NotifyTECNCancellation(int ecnNumber, string ecnFolderPath) {
 | 
			
		||||
    public void NotifyTECNCancellation(int ecnNumber, string ecnFolderPath, string comments) {
 | 
			
		||||
        ECN ecn = ecnDMO.GetECN(ecnNumber);
 | 
			
		||||
        List<int> notificationUserList = ecnDMO.GetTECNNotificationUsers().ToList();
 | 
			
		||||
        string emailSentList = ECNHelper.NotifyTECNCancellation(_AppSettings, userDMO, ecnNumber, ecnFolderPath, ecn, notificationUserList);
 | 
			
		||||
        string emailSentList = ECNHelper.NotifyTECNCancellation(_AppSettings, userDMO, ecnNumber, ecnFolderPath, comments, ecn, notificationUserList);
 | 
			
		||||
        try {
 | 
			
		||||
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "E-TECN", OperationType = "Email", Comments = "Approvers for Cancellation :" + emailSentList });
 | 
			
		||||
        } catch { }
 | 
			
		||||
@ -1157,22 +1156,24 @@ public class ECNController : PdfViewController {
 | 
			
		||||
        return Content(ecnDMO.PCRBExists(pcrb).ToString());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ActionResult CancelDocument(int ecnNumber, byte currentStep, int documentType, string ecnTypeString) {
 | 
			
		||||
    public ActionResult CancelDocument(int ecnNumber, byte currentStep, int documentType, string ecnTypeString, string comments = "") {
 | 
			
		||||
        ECN ecn = ecnDMO.GetECN(ecnNumber);
 | 
			
		||||
        bool lastApproverAndLastStep = false;
 | 
			
		||||
        if (ecn.SubmitedDate is not null && currentStep >= 1)
 | 
			
		||||
            wfDMO.Approve(_AppSettings, ecnNumber, currentStep, comments, out bool lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType, ecn.WorkFlowNumber);
 | 
			
		||||
        int appoverCount = ecnDMO.SubmitForCancellation(ecnNumber, (byte)GlobalVars.WorkFLowStepNumber.Step1, (int)Session[GlobalVars.SESSION_USERID], documentType, ecnTypeString, (int)GlobalVars.TECNExpirationCancellation.Cancellation);
 | 
			
		||||
        if (appoverCount > 0) {
 | 
			
		||||
            NotifyApproversForCancellation(ecnNumber, currentStep, documentType, ecnTypeString);
 | 
			
		||||
        } else // TODO Automatically close the
 | 
			
		||||
          {
 | 
			
		||||
            lastApproverAndLastStep = ApproveCancellation(ecnNumber, currentStep, "", documentType, ecnTypeString);
 | 
			
		||||
            NotifyApproversForCancellation(ecnNumber, ecn, currentStep, documentType, ecnTypeString);
 | 
			
		||||
        } else { // TODO Automatically close the
 | 
			
		||||
            lastApproverAndLastStep = ApproveCancellation(ecnNumber, currentStep, comments, documentType, ecnTypeString);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!lastApproverAndLastStep) {
 | 
			
		||||
            try {
 | 
			
		||||
                lastApproverAndLastStep = true;
 | 
			
		||||
 | 
			
		||||
                ECNPdf ecn = new ECNPdf();
 | 
			
		||||
                GenerateECNPdf(ecnNumber, out ecn);
 | 
			
		||||
                ECNPdf ecnPDF = new ECNPdf();
 | 
			
		||||
                GenerateECNPdf(ecnNumber, out ecnPDF);
 | 
			
		||||
 | 
			
		||||
                string sourceDirectory = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString() + "\\";
 | 
			
		||||
                string outputFullFilePath = "";
 | 
			
		||||
@ -1184,7 +1185,7 @@ public class ECNController : PdfViewController {
 | 
			
		||||
 | 
			
		||||
                Zipper zip = new Zipper();
 | 
			
		||||
                zip.CreateZip(outputFullFilePath, sourceDirectory);
 | 
			
		||||
                NotifyTECNCancellation(ecnNumber, outputFullFilePath);
 | 
			
		||||
                NotifyTECNCancellation(ecnNumber, outputFullFilePath, comments);
 | 
			
		||||
 | 
			
		||||
            } catch (Exception ex) {
 | 
			
		||||
                EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "TECN", OperationType = "Error", Comments = ex.Message });
 | 
			
		||||
@ -1208,19 +1209,20 @@ public class ECNController : PdfViewController {
 | 
			
		||||
    public bool ApproveCancellation(int ecnNumber, byte currentStep, string comments, int documentType, string ecnTypeString) {
 | 
			
		||||
        bool lastApproverAndLastStep = false;
 | 
			
		||||
        bool lastStep = false;
 | 
			
		||||
        ECN ecn = ecnDMO.GetECN(ecnNumber);
 | 
			
		||||
        bool lastApprover = ecnDMO.ECNApproveCancelled_ExpiredDocument(ecnNumber, currentStep, comments, out lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType);
 | 
			
		||||
        while (lastApprover && !lastStep) {
 | 
			
		||||
            currentStep++;
 | 
			
		||||
            lastApprover = ecnDMO.ECNApproveCancelled_ExpiredDocument(ecnNumber, currentStep, comments, out lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType);
 | 
			
		||||
            NotifyApproversForCancellation(ecnNumber, currentStep, documentType, ecnTypeString);
 | 
			
		||||
            NotifyApproversForCancellation(ecnNumber, ecn, currentStep, documentType, ecnTypeString);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (lastApprover && lastStep) {
 | 
			
		||||
            try {
 | 
			
		||||
                lastApproverAndLastStep = true;
 | 
			
		||||
 | 
			
		||||
                ECNPdf ecn = new ECNPdf();
 | 
			
		||||
                GenerateECNPdf(ecnNumber, out ecn);
 | 
			
		||||
                ECNPdf ecnPDF = new ECNPdf();
 | 
			
		||||
                GenerateECNPdf(ecnNumber, out ecnPDF);
 | 
			
		||||
 | 
			
		||||
                string sourceDirectory = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString() + "\\";
 | 
			
		||||
                string outputFullFilePath = "";
 | 
			
		||||
@ -1232,7 +1234,7 @@ public class ECNController : PdfViewController {
 | 
			
		||||
 | 
			
		||||
                Zipper zip = new Zipper();
 | 
			
		||||
                zip.CreateZip(outputFullFilePath, sourceDirectory);
 | 
			
		||||
                NotifyTECNCancellation(ecnNumber, outputFullFilePath);
 | 
			
		||||
                NotifyTECNCancellation(ecnNumber, outputFullFilePath, comments);
 | 
			
		||||
 | 
			
		||||
            } catch (Exception ex) {
 | 
			
		||||
                EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "TECN", OperationType = "Error", Comments = ex.Message });
 | 
			
		||||
 | 
			
		||||
@ -79,7 +79,7 @@ public class MRBController : Controller {
 | 
			
		||||
        string encodedJwt = System.Net.WebUtility.UrlEncode(jwt);
 | 
			
		||||
        string refreshToken = Session["RefreshToken"].ToString();
 | 
			
		||||
        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);
 | 
			
		||||
    }
 | 
			
		||||
@ -102,7 +102,7 @@ public class MRBController : Controller {
 | 
			
		||||
        string encodedJwt = System.Net.WebUtility.UrlEncode(jwt);
 | 
			
		||||
        string refreshToken = Session["RefreshToken"].ToString();
 | 
			
		||||
        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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -37,7 +37,7 @@ public class AdminDMO {
 | 
			
		||||
            foreach (SubRole sr in r.SubRoles) {
 | 
			
		||||
                if (sr.Inactive) {
 | 
			
		||||
                    // hide inactive roles unless parameter says otherwise
 | 
			
		||||
                    if (showInactiveRoles.Equals("true") == false)
 | 
			
		||||
                    if (!showInactiveRoles.Equals("true"))
 | 
			
		||||
                        continue;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -401,7 +401,6 @@ public class AuditDMO {
 | 
			
		||||
            result.Is8DQA = "true";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        audit = GetAuditItem(issueID, userId);
 | 
			
		||||
        // transform audit users from string to list, delimited by a comma.
 | 
			
		||||
        if (audit.Auditees == null) {
 | 
			
		||||
            result.AuditeeNames = new List<string>();
 | 
			
		||||
@ -414,7 +413,7 @@ public class AuditDMO {
 | 
			
		||||
        if (audit.OriginatorID == userId) {
 | 
			
		||||
            result.IsSubmitter = true;
 | 
			
		||||
        }
 | 
			
		||||
        if (isAdmin != true) {
 | 
			
		||||
        if (!isAdmin) {
 | 
			
		||||
            result.IsAdmin = false;
 | 
			
		||||
        } else {
 | 
			
		||||
            result.IsAdmin = true;
 | 
			
		||||
@ -424,7 +423,7 @@ public class AuditDMO {
 | 
			
		||||
        {
 | 
			
		||||
            result.RedirectToAction = true;
 | 
			
		||||
        }
 | 
			
		||||
        if (result.IsAdmin == false && result.IsSubmitter == false) {
 | 
			
		||||
        if (!result.IsAdmin && !result.IsSubmitter) {
 | 
			
		||||
            result.RedirectToAction = true;
 | 
			
		||||
        } else {
 | 
			
		||||
            result.UserList = GetUserList();
 | 
			
		||||
 | 
			
		||||
@ -324,7 +324,7 @@ public class CorrectiveActionDMO {
 | 
			
		||||
        bool isAssignee = false;
 | 
			
		||||
        int aiIndex = 0;
 | 
			
		||||
        List<D5D6CorrectivetAction> actionItems = GetD5D6CorrectivetActions(caId).ToList();
 | 
			
		||||
        while (isAssignee == false && aiIndex < actionItems.Count) {
 | 
			
		||||
        while (!isAssignee && aiIndex < actionItems.Count) {
 | 
			
		||||
            D5D6CorrectivetAction actionItem = actionItems[aiIndex];
 | 
			
		||||
            if (actionItem.ResponsibilityOwnerID == userId && actionItem.ImplementedDate == null && actionItem.Approved) {
 | 
			
		||||
                isAssignee = true;
 | 
			
		||||
 | 
			
		||||
@ -390,7 +390,7 @@ public class ECN_DMO {
 | 
			
		||||
 | 
			
		||||
    internal List<ECNCategory> GetCategories() {
 | 
			
		||||
        List<ECNCategory> r = db.Query<ECNCategory>("ECNGetCategories", null, commandType: CommandType.StoredProcedure).ToList();
 | 
			
		||||
        return r;
 | 
			
		||||
        return r.OrderBy(l => l.CategoryName).ToList();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal List<ECNArea> GetECNAreas() {
 | 
			
		||||
 | 
			
		||||
@ -266,9 +266,9 @@ public class MRB_DMO {
 | 
			
		||||
        DateTime? issueStartDate = tempMRBInfo.IssueStartDate;
 | 
			
		||||
        DateTime? issueEndDate = tempMRBInfo.IssueEndDate;
 | 
			
		||||
 | 
			
		||||
        if (issueStartDate.HasValue == false)
 | 
			
		||||
        if (!issueStartDate.HasValue)
 | 
			
		||||
            throw new Exception("MRB Issue Start Date cannot be blank");
 | 
			
		||||
        if (issueEndDate.HasValue == false)
 | 
			
		||||
        if (!issueEndDate.HasValue)
 | 
			
		||||
            throw new Exception("MRB Issue End Date cannot be blank");
 | 
			
		||||
 | 
			
		||||
        MRB mrbData = new() { MRBNumber = mrbNumber, ToolCSV = tempMRBInfo.ToolCSV, IssueStartDate = tempMRBInfo.IssueStartDate, IssueEndDate = tempMRBInfo.IssueEndDate };
 | 
			
		||||
 | 
			
		||||
@ -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("WHERE (PERequired = 1 OR Location = 'QDB' OR Location = 'EDB' ) AND LD.IssueID = @IssueID ");
 | 
			
		||||
            recordCount = db.Query<int>(sqlString.ToString(), new { IssueID = issueID }).Single();
 | 
			
		||||
            if ((recordCount > 0) && (allLotsAreScrap == false)) {
 | 
			
		||||
            if ((recordCount > 0) && (!allLotsAreScrap)) {
 | 
			
		||||
                // check if there any IG Medical products
 | 
			
		||||
                if (recordCountForIG_MA > 0) {
 | 
			
		||||
                    sqlString = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
@ -2,10 +2,12 @@
 | 
			
		||||
*****Please DO NOT reply to this email***** 
 | 
			
		||||
<br/><br/>
 | 
			
		||||
{3}# {0} has been Cancelled. Please remove posted TECN from point of use. The cancellation date is {4} 
 | 
			
		||||
Please review the cancelled TECN form in the attachment.
 | 
			
		||||
Please review comments below and ensure process has been returned to normal.
 | 
			
		||||
<br/><br/>
 | 
			
		||||
https://messa016ec.infineon.com/ECN/Edit?issueID={1}
 | 
			
		||||
<br/><br/>
 | 
			
		||||
Comments: {5}
 | 
			
		||||
<br/><br/>
 | 
			
		||||
 | 
			
		||||
If you have any questions or trouble logging on please contact a site administrator.
 | 
			
		||||
<br/><br/>
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										17
									
								
								Fab2ApprovalSystem/EmailTemplates/TECNReturnedToProcess.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Fab2ApprovalSystem/EmailTemplates/TECNReturnedToProcess.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
			
		||||
<font size="2" face="verdana">
 | 
			
		||||
*****Please DO NOT reply to this email***** 
 | 
			
		||||
<br/><br/>
 | 
			
		||||
{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.
 | 
			
		||||
<br/><br/>
 | 
			
		||||
https://messa016ec.infineon.com/ECN/Edit?issueID={1}
 | 
			
		||||
<br/><br/>
 | 
			
		||||
Comments: {5}
 | 
			
		||||
<br/><br/>
 | 
			
		||||
 | 
			
		||||
If you have any questions or trouble logging on please contact a site administrator.
 | 
			
		||||
<br/><br/>
 | 
			
		||||
Thank you! 
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
</font>
 | 
			
		||||
@ -388,8 +388,10 @@
 | 
			
		||||
    <Content Include="Views\CorrectiveAction\_D7PAAttachment.cshtml" />
 | 
			
		||||
    <Content Include="Views\CorrectiveAction\Edit.cshtml" />
 | 
			
		||||
    <Content Include="Views\CorrectiveAction\ReadOnlyCA.cshtml" />
 | 
			
		||||
    <Content Include="Views\ECN\_ECNCancel.cshtml" />
 | 
			
		||||
    <Content Include="Views\ECN\_ECNLayout.cshtml" />
 | 
			
		||||
    <Content Include="Views\ECN\_ECNReassignOriginator.cshtml" />
 | 
			
		||||
    <Content Include="Views\ECN\_ECNReturnToProcess.cshtml" />
 | 
			
		||||
    <Content Include="Views\ECN\Acknowledge.cshtml" />
 | 
			
		||||
    <Content Include="Views\ECN\ECNApprovalPdf.cshtml" />
 | 
			
		||||
    <Content Include="Views\ECN\ECNPdf.cshtml" />
 | 
			
		||||
@ -514,6 +516,7 @@
 | 
			
		||||
    <Content Include="EmailTemplates\TECNExpirationApproval.txt" />
 | 
			
		||||
    <Content Include="EmailTemplates\TECNExpired.txt" />
 | 
			
		||||
    <Content Include="EmailTemplates\TECNExtensionReject.txt" />
 | 
			
		||||
    <Content Include="EmailTemplates\TECNReturnedToProcess.txt" />
 | 
			
		||||
    <Content Include="EmailTemplates\WorkRequestApproval.txt" />
 | 
			
		||||
    <Content Include="EmailTemplates\WorkRequestAssigned.txt" />
 | 
			
		||||
    <Content Include="EmailTemplates\WorkRequestReAssigned.txt" />
 | 
			
		||||
 | 
			
		||||
@ -126,7 +126,7 @@ public class ECNHelper {
 | 
			
		||||
        return emailSentList;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static string NotifyTECNCancellation(AppSettings appSettings, UserAccountDMO userDMO, int ecnNumber, string ecnFolderPath, ECN ecn, List<int> notificationUserList) {
 | 
			
		||||
    public static string NotifyTECNCancellation(AppSettings appSettings, UserAccountDMO userDMO, int ecnNumber, string ecnFolderPath, string comments, ECN ecn, List<int> notificationUserList) {
 | 
			
		||||
        string emailSentList = "";
 | 
			
		||||
        List<string> emailIst = MiscDMO.GetTECNCancelledApprovalNotifyList(ecnNumber).Distinct().ToList();
 | 
			
		||||
        foreach (int userId in notificationUserList) {
 | 
			
		||||
@ -135,23 +135,27 @@ public class ECNHelper {
 | 
			
		||||
                emailIst.Add(email);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        string subject = string.Empty;
 | 
			
		||||
        string userEmail = string.Empty;
 | 
			
		||||
        string emailTemplate = "TECNCancelled.txt";
 | 
			
		||||
        if (ecn.CancellationApprovalDate == null) {
 | 
			
		||||
            subject = "TECN Cancellation Initiated  Notice - " + ecnNumber + " for " + ecn.Title + ", Cancellation Initiated on:" + DateTime.Now;
 | 
			
		||||
        } else {
 | 
			
		||||
            subject = "TECN Cancellation Approved Notice - " + ecnNumber + " for " + ecn.Title + ", Cancelled:" + ecn.CancellationApprovalDate;
 | 
			
		||||
        }
 | 
			
		||||
        string subject;
 | 
			
		||||
        string emailTemplate;
 | 
			
		||||
        string senderName = "ECN";
 | 
			
		||||
        string userEmail = string.Empty;
 | 
			
		||||
        DateTime dateTime = ecn.CancellationApprovalDate is null ? DateTime.Now : ecn.CancellationApprovalDate.Value;
 | 
			
		||||
        if (ecn.ExpirationDate > DateTime.Today || ecn.ExtensionDate > DateTime.Today) {
 | 
			
		||||
            emailTemplate = "TECNCancelled.txt";
 | 
			
		||||
            subject = "TECN Cancellation Approved Notice - " + ecnNumber + " for " + ecn.Title + ", Cancelled:" + dateTime;
 | 
			
		||||
        } else {
 | 
			
		||||
            emailTemplate = "TECNReturnedToProcess.txt";
 | 
			
		||||
            subject = "TECN Return to Process Approved Notice - " + ecnNumber + " for " + ecn.Title + ", Returned:" + dateTime;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        EmailNotification en = new(appSettings, subject);
 | 
			
		||||
        string[] emailparams = new string[5];
 | 
			
		||||
        string[] emailparams = new string[6];
 | 
			
		||||
        emailparams[0] = ecnNumber.ToString();
 | 
			
		||||
        emailparams[1] = ecnNumber.ToString();
 | 
			
		||||
        emailparams[2] = GlobalVars.hostURL;
 | 
			
		||||
        emailparams[3] = "TECN";
 | 
			
		||||
        emailparams[4] = DateTime.Now.ToString();
 | 
			
		||||
        emailparams[5] = comments;
 | 
			
		||||
 | 
			
		||||
#if (DEBUG)
 | 
			
		||||
        userEmail = GlobalVars.SENDER_EMAIL;
 | 
			
		||||
 | 
			
		||||
@ -1,53 +1,54 @@
 | 
			
		||||
#if !NET8
 | 
			
		||||
#if NET8
 | 
			
		||||
 | 
			
		||||
using ExcelDataReader;
 | 
			
		||||
 | 
			
		||||
#else 
 | 
			
		||||
 | 
			
		||||
using Excel;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Data;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Web;
 | 
			
		||||
 | 
			
		||||
namespace Fab2ApprovalSystem.Misc {
 | 
			
		||||
namespace Fab2ApprovalSystem.Misc;
 | 
			
		||||
 | 
			
		||||
public class ExcelData {
 | 
			
		||||
 | 
			
		||||
    private readonly string _Path;
 | 
			
		||||
 | 
			
		||||
    public class ExcelData {
 | 
			
		||||
        string _path;
 | 
			
		||||
    public ExcelData(string path) {
 | 
			
		||||
            _path = path;
 | 
			
		||||
        _Path = path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public IExcelDataReader getExcelReader() {
 | 
			
		||||
            // 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 
 | 
			
		||||
        FileStream stream = File.Open(_Path, FileMode.Open, FileAccess.Read);
 | 
			
		||||
        IExcelDataReader reader = null;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
                if (_path.EndsWith(".xls")) {
 | 
			
		||||
            if (_Path.EndsWith(".xls")) {
 | 
			
		||||
                reader = ExcelReaderFactory.CreateBinaryReader(stream);
 | 
			
		||||
            }
 | 
			
		||||
                if (_path.EndsWith(".xlsx")) {
 | 
			
		||||
            if (_Path.EndsWith(".xlsx")) {
 | 
			
		||||
                reader = ExcelReaderFactory.CreateOpenXmlReader(stream);
 | 
			
		||||
            }
 | 
			
		||||
            return reader;
 | 
			
		||||
        } catch (Exception) {
 | 
			
		||||
            throw;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class ExcelLotInfo {
 | 
			
		||||
            public string LotNo { get; set; }
 | 
			
		||||
            public string LotDispo { get; set; }
 | 
			
		||||
        public string? LotNo { get; set; }
 | 
			
		||||
        public string? LotDispo { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public IEnumerable<ExcelLotInfo> ReadData() {
 | 
			
		||||
            var r = new List<ExcelLotInfo>();
 | 
			
		||||
            var excelData = new ExcelData(_path);
 | 
			
		||||
            var lots = excelData.getData().ToList();
 | 
			
		||||
        List<ExcelLotInfo> r = new();
 | 
			
		||||
        ExcelData excelData = new(_Path);
 | 
			
		||||
        List<DataRow> lots = excelData.getData().ToList();
 | 
			
		||||
 | 
			
		||||
        int lotDispoColumnIndex = -1;
 | 
			
		||||
        foreach (DataColumn col in lots[0].Table.Columns) {
 | 
			
		||||
@ -57,7 +58,7 @@ namespace Fab2ApprovalSystem.Misc {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
            foreach (var row in lots) {
 | 
			
		||||
        foreach (DataRow row in lots) {
 | 
			
		||||
            string temValue = row[0].ToString();
 | 
			
		||||
            if (temValue.Trim().Length > 0 && temValue.Trim().Length <= 10) {
 | 
			
		||||
                r.Add(new ExcelLotInfo() {
 | 
			
		||||
@ -71,11 +72,10 @@ namespace Fab2ApprovalSystem.Misc {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public IEnumerable<string> ReadQDBFlagData() {
 | 
			
		||||
            List<string> s = new List<string>();
 | 
			
		||||
            // We return the interface, so that         
 | 
			
		||||
            var excelData = new ExcelData(_path);
 | 
			
		||||
            var lotNos = excelData.getData();
 | 
			
		||||
            foreach (var row in lotNos) {
 | 
			
		||||
        List<string> s = new();
 | 
			
		||||
        ExcelData excelData = new(_Path);
 | 
			
		||||
        IEnumerable<DataRow> lotNos = excelData.getData();
 | 
			
		||||
        foreach (DataRow row in lotNos) {
 | 
			
		||||
            string temValue = row[0].ToString();
 | 
			
		||||
            if (temValue.Trim().Length > 0 && temValue.Trim().Length == 9) {
 | 
			
		||||
                if (row[2].ToString().ToUpper() != "YES" && row[2].ToString().ToUpper() != "NO") {
 | 
			
		||||
@ -89,16 +89,21 @@ namespace Fab2ApprovalSystem.Misc {
 | 
			
		||||
        return s;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if NET8
 | 
			
		||||
 | 
			
		||||
    public IEnumerable<DataRow> getData(bool firstRowIsColumnNames = true) =>
 | 
			
		||||
        throw new NotImplementedException();
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    public IEnumerable<DataRow> getData(bool firstRowIsColumnNames = true) {
 | 
			
		||||
            var reader = this.getExcelReader();
 | 
			
		||||
        IExcelDataReader reader = getExcelReader();
 | 
			
		||||
        reader.IsFirstRowAsColumnNames = firstRowIsColumnNames;
 | 
			
		||||
        var workSheet = reader.AsDataSet().Tables[0];
 | 
			
		||||
        var rows = from DataRow a in workSheet.Rows select a;
 | 
			
		||||
        return rows;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -117,8 +117,8 @@ public class LotDispositionHelper {
 | 
			
		||||
    public static void AttachSave(AppSettings appSettings, LotDispositionDMO lotDispositionDMO, int issueID, int userId, string fullFileName, Stream stream) {
 | 
			
		||||
        // Some browsers send file names with full path.
 | 
			
		||||
        // We are only interested in the file name.
 | 
			
		||||
        var fileName = Path.GetFileName(fullFileName);
 | 
			
		||||
        var physicalPath = Path.Combine(appSettings.AttachmentFolder + "LotDisposition", fileName);
 | 
			
		||||
        string fileName = Path.GetFileName(fullFileName);
 | 
			
		||||
        string physicalPath = Path.Combine(appSettings.AttachmentFolder + "LotDisposition", fileName);
 | 
			
		||||
 | 
			
		||||
        using (FileStream fileStream = new(physicalPath, FileMode.Create, FileAccess.Write)) {
 | 
			
		||||
            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) {
 | 
			
		||||
        string physicalPath;
 | 
			
		||||
 | 
			
		||||
        var fileExtension = Path.GetExtension(fullFileName);
 | 
			
		||||
        string fileExtension = Path.GetExtension(fullFileName);
 | 
			
		||||
        string fName = userIdentityName + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString();
 | 
			
		||||
 | 
			
		||||
        physicalPath = Path.Combine(lotTempPipeLine, fName + "." + fileExtension);
 | 
			
		||||
@ -142,20 +142,18 @@ public class LotDispositionHelper {
 | 
			
		||||
            stream.CopyTo(fileStream);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#if !NET8
 | 
			
		||||
        ExcelData x = new ExcelData(physicalPath);
 | 
			
		||||
        var lotNumbers = x.ReadData();
 | 
			
		||||
        ExcelData x = new (physicalPath);
 | 
			
		||||
        IEnumerable<ExcelData.ExcelLotInfo> lotNumbers = x.ReadData();
 | 
			
		||||
 | 
			
		||||
        foreach (var lotInfo in lotNumbers) {
 | 
			
		||||
            Lot l = new Lot();
 | 
			
		||||
            l.LotNumber = lotInfo.LotNo;
 | 
			
		||||
        foreach (ExcelData.ExcelLotInfo lotInfo in lotNumbers) {
 | 
			
		||||
            Lot l = new();
 | 
			
		||||
            l.LotNumber = lotInfo.LotNo ?? string.Empty;
 | 
			
		||||
            l.IssueID = issueID;
 | 
			
		||||
            if (l.LotStatusOptionID == 0)
 | 
			
		||||
                l.LotStatusOption.LotStatusOptionID = (int)GlobalVars.LotStatusOption.Release;
 | 
			
		||||
 | 
			
		||||
            lotDispositionDMO.InsertLot(l, true);
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        FileInfo f = new(physicalPath);
 | 
			
		||||
        if (f.Exists)
 | 
			
		||||
 | 
			
		||||
@ -46,14 +46,12 @@ public class MRBHelper {
 | 
			
		||||
            stream.CopyTo(fileStream);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#if !NET8
 | 
			
		||||
        ExcelData x = new ExcelData(physicalPath);
 | 
			
		||||
        ExcelData x = new(physicalPath);
 | 
			
		||||
        lotDataList = x.ReadQDBFlagData();
 | 
			
		||||
 | 
			
		||||
        foreach (string lotData in lotDataList) {
 | 
			
		||||
            mrbDMO.InsertMRB_QDB_HoldFlag(guid, lotData, operation);
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        FileInfo f = new(physicalPath);
 | 
			
		||||
        if (f.Exists)
 | 
			
		||||
@ -170,14 +168,12 @@ public class MRBHelper {
 | 
			
		||||
            stream.CopyTo(fileStream);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#if !NET8
 | 
			
		||||
        ExcelData x = new ExcelData(physicalPath);
 | 
			
		||||
        ExcelData x = new(physicalPath);
 | 
			
		||||
        lotDataList = x.ReadQDBFlagData();
 | 
			
		||||
 | 
			
		||||
        foreach (string lotData in lotDataList) {
 | 
			
		||||
            mrbDMO.InsertMRB_QDB_HoldFlag(guid, lotData, operation);
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        FileInfo f = new(physicalPath);
 | 
			
		||||
        if (f.Exists)
 | 
			
		||||
@ -246,17 +242,16 @@ public class MRBHelper {
 | 
			
		||||
        string fName = userIdentityName + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString();
 | 
			
		||||
        string physicalPath = Path.Combine(lotTempPipeLine, fName + "." + fileExtension);
 | 
			
		||||
 | 
			
		||||
#if !NET8
 | 
			
		||||
        IEnumerable<ExcelData.ExcelLotInfo> lotNumbers;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            using (var fileStream = new FileStream(physicalPath, FileMode.Create, FileAccess.Write)) {
 | 
			
		||||
            using (FileStream fileStream = new(physicalPath, FileMode.Create, FileAccess.Write)) {
 | 
			
		||||
                stream.CopyTo(fileStream);
 | 
			
		||||
            }
 | 
			
		||||
            ExcelData x = new ExcelData(physicalPath);
 | 
			
		||||
            ExcelData x = new(physicalPath);
 | 
			
		||||
            lotNumbers = x.ReadData();
 | 
			
		||||
        } 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
 | 
			
		||||
@ -266,7 +261,7 @@ public class MRBHelper {
 | 
			
		||||
        foreach (var lotInfo in lotNumbers) {
 | 
			
		||||
            if (lotInfo.LotDispo.Length == 1) {
 | 
			
		||||
                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));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@ -276,8 +271,8 @@ public class MRBHelper {
 | 
			
		||||
        if (!mrbInfo.ToolCSV.ToUpper().Equals("NA")) {
 | 
			
		||||
            foreach (var lotInfo in lotNumbers) {
 | 
			
		||||
                bool existingLotUpdated;
 | 
			
		||||
                Lot l = new Lot();
 | 
			
		||||
                l.LotNumber = lotInfo.LotNo;
 | 
			
		||||
                Lot l = new();
 | 
			
		||||
                l.LotNumber = lotInfo.LotNo ?? string.Empty;
 | 
			
		||||
                if (lotInfo.LotDispo.Length == 1) {
 | 
			
		||||
                    l.DispoType = lotInfo.LotDispo[0];
 | 
			
		||||
                }
 | 
			
		||||
@ -298,8 +293,8 @@ public class MRBHelper {
 | 
			
		||||
            // Only find the child Splits when a Tool or a list of Tools is provided
 | 
			
		||||
            foreach (var lotInfo in lotNumbers) {
 | 
			
		||||
                bool existingLotUpdated;
 | 
			
		||||
                Lot l = new Lot();
 | 
			
		||||
                l.LotNumber = lotInfo.LotNo;
 | 
			
		||||
                Lot l = new();
 | 
			
		||||
                l.LotNumber = lotInfo.LotNo ?? string.Empty;
 | 
			
		||||
                if (lotInfo.LotDispo.Length == 1) {
 | 
			
		||||
                    l.DispoType = lotInfo.LotDispo[0];
 | 
			
		||||
                }
 | 
			
		||||
@ -308,7 +303,6 @@ public class MRBHelper {
 | 
			
		||||
                mrbDMO.InsertLot(l, true, out existingLotUpdated);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        FileInfo f = new(physicalPath);
 | 
			
		||||
        if (f.Exists)
 | 
			
		||||
 | 
			
		||||
@ -210,10 +210,10 @@
 | 
			
		||||
                            @Html.TextBoxFor(model => model.Title, new { id = "txtTitle", @class = "k-textbox", style = "width:100%", disabled = "disabled" })
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-sm-6 col-sm-offset-4" style="color: red;">
 | 
			
		||||
                            *(DO NOT USE Rev I, O, Q, S, X, and Z)
 | 
			
		||||
                            * (DO NOT USE Rev I, O, S, X, and Z)
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-sm-6 col-sm-offset-4" style="color: red;">
 | 
			
		||||
                            Revision Y is followed by AA. YY is followed by AAA
 | 
			
		||||
                            Revision Y is followed by AA-AY, AY is followed by BA-BY etc. YY is followed by AAA
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="form-group">
 | 
			
		||||
 | 
			
		||||
@ -154,10 +154,10 @@
 | 
			
		||||
                            @Html.TextBoxFor(model => model.Title, new { id = "txtTitle", @class = "k-textbox", style = "width:100%" })
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-sm-6 col-sm-offset-4" style="color: red;">
 | 
			
		||||
                            *(DO NOT USE Rev I, O, Q, S, X, and Z)
 | 
			
		||||
                            * (DO NOT USE Rev I, O, S, X, and Z)
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-sm-6 col-sm-offset-4" style="color: red;">
 | 
			
		||||
                            Revision Y is followed by AA. YY is followed by AAA
 | 
			
		||||
                            Revision Y is followed by AA-AY, AY is followed by BA-BY etc. YY is followed by AAA
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="form-group">
 | 
			
		||||
 | 
			
		||||
@ -86,30 +86,48 @@
 | 
			
		||||
 | 
			
		||||
                if (Model.IsTECN && !Model.CancellationInProgress && !Model.CancellationApproved && !Model.ExpirationInProgress
 | 
			
		||||
                    && !Model.ExpirationProcessed && !Model.Converted
 | 
			
		||||
                    && !Model.LockedForConversion
 | 
			
		||||
                    && (Model.ExpirationDate > DateTime.Today || Model.ExtensionDate > DateTime.Today))
 | 
			
		||||
                    && !Model.LockedForConversion)
 | 
			
		||||
                {
 | 
			
		||||
                    ViewBag.CanResubmit = "true";
 | 
			
		||||
                    <input type="button" value="Change Type" class="btn btn-primary btn-xs" id="ReSubmitDocument" disabled="disabled" />
 | 
			
		||||
                    if (Model.ExpirationDate > DateTime.Today || Model.ExtensionDate > DateTime.Today)
 | 
			
		||||
                    {
 | 
			
		||||
                        <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" />
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        <input type="button" value="Return to Process" class="btn btn-primary btn-xs" id="ReturnToProcessDocument" />
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                else if (Model.IsTECN && !Model.CancellationInProgress && !Model.CancellationApproved && !Model.ExpirationInProgress
 | 
			
		||||
                    && !Model.ExpirationProcessed
 | 
			
		||||
                    && Model.ConversionApprovalInProgress == false
 | 
			
		||||
                    && (Model.ExpirationDate >= DateTime.Today || Model.ExtensionDate >= DateTime.Today))
 | 
			
		||||
                    && Model.ConversionApprovalInProgress == false)
 | 
			
		||||
                {
 | 
			
		||||
                    if (Model.ExpirationDate > DateTime.Today || Model.ExtensionDate > DateTime.Today)
 | 
			
		||||
                    {
 | 
			
		||||
                        <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" />
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        <input type="button" value="Return to Process" class="btn btn-primary btn-xs" id="ReturnToProcessDocument" />
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                else if (Model.IsEmergencyTECN && !Model.CancellationInProgress && !Model.CancellationApproved && !Model.ExpirationInProgress
 | 
			
		||||
                    && !Model.ExpirationProcessed && !Model.Converted
 | 
			
		||||
                        && (Model.ExpirationDate > DateTime.Today || Model.ExtensionDate > DateTime.Today))
 | 
			
		||||
                    && !Model.ExpirationProcessed && !Model.Converted)
 | 
			
		||||
                {
 | 
			
		||||
                    ViewBag.CanResubmit = "true";
 | 
			
		||||
                    <input type="button" value="Change Type" class="btn btn-primary btn-xs" id="ReSubmitDocument" disabled="disabled" />
 | 
			
		||||
                    if (Model.ExpirationDate > DateTime.Today || Model.ExtensionDate > DateTime.Today)
 | 
			
		||||
                    {
 | 
			
		||||
                        <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" />
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        <input type="button" value="Return to Process" class="btn btn-primary btn-xs" id="ReturnToProcessDocument" />
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            <input type="button" value="PRINT PDF" class="btn btn-primary btn-xs" id="PrintPDF" />
 | 
			
		||||
@ -242,10 +260,10 @@
 | 
			
		||||
                            @Html.TextBoxFor(model => model.Title, new { id = "txtTitle", @class = "k-textbox", style = "width:100%", disabled = "disabled" })
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-sm-6 col-sm-offset-4" style="color: red;">
 | 
			
		||||
                            *(DO NOT USE Rev I, O, Q, S, X, and Z)
 | 
			
		||||
                            * (DO NOT USE Rev I, O, S, X, and Z)
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-sm-6 col-sm-offset-4" style="color: red;">
 | 
			
		||||
                            Revision Y is followed by AA. YY is followed by AAA
 | 
			
		||||
                            Revision Y is followed by AA-AY, AY is followed by BA-BY etc. YY is followed by AAA
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="form-group">
 | 
			
		||||
@ -1251,6 +1269,9 @@
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
@Html.Partial("_ECNCancel")
 | 
			
		||||
@Html.Partial("_ECNReturnToProcess")
 | 
			
		||||
 | 
			
		||||
@Html.Partial("_ECNReassignOriginator")
 | 
			
		||||
 | 
			
		||||
<script type="text/javascript">
 | 
			
		||||
@ -2188,40 +2209,6 @@
 | 
			
		||||
        return false;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $('#CancelDocument').on('click', function () {
 | 
			
		||||
        docType = 5;
 | 
			
		||||
        if (confirm("Are you sure you want to Cancel this document?")) {
 | 
			
		||||
            $.ajax({
 | 
			
		||||
                url: "/ECN/CancelDocument",
 | 
			
		||||
                type: "GET",
 | 
			
		||||
                datatype: "json",
 | 
			
		||||
                data: {
 | 
			
		||||
                    ecnNumber: $("#txtECNNumber").val(),
 | 
			
		||||
                    currentStep: 1,
 | 
			
		||||
                    documentType: docType,
 | 
			
		||||
                    ecnTypeString: ecnTypeString
 | 
			
		||||
                },
 | 
			
		||||
                success: function (data) {
 | 
			
		||||
 | 
			
		||||
                    if (data == 'Redirect') {
 | 
			
		||||
                        var url = '@Url.Action("ReadOnly", "ECN", new { issueID = "__id__" })';
 | 
			
		||||
                        url = url.replace('amp;', '');
 | 
			
		||||
                        window.location.href = url.replace('__id__', $("#txtECNNumber").val());
 | 
			
		||||
 | 
			
		||||
                    }
 | 
			
		||||
                    else {
 | 
			
		||||
                        // TODO alert an error message
 | 
			
		||||
                    }
 | 
			
		||||
                },
 | 
			
		||||
                error: function (result) {
 | 
			
		||||
                    alert("Failed on Cancel" + result);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    var returnNoOfDays = function () {
 | 
			
		||||
        //var start = new Date($('#txSubmitDate').val());
 | 
			
		||||
        var start = new Date();
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										75
									
								
								Fab2ApprovalSystem/Views/ECN/_ECNCancel.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								Fab2ApprovalSystem/Views/ECN/_ECNCancel.cshtml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,75 @@
 | 
			
		||||
<div class="modal fade" id="Cancel" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static">
 | 
			
		||||
    <div class="modal-dialog">
 | 
			
		||||
        <div class="modal-content">
 | 
			
		||||
            <div class="modal-header">
 | 
			
		||||
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
 | 
			
		||||
                <h4 class="modal-title" id="myModalLabel"><center>Has the process returned to the original state?</center></h4>
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="modal-body">
 | 
			
		||||
                <div class="control-group">
 | 
			
		||||
                    <div class="row">
 | 
			
		||||
                        <div class="col-sm-13">
 | 
			
		||||
                            <h4 class="modal-title">Comments (Required):</h4>
 | 
			
		||||
                            <textarea class="form-control" rows="5" id="comments" style="resize: none;"></textarea>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="modal-footer">
 | 
			
		||||
                <button type="button" class="btn btn-default" data-dismiss="modal">No</button>
 | 
			
		||||
                <button type="button" class="btn btn-primary" id="ConfirmCancel">Confirm Cancel (Yes)</button>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
<script language="javascript" type="text/javascript">
 | 
			
		||||
 | 
			
		||||
    $(document).ready(function () {
 | 
			
		||||
 | 
			
		||||
        $("#CancelDocument").click(function (e) {
 | 
			
		||||
 | 
			
		||||
            $("#comments").val("");
 | 
			
		||||
 | 
			
		||||
            $("#Cancel").modal('show');
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $('#ConfirmCancel').on('click', function () {
 | 
			
		||||
 | 
			
		||||
            if ($("#comments").val() == "") {
 | 
			
		||||
                alert("Comments are required");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $('#ConfirmCancel').attr("disabled", true);
 | 
			
		||||
 | 
			
		||||
            $.ajax({
 | 
			
		||||
                url: "/ECN/CancelDocument",
 | 
			
		||||
                type: "GET",
 | 
			
		||||
                datatype: "json",
 | 
			
		||||
                data: {
 | 
			
		||||
                    ecnNumber: $("#txtECNNumber").val(),
 | 
			
		||||
                    currentStep: 1,
 | 
			
		||||
                    documentType: 5,
 | 
			
		||||
                    ecnTypeString: ecnTypeString,
 | 
			
		||||
                    comments: $("#comments").val(),
 | 
			
		||||
                },
 | 
			
		||||
                success: function (data) {
 | 
			
		||||
 | 
			
		||||
                    $("#Cancel").modal('hide');
 | 
			
		||||
 | 
			
		||||
                    var url = '@Url.Action("ReadOnly", "ECN", new { issueID = "__id__" })';
 | 
			
		||||
                    url = url.replace('amp;', '');
 | 
			
		||||
                    window.location.href = url.replace('__id__', $("#txtECNNumber").val());
 | 
			
		||||
 | 
			
		||||
                },
 | 
			
		||||
                error: function (result) {
 | 
			
		||||
                    $('#ConfirmCancel').attr("disabled", false);
 | 
			
		||||
                    alert("Server error while canceling document");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
</script>
 | 
			
		||||
							
								
								
									
										75
									
								
								Fab2ApprovalSystem/Views/ECN/_ECNReturnToProcess.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								Fab2ApprovalSystem/Views/ECN/_ECNReturnToProcess.cshtml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,75 @@
 | 
			
		||||
<div class="modal fade" id="ReturnToProcess" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static">
 | 
			
		||||
    <div class="modal-dialog">
 | 
			
		||||
        <div class="modal-content">
 | 
			
		||||
            <div class="modal-header">
 | 
			
		||||
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
 | 
			
		||||
                <h4 class="modal-title" id="myModalLabel"><center>Has the process returned to the original state?</center></h4>
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="modal-body">
 | 
			
		||||
                <div class="control-group">
 | 
			
		||||
                    <div class="row">
 | 
			
		||||
                        <div class="col-sm-13">
 | 
			
		||||
                            <h4 class="modal-title">Comments (Required):</h4>
 | 
			
		||||
                            <textarea class="form-control" rows="5" id="ReturnToProcessComments" style="resize: none;"></textarea>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="modal-footer">
 | 
			
		||||
                <button type="button" class="btn btn-default" data-dismiss="modal">No</button>
 | 
			
		||||
                <button type="button" class="btn btn-primary" id="ConfirmReturnToProcess">Confirm Return to Process (Yes)</button>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
<script language="javascript" type="text/javascript">
 | 
			
		||||
 | 
			
		||||
    $(document).ready(function () {
 | 
			
		||||
 | 
			
		||||
        $("#ReturnToProcessDocument").click(function (e) {
 | 
			
		||||
 | 
			
		||||
            $("#ReturnToProcessComments").val("");
 | 
			
		||||
 | 
			
		||||
            $("#ReturnToProcess").modal('show');
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        $('#ConfirmReturnToProcess').on('click', function () {
 | 
			
		||||
 | 
			
		||||
            if ($("#ReturnToProcessComments").val() == "") {
 | 
			
		||||
                alert("Comments are required");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $('#ConfirmReturnToProcess').attr("disabled", true);
 | 
			
		||||
 | 
			
		||||
            $.ajax({
 | 
			
		||||
                url: "/ECN/CancelDocument",
 | 
			
		||||
                type: "GET",
 | 
			
		||||
                datatype: "json",
 | 
			
		||||
                data: {
 | 
			
		||||
                    ecnNumber: $("#txtECNNumber").val(),
 | 
			
		||||
                    currentStep: 1,
 | 
			
		||||
                    documentType: 5,
 | 
			
		||||
                    ecnTypeString: ecnTypeString,
 | 
			
		||||
                    comments: $("#ReturnToProcessComments").val(),
 | 
			
		||||
                },
 | 
			
		||||
                success: function (data) {
 | 
			
		||||
 | 
			
		||||
                    $("#ReturnToProcess").modal('hide');
 | 
			
		||||
 | 
			
		||||
                    var url = '@Url.Action("ReadOnly", "ECN", new { issueID = "__id__" })';
 | 
			
		||||
                    url = url.replace('amp;', '');
 | 
			
		||||
                    window.location.href = url.replace('__id__', $("#txtECNNumber").val());
 | 
			
		||||
 | 
			
		||||
                },
 | 
			
		||||
                error: function (result) {
 | 
			
		||||
                    $('#ConfirmReturnToProcess').attr("disabled", false);
 | 
			
		||||
                    alert("Server error while ReturnToProcessing document");
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
</script>
 | 
			
		||||
@ -90,16 +90,16 @@
 | 
			
		||||
                            string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken);
 | 
			
		||||
                            string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ??
 | 
			
		||||
                                "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>
 | 
			
		||||
                            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>
 | 
			
		||||
                        } else {
 | 
			
		||||
                            string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ??
 | 
			
		||||
                                                        "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>
 | 
			
		||||
                            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=@Url.Action("CreateWorkRequest", "LotTraveler")>Create Special Work Request</a></li>*@
 | 
			
		||||
@ -150,9 +150,9 @@
 | 
			
		||||
            string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken);
 | 
			
		||||
            string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ??
 | 
			
		||||
                "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);
 | 
			
		||||
            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("Special Work Requests").Action("SpecialWorkRequestList", "Home");
 | 
			
		||||
            //menu.Add().Text("PCRB").Action("ChangeControlList", "Home");
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										232
									
								
								Fab2ApprovalSystem/pipelines-manual.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								Fab2ApprovalSystem/pipelines-manual.yml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,232 @@
 | 
			
		||||
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
 | 
			
		||||
							
								
								
									
										239
									
								
								Fab2ApprovalSystem/pipelines.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								Fab2ApprovalSystem/pipelines.yml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,239 @@
 | 
			
		||||
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
 | 
			
		||||
@ -51,7 +51,7 @@ public class AuditDMOTests {
 | 
			
		||||
        try { throw new Exception(); } catch (Exception) { }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void AuditDMO(ILogger? logger, AppSettings appSettings) {
 | 
			
		||||
    private static void AuditDMO(ILogger? logger, AppSettings appSettings, int auditNo, bool isAdmin) {
 | 
			
		||||
#pragma warning disable IDE0059
 | 
			
		||||
        SetGlobalVars(logger, appSettings);
 | 
			
		||||
        AuditDMO auditDMO = new(appSettings);
 | 
			
		||||
@ -61,25 +61,25 @@ public class AuditDMOTests {
 | 
			
		||||
        AuditedArea[] auditedAreas = auditDMO.GetAuditAreaList().ToArray();
 | 
			
		||||
        // IEnumerable<int> GetAuditFindingCategoryIdsByFindingId(int auditFindingsID);
 | 
			
		||||
        // AuditFindings GetAuditFindingsByID(int auditFindingsID);
 | 
			
		||||
        // IEnumerable<AuditFindings> GetAuditFindingsList(int auditNo);
 | 
			
		||||
        // Audit GetAuditItem(int auditNo, appSettings.UserId);
 | 
			
		||||
        // Audit GetAuditItemReadOnly(int auditNo, appSettings.UserId);
 | 
			
		||||
        AuditFindings[] auditFindings = auditDMO.GetAuditFindingsList(auditNo).ToArray();
 | 
			
		||||
        Audit auditB = auditDMO.GetAuditItem(auditNo, appSettings.UserId);
 | 
			
		||||
        Audit auditC = new();
 | 
			
		||||
        AuditEdit auditEdit = auditDMO.GetAuditEdit(auditNo, auditC, isAdmin, appSettings.UserId);
 | 
			
		||||
        Audit auditD = auditDMO.GetAuditItemReadOnly(auditNo, appSettings.UserId);
 | 
			
		||||
        Auditor[] auditors = auditDMO.GetAuditorList().ToArray();
 | 
			
		||||
        // IEnumerable<AuditReportAttachment> GetAuditReportAttachments(int auditNo);
 | 
			
		||||
        AuditReportAttachment[] auditReportAttachments = auditDMO.GetAuditReportAttachments(auditNo).ToArray();
 | 
			
		||||
        // C_8DAuditedStandard[] c_8DAuditedStandards = auditDMO.GetAuditStandardList().ToArray();
 | 
			
		||||
        AuditType[] auditTypes = auditDMO.GetAuditTypeList().ToArray();
 | 
			
		||||
        // CAFindings GetCAFindingsItem(int caFindingsID);
 | 
			
		||||
        // IEnumerable<AuditReportAttachment> GetCAFindingsItemAttachments(int caFindingsID);
 | 
			
		||||
        // IEnumerable<CAFindings> GetCAFindingsList(int auditNo);
 | 
			
		||||
        CAFindings[] caFindings = auditDMO.GetCAFindingsList(auditNo).ToArray();
 | 
			
		||||
        CANoList[] cANoLists = auditDMO.GetCorrectiveActionNoList().ToArray();
 | 
			
		||||
        // int GetOpenCACountByAuditNo(int auditNo);
 | 
			
		||||
        int openCACountByAuditNo = auditDMO.GetOpenCACountByAuditNo(auditNo);
 | 
			
		||||
        CAUserList[] cAUserLists = auditDMO.GetUserList().ToArray();
 | 
			
		||||
        // Audit InsertAudit(Audit audit);
 | 
			
		||||
        // void InsertAuditReportAttachment(AuditReportAttachment attach);
 | 
			
		||||
        // void InsertCAFindings(CAFindings model);
 | 
			
		||||
        // int IsCAAssignedToAudit(int CANo, int auditNo);
 | 
			
		||||
        // void ReleaseLockOnDocument(appSettings.UserId, int issueID);
 | 
			
		||||
        // void UpdateAudit(Audit audit, appSettings.UserId);
 | 
			
		||||
        // void UpdateCAFindings(CAFindings model);
 | 
			
		||||
        if (auditDMO is null) { }
 | 
			
		||||
#pragma warning restore IDE0059
 | 
			
		||||
@ -89,13 +89,14 @@ public class AuditDMOTests {
 | 
			
		||||
    [Ignore]
 | 
			
		||||
#endif
 | 
			
		||||
    [TestMethod]
 | 
			
		||||
    public void AuditDMOIsAttachedOnly() {
 | 
			
		||||
    [DataRow(250, true)]
 | 
			
		||||
    public void AuditDMOIsAttachedOnly(int auditNo, bool isAdmin) {
 | 
			
		||||
        _Logger?.LogInformation("Starting Web Application");
 | 
			
		||||
        IServiceProvider? serviceProvider = _WebApplicationFactory?.Services.CreateScope().ServiceProvider;
 | 
			
		||||
        AppSettings? appSettings = serviceProvider?.GetRequiredService<AppSettings>();
 | 
			
		||||
        Assert.IsTrue(appSettings is not null);
 | 
			
		||||
        if (System.Diagnostics.Debugger.IsAttached)
 | 
			
		||||
            AuditDMO(_Logger, appSettings);
 | 
			
		||||
            AuditDMO(_Logger, appSettings, auditNo, isAdmin);
 | 
			
		||||
        _Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
 | 
			
		||||
        NonThrowTryCatch();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -85,6 +85,18 @@ public class EngineeringChangeNoticeDMOTests {
 | 
			
		||||
        // int SubmitTECNExtensionDocument(int issueID, appSettings.UserId, int documentType, DateTime extensionDate);
 | 
			
		||||
        // void TECNExtensionLog(int ecnNumber, DateTime extensionDate);
 | 
			
		||||
        // 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) { }
 | 
			
		||||
#pragma warning restore IDE0059
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										32
									
								
								MesaFabApproval.API.Test/MesaFabApproval.API.Test.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								MesaFabApproval.API.Test/MesaFabApproval.API.Test.csproj
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,32 @@
 | 
			
		||||
<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>
 | 
			
		||||
							
								
								
									
										63
									
								
								MesaFabApproval.API.Test/MonInUtilsTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								MesaFabApproval.API.Test/MonInUtilsTests.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,63 @@
 | 
			
		||||
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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										414
									
								
								MesaFabApproval.API.Test/PCRBServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										414
									
								
								MesaFabApproval.API.Test/PCRBServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,414 @@
 | 
			
		||||
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 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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 CreateFollowUp_WithValidParam_ShouldCreateFollowUp() {
 | 
			
		||||
        var followUp = new PCRBFollowUp {
 | 
			
		||||
            PlanNumber = 1,
 | 
			
		||||
            Step = 1,
 | 
			
		||||
            FollowUpDate = DateTime.Now
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp))
 | 
			
		||||
            .ReturnsAsync(1);
 | 
			
		||||
 | 
			
		||||
        await _pcrbService.CreateFollowUp(followUp);
 | 
			
		||||
 | 
			
		||||
        _dalServiceMock.Verify(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp), Times.Once);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task CreateFollowUp_WithNullParam_ShouldThrowException() {
 | 
			
		||||
        await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.CreateFollowUp(null));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task CreateFollowUp_WithDatabaseFailure_ShouldThrowException() {
 | 
			
		||||
        var followUp = new PCRBFollowUp {
 | 
			
		||||
            PlanNumber = 1,
 | 
			
		||||
            Step = 1,
 | 
			
		||||
            FollowUpDate = DateTime.Now
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp))
 | 
			
		||||
            .ReturnsAsync(0);
 | 
			
		||||
 | 
			
		||||
        await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUp(followUp));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task CreateFollowUp_WithDatabaseException_ShouldThrowException() {
 | 
			
		||||
        var followUp = new PCRBFollowUp {
 | 
			
		||||
            PlanNumber = 1,
 | 
			
		||||
            Step = 1,
 | 
			
		||||
            FollowUpDate = DateTime.Now
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp))
 | 
			
		||||
            .Throws<Exception>();
 | 
			
		||||
 | 
			
		||||
        await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUp(followUp));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [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() {
 | 
			
		||||
        var followUp = new PCRBFollowUp {
 | 
			
		||||
            ID = 1,
 | 
			
		||||
            PlanNumber = 1,
 | 
			
		||||
            Step = 1,
 | 
			
		||||
            FollowUpDate = DateTime.Now
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp))
 | 
			
		||||
            .ReturnsAsync(1);
 | 
			
		||||
 | 
			
		||||
        await _pcrbService.UpdateFollowUp(followUp);
 | 
			
		||||
 | 
			
		||||
        _dalServiceMock.Verify(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp), Times.Once);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task UpdateFollowUp_WithNullParam_ShouldThrowException() {
 | 
			
		||||
        await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.UpdateFollowUp(null));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task UpdateFollowUp_WithDatabaseFailure_ShouldThrowException() {
 | 
			
		||||
        var followUp = new PCRBFollowUp {
 | 
			
		||||
            ID = 1,
 | 
			
		||||
            PlanNumber = 1,
 | 
			
		||||
            Step = 1,
 | 
			
		||||
            FollowUpDate = DateTime.Now
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp))
 | 
			
		||||
            .ReturnsAsync(0);
 | 
			
		||||
 | 
			
		||||
        await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUp(followUp));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task UpdateFollowUp_WithDatabaseException_ShouldThrowException() {
 | 
			
		||||
        var followUp = new PCRBFollowUp {
 | 
			
		||||
            ID = 1,
 | 
			
		||||
            PlanNumber = 1,
 | 
			
		||||
            Step = 1,
 | 
			
		||||
            FollowUpDate = DateTime.Now
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp))
 | 
			
		||||
            .Throws<Exception>();
 | 
			
		||||
 | 
			
		||||
        await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUp(followUp));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [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));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -15,6 +15,8 @@ public class SmtpClientWrapper : ISmtpClientWrapper {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void Send(MailMessage message) {
 | 
			
		||||
        message.Subject = message.Subject.Replace('\r', ' ').Replace('\n', ' ');
 | 
			
		||||
 | 
			
		||||
        _client.Send(message);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -53,4 +53,36 @@ 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);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
using MesaFabApproval.API.Services;
 | 
			
		||||
using MesaFabApproval.API.Utilities;
 | 
			
		||||
using MesaFabApproval.Shared.Models;
 | 
			
		||||
using MesaFabApproval.Shared.Services;
 | 
			
		||||
 | 
			
		||||
@ -13,12 +14,12 @@ namespace MesaFabApproval.API.Controllers;
 | 
			
		||||
public class PCRBController : ControllerBase {
 | 
			
		||||
    private readonly ILogger<MRBController> _logger;
 | 
			
		||||
    private readonly IPCRBService _pcrbService;
 | 
			
		||||
    private readonly IMonInWorkerClient _monInClient;
 | 
			
		||||
    private readonly IMonInUtils _monInUtils;
 | 
			
		||||
 | 
			
		||||
    public PCRBController(ILogger<MRBController> logger, IPCRBService pcrbService, IMonInWorkerClient monInClient) {
 | 
			
		||||
    public PCRBController(ILogger<MRBController> logger, IPCRBService pcrbService, IMonInUtils monInUtils) {
 | 
			
		||||
        _logger = logger ?? throw new ArgumentNullException("ILogger not injected");
 | 
			
		||||
        _pcrbService = pcrbService ?? throw new ArgumentNullException("IPCRBService not injected");
 | 
			
		||||
        _monInClient = monInClient ?? throw new ArgumentNullException("IMonInWorkerClient not injected");
 | 
			
		||||
        _monInUtils = monInUtils ?? throw new ArgumentNullException("IMonInUtils not injected");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [HttpPost]
 | 
			
		||||
@ -49,17 +50,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "CreateNewPCRB";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
            
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -84,14 +76,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "GetAllPCRBs";
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, false, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -123,17 +109,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "GetPCRBbyTitle";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -165,17 +142,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "GetPCRBbyPlanNumber";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -207,17 +175,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "UpdatePCRB";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -249,22 +208,14 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "DeletePCRB";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [HttpPost]
 | 
			
		||||
    [Route("pcrb/attachment")]
 | 
			
		||||
    [ApiExplorerSettings(IgnoreApi = true)]
 | 
			
		||||
    public async Task<IActionResult> UploadAttachment([FromForm] IFormFile file, [FromForm] PCRBAttachment attachment) {
 | 
			
		||||
        DateTime start = DateTime.Now;
 | 
			
		||||
        bool isArgumentError = false;
 | 
			
		||||
@ -293,17 +244,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "UploadPCRBAttachment";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -335,17 +277,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "GetPCRBAttachments";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -390,17 +323,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "GetPCRBAttachmentFile";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
            
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -432,17 +356,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "UpdatePCRBAttachment";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -474,17 +389,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "DeletePCRBAttachment";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -516,17 +422,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "CreatePCRBActionItem";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -558,17 +455,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "UpdatePCRBActionItem";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -600,17 +488,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "DeletePCRBActionItem";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -642,17 +521,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "GetPCRBActionItems";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -684,17 +554,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "CreatePCR3Document";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -726,17 +587,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "UpdatePCR3Document";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -768,17 +620,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "GetPCR3Documents";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -810,17 +653,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "CreatePCRBAttendee";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
            
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -852,17 +686,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "UpdatePCRBAttendee";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -894,17 +719,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "DeletePCRBAttendee";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -936,17 +752,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "GetPCRBAttendees";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -978,17 +785,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "NotifyNewPCRBApprovers";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1022,17 +820,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "NotifyPCRBApprovers";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1066,17 +855,8 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "NotifyPCRBOriginator";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            }
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1110,17 +890,140 @@ public class PCRBController : ControllerBase {
 | 
			
		||||
            string metricName = "NotifyPCRBResponsiblePerson";
 | 
			
		||||
            DateTime end = DateTime.Now;
 | 
			
		||||
            double millisecondsDiff = (end - start).TotalMilliseconds;
 | 
			
		||||
            _monInClient.PostAverage(metricName + "Latency", millisecondsDiff);
 | 
			
		||||
 | 
			
		||||
            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);
 | 
			
		||||
            _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [HttpPost]
 | 
			
		||||
    [Route("pcrb/followUp")]
 | 
			
		||||
    public async Task<IActionResult> CreateFollowUp(PCRBFollowUp followUp) {
 | 
			
		||||
        DateTime start = DateTime.Now;
 | 
			
		||||
        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 attendees 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);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -6,6 +6,7 @@ using dotenv.net;
 | 
			
		||||
 | 
			
		||||
using MesaFabApproval.API.Clients;
 | 
			
		||||
using MesaFabApproval.API.Services;
 | 
			
		||||
using MesaFabApproval.API.Utilities;
 | 
			
		||||
using MesaFabApproval.Models;
 | 
			
		||||
using MesaFabApproval.Shared.Services;
 | 
			
		||||
 | 
			
		||||
@ -94,6 +95,7 @@ builder.Services.AddScoped<IECNService, ECNService>();
 | 
			
		||||
builder.Services.AddScoped<ISmtpService, SmtpService>();
 | 
			
		||||
builder.Services.AddScoped<IUserService, UserService>();
 | 
			
		||||
builder.Services.AddScoped<IMonInWorkerClient, MonInWorkerClient>();
 | 
			
		||||
builder.Services.AddScoped<IMonInUtils, MonInUtils>();
 | 
			
		||||
builder.Services.AddScoped<IAuthenticationService, AuthenticationService>();
 | 
			
		||||
builder.Services.AddScoped<IMRBService, MRBService>();
 | 
			
		||||
builder.Services.AddScoped<IPCRBService, PCRBService>();
 | 
			
		||||
@ -101,7 +103,6 @@ builder.Services.AddScoped<IApprovalService, ApprovalService>();
 | 
			
		||||
 | 
			
		||||
builder.Services.AddControllers();
 | 
			
		||||
 | 
			
		||||
#if DEBUG
 | 
			
		||||
builder.Services.AddEndpointsApiExplorer();
 | 
			
		||||
builder.Services.AddSwaggerGen(c => {
 | 
			
		||||
    c.SwaggerDoc("v1", new OpenApiInfo {
 | 
			
		||||
@ -128,13 +129,9 @@ builder.Services.AddSwaggerGen(c => {
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
WebApplication app = builder.Build();
 | 
			
		||||
 | 
			
		||||
if (Debugger.IsAttached)
 | 
			
		||||
    app.Services.GetRequiredService<IApprovalService>();
 | 
			
		||||
 | 
			
		||||
app.UseCors();
 | 
			
		||||
 | 
			
		||||
// Configure the HTTP request pipeline.
 | 
			
		||||
 | 
			
		||||
@ -219,7 +219,10 @@ public class ApprovalService : IApprovalService {
 | 
			
		||||
                queryBuilder.Append($"select a.*, src.SubRoleCategoryItem from Approval a ");
 | 
			
		||||
                queryBuilder.Append("join SubRole sr on a.SubRoleID=sr.SubRoleID ");
 | 
			
		||||
                queryBuilder.Append("join SubRoleCategory src on sr.SubRoleCategoryID=src.SubRoleCategoryID ");
 | 
			
		||||
                queryBuilder.Append($"where UserID={userId} and ");
 | 
			
		||||
                queryBuilder.Append($"where UserID={userId} and ItemStatus=0 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 is null));");
 | 
			
		||||
                string sql = queryBuilder.ToString();
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
using System.Data;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
using Dapper;
 | 
			
		||||
 | 
			
		||||
@ -6,7 +7,9 @@ namespace MesaFabApproval.API.Services;
 | 
			
		||||
 | 
			
		||||
public interface IDalService {
 | 
			
		||||
    Task<IEnumerable<T>> QueryAsync<T>(string sql);
 | 
			
		||||
    Task<IEnumerable<T>> QueryAsync<T>(string sql, object paramaters);
 | 
			
		||||
    Task<int> ExecuteAsync(string sql);
 | 
			
		||||
    Task<int> ExecuteAsync<T>(string sql, T paramaters);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class DalService : IDalService {
 | 
			
		||||
@ -55,6 +58,45 @@ public class DalService : IDalService {
 | 
			
		||||
        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) {
 | 
			
		||||
        if (sql is null) throw new ArgumentNullException("sql cannot be null");
 | 
			
		||||
 | 
			
		||||
@ -86,4 +128,36 @@ public class DalService : IDalService {
 | 
			
		||||
 | 
			
		||||
        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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -4,6 +4,7 @@ namespace MesaFabApproval.API.Services;
 | 
			
		||||
 | 
			
		||||
public interface IECNService {
 | 
			
		||||
    Task<bool> IsValidECNNumber(int number);
 | 
			
		||||
    Task<IEnumerable<int>> GetAllECNNumbers();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class ECNService : IECNService {
 | 
			
		||||
@ -43,4 +44,19 @@ public class ECNService : IECNService {
 | 
			
		||||
            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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -852,8 +852,8 @@ public class MRBService : IMRBService {
 | 
			
		||||
                            convertToPart += partStr;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    dt.Rows.Add(action.Action, convertFromCustomer, convertFromPart, action.Quantity.ToString(),
 | 
			
		||||
                                convertToCustomer, convertToPart,
 | 
			
		||||
                    dt.Rows.Add(action.Action, convertFromCustomer, convertFromPart, action.LotNumber, 
 | 
			
		||||
                                action.Quantity.ToString(), convertToCustomer, convertToPart,
 | 
			
		||||
                                DateTimeUtilities.GetDateAsStringMinDefault(action.AssignedDate),
 | 
			
		||||
                                DateTimeUtilities.GetDateAsStringMaxDefault(action.CompletedDate),
 | 
			
		||||
                                action.CompletedByUser is null ? "" : action.CompletedByUser.GetFullName());
 | 
			
		||||
 | 
			
		||||
@ -37,6 +37,10 @@ public interface IPCRBService {
 | 
			
		||||
    Task NotifyApprovers(PCRBNotification notification);
 | 
			
		||||
    Task NotifyOriginator(PCRBNotification 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class PCRBService : IPCRBService {
 | 
			
		||||
@ -74,16 +78,15 @@ public class PCRBService : IPCRBService {
 | 
			
		||||
 | 
			
		||||
            if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null");
 | 
			
		||||
 | 
			
		||||
            pcrb.LastUpdateDate = DateTime.Now;
 | 
			
		||||
 | 
			
		||||
            StringBuilder queryBuilder = new();
 | 
			
		||||
            queryBuilder.Append("insert into CCChangeControl (OwnerID, Title, ChangeLevel, ReasonForChange, ");
 | 
			
		||||
            queryBuilder.Append("ChangeDescription, IsITAR, CurrentStep, InsertTimeStamp, LastUpdateDate) ");
 | 
			
		||||
            queryBuilder.Append($"values ({pcrb.OwnerID}, '{pcrb.Title}', '{pcrb.ChangeLevel}', ");
 | 
			
		||||
            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")}')");
 | 
			
		||||
            queryBuilder.Append("ChangeDescription, IsITAR, CurrentStep, InsertTimeStamp, LastUpdateDate, Type) ");
 | 
			
		||||
            queryBuilder.Append("values (@OwnerID, @Title, @ChangeLevel, @ReasonForChange, @ChangeDescription, ");
 | 
			
		||||
            queryBuilder.Append("@IsITAR, @CurrentStep, @InsertTimeStamp, @LastUpdateDate, @Type)");
 | 
			
		||||
 | 
			
		||||
            int rowsCreated = await _dalService.ExecuteAsync(queryBuilder.ToString());
 | 
			
		||||
            int rowsCreated = await _dalService.ExecuteAsync(queryBuilder.ToString(), pcrb);
 | 
			
		||||
 | 
			
		||||
            if (rowsCreated <= 0) throw new Exception("unable to insert new PCRB in the database");
 | 
			
		||||
        } catch (Exception ex) {
 | 
			
		||||
@ -194,18 +197,16 @@ public class PCRBService : IPCRBService {
 | 
			
		||||
 | 
			
		||||
            if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null");
 | 
			
		||||
 | 
			
		||||
            StringBuilder queryBuilder = new();
 | 
			
		||||
            queryBuilder.Append($"update CCChangeControl set OwnerID={pcrb.OwnerID}, ");
 | 
			
		||||
            queryBuilder.Append($"Title='{pcrb.Title.Replace("'", "''")}', ChangeLevel='{pcrb.ChangeLevel}', ");
 | 
			
		||||
            queryBuilder.Append($"CurrentStep={pcrb.CurrentStep}, ReasonForChange='{pcrb.ReasonForChange.Replace("'", "''")}', ");
 | 
			
		||||
            queryBuilder.Append($"ChangeDescription='{pcrb.ChangeDescription.Replace("'", "''")}', ");
 | 
			
		||||
            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}");
 | 
			
		||||
            pcrb.LastUpdateDate = DateTime.Now;
 | 
			
		||||
 | 
			
		||||
            int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString());
 | 
			
		||||
            StringBuilder queryBuilder = new();
 | 
			
		||||
            queryBuilder.Append("update CCChangeControl set OwnerID=@OwnerID, Title=@Title, ChangeLevel=@ChangeLevel, ");
 | 
			
		||||
            queryBuilder.Append("Type=@Type, CurrentStep=@CurrentStep, ReasonForChange=@ReasonForChange, ");
 | 
			
		||||
            queryBuilder.Append("ChangeDescription=@ChangeDescription, IsITAR=@IsITAR, ClosedDate=@ClosedDate, ");
 | 
			
		||||
            queryBuilder.Append("LastUpdateDate=@LastUpdateDate ");
 | 
			
		||||
            queryBuilder.Append($"where PlanNumber=@PlanNumber");
 | 
			
		||||
 | 
			
		||||
            int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString(), pcrb);
 | 
			
		||||
 | 
			
		||||
            if (rowsAffected <= 0) throw new Exception("unable to perform update in database");
 | 
			
		||||
 | 
			
		||||
@ -485,6 +486,20 @@ public class PCRBService : IPCRBService {
 | 
			
		||||
            int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString());
 | 
			
		||||
 | 
			
		||||
            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) {
 | 
			
		||||
            _logger.LogError($"Unable to update attendee, because {ex.Message}");
 | 
			
		||||
            throw;
 | 
			
		||||
@ -741,6 +756,90 @@ 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) ");
 | 
			
		||||
            queryBuilder.Append("values (@PlanNumber, @Step, @FollowUpDate, @CompletedDate)");
 | 
			
		||||
 | 
			
		||||
            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.AddMinutes(15));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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, Comments=@Comments ");
 | 
			
		||||
            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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private async Task SaveAttachmentInDb(IFormFile file, PCRBAttachment attachment) {
 | 
			
		||||
        try {
 | 
			
		||||
            _logger.LogInformation($"Attempting to save attachment to database");
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										48
									
								
								MesaFabApproval.API/Utilities/MonInUtils.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								MesaFabApproval.API/Utilities/MonInUtils.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,48 @@
 | 
			
		||||
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}");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										100
									
								
								MesaFabApproval.API/pipeline.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								MesaFabApproval.API/pipeline.yml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,100 @@
 | 
			
		||||
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"
 | 
			
		||||
@ -0,0 +1,31 @@
 | 
			
		||||
<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>
 | 
			
		||||
							
								
								
									
										347
									
								
								MesaFabApproval.Client.Test/PCRBServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										347
									
								
								MesaFabApproval.Client.Test/PCRBServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,347 @@
 | 
			
		||||
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 PCRBServiceTests {
 | 
			
		||||
    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 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 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;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public PCRBServiceTests() {
 | 
			
		||||
        _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() {
 | 
			
		||||
        PCRBFollowUp followUp = new PCRBFollowUp {
 | 
			
		||||
            ID = 1,
 | 
			
		||||
            PlanNumber = 123,
 | 
			
		||||
            Step = 1,
 | 
			
		||||
            FollowUpDate = DateTime.Now,
 | 
			
		||||
            Comments = "Test"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        HttpResponseMessage getResponse = new HttpResponseMessage {
 | 
			
		||||
            StatusCode = HttpStatusCode.OK,
 | 
			
		||||
            Content = new StringContent(JsonSerializer.Serialize(new List<PCRBFollowUp> { followUp }))
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        var 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(getResponse)
 | 
			
		||||
            .Verifiable();
 | 
			
		||||
 | 
			
		||||
        var httpClient = new HttpClient(mockHttpMessageHandler.Object) {
 | 
			
		||||
            BaseAddress = new Uri("https://localhost:5000")
 | 
			
		||||
        };
 | 
			
		||||
        _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
 | 
			
		||||
 | 
			
		||||
        await _pcrbService.CreateFollowUp(followUp);
 | 
			
		||||
 | 
			
		||||
        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() {
 | 
			
		||||
        PCRBFollowUp followUp = new PCRBFollowUp {
 | 
			
		||||
            ID = 1,
 | 
			
		||||
            PlanNumber = 123,
 | 
			
		||||
            Step = 1,
 | 
			
		||||
            FollowUpDate = DateTime.Now,
 | 
			
		||||
            Comments = "Test"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
 | 
			
		||||
        mockHttpMessageHandler.Protected()
 | 
			
		||||
            .Setup<Task<HttpResponseMessage>>(
 | 
			
		||||
                "SendAsync",
 | 
			
		||||
                ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Post),
 | 
			
		||||
                ItExpr.IsAny<CancellationToken>())
 | 
			
		||||
            .ReturnsAsync(UNSUCCESSFUL_RESPONSE)
 | 
			
		||||
            .Verifiable();
 | 
			
		||||
 | 
			
		||||
        var 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(followUp));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task CreateFollowUp_WithNullParam_ShouldThrowException() {
 | 
			
		||||
        await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.CreateFollowUp(null));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task GetFollowUpsByPlanNumber_WithBypassCache_ShouldCallHttpGetAndReturnFollowUps() {
 | 
			
		||||
        PCRBFollowUp followUp = new PCRBFollowUp {
 | 
			
		||||
            ID = 1,
 | 
			
		||||
            PlanNumber = 123,
 | 
			
		||||
            Step = 1,
 | 
			
		||||
            FollowUpDate = DateTime.Now,
 | 
			
		||||
            Comments = "Test"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        HttpResponseMessage getResponse = new HttpResponseMessage {
 | 
			
		||||
            StatusCode = HttpStatusCode.OK,
 | 
			
		||||
            Content = new StringContent(JsonSerializer.Serialize(new List<PCRBFollowUp> { followUp }))
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
 | 
			
		||||
 | 
			
		||||
        mockHttpMessageHandler.Protected()
 | 
			
		||||
            .Setup<Task<HttpResponseMessage>>(
 | 
			
		||||
                "SendAsync",
 | 
			
		||||
                ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get),
 | 
			
		||||
                ItExpr.IsAny<CancellationToken>())
 | 
			
		||||
            .ReturnsAsync(getResponse)
 | 
			
		||||
            .Verifiable();
 | 
			
		||||
 | 
			
		||||
        var 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() {
 | 
			
		||||
        var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
 | 
			
		||||
 | 
			
		||||
        mockHttpMessageHandler.Protected()
 | 
			
		||||
            .Setup<Task<HttpResponseMessage>>(
 | 
			
		||||
                "SendAsync",
 | 
			
		||||
                ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get),
 | 
			
		||||
                ItExpr.IsAny<CancellationToken>())
 | 
			
		||||
            .ReturnsAsync(UNSUCCESSFUL_RESPONSE)
 | 
			
		||||
            .Verifiable();
 | 
			
		||||
 | 
			
		||||
        var 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() {
 | 
			
		||||
        PCRBFollowUp followUp = new PCRBFollowUp {
 | 
			
		||||
            ID = 1,
 | 
			
		||||
            PlanNumber = 123,
 | 
			
		||||
            Step = 1,
 | 
			
		||||
            FollowUpDate = DateTime.Now,
 | 
			
		||||
            Comments = "Test"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
 | 
			
		||||
 | 
			
		||||
        mockHttpMessageHandler.Protected()
 | 
			
		||||
            .Setup<Task<HttpResponseMessage>>(
 | 
			
		||||
                "SendAsync",
 | 
			
		||||
                ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Put),
 | 
			
		||||
                ItExpr.IsAny<CancellationToken>())
 | 
			
		||||
            .ReturnsAsync(SUCCESSFUL_RESPONSE)
 | 
			
		||||
            .Verifiable();
 | 
			
		||||
 | 
			
		||||
        var httpClient = new HttpClient(mockHttpMessageHandler.Object) {
 | 
			
		||||
            BaseAddress = new Uri("https://localhost:5000")
 | 
			
		||||
        };
 | 
			
		||||
        _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient);
 | 
			
		||||
 | 
			
		||||
        await _pcrbService.UpdateFollowUp(followUp);
 | 
			
		||||
 | 
			
		||||
        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>());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task UpdateFollowUp_WithNullParam_ShouldThrowException() {
 | 
			
		||||
        await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.UpdateFollowUp(null));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task UpdateFollowUp_WithBadResponse_ShouldThrowException() {
 | 
			
		||||
        PCRBFollowUp followUp = new PCRBFollowUp {
 | 
			
		||||
            ID = 1,
 | 
			
		||||
            PlanNumber = 123,
 | 
			
		||||
            Step = 1,
 | 
			
		||||
            FollowUpDate = DateTime.Now,
 | 
			
		||||
            Comments = "Test"
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
 | 
			
		||||
 | 
			
		||||
        mockHttpMessageHandler.Protected()
 | 
			
		||||
            .Setup<Task<HttpResponseMessage>>(
 | 
			
		||||
                "SendAsync",
 | 
			
		||||
                ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Put),
 | 
			
		||||
                ItExpr.IsAny<CancellationToken>())
 | 
			
		||||
            .ReturnsAsync(UNSUCCESSFUL_RESPONSE)
 | 
			
		||||
            .Verifiable();
 | 
			
		||||
 | 
			
		||||
        var 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(followUp));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [Fact]
 | 
			
		||||
    public async Task DeleteFollowUp_WithValidParams_ShouldCallHttpDelete() {
 | 
			
		||||
        var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
 | 
			
		||||
 | 
			
		||||
        mockHttpMessageHandler.Protected()
 | 
			
		||||
            .Setup<Task<HttpResponseMessage>>(
 | 
			
		||||
                "SendAsync",
 | 
			
		||||
                ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Delete),
 | 
			
		||||
                ItExpr.IsAny<CancellationToken>())
 | 
			
		||||
            .ReturnsAsync(SUCCESSFUL_RESPONSE)
 | 
			
		||||
            .Verifiable();
 | 
			
		||||
 | 
			
		||||
        var 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() {
 | 
			
		||||
        var mockHttpMessageHandler = new Mock<HttpMessageHandler>();
 | 
			
		||||
 | 
			
		||||
        mockHttpMessageHandler.Protected()
 | 
			
		||||
            .Setup<Task<HttpResponseMessage>>(
 | 
			
		||||
                "SendAsync",
 | 
			
		||||
                ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Delete),
 | 
			
		||||
                ItExpr.IsAny<CancellationToken>())
 | 
			
		||||
            .ReturnsAsync(UNSUCCESSFUL_RESPONSE)
 | 
			
		||||
            .Verifiable();
 | 
			
		||||
 | 
			
		||||
        var 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));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -1,65 +1,2 @@
 | 
			
		||||
@page "/redirect"
 | 
			
		||||
@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");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										77
									
								
								MesaFabApproval.Client/Pages/AuthenticatedRedirect.razor.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								MesaFabApproval.Client/Pages/AuthenticatedRedirect.razor.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,77 @@
 | 
			
		||||
using MesaFabApproval.Client.Services;
 | 
			
		||||
 | 
			
		||||
using Microsoft.AspNetCore.Components;
 | 
			
		||||
using Microsoft.AspNetCore.WebUtilities;
 | 
			
		||||
 | 
			
		||||
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] ISnackbar snackbar { get; set; }
 | 
			
		||||
    [Inject] NavigationManager navigationManager { 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);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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) {
 | 
			
		||||
            await authStateProvider.Logout();
 | 
			
		||||
 | 
			
		||||
            if (!string.IsNullOrWhiteSpace(_redirectPath)) {
 | 
			
		||||
                navigationManager.NavigateTo($"login/{_redirectPath}");
 | 
			
		||||
            } else {
 | 
			
		||||
                navigationManager.NavigateTo("login");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -215,9 +215,7 @@
 | 
			
		||||
        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("Unblock") || mrbAction.Action.Equals("Waiver");
 | 
			
		||||
        actionIsValid = actionIsValid && !string.IsNullOrWhiteSpace(mrbAction.Customer) &&
 | 
			
		||||
            !string.IsNullOrWhiteSpace(mrbAction.PartNumber) &&
 | 
			
		||||
            !string.IsNullOrWhiteSpace(mrbAction.LotNumber);
 | 
			
		||||
        actionIsValid = actionIsValid && !string.IsNullOrWhiteSpace(mrbAction.LotNumber);
 | 
			
		||||
        actionIsValid = actionIsValid && mrbAction.Quantity > 0;
 | 
			
		||||
 | 
			
		||||
        if (mrbAction.Action.Equals("Convert", StringComparison.InvariantCultureIgnoreCase)) {
 | 
			
		||||
@ -225,6 +223,9 @@
 | 
			
		||||
                !string.IsNullOrWhiteSpace(convertFromPart) &&
 | 
			
		||||
                !string.IsNullOrWhiteSpace(convertToCustomer) &&
 | 
			
		||||
                !string.IsNullOrWhiteSpace(convertToPart);
 | 
			
		||||
        } else {
 | 
			
		||||
            actionIsValid = actionIsValid && !string.IsNullOrWhiteSpace(mrbAction.Customer) &&
 | 
			
		||||
            !string.IsNullOrWhiteSpace(mrbAction.PartNumber);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mrbAction.Action.Equals("Scrap", StringComparison.InvariantCultureIgnoreCase))
 | 
			
		||||
 | 
			
		||||
@ -31,16 +31,16 @@
 | 
			
		||||
                                  Immediate
 | 
			
		||||
                                  AutoGrow />
 | 
			
		||||
                } else {
 | 
			
		||||
                    <MudTextField @bind-Value="@document.ECNNumber"
 | 
			
		||||
                    <MudAutocomplete @bind-Value="@document.ECNNumber"
 | 
			
		||||
                                     T="int"
 | 
			
		||||
                                     SearchFunc="Search"
 | 
			
		||||
                                     Required
 | 
			
		||||
                                  RequiredError="You must provide a valid ECN#"
 | 
			
		||||
                                     Clearable
 | 
			
		||||
                                     RequiredError="You must provide a valid ECN#"
 | 
			
		||||
                                     Variant="Variant.Outlined"
 | 
			
		||||
                                  InputType="@InputType.Number"
 | 
			
		||||
                                     Validation="@(new Func<int, Task<string>>(ECNNoIsValid))"
 | 
			
		||||
                                     Label="ECN#"
 | 
			
		||||
                                  Immediate
 | 
			
		||||
                                  AutoGrow />
 | 
			
		||||
                                     Immediate />
 | 
			
		||||
                }
 | 
			
		||||
                <MudCheckBox Label="Complete"
 | 
			
		||||
                             Color="Color.Tertiary"
 | 
			
		||||
@ -79,6 +79,8 @@
 | 
			
		||||
    [Parameter]
 | 
			
		||||
    public required PCR3Document document { get; set; }
 | 
			
		||||
 | 
			
		||||
    private IEnumerable<int> allEcnNumbers = new List<int>();
 | 
			
		||||
 | 
			
		||||
    private string[] errors = { };
 | 
			
		||||
 | 
			
		||||
    private bool complete = false;
 | 
			
		||||
@ -89,6 +91,8 @@
 | 
			
		||||
 | 
			
		||||
    protected override async Task OnParametersSetAsync() {
 | 
			
		||||
        complete = document.CompletedByID > 0;
 | 
			
		||||
 | 
			
		||||
        allEcnNumbers = await ecnService.GetAllECNNumbers();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private async Task Save() {
 | 
			
		||||
@ -143,6 +147,8 @@
 | 
			
		||||
            document.DocNumbers.ToLower().Equals("n/a") ||
 | 
			
		||||
            document.DocNumbers.ToLower().Equals("n a") ||
 | 
			
		||||
            document.DocNumbers.ToLower().Equals("not applicable")) {
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(document.Comment))
 | 
			
		||||
                document.Comment = "Not required";
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
@ -155,4 +161,13 @@
 | 
			
		||||
        StateHasChanged();
 | 
			
		||||
        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();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,16 +1,5 @@
 | 
			
		||||
@page "/"
 | 
			
		||||
@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>
 | 
			
		||||
 | 
			
		||||
@ -226,138 +215,3 @@
 | 
			
		||||
        </MudTabPanel>
 | 
			
		||||
    </MudTabs>
 | 
			
		||||
</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];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										157
									
								
								MesaFabApproval.Client/Pages/Dashboard.razor.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								MesaFabApproval.Client/Pages/Dashboard.razor.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,157 @@
 | 
			
		||||
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];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1025
									
								
								MesaFabApproval.Client/Pages/MRBSingle.razor.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1025
									
								
								MesaFabApproval.Client/Pages/MRBSingle.razor.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1139
									
								
								MesaFabApproval.Client/Pages/PCRBSingle.razor.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1139
									
								
								MesaFabApproval.Client/Pages/PCRBSingle.razor.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -5,6 +5,7 @@ namespace MesaFabApproval.Client.Services;
 | 
			
		||||
public interface IECNService {
 | 
			
		||||
    Task<string> ECNNumberIsValidStr(int ecnNumber);
 | 
			
		||||
    Task<bool> ECNNumberIsValid(int number);
 | 
			
		||||
    Task<IEnumerable<int>> GetAllECNNumbers();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class ECNService : IECNService {
 | 
			
		||||
@ -49,4 +50,32 @@ public class ECNService : IECNService {
 | 
			
		||||
            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}");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4,7 +4,6 @@ using System.Text.Json;
 | 
			
		||||
 | 
			
		||||
using MesaFabApproval.Shared.Models;
 | 
			
		||||
 | 
			
		||||
using Microsoft.AspNetCore.Components.Forms;
 | 
			
		||||
using Microsoft.AspNetCore.StaticFiles;
 | 
			
		||||
using Microsoft.Extensions.Caching.Memory;
 | 
			
		||||
 | 
			
		||||
@ -40,6 +39,10 @@ public interface IPCRBService {
 | 
			
		||||
    Task NotifyApprovers(PCRBNotification notification);
 | 
			
		||||
    Task NotifyOriginator(PCRBNotification 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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public class PCRBService : IPCRBService {
 | 
			
		||||
@ -764,4 +767,86 @@ public class PCRBService : IPCRBService {
 | 
			
		||||
        if (!responseMessage.IsSuccessStatusCode)
 | 
			
		||||
            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.AddMinutes(5));
 | 
			
		||||
            } 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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										100
									
								
								MesaFabApproval.Client/pipeline.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								MesaFabApproval.Client/pipeline.yml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,100 @@
 | 
			
		||||
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"
 | 
			
		||||
@ -23,4 +23,5 @@ public class PCRB {
 | 
			
		||||
    public DateTime InsertTimeStamp { get; set; } = DateTimeUtilities.MIN_DT;
 | 
			
		||||
    public DateTime LastUpdateDate { get; set; } = DateTimeUtilities.MIN_DT;
 | 
			
		||||
    public DateTime ClosedDate { get; set; } = DateTimeUtilities.MAX_DT;
 | 
			
		||||
    public string Type { get; set; } = "";
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										14
									
								
								MesaFabApproval.Shared/Models/PCRBFollowUp.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								MesaFabApproval.Shared/Models/PCRBFollowUp.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
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 DateTime CompletedDate { get; set; } = DateTimeUtilities.MAX_DT;
 | 
			
		||||
    public string Comments { get; set; } = string.Empty;
 | 
			
		||||
}
 | 
			
		||||
@ -1,114 +0,0 @@
 | 
			
		||||
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"
 | 
			
		||||
		Reference in New Issue
	
	Block a user