Compare commits
	
		
			29 Commits
		
	
	
		
			origin/Pro
			...
			8bae94de96
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 8bae94de96 | |||
| 032c971472 | |||
| 704df4fa8c | |||
| e452047dfb | |||
| bf3e46a784 | |||
| 909f358356 | |||
| b3fb328b98 | |||
| f110fba4cd | |||
| c4d29dad4e | |||
| 2dbde5d70c | |||
| 2119b31764 | |||
| 55d3a96228 | |||
| aa38d17daf | |||
| d4fcbe0dc6 | |||
| 6a7bc39ff8 | |||
| b3a2ee7285 | |||
| a2326315a6 | |||
| 8684e97db7 | |||
| 1946623c9e | |||
| 40e7a3f8e0 | |||
| f0df620dc9 | |||
| 6a2bc0b4ab | |||
| c4036471f7 | |||
| e19cb5fcda | |||
| e68a1a4c3b | |||
| 7ddda56987 | |||
| 77f45fabb1 | |||
| 1b22ffa439 | |||
| 123bbdb9fe | 
							
								
								
									
										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
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								Fab2ApprovalMKLink/.vscode/mklink.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								Fab2ApprovalMKLink/.vscode/mklink.md
									
									
									
									
										vendored
									
									
								
							@ -35,3 +35,15 @@ mklink /J "L:\DevOps\Mesa_FI\MesaFabApproval\Fab2ApprovalMKLink\PdfGenerator" "L
 | 
			
		||||
mklink /J "L:\DevOps\Mesa_FI\MesaFabApproval\Fab2ApprovalMKLink\Jobs" "L:\DevOps\Mesa_FI\MesaFabApproval\Fab2ApprovalSystem\Jobs"
 | 
			
		||||
mklink /J "L:\DevOps\Mesa_FI\MesaFabApproval\Fab2ApprovalMKLink\JobSchedules" "L:\DevOps\Mesa_FI\MesaFabApproval\Fab2ApprovalSystem\JobSchedules"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
```bash 1734015544321 = 638696123443210000 = Thu Dec 12 2024 07:59:03 GMT-0700 (Mountain Standard Time)
 | 
			
		||||
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"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
@ -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,18 +1,19 @@
 | 
			
		||||
    /*vertical height between form-groups*/
 | 
			
		||||
    .my-form .form-group {
 | 
			
		||||
        margin-bottom: 4px;
 | 
			
		||||
/*vertical height between form-groups*/
 | 
			
		||||
.my-form .form-group {
 | 
			
		||||
    margin-bottom: 4px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@media (min-width:768px) {
 | 
			
		||||
    .my-form .row {
 | 
			
		||||
        margin-left: -1px;
 | 
			
		||||
        margin-right: -1px;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @media (min-width:768px) {
 | 
			
		||||
        .my-form .row {
 | 
			
		||||
            margin-left: -1px;
 | 
			
		||||
            margin-right: -1px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .my-form [class*="col-"] {
 | 
			
		||||
            padding: 0 2px;
 | 
			
		||||
        }
 | 
			
		||||
    .my-form [class*="col-"] {
 | 
			
		||||
        padding: 0 2px;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
body {
 | 
			
		||||
    padding-top: 50px;
 | 
			
		||||
    padding-bottom: 20px;
 | 
			
		||||
@ -29,12 +30,12 @@ body {
 | 
			
		||||
/*input,
 | 
			
		||||
select
 | 
			
		||||
{
 | 
			
		||||
    max-width: 280px;
 | 
			
		||||
max-width: 280px;
 | 
			
		||||
}*/
 | 
			
		||||
 | 
			
		||||
.row{
 | 
			
		||||
  margin-top: 2px;
 | 
			
		||||
  margin-bottom: 2px
 | 
			
		||||
.row {
 | 
			
		||||
    margin-top: 2px;
 | 
			
		||||
    margin-bottom: 2px
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
textarea {
 | 
			
		||||
@ -68,28 +69,28 @@ input[type="checkbox"].input-validation-error {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.navbar-inner {
 | 
			
		||||
  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: -o-linear-gradient(top, #87b3de, #4d79a5);
 | 
			
		||||
  background-image: linear-gradient(top, #87b3de, #4d79a5);
 | 
			
		||||
  background-repeat: repeat-x;
 | 
			
		||||
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#87b3de', endColorstr='#4d79a5', GradientType=0);
 | 
			
		||||
  -webkit-border-radius: 4px;
 | 
			
		||||
  -moz-border-radius: 4px;
 | 
			
		||||
  border-radius: 4px;
 | 
			
		||||
  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
 | 
			
		||||
  -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
 | 
			
		||||
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
 | 
			
		||||
    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: -o-linear-gradient(top, #87b3de, #4d79a5);
 | 
			
		||||
    background-image: linear-gradient(top, #87b3de, #4d79a5);
 | 
			
		||||
    background-repeat: repeat-x;
 | 
			
		||||
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#87b3de', endColorstr='#4d79a5', GradientType=0);
 | 
			
		||||
    -webkit-border-radius: 4px;
 | 
			
		||||
    -moz-border-radius: 4px;
 | 
			
		||||
    border-radius: 4px;
 | 
			
		||||
    -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
 | 
			
		||||
    -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
 | 
			
		||||
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.label-color {
 | 
			
		||||
        background-color: #e5e0e0;
 | 
			
		||||
    }
 | 
			
		||||
    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;
 | 
			
		||||
}
 | 
			
		||||
@ -24,12 +24,9 @@ namespace Fab2ApprovalSystem.Controllers;
 | 
			
		||||
 | 
			
		||||
[Authorize]
 | 
			
		||||
public class AccountController : Controller {
 | 
			
		||||
    private string _apiBaseUrl;
 | 
			
		||||
 | 
			
		||||
    public AccountController()
 | 
			
		||||
        : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()))) {
 | 
			
		||||
        _apiBaseUrl = Environment.GetEnvironmentVariable("FabApprovalApiBaseUrl") ??
 | 
			
		||||
            throw new ArgumentNullException("FabApprovalApiBaseUrl environment variable not found");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public AccountController(UserManager<ApplicationUser> userManager) {
 | 
			
		||||
@ -69,7 +66,7 @@ public class AccountController : Controller {
 | 
			
		||||
            bool isLoginValid;
 | 
			
		||||
 | 
			
		||||
            HttpClient httpClient = HttpClientFactory.Create();
 | 
			
		||||
            httpClient.BaseAddress = new Uri(_apiBaseUrl);
 | 
			
		||||
            httpClient.BaseAddress = new Uri(GlobalVars.AppSettings.ApiBaseUrl);
 | 
			
		||||
 | 
			
		||||
            LoginResult loginResult = await AccountDMO.LoginAsync(httpClient, model);
 | 
			
		||||
 | 
			
		||||
@ -121,7 +118,7 @@ public class AccountController : Controller {
 | 
			
		||||
            bool isLoginValid;
 | 
			
		||||
 | 
			
		||||
            HttpClient httpClient = HttpClientFactory.Create();
 | 
			
		||||
            httpClient.BaseAddress = new Uri(_apiBaseUrl);
 | 
			
		||||
            httpClient.BaseAddress = new Uri(GlobalVars.AppSettings.ApiBaseUrl);
 | 
			
		||||
 | 
			
		||||
            LoginResult loginResult = await AccountDMO.ExternalAuthSetupAsync(httpClient, authAttempt);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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 });
 | 
			
		||||
 | 
			
		||||
@ -48,60 +48,23 @@ public class ChangeControlController : Controller {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ActionResult Edit(int issueID) {
 | 
			
		||||
        int isITARCompliant = 1;
 | 
			
		||||
        ChangeControlViewModel cc = new ChangeControlViewModel();
 | 
			
		||||
        cc = ccDMO.GetChangeControlRead(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
 | 
			
		||||
        string jwt = Session["JWT"].ToString();
 | 
			
		||||
        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}";
 | 
			
		||||
 | 
			
		||||
        List<ApproversListViewModel> userList = MiscDMO.GetApproversListByDocument(cc.PlanNumber, cc.CurrentStep, (int)GlobalVars.DocumentType.ChangeControl);
 | 
			
		||||
        ApproversListViewModel appUser = userList.Find(delegate (ApproversListViewModel al) { return al.UserID == (int)Session[GlobalVars.SESSION_USERID]; });
 | 
			
		||||
        if (appUser != null) {
 | 
			
		||||
            ViewBag.IsApprover = "true";
 | 
			
		||||
        }
 | 
			
		||||
        // TODO locked functionality
 | 
			
		||||
 | 
			
		||||
        if (isITARCompliant == 0) // not ITAR Compliant
 | 
			
		||||
        {
 | 
			
		||||
            return View("UnAuthorizedAccess");
 | 
			
		||||
        } else {
 | 
			
		||||
            if ((int)Session[GlobalVars.SESSION_USERID] == cc.OwnerID)
 | 
			
		||||
                ViewBag.IsOriginator = "true";
 | 
			
		||||
            else
 | 
			
		||||
                ViewBag.IsOriginator = "false";
 | 
			
		||||
 | 
			
		||||
            if ((cc.RecordLockIndicator && cc.RecordLockedBy != (int)Session[GlobalVars.SESSION_USERID]) ||
 | 
			
		||||
                cc.ClosedDate != null) {
 | 
			
		||||
                return RedirectToAction("ReadOnlyCC", new { issueID = issueID });
 | 
			
		||||
            } else {
 | 
			
		||||
                cc = ccDMO.GetChangeControl(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
 | 
			
		||||
                ViewBag.Attendees = ccDMO.GetUsers();
 | 
			
		||||
                ViewBag.Generations = ccDMO.GetGenerations();
 | 
			
		||||
                ViewBag.PartNumbers = ccDMO.GetPartNumbers();
 | 
			
		||||
                ViewBag.Processes = ccDMO.GetProcesses();
 | 
			
		||||
                ViewBag.Logistics = ccDMO.GetLogistics();
 | 
			
		||||
                ViewBag.AIResponsibles = ccDMO.GetActionItemResponsible();
 | 
			
		||||
                ViewBag.Sites = ccDMO.GetSites();
 | 
			
		||||
                return View(cc);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return Redirect(mrbUrl);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public ActionResult ReadOnlyCC(int issueID) {
 | 
			
		||||
        int isITARCompliant = 1;
 | 
			
		||||
        ChangeControlViewModel cc = new ChangeControlViewModel();
 | 
			
		||||
        cc = ccDMO.GetChangeControlRead(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
 | 
			
		||||
        // TODO locked functionality
 | 
			
		||||
        string jwt = Session["JWT"].ToString();
 | 
			
		||||
        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}";
 | 
			
		||||
 | 
			
		||||
        if (isITARCompliant == 0) // not ITAR Compliant
 | 
			
		||||
        {
 | 
			
		||||
            return View("UnAuthorizedAccess");
 | 
			
		||||
        } else {
 | 
			
		||||
            ViewBag.MeetingList = ccDMO.GetMeetingList(issueID);
 | 
			
		||||
            ViewBag.Generations = ccDMO.GetGenerations();
 | 
			
		||||
            ViewBag.PartNumbers = ccDMO.GetPartNumbers();
 | 
			
		||||
            ViewBag.Processes = ccDMO.GetProcesses();
 | 
			
		||||
            ViewBag.Logistics = ccDMO.GetLogistics();
 | 
			
		||||
            return View(cc);
 | 
			
		||||
        }
 | 
			
		||||
        return Redirect(mrbUrl);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [HttpPost]
 | 
			
		||||
 | 
			
		||||
@ -601,7 +601,7 @@ public class ECNController : PdfViewController {
 | 
			
		||||
        try {
 | 
			
		||||
            string emailSentList = "";
 | 
			
		||||
            ECN ecn = ecnDMO.GetECN(ecnNumber);
 | 
			
		||||
                emailSentList = ECNHelper.NotifySubmitter(_AppSettings, ecnNumber, ecnTypeString, ecn);
 | 
			
		||||
            emailSentList = ECNHelper.NotifySubmitter(_AppSettings, ecnNumber, ecnTypeString, ecn);
 | 
			
		||||
            try {
 | 
			
		||||
                EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + ":" + emailSentList });
 | 
			
		||||
            } catch { }
 | 
			
		||||
@ -625,7 +625,7 @@ public class ECNController : PdfViewController {
 | 
			
		||||
            ECN ecn = ecnDMO.GetECN(ecnNumber);
 | 
			
		||||
            IEnumerable<int> ecnAdminIDs = MiscDMO.GetUserIDsBySubRoleID(383);
 | 
			
		||||
            foreach (int id in ecnAdminIDs) {
 | 
			
		||||
                        emailSentList = ECNHelper.NotifyAdmin(_AppSettings, ecnNumber, ecnTypeString, ecn, id);
 | 
			
		||||
                emailSentList = ECNHelper.NotifyAdmin(_AppSettings, ecnNumber, ecnTypeString, ecn, id);
 | 
			
		||||
                try {
 | 
			
		||||
                    EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + ":" + emailSentList });
 | 
			
		||||
                } catch { }
 | 
			
		||||
@ -650,7 +650,7 @@ public class ECNController : PdfViewController {
 | 
			
		||||
            string emailSentList = "";
 | 
			
		||||
            ECN ecn = ecnDMO.GetECN(ecnNumber);
 | 
			
		||||
            List<string> emailIst = MiscDMO.GetApproverEmailListByDocument(@ecnNumber, currentStep, documentType).Distinct().ToList();
 | 
			
		||||
                emailSentList = ECNHelper.NotifyApprovers(_AppSettings, ecnNumber, ecnTypeString, emailSentList, ecn, emailIst);
 | 
			
		||||
            emailSentList = ECNHelper.NotifyApprovers(_AppSettings, ecnNumber, ecnTypeString, emailSentList, ecn, emailIst);
 | 
			
		||||
            try {
 | 
			
		||||
                EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + currentStep.ToString() + ":" + emailSentList });
 | 
			
		||||
            } catch { }
 | 
			
		||||
@ -883,6 +883,8 @@ public class ECNController : PdfViewController {
 | 
			
		||||
 | 
			
		||||
            string outputFileName = "";
 | 
			
		||||
            ecn = ecnDMO.GetECNPdf(ecnNumber);
 | 
			
		||||
            ViewBag.Category = ecnDMO.GetCategoryID(ecn);
 | 
			
		||||
            ViewBag.TrainingNotificationTo = ecnDMO.GetTrainingNotificationTo(ecn, trainingDMO);
 | 
			
		||||
            outputFileName = ecnNumber.ToString() + ".pdf";
 | 
			
		||||
 | 
			
		||||
            string ecnFolderPath = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString();
 | 
			
		||||
@ -910,6 +912,8 @@ public class ECNController : PdfViewController {
 | 
			
		||||
            string outputFileName = "";
 | 
			
		||||
 | 
			
		||||
            ecn = ecnDMO.GetECNPdf(ecnNumber);
 | 
			
		||||
            ViewBag.Category = ecnDMO.GetCategoryID(ecn);
 | 
			
		||||
            ViewBag.TrainingNotificationTo = ecnDMO.GetTrainingNotificationTo(ecn, trainingDMO);
 | 
			
		||||
            outputFileName = ecnNumber.ToString() + ".pdf";
 | 
			
		||||
 | 
			
		||||
            string ecnFolderPath = _AppSettings.AttachmentFolder + "ECN\\" + folderName.ToString();
 | 
			
		||||
@ -935,13 +939,15 @@ public class ECNController : PdfViewController {
 | 
			
		||||
        ECNPdf ecn;
 | 
			
		||||
        try {
 | 
			
		||||
            ecn = ecnDMO.GetECNPdf(ecnNumber);
 | 
			
		||||
            ViewBag.Category = ecnDMO.GetCategoryID(ecn);
 | 
			
		||||
            ViewBag.TrainingNotificationTo = ecnDMO.GetTrainingNotificationTo(ecn, trainingDMO);
 | 
			
		||||
            // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This
 | 
			
		||||
            // requires the controller to be inherited from MyController instead of MVC's Controller.
 | 
			
		||||
            return this.ViewPdf("", "ECNPdf", ecn);
 | 
			
		||||
        } catch (Exception ex) {
 | 
			
		||||
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Print PDF", Comments = ex.Message });
 | 
			
		||||
            ecn = null;
 | 
			
		||||
            return Content("");
 | 
			
		||||
            return Content("An unexpected error has occurred!");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -953,8 +959,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 +982,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 +1162,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 +1191,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 +1215,26 @@ 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);
 | 
			
		||||
                ecn.CancellationDate = DateTime.Now;
 | 
			
		||||
                ecn.CancellationApprovalDate = DateTime.Now;
 | 
			
		||||
                ecn.CancellationApproved = true;
 | 
			
		||||
                ecn.Cancelled = true;
 | 
			
		||||
                ecnDMO.UpdateECN(ecn);
 | 
			
		||||
 | 
			
		||||
                ECNPdf ecnPDF = new ECNPdf();
 | 
			
		||||
                GenerateECNPdf(ecnNumber, out ecnPDF);
 | 
			
		||||
 | 
			
		||||
                string sourceDirectory = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString() + "\\";
 | 
			
		||||
                string outputFullFilePath = "";
 | 
			
		||||
@ -1232,7 +1246,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,9 +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 wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ??
 | 
			
		||||
            "https://localhost:7255";
 | 
			
		||||
        string mrbUrl = $"{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);
 | 
			
		||||
    }
 | 
			
		||||
@ -104,9 +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 wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ??
 | 
			
		||||
            "https://localhost:7255";
 | 
			
		||||
        string mrbUrl = $"{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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								Fab2ApprovalSystem/Controllers/PCRBController.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Fab2ApprovalSystem/Controllers/PCRBController.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Web.Mvc;
 | 
			
		||||
 | 
			
		||||
using Fab2ApprovalSystem.Misc;
 | 
			
		||||
 | 
			
		||||
namespace Fab2ApprovalSystem.Controllers;
 | 
			
		||||
 | 
			
		||||
[Authorize]
 | 
			
		||||
[SessionExpireFilter]
 | 
			
		||||
public class PCRBController : Controller {
 | 
			
		||||
    public ActionResult Edit(int issueID) {
 | 
			
		||||
        string jwt = Session["JWT"].ToString();
 | 
			
		||||
        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}";
 | 
			
		||||
 | 
			
		||||
        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();
 | 
			
		||||
 | 
			
		||||
@ -90,6 +90,7 @@ public class CorrectiveActionDMO {
 | 
			
		||||
                parameters.Add("@EscapePoint", model.EscapePoint);
 | 
			
		||||
                parameters.Add("@FollowUpDate", model.FollowUpDate);
 | 
			
		||||
                parameters.Add("@CASubmitted", model.CASubmitted);
 | 
			
		||||
                parameters.Add("@CAStandardType", model.CAStandardType);
 | 
			
		||||
 | 
			
		||||
                db.Execute("_8DUpdateCorrectiveAction", parameters, commandType: CommandType.StoredProcedure);
 | 
			
		||||
                EventLogDMO.Add(new WinEventLog { UserID = "System", Comments = "Saved Corrective Action", DocumentType = "9", IssueID = model.CANo, OperationType = "Status", SysDocumentID = 1 });
 | 
			
		||||
@ -323,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;
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,7 @@ using Fab2ApprovalSystem.ViewModels;
 | 
			
		||||
namespace Fab2ApprovalSystem.DMO;
 | 
			
		||||
 | 
			
		||||
public class ECN_DMO {
 | 
			
		||||
 | 
			
		||||
    private readonly IDbConnection db = new SqlConnection(GlobalVars.DB_CONNECTION_STRING);
 | 
			
		||||
    private readonly WorkflowDMO wfDMO = new();
 | 
			
		||||
 | 
			
		||||
@ -41,6 +42,9 @@ public class ECN_DMO {
 | 
			
		||||
            parameters.Add("@ExpirationDate", ecn.ExpirationDate);
 | 
			
		||||
            parameters.Add("@ExtensionDate", ecn.ExtensionDate);
 | 
			
		||||
            parameters.Add("@CancellationDate", ecn.CancellationDate);
 | 
			
		||||
            parameters.Add("@CancellationApprovalDate", ecn.CancellationApprovalDate);
 | 
			
		||||
            parameters.Add("@CancellationApproved", ecn.CancellationApproved);
 | 
			
		||||
            parameters.Add("@Cancelled", ecn.Cancelled);
 | 
			
		||||
            parameters.Add("@AcknowledgementRequired", ecn.AcknowledgementRequired);
 | 
			
		||||
            parameters.Add("@TrainingRequired", ecn.TrainingRequired);
 | 
			
		||||
            parameters.Add("@AreaID", ecn.AreaID);
 | 
			
		||||
@ -352,14 +356,17 @@ public class ECN_DMO {
 | 
			
		||||
            List<string> affectedAreas = multipleResultItems.Read<string>().ToList();
 | 
			
		||||
            List<string> affectedTechnologies = multipleResultItems.Read<string>().ToList();
 | 
			
		||||
            List<string> acknowledgementBy = multipleResultItems.Read<string>().ToList();
 | 
			
		||||
            List<string> trainingBy = multipleResultItems.Read<string>().ToList();
 | 
			
		||||
            List<int> trainingby = multipleResultItems.Read<int>().ToList();
 | 
			
		||||
            if (ecnItem != null && trainingby != null) {
 | 
			
		||||
                if (trainingby.Count > 0)
 | 
			
		||||
                    ecnItem.TrainingByIDs.AddRange(trainingby);
 | 
			
		||||
            }
 | 
			
		||||
            List<string> productfamilies = multipleResultItems.Read<string>().ToList();
 | 
			
		||||
 | 
			
		||||
            ecnItem.AffectedModules = string.Join(", ", modules);
 | 
			
		||||
            ecnItem.AffectedDepartments = string.Join(", ", departments);
 | 
			
		||||
            ecnItem.AffectedAreas = string.Join(",", affectedAreas);
 | 
			
		||||
            ecnItem.AffectedTechnologies = string.Join(",", affectedTechnologies);
 | 
			
		||||
            ecnItem.TrainingBy = string.Join(",", trainingBy);
 | 
			
		||||
            ecnItem.AcknowledgementBy = string.Join(",", acknowledgementBy);
 | 
			
		||||
            ecnItem.AffectedProductFamilies = string.Join(",", productfamilies);
 | 
			
		||||
 | 
			
		||||
@ -367,7 +374,7 @@ public class ECN_DMO {
 | 
			
		||||
        return ecnItem;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal ECN GetECN(int ecnNumber) {
 | 
			
		||||
    public ECN GetECN(int ecnNumber) {
 | 
			
		||||
        ECN ecnItem = new();
 | 
			
		||||
        DynamicParameters parameters = new();
 | 
			
		||||
        parameters.Add("@ECNNumber", value: ecnNumber);
 | 
			
		||||
@ -389,7 +396,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() {
 | 
			
		||||
@ -710,4 +717,26 @@ public class ECN_DMO {
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal string GetCategoryID(ECNPdf ecn) {
 | 
			
		||||
        string result;
 | 
			
		||||
        if (ecn.CategoryID is null) {
 | 
			
		||||
            result = string.Empty;
 | 
			
		||||
        } else {
 | 
			
		||||
            List<ECNCategory> categories = GetCategories();
 | 
			
		||||
            result = (from l in categories where l.CategoryID == ecn.CategoryID.Value select l.CategoryName).FirstOrDefault();
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    internal string GetTrainingNotificationTo(ECNPdf ecn, TrainingDMO trainingDMO) {
 | 
			
		||||
        string result;
 | 
			
		||||
        if (ecn.TrainingByIDs is null) {
 | 
			
		||||
            result = string.Empty;
 | 
			
		||||
        } else {
 | 
			
		||||
            List<TrainingGroup> trainingGroups = trainingDMO.GetTrainingGroups();
 | 
			
		||||
            result = string.Join(", ", (from l in trainingGroups where ecn.TrainingByIDs.Contains(l.TrainingGroupID) select l.TrainingGroupName).ToArray());
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -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>
 | 
			
		||||
@ -255,6 +255,7 @@
 | 
			
		||||
    <Compile Include="Controllers\TrainingController.cs" />
 | 
			
		||||
    <Compile Include="Controllers\WebAPIController.cs" />
 | 
			
		||||
    <Compile Include="Controllers\WorkflowController.cs" />
 | 
			
		||||
    <Compile Include="Controllers\PCRBController.cs" />
 | 
			
		||||
    <Compile Include="DMO\AccountDMO.cs" />
 | 
			
		||||
    <Compile Include="DMO\AdminDMO.cs" />
 | 
			
		||||
    <Compile Include="DMO\ApprovalLogDMO.cs" />
 | 
			
		||||
@ -387,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" />
 | 
			
		||||
@ -513,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,104 +1,109 @@
 | 
			
		||||
#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 {
 | 
			
		||||
        string _path;
 | 
			
		||||
        public ExcelData(string path) {
 | 
			
		||||
            _path = path;
 | 
			
		||||
        }
 | 
			
		||||
public class ExcelData {
 | 
			
		||||
 | 
			
		||||
        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 
 | 
			
		||||
            IExcelDataReader reader = null;
 | 
			
		||||
 | 
			
		||||
            try {
 | 
			
		||||
                if (_path.EndsWith(".xls")) {
 | 
			
		||||
                    reader = ExcelReaderFactory.CreateBinaryReader(stream);
 | 
			
		||||
                }
 | 
			
		||||
                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 IEnumerable<ExcelLotInfo> ReadData() {
 | 
			
		||||
            var r = new List<ExcelLotInfo>();
 | 
			
		||||
            var excelData = new ExcelData(_path);
 | 
			
		||||
            var lots = excelData.getData().ToList();
 | 
			
		||||
 | 
			
		||||
            int lotDispoColumnIndex = -1;
 | 
			
		||||
            foreach (DataColumn col in lots[0].Table.Columns) {
 | 
			
		||||
                if (col.ColumnName.ToLower().Contains("dispo")) {
 | 
			
		||||
                    lotDispoColumnIndex = col.Ordinal;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            foreach (var row in lots) {
 | 
			
		||||
                string temValue = row[0].ToString();
 | 
			
		||||
                if (temValue.Trim().Length > 0 && temValue.Trim().Length <= 10) {
 | 
			
		||||
                    r.Add(new ExcelLotInfo() {
 | 
			
		||||
                        LotNo = row[0].ToString(),
 | 
			
		||||
                        LotDispo = (lotDispoColumnIndex >= 0 ? row[lotDispoColumnIndex].ToString() : "")
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            return r;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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) {
 | 
			
		||||
                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") {
 | 
			
		||||
                        throw new Exception("Invalid data in the file");
 | 
			
		||||
                    } else {
 | 
			
		||||
                        s.Add(row[0].ToString() + "~" + row[1] + "~" + row[2]);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            return s;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<DataRow> getData(bool firstRowIsColumnNames = true) {
 | 
			
		||||
            var reader = this.getExcelReader();
 | 
			
		||||
            reader.IsFirstRowAsColumnNames = firstRowIsColumnNames;
 | 
			
		||||
            var workSheet = reader.AsDataSet().Tables[0];
 | 
			
		||||
            var rows = from DataRow a in workSheet.Rows select a;
 | 
			
		||||
            return rows;
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    private readonly string _Path;
 | 
			
		||||
 | 
			
		||||
    public ExcelData(string path) {
 | 
			
		||||
        _Path = path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public IExcelDataReader getExcelReader() {
 | 
			
		||||
        FileStream stream = File.Open(_Path, FileMode.Open, FileAccess.Read);
 | 
			
		||||
        IExcelDataReader reader = null;
 | 
			
		||||
        try {
 | 
			
		||||
            if (_Path.EndsWith(".xls")) {
 | 
			
		||||
                reader = ExcelReaderFactory.CreateBinaryReader(stream);
 | 
			
		||||
            }
 | 
			
		||||
            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 IEnumerable<ExcelLotInfo> ReadData() {
 | 
			
		||||
        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) {
 | 
			
		||||
            if (col.ColumnName.ToLower().Contains("dispo")) {
 | 
			
		||||
                lotDispoColumnIndex = col.Ordinal;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        foreach (DataRow row in lots) {
 | 
			
		||||
            string temValue = row[0].ToString();
 | 
			
		||||
            if (temValue.Trim().Length > 0 && temValue.Trim().Length <= 10) {
 | 
			
		||||
                r.Add(new ExcelLotInfo() {
 | 
			
		||||
                    LotNo = row[0].ToString(),
 | 
			
		||||
                    LotDispo = (lotDispoColumnIndex >= 0 ? row[lotDispoColumnIndex].ToString() : "")
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public IEnumerable<string> ReadQDBFlagData() {
 | 
			
		||||
        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") {
 | 
			
		||||
                    throw new Exception("Invalid data in the file");
 | 
			
		||||
                } else {
 | 
			
		||||
                    s.Add(row[0].ToString() + "~" + row[1] + "~" + row[2]);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        return s;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if NET8
 | 
			
		||||
 | 
			
		||||
    public IEnumerable<DataRow> getData(bool firstRowIsColumnNames = true) =>
 | 
			
		||||
        throw new NotImplementedException();
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
    public IEnumerable<DataRow> getData(bool firstRowIsColumnNames = true) {
 | 
			
		||||
        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)
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@ namespace Fab2ApprovalSystem.Models;
 | 
			
		||||
public class AppSettings {
 | 
			
		||||
 | 
			
		||||
    public AppSettings(string adminNotificationRecepient,
 | 
			
		||||
                       string? apiBaseUrl,
 | 
			
		||||
                       string apiBaseUrl,
 | 
			
		||||
                       string attachmentFolder,
 | 
			
		||||
                       string? attachmentUrl,
 | 
			
		||||
                       string caBlankFormsLocation,
 | 
			
		||||
@ -46,6 +46,7 @@ public class AppSettings {
 | 
			
		||||
                       string urls,
 | 
			
		||||
                       int userId,
 | 
			
		||||
                       bool userIsAdmin,
 | 
			
		||||
                       string wasmClientUrl,
 | 
			
		||||
                       string wsr_URL,
 | 
			
		||||
                       string? workingDirectoryName) {
 | 
			
		||||
        AdminNotificationRecepient = adminNotificationRecepient;
 | 
			
		||||
@ -88,11 +89,12 @@ public class AppSettings {
 | 
			
		||||
        UserId = userId;
 | 
			
		||||
        UserIsAdmin = userIsAdmin;
 | 
			
		||||
        WSR_URL = wsr_URL;
 | 
			
		||||
        WasmClientUrl = wasmClientUrl;
 | 
			
		||||
        WorkingDirectoryName = workingDirectoryName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public string AdminNotificationRecepient { get; }
 | 
			
		||||
    public string? ApiBaseUrl { get; }
 | 
			
		||||
    public string ApiBaseUrl { get; }
 | 
			
		||||
    public string AttachmentFolder { get; }
 | 
			
		||||
    public string? AttachmentUrl { get; }
 | 
			
		||||
    public string CABlankFormsLocation { get; }
 | 
			
		||||
@ -130,6 +132,7 @@ public class AppSettings {
 | 
			
		||||
    public string URLs { get; }
 | 
			
		||||
    public int UserId { get; }
 | 
			
		||||
    public bool UserIsAdmin { get; }
 | 
			
		||||
    public string WasmClientUrl { get; }
 | 
			
		||||
    public string WSR_URL { get; }
 | 
			
		||||
    public string? WorkingDirectoryName { get; }
 | 
			
		||||
 | 
			
		||||
@ -211,12 +214,15 @@ public class AppSettings {
 | 
			
		||||
                throw new ArgumentNullException("SSRSPassword environment variable not found");
 | 
			
		||||
            string testEmailRecipients = ConfigurationManager.AppSettings["Test Email Recipients"] ??
 | 
			
		||||
                throw new ArgumentNullException("Test Email Recipients environment variable not found");
 | 
			
		||||
            string? apiBaseUrl = ConfigurationManager.AppSettings["FabApprovalApiBaseUrl"]?.ToString();
 | 
			
		||||
            string apiBaseUrl = Environment.GetEnvironmentVariable("FabApprovalApiBaseUrl") ??
 | 
			
		||||
                throw new ArgumentNullException("FabApprovalApiBaseUrl environment variable not found");
 | 
			
		||||
            string? attachmentUrl = ConfigurationManager.AppSettings["AttachmentUrl"]?.ToString();
 | 
			
		||||
            string? company = ConfigurationManager.AppSettings["Company"]?.ToString();
 | 
			
		||||
            string? smtpServer = ConfigurationManager.AppSettings["SMTP Server"]?.ToString();
 | 
			
		||||
            string? urls = ConfigurationManager.AppSettings["URLs"]?.ToString();
 | 
			
		||||
            string? workingDirectoryName = ConfigurationManager.AppSettings["WorkingDirectoryName"]?.ToString();
 | 
			
		||||
            string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ??
 | 
			
		||||
                "https://localhost:7255";
 | 
			
		||||
            result = new(adminNotificationRecepient: adminNotificationRecepient,
 | 
			
		||||
                         apiBaseUrl: apiBaseUrl,
 | 
			
		||||
                         attachmentFolder: attachmentFolder,
 | 
			
		||||
@ -256,6 +262,7 @@ public class AppSettings {
 | 
			
		||||
                         urls: urls,
 | 
			
		||||
                         userId: userId,
 | 
			
		||||
                         userIsAdmin: Misc.GlobalVars.USER_ISADMIN,
 | 
			
		||||
                         wasmClientUrl: wasmClientUrl,
 | 
			
		||||
                         wsr_URL: Misc.GlobalVars.WSR_URL,
 | 
			
		||||
                         workingDirectoryName: workingDirectoryName);
 | 
			
		||||
            return result;
 | 
			
		||||
 | 
			
		||||
@ -231,6 +231,7 @@ public class CorrectiveAction {
 | 
			
		||||
    public DateTime? NextDueDate { get; set; }
 | 
			
		||||
    public DateTime? FollowUpDate { get; set; }
 | 
			
		||||
    public bool CASubmitted { get; set; }
 | 
			
		||||
    public string CAStandardType { get; set; }
 | 
			
		||||
    public DateTime? ClosedDate { get; set; }
 | 
			
		||||
    public CorrectiveAction() {
 | 
			
		||||
        TeamMemberIDs = new List<int>();
 | 
			
		||||
 | 
			
		||||
@ -30,7 +30,7 @@ public class ECNPdf {
 | 
			
		||||
    public string AffectedDepartments { get; set; }
 | 
			
		||||
    public string AffectedAreas { get; set; }
 | 
			
		||||
    public string AffectedTechnologies { get; set; }
 | 
			
		||||
    public string TrainingBy { get; set; }
 | 
			
		||||
    public List<int> TrainingByIDs { get; set; }
 | 
			
		||||
    public string AcknowledgementBy { get; set; }
 | 
			
		||||
    public bool IsECN { get; set; }
 | 
			
		||||
    public bool IsTECN { get; set; }
 | 
			
		||||
@ -79,6 +79,7 @@ public class ECNPdf {
 | 
			
		||||
    public int? ConvertedToNumber { get; set; }
 | 
			
		||||
    public int? ConvertedFromNumber { get; set; }
 | 
			
		||||
    public int WorkFlowNumber { get; set; }
 | 
			
		||||
    public int? CategoryID { get; set; }
 | 
			
		||||
    public bool FIChangeRequired { get; set; }
 | 
			
		||||
    public string NumberOfLotsAffected { get; set; }
 | 
			
		||||
    public string RecipeChange { get; set; }
 | 
			
		||||
@ -87,6 +88,7 @@ public class ECNPdf {
 | 
			
		||||
    public ECNPdf() {
 | 
			
		||||
        Approvalog = new List<ECNApprovalLog>();
 | 
			
		||||
        Attachments = new List<string>();
 | 
			
		||||
        TrainingByIDs = new List<int>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -380,6 +380,43 @@
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="col-sm-3">
 | 
			
		||||
                        <div class="row">
 | 
			
		||||
                            <div class="col-sm-3">
 | 
			
		||||
                                <label class="control-label pull-right">CA Standard Type:</label>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <div class="col-sm-9">
 | 
			
		||||
                                @(Html.Kendo().DropDownList()
 | 
			
		||||
                                    .Name("CAStandardTypeList")
 | 
			
		||||
 | 
			
		||||
                                    .DataTextField("Text")
 | 
			
		||||
                                    .DataValueField("Value")
 | 
			
		||||
                                        .BindTo(new List<SelectListItem>()
 | 
			
		||||
                                        {
 | 
			
		||||
                                            new SelectListItem()
 | 
			
		||||
                                            {
 | 
			
		||||
                                                Text = "IATF16949",
 | 
			
		||||
                                                Value = "IATF16949"
 | 
			
		||||
                                            },
 | 
			
		||||
                                            new SelectListItem()
 | 
			
		||||
                                            {
 | 
			
		||||
                                                Text = "ISO14001",
 | 
			
		||||
                                                Value = "ISO14001"
 | 
			
		||||
                                            },
 | 
			
		||||
                                            new SelectListItem()
 | 
			
		||||
                                            {
 | 
			
		||||
                                                Text = "ISO45001",
 | 
			
		||||
                                                Value = "ISO45001"
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                    )
 | 
			
		||||
                                    .OptionLabel("Select")
 | 
			
		||||
                                    .Value(Model.CAStandardType)
 | 
			
		||||
                                )
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row">
 | 
			
		||||
                    <div class="col-sm-3">
 | 
			
		||||
@ -2176,6 +2213,7 @@
 | 
			
		||||
            $('#txtApprovedDate').attr("disabled", true);
 | 
			
		||||
            $('#txtRelatedMRB').attr("disabled", true);
 | 
			
		||||
            $('#CATypeList').data("kendoDropDownList").enable(false);
 | 
			
		||||
            $('#CAStandardTypeList').data("kendoDropDownList").enable(false);
 | 
			
		||||
            $('#d0Comments').attr("disabled", true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -3689,6 +3727,7 @@
 | 
			
		||||
            TeamCaptainID: $("#TeamCaptainList").data("kendoDropDownList").value(),
 | 
			
		||||
            CASponsorID: $("#CASponsorList").data("kendoDropDownList").value(),
 | 
			
		||||
            CASubmitted: isCASubmitted,
 | 
			
		||||
            CAStandardType : $("#CAStandardTypeList").data("kendoDropDownList").value(),
 | 
			
		||||
 | 
			
		||||
            //D0
 | 
			
		||||
            D0Comments : $("#d0Comments").val(),
 | 
			
		||||
 | 
			
		||||
@ -325,6 +325,16 @@
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="col-sm-3">
 | 
			
		||||
                        <div class="row">
 | 
			
		||||
                            <div class="col-sm-3">
 | 
			
		||||
                                <label class="control-label pull-right">CA Standard Type:</label>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <div class="col-sm-9">
 | 
			
		||||
                                @Html.TextBoxFor(model => model.CAStandardType, new { id = "txtCAStandardType", @class = "k-textbox", Readonly = "Readonly", style = "background-color:lightblue" })
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="row">
 | 
			
		||||
                    <div class="col-sm-3">
 | 
			
		||||
 | 
			
		||||
@ -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">
 | 
			
		||||
 | 
			
		||||
@ -30,11 +30,11 @@
 | 
			
		||||
                            }
 | 
			
		||||
                            @if (@Model.ConvertedFromNumber == null && @Model.ConvertedToNumber == null)
 | 
			
		||||
                            {
 | 
			
		||||
                            <tr>
 | 
			
		||||
                                <td>
 | 
			
		||||
                                    ECN# @Model.ECNNumber
 | 
			
		||||
                                </td>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                                <tr>
 | 
			
		||||
                                    <td>
 | 
			
		||||
                                        ECN# @Model.ECNNumber
 | 
			
		||||
                                    </td>
 | 
			
		||||
                                </tr>
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            <tr>
 | 
			
		||||
@ -63,14 +63,14 @@
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <table border="0">
 | 
			
		||||
                            @*<tr>
 | 
			
		||||
                                <td>
 | 
			
		||||
                                    <font size="2">
 | 
			
		||||
                                        Affected Department: 
 | 
			
		||||
                                    </font>
 | 
			
		||||
                                    <font size="1">
 | 
			
		||||
                                        @Model.AffectedDepartments
 | 
			
		||||
                                    </font>
 | 
			
		||||
                                </td>
 | 
			
		||||
                            <td>
 | 
			
		||||
                            <font size="2">
 | 
			
		||||
                            Affected Department: 
 | 
			
		||||
                            </font>
 | 
			
		||||
                            <font size="1">
 | 
			
		||||
                            @Model.AffectedDepartments
 | 
			
		||||
                            </font>
 | 
			
		||||
                            </td>
 | 
			
		||||
 | 
			
		||||
                            </tr>*@
 | 
			
		||||
                            <tr>
 | 
			
		||||
@ -84,6 +84,16 @@
 | 
			
		||||
                                    </font>
 | 
			
		||||
                                </td>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                            <tr>
 | 
			
		||||
                                <td>
 | 
			
		||||
                                    <font size="2">
 | 
			
		||||
                                        Category: 
 | 
			
		||||
                                    </font>
 | 
			
		||||
                                    <font size="1">
 | 
			
		||||
                                        @(ViewBag.Category)
 | 
			
		||||
                                    </font>
 | 
			
		||||
                                </td>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                            <tr>
 | 
			
		||||
                                <td>
 | 
			
		||||
                                    <font size="2">
 | 
			
		||||
@ -224,7 +234,7 @@
 | 
			
		||||
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td>
 | 
			
		||||
            <table border="1" >
 | 
			
		||||
            <table border="1">
 | 
			
		||||
                <tr bgcolor="#c4baba" color="#000000">
 | 
			
		||||
                    <td> Description of Change</td>
 | 
			
		||||
                    <td> Reason for Change</td>
 | 
			
		||||
@ -245,33 +255,33 @@
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    @*<tr>
 | 
			
		||||
        <td>
 | 
			
		||||
    <td>
 | 
			
		||||
 | 
			
		||||
            <table border="1">
 | 
			
		||||
                <tr bgcolor="#c4baba" color="#000000">
 | 
			
		||||
                    <td colspan="3">Training Notification</td>                    
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <td>
 | 
			
		||||
                       <table border="0">
 | 
			
		||||
                           <tr>
 | 
			
		||||
                               <td>
 | 
			
		||||
                                   <font size="1">
 | 
			
		||||
                                       Training:
 | 
			
		||||
                                       @(Model.TrainingRequired ? "Yes" : "No")
 | 
			
		||||
                                   </font>
 | 
			
		||||
    <table border="1">
 | 
			
		||||
    <tr bgcolor="#c4baba" color="#000000">
 | 
			
		||||
    <td colspan="3">Training Notification</td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
    <td>
 | 
			
		||||
    <table border="0">
 | 
			
		||||
    <tr>
 | 
			
		||||
    <td>
 | 
			
		||||
    <font size="1">
 | 
			
		||||
    Training:
 | 
			
		||||
    @(Model.TrainingRequired ? "Yes" : "No")
 | 
			
		||||
    </font>
 | 
			
		||||
 | 
			
		||||
                                   <font size="1">
 | 
			
		||||
                                       @(Model.TrainingBy.Length > 0 ? "(" + Model.TrainingBy + ")" : Model.TrainingBy)                                       
 | 
			
		||||
                                   </font>
 | 
			
		||||
                               </td>
 | 
			
		||||
                           </tr>
 | 
			
		||||
                       </table>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
            </table>
 | 
			
		||||
    <font size="1">
 | 
			
		||||
    @(Model.TrainingBy.Length > 0 ? "(" + Model.TrainingBy + ")" : Model.TrainingBy)
 | 
			
		||||
    </font>
 | 
			
		||||
    </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
    </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    </table>
 | 
			
		||||
 | 
			
		||||
        </td>
 | 
			
		||||
    </td>
 | 
			
		||||
    </tr>*@
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td>
 | 
			
		||||
@ -286,7 +296,7 @@
 | 
			
		||||
                            PCRB:
 | 
			
		||||
                        </font>
 | 
			
		||||
                        <font size="1">
 | 
			
		||||
                            @(Model.PCRBRequired ? "Yes": "No")
 | 
			
		||||
                            @(Model.PCRBRequired ? "Yes" : "No")
 | 
			
		||||
                        </font>
 | 
			
		||||
                    </td>
 | 
			
		||||
                    <td>
 | 
			
		||||
@ -300,7 +310,7 @@
 | 
			
		||||
                            Metrology Change:   
 | 
			
		||||
                        </font>
 | 
			
		||||
                        <font size="1">
 | 
			
		||||
                            @(Model.MetrologyChangeRequired ? "Yes": "No")
 | 
			
		||||
                            @(Model.MetrologyChangeRequired ? "Yes" : "No")
 | 
			
		||||
                        </font>
 | 
			
		||||
                    </td>
 | 
			
		||||
                    <td>
 | 
			
		||||
@ -308,7 +318,7 @@
 | 
			
		||||
                            SPC Change:
 | 
			
		||||
                        </font>
 | 
			
		||||
                        <font size="1">
 | 
			
		||||
                            @(Model.SPCChangeRequired ? "Yes": "No")
 | 
			
		||||
                            @(Model.SPCChangeRequired ? "Yes" : "No")
 | 
			
		||||
                        </font>
 | 
			
		||||
                    </td>
 | 
			
		||||
                    <td>
 | 
			
		||||
@ -316,7 +326,7 @@
 | 
			
		||||
                            FI Change:
 | 
			
		||||
                        </font>
 | 
			
		||||
                        <font size="1">
 | 
			
		||||
                           @(Model.FIChangeRequired ? "Yes" : "No")
 | 
			
		||||
                            @(Model.FIChangeRequired ? "Yes" : "No")
 | 
			
		||||
                        </font>
 | 
			
		||||
                    </td>
 | 
			
		||||
                    <td>
 | 
			
		||||
@ -327,7 +337,35 @@
 | 
			
		||||
                            @(Model.SPNChangeRequired ? "Yes" : "No")
 | 
			
		||||
                        </font>
 | 
			
		||||
                    </td>
 | 
			
		||||
                    <td></td>
 | 
			
		||||
                </tr>
 | 
			
		||||
 | 
			
		||||
            </table>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
    <tr>
 | 
			
		||||
        <td>
 | 
			
		||||
 | 
			
		||||
            <table border="1">
 | 
			
		||||
                <tr bgcolor="#c4baba" color="#000000">
 | 
			
		||||
                    <td colspan="5">Training Notification</td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                <tr style="display:block;">
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <font size="2">
 | 
			
		||||
                            Training:
 | 
			
		||||
                        </font>
 | 
			
		||||
                        <font size="1">
 | 
			
		||||
                            @(Model.TrainingRequired ? "Yes" : "No")
 | 
			
		||||
                        </font>
 | 
			
		||||
                    </td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        <font size="2">
 | 
			
		||||
                            Training Notification to:  
 | 
			
		||||
                            @(ViewBag.TrainingNotificationTo)
 | 
			
		||||
                        </font>
 | 
			
		||||
                    </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
 | 
			
		||||
            </table>
 | 
			
		||||
@ -369,7 +407,7 @@
 | 
			
		||||
                                <td>
 | 
			
		||||
                                    <font size="1">
 | 
			
		||||
                                        @Html.Raw(@Model.ImpactOnEnvironmentDescription)
 | 
			
		||||
                                        </font>
 | 
			
		||||
                                    </font>
 | 
			
		||||
                                </td>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                        </table>
 | 
			
		||||
@ -390,23 +428,23 @@
 | 
			
		||||
                                <td>
 | 
			
		||||
                                    <font size="1">
 | 
			
		||||
                                        @Html.Raw(@Model.ImpactOnCapacityDescription)
 | 
			
		||||
                                        </font>
 | 
			
		||||
                                    </font>
 | 
			
		||||
                                </td>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                        </table>
 | 
			
		||||
                    </td>
 | 
			
		||||
                    <td>
 | 
			
		||||
                        @*<table border="0">
 | 
			
		||||
                            <tr>
 | 
			
		||||
                                <td>
 | 
			
		||||
                                    <font size="2">
 | 
			
		||||
                                        RH(ITAR):
 | 
			
		||||
                                    </font>
 | 
			
		||||
                                    <font size="1">
 | 
			
		||||
                                        @(Model.IsRH ? "Yes" : "No")
 | 
			
		||||
                                    </font>
 | 
			
		||||
                                </td>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                        <tr>
 | 
			
		||||
                        <td>
 | 
			
		||||
                        <font size="2">
 | 
			
		||||
                        RH(ITAR):
 | 
			
		||||
                        </font>
 | 
			
		||||
                        <font size="1">
 | 
			
		||||
                        @(Model.IsRH ? "Yes" : "No")
 | 
			
		||||
                        </font>
 | 
			
		||||
                        </td>
 | 
			
		||||
                        </tr>
 | 
			
		||||
                        </table>*@
 | 
			
		||||
                    </td>
 | 
			
		||||
                    <td>
 | 
			
		||||
 | 
			
		||||
@ -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,29 +86,47 @@
 | 
			
		||||
 | 
			
		||||
                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" />
 | 
			
		||||
                    <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" />
 | 
			
		||||
                    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)
 | 
			
		||||
                {
 | 
			
		||||
                    <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" />
 | 
			
		||||
                    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" />
 | 
			
		||||
                    <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" />
 | 
			
		||||
                    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" />
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@ -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,17 +90,17 @@
 | 
			
		||||
                            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";
 | 
			
		||||
                            <li><a href="@pcrbUrl">Create PCRB</a></li>*@
 | 
			
		||||
                            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";
 | 
			
		||||
                            <li><a href="@pcrbUrl">Create PCRB</a></li>*@
 | 
			
		||||
                            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>*@
 | 
			
		||||
                        @*<li><a href=@Url.Action("Create", "ChangeControl")>Create PCR</a></li>*@
 | 
			
		||||
@ -150,10 +150,10 @@
 | 
			
		||||
            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";
 | 
			
		||||
            //menu.Add().Text("PCRB").Url(pcrbUrl);
 | 
			
		||||
            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");
 | 
			
		||||
            //menu.Add().Text("MRB").Action("MRBList", "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
 | 
			
		||||
@ -54,7 +54,7 @@ public class HomeControllerTests {
 | 
			
		||||
 | 
			
		||||
    private static void GetMyOpenActionItems(ILogger? logger, AppSettings appSettings) {
 | 
			
		||||
        SetGlobalVars(logger, appSettings);
 | 
			
		||||
        LotDispositionDMO lotDispositionDMO = new(appSettings);
 | 
			
		||||
        LotDispositionDMO lotDispositionDMO = new();
 | 
			
		||||
        OpenActionItemViewModel[] openActionItemViewModels = lotDispositionDMO.GetMyOpenActionItems(appSettings.UserId).ToArray();
 | 
			
		||||
        if (openActionItemViewModels.Length == 0) { }
 | 
			
		||||
    }
 | 
			
		||||
@ -76,7 +76,7 @@ public class HomeControllerTests {
 | 
			
		||||
 | 
			
		||||
    private static void GetTaskList(ILogger? logger, AppSettings appSettings) {
 | 
			
		||||
        SetGlobalVars(logger, appSettings);
 | 
			
		||||
        LotDispositionDMO lotDispositionDMO = new(appSettings);
 | 
			
		||||
        LotDispositionDMO lotDispositionDMO = new();
 | 
			
		||||
        IssuesViewModel[] issuesViewModels = lotDispositionDMO.GetTaskList(appSettings.UserId).ToArray();
 | 
			
		||||
        if (issuesViewModels.Length == 0) { }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -56,8 +56,8 @@ public class AdminDMOTests {
 | 
			
		||||
        AdminDMO adminDMO = new();
 | 
			
		||||
        // void AddNewTrainingGroup(string groupName);
 | 
			
		||||
        // void AddUserRoles(int subRole, string userids);
 | 
			
		||||
        // void AddUserToGroup(int userId, int groupId);
 | 
			
		||||
        // void DeleteFromGroup(int userId, int groupId);
 | 
			
		||||
        // void AddUserToGroup(appSettings.UserId, int groupId);
 | 
			
		||||
        // void DeleteFromGroup(appSettings.UserId, int groupId);
 | 
			
		||||
        // void DeleteTrainingGroup(int groupID);
 | 
			
		||||
        // adminDMO.DeleteUserFromAllTrainingGroups(appSettings.UserId);
 | 
			
		||||
        // void DeleteUserRoles(int subRole, string userids);
 | 
			
		||||
 | 
			
		||||
@ -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, int userID);
 | 
			
		||||
        // Audit GetAuditItemReadOnly(int auditNo, int 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(int userID, int issueID);
 | 
			
		||||
        // void UpdateAudit(Audit audit, int userID);
 | 
			
		||||
        // void ReleaseLockOnDocument(appSettings.UserId, int issueID);
 | 
			
		||||
        // 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();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -53,12 +53,12 @@ public class ChangeControlDMOTests {
 | 
			
		||||
    private static void ChangeControlDMO(ILogger? logger, AppSettings appSettings) {
 | 
			
		||||
#pragma warning disable IDE0059
 | 
			
		||||
        SetGlobalVars(logger, appSettings);
 | 
			
		||||
        ChangeControlDMO changeControlDMO = new(appSettings);
 | 
			
		||||
        ChangeControlDMO changeControlDMO = new();
 | 
			
		||||
        // IEnumerable<CCAttachment> GetCCAttachment(int planNumber);
 | 
			
		||||
        // IEnumerable<CCMeetingAttachment> GetMeetingAttachments(int meetingID);
 | 
			
		||||
        // IEnumerable<MeetingDecisionSummaryList> GetMeetingDecisionSummaryList(int planNumber);
 | 
			
		||||
        // IEnumerable<CCMeeting> GetMeetingList(int planNumber);
 | 
			
		||||
        // void ReassignOwner(int planNumber, int newOwnerID, string comments, int userID);
 | 
			
		||||
        // void ReassignOwner(int planNumber, int newOwnerID, string comments, appSettings.UserId);
 | 
			
		||||
        if (changeControlDMO is null) { }
 | 
			
		||||
#pragma warning restore IDE0059
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -55,8 +55,8 @@ public class CorrectiveActionDMOTests {
 | 
			
		||||
    private static void CorrectiveActionDMO(ILogger? logger, AppSettings appSettings) {
 | 
			
		||||
#pragma warning disable IDE0059
 | 
			
		||||
        SetGlobalVars(logger, appSettings);
 | 
			
		||||
        CorrectiveActionDMO correctiveActionDMO = new(appSettings);
 | 
			
		||||
        // void ApproveSection(int issueID, int userID, string DSection);
 | 
			
		||||
        CorrectiveActionDMO correctiveActionDMO = new();
 | 
			
		||||
        // void ApproveSection(int issueID, appSettings.UserId, string DSection);
 | 
			
		||||
        // void DeleteCAAttachment(int attachmentID);
 | 
			
		||||
        // void DeleteD3ContainmentActionItem(int d3ContainmentActionID);
 | 
			
		||||
        // void DeleteD5D6CorrectivetAction(int d5d6CAID);
 | 
			
		||||
@ -67,8 +67,8 @@ public class CorrectiveActionDMOTests {
 | 
			
		||||
        // IEnumerable<CA_Attachment> GetCAAttachmentsList(int caNo, string section);
 | 
			
		||||
        CAD3D5D7Due[] cAD3D5D7Dues = correctiveActionDMO.GetCAD3D5D7Due().ToArray();
 | 
			
		||||
        // IEnumerable<CA_Attachment> GetCAFindingsItemAttachments(int caFindingsID);
 | 
			
		||||
        // CorrectiveAction GetCAItem(int caNo, int userID);
 | 
			
		||||
        // CorrectiveAction GetCAItemReadOnly(int caNo, int userID);
 | 
			
		||||
        // CorrectiveAction GetCAItem(int caNo, appSettings.UserId);
 | 
			
		||||
        // CorrectiveAction GetCAItemReadOnly(int caNo, appSettings.UserId);
 | 
			
		||||
        // IEnumerable<CASectionApproval> GetCASectionApprovalLog(int caNo);
 | 
			
		||||
        CASource[] cASources = correctiveActionDMO.GetCASourceList().ToArray();
 | 
			
		||||
        // IEnumerable<D3ContainmentAction> GetD3ContainmentActions(int caNo);
 | 
			
		||||
@ -89,17 +89,17 @@ public class CorrectiveActionDMOTests {
 | 
			
		||||
        // void InsertD3ContainmentAction(D3ContainmentAction model);
 | 
			
		||||
        // void InsertD5D6CorrectivetAction(D5D6CorrectivetAction model);
 | 
			
		||||
        // void InsertD7PreventiveAction(D7PreventiveAction model);
 | 
			
		||||
        // bool IsAIAssignee(int userId, int caId);
 | 
			
		||||
        // bool IsAIAssignee(appSettings.UserId, int caId);
 | 
			
		||||
        // bool IsLastSectionApprover(int caNo, string dSection);
 | 
			
		||||
        // bool IsUserSectionApprover(int issueId, int userId);
 | 
			
		||||
        // void RejectSection(int issueID, int userID, string DSection, string comments);
 | 
			
		||||
        // void ReleaseLockOnDocument(int userID, int issueID);
 | 
			
		||||
        // bool IsUserSectionApprover(int issueId, appSettings.UserId);
 | 
			
		||||
        // void RejectSection(int issueID, appSettings.UserId, string DSection, string comments);
 | 
			
		||||
        // void ReleaseLockOnDocument(appSettings.UserId, int issueID);
 | 
			
		||||
        // DateTime SetCAComplete(int issueID);
 | 
			
		||||
        // DateTime SetCAD3DueDate(int issueID);
 | 
			
		||||
        // DateTime SetCAD5D7DueDate(int issueID);
 | 
			
		||||
        // void SetD3D5D7NotificationDate(int caNo, string section);
 | 
			
		||||
        // int StartApproval(int issueID, int userID, int worlflowNumber);
 | 
			
		||||
        // void StartSectionApproval(int issueID, int userID, string DSection);
 | 
			
		||||
        // int StartApproval(int issueID, appSettings.UserId, int worlflowNumber);
 | 
			
		||||
        // void StartSectionApproval(int issueID, appSettings.UserId, string DSection);
 | 
			
		||||
        // void UpdateCorrectiveAction(CorrectiveAction model);
 | 
			
		||||
        // void UpdateD3ContainmentAction(D3ContainmentAction model);
 | 
			
		||||
        // void UpdateD5D6CorrectivetAction(D5D6CorrectivetAction model);
 | 
			
		||||
 | 
			
		||||
@ -58,30 +58,30 @@ public class EngChangeNoticeDMOTests {
 | 
			
		||||
        ECN_DMO ecnDMO = new();
 | 
			
		||||
        // void CancelECN(int? ecnNumber);
 | 
			
		||||
        // bool CanSubmitECN(int ecnNumber);
 | 
			
		||||
        // void DeleteDocument(int ecnNumber, int userid, string ecnTypeString);
 | 
			
		||||
        // void DeleteDocument(int ecnNumber, appSettings.UserId, string ecnTypeString);
 | 
			
		||||
        // void DeleteECNAttachment(int attachmentID);
 | 
			
		||||
        // bool ECNApproveCancelled_ExpiredDocument(int issueID, byte step, string comments, out bool lastStep, int userID, int documentType);
 | 
			
		||||
        // void ECNResetTECNAtRejection(int ecnNumber, int userID, int docType);
 | 
			
		||||
        // bool ECNApproveCancelled_ExpiredDocument(int issueID, byte step, string comments, out bool lastStep, appSettings.UserId, int documentType);
 | 
			
		||||
        // void ECNResetTECNAtRejection(int ecnNumber, appSettings.UserId, int docType);
 | 
			
		||||
        IssuesViewModel[] issuesViewModels = ecnDMO.GetAllTECNs().ToArray();
 | 
			
		||||
        // IEnumerable<ApprovalLogHistory> GetECNApprovalLogHistory(int ecnNumber);
 | 
			
		||||
        // IEnumerable<ECNAttachment> GetECNAttachments(int ecnNumber);
 | 
			
		||||
        IssuesViewModel[] issuesViewModelsB = ecnDMO.GetECN_TECNPendingApprovals(appSettings.UserId).ToArray();
 | 
			
		||||
        // string GetFileName(string attachmentID);
 | 
			
		||||
        // IEnumerable<IssuesViewModel> GetMyConvertedTECNsToECNs(int userID, int maxDays);
 | 
			
		||||
        // IEnumerable<IssuesViewModel> GetMyExpiredTECNs(int userID, int maxDays);
 | 
			
		||||
        // IEnumerable<IssuesViewModel> GetMyExpiringTECNs(int userID, int maxDays);
 | 
			
		||||
        // IEnumerable<IssuesViewModel> GetMyConvertedTECNsToECNs(appSettings.UserId, int maxDays);
 | 
			
		||||
        // IEnumerable<IssuesViewModel> GetMyExpiredTECNs(appSettings.UserId, int maxDays);
 | 
			
		||||
        // IEnumerable<IssuesViewModel> GetMyExpiringTECNs(appSettings.UserId, int maxDays);
 | 
			
		||||
        // List<string> GetRejectionOrginatorEmailList(int ecnNumber);
 | 
			
		||||
        int[] ints = ecnDMO.GetTECNNotificationUsers().ToArray();
 | 
			
		||||
        // void InsertECNAttachment(ECNAttachment attach);
 | 
			
		||||
        // int PCRBExists(int pcrb);
 | 
			
		||||
        // void ReassignOriginatorECN(int ecnNumber, int newOriginatorID, string comments, int userID);
 | 
			
		||||
        // void ReleaseLockOnDocument(int userID, int issueID);
 | 
			
		||||
        // int ReSubmitDocument(int issueID, int userID, int documentType, out int allowedITAR, string descriptionOfChange, string reasonForChange, string ecnTypeString, out int newECNNumber, int categoryId);
 | 
			
		||||
        // void ReassignOriginatorECN(int ecnNumber, int newOriginatorID, string comments, appSettings.UserId);
 | 
			
		||||
        // void ReleaseLockOnDocument(appSettings.UserId, int issueID);
 | 
			
		||||
        // int ReSubmitDocument(int issueID, appSettings.UserId, int documentType, out int allowedITAR, string descriptionOfChange, string reasonForChange, string ecnTypeString, out int newECNNumber, int categoryId);
 | 
			
		||||
        // void SaveAfterSubmitByApprover(int ecnNumber, string implementationDetails);
 | 
			
		||||
        // void SetToExecutionStep(int ecnNumber, int userid, int documentType, string ecnTypeString);
 | 
			
		||||
        // int SubmitDocument(int issueID, int userID, int documentType, out int allowedITAR);
 | 
			
		||||
        // int SubmitForCancellation(int issueID, byte currentStep, int userID, int documentType, string ecnType, int TECNOperationType);
 | 
			
		||||
        // int SubmitTECNExtensionDocument(int issueID, int userID, int documentType, DateTime extensionDate);
 | 
			
		||||
        // void SetToExecutionStep(int ecnNumber, appSettings.UserId, int documentType, string ecnTypeString);
 | 
			
		||||
        // int SubmitDocument(int issueID, appSettings.UserId, int documentType, out int allowedITAR);
 | 
			
		||||
        // int SubmitForCancellation(int issueID, byte currentStep, appSettings.UserId, int documentType, string ecnType, int TECNOperationType);
 | 
			
		||||
        // int SubmitTECNExtensionDocument(int issueID, appSettings.UserId, int documentType, DateTime extensionDate);
 | 
			
		||||
        // void TECNExtensionLog(int ecnNumber, DateTime extensionDate);
 | 
			
		||||
        // void UpdateECNType(int ecnNumber, string ecnType);
 | 
			
		||||
        if (ecnDMO is null) { }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										120
									
								
								Fab2ApprovalTests/DMO/EngineeringChangeNoticeDMOTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								Fab2ApprovalTests/DMO/EngineeringChangeNoticeDMOTests.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,120 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
 | 
			
		||||
using Fab2ApprovalSystem.DMO;
 | 
			
		||||
using Fab2ApprovalSystem.Models;
 | 
			
		||||
using Fab2ApprovalSystem.ViewModels;
 | 
			
		||||
 | 
			
		||||
using Microsoft.AspNetCore.Mvc.Testing;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
 | 
			
		||||
namespace Fab2ApprovalTests.DMO;
 | 
			
		||||
 | 
			
		||||
[TestClass]
 | 
			
		||||
public class EngineeringChangeNoticeDMOTests {
 | 
			
		||||
 | 
			
		||||
#pragma warning disable CS8618
 | 
			
		||||
 | 
			
		||||
    private static ILogger? _Logger;
 | 
			
		||||
    private static TestContext _TestContext;
 | 
			
		||||
    private static WebApplicationFactory<Fab2ApprovalMKLink.Program> _WebApplicationFactory;
 | 
			
		||||
 | 
			
		||||
#pragma warning restore
 | 
			
		||||
 | 
			
		||||
    public static void SetGlobalVars(ILogger? logger, AppSettings appSettings) {
 | 
			
		||||
        logger?.LogDebug("Starting to set Fab2ApprovalSystem.Misc.GlobalVars");
 | 
			
		||||
        Fab2ApprovalSystem.Misc.GlobalVars.AppSettings = appSettings;
 | 
			
		||||
        Fab2ApprovalSystem.Misc.GlobalVars.AttachmentUrl = appSettings.AttachmentUrl is null ? string.Empty : appSettings.AttachmentUrl;
 | 
			
		||||
        Fab2ApprovalSystem.Misc.GlobalVars.CA_BlankFormsLocation = appSettings.CABlankFormsLocation;
 | 
			
		||||
        Fab2ApprovalSystem.Misc.GlobalVars.DBConnection = appSettings.DBConnection;
 | 
			
		||||
        Fab2ApprovalSystem.Misc.GlobalVars.DB_CONNECTION_STRING = appSettings.DBConnectionString;
 | 
			
		||||
        Fab2ApprovalSystem.Misc.GlobalVars.hostURL = appSettings.HostURL;
 | 
			
		||||
        Fab2ApprovalSystem.Misc.GlobalVars.IS_INFINEON_DOMAIN = appSettings.IsInfineonDomain;
 | 
			
		||||
        Fab2ApprovalSystem.Misc.GlobalVars.MesaTemplateFiles = appSettings.MesaTemplateFiles;
 | 
			
		||||
        Fab2ApprovalSystem.Misc.GlobalVars.NDriveURL = appSettings.NDriveURL;
 | 
			
		||||
        Fab2ApprovalSystem.Misc.GlobalVars.SENDER_EMAIL = appSettings.SenderEmail;
 | 
			
		||||
        Fab2ApprovalSystem.Misc.GlobalVars.USER_ID = appSettings.UserId;
 | 
			
		||||
        Fab2ApprovalSystem.Misc.GlobalVars.USER_ISADMIN = appSettings.UserIsAdmin;
 | 
			
		||||
        Fab2ApprovalSystem.Misc.GlobalVars.WSR_URL = appSettings.WSR_URL;
 | 
			
		||||
        logger?.LogDebug("Finished setting Fab2ApprovalSystem.Misc.GlobalVars");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    [ClassInitialize]
 | 
			
		||||
    public static void ClassInitAsync(TestContext testContext) {
 | 
			
		||||
        _TestContext = testContext;
 | 
			
		||||
        _WebApplicationFactory = new WebApplicationFactory<Fab2ApprovalMKLink.Program>();
 | 
			
		||||
        IServiceProvider serviceProvider = _WebApplicationFactory.Services.CreateScope().ServiceProvider;
 | 
			
		||||
        _Logger = serviceProvider.GetRequiredService<ILogger<Fab2ApprovalMKLink.Program>>();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void NonThrowTryCatch() {
 | 
			
		||||
        try { throw new Exception(); } catch (Exception) { }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void EngineeringChangeNoticeDMO(ILogger? logger, AppSettings appSettings, int maxDays, int ecnNumber) {
 | 
			
		||||
#pragma warning disable IDE0059
 | 
			
		||||
        SetGlobalVars(logger, appSettings);
 | 
			
		||||
        ECN_DMO ecnDMO = new();
 | 
			
		||||
        ECN ecn = ecnDMO.GetECN(ecnNumber);
 | 
			
		||||
        // void CancelECN(int? ecnNumber);
 | 
			
		||||
        bool canSubmitECN = ecnDMO.CanSubmitECN(ecnNumber);
 | 
			
		||||
        // void DeleteDocument(int ecnNumber, appSettings.UserId, string ecnTypeString);
 | 
			
		||||
        // void DeleteECNAttachment(int attachmentID);
 | 
			
		||||
        // bool ECNApproveCancelled_ExpiredDocument(int issueID, byte step, string comments, out bool lastStep, appSettings.UserId, int documentType);
 | 
			
		||||
        // void ECNResetTECNAtRejection(int ecnNumber, appSettings.UserId, int docType);
 | 
			
		||||
        IssuesViewModel[] issuesViewModels = ecnDMO.GetAllTECNs().ToArray();
 | 
			
		||||
        ApprovalLogHistory[] approvalLogHistories = ecnDMO.GetECNApprovalLogHistory(ecnNumber).ToArray();
 | 
			
		||||
        ECNAttachment[] eCNAttachments = ecnDMO.GetECNAttachments(ecnNumber).ToArray();
 | 
			
		||||
        IssuesViewModel[] issuesViewModelsB = ecnDMO.GetECN_TECNPendingApprovals(appSettings.UserId).ToArray();
 | 
			
		||||
        // string GetFileName(string attachmentID);
 | 
			
		||||
        IssuesViewModel[] issuesViewModelsC = ecnDMO.GetMyConvertedTECNsToECNs(appSettings.UserId, maxDays).ToArray();
 | 
			
		||||
        IssuesViewModel[] issuesViewModelsD = ecnDMO.GetMyExpiredTECNs(appSettings.UserId, maxDays).ToArray();
 | 
			
		||||
        IssuesViewModel[] issuesViewModelsE = ecnDMO.GetMyExpiringTECNs(appSettings.UserId, maxDays).ToArray();
 | 
			
		||||
        // List<string> GetRejectionOrginatorEmailList(int ecnNumber);
 | 
			
		||||
        int[] ints = ecnDMO.GetTECNNotificationUsers().ToArray();
 | 
			
		||||
        // void InsertECNAttachment(ECNAttachment attach);
 | 
			
		||||
        // int PCRBExists(int pcrb);
 | 
			
		||||
        // void ReassignOriginatorECN(int ecnNumber, int newOriginatorID, string comments, appSettings.UserId);
 | 
			
		||||
        // void ReleaseLockOnDocument(appSettings.UserId, int issueID);
 | 
			
		||||
        // int ReSubmitDocument(int issueID, appSettings.UserId, int documentType, out int allowedITAR, string descriptionOfChange, string reasonForChange, string ecnTypeString, out int newECNNumber, int categoryId);
 | 
			
		||||
        // void SaveAfterSubmitByApprover(int ecnNumber, string implementationDetails);
 | 
			
		||||
        // void SetToExecutionStep(int ecnNumber, appSettings.UserId, int documentType, string ecnTypeString);
 | 
			
		||||
        // int SubmitDocument(int issueID, appSettings.UserId, int documentType, out int allowedITAR);
 | 
			
		||||
        // int SubmitForCancellation(int issueID, byte currentStep, appSettings.UserId, int documentType, string ecnType, int TECNOperationType);
 | 
			
		||||
        // 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
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#if Release
 | 
			
		||||
    [Ignore]
 | 
			
		||||
#endif
 | 
			
		||||
    [TestMethod]
 | 
			
		||||
    [DataRow(1, 82700)]
 | 
			
		||||
    public void EngineeringChangeNoticeIsAttachedOnlyDMO(int maxDays, int ecnNumber) {
 | 
			
		||||
        _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)
 | 
			
		||||
            EngineeringChangeNoticeDMO(_Logger, appSettings, maxDays, ecnNumber);
 | 
			
		||||
        _Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
 | 
			
		||||
        NonThrowTryCatch();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -55,9 +55,9 @@ public class LotDispositionDMOTests {
 | 
			
		||||
    private static void LotDispositionDMO(ILogger? logger, AppSettings appSettings) {
 | 
			
		||||
#pragma warning disable IDE0059
 | 
			
		||||
        SetGlobalVars(logger, appSettings);
 | 
			
		||||
        LotDispositionDMO lotDispositionDMO = new(appSettings);
 | 
			
		||||
        LotDispositionDMO lotDispositionDMO = new();
 | 
			
		||||
        // void DeleteAllLotDispoLot(int issueID);
 | 
			
		||||
        // void DeleteCADocument(int CANo, int userID, string caTypeString);
 | 
			
		||||
        // void DeleteCADocument(int CANo, appSettings.UserId, string caTypeString);
 | 
			
		||||
        // void DeleteLotDispoAttachment(int attachmentID);
 | 
			
		||||
        // void DeleteLotDispoLot(int lotID);
 | 
			
		||||
        AuditList[] auditLists = lotDispositionDMO.GetAuditList(appSettings.UserId).ToArray();
 | 
			
		||||
@ -68,8 +68,8 @@ public class LotDispositionDMOTests {
 | 
			
		||||
        IssuesViewModel[] issuesViewModelsB = lotDispositionDMO.GetECNList(appSettings.UserId).ToArray();
 | 
			
		||||
        // string GetFileName(string attachmentID);
 | 
			
		||||
        // Attachment[] GetLotDispoAttachments(int issueID);
 | 
			
		||||
        // LotDisposition GetLotDispositionItem(int issueID, out int isITAR, int userID);
 | 
			
		||||
        // LotDisposition GetLotDispositionItemForRead(int issueID, out int isITAR, int userID);
 | 
			
		||||
        // LotDisposition GetLotDispositionItem(int issueID, out int isITAR, appSettings.UserId);
 | 
			
		||||
        // LotDisposition GetLotDispositionItemForRead(int issueID, out int isITAR, appSettings.UserId);
 | 
			
		||||
        IssuesViewModel[] issuesViewModelsC = lotDispositionDMO.GetLotDispositionList(appSettings.UserId).ToArray();
 | 
			
		||||
        // Lot[] GetLotDispositionLots(int issueID);
 | 
			
		||||
        // LotDispositionLotSummaryViewModel GetLotDispositionLotSummary(int issueID);
 | 
			
		||||
@ -91,9 +91,9 @@ public class LotDispositionDMOTests {
 | 
			
		||||
        // int InsertLot(Lot lot, bool getLotInfo);
 | 
			
		||||
        // LotDisposition InsertLotDisposition(LotDisposition lotDispo);
 | 
			
		||||
        // void InsertLotDispositionAttachment(Attachment attach);
 | 
			
		||||
        // void ReleaseLockOnDocument(int userID, int issueID);
 | 
			
		||||
        // void ReleaseLockOnDocument(appSettings.UserId, int issueID);
 | 
			
		||||
        // Lot[] SearchLots(string searchText);
 | 
			
		||||
        // int SubmitDocument(int issueID, bool peRequired, bool mrbRequired, int userID);
 | 
			
		||||
        // int SubmitDocument(int issueID, bool peRequired, bool mrbRequired, appSettings.UserId);
 | 
			
		||||
        // void UpdateLotDispoLot(Lot lot);
 | 
			
		||||
        // void UpdateLotDisposition(LotDisposition lotDispo);
 | 
			
		||||
        // void UpdateLotScrapReleaseStatus(ScrapLot scrap);
 | 
			
		||||
 | 
			
		||||
@ -53,17 +53,17 @@ public class LotTravelerDMOTests {
 | 
			
		||||
    private static void LotTravelerDMO(ILogger? logger, AppSettings appSettings) {
 | 
			
		||||
#pragma warning disable IDE0059
 | 
			
		||||
        SetGlobalVars(logger, appSettings);
 | 
			
		||||
        LotTravelerDMO lotTravelerDMO = new(appSettings);
 | 
			
		||||
        LotTravelerDMO lotTravelerDMO = new();
 | 
			
		||||
        // int CanAddLocationOperation(LTLotTravelerHoldSteps model);
 | 
			
		||||
        // int CreateLotTravelerRevision(LTLotTravelerHoldSteps model, int userID);
 | 
			
		||||
        // void CreateTraveler(int ltLotID, int workRequestID, int UserID);
 | 
			
		||||
        // int CreateWorkRequestRevision(LTWorkRequest data, int userID);
 | 
			
		||||
        // int CreateLotTravelerRevision(LTLotTravelerHoldSteps model, appSettings.UserId);
 | 
			
		||||
        // void CreateTraveler(int ltLotID, int workRequestID, appSettings.UserId);
 | 
			
		||||
        // int CreateWorkRequestRevision(LTWorkRequest data, appSettings.UserId);
 | 
			
		||||
        // void DeleteLot(int ltLotID);
 | 
			
		||||
        // IEnumerable<LTLot> GetLotList(int workRequestID);
 | 
			
		||||
        // IEnumerable<LTLot> GetLotListBasedOnSWRNumber(int swrNumber);
 | 
			
		||||
        // IEnumerable<LotWithTraveler> GetLotsWithTraveler(int workRequestID);
 | 
			
		||||
        // LTLotTravelerHeaderViewModel GetLotTravelerHeaderForReadOnly(int ltLotID, int revisionNumber);
 | 
			
		||||
        // LTLotTravelerHeaderViewModel GetLotTravelerHeaderForUpdate(int ltLotID, int UserID);
 | 
			
		||||
        // LTLotTravelerHeaderViewModel GetLotTravelerHeaderForUpdate(int ltLotID, appSettings.UserId);
 | 
			
		||||
        // IEnumerable<LTLotTravelerHoldSteps> GetLotTravelerHolStepsByRevision(int ltLotID, int revisionNumber);
 | 
			
		||||
        // IEnumerable<RevisionHistory> GetLotTravelerRevisionHistory(int lotID);
 | 
			
		||||
        // IEnumerable<LTLotTravelerHoldSteps> GetLotTravHoldSteps(int ltLotID);
 | 
			
		||||
@ -76,15 +76,15 @@ public class LotTravelerDMOTests {
 | 
			
		||||
        // IEnumerable<RevisionHistory> GetWorkReqRevisionHistory(int swrNumber);
 | 
			
		||||
        // List<Revision> GetWorkReqRevisions(int swrNumber);
 | 
			
		||||
        // void InsertLot(LTLot lot);
 | 
			
		||||
        // int InsertLotTravelerHoldStep(LTLotTravelerHoldSteps model, int userID);
 | 
			
		||||
        // void ReassignOriginator(int workRequestID, int newOriginatorID, string comments, int userID);
 | 
			
		||||
        // void ReleaseLockOnDocument(int userID, int workRequestID);
 | 
			
		||||
        // void ReleaseLockOnLotTravelerUpdateDoc(int userID, int ltLotID);
 | 
			
		||||
        // int InsertLotTravelerHoldStep(LTLotTravelerHoldSteps model, appSettings.UserId);
 | 
			
		||||
        // void ReassignOriginator(int workRequestID, int newOriginatorID, string comments, appSettings.UserId);
 | 
			
		||||
        // void ReleaseLockOnDocument(appSettings.UserId, int workRequestID);
 | 
			
		||||
        // void ReleaseLockOnLotTravelerUpdateDoc(appSettings.UserId, int ltLotID);
 | 
			
		||||
        // void RestoreLotTravToPrevRevision(int prevLotTravRevID, int newLotTravRevID);
 | 
			
		||||
        // int SubmitDocument(int workRequestID, int userID, int documentType, out int allowedITAR);
 | 
			
		||||
        // int UpdateLotTravelerHoldStep(LTLotTravelerHoldSteps model, int userID);
 | 
			
		||||
        // void UpdateLotTravlerExecution(int lotTravHoldStepID, string taskComments, bool CompletedFlag, int userID);
 | 
			
		||||
        // int UpdateRevisedLotTravelerHoldStep(LTLotTravelerHoldSteps model, int userID);
 | 
			
		||||
        // int SubmitDocument(int workRequestID, appSettings.UserId, int documentType, out int allowedITAR);
 | 
			
		||||
        // int UpdateLotTravelerHoldStep(LTLotTravelerHoldSteps model, appSettings.UserId);
 | 
			
		||||
        // void UpdateLotTravlerExecution(int lotTravHoldStepID, string taskComments, bool CompletedFlag, appSettings.UserId);
 | 
			
		||||
        // int UpdateRevisedLotTravelerHoldStep(LTLotTravelerHoldSteps model, appSettings.UserId);
 | 
			
		||||
        if (lotTravelerDMO is null) { }
 | 
			
		||||
#pragma warning restore IDE0059
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -54,9 +54,9 @@ public class PartsRequestDMOTests {
 | 
			
		||||
    private static void PartsRequestDMO(ILogger? logger, AppSettings appSettings) {
 | 
			
		||||
#pragma warning disable IDE0059
 | 
			
		||||
        SetGlobalVars(logger, appSettings);
 | 
			
		||||
        PartsRequestDMO partsRequestDMO = new(appSettings);
 | 
			
		||||
        PartsRequestDMO partsRequestDMO = new();
 | 
			
		||||
        // void DeleteAttachment(int attachmentID);
 | 
			
		||||
        // void DeleteDocument(int prNumber, int userid);
 | 
			
		||||
        // void DeleteDocument(int prNumber, appSettings.UserId);
 | 
			
		||||
        // PartsRequest Get(int PRNumber);
 | 
			
		||||
        // IEnumerable<ApprovalLogHistory> GetApprovalLogHistory(int prNumber);
 | 
			
		||||
        // IEnumerable<PartsRequestAttachmentList> GetAttachments(int prNumber);
 | 
			
		||||
@ -65,7 +65,7 @@ public class PartsRequestDMOTests {
 | 
			
		||||
        PartsRequestList[] partsRequestLists = partsRequestDMO.GetPartsRequestList().ToArray();
 | 
			
		||||
        // void Insert(PartsRequest pr);
 | 
			
		||||
        // void InsertAttachment(PartsRequestAttachment attach);
 | 
			
		||||
        // void Submit(int prNumber, int userID);
 | 
			
		||||
        // void Submit(int prNumber, appSettings.UserId);
 | 
			
		||||
        // void Update(PartsRequest pr);
 | 
			
		||||
        if (partsRequestDMO is null) { }
 | 
			
		||||
#pragma warning restore IDE0059
 | 
			
		||||
 | 
			
		||||
@ -60,8 +60,8 @@ public class TrainingDMOTests {
 | 
			
		||||
        // bool CheckTrainingStatus(int trainingAssignmentID);
 | 
			
		||||
        // bool CheckValidDocAck(int docAckId);
 | 
			
		||||
        // int Create(int issueId);
 | 
			
		||||
        // int CreateAssignment(int trainingId, int userId);
 | 
			
		||||
        // void DeleteAssignmentByUserId(int userId);
 | 
			
		||||
        // int CreateAssignment(int trainingId, appSettings.UserId);
 | 
			
		||||
        // void DeleteAssignmentByUserId(appSettings.UserId);
 | 
			
		||||
        // void DeleteTraining(int trainingId);
 | 
			
		||||
        // void DeleteTrainingAssignment(int trainingAssignmentId);
 | 
			
		||||
        // void DeleteTrainingDocAck(int trainingAssignmentId);
 | 
			
		||||
@ -75,15 +75,15 @@ public class TrainingDMOTests {
 | 
			
		||||
        // List<int> GetTrainees(int groupId);
 | 
			
		||||
        // Training GetTraining(int trainingId);
 | 
			
		||||
        // List<TrainingAssignment> GetTrainingAssignments(int TrainingID);
 | 
			
		||||
        // List<TrainingAssignment> GetTrainingAssignmentsByUser(int TrainingID, int userID);
 | 
			
		||||
        // List<TrainingAssignment> GetTrainingAssignmentsByUserID(int userID);
 | 
			
		||||
        // List<TrainingAssignment> GetTrainingAssignmentsByUser(int TrainingID, appSettings.UserId);
 | 
			
		||||
        // List<TrainingAssignment> GetTrainingAssignmentsByUserID(appSettings.UserId);
 | 
			
		||||
        // TrainingGroup GetTrainingGroupByID(int groupId);
 | 
			
		||||
        // TrainingGroup[] trainingGroups = trainingDMO.GetTrainingGroups().ToArray();
 | 
			
		||||
        // int GetTrainingId(int issueId);
 | 
			
		||||
        // int GetTrainingIdByAssignment(int trainingAssignmentID);
 | 
			
		||||
        // Training[] trainingsC = trainingDMO.GetTrainings().ToArray();
 | 
			
		||||
        // bool IsUserAssigned(int userId, int trainingId);
 | 
			
		||||
        // bool isUserTrainingMember(int groupId, int userId);
 | 
			
		||||
        // bool IsUserAssigned(appSettings.UserId, int trainingId);
 | 
			
		||||
        // bool isUserTrainingMember(int groupId, appSettings.UserId);
 | 
			
		||||
        // void reOpenTraining(int trainingId);
 | 
			
		||||
        // void SetTrainingFlag(int ECNNumber);
 | 
			
		||||
        // void UpdateAssignmentStatus(int trainingAssignmentID);
 | 
			
		||||
 | 
			
		||||
@ -50,22 +50,25 @@ public class WorkflowDMOTests {
 | 
			
		||||
        try { throw new Exception(); } catch (Exception) { }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void WorkflowDMO(ILogger? logger, AppSettings appSettings) {
 | 
			
		||||
    private static void WorkflowDMO(ILogger? logger, AppSettings appSettings, int issueID, string comments, int documentType) {
 | 
			
		||||
#pragma warning disable IDE0059
 | 
			
		||||
        bool isLastStep;
 | 
			
		||||
        SetGlobalVars(logger, appSettings);
 | 
			
		||||
        ECN_DMO ecnDMO = new();
 | 
			
		||||
        ECN ecn = ecnDMO.GetECN(issueID);
 | 
			
		||||
        WorkflowDMO workflowDMO = new();        
 | 
			
		||||
        // string AddAdditionalApproval(int issueID, string userIDs, byte step, int documentType);
 | 
			
		||||
        // string AddEECNApproval(int ecnNumber, byte step, int documentType, string engUserIDs, string opUserIDs);
 | 
			
		||||
        // bool Approve(int issueID, byte step, string comments, out bool lastStep, int userID, int documentType, int workFlowNumber);
 | 
			
		||||
        bool check = workflowDMO.Approve(appSettings, issueID, ecn.CurrentStep, comments, out isLastStep, appSettings.UserId, documentType, ecn.WorkFlowNumber);
 | 
			
		||||
        // string DelegateDocumentApproval(int issueID, int delegateFromUser, int delegateToUser);
 | 
			
		||||
        // string GetApproversForCancelled_ExpiredTECNDocs(int ecnNumber);
 | 
			
		||||
        // string GetSubRoleItems(int issueID, int docType);
 | 
			
		||||
        // string GetSubRolesForPartsRequestNextStep(int prNumber);
 | 
			
		||||
        // WorkflowSteps GetWorkflowStep(int docTypeID, int wfNumber, int stepNumber);
 | 
			
		||||
        // string ReAssignApproval(int issueID, int assignedFromUser, int assignedToUser, byte step, int docType);
 | 
			
		||||
        // bool Recall(int issueID, byte step, string comments, int userID, int docType);
 | 
			
		||||
        // bool Reject(int issueID, byte step, string comments, int userID, int docType);
 | 
			
		||||
        // void RejectTECNExtension(int ecnNumber, byte step, string comments, int userID, int docType);
 | 
			
		||||
        // bool Recall(int issueID, byte step, string comments, appSettings.UserId, int docType);
 | 
			
		||||
        // bool Reject(int issueID, byte step, string comments, appSettings.UserId, int docType);
 | 
			
		||||
        // void RejectTECNExtension(int ecnNumber, byte step, string comments, appSettings.UserId, int docType);
 | 
			
		||||
        if (workflowDMO is null) { }
 | 
			
		||||
#pragma warning restore IDE0059
 | 
			
		||||
    }
 | 
			
		||||
@ -74,13 +77,14 @@ public class WorkflowDMOTests {
 | 
			
		||||
    [Ignore]
 | 
			
		||||
#endif
 | 
			
		||||
    [TestMethod]
 | 
			
		||||
    public void WorkflowDMOIsAttachedOnly() {
 | 
			
		||||
    [DataRow(82700, "comment", 3)]
 | 
			
		||||
    public void WorkflowDMOIsAttachedOnly(int issueID, string comments, int documentType) {
 | 
			
		||||
        _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)
 | 
			
		||||
            WorkflowDMO(_Logger, appSettings);
 | 
			
		||||
            WorkflowDMO(_Logger, appSettings, issueID, comments, documentType);
 | 
			
		||||
        _Logger?.LogInformation("{TestName} completed", _TestContext?.TestName);
 | 
			
		||||
        NonThrowTryCatch();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -102,7 +102,7 @@ public class CorrectiveActionTests {
 | 
			
		||||
    internal static void TestCorrectiveAction(ILogger? logger, AppSettings appSettings, int caNo) {
 | 
			
		||||
        SetGlobalVars(logger, appSettings);
 | 
			
		||||
        CorrectiveAction ca;
 | 
			
		||||
        CorrectiveActionDMO caDMO = new(appSettings);
 | 
			
		||||
        CorrectiveActionDMO caDMO = new();
 | 
			
		||||
        ca = caDMO.GetCAItemReadOnly(caNo, appSettings.UserId);
 | 
			
		||||
        if (ca is null)
 | 
			
		||||
            throw new Exception($"{nameof(ca)}");
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -30,4 +30,11 @@
 | 
			
		||||
        <ProjectReference Include="..\MesaFabApproval.Shared\MesaFabApproval.Shared.csproj" />
 | 
			
		||||
    </ItemGroup>
 | 
			
		||||
 | 
			
		||||
    <ItemGroup>
 | 
			
		||||
      <Content Update="wwwroot\appsettings.Development.json">
 | 
			
		||||
        <ExcludeFromSingleFile>true</ExcludeFromSingleFile>
 | 
			
		||||
        <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
 | 
			
		||||
      </Content>
 | 
			
		||||
    </ItemGroup>
 | 
			
		||||
 | 
			
		||||
</Project>
 | 
			
		||||
 | 
			
		||||
@ -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))
 | 
			
		||||
 | 
			
		||||
@ -19,6 +19,7 @@
 | 
			
		||||
                              @bind-Value="@document.DocNumbers"
 | 
			
		||||
                              @bind-Text="@document.DocNumbers"
 | 
			
		||||
                              Immediate
 | 
			
		||||
                              Required
 | 
			
		||||
                              AutoGrow
 | 
			
		||||
                              AutoFocus />
 | 
			
		||||
                @if (DocNumberIsNA()) {
 | 
			
		||||
@ -30,16 +31,16 @@
 | 
			
		||||
                                  Immediate
 | 
			
		||||
                                  AutoGrow />
 | 
			
		||||
                } else {
 | 
			
		||||
                    <MudTextField @bind-Value="@document.ECNNumber"
 | 
			
		||||
                                  Required
 | 
			
		||||
                                  RequiredError="You must provide a valid ECN#"
 | 
			
		||||
                                  Clearable
 | 
			
		||||
                                  Variant="Variant.Outlined"
 | 
			
		||||
                                  InputType="@InputType.Number"
 | 
			
		||||
                                  Validation="@(new Func<int, Task<string>>(ECNNoIsValid))"
 | 
			
		||||
                                  Label="ECN#"
 | 
			
		||||
                                  Immediate
 | 
			
		||||
                                  AutoGrow />
 | 
			
		||||
                    <MudAutocomplete @bind-Value="@document.ECNNumber"
 | 
			
		||||
                                     T="int"
 | 
			
		||||
                                     SearchFunc="Search"
 | 
			
		||||
                                     Required
 | 
			
		||||
                                     Clearable
 | 
			
		||||
                                     RequiredError="You must provide a valid ECN#"
 | 
			
		||||
                                     Variant="Variant.Outlined"
 | 
			
		||||
                                     Validation="@(new Func<int, Task<string>>(ECNNoIsValid))"
 | 
			
		||||
                                     Label="ECN#"
 | 
			
		||||
                                     Immediate />
 | 
			
		||||
                }
 | 
			
		||||
                <MudCheckBox Label="Complete"
 | 
			
		||||
                             Color="Color.Tertiary"
 | 
			
		||||
@ -49,8 +50,8 @@
 | 
			
		||||
        </MudPaper>
 | 
			
		||||
    </DialogContent>
 | 
			
		||||
    <DialogActions>
 | 
			
		||||
        @if ((DocNumberIsNA() && !string.IsNullOrWhiteSpace(document.Comment)) || 
 | 
			
		||||
             (!DocNumberIsNA() && ecnNoIsValid)) {
 | 
			
		||||
        @if (!string.IsNullOrWhiteSpace(document.DocNumbers) && ((DocNumberIsNA() && !string.IsNullOrWhiteSpace(document.Comment)) || 
 | 
			
		||||
             (!DocNumberIsNA() && ecnNoIsValid))) {
 | 
			
		||||
            <MudButton Variant="Variant.Filled"
 | 
			
		||||
                       Color="Color.Tertiary"
 | 
			
		||||
                       Class="m1-auto"
 | 
			
		||||
@ -78,6 +79,8 @@
 | 
			
		||||
    [Parameter]
 | 
			
		||||
    public required PCR3Document document { get; set; }
 | 
			
		||||
 | 
			
		||||
    private IEnumerable<int> allEcnNumbers = new List<int>();
 | 
			
		||||
 | 
			
		||||
    private string[] errors = { };
 | 
			
		||||
 | 
			
		||||
    private bool complete = false;
 | 
			
		||||
@ -88,6 +91,8 @@
 | 
			
		||||
 | 
			
		||||
    protected override async Task OnParametersSetAsync() {
 | 
			
		||||
        complete = document.CompletedByID > 0;
 | 
			
		||||
 | 
			
		||||
        allEcnNumbers = await ecnService.GetAllECNNumbers();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private async Task Save() {
 | 
			
		||||
@ -111,6 +116,10 @@
 | 
			
		||||
                document.CompletedDate = DateTime.Now;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (string.IsNullOrWhiteSpace(document.DocNumbers)) {
 | 
			
		||||
                throw new Exception("Document Numbers cannot be empty");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (!DocNumberIsNA() && !ecnNoIsValid) 
 | 
			
		||||
                throw new Exception($"{document.ECNNumber} is not a valid ECN#");
 | 
			
		||||
            if (DocNumberIsNA() && string.IsNullOrWhiteSpace(document.Comment))
 | 
			
		||||
@ -135,7 +144,11 @@
 | 
			
		||||
 | 
			
		||||
    private bool DocNumberIsNA() {
 | 
			
		||||
        if (document.DocNumbers.ToLower().Equals("na") ||
 | 
			
		||||
            document.DocNumbers.ToLower().Equals("n/a")) {
 | 
			
		||||
            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;
 | 
			
		||||
@ -148,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"
 | 
			
		||||
@ -0,0 +1,4 @@
 | 
			
		||||
{
 | 
			
		||||
  "OldFabApprovalUrl": "https://mesaapproval-test.mes.infineon.com",
 | 
			
		||||
  "FabApprovalApiBaseUrl": "https://mesaapproval-test.mes.infineon.com:7114"
 | 
			
		||||
}
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
{
 | 
			
		||||
  "OldFabApprovalUrl": "https://mesaapproval-test.mes.infineon.com",
 | 
			
		||||
  "FabApprovalApiBaseUrl": "https://mesaapproval-test.mes.infineon.com:7114"
 | 
			
		||||
  "OldFabApprovalUrl": "https://mesaapproval.mes.infineon.com",
 | 
			
		||||
  "FabApprovalApiBaseUrl": "https://mesaapproval.mes.infineon.com:7114"
 | 
			
		||||
}
 | 
			
		||||
@ -6,7 +6,7 @@ public class PCR3Document {
 | 
			
		||||
    public int ID { get; set; }
 | 
			
		||||
    public required int PlanNumber { get; set; }
 | 
			
		||||
    public required string DocType { get; set; }
 | 
			
		||||
    public string DocNumbers { get; set; } = "N/A";
 | 
			
		||||
    public string DocNumbers { get; set; } = string.Empty;
 | 
			
		||||
    public DateTime CompletedDate { get; set; } = DateTimeUtilities.MAX_DT;
 | 
			
		||||
    public int CompletedByID { get; set; } = 0;
 | 
			
		||||
    public User? CompletedBy { get; set; }
 | 
			
		||||
 | 
			
		||||
@ -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,16 +0,0 @@
 | 
			
		||||
USE [FabApprovalSystem]
 | 
			
		||||
GO
 | 
			
		||||
  /****** Object:  UserDefinedFunction [dbo].[EncodeHtml]    Script Date: 11/21/2024 11:31:55 AM ******/
 | 
			
		||||
SET
 | 
			
		||||
  ANSI_NULLS ON
 | 
			
		||||
GO
 | 
			
		||||
SET
 | 
			
		||||
  QUOTED_IDENTIFIER ON
 | 
			
		||||
GO
 | 
			
		||||
  CREATE FUNCTION [dbo].[EncodeHtml] (@RawStr varchar(max)) RETURNS varchar(max) AS BEGIN RETURN REPLACE(
 | 
			
		||||
    REPLACE(REPLACE(@RawStr, '&', '&'), '<', '<'),
 | 
			
		||||
    '>',
 | 
			
		||||
    '>'
 | 
			
		||||
  )
 | 
			
		||||
END
 | 
			
		||||
GO
 | 
			
		||||
@ -1,33 +0,0 @@
 | 
			
		||||
USE [FabApprovalSystem]
 | 
			
		||||
GO
 | 
			
		||||
	/****** Object:  UserDefinedFunction [dbo].[fn8DConvertCANoToCADisplayFormat]    Script Date: 11/21/2024 11:31:55 AM ******/
 | 
			
		||||
SET
 | 
			
		||||
	ANSI_NULLS ON
 | 
			
		||||
GO
 | 
			
		||||
SET
 | 
			
		||||
	QUOTED_IDENTIFIER ON
 | 
			
		||||
GO
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	-- Author:		<Author,,Name>
 | 
			
		||||
	-- Create date: <Create Date, ,>
 | 
			
		||||
	-- Description:	<Description, ,>
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	CREATE FUNCTION [dbo].[fn8DConvertCANoToCADisplayFormat] (
 | 
			
		||||
		-- Add the parameters for the function here
 | 
			
		||||
		@CANo INT
 | 
			
		||||
	) RETURNS VARCHAR(10) AS BEGIN -- Declare the return variable here
 | 
			
		||||
	DECLARE @CADisplay VARCHAR(10) -- Add the T-SQL statements to compute the return value here
 | 
			
		||||
SET
 | 
			
		||||
	@CADisplay = LTRIM(
 | 
			
		||||
		RTRIM(
 | 
			
		||||
			CAST(
 | 
			
		||||
				'C' + RIGHT(
 | 
			
		||||
					'00000' + ISNULL(CAST(@CANo AS VARCHAR(10)), ''),
 | 
			
		||||
					5
 | 
			
		||||
				) AS VARCHAR(50)
 | 
			
		||||
			)
 | 
			
		||||
		)
 | 
			
		||||
	) -- Return the result of the function
 | 
			
		||||
	RETURN @CADisplay
 | 
			
		||||
END
 | 
			
		||||
GO
 | 
			
		||||
@ -1,28 +0,0 @@
 | 
			
		||||
USE [FabApprovalSystem]
 | 
			
		||||
GO
 | 
			
		||||
	/****** Object:  UserDefinedFunction [dbo].[fnAuditConvertAuditNoToDisplayFormat]    Script Date: 11/21/2024 11:31:55 AM ******/
 | 
			
		||||
SET
 | 
			
		||||
	ANSI_NULLS ON
 | 
			
		||||
GO
 | 
			
		||||
SET
 | 
			
		||||
	QUOTED_IDENTIFIER ON
 | 
			
		||||
GO
 | 
			
		||||
	CREATE FUNCTION [dbo].[fnAuditConvertAuditNoToDisplayFormat] (
 | 
			
		||||
		-- Add the parameters for the function here
 | 
			
		||||
		@AuditNo INT
 | 
			
		||||
	) RETURNS VARCHAR(10) AS BEGIN -- Declare the return variable here
 | 
			
		||||
	DECLARE @Display VARCHAR(10) -- Add the T-SQL statements to compute the return value here
 | 
			
		||||
SET
 | 
			
		||||
	@Display = LTRIM(
 | 
			
		||||
		RTRIM(
 | 
			
		||||
			CAST(
 | 
			
		||||
				'A' + RIGHT(
 | 
			
		||||
					'00000' + ISNULL(CAST(@AuditNo AS VARCHAR(10)), ''),
 | 
			
		||||
					5
 | 
			
		||||
				) AS VARCHAR(50)
 | 
			
		||||
			)
 | 
			
		||||
		)
 | 
			
		||||
	) -- Return the result of the function
 | 
			
		||||
	RETURN @Display
 | 
			
		||||
END
 | 
			
		||||
GO
 | 
			
		||||
@ -1,64 +0,0 @@
 | 
			
		||||
USE [FabApprovalSystem]
 | 
			
		||||
GO
 | 
			
		||||
	/****** Object:  UserDefinedFunction [dbo].[fnGetApprovalFullNames]    Script Date: 11/21/2024 11:31:55 AM ******/
 | 
			
		||||
SET
 | 
			
		||||
	ANSI_NULLS ON
 | 
			
		||||
GO
 | 
			
		||||
SET
 | 
			
		||||
	QUOTED_IDENTIFIER ON
 | 
			
		||||
GO
 | 
			
		||||
	CREATE FUNCTION [dbo].[fnGetApprovalFullNames] (
 | 
			
		||||
		@IssueID int,
 | 
			
		||||
		@DocumentTypeID int,
 | 
			
		||||
		@Separator varchar(10),
 | 
			
		||||
		@IncludeRole bit,
 | 
			
		||||
		@IncludeSubRole bit,
 | 
			
		||||
		@IncludePending bit,
 | 
			
		||||
		@IncludeApproved bit,
 | 
			
		||||
		@IncludeOthers bit
 | 
			
		||||
	) RETURNS varchar(max) AS BEGIN DECLARE @r varchar(max) DECLARE @t TABLE(u varchar(200))
 | 
			
		||||
INSERT INTO
 | 
			
		||||
	@t
 | 
			
		||||
SELECT
 | 
			
		||||
	@Separator + ISNULL(U.FirstName, '') + ' ' + ISNULL(U.LastName, '') + CASE
 | 
			
		||||
		WHEN @IncludeRole <> 0 THEN ' (' + A.RoleName + ')'
 | 
			
		||||
		ELSE ''
 | 
			
		||||
	END + CASE
 | 
			
		||||
		WHEN @IncludeSubRole <> 0 THEN ' (' + A.SubRole + ')'
 | 
			
		||||
		ELSE ''
 | 
			
		||||
	END
 | 
			
		||||
FROM
 | 
			
		||||
	Approval A
 | 
			
		||||
	LEFT OUTER JOIN Users U ON A.UserID = U.UserID
 | 
			
		||||
WHERE
 | 
			
		||||
	A.IssueID = @IssueID
 | 
			
		||||
	AND A.DocumentTypeID = @DocumentTypeID
 | 
			
		||||
	AND (
 | 
			
		||||
		(
 | 
			
		||||
			@IncludeOthers <> 0
 | 
			
		||||
			AND A.ItemStatus NOT IN (0, 1)
 | 
			
		||||
		)
 | 
			
		||||
		OR (
 | 
			
		||||
			@IncludePending <> 0
 | 
			
		||||
			AND A.ItemStatus = 0
 | 
			
		||||
		)
 | 
			
		||||
		OR (
 | 
			
		||||
			@IncludeApproved <> 0
 | 
			
		||||
			AND A.ItemStatus = 1
 | 
			
		||||
		)
 | 
			
		||||
	)
 | 
			
		||||
ORDER BY
 | 
			
		||||
	A.Step,
 | 
			
		||||
	U.FirstName,
 | 
			
		||||
	U.LastName
 | 
			
		||||
SELECT
 | 
			
		||||
	@r = (
 | 
			
		||||
		SELECT
 | 
			
		||||
			u + ''
 | 
			
		||||
		FROM
 | 
			
		||||
			@t FOR XML PATH('')
 | 
			
		||||
	) IF @r <> ''
 | 
			
		||||
SET
 | 
			
		||||
	@r = STUFF(@r, 1, LEN(@Separator), '') RETURN @r
 | 
			
		||||
END
 | 
			
		||||
GO
 | 
			
		||||
@ -1,24 +0,0 @@
 | 
			
		||||
USE [FabApprovalSystem]
 | 
			
		||||
GO
 | 
			
		||||
	/****** Object:  UserDefinedFunction [dbo].[fnGetITARUsers]    Script Date: 11/21/2024 11:31:55 AM ******/
 | 
			
		||||
SET
 | 
			
		||||
	ANSI_NULLS ON
 | 
			
		||||
GO
 | 
			
		||||
SET
 | 
			
		||||
	QUOTED_IDENTIFIER ON
 | 
			
		||||
GO
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	-- Author:		<Author,,Name>
 | 
			
		||||
	-- Create date: <Create Date,,>
 | 
			
		||||
	-- Description:	<Description,,>
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	CREATE FUNCTION [dbo].[fnGetITARUsers] () RETURNS TABLE AS RETURN (
 | 
			
		||||
		SELECT
 | 
			
		||||
			UserID,
 | 
			
		||||
			HasITARAccess
 | 
			
		||||
		FROM
 | 
			
		||||
			SAMUsers
 | 
			
		||||
		WHERE
 | 
			
		||||
			HasITARAccess = 1
 | 
			
		||||
	)
 | 
			
		||||
GO
 | 
			
		||||
@ -1,33 +0,0 @@
 | 
			
		||||
USE [FabApprovalSystem]
 | 
			
		||||
GO
 | 
			
		||||
	/****** Object:  UserDefinedFunction [dbo].[fnGetLotCount_Fab]    Script Date: 11/21/2024 11:31:55 AM ******/
 | 
			
		||||
SET
 | 
			
		||||
	ANSI_NULLS ON
 | 
			
		||||
GO
 | 
			
		||||
SET
 | 
			
		||||
	QUOTED_IDENTIFIER ON
 | 
			
		||||
GO
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	-- Author:		<Author,,Name>
 | 
			
		||||
	-- Create date: <Create Date, ,>
 | 
			
		||||
	-- Description:	<Description, ,>
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	CREATE FUNCTION [dbo].[fnGetLotCount_Fab] (
 | 
			
		||||
		-- Add the parameters for the function here
 | 
			
		||||
		@IssueID INT
 | 
			
		||||
	) RETURNS FLOAT AS BEGIN DECLARE @FabCount INT -- Declare the return variable here
 | 
			
		||||
SET
 | 
			
		||||
	@FabCount = 0
 | 
			
		||||
SET
 | 
			
		||||
	@FabCount = (
 | 
			
		||||
		SELECT
 | 
			
		||||
			COUNT(*)
 | 
			
		||||
		FROM
 | 
			
		||||
			Lot L
 | 
			
		||||
		WHERE
 | 
			
		||||
			L.IssueID = @IssueID
 | 
			
		||||
			AND L.Location NOT IN ('6300', '6400 ', '6600', 'QDB')
 | 
			
		||||
	) -- Return the result of the function
 | 
			
		||||
	RETURN @FabCount
 | 
			
		||||
END
 | 
			
		||||
GO
 | 
			
		||||
@ -1,33 +0,0 @@
 | 
			
		||||
USE [FabApprovalSystem]
 | 
			
		||||
GO
 | 
			
		||||
	/****** Object:  UserDefinedFunction [dbo].[fnGetLotCount_Probe]    Script Date: 11/21/2024 11:31:55 AM ******/
 | 
			
		||||
SET
 | 
			
		||||
	ANSI_NULLS ON
 | 
			
		||||
GO
 | 
			
		||||
SET
 | 
			
		||||
	QUOTED_IDENTIFIER ON
 | 
			
		||||
GO
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	-- Author:		<Author,,Name>
 | 
			
		||||
	-- Create date: <Create Date, ,>
 | 
			
		||||
	-- Description:	<Description, ,>
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	CREATE FUNCTION [dbo].[fnGetLotCount_Probe] (
 | 
			
		||||
		-- Add the parameters for the function here
 | 
			
		||||
		@IssueID INT
 | 
			
		||||
	) RETURNS FLOAT AS BEGIN DECLARE @ProbeCount INT -- Declare the return variable here
 | 
			
		||||
SET
 | 
			
		||||
	@ProbeCount = 0
 | 
			
		||||
SET
 | 
			
		||||
	@ProbeCount = (
 | 
			
		||||
		SELECT
 | 
			
		||||
			COUNT(*)
 | 
			
		||||
		FROM
 | 
			
		||||
			Lot L
 | 
			
		||||
		WHERE
 | 
			
		||||
			L.IssueID = @IssueID
 | 
			
		||||
			AND L.Location IN ('6300', '6400 ', '6600')
 | 
			
		||||
	) -- Return the result of the function
 | 
			
		||||
	RETURN @ProbeCount
 | 
			
		||||
END
 | 
			
		||||
GO
 | 
			
		||||
@ -1,33 +0,0 @@
 | 
			
		||||
USE [FabApprovalSystem]
 | 
			
		||||
GO
 | 
			
		||||
	/****** Object:  UserDefinedFunction [dbo].[fnGetLotCount_QDB]    Script Date: 11/21/2024 11:31:55 AM ******/
 | 
			
		||||
SET
 | 
			
		||||
	ANSI_NULLS ON
 | 
			
		||||
GO
 | 
			
		||||
SET
 | 
			
		||||
	QUOTED_IDENTIFIER ON
 | 
			
		||||
GO
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	-- Author:		<Author,,Name>
 | 
			
		||||
	-- Create date: <Create Date, ,>
 | 
			
		||||
	-- Description:	<Description, ,>
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	CREATE FUNCTION [dbo].[fnGetLotCount_QDB] (
 | 
			
		||||
		-- Add the parameters for the function here
 | 
			
		||||
		@IssueID INT
 | 
			
		||||
	) RETURNS FLOAT AS BEGIN DECLARE @QDBCount INT -- Declare the return variable here
 | 
			
		||||
SET
 | 
			
		||||
	@QDBCount = 0
 | 
			
		||||
SET
 | 
			
		||||
	@QDBCount = (
 | 
			
		||||
		SELECT
 | 
			
		||||
			COUNT(*)
 | 
			
		||||
		FROM
 | 
			
		||||
			Lot L
 | 
			
		||||
		WHERE
 | 
			
		||||
			L.IssueID = @IssueID
 | 
			
		||||
			AND L.Location = 'QDB'
 | 
			
		||||
	) -- Return the result of the function
 | 
			
		||||
	RETURN @QDBCount
 | 
			
		||||
END
 | 
			
		||||
GO
 | 
			
		||||
@ -1,37 +0,0 @@
 | 
			
		||||
USE [FabApprovalSystem]
 | 
			
		||||
GO
 | 
			
		||||
	/****** Object:  UserDefinedFunction [dbo].[fnGetLotCount_RH_MA]    Script Date: 11/21/2024 11:31:55 AM ******/
 | 
			
		||||
SET
 | 
			
		||||
	ANSI_NULLS ON
 | 
			
		||||
GO
 | 
			
		||||
SET
 | 
			
		||||
	QUOTED_IDENTIFIER ON
 | 
			
		||||
GO
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	-- Author:		<Author,,Name>
 | 
			
		||||
	-- Create date: <Create Date, ,>
 | 
			
		||||
	-- Description:	<Description, ,>
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	CREATE FUNCTION [dbo].[fnGetLotCount_RH_MA] (
 | 
			
		||||
		-- Add the parameters for the function here
 | 
			
		||||
		@IssueID INT
 | 
			
		||||
	) RETURNS FLOAT AS BEGIN DECLARE @QDBCount INT -- Declare the return variable here
 | 
			
		||||
SET
 | 
			
		||||
	@QDBCount = 0
 | 
			
		||||
SET
 | 
			
		||||
	@QDBCount = (
 | 
			
		||||
		SELECT
 | 
			
		||||
			COUNT(*)
 | 
			
		||||
		FROM
 | 
			
		||||
			LotDisposition LD
 | 
			
		||||
			INNER JOIN Lot L ON LD.IssueID = L.IssueID
 | 
			
		||||
		WHERE
 | 
			
		||||
			(
 | 
			
		||||
				L.ProductFamily = 'RH'
 | 
			
		||||
				OR L.ProductFamily = 'MA'
 | 
			
		||||
			)
 | 
			
		||||
			AND LD.IssueID = @IssueID
 | 
			
		||||
	) -- Return the result of the function
 | 
			
		||||
	RETURN @QDBCount
 | 
			
		||||
END
 | 
			
		||||
GO
 | 
			
		||||
@ -1,27 +0,0 @@
 | 
			
		||||
USE [FabApprovalSystem]
 | 
			
		||||
GO
 | 
			
		||||
	/****** Object:  UserDefinedFunction [dbo].[fnGetLot_RH]    Script Date: 11/21/2024 11:31:55 AM ******/
 | 
			
		||||
SET
 | 
			
		||||
	ANSI_NULLS ON
 | 
			
		||||
GO
 | 
			
		||||
SET
 | 
			
		||||
	QUOTED_IDENTIFIER ON
 | 
			
		||||
GO
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	-- Author:		<Author,,Name>
 | 
			
		||||
	-- Create date: <Create Date,,>
 | 
			
		||||
	-- Description:	<Description,,>
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	CREATE FUNCTION [dbo].[fnGetLot_RH] (
 | 
			
		||||
		-- Add the parameters for the function here
 | 
			
		||||
		@IssueID INT
 | 
			
		||||
	) RETURNS TABLE AS RETURN (
 | 
			
		||||
		SELECT
 | 
			
		||||
			L.IssueID
 | 
			
		||||
		FROM
 | 
			
		||||
			LotDisposition LD
 | 
			
		||||
			INNER JOIN Lot L ON LD.IssueID = L.IssueID
 | 
			
		||||
		WHERE
 | 
			
		||||
			LD.IssueID = @IssueID
 | 
			
		||||
	)
 | 
			
		||||
GO
 | 
			
		||||
@ -1,63 +0,0 @@
 | 
			
		||||
USE [FabApprovalSystem]
 | 
			
		||||
GO
 | 
			
		||||
	/****** Object:  UserDefinedFunction [dbo].[fnGetMRB_SPN_HoldLots]    Script Date: 11/21/2024 11:31:55 AM ******/
 | 
			
		||||
SET
 | 
			
		||||
	ANSI_NULLS ON
 | 
			
		||||
GO
 | 
			
		||||
SET
 | 
			
		||||
	QUOTED_IDENTIFIER ON
 | 
			
		||||
GO
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	-- Author:		<Author,,Name>
 | 
			
		||||
	-- Create date: <Create Date,,>
 | 
			
		||||
	-- Description:	<Description,,>
 | 
			
		||||
	-- =============================================
 | 
			
		||||
	CREATE FUNCTION [dbo].[fnGetMRB_SPN_HoldLots] (
 | 
			
		||||
		-- Add the parameters for the function here
 | 
			
		||||
		@MRBNumber INT
 | 
			
		||||
	) RETURNS TABLE AS RETURN (
 | 
			
		||||
		-- Add the SELECT statement with parameter references here
 | 
			
		||||
		SELECT
 | 
			
		||||
			L.LotNumber,
 | 
			
		||||
			MD.MRBNumber
 | 
			
		||||
		FROM
 | 
			
		||||
			MRBDispositionByMRB MD
 | 
			
		||||
			INNER JOIN MRBLot L ON MD.DispositionType = L.DispoType
 | 
			
		||||
			INNER JOIN MRB M ON M.MRBNumber = MD.MRBNumber
 | 
			
		||||
		WHERE
 | 
			
		||||
			CloseToQDBOptionID = 1
 | 
			
		||||
			AND L.MRBNumber = @MRBNumber
 | 
			
		||||
			AND MD.MRBNumber = @MRBNumber
 | 
			
		||||
			AND L.LotNumber + CONVERt(VARCHAR(10), MD.MRBNumber) NOT IN (
 | 
			
		||||
				SELECT
 | 
			
		||||
					LotNumber + CONVERt(VARCHAR(10), MRBNumber)
 | 
			
		||||
				FROM
 | 
			
		||||
					MRB_SPN_HoldFlagLot
 | 
			
		||||
			)
 | 
			
		||||
		UNION
 | 
			
		||||
		SELECT
 | 
			
		||||
			LotNumber,
 | 
			
		||||
			MRBNumber
 | 
			
		||||
		FROM
 | 
			
		||||
			MRB_SPN_HoldFlagLot
 | 
			
		||||
		WHERE
 | 
			
		||||
			LotNumber IN (
 | 
			
		||||
				SELECT
 | 
			
		||||
					DISTINCT L.LotNumber
 | 
			
		||||
				FROM
 | 
			
		||||
					MRBDispositionByMRB MD
 | 
			
		||||
					INNER JOIN MRBLot L ON MD.DispositionType = L.DispoType
 | 
			
		||||
					INNER JOIN MRB M ON M.MRBNumber = MD.MRBNumber
 | 
			
		||||
				WHERE
 | 
			
		||||
					CloseToQDBOptionID = 1
 | 
			
		||||
					AND L.MRBNumber = @MRBNumber
 | 
			
		||||
					AND MD.MRBNumber = @MRBNumber
 | 
			
		||||
					AND L.LotNumber + CONVERt(VARCHAR(10), MD.MRBNumber) NOT IN (
 | 
			
		||||
						SELECT
 | 
			
		||||
							LotNumber + CONVERt(VARCHAR(10), MRBNumber)
 | 
			
		||||
						FROM
 | 
			
		||||
							MRB_SPN_HoldFlagLot
 | 
			
		||||
					)
 | 
			
		||||
			)
 | 
			
		||||
	)
 | 
			
		||||
GO
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user