Compare commits
	
		
			33 Commits
		
	
	
		
			origin/Pro
			...
			ae8710e6d8
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ae8710e6d8 | |||
| cc4781b990 | |||
| 4871668a90 | |||
| 65a433e9ab | |||
| 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", |     "windowsphone", | ||||||
|     "Winsock", |     "Winsock", | ||||||
|     "worlflow" |     "worlflow" | ||||||
|   ] |   ], | ||||||
|  |   "dotnet.preferCSharpExtension": true | ||||||
| } | } | ||||||
							
								
								
									
										17
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							| @ -2,7 +2,7 @@ | |||||||
|     "version": "2.0.0", |     "version": "2.0.0", | ||||||
|     "tasks": [ |     "tasks": [ | ||||||
|         { |         { | ||||||
|             "label": "MSBuild", |             "label": "MSBuild-Debug", | ||||||
|             "command": "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe", |             "command": "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe", | ||||||
|             "type": "process", |             "type": "process", | ||||||
|             "args": [ |             "args": [ | ||||||
| @ -16,6 +16,21 @@ | |||||||
|             ], |             ], | ||||||
|             "problemMatcher": "$msCompile" |             "problemMatcher": "$msCompile" | ||||||
|         }, |         }, | ||||||
|  |         { | ||||||
|  |             "label": "MSBuild-Release", | ||||||
|  |             "command": "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe", | ||||||
|  |             "type": "process", | ||||||
|  |             "args": [ | ||||||
|  |                 "/target:Build", | ||||||
|  |                 "/restore:True", | ||||||
|  |                 "/p:RestoreSources=https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/%3Bhttps://packagemanagement.eu.infineon.com:4430/api/v2/%3Bhttps://api.nuget.org/v3/index.json", | ||||||
|  |                 "/detailedsummary", | ||||||
|  |                 "/consoleloggerparameters:PerformanceSummary;ErrorsOnly;", | ||||||
|  |                 "/property:Configuration=Release;TargetFrameworkVersion=v4.8", | ||||||
|  |                 "Fab2ApprovalSystem/Fab2ApprovalSystem.csproj" | ||||||
|  |             ], | ||||||
|  |             "problemMatcher": "$msCompile" | ||||||
|  |         }, | ||||||
|         { |         { | ||||||
|             "label": "Fab2ApprovalMKLink-User Secrets Init", |             "label": "Fab2ApprovalMKLink-User Secrets Init", | ||||||
|             "command": "dotnet", |             "command": "dotnet", | ||||||
|  | |||||||
| @ -367,6 +367,7 @@ dotnet_diagnostic.IDE0065.severity = none # Question - | |||||||
| dotnet_diagnostic.IDE0066.severity = none # Question - Use  | dotnet_diagnostic.IDE0066.severity = none # Question - Use  | ||||||
| dotnet_diagnostic.IDE0078.severity = none # Question - Use pattern matching (may change code meaning) | dotnet_diagnostic.IDE0078.severity = none # Question - Use pattern matching (may change code meaning) | ||||||
| dotnet_diagnostic.IDE0090.severity = warning # Question - Simplify new expression | dotnet_diagnostic.IDE0090.severity = warning # Question - Simplify new expression | ||||||
|  | dotnet_diagnostic.IDE0100.severity = error # Question - Remove redundant equality | ||||||
| dotnet_diagnostic.IDE0160.severity = warning # Question - Use block-scoped namespace | dotnet_diagnostic.IDE0160.severity = warning # Question - Use block-scoped namespace | ||||||
| dotnet_diagnostic.IDE0161.severity = warning # Question - Namespace declaration preferences | dotnet_diagnostic.IDE0161.severity = warning # Question - Namespace declaration preferences | ||||||
| dotnet_diagnostic.IDE0270.severity = none # Question - Null check can be simplified | dotnet_diagnostic.IDE0270.severity = none # Question - Null check can be simplified | ||||||
|  | |||||||
							
								
								
									
										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\Jobs" "L:\DevOps\Mesa_FI\MesaFabApproval\Fab2ApprovalSystem\Jobs" | ||||||
| mklink /J "L:\DevOps\Mesa_FI\MesaFabApproval\Fab2ApprovalMKLink\JobSchedules" "L:\DevOps\Mesa_FI\MesaFabApproval\Fab2ApprovalSystem\JobSchedules" | 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'"> |   <PropertyGroup Condition="'$(TargetFramework)' == 'net8.0'"> | ||||||
|     <DefineConstants>NET8</DefineConstants> |     <DefineConstants>NET8</DefineConstants> | ||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo"> | ||||||
|  |       <_Parameter1>Fab2ApprovalTests</_Parameter1> | ||||||
|  |     </AssemblyAttribute> | ||||||
|  |   </ItemGroup> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <PackageReference Include="Dapper.Contrib" Version="2.0.78" /> |     <PackageReference Include="Dapper.Contrib" Version="2.0.78" /> | ||||||
|     <PackageReference Include="Dapper" Version="2.1.44" /> |     <PackageReference Include="Dapper" Version="2.1.44" /> | ||||||
|  |     <PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" /> | ||||||
|     <PackageReference Include="EntityFramework" Version="6.5.1" /> |     <PackageReference Include="EntityFramework" Version="6.5.1" /> | ||||||
|     <PackageReference Include="ExcelDataReader" Version="3.7.0" /> |     <PackageReference Include="ExcelDataReader" Version="3.7.0" /> | ||||||
|     <PackageReference Include="jQuery" Version="3.7.1" /> |     <PackageReference Include="jQuery" Version="3.7.1" /> | ||||||
|  | |||||||
| @ -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}" | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fab2ApprovalSystem", "Fab2ApprovalSystem\Fab2ApprovalSystem.csproj", "{AAE52608-4DD1-4732-92BD-CC8915DEC71E}" | ||||||
| EndProject | EndProject | ||||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MesaFabApproval.API", "MesaFabApproval.API\MesaFabApproval.API.csproj", "{852E528D-015A-43B5-999D-F281E3359E5E}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MesaFabApproval.API", "MesaFabApproval.API\MesaFabApproval.API.csproj", "{852E528D-015A-43B5-999D-F281E3359E5E}" | ||||||
|  | 	ProjectSection(ProjectDependencies) = postProject | ||||||
|  | 		{2C16014D-B04E-46AF-AB4C-D2691D44A339} = {2C16014D-B04E-46AF-AB4C-D2691D44A339} | ||||||
|  | 	EndProjectSection | ||||||
| EndProject | EndProject | ||||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MesaFabApproval.Shared", "MesaFabApproval.Shared\MesaFabApproval.Shared.csproj", "{2C16014D-B04E-46AF-AB4C-D2691D44A339}" | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MesaFabApproval.Shared", "MesaFabApproval.Shared\MesaFabApproval.Shared.csproj", "{2C16014D-B04E-46AF-AB4C-D2691D44A339}" | ||||||
| EndProject | EndProject | ||||||
| @ -14,6 +17,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MesaFabApproval.Client", "M | |||||||
| 		{2C16014D-B04E-46AF-AB4C-D2691D44A339} = {2C16014D-B04E-46AF-AB4C-D2691D44A339} | 		{2C16014D-B04E-46AF-AB4C-D2691D44A339} = {2C16014D-B04E-46AF-AB4C-D2691D44A339} | ||||||
| 	EndProjectSection | 	EndProjectSection | ||||||
| EndProject | EndProject | ||||||
|  | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MesaFabApproval.API.Test", "MesaFabApproval.API.Test\MesaFabApproval.API.Test.csproj", "{D03AB305-BA29-4EB1-AC66-ABBF76FBF5C1}" | ||||||
|  | 	ProjectSection(ProjectDependencies) = postProject | ||||||
|  | 		{2C16014D-B04E-46AF-AB4C-D2691D44A339} = {2C16014D-B04E-46AF-AB4C-D2691D44A339} | ||||||
|  | 		{852E528D-015A-43B5-999D-F281E3359E5E} = {852E528D-015A-43B5-999D-F281E3359E5E} | ||||||
|  | 	EndProjectSection | ||||||
|  | EndProject | ||||||
|  | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MesaFabApproval.Client.Test", "MesaFabApproval.Client.Test\MesaFabApproval.Client.Test.csproj", "{A0E5BD7D-3910-43BD-BBA3-3820AD524423}" | ||||||
|  | 	ProjectSection(ProjectDependencies) = postProject | ||||||
|  | 		{2C16014D-B04E-46AF-AB4C-D2691D44A339} = {2C16014D-B04E-46AF-AB4C-D2691D44A339} | ||||||
|  | 		{34D52F44-A81F-4247-8180-16E204824A07} = {34D52F44-A81F-4247-8180-16E204824A07} | ||||||
|  | 	EndProjectSection | ||||||
|  | EndProject | ||||||
| Global | Global | ||||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||||
| 		Debug|Any CPU = Debug|Any CPU | 		Debug|Any CPU = Debug|Any CPU | ||||||
| @ -36,6 +51,14 @@ Global | |||||||
| 		{34D52F44-A81F-4247-8180-16E204824A07}.Debug|Any CPU.Build.0 = Debug|Any CPU | 		{34D52F44-A81F-4247-8180-16E204824A07}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
| 		{34D52F44-A81F-4247-8180-16E204824A07}.Release|Any CPU.ActiveCfg = Release|Any CPU | 		{34D52F44-A81F-4247-8180-16E204824A07}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
| 		{34D52F44-A81F-4247-8180-16E204824A07}.Release|Any CPU.Build.0 = Release|Any CPU | 		{34D52F44-A81F-4247-8180-16E204824A07}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
|  | 		{D03AB305-BA29-4EB1-AC66-ABBF76FBF5C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{D03AB305-BA29-4EB1-AC66-ABBF76FBF5C1}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
|  | 		{D03AB305-BA29-4EB1-AC66-ABBF76FBF5C1}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
|  | 		{D03AB305-BA29-4EB1-AC66-ABBF76FBF5C1}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
|  | 		{A0E5BD7D-3910-43BD-BBA3-3820AD524423}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{A0E5BD7D-3910-43BD-BBA3-3820AD524423}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
|  | 		{A0E5BD7D-3910-43BD-BBA3-3820AD524423}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
|  | 		{A0E5BD7D-3910-43BD-BBA3-3820AD524423}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
| 	EndGlobalSection | 	EndGlobalSection | ||||||
| 	GlobalSection(SolutionProperties) = preSolution | 	GlobalSection(SolutionProperties) = preSolution | ||||||
| 		HideSolutionNode = FALSE | 		HideSolutionNode = FALSE | ||||||
|  | |||||||
| @ -1,9 +1,9 @@ | |||||||
|     /*vertical height between form-groups*/ | /*vertical height between form-groups*/ | ||||||
|     .my-form .form-group { | .my-form .form-group { | ||||||
|     margin-bottom: 4px; |     margin-bottom: 4px; | ||||||
|     } | } | ||||||
|  |  | ||||||
|     @media (min-width:768px) { | @media (min-width:768px) { | ||||||
|     .my-form .row { |     .my-form .row { | ||||||
|         margin-left: -1px; |         margin-left: -1px; | ||||||
|         margin-right: -1px; |         margin-right: -1px; | ||||||
| @ -12,7 +12,8 @@ | |||||||
|     .my-form [class*="col-"] { |     .my-form [class*="col-"] { | ||||||
|         padding: 0 2px; |         padding: 0 2px; | ||||||
|     } |     } | ||||||
|     } | } | ||||||
|  |  | ||||||
| body { | body { | ||||||
|     padding-top: 50px; |     padding-top: 50px; | ||||||
|     padding-bottom: 20px; |     padding-bottom: 20px; | ||||||
| @ -29,10 +30,10 @@ body { | |||||||
| /*input, | /*input, | ||||||
| select | select | ||||||
| { | { | ||||||
|     max-width: 280px; | max-width: 280px; | ||||||
| }*/ | }*/ | ||||||
|  |  | ||||||
| .row{ | .row { | ||||||
|     margin-top: 2px; |     margin-top: 2px; | ||||||
|     margin-bottom: 2px |     margin-bottom: 2px | ||||||
| } | } | ||||||
| @ -71,10 +72,10 @@ input[type="checkbox"].input-validation-error { | |||||||
|     padding-left: 20px; |     padding-left: 20px; | ||||||
|     padding-right: 20px; |     padding-right: 20px; | ||||||
|     background-color: #87b3de; |     background-color: #87b3de; | ||||||
|   background-image: -moz-linear-gradient(top,#87b3de, #4d79a5); |     background-image: -moz-linear-gradient(top, #87b3de, #4d79a5); | ||||||
|   background-image: -ms-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-gradient(linear, 0 0, 0 50%, from(#87b3de), to(#4d79a5)); | ||||||
|   background-image: -webkit-linear-gradient(top,#87b3de, #4d79a5); |     background-image: -webkit-linear-gradient(top, #87b3de, #4d79a5); | ||||||
|     background-image: -o-linear-gradient(top, #87b3de, #4d79a5); |     background-image: -o-linear-gradient(top, #87b3de, #4d79a5); | ||||||
|     background-image: linear-gradient(top, #87b3de, #4d79a5); |     background-image: linear-gradient(top, #87b3de, #4d79a5); | ||||||
|     background-repeat: repeat-x; |     background-repeat: repeat-x; | ||||||
| @ -89,7 +90,7 @@ input[type="checkbox"].input-validation-error { | |||||||
|  |  | ||||||
| .label-color { | .label-color { | ||||||
|     background-color: #e5e0e0; |     background-color: #e5e0e0; | ||||||
|     } | } | ||||||
|  |  | ||||||
| .linkbutton { | .linkbutton { | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
| @ -101,6 +102,17 @@ input[type="checkbox"].input-validation-error { | |||||||
|     border: 0; |     border: 0; | ||||||
|     vertical-align: middle; |     vertical-align: middle; | ||||||
| } | } | ||||||
|  |  | ||||||
| .linkbutton.edit { | .linkbutton.edit { | ||||||
|     background: url('/Content/icons/edit.gif'); |     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] | [Authorize] | ||||||
| public class AccountController : Controller { | public class AccountController : Controller { | ||||||
|     private string _apiBaseUrl; |  | ||||||
|  |  | ||||||
|     public AccountController() |     public AccountController() | ||||||
|         : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()))) { |         : 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) { |     public AccountController(UserManager<ApplicationUser> userManager) { | ||||||
| @ -69,7 +66,7 @@ public class AccountController : Controller { | |||||||
|             bool isLoginValid; |             bool isLoginValid; | ||||||
|  |  | ||||||
|             HttpClient httpClient = HttpClientFactory.Create(); |             HttpClient httpClient = HttpClientFactory.Create(); | ||||||
|             httpClient.BaseAddress = new Uri(_apiBaseUrl); |             httpClient.BaseAddress = new Uri(GlobalVars.AppSettings.ApiBaseUrl); | ||||||
|  |  | ||||||
|             LoginResult loginResult = await AccountDMO.LoginAsync(httpClient, model); |             LoginResult loginResult = await AccountDMO.LoginAsync(httpClient, model); | ||||||
|  |  | ||||||
| @ -121,7 +118,7 @@ public class AccountController : Controller { | |||||||
|             bool isLoginValid; |             bool isLoginValid; | ||||||
|  |  | ||||||
|             HttpClient httpClient = HttpClientFactory.Create(); |             HttpClient httpClient = HttpClientFactory.Create(); | ||||||
|             httpClient.BaseAddress = new Uri(_apiBaseUrl); |             httpClient.BaseAddress = new Uri(GlobalVars.AppSettings.ApiBaseUrl); | ||||||
|  |  | ||||||
|             LoginResult loginResult = await AccountDMO.ExternalAuthSetupAsync(httpClient, authAttempt); |             LoginResult loginResult = await AccountDMO.ExternalAuthSetupAsync(httpClient, authAttempt); | ||||||
|  |  | ||||||
|  | |||||||
| @ -58,6 +58,7 @@ public class AuditController : Controller { | |||||||
|         try { |         try { | ||||||
|             bool isAdmin = (bool)Session[GlobalVars.IS_ADMIN]; |             bool isAdmin = (bool)Session[GlobalVars.IS_ADMIN]; | ||||||
|             int userId = (int)Session[GlobalVars.SESSION_USERID]; |             int userId = (int)Session[GlobalVars.SESSION_USERID]; | ||||||
|  |             audit = auditDMO.GetAuditItem(issueID, userId); | ||||||
|             AuditEdit auditEdit = auditDMO.GetAuditEdit(issueID, audit, isAdmin, userId); |             AuditEdit auditEdit = auditDMO.GetAuditEdit(issueID, audit, isAdmin, userId); | ||||||
|             if (auditEdit.RedirectToAction) |             if (auditEdit.RedirectToAction) | ||||||
|                 return RedirectToAction("ReadOnlyAudit", new { auditNo = audit.AuditNo }); |                 return RedirectToAction("ReadOnlyAudit", new { auditNo = audit.AuditNo }); | ||||||
|  | |||||||
| @ -48,60 +48,23 @@ public class ChangeControlController : Controller { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     public ActionResult Edit(int issueID) { |     public ActionResult Edit(int issueID) { | ||||||
|         int isITARCompliant = 1; |         string jwt = Session["JWT"].ToString(); | ||||||
|         ChangeControlViewModel cc = new ChangeControlViewModel(); |         string encodedJwt = System.Net.WebUtility.UrlEncode(jwt); | ||||||
|         cc = ccDMO.GetChangeControlRead(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]); |         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); |         return Redirect(mrbUrl); | ||||||
|         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); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public ActionResult ReadOnlyCC(int issueID) { |     public ActionResult ReadOnlyCC(int issueID) { | ||||||
|         int isITARCompliant = 1; |         string jwt = Session["JWT"].ToString(); | ||||||
|         ChangeControlViewModel cc = new ChangeControlViewModel(); |         string encodedJwt = System.Net.WebUtility.UrlEncode(jwt); | ||||||
|         cc = ccDMO.GetChangeControlRead(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]); |         string refreshToken = Session["RefreshToken"].ToString(); | ||||||
|         // TODO locked functionality |         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 Redirect(mrbUrl); | ||||||
|         { |  | ||||||
|             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); |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     [HttpPost] |     [HttpPost] | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| using System; | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| using System.Configuration; | using System.Configuration; | ||||||
|  | using System.IO; | ||||||
| using System.Linq; | using System.Linq; | ||||||
| using System.Web; | using System.Web; | ||||||
| using System.Web.Mvc; | using System.Web.Mvc; | ||||||
| @ -21,7 +22,7 @@ namespace Fab2ApprovalSystem.Controllers; | |||||||
| [Authorize] | [Authorize] | ||||||
| [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")] | [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")] | ||||||
| [SessionExpireFilter] | [SessionExpireFilter] | ||||||
| public class ECNController : PdfViewController { | public class ECNController : Controller { | ||||||
|  |  | ||||||
|     private const string ECN_PREFIX = "ECN_"; |     private const string ECN_PREFIX = "ECN_"; | ||||||
|     private const string TECN_PREFIX = "TECN_"; |     private const string TECN_PREFIX = "TECN_"; | ||||||
| @ -669,9 +670,6 @@ public class ECNController : PdfViewController { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// Get a list of Approvers and the status |  | ||||||
|     /// </summary> |  | ||||||
|     public ActionResult GetApproversList([DataSourceRequest] DataSourceRequest request, int issueID, byte step, bool isTECN, bool isEmergrncyTECN) { |     public ActionResult GetApproversList([DataSourceRequest] DataSourceRequest request, int issueID, byte step, bool isTECN, bool isEmergrncyTECN) { | ||||||
|         int isITARCompliant = 0; |         int isITARCompliant = 0; | ||||||
|         ECN ecn = new ECN(); |         ECN ecn = new ECN(); | ||||||
| @ -883,6 +881,8 @@ public class ECNController : PdfViewController { | |||||||
|  |  | ||||||
|             string outputFileName = ""; |             string outputFileName = ""; | ||||||
|             ecn = ecnDMO.GetECNPdf(ecnNumber); |             ecn = ecnDMO.GetECNPdf(ecnNumber); | ||||||
|  |             ViewBag.Category = ecnDMO.GetCategoryID(ecn); | ||||||
|  |             ViewBag.TrainingNotificationTo = ecnDMO.GetTrainingNotificationTo(ecn, trainingDMO); | ||||||
|             outputFileName = ecnNumber.ToString() + ".pdf"; |             outputFileName = ecnNumber.ToString() + ".pdf"; | ||||||
|  |  | ||||||
|             string ecnFolderPath = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString(); |             string ecnFolderPath = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString(); | ||||||
| @ -891,10 +891,12 @@ public class ECNController : PdfViewController { | |||||||
|             if (!di.Exists) |             if (!di.Exists) | ||||||
|                 di.Create(); |                 di.Create(); | ||||||
|  |  | ||||||
|             // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This |             string htmlText; | ||||||
|             // requires the controller to be inherited from MyController instead of MVC's Controller. |             string pageTitle = string.Empty; | ||||||
|             SavePdf(ecnFolderPath + "\\ECNForm_" + outputFileName, "ECNPdf", ecn); |             htmlText = RenderViewToString("ECNPdf", ecn); | ||||||
|             SavePdf(ecnFolderPath + "\\ECNApprovalLog_" + outputFileName, "ECNApprovalPdf", ecn); |             StandardPdfRenderer.WritePortableDocumentFormatToFile(pageTitle, htmlText, $"{ecnFolderPath}\\ECNForm_{outputFileName}"); | ||||||
|  |             htmlText = RenderViewToString("ECNApprovalPdf", ecn); | ||||||
|  |             StandardPdfRenderer.WritePortableDocumentFormatToFile(pageTitle, htmlText, $"{ecnFolderPath}\\ECNApprovalLog_{outputFileName}"); | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Generate PDF", Comments = ex.Message }); |             EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Generate PDF", Comments = ex.Message }); | ||||||
|             ecn = null; |             ecn = null; | ||||||
| @ -904,12 +906,32 @@ public class ECNController : PdfViewController { | |||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private string RenderViewToString(string viewName, ECNPdf ecnPdf) { | ||||||
|  |         string result; | ||||||
|  |         ViewData.Model = ecnPdf; | ||||||
|  |         using (StringWriter writer = new()) { | ||||||
|  |             try { | ||||||
|  |                 ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, viewName, string.Empty); | ||||||
|  |                 if (viewResult is null) | ||||||
|  |                     return $"A view with the name '{viewName}' could not be found"; | ||||||
|  |                 ViewContext viewContext = new(ControllerContext, viewResult.View, ViewData, TempData, writer); | ||||||
|  |                 viewResult.View.Render(viewContext, writer); | ||||||
|  |                 result = writer.GetStringBuilder().ToString(); | ||||||
|  |             } catch (Exception ex) { | ||||||
|  |                 result = $"Failed - {ex.Message}"; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public bool GenerateECNPdfDifferentLocation(int ecnNumber, int folderName) { |     public bool GenerateECNPdfDifferentLocation(int ecnNumber, int folderName) { | ||||||
|         ECNPdf ecn = new ECNPdf(); |         ECNPdf ecn = new ECNPdf(); | ||||||
|         try { |         try { | ||||||
|             string outputFileName = ""; |             string outputFileName = ""; | ||||||
|  |  | ||||||
|             ecn = ecnDMO.GetECNPdf(ecnNumber); |             ecn = ecnDMO.GetECNPdf(ecnNumber); | ||||||
|  |             ViewBag.Category = ecnDMO.GetCategoryID(ecn); | ||||||
|  |             ViewBag.TrainingNotificationTo = ecnDMO.GetTrainingNotificationTo(ecn, trainingDMO); | ||||||
|             outputFileName = ecnNumber.ToString() + ".pdf"; |             outputFileName = ecnNumber.ToString() + ".pdf"; | ||||||
|  |  | ||||||
|             string ecnFolderPath = _AppSettings.AttachmentFolder + "ECN\\" + folderName.ToString(); |             string ecnFolderPath = _AppSettings.AttachmentFolder + "ECN\\" + folderName.ToString(); | ||||||
| @ -919,9 +941,9 @@ public class ECNController : PdfViewController { | |||||||
|             if (!di.Exists) |             if (!di.Exists) | ||||||
|                 di.Create(); |                 di.Create(); | ||||||
|  |  | ||||||
|             // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This |             string pageTitle = string.Empty; | ||||||
|             // requires the controller to be inherited from MyController instead of MVC's Controller. |             string htmlText = RenderViewToString("ECNPdf", ecn); | ||||||
|             SavePdf(ecnFolderPath + "\\ECNForm_" + outputFileName, "ECNPdf", ecn); |             StandardPdfRenderer.WritePortableDocumentFormatToFile(pageTitle, htmlText, $"{ecnFolderPath}\\ECNForm_{outputFileName}"); | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Generate PDF", Comments = ex.Message }); |             EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Generate PDF", Comments = ex.Message }); | ||||||
|             ecn = null; |             ecn = null; | ||||||
| @ -935,13 +957,20 @@ public class ECNController : PdfViewController { | |||||||
|         ECNPdf ecn; |         ECNPdf ecn; | ||||||
|         try { |         try { | ||||||
|             ecn = ecnDMO.GetECNPdf(ecnNumber); |             ecn = ecnDMO.GetECNPdf(ecnNumber); | ||||||
|             // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This |             ViewBag.Category = ecnDMO.GetCategoryID(ecn); | ||||||
|             // requires the controller to be inherited from MyController instead of MVC's Controller. |             ViewBag.TrainingNotificationTo = ecnDMO.GetTrainingNotificationTo(ecn, trainingDMO); | ||||||
|             return this.ViewPdf("", "ECNPdf", ecn); |             string pageTitle = string.Empty; | ||||||
|  |             string htmlText = RenderViewToString("ECNPdf", ecn); | ||||||
|  |             if (System.Diagnostics.Debugger.IsAttached) { | ||||||
|  |                 return Content(htmlText, "text/html"); | ||||||
|  |             } else { | ||||||
|  |                 byte[] buffer = StandardPdfRenderer.GetPortableDocumentFormatBytes(pageTitle, htmlText); | ||||||
|  |                 return new BinaryContentResult(buffer, "application/pdf"); | ||||||
|  |             } | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Print PDF", Comments = ex.Message }); |             EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Print PDF", Comments = ex.Message }); | ||||||
|             ecn = null; |             ecn = null; | ||||||
|             return Content(""); |             return Content("An unexpected error has occurred!"); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -953,8 +982,7 @@ public class ECNController : PdfViewController { | |||||||
|         } catch { } |         } catch { } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void NotifyApproversForCancellation(int ecnNumber, byte currentStep, int documentType, string ecnTypeString) { |     public void NotifyApproversForCancellation(int ecnNumber, ECN ecn, byte currentStep, int documentType, string ecnTypeString) { | ||||||
|         ECN ecn = ecnDMO.GetECN(ecnNumber); |  | ||||||
|         string emailSentList = ECNHelper.NotifyApproversForCancellation(_AppSettings, ecnNumber, currentStep, documentType, ecnTypeString, ecn); |         string emailSentList = ECNHelper.NotifyApproversForCancellation(_AppSettings, ecnNumber, currentStep, documentType, ecnTypeString, ecn); | ||||||
|         try { |         try { | ||||||
|             EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + currentStep.ToString() + ":" + emailSentList }); |             EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + currentStep.ToString() + ":" + emailSentList }); | ||||||
| @ -977,10 +1005,10 @@ public class ECNController : PdfViewController { | |||||||
|         } catch { } |         } catch { } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void NotifyTECNCancellation(int ecnNumber, string ecnFolderPath) { |     public void NotifyTECNCancellation(int ecnNumber, string ecnFolderPath, string comments) { | ||||||
|         ECN ecn = ecnDMO.GetECN(ecnNumber); |         ECN ecn = ecnDMO.GetECN(ecnNumber); | ||||||
|         List<int> notificationUserList = ecnDMO.GetTECNNotificationUsers().ToList(); |         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 { |         try { | ||||||
|             EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "E-TECN", OperationType = "Email", Comments = "Approvers for Cancellation :" + emailSentList }); |             EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "E-TECN", OperationType = "Email", Comments = "Approvers for Cancellation :" + emailSentList }); | ||||||
|         } catch { } |         } catch { } | ||||||
| @ -1157,22 +1185,24 @@ public class ECNController : PdfViewController { | |||||||
|         return Content(ecnDMO.PCRBExists(pcrb).ToString()); |         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; |         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); |         int appoverCount = ecnDMO.SubmitForCancellation(ecnNumber, (byte)GlobalVars.WorkFLowStepNumber.Step1, (int)Session[GlobalVars.SESSION_USERID], documentType, ecnTypeString, (int)GlobalVars.TECNExpirationCancellation.Cancellation); | ||||||
|         if (appoverCount > 0) { |         if (appoverCount > 0) { | ||||||
|             NotifyApproversForCancellation(ecnNumber, currentStep, documentType, ecnTypeString); |             NotifyApproversForCancellation(ecnNumber, ecn, currentStep, documentType, ecnTypeString); | ||||||
|         } else // TODO Automatically close the |         } else { // TODO Automatically close the | ||||||
|           { |             lastApproverAndLastStep = ApproveCancellation(ecnNumber, currentStep, comments, documentType, ecnTypeString); | ||||||
|             lastApproverAndLastStep = ApproveCancellation(ecnNumber, currentStep, "", documentType, ecnTypeString); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!lastApproverAndLastStep) { |         if (!lastApproverAndLastStep) { | ||||||
|             try { |             try { | ||||||
|                 lastApproverAndLastStep = true; |                 lastApproverAndLastStep = true; | ||||||
|  |  | ||||||
|                 ECNPdf ecn = new ECNPdf(); |                 ECNPdf ecnPDF = new ECNPdf(); | ||||||
|                 GenerateECNPdf(ecnNumber, out ecn); |                 GenerateECNPdf(ecnNumber, out ecnPDF); | ||||||
|  |  | ||||||
|                 string sourceDirectory = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString() + "\\"; |                 string sourceDirectory = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString() + "\\"; | ||||||
|                 string outputFullFilePath = ""; |                 string outputFullFilePath = ""; | ||||||
| @ -1184,7 +1214,7 @@ public class ECNController : PdfViewController { | |||||||
|  |  | ||||||
|                 Zipper zip = new Zipper(); |                 Zipper zip = new Zipper(); | ||||||
|                 zip.CreateZip(outputFullFilePath, sourceDirectory); |                 zip.CreateZip(outputFullFilePath, sourceDirectory); | ||||||
|                 NotifyTECNCancellation(ecnNumber, outputFullFilePath); |                 NotifyTECNCancellation(ecnNumber, outputFullFilePath, comments); | ||||||
|  |  | ||||||
|             } catch (Exception ex) { |             } catch (Exception ex) { | ||||||
|                 EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "TECN", OperationType = "Error", Comments = ex.Message }); |                 EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "TECN", OperationType = "Error", Comments = ex.Message }); | ||||||
| @ -1208,19 +1238,26 @@ public class ECNController : PdfViewController { | |||||||
|     public bool ApproveCancellation(int ecnNumber, byte currentStep, string comments, int documentType, string ecnTypeString) { |     public bool ApproveCancellation(int ecnNumber, byte currentStep, string comments, int documentType, string ecnTypeString) { | ||||||
|         bool lastApproverAndLastStep = false; |         bool lastApproverAndLastStep = false; | ||||||
|         bool lastStep = 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); |         bool lastApprover = ecnDMO.ECNApproveCancelled_ExpiredDocument(ecnNumber, currentStep, comments, out lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType); | ||||||
|         while (lastApprover && !lastStep) { |         while (lastApprover && !lastStep) { | ||||||
|             currentStep++; |             currentStep++; | ||||||
|             lastApprover = ecnDMO.ECNApproveCancelled_ExpiredDocument(ecnNumber, currentStep, comments, out lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType); |             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) { |         if (lastApprover && lastStep) { | ||||||
|             try { |             try { | ||||||
|                 lastApproverAndLastStep = true; |                 lastApproverAndLastStep = true; | ||||||
|  |  | ||||||
|                 ECNPdf ecn = new ECNPdf(); |                 ecn.CancellationDate = DateTime.Now; | ||||||
|                 GenerateECNPdf(ecnNumber, out ecn); |                 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 sourceDirectory = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString() + "\\"; | ||||||
|                 string outputFullFilePath = ""; |                 string outputFullFilePath = ""; | ||||||
| @ -1232,7 +1269,7 @@ public class ECNController : PdfViewController { | |||||||
|  |  | ||||||
|                 Zipper zip = new Zipper(); |                 Zipper zip = new Zipper(); | ||||||
|                 zip.CreateZip(outputFullFilePath, sourceDirectory); |                 zip.CreateZip(outputFullFilePath, sourceDirectory); | ||||||
|                 NotifyTECNCancellation(ecnNumber, outputFullFilePath); |                 NotifyTECNCancellation(ecnNumber, outputFullFilePath, comments); | ||||||
|  |  | ||||||
|             } catch (Exception ex) { |             } catch (Exception ex) { | ||||||
|                 EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "TECN", OperationType = "Error", Comments = ex.Message }); |                 EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "TECN", OperationType = "Error", Comments = ex.Message }); | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| using System; | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| using System.Configuration; | using System.Configuration; | ||||||
|  | using System.IO; | ||||||
| using System.Linq; | using System.Linq; | ||||||
| using System.Threading; | using System.Threading; | ||||||
| using System.Web; | using System.Web; | ||||||
| @ -20,7 +21,7 @@ namespace Fab2ApprovalSystem.Controllers; | |||||||
| [Authorize] | [Authorize] | ||||||
| [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")] | [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")] | ||||||
| [SessionExpireFilter] | [SessionExpireFilter] | ||||||
| public class LotTravelerController : PdfViewController { | public class LotTravelerController : Controller { | ||||||
|  |  | ||||||
|     LotTravelerDMO LotTravDMO = new LotTravelerDMO(); |     LotTravelerDMO LotTravDMO = new LotTravelerDMO(); | ||||||
|     string docTypeString = "LotTraveler"; |     string docTypeString = "LotTraveler"; | ||||||
| @ -199,9 +200,14 @@ public class LotTravelerController : PdfViewController { | |||||||
|         try { |         try { | ||||||
|             workRequest = LotTravDMO.GetLTWorkRequestItemPDF(workRequestID); |             workRequest = LotTravDMO.GetLTWorkRequestItemPDF(workRequestID); | ||||||
|  |  | ||||||
|             // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This |             string pageTitle = string.Empty; | ||||||
|             // requires the controller to be inherited from MyController instead of MVC's Controller. |             string htmlText = RenderViewToString("WorkRequestPDF", workRequest); | ||||||
|             return this.ViewPdf("", "WorkRequestPDF", workRequest); |             if (System.Diagnostics.Debugger.IsAttached) { | ||||||
|  |                 return Content(htmlText, "text/html"); | ||||||
|  |             } else { | ||||||
|  |                 byte[] buffer = StandardPdfRenderer.GetPortableDocumentFormatBytes(pageTitle, htmlText); | ||||||
|  |                 return new BinaryContentResult(buffer, "application/pdf"); | ||||||
|  |             } | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n DisplayWorkRequestPDF - LotTraveler\r\n" + ex.InnerException.ToString(), System.Diagnostics.EventLogEntryType.Error); |             Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n DisplayWorkRequestPDF - LotTraveler\r\n" + ex.InnerException.ToString(), System.Diagnostics.EventLogEntryType.Error); | ||||||
|             EventLogDMO.Add(new WinEventLog() { IssueID = workRequest.SWRNumber, UserID = @User.Identity.Name, DocumentType = "LotTravler", OperationType = "Generate PDF", Comments = ex.Message }); |             EventLogDMO.Add(new WinEventLog() { IssueID = workRequest.SWRNumber, UserID = @User.Identity.Name, DocumentType = "LotTravler", OperationType = "Generate PDF", Comments = ex.Message }); | ||||||
| @ -210,6 +216,24 @@ public class LotTravelerController : PdfViewController { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private string RenderViewToString(string viewName, object model) { | ||||||
|  |         string result; | ||||||
|  |         ViewData.Model = model; | ||||||
|  |         using (StringWriter writer = new()) { | ||||||
|  |             try { | ||||||
|  |                 ViewEngineResult viewResult = ViewEngines.Engines.FindView(ControllerContext, viewName, string.Empty); | ||||||
|  |                 if (viewResult is null) | ||||||
|  |                     return $"A view with the name '{viewName}' could not be found"; | ||||||
|  |                 ViewContext viewContext = new(ControllerContext, viewResult.View, ViewData, TempData, writer); | ||||||
|  |                 viewResult.View.Render(viewContext, writer); | ||||||
|  |                 result = writer.GetStringBuilder().ToString(); | ||||||
|  |             } catch (Exception ex) { | ||||||
|  |                 result = $"Failed - {ex.Message}"; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public ActionResult WorkRequestRevision(int workRequestID) { |     public ActionResult WorkRequestRevision(int workRequestID) { | ||||||
|         int isITARCompliant = 1; |         int isITARCompliant = 1; | ||||||
|         LTWorkRequest workRequest = new LTWorkRequest(); |         LTWorkRequest workRequest = new LTWorkRequest(); | ||||||
| @ -251,9 +275,7 @@ public class LotTravelerController : PdfViewController { | |||||||
|  |  | ||||||
|         return Content("Successfully Saved"); |         return Content("Successfully Saved"); | ||||||
|     } |     } | ||||||
|     /// <summary> |  | ||||||
|     ///  |  | ||||||
|     /// </summary> |  | ||||||
|     public JsonResult GetBaseFlowLocations(string baseFlow) { |     public JsonResult GetBaseFlowLocations(string baseFlow) { | ||||||
|         List<BaseFlowLocation> loclist = LotTravDMO.GetBaseFlowLocations(baseFlow); |         List<BaseFlowLocation> loclist = LotTravDMO.GetBaseFlowLocations(baseFlow); | ||||||
|         return Json(loclist, JsonRequestBehavior.AllowGet); |         return Json(loclist, JsonRequestBehavior.AllowGet); | ||||||
| @ -332,9 +354,6 @@ public class LotTravelerController : PdfViewController { | |||||||
|         return Content(newWorkRequestID.ToString()); |         return Content(newWorkRequestID.ToString()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// For the Revison |  | ||||||
|     /// </summary> |  | ||||||
|     public ActionResult UpdateMaterialDetailRevision(LTWorkRequest model) { |     public ActionResult UpdateMaterialDetailRevision(LTWorkRequest model) { | ||||||
|         var modelMaterialDetail = model.LTMaterial; |         var modelMaterialDetail = model.LTMaterial; | ||||||
|         int previousMaterialID = model.LTMaterial.ID; |         int previousMaterialID = model.LTMaterial.ID; | ||||||
| @ -1232,15 +1251,19 @@ public class LotTravelerController : PdfViewController { | |||||||
|         LotTravDMO.DeleteLot(ltLotID); |         LotTravDMO.DeleteLot(ltLotID); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// |  | ||||||
|     public ActionResult DisplayLotTravlerPdf(int ltLotID, int revisionNumber) { |     public ActionResult DisplayLotTravlerPdf(int ltLotID, int revisionNumber) { | ||||||
|         LotTravelerPdf traveler = new LotTravelerPdf(); |         LotTravelerPdf traveler = new LotTravelerPdf(); | ||||||
|         try { |         try { | ||||||
|             traveler = LotTravDMO.GetLotTravlerPdf(ltLotID, revisionNumber); |             traveler = LotTravDMO.GetLotTravlerPdf(ltLotID, revisionNumber); | ||||||
|  |  | ||||||
|             // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This |             string pageTitle = string.Empty; | ||||||
|             // requires the controller to be inherited from MyController instead of MVC's Controller. |             string htmlText = RenderViewToString("LotTravelerPDF", traveler); | ||||||
|             return this.ViewPdf("", "LotTravelerPDF", traveler); |             if (System.Diagnostics.Debugger.IsAttached) { | ||||||
|  |                 return Content(htmlText, "text/html"); | ||||||
|  |             } else { | ||||||
|  |                 byte[] buffer = StandardPdfRenderer.GetPortableDocumentFormatBytes(pageTitle, htmlText); | ||||||
|  |                 return new BinaryContentResult(buffer, "application/pdf"); | ||||||
|  |             } | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             EventLogDMO.Add(new WinEventLog() { IssueID = traveler.SWRNumber, UserID = @User.Identity.Name, DocumentType = "LotTraveler", OperationType = "Generate PDF", Comments = ex.Message }); |             EventLogDMO.Add(new WinEventLog() { IssueID = traveler.SWRNumber, UserID = @User.Identity.Name, DocumentType = "LotTraveler", OperationType = "Generate PDF", Comments = ex.Message }); | ||||||
|             traveler = null; |             traveler = null; | ||||||
|  | |||||||
| @ -79,9 +79,7 @@ public class MRBController : Controller { | |||||||
|         string encodedJwt = System.Net.WebUtility.UrlEncode(jwt); |         string encodedJwt = System.Net.WebUtility.UrlEncode(jwt); | ||||||
|         string refreshToken = Session["RefreshToken"].ToString(); |         string refreshToken = Session["RefreshToken"].ToString(); | ||||||
|         string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); |         string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); | ||||||
|         string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? |         string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=mrb/{issueID}"; | ||||||
|             "https://localhost:7255"; |  | ||||||
|         string mrbUrl = $"{wasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=/mrb/{issueID}"; |  | ||||||
|  |  | ||||||
|         return Redirect(mrbUrl); |         return Redirect(mrbUrl); | ||||||
|     } |     } | ||||||
| @ -104,9 +102,7 @@ public class MRBController : Controller { | |||||||
|         string encodedJwt = System.Net.WebUtility.UrlEncode(jwt); |         string encodedJwt = System.Net.WebUtility.UrlEncode(jwt); | ||||||
|         string refreshToken = Session["RefreshToken"].ToString(); |         string refreshToken = Session["RefreshToken"].ToString(); | ||||||
|         string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); |         string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); | ||||||
|         string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? |         string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=mrb/{issueID}"; | ||||||
|             "https://localhost:7255"; |  | ||||||
|         string mrbUrl = $"{wasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=/mrb/{issueID}"; |  | ||||||
|  |  | ||||||
|         return Redirect(mrbUrl); |         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) { |             foreach (SubRole sr in r.SubRoles) { | ||||||
|                 if (sr.Inactive) { |                 if (sr.Inactive) { | ||||||
|                     // hide inactive roles unless parameter says otherwise |                     // hide inactive roles unless parameter says otherwise | ||||||
|                     if (showInactiveRoles.Equals("true") == false) |                     if (!showInactiveRoles.Equals("true")) | ||||||
|                         continue; |                         continue; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|  | |||||||
| @ -401,7 +401,6 @@ public class AuditDMO { | |||||||
|             result.Is8DQA = "true"; |             result.Is8DQA = "true"; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         audit = GetAuditItem(issueID, userId); |  | ||||||
|         // transform audit users from string to list, delimited by a comma. |         // transform audit users from string to list, delimited by a comma. | ||||||
|         if (audit.Auditees == null) { |         if (audit.Auditees == null) { | ||||||
|             result.AuditeeNames = new List<string>(); |             result.AuditeeNames = new List<string>(); | ||||||
| @ -414,7 +413,7 @@ public class AuditDMO { | |||||||
|         if (audit.OriginatorID == userId) { |         if (audit.OriginatorID == userId) { | ||||||
|             result.IsSubmitter = true; |             result.IsSubmitter = true; | ||||||
|         } |         } | ||||||
|         if (isAdmin != true) { |         if (!isAdmin) { | ||||||
|             result.IsAdmin = false; |             result.IsAdmin = false; | ||||||
|         } else { |         } else { | ||||||
|             result.IsAdmin = true; |             result.IsAdmin = true; | ||||||
| @ -424,7 +423,7 @@ public class AuditDMO { | |||||||
|         { |         { | ||||||
|             result.RedirectToAction = true; |             result.RedirectToAction = true; | ||||||
|         } |         } | ||||||
|         if (result.IsAdmin == false && result.IsSubmitter == false) { |         if (!result.IsAdmin && !result.IsSubmitter) { | ||||||
|             result.RedirectToAction = true; |             result.RedirectToAction = true; | ||||||
|         } else { |         } else { | ||||||
|             result.UserList = GetUserList(); |             result.UserList = GetUserList(); | ||||||
|  | |||||||
| @ -90,6 +90,7 @@ public class CorrectiveActionDMO { | |||||||
|                 parameters.Add("@EscapePoint", model.EscapePoint); |                 parameters.Add("@EscapePoint", model.EscapePoint); | ||||||
|                 parameters.Add("@FollowUpDate", model.FollowUpDate); |                 parameters.Add("@FollowUpDate", model.FollowUpDate); | ||||||
|                 parameters.Add("@CASubmitted", model.CASubmitted); |                 parameters.Add("@CASubmitted", model.CASubmitted); | ||||||
|  |                 parameters.Add("@CAStandardType", model.CAStandardType); | ||||||
|  |  | ||||||
|                 db.Execute("_8DUpdateCorrectiveAction", parameters, commandType: CommandType.StoredProcedure); |                 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 }); |                 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; |         bool isAssignee = false; | ||||||
|         int aiIndex = 0; |         int aiIndex = 0; | ||||||
|         List<D5D6CorrectivetAction> actionItems = GetD5D6CorrectivetActions(caId).ToList(); |         List<D5D6CorrectivetAction> actionItems = GetD5D6CorrectivetActions(caId).ToList(); | ||||||
|         while (isAssignee == false && aiIndex < actionItems.Count) { |         while (!isAssignee && aiIndex < actionItems.Count) { | ||||||
|             D5D6CorrectivetAction actionItem = actionItems[aiIndex]; |             D5D6CorrectivetAction actionItem = actionItems[aiIndex]; | ||||||
|             if (actionItem.ResponsibilityOwnerID == userId && actionItem.ImplementedDate == null && actionItem.Approved) { |             if (actionItem.ResponsibilityOwnerID == userId && actionItem.ImplementedDate == null && actionItem.Approved) { | ||||||
|                 isAssignee = true; |                 isAssignee = true; | ||||||
|  | |||||||
| @ -15,6 +15,7 @@ using Fab2ApprovalSystem.ViewModels; | |||||||
| namespace Fab2ApprovalSystem.DMO; | namespace Fab2ApprovalSystem.DMO; | ||||||
|  |  | ||||||
| public class ECN_DMO { | public class ECN_DMO { | ||||||
|  |  | ||||||
|     private readonly IDbConnection db = new SqlConnection(GlobalVars.DB_CONNECTION_STRING); |     private readonly IDbConnection db = new SqlConnection(GlobalVars.DB_CONNECTION_STRING); | ||||||
|     private readonly WorkflowDMO wfDMO = new(); |     private readonly WorkflowDMO wfDMO = new(); | ||||||
|  |  | ||||||
| @ -41,6 +42,9 @@ public class ECN_DMO { | |||||||
|             parameters.Add("@ExpirationDate", ecn.ExpirationDate); |             parameters.Add("@ExpirationDate", ecn.ExpirationDate); | ||||||
|             parameters.Add("@ExtensionDate", ecn.ExtensionDate); |             parameters.Add("@ExtensionDate", ecn.ExtensionDate); | ||||||
|             parameters.Add("@CancellationDate", ecn.CancellationDate); |             parameters.Add("@CancellationDate", ecn.CancellationDate); | ||||||
|  |             parameters.Add("@CancellationApprovalDate", ecn.CancellationApprovalDate); | ||||||
|  |             parameters.Add("@CancellationApproved", ecn.CancellationApproved); | ||||||
|  |             parameters.Add("@Cancelled", ecn.Cancelled); | ||||||
|             parameters.Add("@AcknowledgementRequired", ecn.AcknowledgementRequired); |             parameters.Add("@AcknowledgementRequired", ecn.AcknowledgementRequired); | ||||||
|             parameters.Add("@TrainingRequired", ecn.TrainingRequired); |             parameters.Add("@TrainingRequired", ecn.TrainingRequired); | ||||||
|             parameters.Add("@AreaID", ecn.AreaID); |             parameters.Add("@AreaID", ecn.AreaID); | ||||||
| @ -352,14 +356,17 @@ public class ECN_DMO { | |||||||
|             List<string> affectedAreas = multipleResultItems.Read<string>().ToList(); |             List<string> affectedAreas = multipleResultItems.Read<string>().ToList(); | ||||||
|             List<string> affectedTechnologies = multipleResultItems.Read<string>().ToList(); |             List<string> affectedTechnologies = multipleResultItems.Read<string>().ToList(); | ||||||
|             List<string> acknowledgementBy = multipleResultItems.Read<string>().ToList(); |             List<string> acknowledgementBy = multipleResultItems.Read<string>().ToList(); | ||||||
|             List<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(); |             List<string> productfamilies = multipleResultItems.Read<string>().ToList(); | ||||||
|  |  | ||||||
|             ecnItem.AffectedModules = string.Join(", ", modules); |             ecnItem.AffectedModules = string.Join(", ", modules); | ||||||
|             ecnItem.AffectedDepartments = string.Join(", ", departments); |             ecnItem.AffectedDepartments = string.Join(", ", departments); | ||||||
|             ecnItem.AffectedAreas = string.Join(",", affectedAreas); |             ecnItem.AffectedAreas = string.Join(",", affectedAreas); | ||||||
|             ecnItem.AffectedTechnologies = string.Join(",", affectedTechnologies); |             ecnItem.AffectedTechnologies = string.Join(",", affectedTechnologies); | ||||||
|             ecnItem.TrainingBy = string.Join(",", trainingBy); |  | ||||||
|             ecnItem.AcknowledgementBy = string.Join(",", acknowledgementBy); |             ecnItem.AcknowledgementBy = string.Join(",", acknowledgementBy); | ||||||
|             ecnItem.AffectedProductFamilies = string.Join(",", productfamilies); |             ecnItem.AffectedProductFamilies = string.Join(",", productfamilies); | ||||||
|  |  | ||||||
| @ -367,7 +374,7 @@ public class ECN_DMO { | |||||||
|         return ecnItem; |         return ecnItem; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     internal ECN GetECN(int ecnNumber) { |     public ECN GetECN(int ecnNumber) { | ||||||
|         ECN ecnItem = new(); |         ECN ecnItem = new(); | ||||||
|         DynamicParameters parameters = new(); |         DynamicParameters parameters = new(); | ||||||
|         parameters.Add("@ECNNumber", value: ecnNumber); |         parameters.Add("@ECNNumber", value: ecnNumber); | ||||||
| @ -389,7 +396,7 @@ public class ECN_DMO { | |||||||
|  |  | ||||||
|     internal List<ECNCategory> GetCategories() { |     internal List<ECNCategory> GetCategories() { | ||||||
|         List<ECNCategory> r = db.Query<ECNCategory>("ECNGetCategories", null, commandType: CommandType.StoredProcedure).ToList(); |         List<ECNCategory> r = db.Query<ECNCategory>("ECNGetCategories", null, commandType: CommandType.StoredProcedure).ToList(); | ||||||
|         return r; |         return r.OrderBy(l => l.CategoryName).ToList(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     internal List<ECNArea> GetECNAreas() { |     internal List<ECNArea> GetECNAreas() { | ||||||
| @ -710,4 +717,26 @@ public class ECN_DMO { | |||||||
|         return r; |         return r; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     internal string GetCategoryID(ECNPdf ecn) { | ||||||
|  |         string result; | ||||||
|  |         if (ecn.CategoryID is null) { | ||||||
|  |             result = string.Empty; | ||||||
|  |         } else { | ||||||
|  |             List<ECNCategory> categories = GetCategories(); | ||||||
|  |             result = (from l in categories where l.CategoryID == ecn.CategoryID.Value select l.CategoryName).FirstOrDefault(); | ||||||
|  |         } | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     internal string GetTrainingNotificationTo(ECNPdf ecn, TrainingDMO trainingDMO) { | ||||||
|  |         string result; | ||||||
|  |         if (ecn.TrainingByIDs is null) { | ||||||
|  |             result = string.Empty; | ||||||
|  |         } else { | ||||||
|  |             List<TrainingGroup> trainingGroups = trainingDMO.GetTrainingGroups(); | ||||||
|  |             result = string.Join(", ", (from l in trainingGroups where ecn.TrainingByIDs.Contains(l.TrainingGroupID) select l.TrainingGroupName).ToArray()); | ||||||
|  |         } | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @ -266,9 +266,9 @@ public class MRB_DMO { | |||||||
|         DateTime? issueStartDate = tempMRBInfo.IssueStartDate; |         DateTime? issueStartDate = tempMRBInfo.IssueStartDate; | ||||||
|         DateTime? issueEndDate = tempMRBInfo.IssueEndDate; |         DateTime? issueEndDate = tempMRBInfo.IssueEndDate; | ||||||
|  |  | ||||||
|         if (issueStartDate.HasValue == false) |         if (!issueStartDate.HasValue) | ||||||
|             throw new Exception("MRB Issue Start Date cannot be blank"); |             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"); |             throw new Exception("MRB Issue End Date cannot be blank"); | ||||||
|  |  | ||||||
|         MRB mrbData = new() { MRBNumber = mrbNumber, ToolCSV = tempMRBInfo.ToolCSV, IssueStartDate = tempMRBInfo.IssueStartDate, IssueEndDate = tempMRBInfo.IssueEndDate }; |         MRB mrbData = new() { MRBNumber = mrbNumber, ToolCSV = tempMRBInfo.ToolCSV, IssueStartDate = tempMRBInfo.IssueStartDate, IssueEndDate = tempMRBInfo.IssueEndDate }; | ||||||
|  | |||||||
| @ -166,7 +166,7 @@ public class WorkflowDMO { | |||||||
|             sqlString.Append("SELECT COUNT(*) FROM LotDisposition LD INNER JOIN Lot L  ON LD.IssueID = L.IssueID "); |             sqlString.Append("SELECT COUNT(*) FROM LotDisposition LD INNER JOIN Lot L  ON LD.IssueID = L.IssueID "); | ||||||
|             sqlString.Append("WHERE (PERequired = 1 OR Location = 'QDB' OR Location = 'EDB' ) AND LD.IssueID = @IssueID "); |             sqlString.Append("WHERE (PERequired = 1 OR Location = 'QDB' OR Location = 'EDB' ) AND LD.IssueID = @IssueID "); | ||||||
|             recordCount = db.Query<int>(sqlString.ToString(), new { IssueID = issueID }).Single(); |             recordCount = db.Query<int>(sqlString.ToString(), new { IssueID = issueID }).Single(); | ||||||
|             if ((recordCount > 0) && (allLotsAreScrap == false)) { |             if ((recordCount > 0) && (!allLotsAreScrap)) { | ||||||
|                 // check if there any IG Medical products |                 // check if there any IG Medical products | ||||||
|                 if (recordCountForIG_MA > 0) { |                 if (recordCountForIG_MA > 0) { | ||||||
|                     sqlString = new StringBuilder(); |                     sqlString = new StringBuilder(); | ||||||
|  | |||||||
| @ -2,10 +2,12 @@ | |||||||
| *****Please DO NOT reply to this email*****  | *****Please DO NOT reply to this email*****  | ||||||
| <br/><br/> | <br/><br/> | ||||||
| {3}# {0} has been Cancelled. Please remove posted TECN from point of use. The cancellation date is {4}  | {3}# {0} has been Cancelled. Please remove posted TECN from point of use. The cancellation date is {4}  | ||||||
| Please review the cancelled TECN form in the attachment. | Please review comments below and ensure process has been returned to normal. | ||||||
| <br/><br/> | <br/><br/> | ||||||
| https://messa016ec.infineon.com/ECN/Edit?issueID={1} | https://messa016ec.infineon.com/ECN/Edit?issueID={1} | ||||||
| <br/><br/> | <br/><br/> | ||||||
|  | Comments: {5} | ||||||
|  | <br/><br/> | ||||||
|  |  | ||||||
| If you have any questions or trouble logging on please contact a site administrator. | If you have any questions or trouble logging on please contact a site administrator. | ||||||
| <br/><br/> | <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\TrainingController.cs" /> | ||||||
|     <Compile Include="Controllers\WebAPIController.cs" /> |     <Compile Include="Controllers\WebAPIController.cs" /> | ||||||
|     <Compile Include="Controllers\WorkflowController.cs" /> |     <Compile Include="Controllers\WorkflowController.cs" /> | ||||||
|  |     <Compile Include="Controllers\PCRBController.cs" /> | ||||||
|     <Compile Include="DMO\AccountDMO.cs" /> |     <Compile Include="DMO\AccountDMO.cs" /> | ||||||
|     <Compile Include="DMO\AdminDMO.cs" /> |     <Compile Include="DMO\AdminDMO.cs" /> | ||||||
|     <Compile Include="DMO\ApprovalLogDMO.cs" /> |     <Compile Include="DMO\ApprovalLogDMO.cs" /> | ||||||
| @ -324,9 +325,6 @@ | |||||||
|     <Compile Include="Models\WinEventLogModel.cs" /> |     <Compile Include="Models\WinEventLogModel.cs" /> | ||||||
|     <Compile Include="Models\WorkFlowModels.cs" /> |     <Compile Include="Models\WorkFlowModels.cs" /> | ||||||
|     <Compile Include="PdfGenerator\BinaryContentResult.cs" /> |     <Compile Include="PdfGenerator\BinaryContentResult.cs" /> | ||||||
|     <Compile Include="PdfGenerator\FakeView.cs" /> |  | ||||||
|     <Compile Include="PdfGenerator\HtmlViewRenderer.cs" /> |  | ||||||
|     <Compile Include="PdfGenerator\PdfViewController.cs" /> |  | ||||||
|     <Compile Include="PdfGenerator\PrintHeaderFooter.cs" /> |     <Compile Include="PdfGenerator\PrintHeaderFooter.cs" /> | ||||||
|     <Compile Include="PdfGenerator\StandardPdfRenderer.cs" /> |     <Compile Include="PdfGenerator\StandardPdfRenderer.cs" /> | ||||||
|     <Compile Include="Properties\AssemblyInfo.cs" /> |     <Compile Include="Properties\AssemblyInfo.cs" /> | ||||||
| @ -387,8 +385,10 @@ | |||||||
|     <Content Include="Views\CorrectiveAction\_D7PAAttachment.cshtml" /> |     <Content Include="Views\CorrectiveAction\_D7PAAttachment.cshtml" /> | ||||||
|     <Content Include="Views\CorrectiveAction\Edit.cshtml" /> |     <Content Include="Views\CorrectiveAction\Edit.cshtml" /> | ||||||
|     <Content Include="Views\CorrectiveAction\ReadOnlyCA.cshtml" /> |     <Content Include="Views\CorrectiveAction\ReadOnlyCA.cshtml" /> | ||||||
|  |     <Content Include="Views\ECN\_ECNCancel.cshtml" /> | ||||||
|     <Content Include="Views\ECN\_ECNLayout.cshtml" /> |     <Content Include="Views\ECN\_ECNLayout.cshtml" /> | ||||||
|     <Content Include="Views\ECN\_ECNReassignOriginator.cshtml" /> |     <Content Include="Views\ECN\_ECNReassignOriginator.cshtml" /> | ||||||
|  |     <Content Include="Views\ECN\_ECNReturnToProcess.cshtml" /> | ||||||
|     <Content Include="Views\ECN\Acknowledge.cshtml" /> |     <Content Include="Views\ECN\Acknowledge.cshtml" /> | ||||||
|     <Content Include="Views\ECN\ECNApprovalPdf.cshtml" /> |     <Content Include="Views\ECN\ECNApprovalPdf.cshtml" /> | ||||||
|     <Content Include="Views\ECN\ECNPdf.cshtml" /> |     <Content Include="Views\ECN\ECNPdf.cshtml" /> | ||||||
| @ -513,6 +513,7 @@ | |||||||
|     <Content Include="EmailTemplates\TECNExpirationApproval.txt" /> |     <Content Include="EmailTemplates\TECNExpirationApproval.txt" /> | ||||||
|     <Content Include="EmailTemplates\TECNExpired.txt" /> |     <Content Include="EmailTemplates\TECNExpired.txt" /> | ||||||
|     <Content Include="EmailTemplates\TECNExtensionReject.txt" /> |     <Content Include="EmailTemplates\TECNExtensionReject.txt" /> | ||||||
|  |     <Content Include="EmailTemplates\TECNReturnedToProcess.txt" /> | ||||||
|     <Content Include="EmailTemplates\WorkRequestApproval.txt" /> |     <Content Include="EmailTemplates\WorkRequestApproval.txt" /> | ||||||
|     <Content Include="EmailTemplates\WorkRequestAssigned.txt" /> |     <Content Include="EmailTemplates\WorkRequestAssigned.txt" /> | ||||||
|     <Content Include="EmailTemplates\WorkRequestReAssigned.txt" /> |     <Content Include="EmailTemplates\WorkRequestReAssigned.txt" /> | ||||||
|  | |||||||
| @ -126,7 +126,7 @@ public class ECNHelper { | |||||||
|         return emailSentList; |         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 = ""; |         string emailSentList = ""; | ||||||
|         List<string> emailIst = MiscDMO.GetTECNCancelledApprovalNotifyList(ecnNumber).Distinct().ToList(); |         List<string> emailIst = MiscDMO.GetTECNCancelledApprovalNotifyList(ecnNumber).Distinct().ToList(); | ||||||
|         foreach (int userId in notificationUserList) { |         foreach (int userId in notificationUserList) { | ||||||
| @ -135,23 +135,27 @@ public class ECNHelper { | |||||||
|                 emailIst.Add(email); |                 emailIst.Add(email); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         string subject = string.Empty; |         string subject; | ||||||
|         string userEmail = string.Empty; |         string emailTemplate; | ||||||
|         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 senderName = "ECN"; |         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); |         EmailNotification en = new(appSettings, subject); | ||||||
|         string[] emailparams = new string[5]; |         string[] emailparams = new string[6]; | ||||||
|         emailparams[0] = ecnNumber.ToString(); |         emailparams[0] = ecnNumber.ToString(); | ||||||
|         emailparams[1] = ecnNumber.ToString(); |         emailparams[1] = ecnNumber.ToString(); | ||||||
|         emailparams[2] = GlobalVars.hostURL; |         emailparams[2] = GlobalVars.hostURL; | ||||||
|         emailparams[3] = "TECN"; |         emailparams[3] = "TECN"; | ||||||
|         emailparams[4] = DateTime.Now.ToString(); |         emailparams[4] = DateTime.Now.ToString(); | ||||||
|  |         emailparams[5] = comments; | ||||||
|  |  | ||||||
| #if (DEBUG) | #if (DEBUG) | ||||||
|         userEmail = GlobalVars.SENDER_EMAIL; |         userEmail = GlobalVars.SENDER_EMAIL; | ||||||
|  | |||||||
| @ -1,53 +1,54 @@ | |||||||
| #if !NET8 | #if NET8 | ||||||
|  |  | ||||||
|  | using ExcelDataReader; | ||||||
|  |  | ||||||
|  | #else  | ||||||
|  |  | ||||||
| using Excel; | using Excel; | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
| using System; | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| using System.Data; | using System.Data; | ||||||
| using System.IO; | using System.IO; | ||||||
| using System.Linq; | using System.Linq; | ||||||
| using System.Web; |  | ||||||
|  |  | ||||||
| namespace Fab2ApprovalSystem.Misc { | namespace Fab2ApprovalSystem.Misc; | ||||||
|  |  | ||||||
|  | public class ExcelData { | ||||||
|  |  | ||||||
|  |     private readonly string _Path; | ||||||
|  |  | ||||||
|     public class ExcelData { |  | ||||||
|         string _path; |  | ||||||
|     public ExcelData(string path) { |     public ExcelData(string path) { | ||||||
|             _path = path; |         _Path = path; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public IExcelDataReader getExcelReader() { |     public IExcelDataReader getExcelReader() { | ||||||
|             // ExcelDataReader works with the binary Excel file, so it needs a FileStream |         FileStream stream = File.Open(_Path, FileMode.Open, FileAccess.Read); | ||||||
|             // to get started. This is how we avoid dependencies on ACE or Interop: |  | ||||||
|  |  | ||||||
|             FileStream stream = File.Open(_path, FileMode.Open, FileAccess.Read); |  | ||||||
|             // We return the interface, so that  |  | ||||||
|         IExcelDataReader reader = null; |         IExcelDataReader reader = null; | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
|                 if (_path.EndsWith(".xls")) { |             if (_Path.EndsWith(".xls")) { | ||||||
|                 reader = ExcelReaderFactory.CreateBinaryReader(stream); |                 reader = ExcelReaderFactory.CreateBinaryReader(stream); | ||||||
|             } |             } | ||||||
|                 if (_path.EndsWith(".xlsx")) { |             if (_Path.EndsWith(".xlsx")) { | ||||||
|                 reader = ExcelReaderFactory.CreateOpenXmlReader(stream); |                 reader = ExcelReaderFactory.CreateOpenXmlReader(stream); | ||||||
|             } |             } | ||||||
|             return reader; |             return reader; | ||||||
|         } catch (Exception) { |         } catch (Exception) { | ||||||
|             throw; |             throw; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public class ExcelLotInfo { |     public class ExcelLotInfo { | ||||||
|             public string LotNo { get; set; } |         public string? LotNo { get; set; } | ||||||
|             public string LotDispo { get; set; } |         public string? LotDispo { get; set; } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public IEnumerable<ExcelLotInfo> ReadData() { |     public IEnumerable<ExcelLotInfo> ReadData() { | ||||||
|             var r = new List<ExcelLotInfo>(); |         List<ExcelLotInfo> r = new(); | ||||||
|             var excelData = new ExcelData(_path); |         ExcelData excelData = new(_Path); | ||||||
|             var lots = excelData.getData().ToList(); |         List<DataRow> lots = excelData.getData().ToList(); | ||||||
|  |  | ||||||
|         int lotDispoColumnIndex = -1; |         int lotDispoColumnIndex = -1; | ||||||
|         foreach (DataColumn col in lots[0].Table.Columns) { |         foreach (DataColumn col in lots[0].Table.Columns) { | ||||||
| @ -57,7 +58,7 @@ namespace Fab2ApprovalSystem.Misc { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|             foreach (var row in lots) { |         foreach (DataRow row in lots) { | ||||||
|             string temValue = row[0].ToString(); |             string temValue = row[0].ToString(); | ||||||
|             if (temValue.Trim().Length > 0 && temValue.Trim().Length <= 10) { |             if (temValue.Trim().Length > 0 && temValue.Trim().Length <= 10) { | ||||||
|                 r.Add(new ExcelLotInfo() { |                 r.Add(new ExcelLotInfo() { | ||||||
| @ -71,11 +72,10 @@ namespace Fab2ApprovalSystem.Misc { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     public IEnumerable<string> ReadQDBFlagData() { |     public IEnumerable<string> ReadQDBFlagData() { | ||||||
|             List<string> s = new List<string>(); |         List<string> s = new(); | ||||||
|             // We return the interface, so that          |         ExcelData excelData = new(_Path); | ||||||
|             var excelData = new ExcelData(_path); |         IEnumerable<DataRow> lotNos = excelData.getData(); | ||||||
|             var lotNos = excelData.getData(); |         foreach (DataRow row in lotNos) { | ||||||
|             foreach (var row in lotNos) { |  | ||||||
|             string temValue = row[0].ToString(); |             string temValue = row[0].ToString(); | ||||||
|             if (temValue.Trim().Length > 0 && temValue.Trim().Length == 9) { |             if (temValue.Trim().Length > 0 && temValue.Trim().Length == 9) { | ||||||
|                 if (row[2].ToString().ToUpper() != "YES" && row[2].ToString().ToUpper() != "NO") { |                 if (row[2].ToString().ToUpper() != "YES" && row[2].ToString().ToUpper() != "NO") { | ||||||
| @ -89,16 +89,21 @@ namespace Fab2ApprovalSystem.Misc { | |||||||
|         return s; |         return s; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | #if NET8 | ||||||
|  |  | ||||||
|  |     public IEnumerable<DataRow> getData(bool firstRowIsColumnNames = true) => | ||||||
|  |         throw new NotImplementedException(); | ||||||
|  |  | ||||||
|  | #else | ||||||
|  |  | ||||||
|     public IEnumerable<DataRow> getData(bool firstRowIsColumnNames = true) { |     public IEnumerable<DataRow> getData(bool firstRowIsColumnNames = true) { | ||||||
|             var reader = this.getExcelReader(); |         IExcelDataReader reader = getExcelReader(); | ||||||
|         reader.IsFirstRowAsColumnNames = firstRowIsColumnNames; |         reader.IsFirstRowAsColumnNames = firstRowIsColumnNames; | ||||||
|         var workSheet = reader.AsDataSet().Tables[0]; |         var workSheet = reader.AsDataSet().Tables[0]; | ||||||
|         var rows = from DataRow a in workSheet.Rows select a; |         var rows = from DataRow a in workSheet.Rows select a; | ||||||
|         return rows; |         return rows; | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -117,8 +117,8 @@ public class LotDispositionHelper { | |||||||
|     public static void AttachSave(AppSettings appSettings, LotDispositionDMO lotDispositionDMO, int issueID, int userId, string fullFileName, Stream stream) { |     public static void AttachSave(AppSettings appSettings, LotDispositionDMO lotDispositionDMO, int issueID, int userId, string fullFileName, Stream stream) { | ||||||
|         // Some browsers send file names with full path. |         // Some browsers send file names with full path. | ||||||
|         // We are only interested in the file name. |         // We are only interested in the file name. | ||||||
|         var fileName = Path.GetFileName(fullFileName); |         string fileName = Path.GetFileName(fullFileName); | ||||||
|         var physicalPath = Path.Combine(appSettings.AttachmentFolder + "LotDisposition", fileName); |         string physicalPath = Path.Combine(appSettings.AttachmentFolder + "LotDisposition", fileName); | ||||||
|  |  | ||||||
|         using (FileStream fileStream = new(physicalPath, FileMode.Create, FileAccess.Write)) { |         using (FileStream fileStream = new(physicalPath, FileMode.Create, FileAccess.Write)) { | ||||||
|             stream.CopyTo(fileStream); |             stream.CopyTo(fileStream); | ||||||
| @ -134,7 +134,7 @@ public class LotDispositionHelper { | |||||||
|     public static string ExcelLotOpen(LotDispositionDMO lotDispositionDMO, int issueID, string userIdentityName, string lotTempPipeLine, string fullFileName, Stream stream) { |     public static string ExcelLotOpen(LotDispositionDMO lotDispositionDMO, int issueID, string userIdentityName, string lotTempPipeLine, string fullFileName, Stream stream) { | ||||||
|         string physicalPath; |         string physicalPath; | ||||||
|  |  | ||||||
|         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(); |         string fName = userIdentityName + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString(); | ||||||
|  |  | ||||||
|         physicalPath = Path.Combine(lotTempPipeLine, fName + "." + fileExtension); |         physicalPath = Path.Combine(lotTempPipeLine, fName + "." + fileExtension); | ||||||
| @ -142,20 +142,18 @@ public class LotDispositionHelper { | |||||||
|             stream.CopyTo(fileStream); |             stream.CopyTo(fileStream); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| #if !NET8 |         ExcelData x = new (physicalPath); | ||||||
|         ExcelData x = new ExcelData(physicalPath); |         IEnumerable<ExcelData.ExcelLotInfo> lotNumbers = x.ReadData(); | ||||||
|         var lotNumbers = x.ReadData(); |  | ||||||
|  |  | ||||||
|         foreach (var lotInfo in lotNumbers) { |         foreach (ExcelData.ExcelLotInfo lotInfo in lotNumbers) { | ||||||
|             Lot l = new Lot(); |             Lot l = new(); | ||||||
|             l.LotNumber = lotInfo.LotNo; |             l.LotNumber = lotInfo.LotNo ?? string.Empty; | ||||||
|             l.IssueID = issueID; |             l.IssueID = issueID; | ||||||
|             if (l.LotStatusOptionID == 0) |             if (l.LotStatusOptionID == 0) | ||||||
|                 l.LotStatusOption.LotStatusOptionID = (int)GlobalVars.LotStatusOption.Release; |                 l.LotStatusOption.LotStatusOptionID = (int)GlobalVars.LotStatusOption.Release; | ||||||
|  |  | ||||||
|             lotDispositionDMO.InsertLot(l, true); |             lotDispositionDMO.InsertLot(l, true); | ||||||
|         } |         } | ||||||
| #endif |  | ||||||
|  |  | ||||||
|         FileInfo f = new(physicalPath); |         FileInfo f = new(physicalPath); | ||||||
|         if (f.Exists) |         if (f.Exists) | ||||||
|  | |||||||
| @ -46,14 +46,12 @@ public class MRBHelper { | |||||||
|             stream.CopyTo(fileStream); |             stream.CopyTo(fileStream); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| #if !NET8 |         ExcelData x = new(physicalPath); | ||||||
|         ExcelData x = new ExcelData(physicalPath); |  | ||||||
|         lotDataList = x.ReadQDBFlagData(); |         lotDataList = x.ReadQDBFlagData(); | ||||||
|  |  | ||||||
|         foreach (string lotData in lotDataList) { |         foreach (string lotData in lotDataList) { | ||||||
|             mrbDMO.InsertMRB_QDB_HoldFlag(guid, lotData, operation); |             mrbDMO.InsertMRB_QDB_HoldFlag(guid, lotData, operation); | ||||||
|         } |         } | ||||||
| #endif |  | ||||||
|  |  | ||||||
|         FileInfo f = new(physicalPath); |         FileInfo f = new(physicalPath); | ||||||
|         if (f.Exists) |         if (f.Exists) | ||||||
| @ -170,14 +168,12 @@ public class MRBHelper { | |||||||
|             stream.CopyTo(fileStream); |             stream.CopyTo(fileStream); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| #if !NET8 |         ExcelData x = new(physicalPath); | ||||||
|         ExcelData x = new ExcelData(physicalPath); |  | ||||||
|         lotDataList = x.ReadQDBFlagData(); |         lotDataList = x.ReadQDBFlagData(); | ||||||
|  |  | ||||||
|         foreach (string lotData in lotDataList) { |         foreach (string lotData in lotDataList) { | ||||||
|             mrbDMO.InsertMRB_QDB_HoldFlag(guid, lotData, operation); |             mrbDMO.InsertMRB_QDB_HoldFlag(guid, lotData, operation); | ||||||
|         } |         } | ||||||
| #endif |  | ||||||
|  |  | ||||||
|         FileInfo f = new(physicalPath); |         FileInfo f = new(physicalPath); | ||||||
|         if (f.Exists) |         if (f.Exists) | ||||||
| @ -246,17 +242,16 @@ public class MRBHelper { | |||||||
|         string fName = userIdentityName + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString(); |         string fName = userIdentityName + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString(); | ||||||
|         string physicalPath = Path.Combine(lotTempPipeLine, fName + "." + fileExtension); |         string physicalPath = Path.Combine(lotTempPipeLine, fName + "." + fileExtension); | ||||||
|  |  | ||||||
| #if !NET8 |  | ||||||
|         IEnumerable<ExcelData.ExcelLotInfo> lotNumbers; |         IEnumerable<ExcelData.ExcelLotInfo> lotNumbers; | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
|             using (var fileStream = new FileStream(physicalPath, FileMode.Create, FileAccess.Write)) { |             using (FileStream fileStream = new(physicalPath, FileMode.Create, FileAccess.Write)) { | ||||||
|                 stream.CopyTo(fileStream); |                 stream.CopyTo(fileStream); | ||||||
|             } |             } | ||||||
|             ExcelData x = new ExcelData(physicalPath); |             ExcelData x = new(physicalPath); | ||||||
|             lotNumbers = x.ReadData(); |             lotNumbers = x.ReadData(); | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             throw new Exception(String.Format("Invalid file format for {0}: {1}", fileName, ex.Message)); |             throw new Exception(string.Format("Invalid file format for {0}: {1}", fileName, ex.Message)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Get Tool, Issue Start and End Date |         // Get Tool, Issue Start and End Date | ||||||
| @ -266,7 +261,7 @@ public class MRBHelper { | |||||||
|         foreach (var lotInfo in lotNumbers) { |         foreach (var lotInfo in lotNumbers) { | ||||||
|             if (lotInfo.LotDispo.Length == 1) { |             if (lotInfo.LotDispo.Length == 1) { | ||||||
|                 if (dispos.Count(d => d.DispositionType.Trim().ToUpper() == lotInfo.LotDispo.Trim().ToUpper()) == 0) { |                 if (dispos.Count(d => d.DispositionType.Trim().ToUpper() == lotInfo.LotDispo.Trim().ToUpper()) == 0) { | ||||||
|                     throw new Exception(String.Format("Invalid lot disposition {0} for lot no {1}", |                     throw new Exception(string.Format("Invalid lot disposition {0} for lot no {1}", | ||||||
|                         lotInfo.LotDispo, lotInfo.LotNo)); |                         lotInfo.LotDispo, lotInfo.LotNo)); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @ -276,8 +271,8 @@ public class MRBHelper { | |||||||
|         if (!mrbInfo.ToolCSV.ToUpper().Equals("NA")) { |         if (!mrbInfo.ToolCSV.ToUpper().Equals("NA")) { | ||||||
|             foreach (var lotInfo in lotNumbers) { |             foreach (var lotInfo in lotNumbers) { | ||||||
|                 bool existingLotUpdated; |                 bool existingLotUpdated; | ||||||
|                 Lot l = new Lot(); |                 Lot l = new(); | ||||||
|                 l.LotNumber = lotInfo.LotNo; |                 l.LotNumber = lotInfo.LotNo ?? string.Empty; | ||||||
|                 if (lotInfo.LotDispo.Length == 1) { |                 if (lotInfo.LotDispo.Length == 1) { | ||||||
|                     l.DispoType = lotInfo.LotDispo[0]; |                     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 |             // Only find the child Splits when a Tool or a list of Tools is provided | ||||||
|             foreach (var lotInfo in lotNumbers) { |             foreach (var lotInfo in lotNumbers) { | ||||||
|                 bool existingLotUpdated; |                 bool existingLotUpdated; | ||||||
|                 Lot l = new Lot(); |                 Lot l = new(); | ||||||
|                 l.LotNumber = lotInfo.LotNo; |                 l.LotNumber = lotInfo.LotNo ?? string.Empty; | ||||||
|                 if (lotInfo.LotDispo.Length == 1) { |                 if (lotInfo.LotDispo.Length == 1) { | ||||||
|                     l.DispoType = lotInfo.LotDispo[0]; |                     l.DispoType = lotInfo.LotDispo[0]; | ||||||
|                 } |                 } | ||||||
| @ -308,7 +303,6 @@ public class MRBHelper { | |||||||
|                 mrbDMO.InsertLot(l, true, out existingLotUpdated); |                 mrbDMO.InsertLot(l, true, out existingLotUpdated); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| #endif |  | ||||||
|  |  | ||||||
|         FileInfo f = new(physicalPath); |         FileInfo f = new(physicalPath); | ||||||
|         if (f.Exists) |         if (f.Exists) | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ namespace Fab2ApprovalSystem.Models; | |||||||
| public class AppSettings { | public class AppSettings { | ||||||
|  |  | ||||||
|     public AppSettings(string adminNotificationRecepient, |     public AppSettings(string adminNotificationRecepient, | ||||||
|                        string? apiBaseUrl, |                        string apiBaseUrl, | ||||||
|                        string attachmentFolder, |                        string attachmentFolder, | ||||||
|                        string? attachmentUrl, |                        string? attachmentUrl, | ||||||
|                        string caBlankFormsLocation, |                        string caBlankFormsLocation, | ||||||
| @ -46,6 +46,7 @@ public class AppSettings { | |||||||
|                        string urls, |                        string urls, | ||||||
|                        int userId, |                        int userId, | ||||||
|                        bool userIsAdmin, |                        bool userIsAdmin, | ||||||
|  |                        string wasmClientUrl, | ||||||
|                        string wsr_URL, |                        string wsr_URL, | ||||||
|                        string? workingDirectoryName) { |                        string? workingDirectoryName) { | ||||||
|         AdminNotificationRecepient = adminNotificationRecepient; |         AdminNotificationRecepient = adminNotificationRecepient; | ||||||
| @ -88,11 +89,12 @@ public class AppSettings { | |||||||
|         UserId = userId; |         UserId = userId; | ||||||
|         UserIsAdmin = userIsAdmin; |         UserIsAdmin = userIsAdmin; | ||||||
|         WSR_URL = wsr_URL; |         WSR_URL = wsr_URL; | ||||||
|  |         WasmClientUrl = wasmClientUrl; | ||||||
|         WorkingDirectoryName = workingDirectoryName; |         WorkingDirectoryName = workingDirectoryName; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public string AdminNotificationRecepient { get; } |     public string AdminNotificationRecepient { get; } | ||||||
|     public string? ApiBaseUrl { get; } |     public string ApiBaseUrl { get; } | ||||||
|     public string AttachmentFolder { get; } |     public string AttachmentFolder { get; } | ||||||
|     public string? AttachmentUrl { get; } |     public string? AttachmentUrl { get; } | ||||||
|     public string CABlankFormsLocation { get; } |     public string CABlankFormsLocation { get; } | ||||||
| @ -130,6 +132,7 @@ public class AppSettings { | |||||||
|     public string URLs { get; } |     public string URLs { get; } | ||||||
|     public int UserId { get; } |     public int UserId { get; } | ||||||
|     public bool UserIsAdmin { get; } |     public bool UserIsAdmin { get; } | ||||||
|  |     public string WasmClientUrl { get; } | ||||||
|     public string WSR_URL { get; } |     public string WSR_URL { get; } | ||||||
|     public string? WorkingDirectoryName { get; } |     public string? WorkingDirectoryName { get; } | ||||||
|  |  | ||||||
| @ -211,12 +214,15 @@ public class AppSettings { | |||||||
|                 throw new ArgumentNullException("SSRSPassword environment variable not found"); |                 throw new ArgumentNullException("SSRSPassword environment variable not found"); | ||||||
|             string testEmailRecipients = ConfigurationManager.AppSettings["Test Email Recipients"] ?? |             string testEmailRecipients = ConfigurationManager.AppSettings["Test Email Recipients"] ?? | ||||||
|                 throw new ArgumentNullException("Test Email Recipients environment variable not found"); |                 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? attachmentUrl = ConfigurationManager.AppSettings["AttachmentUrl"]?.ToString(); | ||||||
|             string? company = ConfigurationManager.AppSettings["Company"]?.ToString(); |             string? company = ConfigurationManager.AppSettings["Company"]?.ToString(); | ||||||
|             string? smtpServer = ConfigurationManager.AppSettings["SMTP Server"]?.ToString(); |             string? smtpServer = ConfigurationManager.AppSettings["SMTP Server"]?.ToString(); | ||||||
|             string? urls = ConfigurationManager.AppSettings["URLs"]?.ToString(); |             string? urls = ConfigurationManager.AppSettings["URLs"]?.ToString(); | ||||||
|             string? workingDirectoryName = ConfigurationManager.AppSettings["WorkingDirectoryName"]?.ToString(); |             string? workingDirectoryName = ConfigurationManager.AppSettings["WorkingDirectoryName"]?.ToString(); | ||||||
|  |             string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? | ||||||
|  |                 "https://localhost:7255"; | ||||||
|             result = new(adminNotificationRecepient: adminNotificationRecepient, |             result = new(adminNotificationRecepient: adminNotificationRecepient, | ||||||
|                          apiBaseUrl: apiBaseUrl, |                          apiBaseUrl: apiBaseUrl, | ||||||
|                          attachmentFolder: attachmentFolder, |                          attachmentFolder: attachmentFolder, | ||||||
| @ -256,6 +262,7 @@ public class AppSettings { | |||||||
|                          urls: urls, |                          urls: urls, | ||||||
|                          userId: userId, |                          userId: userId, | ||||||
|                          userIsAdmin: Misc.GlobalVars.USER_ISADMIN, |                          userIsAdmin: Misc.GlobalVars.USER_ISADMIN, | ||||||
|  |                          wasmClientUrl: wasmClientUrl, | ||||||
|                          wsr_URL: Misc.GlobalVars.WSR_URL, |                          wsr_URL: Misc.GlobalVars.WSR_URL, | ||||||
|                          workingDirectoryName: workingDirectoryName); |                          workingDirectoryName: workingDirectoryName); | ||||||
|             return result; |             return result; | ||||||
|  | |||||||
| @ -231,6 +231,7 @@ public class CorrectiveAction { | |||||||
|     public DateTime? NextDueDate { get; set; } |     public DateTime? NextDueDate { get; set; } | ||||||
|     public DateTime? FollowUpDate { get; set; } |     public DateTime? FollowUpDate { get; set; } | ||||||
|     public bool CASubmitted { get; set; } |     public bool CASubmitted { get; set; } | ||||||
|  |     public string CAStandardType { get; set; } | ||||||
|     public DateTime? ClosedDate { get; set; } |     public DateTime? ClosedDate { get; set; } | ||||||
|     public CorrectiveAction() { |     public CorrectiveAction() { | ||||||
|         TeamMemberIDs = new List<int>(); |         TeamMemberIDs = new List<int>(); | ||||||
|  | |||||||
| @ -1,28 +0,0 @@ | |||||||
| #if !NET8 |  | ||||||
|  |  | ||||||
| // -------------------------------------------------------------------------------------------------------------------- |  | ||||||
| // <copyright file="FakeView.cs" company="SemanticArchitecture"> |  | ||||||
| //   http://www.SemanticArchitecture.net pkalkie@gmail.com |  | ||||||
| // </copyright> |  | ||||||
| // <summary> |  | ||||||
| //   Defines the FakeView type. |  | ||||||
| // </summary> |  | ||||||
| // -------------------------------------------------------------------------------------------------------------------- |  | ||||||
|  |  | ||||||
| namespace Fab2ApprovalSystem.PdfGenerator { |  | ||||||
|     using System; |  | ||||||
|     using System.IO; |  | ||||||
|     using System.Web.Mvc; |  | ||||||
|  |  | ||||||
|     public class FakeView : IView { |  | ||||||
|         #region IView Members |  | ||||||
|  |  | ||||||
|         public void Render(ViewContext viewContext, TextWriter writer) { |  | ||||||
|             throw new NotImplementedException(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         #endregion |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
| @ -1,49 +0,0 @@ | |||||||
| #if !NET8 |  | ||||||
|  |  | ||||||
| // -------------------------------------------------------------------------------------------------------------------- |  | ||||||
| // <copyright file="HtmlViewRenderer.cs" company="SemanticArchitecture"> |  | ||||||
| //   http://www.SemanticArchitecture.net pkalkie@gmail.com |  | ||||||
| // </copyright> |  | ||||||
| // <summary> |  | ||||||
| //   This class is responsible for rendering a HTML view to a string. |  | ||||||
| // </summary> |  | ||||||
| // -------------------------------------------------------------------------------------------------------------------- |  | ||||||
|  |  | ||||||
| namespace Fab2ApprovalSystem.PdfGenerator { |  | ||||||
|     using System.IO; |  | ||||||
|     using System.Text; |  | ||||||
|     using System.Web; |  | ||||||
|     using System.Web.Mvc; |  | ||||||
|     using System.Web.Mvc.Html; |  | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// This class is responsible for rendering a HTML view into a string.  |  | ||||||
|     /// </summary> |  | ||||||
|     public class HtmlViewRenderer { |  | ||||||
|         public string RenderViewToString(Controller controller, string viewName, object viewData) { |  | ||||||
|             var renderedView = new StringBuilder(); |  | ||||||
|             using (var responseWriter = new StringWriter(renderedView)) { |  | ||||||
|                 var fakeResponse = new HttpResponse(responseWriter); |  | ||||||
|                 var fakeContext = new HttpContext(HttpContext.Current.Request, fakeResponse); |  | ||||||
|                 var fakeControllerContext = new ControllerContext(new HttpContextWrapper(fakeContext), controller.ControllerContext.RouteData, controller.ControllerContext.Controller); |  | ||||||
|  |  | ||||||
|                 var oldContext = HttpContext.Current; |  | ||||||
|                 HttpContext.Current = fakeContext; |  | ||||||
|  |  | ||||||
|                 using (var viewPage = new ViewPage()) { |  | ||||||
|                     var html = new HtmlHelper(CreateViewContext(responseWriter, fakeControllerContext), viewPage); |  | ||||||
|                     html.RenderPartial(viewName, viewData); |  | ||||||
|                     HttpContext.Current = oldContext; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             return renderedView.ToString(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         private static ViewContext CreateViewContext(TextWriter responseWriter, ControllerContext fakeControllerContext) { |  | ||||||
|             return new ViewContext(fakeControllerContext, new FakeView(), new ViewDataDictionary(), new TempDataDictionary(), responseWriter); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
| @ -1,54 +0,0 @@ | |||||||
| #if !NET8 |  | ||||||
|  |  | ||||||
| // -------------------------------------------------------------------------------------------------------------------- |  | ||||||
| // <copyright file="PdfViewController.cs" company="SemanticArchitecture"> |  | ||||||
| //   http://www.SemanticArchitecture.net pkalkie@gmail.com |  | ||||||
| // </copyright> |  | ||||||
| // <summary> |  | ||||||
| //   Extends the controller with functionality for rendering PDF views |  | ||||||
| // </summary> |  | ||||||
| // -------------------------------------------------------------------------------------------------------------------- |  | ||||||
|  |  | ||||||
| namespace Fab2ApprovalSystem.PdfGenerator { |  | ||||||
|     using System.Web.Mvc; |  | ||||||
|     using System.IO; |  | ||||||
|  |  | ||||||
|     /// <summary> |  | ||||||
|     /// Extends the controller with functionality for rendering PDF views |  | ||||||
|     /// </summary> |  | ||||||
|     public class PdfViewController : Controller { |  | ||||||
|         private readonly HtmlViewRenderer htmlViewRenderer; |  | ||||||
|         private readonly StandardPdfRenderer standardPdfRenderer; |  | ||||||
|  |  | ||||||
|         public PdfViewController() { |  | ||||||
|             this.htmlViewRenderer = new HtmlViewRenderer(); |  | ||||||
|             this.standardPdfRenderer = new StandardPdfRenderer(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         protected ActionResult ViewPdf(string pageTitle, string viewName, object model) { |  | ||||||
|             // Render the view html to a string. |  | ||||||
|             string htmlText = this.htmlViewRenderer.RenderViewToString(this, viewName, model); |  | ||||||
|  |  | ||||||
|             // Let the html be rendered into a PDF document through iTextSharp. |  | ||||||
|             byte[] buffer = standardPdfRenderer.Render(htmlText, pageTitle); |  | ||||||
|  |  | ||||||
|             // Return the PDF as a binary stream to the client. |  | ||||||
|             return new BinaryContentResult(buffer, "application/pdf"); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         protected void SavePdf(string fileName, string viewName, object model) { |  | ||||||
|             // Render the view html to a string. |  | ||||||
|             string htmlText = this.htmlViewRenderer.RenderViewToString(this, viewName, model); |  | ||||||
|  |  | ||||||
|             // Let the html be rendered into a PDF document through iTextSharp. |  | ||||||
|             byte[] buffer = standardPdfRenderer.Render(htmlText, ""); |  | ||||||
|  |  | ||||||
|             using (FileStream fs = new FileStream(fileName, FileMode.Create)) { |  | ||||||
|                 fs.Write(buffer, 0, buffer.Length); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
| @ -1,27 +1,38 @@ | |||||||
| #if !NET8 |  | ||||||
| using iTextSharp.text; | using iTextSharp.text; | ||||||
| using iTextSharp.text.html.simpleparser; | using iTextSharp.text.html.simpleparser; | ||||||
| using iTextSharp.text.pdf; | using iTextSharp.text.pdf; | ||||||
| #endif |  | ||||||
|  |  | ||||||
| using System.IO; | using System.IO; | ||||||
|  |  | ||||||
| namespace Fab2ApprovalSystem.PdfGenerator; | namespace Fab2ApprovalSystem.PdfGenerator; | ||||||
|  |  | ||||||
| /// <summary> |  | ||||||
| /// This class is responsible for rendering a html text string to a PDF document using the html renderer of iTextSharp. |  | ||||||
| /// </summary> |  | ||||||
| public class StandardPdfRenderer { | public class StandardPdfRenderer { | ||||||
|  |  | ||||||
|     private const int HorizontalMargin = 40; |     private const int HorizontalMargin = 40; | ||||||
|     private const int VerticalMargin = 40; |     private const int VerticalMargin = 40; | ||||||
|  |  | ||||||
|     public byte[] Render(string htmlText, string pageTitle) { |     public static byte[] GetPortableDocumentFormatBytes(string pageTitle, string htmlText) { | ||||||
|         byte[] renderedBuffer; |         byte[] results; | ||||||
|  |         using (MemoryStream memoryStream = GetPortableDocumentFormat(pageTitle, htmlText)) { | ||||||
|  |             results = new byte[memoryStream.Position]; | ||||||
|  |             memoryStream.Position = 0; | ||||||
|  |             memoryStream.Read(results, 0, results.Length); | ||||||
|  |         } | ||||||
|  |         return results; | ||||||
|  |     } | ||||||
|  |  | ||||||
|         using (MemoryStream outputMemoryStream = new()) { |     public static void WritePortableDocumentFormatToFile(string pageTitle, string htmlText, string path) { | ||||||
| #if !NET8 |         using (MemoryStream memoryStream = GetPortableDocumentFormat(pageTitle, htmlText)) { | ||||||
|  |             using (FileStream fileStream = new(path, FileMode.Create)) { | ||||||
|  |                 memoryStream.CopyTo(fileStream); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static MemoryStream GetPortableDocumentFormat(string pageTitle, string htmlText) { | ||||||
|  |         MemoryStream result = new(); | ||||||
|         using (Document pdfDocument = new Document(PageSize.A4, HorizontalMargin, HorizontalMargin, VerticalMargin, VerticalMargin)) { |         using (Document pdfDocument = new Document(PageSize.A4, HorizontalMargin, HorizontalMargin, VerticalMargin, VerticalMargin)) { | ||||||
|                 PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDocument, outputMemoryStream); |             using (PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDocument, result)) { | ||||||
|                 pdfWriter.CloseStream = false; |                 pdfWriter.CloseStream = false; | ||||||
|                 pdfWriter.PageEvent = new PrintHeaderFooter { Title = pageTitle }; |                 pdfWriter.PageEvent = new PrintHeaderFooter { Title = pageTitle }; | ||||||
|                 pdfDocument.Open(); |                 pdfDocument.Open(); | ||||||
| @ -30,15 +41,9 @@ public class StandardPdfRenderer { | |||||||
|                         htmlWorker.Parse(htmlViewReader); |                         htmlWorker.Parse(htmlViewReader); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|             } |             } | ||||||
| #endif |         } | ||||||
|  |         return result; | ||||||
|             renderedBuffer = new byte[outputMemoryStream.Position]; |  | ||||||
|             outputMemoryStream.Position = 0; |  | ||||||
|             outputMemoryStream.Read(renderedBuffer, 0, renderedBuffer.Length); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|         return renderedBuffer; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| @ -30,7 +30,7 @@ public class ECNPdf { | |||||||
|     public string AffectedDepartments { get; set; } |     public string AffectedDepartments { get; set; } | ||||||
|     public string AffectedAreas { get; set; } |     public string AffectedAreas { get; set; } | ||||||
|     public string AffectedTechnologies { get; set; } |     public string AffectedTechnologies { get; set; } | ||||||
|     public string TrainingBy { get; set; } |     public List<int> TrainingByIDs { get; set; } | ||||||
|     public string AcknowledgementBy { get; set; } |     public string AcknowledgementBy { get; set; } | ||||||
|     public bool IsECN { get; set; } |     public bool IsECN { get; set; } | ||||||
|     public bool IsTECN { get; set; } |     public bool IsTECN { get; set; } | ||||||
| @ -79,6 +79,7 @@ public class ECNPdf { | |||||||
|     public int? ConvertedToNumber { get; set; } |     public int? ConvertedToNumber { get; set; } | ||||||
|     public int? ConvertedFromNumber { get; set; } |     public int? ConvertedFromNumber { get; set; } | ||||||
|     public int WorkFlowNumber { get; set; } |     public int WorkFlowNumber { get; set; } | ||||||
|  |     public int? CategoryID { get; set; } | ||||||
|     public bool FIChangeRequired { get; set; } |     public bool FIChangeRequired { get; set; } | ||||||
|     public string NumberOfLotsAffected { get; set; } |     public string NumberOfLotsAffected { get; set; } | ||||||
|     public string RecipeChange { get; set; } |     public string RecipeChange { get; set; } | ||||||
| @ -87,6 +88,7 @@ public class ECNPdf { | |||||||
|     public ECNPdf() { |     public ECNPdf() { | ||||||
|         Approvalog = new List<ECNApprovalLog>(); |         Approvalog = new List<ECNApprovalLog>(); | ||||||
|         Attachments = new List<string>(); |         Attachments = new List<string>(); | ||||||
|  |         TrainingByIDs = new List<int>(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -380,6 +380,43 @@ | |||||||
|                             </div> |                             </div> | ||||||
|                         </div> |                         </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> | ||||||
|                 <div class="row"> |                 <div class="row"> | ||||||
|                     <div class="col-sm-3"> |                     <div class="col-sm-3"> | ||||||
| @ -2176,6 +2213,7 @@ | |||||||
|             $('#txtApprovedDate').attr("disabled", true); |             $('#txtApprovedDate').attr("disabled", true); | ||||||
|             $('#txtRelatedMRB').attr("disabled", true); |             $('#txtRelatedMRB').attr("disabled", true); | ||||||
|             $('#CATypeList').data("kendoDropDownList").enable(false); |             $('#CATypeList').data("kendoDropDownList").enable(false); | ||||||
|  |             $('#CAStandardTypeList').data("kendoDropDownList").enable(false); | ||||||
|             $('#d0Comments').attr("disabled", true); |             $('#d0Comments').attr("disabled", true); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @ -3689,6 +3727,7 @@ | |||||||
|             TeamCaptainID: $("#TeamCaptainList").data("kendoDropDownList").value(), |             TeamCaptainID: $("#TeamCaptainList").data("kendoDropDownList").value(), | ||||||
|             CASponsorID: $("#CASponsorList").data("kendoDropDownList").value(), |             CASponsorID: $("#CASponsorList").data("kendoDropDownList").value(), | ||||||
|             CASubmitted: isCASubmitted, |             CASubmitted: isCASubmitted, | ||||||
|  |             CAStandardType : $("#CAStandardTypeList").data("kendoDropDownList").value(), | ||||||
|  |  | ||||||
|             //D0 |             //D0 | ||||||
|             D0Comments : $("#d0Comments").val(), |             D0Comments : $("#d0Comments").val(), | ||||||
|  | |||||||
| @ -325,6 +325,16 @@ | |||||||
|                             </div> |                             </div> | ||||||
|                         </div> |                         </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> | ||||||
|                 <div class="row"> |                 <div class="row"> | ||||||
|                     <div class="col-sm-3"> |                     <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" }) |                             @Html.TextBoxFor(model => model.Title, new { id = "txtTitle", @class = "k-textbox", style = "width:100%", disabled = "disabled" }) | ||||||
|                         </div> |                         </div> | ||||||
|                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> |                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> | ||||||
|                             *(DO NOT USE Rev I, O, Q, S, X, and Z) |                             * (DO NOT USE Rev I, O, Q, S, X, and Z) | ||||||
|                         </div> |                         </div> | ||||||
|                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> |                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> | ||||||
|                             Revision Y is followed by AA. 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> |                     </div> | ||||||
|                     <div class="form-group"> |                     <div class="form-group"> | ||||||
|  | |||||||
| @ -1,5 +1,19 @@ | |||||||
| @model Fab2ApprovalSystem.ViewModels.ECNPdf | @model Fab2ApprovalSystem.ViewModels.ECNPdf | ||||||
| <table style="width:100%;"> | @{ | ||||||
|  |     Layout = null; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | <!DOCTYPE html> | ||||||
|  |  | ||||||
|  | <head> | ||||||
|  |     <meta charset="utf-8" /> | ||||||
|  |     <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||||||
|  |     <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||||||
|  |     <title></title> | ||||||
|  | </head> | ||||||
|  |  | ||||||
|  | <body class="navbar-inner"> | ||||||
|  |     <table style="width:100%;"> | ||||||
|         <tr> |         <tr> | ||||||
|             <td> |             <td> | ||||||
|                 <table cellpadding="3" cellspacing="3" border="1"> |                 <table cellpadding="3" cellspacing="3" border="1"> | ||||||
| @ -84,6 +98,16 @@ | |||||||
|                                         </font> |                                         </font> | ||||||
|                                     </td> |                                     </td> | ||||||
|                                 </tr> |                                 </tr> | ||||||
|  |                                 <tr> | ||||||
|  |                                     <td> | ||||||
|  |                                         <font size="2"> | ||||||
|  |                                             Category:  | ||||||
|  |                                         </font> | ||||||
|  |                                         <font size="1"> | ||||||
|  |                                             @(ViewBag.Category) | ||||||
|  |                                         </font> | ||||||
|  |                                     </td> | ||||||
|  |                                 </tr> | ||||||
|                                 <tr> |                                 <tr> | ||||||
|                                     <td> |                                     <td> | ||||||
|                                         <font size="2"> |                                         <font size="2"> | ||||||
| @ -97,7 +121,6 @@ | |||||||
|                             </table> |                             </table> | ||||||
|                         </td> |                         </td> | ||||||
|                     </tr> |                     </tr> | ||||||
|                  |  | ||||||
|                 </table> |                 </table> | ||||||
|             </td> |             </td> | ||||||
|         </tr> |         </tr> | ||||||
| @ -217,14 +240,13 @@ | |||||||
|                         </td> |                         </td> | ||||||
|                     </tr> |                     </tr> | ||||||
|  |  | ||||||
|                  |  | ||||||
|                 </table> |                 </table> | ||||||
|             </td> |             </td> | ||||||
|         </tr> |         </tr> | ||||||
|  |  | ||||||
|         <tr> |         <tr> | ||||||
|             <td> |             <td> | ||||||
|             <table border="1" > |                 <table border="1"> | ||||||
|                     <tr bgcolor="#c4baba" color="#000000"> |                     <tr bgcolor="#c4baba" color="#000000"> | ||||||
|                         <td> Description of Change</td> |                         <td> Description of Change</td> | ||||||
|                         <td> Reason for Change</td> |                         <td> Reason for Change</td> | ||||||
| @ -244,35 +266,6 @@ | |||||||
|                 </table> |                 </table> | ||||||
|             </td> |             </td> | ||||||
|         </tr> |         </tr> | ||||||
|     @*<tr> |  | ||||||
|         <td> |  | ||||||
|  |  | ||||||
|             <table border="1"> |  | ||||||
|                 <tr bgcolor="#c4baba" color="#000000"> |  | ||||||
|                     <td colspan="3">Training Notification</td>                     |  | ||||||
|                 </tr> |  | ||||||
|                 <tr> |  | ||||||
|                     <td> |  | ||||||
|                        <table border="0"> |  | ||||||
|                            <tr> |  | ||||||
|                                <td> |  | ||||||
|                                    <font size="1"> |  | ||||||
|                                        Training: |  | ||||||
|                                        @(Model.TrainingRequired ? "Yes" : "No") |  | ||||||
|                                    </font> |  | ||||||
|                                |  | ||||||
|                                    <font size="1"> |  | ||||||
|                                        @(Model.TrainingBy.Length > 0 ? "(" + Model.TrainingBy + ")" : Model.TrainingBy)                                        |  | ||||||
|                                    </font> |  | ||||||
|                                </td> |  | ||||||
|                            </tr> |  | ||||||
|                        </table> |  | ||||||
|                     </td> |  | ||||||
|                 </tr> |  | ||||||
|             </table> |  | ||||||
|  |  | ||||||
|         </td> |  | ||||||
|     </tr>*@ |  | ||||||
|         <tr> |         <tr> | ||||||
|             <td> |             <td> | ||||||
|  |  | ||||||
| @ -286,7 +279,7 @@ | |||||||
|                                 PCRB: |                                 PCRB: | ||||||
|                             </font> |                             </font> | ||||||
|                             <font size="1"> |                             <font size="1"> | ||||||
|                             @(Model.PCRBRequired ? "Yes": "No") |                                 @(Model.PCRBRequired ? "Yes" : "No") | ||||||
|                             </font> |                             </font> | ||||||
|                         </td> |                         </td> | ||||||
|                         <td> |                         <td> | ||||||
| @ -300,7 +293,7 @@ | |||||||
|                                 Metrology Change:    |                                 Metrology Change:    | ||||||
|                             </font> |                             </font> | ||||||
|                             <font size="1"> |                             <font size="1"> | ||||||
|                             @(Model.MetrologyChangeRequired ? "Yes": "No") |                                 @(Model.MetrologyChangeRequired ? "Yes" : "No") | ||||||
|                             </font> |                             </font> | ||||||
|                         </td> |                         </td> | ||||||
|                         <td> |                         <td> | ||||||
| @ -308,7 +301,7 @@ | |||||||
|                                 SPC Change: |                                 SPC Change: | ||||||
|                             </font> |                             </font> | ||||||
|                             <font size="1"> |                             <font size="1"> | ||||||
|                             @(Model.SPCChangeRequired ? "Yes": "No") |                                 @(Model.SPCChangeRequired ? "Yes" : "No") | ||||||
|                             </font> |                             </font> | ||||||
|                         </td> |                         </td> | ||||||
|                         <td> |                         <td> | ||||||
| @ -327,11 +320,35 @@ | |||||||
|                                 @(Model.SPNChangeRequired ? "Yes" : "No") |                                 @(Model.SPNChangeRequired ? "Yes" : "No") | ||||||
|                             </font> |                             </font> | ||||||
|                         </td> |                         </td> | ||||||
|                     <td></td> |  | ||||||
|                     </tr> |                     </tr> | ||||||
|                  |  | ||||||
|                 </table> |                 </table> | ||||||
|  |  | ||||||
|  |             </td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |             <td> | ||||||
|  |  | ||||||
|  |                 <table border="1"> | ||||||
|  |                     <tr bgcolor="#c4baba" color="#000000"> | ||||||
|  |                         <td colspan="1">Training Notification</td> | ||||||
|  |                     </tr> | ||||||
|  |                     <tr style="display:block;"> | ||||||
|  |                         <td> | ||||||
|  |                             <font size="2"> | ||||||
|  |                                 Training: | ||||||
|  |                             </font> | ||||||
|  |                             <font size="1"> | ||||||
|  |                                 @(Model.TrainingRequired ? "Yes" : "No") | ||||||
|  |                             </font> | ||||||
|  |                         </td> | ||||||
|  |                         <td> | ||||||
|  |                             <font size="2"> | ||||||
|  |                                 Training Notification to:   | ||||||
|  |                                 @(ViewBag.TrainingNotificationTo) | ||||||
|  |                             </font> | ||||||
|  |                         </td> | ||||||
|  |                     </tr> | ||||||
|  |                 </table> | ||||||
|  |  | ||||||
|             </td> |             </td> | ||||||
|         </tr> |         </tr> | ||||||
| @ -479,19 +496,11 @@ | |||||||
|                         </tr> |                         </tr> | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|  |  | ||||||
|                 </table> |                 </table> | ||||||
|             </td> |             </td> | ||||||
|         </tr> |         </tr> | ||||||
|  |  | ||||||
|  |     </table> | ||||||
|  | </body> | ||||||
|  |  | ||||||
| </table> <!--main table --> | </html> | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|      |  | ||||||
|  |  | ||||||
|     |  | ||||||
|      |  | ||||||
|      |  | ||||||
| @ -154,10 +154,10 @@ | |||||||
|                             @Html.TextBoxFor(model => model.Title, new { id = "txtTitle", @class = "k-textbox", style = "width:100%" }) |                             @Html.TextBoxFor(model => model.Title, new { id = "txtTitle", @class = "k-textbox", style = "width:100%" }) | ||||||
|                         </div> |                         </div> | ||||||
|                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> |                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> | ||||||
|                             *(DO NOT USE Rev I, O, Q, S, X, and Z) |                             * (DO NOT USE Rev I, O, Q, S, X, and Z) | ||||||
|                         </div> |                         </div> | ||||||
|                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> |                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> | ||||||
|                             Revision Y is followed by AA. 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> |                     </div> | ||||||
|                     <div class="form-group"> |                     <div class="form-group"> | ||||||
|  | |||||||
| @ -86,30 +86,48 @@ | |||||||
|  |  | ||||||
|                 if (Model.IsTECN && !Model.CancellationInProgress && !Model.CancellationApproved && !Model.ExpirationInProgress |                 if (Model.IsTECN && !Model.CancellationInProgress && !Model.CancellationApproved && !Model.ExpirationInProgress | ||||||
|                     && !Model.ExpirationProcessed && !Model.Converted |                     && !Model.ExpirationProcessed && !Model.Converted | ||||||
|                     && !Model.LockedForConversion |                     && !Model.LockedForConversion) | ||||||
|                     && (Model.ExpirationDate > DateTime.Today || Model.ExtensionDate > DateTime.Today)) |  | ||||||
|                 { |                 { | ||||||
|                     ViewBag.CanResubmit = "true"; |                     ViewBag.CanResubmit = "true"; | ||||||
|                     <input type="button" value="Change Type" class="btn btn-primary btn-xs" id="ReSubmitDocument" disabled="disabled" /> |                     <input type="button" value="Change Type" class="btn btn-primary btn-xs" id="ReSubmitDocument" disabled="disabled" /> | ||||||
|  |                     if (Model.ExpirationDate > DateTime.Today || Model.ExtensionDate > DateTime.Today) | ||||||
|  |                     { | ||||||
|                         <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" /> |                         <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 |                 else if (Model.IsTECN && !Model.CancellationInProgress && !Model.CancellationApproved && !Model.ExpirationInProgress | ||||||
|                     && !Model.ExpirationProcessed |                     && !Model.ExpirationProcessed | ||||||
|                     && Model.ConversionApprovalInProgress == false |                     && Model.ConversionApprovalInProgress == false) | ||||||
|                     && (Model.ExpirationDate >= DateTime.Today || Model.ExtensionDate >= DateTime.Today)) |                 { | ||||||
|  |                     if (Model.ExpirationDate > DateTime.Today || Model.ExtensionDate > DateTime.Today) | ||||||
|                     { |                     { | ||||||
|                         <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" /> |                         <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 |                 else if (Model.IsEmergencyTECN && !Model.CancellationInProgress && !Model.CancellationApproved && !Model.ExpirationInProgress | ||||||
|                     && !Model.ExpirationProcessed && !Model.Converted |                     && !Model.ExpirationProcessed && !Model.Converted) | ||||||
|                         && (Model.ExpirationDate > DateTime.Today || Model.ExtensionDate > DateTime.Today)) |  | ||||||
|                 { |                 { | ||||||
|                     ViewBag.CanResubmit = "true"; |                     ViewBag.CanResubmit = "true"; | ||||||
|                     <input type="button" value="Change Type" class="btn btn-primary btn-xs" id="ReSubmitDocument" disabled="disabled" /> |                     <input type="button" value="Change Type" class="btn btn-primary btn-xs" id="ReSubmitDocument" disabled="disabled" /> | ||||||
|  |                     if (Model.ExpirationDate > DateTime.Today || Model.ExtensionDate > DateTime.Today) | ||||||
|  |                     { | ||||||
|                         <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" /> |                         <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" /> | ||||||
|                     } |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                         <input type="button" value="Return to Process" class="btn btn-primary btn-xs" id="ReturnToProcessDocument" /> | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             <input type="button" value="PRINT PDF" class="btn btn-primary btn-xs" id="PrintPDF" /> |             <input type="button" value="PRINT PDF" class="btn btn-primary btn-xs" id="PrintPDF" /> | ||||||
| @ -242,10 +260,10 @@ | |||||||
|                             @Html.TextBoxFor(model => model.Title, new { id = "txtTitle", @class = "k-textbox", style = "width:100%", disabled = "disabled" }) |                             @Html.TextBoxFor(model => model.Title, new { id = "txtTitle", @class = "k-textbox", style = "width:100%", disabled = "disabled" }) | ||||||
|                         </div> |                         </div> | ||||||
|                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> |                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> | ||||||
|                             *(DO NOT USE Rev I, O, Q, S, X, and Z) |                             * (DO NOT USE Rev I, O, Q, S, X, and Z) | ||||||
|                         </div> |                         </div> | ||||||
|                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> |                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> | ||||||
|                             Revision Y is followed by AA. 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> |                     </div> | ||||||
|                     <div class="form-group"> |                     <div class="form-group"> | ||||||
| @ -1251,6 +1269,9 @@ | |||||||
|     </div> |     </div> | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
|  | @Html.Partial("_ECNCancel") | ||||||
|  | @Html.Partial("_ECNReturnToProcess") | ||||||
|  |  | ||||||
| @Html.Partial("_ECNReassignOriginator") | @Html.Partial("_ECNReassignOriginator") | ||||||
|  |  | ||||||
| <script type="text/javascript"> | <script type="text/javascript"> | ||||||
| @ -2188,40 +2209,6 @@ | |||||||
|         return false; |         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 returnNoOfDays = function () { | ||||||
|         //var start = new Date($('#txSubmitDate').val()); |         //var start = new Date($('#txSubmitDate').val()); | ||||||
|         var start = new Date(); |         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 encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); | ||||||
|                             string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? |                             string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? | ||||||
|                                 "https://localhost:7255"; |                                 "https://localhost:7255"; | ||||||
|                             string mrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=/mrb/new"; |                             string mrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=mrb/new"; | ||||||
|                             <li><a href="@mrbUrl">Create MRB</a></li> |                             <li><a href="@mrbUrl">Create MRB</a></li> | ||||||
|                             @*string pcrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=/pcrb/new"; |                             string pcrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=pcrb/new"; | ||||||
|                             <li><a href="@pcrbUrl">Create PCRB</a></li>*@ |                             <li><a href="@pcrbUrl">Create PCRB</a></li> | ||||||
|                         } else { |                         } else { | ||||||
|                             string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? |                             string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? | ||||||
|                                                         "https://localhost:7255"; |                                                         "https://localhost:7255"; | ||||||
|                             string mrbUrl = wasmClientUrl + "/redirect?redirectPath=/mrb/new"; |                             string mrbUrl = wasmClientUrl + "/redirect?redirectPath=mrb/new"; | ||||||
|                             <li><a href="@mrbUrl">Create MRB</a></li> |                             <li><a href="@mrbUrl">Create MRB</a></li> | ||||||
|                             @*string pcrbUrl = wasmClientUrl + "/redirect?redirectPath=/pcrb/new"; |                             string pcrbUrl = wasmClientUrl + "/redirect?redirectPath=pcrb/new"; | ||||||
|                             <li><a href="@pcrbUrl">Create PCRB</a></li>*@ |                             <li><a href="@pcrbUrl">Create PCRB</a></li> | ||||||
|                         } |                         } | ||||||
|                         @*<li><a href=@Url.Action("CreateWorkRequest", "LotTraveler")>Create Special Work Request</a></li>*@ |                         @*<li><a href=@Url.Action("CreateWorkRequest", "LotTraveler")>Create Special Work Request</a></li>*@ | ||||||
|                         @*<li><a href=@Url.Action("Create", "ChangeControl")>Create PCR</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 encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); | ||||||
|             string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? |             string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? | ||||||
|                 "https://localhost:7255"; |                 "https://localhost:7255"; | ||||||
|             string mrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=/mrb/all"; |             string mrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=mrb/all"; | ||||||
|             menu.Add().Text("MRB").Url(mrbUrl); |             menu.Add().Text("MRB").Url(mrbUrl); | ||||||
|             //string pcrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=/pcrb/all"; |             string pcrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=pcrb/all"; | ||||||
|             //menu.Add().Text("PCRB").Url(pcrbUrl); |             menu.Add().Text("PCRB").Url(pcrbUrl); | ||||||
|             //menu.Add().Text("Special Work Requests").Action("SpecialWorkRequestList", "Home"); |             //menu.Add().Text("Special Work Requests").Action("SpecialWorkRequestList", "Home"); | ||||||
|             //menu.Add().Text("PCRB").Action("ChangeControlList", "Home"); |             //menu.Add().Text("PCRB").Action("ChangeControlList", "Home"); | ||||||
|             //menu.Add().Text("MRB").Action("MRBList", "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) { |     private static void GetMyOpenActionItems(ILogger? logger, AppSettings appSettings) { | ||||||
|         SetGlobalVars(logger, appSettings); |         SetGlobalVars(logger, appSettings); | ||||||
|         LotDispositionDMO lotDispositionDMO = new(appSettings); |         LotDispositionDMO lotDispositionDMO = new(); | ||||||
|         OpenActionItemViewModel[] openActionItemViewModels = lotDispositionDMO.GetMyOpenActionItems(appSettings.UserId).ToArray(); |         OpenActionItemViewModel[] openActionItemViewModels = lotDispositionDMO.GetMyOpenActionItems(appSettings.UserId).ToArray(); | ||||||
|         if (openActionItemViewModels.Length == 0) { } |         if (openActionItemViewModels.Length == 0) { } | ||||||
|     } |     } | ||||||
| @ -76,7 +76,7 @@ public class HomeControllerTests { | |||||||
|  |  | ||||||
|     private static void GetTaskList(ILogger? logger, AppSettings appSettings) { |     private static void GetTaskList(ILogger? logger, AppSettings appSettings) { | ||||||
|         SetGlobalVars(logger, appSettings); |         SetGlobalVars(logger, appSettings); | ||||||
|         LotDispositionDMO lotDispositionDMO = new(appSettings); |         LotDispositionDMO lotDispositionDMO = new(); | ||||||
|         IssuesViewModel[] issuesViewModels = lotDispositionDMO.GetTaskList(appSettings.UserId).ToArray(); |         IssuesViewModel[] issuesViewModels = lotDispositionDMO.GetTaskList(appSettings.UserId).ToArray(); | ||||||
|         if (issuesViewModels.Length == 0) { } |         if (issuesViewModels.Length == 0) { } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -56,8 +56,8 @@ public class AdminDMOTests { | |||||||
|         AdminDMO adminDMO = new(); |         AdminDMO adminDMO = new(); | ||||||
|         // void AddNewTrainingGroup(string groupName); |         // void AddNewTrainingGroup(string groupName); | ||||||
|         // void AddUserRoles(int subRole, string userids); |         // void AddUserRoles(int subRole, string userids); | ||||||
|         // void AddUserToGroup(int userId, int groupId); |         // void AddUserToGroup(appSettings.UserId, int groupId); | ||||||
|         // void DeleteFromGroup(int userId, int groupId); |         // void DeleteFromGroup(appSettings.UserId, int groupId); | ||||||
|         // void DeleteTrainingGroup(int groupID); |         // void DeleteTrainingGroup(int groupID); | ||||||
|         // adminDMO.DeleteUserFromAllTrainingGroups(appSettings.UserId); |         // adminDMO.DeleteUserFromAllTrainingGroups(appSettings.UserId); | ||||||
|         // void DeleteUserRoles(int subRole, string userids); |         // void DeleteUserRoles(int subRole, string userids); | ||||||
|  | |||||||
| @ -51,7 +51,7 @@ public class AuditDMOTests { | |||||||
|         try { throw new Exception(); } catch (Exception) { } |         try { throw new Exception(); } catch (Exception) { } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static void AuditDMO(ILogger? logger, AppSettings appSettings) { |     private static void AuditDMO(ILogger? logger, AppSettings appSettings, int auditNo, bool isAdmin) { | ||||||
| #pragma warning disable IDE0059 | #pragma warning disable IDE0059 | ||||||
|         SetGlobalVars(logger, appSettings); |         SetGlobalVars(logger, appSettings); | ||||||
|         AuditDMO auditDMO = new(appSettings); |         AuditDMO auditDMO = new(appSettings); | ||||||
| @ -61,25 +61,25 @@ public class AuditDMOTests { | |||||||
|         AuditedArea[] auditedAreas = auditDMO.GetAuditAreaList().ToArray(); |         AuditedArea[] auditedAreas = auditDMO.GetAuditAreaList().ToArray(); | ||||||
|         // IEnumerable<int> GetAuditFindingCategoryIdsByFindingId(int auditFindingsID); |         // IEnumerable<int> GetAuditFindingCategoryIdsByFindingId(int auditFindingsID); | ||||||
|         // AuditFindings GetAuditFindingsByID(int auditFindingsID); |         // AuditFindings GetAuditFindingsByID(int auditFindingsID); | ||||||
|         // IEnumerable<AuditFindings> GetAuditFindingsList(int auditNo); |         AuditFindings[] auditFindings = auditDMO.GetAuditFindingsList(auditNo).ToArray(); | ||||||
|         // Audit GetAuditItem(int auditNo, int userID); |         Audit auditB = auditDMO.GetAuditItem(auditNo, appSettings.UserId); | ||||||
|         // Audit GetAuditItemReadOnly(int auditNo, int 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(); |         Auditor[] auditors = auditDMO.GetAuditorList().ToArray(); | ||||||
|         // IEnumerable<AuditReportAttachment> GetAuditReportAttachments(int auditNo); |         AuditReportAttachment[] auditReportAttachments = auditDMO.GetAuditReportAttachments(auditNo).ToArray(); | ||||||
|         // C_8DAuditedStandard[] c_8DAuditedStandards = auditDMO.GetAuditStandardList().ToArray(); |         // C_8DAuditedStandard[] c_8DAuditedStandards = auditDMO.GetAuditStandardList().ToArray(); | ||||||
|         AuditType[] auditTypes = auditDMO.GetAuditTypeList().ToArray(); |         AuditType[] auditTypes = auditDMO.GetAuditTypeList().ToArray(); | ||||||
|         // CAFindings GetCAFindingsItem(int caFindingsID); |         // CAFindings GetCAFindingsItem(int caFindingsID); | ||||||
|         // IEnumerable<AuditReportAttachment> GetCAFindingsItemAttachments(int caFindingsID); |         // IEnumerable<AuditReportAttachment> GetCAFindingsItemAttachments(int caFindingsID); | ||||||
|         // IEnumerable<CAFindings> GetCAFindingsList(int auditNo); |         CAFindings[] caFindings = auditDMO.GetCAFindingsList(auditNo).ToArray(); | ||||||
|         CANoList[] cANoLists = auditDMO.GetCorrectiveActionNoList().ToArray(); |         CANoList[] cANoLists = auditDMO.GetCorrectiveActionNoList().ToArray(); | ||||||
|         // int GetOpenCACountByAuditNo(int auditNo); |         int openCACountByAuditNo = auditDMO.GetOpenCACountByAuditNo(auditNo); | ||||||
|         CAUserList[] cAUserLists = auditDMO.GetUserList().ToArray(); |         CAUserList[] cAUserLists = auditDMO.GetUserList().ToArray(); | ||||||
|         // Audit InsertAudit(Audit audit); |  | ||||||
|         // void InsertAuditReportAttachment(AuditReportAttachment attach); |         // void InsertAuditReportAttachment(AuditReportAttachment attach); | ||||||
|         // void InsertCAFindings(CAFindings model); |         // void InsertCAFindings(CAFindings model); | ||||||
|         // int IsCAAssignedToAudit(int CANo, int auditNo); |         // int IsCAAssignedToAudit(int CANo, int auditNo); | ||||||
|         // void ReleaseLockOnDocument(int userID, int issueID); |         // void ReleaseLockOnDocument(appSettings.UserId, int issueID); | ||||||
|         // void UpdateAudit(Audit audit, int userID); |  | ||||||
|         // void UpdateCAFindings(CAFindings model); |         // void UpdateCAFindings(CAFindings model); | ||||||
|         if (auditDMO is null) { } |         if (auditDMO is null) { } | ||||||
| #pragma warning restore IDE0059 | #pragma warning restore IDE0059 | ||||||
| @ -89,13 +89,14 @@ public class AuditDMOTests { | |||||||
|     [Ignore] |     [Ignore] | ||||||
| #endif | #endif | ||||||
|     [TestMethod] |     [TestMethod] | ||||||
|     public void AuditDMOIsAttachedOnly() { |     [DataRow(250, true)] | ||||||
|  |     public void AuditDMOIsAttachedOnly(int auditNo, bool isAdmin) { | ||||||
|         _Logger?.LogInformation("Starting Web Application"); |         _Logger?.LogInformation("Starting Web Application"); | ||||||
|         IServiceProvider? serviceProvider = _WebApplicationFactory?.Services.CreateScope().ServiceProvider; |         IServiceProvider? serviceProvider = _WebApplicationFactory?.Services.CreateScope().ServiceProvider; | ||||||
|         AppSettings? appSettings = serviceProvider?.GetRequiredService<AppSettings>(); |         AppSettings? appSettings = serviceProvider?.GetRequiredService<AppSettings>(); | ||||||
|         Assert.IsTrue(appSettings is not null); |         Assert.IsTrue(appSettings is not null); | ||||||
|         if (System.Diagnostics.Debugger.IsAttached) |         if (System.Diagnostics.Debugger.IsAttached) | ||||||
|             AuditDMO(_Logger, appSettings); |             AuditDMO(_Logger, appSettings, auditNo, isAdmin); | ||||||
|         _Logger?.LogInformation("{TestName} completed", _TestContext?.TestName); |         _Logger?.LogInformation("{TestName} completed", _TestContext?.TestName); | ||||||
|         NonThrowTryCatch(); |         NonThrowTryCatch(); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -53,12 +53,12 @@ public class ChangeControlDMOTests { | |||||||
|     private static void ChangeControlDMO(ILogger? logger, AppSettings appSettings) { |     private static void ChangeControlDMO(ILogger? logger, AppSettings appSettings) { | ||||||
| #pragma warning disable IDE0059 | #pragma warning disable IDE0059 | ||||||
|         SetGlobalVars(logger, appSettings); |         SetGlobalVars(logger, appSettings); | ||||||
|         ChangeControlDMO changeControlDMO = new(appSettings); |         ChangeControlDMO changeControlDMO = new(); | ||||||
|         // IEnumerable<CCAttachment> GetCCAttachment(int planNumber); |         // IEnumerable<CCAttachment> GetCCAttachment(int planNumber); | ||||||
|         // IEnumerable<CCMeetingAttachment> GetMeetingAttachments(int meetingID); |         // IEnumerable<CCMeetingAttachment> GetMeetingAttachments(int meetingID); | ||||||
|         // IEnumerable<MeetingDecisionSummaryList> GetMeetingDecisionSummaryList(int planNumber); |         // IEnumerable<MeetingDecisionSummaryList> GetMeetingDecisionSummaryList(int planNumber); | ||||||
|         // IEnumerable<CCMeeting> GetMeetingList(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) { } |         if (changeControlDMO is null) { } | ||||||
| #pragma warning restore IDE0059 | #pragma warning restore IDE0059 | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -55,8 +55,8 @@ public class CorrectiveActionDMOTests { | |||||||
|     private static void CorrectiveActionDMO(ILogger? logger, AppSettings appSettings) { |     private static void CorrectiveActionDMO(ILogger? logger, AppSettings appSettings) { | ||||||
| #pragma warning disable IDE0059 | #pragma warning disable IDE0059 | ||||||
|         SetGlobalVars(logger, appSettings); |         SetGlobalVars(logger, appSettings); | ||||||
|         CorrectiveActionDMO correctiveActionDMO = new(appSettings); |         CorrectiveActionDMO correctiveActionDMO = new(); | ||||||
|         // void ApproveSection(int issueID, int userID, string DSection); |         // void ApproveSection(int issueID, appSettings.UserId, string DSection); | ||||||
|         // void DeleteCAAttachment(int attachmentID); |         // void DeleteCAAttachment(int attachmentID); | ||||||
|         // void DeleteD3ContainmentActionItem(int d3ContainmentActionID); |         // void DeleteD3ContainmentActionItem(int d3ContainmentActionID); | ||||||
|         // void DeleteD5D6CorrectivetAction(int d5d6CAID); |         // void DeleteD5D6CorrectivetAction(int d5d6CAID); | ||||||
| @ -67,8 +67,8 @@ public class CorrectiveActionDMOTests { | |||||||
|         // IEnumerable<CA_Attachment> GetCAAttachmentsList(int caNo, string section); |         // IEnumerable<CA_Attachment> GetCAAttachmentsList(int caNo, string section); | ||||||
|         CAD3D5D7Due[] cAD3D5D7Dues = correctiveActionDMO.GetCAD3D5D7Due().ToArray(); |         CAD3D5D7Due[] cAD3D5D7Dues = correctiveActionDMO.GetCAD3D5D7Due().ToArray(); | ||||||
|         // IEnumerable<CA_Attachment> GetCAFindingsItemAttachments(int caFindingsID); |         // IEnumerable<CA_Attachment> GetCAFindingsItemAttachments(int caFindingsID); | ||||||
|         // CorrectiveAction GetCAItem(int caNo, int userID); |         // CorrectiveAction GetCAItem(int caNo, appSettings.UserId); | ||||||
|         // CorrectiveAction GetCAItemReadOnly(int caNo, int userID); |         // CorrectiveAction GetCAItemReadOnly(int caNo, appSettings.UserId); | ||||||
|         // IEnumerable<CASectionApproval> GetCASectionApprovalLog(int caNo); |         // IEnumerable<CASectionApproval> GetCASectionApprovalLog(int caNo); | ||||||
|         CASource[] cASources = correctiveActionDMO.GetCASourceList().ToArray(); |         CASource[] cASources = correctiveActionDMO.GetCASourceList().ToArray(); | ||||||
|         // IEnumerable<D3ContainmentAction> GetD3ContainmentActions(int caNo); |         // IEnumerable<D3ContainmentAction> GetD3ContainmentActions(int caNo); | ||||||
| @ -89,17 +89,17 @@ public class CorrectiveActionDMOTests { | |||||||
|         // void InsertD3ContainmentAction(D3ContainmentAction model); |         // void InsertD3ContainmentAction(D3ContainmentAction model); | ||||||
|         // void InsertD5D6CorrectivetAction(D5D6CorrectivetAction model); |         // void InsertD5D6CorrectivetAction(D5D6CorrectivetAction model); | ||||||
|         // void InsertD7PreventiveAction(D7PreventiveAction model); |         // void InsertD7PreventiveAction(D7PreventiveAction model); | ||||||
|         // bool IsAIAssignee(int userId, int caId); |         // bool IsAIAssignee(appSettings.UserId, int caId); | ||||||
|         // bool IsLastSectionApprover(int caNo, string dSection); |         // bool IsLastSectionApprover(int caNo, string dSection); | ||||||
|         // bool IsUserSectionApprover(int issueId, int userId); |         // bool IsUserSectionApprover(int issueId, appSettings.UserId); | ||||||
|         // void RejectSection(int issueID, int userID, string DSection, string comments); |         // void RejectSection(int issueID, appSettings.UserId, string DSection, string comments); | ||||||
|         // void ReleaseLockOnDocument(int userID, int issueID); |         // void ReleaseLockOnDocument(appSettings.UserId, int issueID); | ||||||
|         // DateTime SetCAComplete(int issueID); |         // DateTime SetCAComplete(int issueID); | ||||||
|         // DateTime SetCAD3DueDate(int issueID); |         // DateTime SetCAD3DueDate(int issueID); | ||||||
|         // DateTime SetCAD5D7DueDate(int issueID); |         // DateTime SetCAD5D7DueDate(int issueID); | ||||||
|         // void SetD3D5D7NotificationDate(int caNo, string section); |         // void SetD3D5D7NotificationDate(int caNo, string section); | ||||||
|         // int StartApproval(int issueID, int userID, int worlflowNumber); |         // int StartApproval(int issueID, appSettings.UserId, int worlflowNumber); | ||||||
|         // void StartSectionApproval(int issueID, int userID, string DSection); |         // void StartSectionApproval(int issueID, appSettings.UserId, string DSection); | ||||||
|         // void UpdateCorrectiveAction(CorrectiveAction model); |         // void UpdateCorrectiveAction(CorrectiveAction model); | ||||||
|         // void UpdateD3ContainmentAction(D3ContainmentAction model); |         // void UpdateD3ContainmentAction(D3ContainmentAction model); | ||||||
|         // void UpdateD5D6CorrectivetAction(D5D6CorrectivetAction model); |         // void UpdateD5D6CorrectivetAction(D5D6CorrectivetAction model); | ||||||
|  | |||||||
| @ -58,30 +58,30 @@ public class EngChangeNoticeDMOTests { | |||||||
|         ECN_DMO ecnDMO = new(); |         ECN_DMO ecnDMO = new(); | ||||||
|         // void CancelECN(int? ecnNumber); |         // void CancelECN(int? ecnNumber); | ||||||
|         // bool CanSubmitECN(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); |         // void DeleteECNAttachment(int attachmentID); | ||||||
|         // bool ECNApproveCancelled_ExpiredDocument(int issueID, byte step, string comments, out bool lastStep, int userID, int documentType); |         // bool ECNApproveCancelled_ExpiredDocument(int issueID, byte step, string comments, out bool lastStep, appSettings.UserId, int documentType); | ||||||
|         // void ECNResetTECNAtRejection(int ecnNumber, int userID, int docType); |         // void ECNResetTECNAtRejection(int ecnNumber, appSettings.UserId, int docType); | ||||||
|         IssuesViewModel[] issuesViewModels = ecnDMO.GetAllTECNs().ToArray(); |         IssuesViewModel[] issuesViewModels = ecnDMO.GetAllTECNs().ToArray(); | ||||||
|         // IEnumerable<ApprovalLogHistory> GetECNApprovalLogHistory(int ecnNumber); |         // IEnumerable<ApprovalLogHistory> GetECNApprovalLogHistory(int ecnNumber); | ||||||
|         // IEnumerable<ECNAttachment> GetECNAttachments(int ecnNumber); |         // IEnumerable<ECNAttachment> GetECNAttachments(int ecnNumber); | ||||||
|         IssuesViewModel[] issuesViewModelsB = ecnDMO.GetECN_TECNPendingApprovals(appSettings.UserId).ToArray(); |         IssuesViewModel[] issuesViewModelsB = ecnDMO.GetECN_TECNPendingApprovals(appSettings.UserId).ToArray(); | ||||||
|         // string GetFileName(string attachmentID); |         // string GetFileName(string attachmentID); | ||||||
|         // IEnumerable<IssuesViewModel> GetMyConvertedTECNsToECNs(int userID, int maxDays); |         // IEnumerable<IssuesViewModel> GetMyConvertedTECNsToECNs(appSettings.UserId, int maxDays); | ||||||
|         // IEnumerable<IssuesViewModel> GetMyExpiredTECNs(int userID, int maxDays); |         // IEnumerable<IssuesViewModel> GetMyExpiredTECNs(appSettings.UserId, int maxDays); | ||||||
|         // IEnumerable<IssuesViewModel> GetMyExpiringTECNs(int userID, int maxDays); |         // IEnumerable<IssuesViewModel> GetMyExpiringTECNs(appSettings.UserId, int maxDays); | ||||||
|         // List<string> GetRejectionOrginatorEmailList(int ecnNumber); |         // List<string> GetRejectionOrginatorEmailList(int ecnNumber); | ||||||
|         int[] ints = ecnDMO.GetTECNNotificationUsers().ToArray(); |         int[] ints = ecnDMO.GetTECNNotificationUsers().ToArray(); | ||||||
|         // void InsertECNAttachment(ECNAttachment attach); |         // void InsertECNAttachment(ECNAttachment attach); | ||||||
|         // int PCRBExists(int pcrb); |         // int PCRBExists(int pcrb); | ||||||
|         // void ReassignOriginatorECN(int ecnNumber, int newOriginatorID, string comments, int userID); |         // void ReassignOriginatorECN(int ecnNumber, int newOriginatorID, string comments, appSettings.UserId); | ||||||
|         // void ReleaseLockOnDocument(int userID, int issueID); |         // void ReleaseLockOnDocument(appSettings.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); |         // 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 SaveAfterSubmitByApprover(int ecnNumber, string implementationDetails); | ||||||
|         // void SetToExecutionStep(int ecnNumber, int userid, int documentType, string ecnTypeString); |         // void SetToExecutionStep(int ecnNumber, appSettings.UserId, int documentType, string ecnTypeString); | ||||||
|         // int SubmitDocument(int issueID, int userID, int documentType, out int allowedITAR); |         // int SubmitDocument(int issueID, appSettings.UserId, int documentType, out int allowedITAR); | ||||||
|         // int SubmitForCancellation(int issueID, byte currentStep, int userID, int documentType, string ecnType, int TECNOperationType); |         // int SubmitForCancellation(int issueID, byte currentStep, appSettings.UserId, int documentType, string ecnType, int TECNOperationType); | ||||||
|         // int SubmitTECNExtensionDocument(int issueID, int userID, int documentType, DateTime extensionDate); |         // int SubmitTECNExtensionDocument(int issueID, appSettings.UserId, int documentType, DateTime extensionDate); | ||||||
|         // void TECNExtensionLog(int ecnNumber, DateTime extensionDate); |         // void TECNExtensionLog(int ecnNumber, DateTime extensionDate); | ||||||
|         // void UpdateECNType(int ecnNumber, string ecnType); |         // void UpdateECNType(int ecnNumber, string ecnType); | ||||||
|         if (ecnDMO is null) { } |         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) { |     private static void LotDispositionDMO(ILogger? logger, AppSettings appSettings) { | ||||||
| #pragma warning disable IDE0059 | #pragma warning disable IDE0059 | ||||||
|         SetGlobalVars(logger, appSettings); |         SetGlobalVars(logger, appSettings); | ||||||
|         LotDispositionDMO lotDispositionDMO = new(appSettings); |         LotDispositionDMO lotDispositionDMO = new(); | ||||||
|         // void DeleteAllLotDispoLot(int issueID); |         // 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 DeleteLotDispoAttachment(int attachmentID); | ||||||
|         // void DeleteLotDispoLot(int lotID); |         // void DeleteLotDispoLot(int lotID); | ||||||
|         AuditList[] auditLists = lotDispositionDMO.GetAuditList(appSettings.UserId).ToArray(); |         AuditList[] auditLists = lotDispositionDMO.GetAuditList(appSettings.UserId).ToArray(); | ||||||
| @ -68,8 +68,8 @@ public class LotDispositionDMOTests { | |||||||
|         IssuesViewModel[] issuesViewModelsB = lotDispositionDMO.GetECNList(appSettings.UserId).ToArray(); |         IssuesViewModel[] issuesViewModelsB = lotDispositionDMO.GetECNList(appSettings.UserId).ToArray(); | ||||||
|         // string GetFileName(string attachmentID); |         // string GetFileName(string attachmentID); | ||||||
|         // Attachment[] GetLotDispoAttachments(int issueID); |         // Attachment[] GetLotDispoAttachments(int issueID); | ||||||
|         // LotDisposition GetLotDispositionItem(int issueID, out int isITAR, int userID); |         // LotDisposition GetLotDispositionItem(int issueID, out int isITAR, appSettings.UserId); | ||||||
|         // LotDisposition GetLotDispositionItemForRead(int issueID, out int isITAR, int userID); |         // LotDisposition GetLotDispositionItemForRead(int issueID, out int isITAR, appSettings.UserId); | ||||||
|         IssuesViewModel[] issuesViewModelsC = lotDispositionDMO.GetLotDispositionList(appSettings.UserId).ToArray(); |         IssuesViewModel[] issuesViewModelsC = lotDispositionDMO.GetLotDispositionList(appSettings.UserId).ToArray(); | ||||||
|         // Lot[] GetLotDispositionLots(int issueID); |         // Lot[] GetLotDispositionLots(int issueID); | ||||||
|         // LotDispositionLotSummaryViewModel GetLotDispositionLotSummary(int issueID); |         // LotDispositionLotSummaryViewModel GetLotDispositionLotSummary(int issueID); | ||||||
| @ -91,9 +91,9 @@ public class LotDispositionDMOTests { | |||||||
|         // int InsertLot(Lot lot, bool getLotInfo); |         // int InsertLot(Lot lot, bool getLotInfo); | ||||||
|         // LotDisposition InsertLotDisposition(LotDisposition lotDispo); |         // LotDisposition InsertLotDisposition(LotDisposition lotDispo); | ||||||
|         // void InsertLotDispositionAttachment(Attachment attach); |         // void InsertLotDispositionAttachment(Attachment attach); | ||||||
|         // void ReleaseLockOnDocument(int userID, int issueID); |         // void ReleaseLockOnDocument(appSettings.UserId, int issueID); | ||||||
|         // Lot[] SearchLots(string searchText); |         // 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 UpdateLotDispoLot(Lot lot); | ||||||
|         // void UpdateLotDisposition(LotDisposition lotDispo); |         // void UpdateLotDisposition(LotDisposition lotDispo); | ||||||
|         // void UpdateLotScrapReleaseStatus(ScrapLot scrap); |         // void UpdateLotScrapReleaseStatus(ScrapLot scrap); | ||||||
|  | |||||||
| @ -53,17 +53,17 @@ public class LotTravelerDMOTests { | |||||||
|     private static void LotTravelerDMO(ILogger? logger, AppSettings appSettings) { |     private static void LotTravelerDMO(ILogger? logger, AppSettings appSettings) { | ||||||
| #pragma warning disable IDE0059 | #pragma warning disable IDE0059 | ||||||
|         SetGlobalVars(logger, appSettings); |         SetGlobalVars(logger, appSettings); | ||||||
|         LotTravelerDMO lotTravelerDMO = new(appSettings); |         LotTravelerDMO lotTravelerDMO = new(); | ||||||
|         // int CanAddLocationOperation(LTLotTravelerHoldSteps model); |         // int CanAddLocationOperation(LTLotTravelerHoldSteps model); | ||||||
|         // int CreateLotTravelerRevision(LTLotTravelerHoldSteps model, int userID); |         // int CreateLotTravelerRevision(LTLotTravelerHoldSteps model, appSettings.UserId); | ||||||
|         // void CreateTraveler(int ltLotID, int workRequestID, int UserID); |         // void CreateTraveler(int ltLotID, int workRequestID, appSettings.UserId); | ||||||
|         // int CreateWorkRequestRevision(LTWorkRequest data, int userID); |         // int CreateWorkRequestRevision(LTWorkRequest data, appSettings.UserId); | ||||||
|         // void DeleteLot(int ltLotID); |         // void DeleteLot(int ltLotID); | ||||||
|         // IEnumerable<LTLot> GetLotList(int workRequestID); |         // IEnumerable<LTLot> GetLotList(int workRequestID); | ||||||
|         // IEnumerable<LTLot> GetLotListBasedOnSWRNumber(int swrNumber); |         // IEnumerable<LTLot> GetLotListBasedOnSWRNumber(int swrNumber); | ||||||
|         // IEnumerable<LotWithTraveler> GetLotsWithTraveler(int workRequestID); |         // IEnumerable<LotWithTraveler> GetLotsWithTraveler(int workRequestID); | ||||||
|         // LTLotTravelerHeaderViewModel GetLotTravelerHeaderForReadOnly(int ltLotID, int revisionNumber); |         // 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<LTLotTravelerHoldSteps> GetLotTravelerHolStepsByRevision(int ltLotID, int revisionNumber); | ||||||
|         // IEnumerable<RevisionHistory> GetLotTravelerRevisionHistory(int lotID); |         // IEnumerable<RevisionHistory> GetLotTravelerRevisionHistory(int lotID); | ||||||
|         // IEnumerable<LTLotTravelerHoldSteps> GetLotTravHoldSteps(int ltLotID); |         // IEnumerable<LTLotTravelerHoldSteps> GetLotTravHoldSteps(int ltLotID); | ||||||
| @ -76,15 +76,15 @@ public class LotTravelerDMOTests { | |||||||
|         // IEnumerable<RevisionHistory> GetWorkReqRevisionHistory(int swrNumber); |         // IEnumerable<RevisionHistory> GetWorkReqRevisionHistory(int swrNumber); | ||||||
|         // List<Revision> GetWorkReqRevisions(int swrNumber); |         // List<Revision> GetWorkReqRevisions(int swrNumber); | ||||||
|         // void InsertLot(LTLot lot); |         // void InsertLot(LTLot lot); | ||||||
|         // int InsertLotTravelerHoldStep(LTLotTravelerHoldSteps model, int userID); |         // int InsertLotTravelerHoldStep(LTLotTravelerHoldSteps model, appSettings.UserId); | ||||||
|         // void ReassignOriginator(int workRequestID, int newOriginatorID, string comments, int userID); |         // void ReassignOriginator(int workRequestID, int newOriginatorID, string comments, appSettings.UserId); | ||||||
|         // void ReleaseLockOnDocument(int userID, int workRequestID); |         // void ReleaseLockOnDocument(appSettings.UserId, int workRequestID); | ||||||
|         // void ReleaseLockOnLotTravelerUpdateDoc(int userID, int ltLotID); |         // void ReleaseLockOnLotTravelerUpdateDoc(appSettings.UserId, int ltLotID); | ||||||
|         // void RestoreLotTravToPrevRevision(int prevLotTravRevID, int newLotTravRevID); |         // void RestoreLotTravToPrevRevision(int prevLotTravRevID, int newLotTravRevID); | ||||||
|         // int SubmitDocument(int workRequestID, int userID, int documentType, out int allowedITAR); |         // int SubmitDocument(int workRequestID, appSettings.UserId, int documentType, out int allowedITAR); | ||||||
|         // int UpdateLotTravelerHoldStep(LTLotTravelerHoldSteps model, int userID); |         // int UpdateLotTravelerHoldStep(LTLotTravelerHoldSteps model, appSettings.UserId); | ||||||
|         // void UpdateLotTravlerExecution(int lotTravHoldStepID, string taskComments, bool CompletedFlag, int userID); |         // void UpdateLotTravlerExecution(int lotTravHoldStepID, string taskComments, bool CompletedFlag, appSettings.UserId); | ||||||
|         // int UpdateRevisedLotTravelerHoldStep(LTLotTravelerHoldSteps model, int userID); |         // int UpdateRevisedLotTravelerHoldStep(LTLotTravelerHoldSteps model, appSettings.UserId); | ||||||
|         if (lotTravelerDMO is null) { } |         if (lotTravelerDMO is null) { } | ||||||
| #pragma warning restore IDE0059 | #pragma warning restore IDE0059 | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -54,9 +54,9 @@ public class PartsRequestDMOTests { | |||||||
|     private static void PartsRequestDMO(ILogger? logger, AppSettings appSettings) { |     private static void PartsRequestDMO(ILogger? logger, AppSettings appSettings) { | ||||||
| #pragma warning disable IDE0059 | #pragma warning disable IDE0059 | ||||||
|         SetGlobalVars(logger, appSettings); |         SetGlobalVars(logger, appSettings); | ||||||
|         PartsRequestDMO partsRequestDMO = new(appSettings); |         PartsRequestDMO partsRequestDMO = new(); | ||||||
|         // void DeleteAttachment(int attachmentID); |         // void DeleteAttachment(int attachmentID); | ||||||
|         // void DeleteDocument(int prNumber, int userid); |         // void DeleteDocument(int prNumber, appSettings.UserId); | ||||||
|         // PartsRequest Get(int PRNumber); |         // PartsRequest Get(int PRNumber); | ||||||
|         // IEnumerable<ApprovalLogHistory> GetApprovalLogHistory(int prNumber); |         // IEnumerable<ApprovalLogHistory> GetApprovalLogHistory(int prNumber); | ||||||
|         // IEnumerable<PartsRequestAttachmentList> GetAttachments(int prNumber); |         // IEnumerable<PartsRequestAttachmentList> GetAttachments(int prNumber); | ||||||
| @ -65,7 +65,7 @@ public class PartsRequestDMOTests { | |||||||
|         PartsRequestList[] partsRequestLists = partsRequestDMO.GetPartsRequestList().ToArray(); |         PartsRequestList[] partsRequestLists = partsRequestDMO.GetPartsRequestList().ToArray(); | ||||||
|         // void Insert(PartsRequest pr); |         // void Insert(PartsRequest pr); | ||||||
|         // void InsertAttachment(PartsRequestAttachment attach); |         // void InsertAttachment(PartsRequestAttachment attach); | ||||||
|         // void Submit(int prNumber, int userID); |         // void Submit(int prNumber, appSettings.UserId); | ||||||
|         // void Update(PartsRequest pr); |         // void Update(PartsRequest pr); | ||||||
|         if (partsRequestDMO is null) { } |         if (partsRequestDMO is null) { } | ||||||
| #pragma warning restore IDE0059 | #pragma warning restore IDE0059 | ||||||
|  | |||||||
| @ -60,8 +60,8 @@ public class TrainingDMOTests { | |||||||
|         // bool CheckTrainingStatus(int trainingAssignmentID); |         // bool CheckTrainingStatus(int trainingAssignmentID); | ||||||
|         // bool CheckValidDocAck(int docAckId); |         // bool CheckValidDocAck(int docAckId); | ||||||
|         // int Create(int issueId); |         // int Create(int issueId); | ||||||
|         // int CreateAssignment(int trainingId, int userId); |         // int CreateAssignment(int trainingId, appSettings.UserId); | ||||||
|         // void DeleteAssignmentByUserId(int userId); |         // void DeleteAssignmentByUserId(appSettings.UserId); | ||||||
|         // void DeleteTraining(int trainingId); |         // void DeleteTraining(int trainingId); | ||||||
|         // void DeleteTrainingAssignment(int trainingAssignmentId); |         // void DeleteTrainingAssignment(int trainingAssignmentId); | ||||||
|         // void DeleteTrainingDocAck(int trainingAssignmentId); |         // void DeleteTrainingDocAck(int trainingAssignmentId); | ||||||
| @ -75,15 +75,15 @@ public class TrainingDMOTests { | |||||||
|         // List<int> GetTrainees(int groupId); |         // List<int> GetTrainees(int groupId); | ||||||
|         // Training GetTraining(int trainingId); |         // Training GetTraining(int trainingId); | ||||||
|         // List<TrainingAssignment> GetTrainingAssignments(int TrainingID); |         // List<TrainingAssignment> GetTrainingAssignments(int TrainingID); | ||||||
|         // List<TrainingAssignment> GetTrainingAssignmentsByUser(int TrainingID, int userID); |         // List<TrainingAssignment> GetTrainingAssignmentsByUser(int TrainingID, appSettings.UserId); | ||||||
|         // List<TrainingAssignment> GetTrainingAssignmentsByUserID(int userID); |         // List<TrainingAssignment> GetTrainingAssignmentsByUserID(appSettings.UserId); | ||||||
|         // TrainingGroup GetTrainingGroupByID(int groupId); |         // TrainingGroup GetTrainingGroupByID(int groupId); | ||||||
|         // TrainingGroup[] trainingGroups = trainingDMO.GetTrainingGroups().ToArray(); |         // TrainingGroup[] trainingGroups = trainingDMO.GetTrainingGroups().ToArray(); | ||||||
|         // int GetTrainingId(int issueId); |         // int GetTrainingId(int issueId); | ||||||
|         // int GetTrainingIdByAssignment(int trainingAssignmentID); |         // int GetTrainingIdByAssignment(int trainingAssignmentID); | ||||||
|         // Training[] trainingsC = trainingDMO.GetTrainings().ToArray(); |         // Training[] trainingsC = trainingDMO.GetTrainings().ToArray(); | ||||||
|         // bool IsUserAssigned(int userId, int trainingId); |         // bool IsUserAssigned(appSettings.UserId, int trainingId); | ||||||
|         // bool isUserTrainingMember(int groupId, int userId); |         // bool isUserTrainingMember(int groupId, appSettings.UserId); | ||||||
|         // void reOpenTraining(int trainingId); |         // void reOpenTraining(int trainingId); | ||||||
|         // void SetTrainingFlag(int ECNNumber); |         // void SetTrainingFlag(int ECNNumber); | ||||||
|         // void UpdateAssignmentStatus(int trainingAssignmentID); |         // void UpdateAssignmentStatus(int trainingAssignmentID); | ||||||
|  | |||||||
| @ -50,22 +50,25 @@ public class WorkflowDMOTests { | |||||||
|         try { throw new Exception(); } catch (Exception) { } |         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 | #pragma warning disable IDE0059 | ||||||
|  |         bool isLastStep; | ||||||
|         SetGlobalVars(logger, appSettings); |         SetGlobalVars(logger, appSettings); | ||||||
|  |         ECN_DMO ecnDMO = new(); | ||||||
|  |         ECN ecn = ecnDMO.GetECN(issueID); | ||||||
|         WorkflowDMO workflowDMO = new();         |         WorkflowDMO workflowDMO = new();         | ||||||
|         // string AddAdditionalApproval(int issueID, string userIDs, byte step, int documentType); |         // string AddAdditionalApproval(int issueID, string userIDs, byte step, int documentType); | ||||||
|         // string AddEECNApproval(int ecnNumber, byte step, int documentType, string engUserIDs, string opUserIDs); |         // 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 DelegateDocumentApproval(int issueID, int delegateFromUser, int delegateToUser); | ||||||
|         // string GetApproversForCancelled_ExpiredTECNDocs(int ecnNumber); |         // string GetApproversForCancelled_ExpiredTECNDocs(int ecnNumber); | ||||||
|         // string GetSubRoleItems(int issueID, int docType); |         // string GetSubRoleItems(int issueID, int docType); | ||||||
|         // string GetSubRolesForPartsRequestNextStep(int prNumber); |         // string GetSubRolesForPartsRequestNextStep(int prNumber); | ||||||
|         // WorkflowSteps GetWorkflowStep(int docTypeID, int wfNumber, int stepNumber); |         // WorkflowSteps GetWorkflowStep(int docTypeID, int wfNumber, int stepNumber); | ||||||
|         // string ReAssignApproval(int issueID, int assignedFromUser, int assignedToUser, byte step, int docType); |         // 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 Recall(int issueID, byte step, string comments, appSettings.UserId, int docType); | ||||||
|         // bool Reject(int issueID, byte step, string comments, int userID, int docType); |         // bool Reject(int issueID, byte step, string comments, appSettings.UserId, int docType); | ||||||
|         // void RejectTECNExtension(int ecnNumber, byte step, string comments, int userID, int docType); |         // void RejectTECNExtension(int ecnNumber, byte step, string comments, appSettings.UserId, int docType); | ||||||
|         if (workflowDMO is null) { } |         if (workflowDMO is null) { } | ||||||
| #pragma warning restore IDE0059 | #pragma warning restore IDE0059 | ||||||
|     } |     } | ||||||
| @ -74,13 +77,14 @@ public class WorkflowDMOTests { | |||||||
|     [Ignore] |     [Ignore] | ||||||
| #endif | #endif | ||||||
|     [TestMethod] |     [TestMethod] | ||||||
|     public void WorkflowDMOIsAttachedOnly() { |     [DataRow(82700, "comment", 3)] | ||||||
|  |     public void WorkflowDMOIsAttachedOnly(int issueID, string comments, int documentType) { | ||||||
|         _Logger?.LogInformation("Starting Web Application"); |         _Logger?.LogInformation("Starting Web Application"); | ||||||
|         IServiceProvider? serviceProvider = _WebApplicationFactory?.Services.CreateScope().ServiceProvider; |         IServiceProvider? serviceProvider = _WebApplicationFactory?.Services.CreateScope().ServiceProvider; | ||||||
|         AppSettings? appSettings = serviceProvider?.GetRequiredService<AppSettings>(); |         AppSettings? appSettings = serviceProvider?.GetRequiredService<AppSettings>(); | ||||||
|         Assert.IsTrue(appSettings is not null); |         Assert.IsTrue(appSettings is not null); | ||||||
|         if (System.Diagnostics.Debugger.IsAttached) |         if (System.Diagnostics.Debugger.IsAttached) | ||||||
|             WorkflowDMO(_Logger, appSettings); |             WorkflowDMO(_Logger, appSettings, issueID, comments, documentType); | ||||||
|         _Logger?.LogInformation("{TestName} completed", _TestContext?.TestName); |         _Logger?.LogInformation("{TestName} completed", _TestContext?.TestName); | ||||||
|         NonThrowTryCatch(); |         NonThrowTryCatch(); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -102,7 +102,7 @@ public class CorrectiveActionTests { | |||||||
|     internal static void TestCorrectiveAction(ILogger? logger, AppSettings appSettings, int caNo) { |     internal static void TestCorrectiveAction(ILogger? logger, AppSettings appSettings, int caNo) { | ||||||
|         SetGlobalVars(logger, appSettings); |         SetGlobalVars(logger, appSettings); | ||||||
|         CorrectiveAction ca; |         CorrectiveAction ca; | ||||||
|         CorrectiveActionDMO caDMO = new(appSettings); |         CorrectiveActionDMO caDMO = new(); | ||||||
|         ca = caDMO.GetCAItemReadOnly(caNo, appSettings.UserId); |         ca = caDMO.GetCAItemReadOnly(caNo, appSettings.UserId); | ||||||
|         if (ca is null) |         if (ca is null) | ||||||
|             throw new Exception($"{nameof(ca)}"); |             throw new Exception($"{nameof(ca)}"); | ||||||
|  | |||||||
							
								
								
									
										55
									
								
								MesaFabApproval.API.Test/ApprovalServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								MesaFabApproval.API.Test/ApprovalServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | |||||||
|  | using System; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | using MesaFabApproval.API.Services; | ||||||
|  | using MesaFabApproval.Shared.Models; | ||||||
|  |  | ||||||
|  | using Microsoft.Extensions.Caching.Memory; | ||||||
|  | using Microsoft.Extensions.Logging; | ||||||
|  |  | ||||||
|  | using Moq; | ||||||
|  |  | ||||||
|  | using Xunit; | ||||||
|  |  | ||||||
|  | namespace MesaFabApproval.API.Test; | ||||||
|  |  | ||||||
|  | public class ApprovalServiceTests { | ||||||
|  |     private readonly Mock<ILogger<ApprovalService>> _loggerMock; | ||||||
|  |     private readonly Mock<IMemoryCache> _cacheMock; | ||||||
|  |     private readonly Mock<IDalService> _dalServiceMock; | ||||||
|  |     private readonly Mock<IUserService> _userServiceMock; | ||||||
|  |     private readonly ApprovalService _approvalService; | ||||||
|  |  | ||||||
|  |     public ApprovalServiceTests() { | ||||||
|  |         _loggerMock = new Mock<ILogger<ApprovalService>>(); | ||||||
|  |         _cacheMock = new Mock<IMemoryCache>(); | ||||||
|  |         _dalServiceMock = new Mock<IDalService>(); | ||||||
|  |         _userServiceMock = new Mock<IUserService>(); | ||||||
|  |         _approvalService = new ApprovalService(_loggerMock.Object, _cacheMock.Object, _dalServiceMock.Object, _userServiceMock.Object); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteApproval_ValidApprovalID_DeletesApproval() { | ||||||
|  |         int approvalID = 1; | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>())).ReturnsAsync(1); | ||||||
|  |  | ||||||
|  |         await _approvalService.DeleteApproval(approvalID); | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Verify(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>()), Times.Once); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteApproval_InvalidApprovalID_ThrowsArgumentException() { | ||||||
|  |         int approvalID = 0; | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<ArgumentException>(() => _approvalService.DeleteApproval(approvalID)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteApproval_DeletionFails_ThrowsException() { | ||||||
|  |         int approvalID = 1; | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>())).ReturnsAsync(0); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _approvalService.DeleteApproval(approvalID)); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										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> | ||||||
							
								
								
									
										18
									
								
								MesaFabApproval.API.Test/MockMemoryCacheService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								MesaFabApproval.API.Test/MockMemoryCacheService.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | using Microsoft.Extensions.Caching.Memory; | ||||||
|  |  | ||||||
|  | using Moq; | ||||||
|  |  | ||||||
|  | namespace MesaFabApproval.API.Test; | ||||||
|  |  | ||||||
|  | public static class MockMemoryCacheService { | ||||||
|  |     public static Mock<IMemoryCache> GetMemoryCache(object expectedValue) { | ||||||
|  |         Mock<IMemoryCache> mockMemoryCache = new Mock<IMemoryCache>(); | ||||||
|  |         mockMemoryCache | ||||||
|  |             .Setup(x => x.TryGetValue(It.IsAny<object>(), out expectedValue)) | ||||||
|  |             .Returns(true); | ||||||
|  |         mockMemoryCache | ||||||
|  |             .Setup(x => x.CreateEntry(It.IsAny<object>())) | ||||||
|  |             .Returns(Mock.Of<ICacheEntry>()); | ||||||
|  |         return mockMemoryCache; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										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); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										196
									
								
								MesaFabApproval.API.Test/PCRBFollowUpCommentsTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								MesaFabApproval.API.Test/PCRBFollowUpCommentsTests.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,196 @@ | |||||||
|  | using MesaFabApproval.API.Services; | ||||||
|  | using MesaFabApproval.Models; | ||||||
|  | using MesaFabApproval.Shared.Models; | ||||||
|  |  | ||||||
|  | using Microsoft.Extensions.Caching.Memory; | ||||||
|  | using Microsoft.Extensions.Logging; | ||||||
|  |  | ||||||
|  | using Moq; | ||||||
|  |  | ||||||
|  | namespace MesaFabApproval.API.Test; | ||||||
|  |  | ||||||
|  | public class PCRBFollowUpCommentsTests { | ||||||
|  |     private readonly Mock<ILogger<PCRBService>> _loggerMock; | ||||||
|  |     private readonly Mock<IDalService> _dalServiceMock; | ||||||
|  |     private readonly Mock<IMemoryCache> _cacheMock; | ||||||
|  |     private readonly Mock<IUserService> _userServiceMock; | ||||||
|  |     private readonly Mock<IApprovalService> _approvalServiceMock; | ||||||
|  |     private readonly Mock<ISmtpService> _smtpServiceMock; | ||||||
|  |     private readonly PCRBService _pcrbService; | ||||||
|  |     private readonly AppSettings _appSettings; | ||||||
|  |  | ||||||
|  |     private static PCRBFollowUpComment FOLLOW_UP_COMMENT = new PCRBFollowUpComment { | ||||||
|  |         PlanNumber = 1, | ||||||
|  |         FollowUpID = 1, | ||||||
|  |         Comment = "Comment", | ||||||
|  |         UserID = 1 | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     private static IEnumerable<PCRBFollowUpComment> FOLLOW_UP_COMMENTS = new List<PCRBFollowUpComment>() { FOLLOW_UP_COMMENT }; | ||||||
|  |  | ||||||
|  |     public PCRBFollowUpCommentsTests() { | ||||||
|  |         _loggerMock = new Mock<ILogger<PCRBService>>(); | ||||||
|  |         _dalServiceMock = new Mock<IDalService>(); | ||||||
|  |         _userServiceMock = new Mock<IUserService>(); | ||||||
|  |         _approvalServiceMock = new Mock<IApprovalService>(); | ||||||
|  |         _smtpServiceMock = new Mock<ISmtpService>(); | ||||||
|  |         _cacheMock = MockMemoryCacheService.GetMemoryCache(FOLLOW_UP_COMMENTS); | ||||||
|  |         _appSettings = new AppSettings( | ||||||
|  |             Company: "Infineon", | ||||||
|  |             DbConnectionString: "connectionString", | ||||||
|  |             JwtAudience: "audience", | ||||||
|  |             JwtIssuer: "issuer", | ||||||
|  |             JwtKey: "key", | ||||||
|  |             MrbAttachmentPath: "mrbAttachmentPath", | ||||||
|  |             PcrbAttachmentPath: "pcrbAttachmentPath", | ||||||
|  |             ShouldSendEmail: false, | ||||||
|  |             SiteBaseUrl: "siteBaseUrl", | ||||||
|  |             WorkingDirectoryName: "workingDirectoryName" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         _pcrbService = new PCRBService( | ||||||
|  |             _loggerMock.Object, | ||||||
|  |             _dalServiceMock.Object, | ||||||
|  |             _cacheMock.Object, | ||||||
|  |             _userServiceMock.Object, | ||||||
|  |             _approvalServiceMock.Object, | ||||||
|  |             _smtpServiceMock.Object, | ||||||
|  |             _appSettings | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateFollowUpComment_WithValidParam_ShouldCreateFollowUp() { | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT)) | ||||||
|  |             .ReturnsAsync(1); | ||||||
|  |  | ||||||
|  |         await _pcrbService.CreateFollowUpComment(FOLLOW_UP_COMMENT); | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Verify(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT), Times.Once); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateFollowUpComment_WithNullParam_ShouldThrowException() { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.CreateFollowUpComment(null)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateFollowUpComment_WithDatabaseFailure_ShouldThrowException() { | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT)) | ||||||
|  |             .ReturnsAsync(0); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUpComment(FOLLOW_UP_COMMENT)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateFollowUpComment_WithDatabaseException_ShouldThrowException() { | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT)) | ||||||
|  |             .Throws<Exception>(); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUpComment(FOLLOW_UP_COMMENT)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task GetFollowUpCommentsByPlanNumber_WithCacheBypass_ShouldReturnFollowUps() { | ||||||
|  |         int planNumber = 1; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.QueryAsync<PCRBFollowUpComment>(It.IsAny<string>(), It.IsAny<object>())) | ||||||
|  |             .ReturnsAsync(FOLLOW_UP_COMMENTS); | ||||||
|  |  | ||||||
|  |         IEnumerable<PCRBFollowUpComment> result = await _pcrbService.GetFollowUpCommentsByPlanNumber(planNumber, true); | ||||||
|  |  | ||||||
|  |         Assert.NotNull(result); | ||||||
|  |         Assert.Single(result); | ||||||
|  |         Assert.Equal(FOLLOW_UP_COMMENTS, result); | ||||||
|  |         _dalServiceMock.Verify(d => d.QueryAsync<PCRBFollowUpComment>(It.IsAny<string>(), It.IsAny<object>()), Times.Once); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task GetFollowUpCommentsByPlanNumber_WithCacheBypass_AndDatabaseException_ShouldThrowException() { | ||||||
|  |         int planNumber = 1; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.QueryAsync<PCRBFollowUpComment>(It.IsAny<string>(), It.IsAny<object>())) | ||||||
|  |             .Throws<Exception>(); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.GetFollowUpCommentsByPlanNumber(planNumber, true)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task GetFollowUpCommentsByPlanNumber_WithoutCacheBypass_ShouldReturnFollowUps() { | ||||||
|  |         int planNumber = 1; | ||||||
|  |  | ||||||
|  |         IEnumerable<PCRBFollowUpComment> result = await _pcrbService.GetFollowUpCommentsByPlanNumber(planNumber, false); | ||||||
|  |  | ||||||
|  |         Assert.NotNull(result); | ||||||
|  |         Assert.Single(result); | ||||||
|  |         Assert.Equal(FOLLOW_UP_COMMENTS, result); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdateFollowUpComment_WithValidParam_ShouldUpdateFollowUp() { | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT)) | ||||||
|  |             .ReturnsAsync(1); | ||||||
|  |  | ||||||
|  |         await _pcrbService.UpdateFollowUpComment(FOLLOW_UP_COMMENT); | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Verify(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT), Times.Once); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdateFollowUpComment_WithNullParam_ShouldThrowException() { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.UpdateFollowUpComment(null)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdateFollowUpComment_WithDatabaseFailure_ShouldThrowException() { | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT)) | ||||||
|  |             .ReturnsAsync(0); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUpComment(FOLLOW_UP_COMMENT)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdateFollowUpComment_WithDatabaseException_ShouldThrowException() { | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUpComment>(It.IsAny<string>(), FOLLOW_UP_COMMENT)) | ||||||
|  |             .Throws<Exception>(); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUpComment(FOLLOW_UP_COMMENT)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteFollowUpComment_WithValidId_ShouldDeleteFollowUp() { | ||||||
|  |         int commentId = 1; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>())) | ||||||
|  |             .ReturnsAsync(1); | ||||||
|  |  | ||||||
|  |         await _pcrbService.DeleteFollowUpComment(commentId); | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Verify(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>()), Times.Once); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteFollowUpComment_WithInvalidId_ShouldThrowException() { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentException>(() => _pcrbService.DeleteFollowUpComment(0)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteFollowUpComment_WithDatabaseFailure_ShouldThrowException() { | ||||||
|  |         int commentId = 1; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>())) | ||||||
|  |             .ReturnsAsync(0); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.DeleteFollowUpComment(commentId)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteFollowUpComment_WithDatabaseException_ShouldThrowException() { | ||||||
|  |         int commentId = 1; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>())) | ||||||
|  |             .Throws<Exception>(); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.DeleteFollowUpComment(commentId)); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										198
									
								
								MesaFabApproval.API.Test/PCRBFollowUpTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								MesaFabApproval.API.Test/PCRBFollowUpTests.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,198 @@ | |||||||
|  | using MesaFabApproval.API.Services; | ||||||
|  | using MesaFabApproval.Models; | ||||||
|  | using MesaFabApproval.Shared.Models; | ||||||
|  |  | ||||||
|  | using Microsoft.Extensions.Caching.Memory; | ||||||
|  | using Microsoft.Extensions.Logging; | ||||||
|  |  | ||||||
|  | using Moq; | ||||||
|  |  | ||||||
|  | namespace MesaFabApproval.API.Test; | ||||||
|  |  | ||||||
|  | public class PCRBFollowUpTests { | ||||||
|  |     private readonly Mock<ILogger<PCRBService>> _loggerMock; | ||||||
|  |     private readonly Mock<IDalService> _dalServiceMock; | ||||||
|  |     private readonly Mock<IMemoryCache> _cacheMock; | ||||||
|  |     private readonly Mock<IUserService> _userServiceMock; | ||||||
|  |     private readonly Mock<IApprovalService> _approvalServiceMock; | ||||||
|  |     private readonly Mock<ISmtpService> _smtpServiceMock; | ||||||
|  |     private readonly PCRBService _pcrbService; | ||||||
|  |     private readonly AppSettings _appSettings; | ||||||
|  |  | ||||||
|  |     private static PCRBFollowUp FOLLOW_UP = new PCRBFollowUp { | ||||||
|  |         ID = 1, | ||||||
|  |         PlanNumber = 1, | ||||||
|  |         Step = 1, | ||||||
|  |         FollowUpDate = DateTime.Now | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     private static IEnumerable<PCRBFollowUp> FOLLOW_UPS = new List<PCRBFollowUp>() {  | ||||||
|  |         new PCRBFollowUp { ID = 1, PlanNumber = 1, Step = 1, FollowUpDate = DateTime.Now } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     public PCRBFollowUpTests() { | ||||||
|  |         _loggerMock = new Mock<ILogger<PCRBService>>(); | ||||||
|  |         _dalServiceMock = new Mock<IDalService>(); | ||||||
|  |         _userServiceMock = new Mock<IUserService>(); | ||||||
|  |         _approvalServiceMock = new Mock<IApprovalService>(); | ||||||
|  |         _smtpServiceMock = new Mock<ISmtpService>(); | ||||||
|  |         _cacheMock = MockMemoryCacheService.GetMemoryCache(FOLLOW_UPS); | ||||||
|  |         _appSettings = new AppSettings( | ||||||
|  |             Company: "Infineon", | ||||||
|  |             DbConnectionString: "connectionString", | ||||||
|  |             JwtAudience: "audience", | ||||||
|  |             JwtIssuer: "issuer", | ||||||
|  |             JwtKey: "key", | ||||||
|  |             MrbAttachmentPath: "mrbAttachmentPath", | ||||||
|  |             PcrbAttachmentPath: "pcrbAttachmentPath", | ||||||
|  |             ShouldSendEmail: false, | ||||||
|  |             SiteBaseUrl: "siteBaseUrl", | ||||||
|  |             WorkingDirectoryName: "workingDirectoryName" | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         _pcrbService = new PCRBService( | ||||||
|  |             _loggerMock.Object, | ||||||
|  |             _dalServiceMock.Object, | ||||||
|  |             _cacheMock.Object, | ||||||
|  |             _userServiceMock.Object, | ||||||
|  |             _approvalServiceMock.Object, | ||||||
|  |             _smtpServiceMock.Object, | ||||||
|  |             _appSettings | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateFollowUp_WithValidParam_ShouldCreateFollowUp() { | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP)) | ||||||
|  |             .ReturnsAsync(1); | ||||||
|  |  | ||||||
|  |         await _pcrbService.CreateFollowUp(FOLLOW_UP); | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Verify(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP), Times.Once); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateFollowUp_WithNullParam_ShouldThrowException() { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.CreateFollowUp(null)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateFollowUp_WithDatabaseFailure_ShouldThrowException() { | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP)) | ||||||
|  |             .ReturnsAsync(0); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUp(FOLLOW_UP)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateFollowUp_WithDatabaseException_ShouldThrowException() { | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP)) | ||||||
|  |             .Throws<Exception>(); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUp(FOLLOW_UP)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task GetFollowUpsByPlanNumber_WithCacheBypass_ShouldReturnFollowUps() { | ||||||
|  |         int planNumber = 1; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.QueryAsync<PCRBFollowUp>(It.IsAny<string>(), It.IsAny<object>())) | ||||||
|  |             .ReturnsAsync(FOLLOW_UPS); | ||||||
|  |  | ||||||
|  |         IEnumerable<PCRBFollowUp> result = await _pcrbService.GetFollowUpsByPlanNumber(planNumber, true); | ||||||
|  |  | ||||||
|  |         Assert.NotNull(result); | ||||||
|  |         Assert.Single(result); | ||||||
|  |         Assert.Equal(FOLLOW_UPS, result); | ||||||
|  |         _dalServiceMock.Verify(d => d.QueryAsync<PCRBFollowUp>(It.IsAny<string>(), It.IsAny<object>()), Times.Once); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task GetFollowUpsByPlanNumber_WithCacheBypass_AndDatabaseException_ShouldThrowException() { | ||||||
|  |         int planNumber = 1; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.QueryAsync<PCRBFollowUp>(It.IsAny<string>(), It.IsAny<object>())) | ||||||
|  |             .Throws<Exception>(); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.GetFollowUpsByPlanNumber(planNumber, true)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task GetFollowUpsByPlanNumber_WithoutCacheBypass_ShouldReturnFollowUps() { | ||||||
|  |         int planNumber = 1; | ||||||
|  |  | ||||||
|  |         IEnumerable<PCRBFollowUp> result = await _pcrbService.GetFollowUpsByPlanNumber(planNumber, false); | ||||||
|  |  | ||||||
|  |         Assert.NotNull(result); | ||||||
|  |         Assert.Single(result); | ||||||
|  |         Assert.Equal(FOLLOW_UPS, result); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdateFollowUp_WithValidParam_ShouldUpdateFollowUp() { | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP)) | ||||||
|  |             .ReturnsAsync(1); | ||||||
|  |  | ||||||
|  |         await _pcrbService.UpdateFollowUp(FOLLOW_UP); | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Verify(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP), Times.Once); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdateFollowUp_WithNullParam_ShouldThrowException() { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.UpdateFollowUp(null)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdateFollowUp_WithDatabaseFailure_ShouldThrowException() { | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP)) | ||||||
|  |             .ReturnsAsync(0); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUp(FOLLOW_UP)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdateFollowUp_WithDatabaseException_ShouldThrowException() { | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), FOLLOW_UP)) | ||||||
|  |             .Throws<Exception>(); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUp(FOLLOW_UP)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteFollowUp_WithValidId_ShouldDeleteFollowUp() { | ||||||
|  |         int followUpId = 1; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>())) | ||||||
|  |             .ReturnsAsync(1); | ||||||
|  |  | ||||||
|  |         await _pcrbService.DeleteFollowUp(followUpId); | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Verify(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>()), Times.Once); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteFollowUp_WithInvalidId_ShouldThrowException() { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentException>(() => _pcrbService.DeleteFollowUp(0)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteFollowUp_WithDatabaseFailure_ShouldThrowException() { | ||||||
|  |         int followUpId = 1; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>())) | ||||||
|  |             .ReturnsAsync(0); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.DeleteFollowUp(followUpId)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteFollowUp_WithDatabaseException_ShouldThrowException() { | ||||||
|  |         int followUpId = 1; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>())) | ||||||
|  |             .Throws<Exception>(); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.DeleteFollowUp(followUpId)); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										328
									
								
								MesaFabApproval.API.Test/PCRBServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										328
									
								
								MesaFabApproval.API.Test/PCRBServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,328 @@ | |||||||
|  | using MesaFabApproval.API.Services; | ||||||
|  | using MesaFabApproval.Models; | ||||||
|  | using MesaFabApproval.Shared.Models; | ||||||
|  | using Microsoft.Extensions.Caching.Memory; | ||||||
|  | using Microsoft.Extensions.Logging; | ||||||
|  | using Moq; | ||||||
|  |  | ||||||
|  | using System.Net.Mail; | ||||||
|  |  | ||||||
|  | namespace MesaFabApproval.API.Test; | ||||||
|  | public class PCRBServiceTests | ||||||
|  | { | ||||||
|  |     private readonly Mock<ILogger<PCRBService>> _loggerMock; | ||||||
|  |     private readonly Mock<IDalService> _dalServiceMock; | ||||||
|  |     private Mock<IMemoryCache> _cacheMock; | ||||||
|  |     private readonly Mock<IUserService> _userServiceMock; | ||||||
|  |     private readonly Mock<IApprovalService> _approvalServiceMock; | ||||||
|  |     private readonly Mock<ISmtpService> _smtpServiceMock; | ||||||
|  |     private PCRBService _pcrbService; | ||||||
|  |  | ||||||
|  |     private static IEnumerable<PCRB> PCRBS = new List<PCRB>() { | ||||||
|  |         new PCRB { | ||||||
|  |             PlanNumber = 1, | ||||||
|  |             OwnerID = 1, | ||||||
|  |             Title = "Test Title", | ||||||
|  |             ChangeLevel = "Level 1", | ||||||
|  |             ReasonForChange = "Test Reason", | ||||||
|  |             ChangeDescription = "Test Description", | ||||||
|  |             IsITAR = false, | ||||||
|  |             CurrentStep = 1, | ||||||
|  |             InsertTimeStamp = DateTime.Now, | ||||||
|  |             LastUpdateDate = DateTime.Now, | ||||||
|  |             Type = "Type 1" | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     private static IEnumerable<PCRBFollowUp> FOLLOW_UPS = new List<PCRBFollowUp>() { | ||||||
|  |         new PCRBFollowUp { ID = 1, PlanNumber = 1, Step = 1, FollowUpDate = DateTime.Now } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     private static AppSettings appSettings = new AppSettings( | ||||||
|  |         Company: "Infineon", | ||||||
|  |         DbConnectionString: "connectionString", | ||||||
|  |         JwtAudience: "audience", | ||||||
|  |         JwtIssuer: "issuer", | ||||||
|  |         JwtKey: "key", | ||||||
|  |         MrbAttachmentPath: "mrbAttachmentPath", | ||||||
|  |         PcrbAttachmentPath: "pcrbAttachmentPath", | ||||||
|  |         ShouldSendEmail: false, | ||||||
|  |         SiteBaseUrl: "siteBaseUrl", | ||||||
|  |         WorkingDirectoryName: "workingDirectoryName" | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     public PCRBServiceTests() | ||||||
|  |     { | ||||||
|  |         _loggerMock = new Mock<ILogger<PCRBService>>(); | ||||||
|  |         _dalServiceMock = new Mock<IDalService>(); | ||||||
|  |         _userServiceMock = new Mock<IUserService>(); | ||||||
|  |         _approvalServiceMock = new Mock<IApprovalService>(); | ||||||
|  |         _smtpServiceMock = new Mock<ISmtpService>(); | ||||||
|  |         _cacheMock = MockMemoryCacheService.GetMemoryCache(FOLLOW_UPS); | ||||||
|  |  | ||||||
|  |         _pcrbService = new PCRBService( | ||||||
|  |             _loggerMock.Object, | ||||||
|  |             _dalServiceMock.Object, | ||||||
|  |             _cacheMock.Object, | ||||||
|  |             _userServiceMock.Object, | ||||||
|  |             _approvalServiceMock.Object, | ||||||
|  |             _smtpServiceMock.Object, | ||||||
|  |             appSettings | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateNewPCRB_WithValidParam_ShouldCreatePCRB() | ||||||
|  |     { | ||||||
|  |         var pcrb = new PCRB | ||||||
|  |         { | ||||||
|  |             OwnerID = 1, | ||||||
|  |             Title = "Test Title", | ||||||
|  |             ChangeLevel = "Level 1", | ||||||
|  |             ReasonForChange = "Test Reason", | ||||||
|  |             ChangeDescription = "Test Description", | ||||||
|  |             IsITAR = false, | ||||||
|  |             CurrentStep = 1, | ||||||
|  |             InsertTimeStamp = DateTime.Now, | ||||||
|  |             LastUpdateDate = DateTime.Now, | ||||||
|  |             Type = "Type 1" | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb)) | ||||||
|  |             .ReturnsAsync(1); | ||||||
|  |  | ||||||
|  |         await _pcrbService.CreateNewPCRB(pcrb); | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Verify(d => d.ExecuteAsync(It.IsAny<string>(), pcrb), Times.Once); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateNewPCRB_WithNullParam_ShouldThrowException() | ||||||
|  |     { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.CreateNewPCRB(null)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateNewPCRB_WithDatabaseFailure_ShouldThrowException() | ||||||
|  |     { | ||||||
|  |         var pcrb = new PCRB | ||||||
|  |         { | ||||||
|  |             OwnerID = 1, | ||||||
|  |             Title = "Test Title", | ||||||
|  |             ChangeLevel = "Level 1", | ||||||
|  |             ReasonForChange = "Test Reason", | ||||||
|  |             ChangeDescription = "Test Description", | ||||||
|  |             IsITAR = false, | ||||||
|  |             CurrentStep = 1, | ||||||
|  |             InsertTimeStamp = DateTime.Now, | ||||||
|  |             LastUpdateDate = DateTime.Now, | ||||||
|  |             Type = "Type 1" | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb)) | ||||||
|  |             .ReturnsAsync(0); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateNewPCRB(pcrb)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateNewPCRB_WithDatabaseException_ShouldThrowException() | ||||||
|  |     { | ||||||
|  |         var pcrb = new PCRB | ||||||
|  |         { | ||||||
|  |             OwnerID = 1, | ||||||
|  |             Title = "Test Title", | ||||||
|  |             ChangeLevel = "Level 1", | ||||||
|  |             ReasonForChange = "Test Reason", | ||||||
|  |             ChangeDescription = "Test Description", | ||||||
|  |             IsITAR = false, | ||||||
|  |             CurrentStep = 1, | ||||||
|  |             InsertTimeStamp = DateTime.Now, | ||||||
|  |             LastUpdateDate = DateTime.Now, | ||||||
|  |             Type = "Type 1" | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb)) | ||||||
|  |             .Throws<Exception>(); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateNewPCRB(pcrb)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdatePCRB_WithValidParam_ShouldUpdatePCRB() | ||||||
|  |     { | ||||||
|  |         _cacheMock = MockMemoryCacheService.GetMemoryCache(PCRBS); | ||||||
|  |  | ||||||
|  |         _pcrbService = new PCRBService( | ||||||
|  |             _loggerMock.Object, | ||||||
|  |             _dalServiceMock.Object, | ||||||
|  |             _cacheMock.Object, | ||||||
|  |             _userServiceMock.Object, | ||||||
|  |             _approvalServiceMock.Object, | ||||||
|  |             _smtpServiceMock.Object, | ||||||
|  |             appSettings | ||||||
|  |         ); | ||||||
|  |  | ||||||
|  |         var pcrb = new PCRB | ||||||
|  |         { | ||||||
|  |             PlanNumber = 1, | ||||||
|  |             OwnerID = 1, | ||||||
|  |             Title = "Test Title", | ||||||
|  |             ChangeLevel = "Level 1", | ||||||
|  |             ReasonForChange = "Test Reason", | ||||||
|  |             ChangeDescription = "Test Description", | ||||||
|  |             IsITAR = false, | ||||||
|  |             CurrentStep = 1, | ||||||
|  |             LastUpdateDate = DateTime.Now, | ||||||
|  |             ClosedDate = DateTime.Now, | ||||||
|  |             Type = "Type 1" | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb)) | ||||||
|  |             .ReturnsAsync(1); | ||||||
|  |  | ||||||
|  |         await _pcrbService.UpdatePCRB(pcrb); | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Verify(d => d.ExecuteAsync(It.IsAny<string>(), pcrb), Times.Once); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdatePCRB_WithNullParam_ShouldThrowException() | ||||||
|  |     { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.UpdatePCRB(null)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdatePCRB_WithDatabaseFailure_ShouldThrowException() | ||||||
|  |     { | ||||||
|  |         var pcrb = new PCRB | ||||||
|  |         { | ||||||
|  |             PlanNumber = 1, | ||||||
|  |             OwnerID = 1, | ||||||
|  |             Title = "Test Title", | ||||||
|  |             ChangeLevel = "Level 1", | ||||||
|  |             ReasonForChange = "Test Reason", | ||||||
|  |             ChangeDescription = "Test Description", | ||||||
|  |             IsITAR = false, | ||||||
|  |             CurrentStep = 1, | ||||||
|  |             LastUpdateDate = DateTime.Now, | ||||||
|  |             ClosedDate = DateTime.Now, | ||||||
|  |             Type = "Type 1" | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb)) | ||||||
|  |             .ReturnsAsync(0); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdatePCRB(pcrb)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdatePCRB_WithDatabaseException_ShouldThrowException() | ||||||
|  |     { | ||||||
|  |         var pcrb = new PCRB | ||||||
|  |         { | ||||||
|  |             PlanNumber = 1, | ||||||
|  |             OwnerID = 1, | ||||||
|  |             Title = "Test Title", | ||||||
|  |             ChangeLevel = "Level 1", | ||||||
|  |             ReasonForChange = "Test Reason", | ||||||
|  |             ChangeDescription = "Test Description", | ||||||
|  |             IsITAR = false, | ||||||
|  |             CurrentStep = 1, | ||||||
|  |             LastUpdateDate = DateTime.Now, | ||||||
|  |             ClosedDate = DateTime.Now, | ||||||
|  |             Type = "Type 1" | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb)) | ||||||
|  |             .Throws<Exception>(); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdatePCRB(pcrb)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task NotifyApprover_ShouldSendNotification() | ||||||
|  |     { | ||||||
|  |         PCRBNotification notification = new PCRBNotification | ||||||
|  |         { | ||||||
|  |             Message = "Test Message", | ||||||
|  |             PCRB = new PCRB { PlanNumber = 1, Title = "Test PCRB" }, | ||||||
|  |             Approval = new Approval | ||||||
|  |             { | ||||||
|  |                 UserID = 1, | ||||||
|  |                 IssueID = 1, | ||||||
|  |                 RoleName = "Role", | ||||||
|  |                 SubRole = "SubRole", | ||||||
|  |                 SubRoleID = 1, | ||||||
|  |                 AssignedDate = DateTime.Now | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _userServiceMock.Setup(s => s.GetUserByUserId(It.IsAny<int>())) | ||||||
|  |                         .ReturnsAsync(new User | ||||||
|  |                         { | ||||||
|  |                             UserID = 1, | ||||||
|  |                             LoginID = "testLogin", | ||||||
|  |                             FirstName = "Test", | ||||||
|  |                             LastName = "User", | ||||||
|  |                             Email = "test@example.com" | ||||||
|  |                         }); | ||||||
|  |  | ||||||
|  |         _smtpServiceMock.Setup(s => s.SendEmail(It.IsAny<IEnumerable<MailAddress>>(), | ||||||
|  |                                                 It.IsAny<IEnumerable<MailAddress>>(), | ||||||
|  |                                                 It.IsAny<string>(), | ||||||
|  |                                                 It.IsAny<string>())) | ||||||
|  |             .ReturnsAsync(true); | ||||||
|  |  | ||||||
|  |         _approvalServiceMock.Setup(s => s.UpdateApproval(It.IsAny<Approval>())) | ||||||
|  |             .Returns(Task.CompletedTask); | ||||||
|  |  | ||||||
|  |         await _pcrbService.NotifyApprover(notification); | ||||||
|  |  | ||||||
|  |         _smtpServiceMock.Verify(s => s.SendEmail(It.IsAny<IEnumerable<MailAddress>>(), | ||||||
|  |                                                  It.IsAny<IEnumerable<MailAddress>>(), | ||||||
|  |                                                  It.IsAny<string>(), | ||||||
|  |                                                  It.IsAny<string>()), Times.Once); | ||||||
|  |         _approvalServiceMock.Verify(s => s.UpdateApproval(It.IsAny<Approval>()), Times.Once); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task NotifyApprover_ShouldThrowException_WhenNotificationIsNull() | ||||||
|  |     { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.NotifyApprover(null)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task NotifyApprover_ShouldThrowException_WhenPCRBIsNull() | ||||||
|  |     { | ||||||
|  |         PCRBNotification notification = new PCRBNotification | ||||||
|  |         { | ||||||
|  |             Message = "Test Message", | ||||||
|  |             PCRB = null, | ||||||
|  |             Approval = new Approval | ||||||
|  |             { | ||||||
|  |                 UserID = 1, | ||||||
|  |                 IssueID = 1, | ||||||
|  |                 RoleName = "Role", | ||||||
|  |                 SubRole = "SubRole", | ||||||
|  |                 SubRoleID = 1, | ||||||
|  |                 AssignedDate = DateTime.Now | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.NotifyApprover(notification)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task NotifyApprover_ShouldThrowException_WhenApprovalIsNull() | ||||||
|  |     { | ||||||
|  |         PCRBNotification notification = new PCRBNotification | ||||||
|  |         { | ||||||
|  |             Message = "Test Message", | ||||||
|  |             PCRB = new PCRB { PlanNumber = 1, Title = "Test PCRB" }, | ||||||
|  |             Approval = null | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.NotifyApprover(notification)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -15,6 +15,8 @@ public class SmtpClientWrapper : ISmtpClientWrapper { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void Send(MailMessage message) { |     public void Send(MailMessage message) { | ||||||
|  |         message.Subject = message.Subject.Replace('\r', ' ').Replace('\n', ' '); | ||||||
|  |  | ||||||
|         _client.Send(message); |         _client.Send(message); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -1,4 +1,5 @@ | |||||||
| using MesaFabApproval.API.Services; | using MesaFabApproval.API.Services; | ||||||
|  | using MesaFabApproval.API.Utilities; | ||||||
| using MesaFabApproval.Shared.Models; | using MesaFabApproval.Shared.Models; | ||||||
| using MesaFabApproval.Shared.Services; | using MesaFabApproval.Shared.Services; | ||||||
|  |  | ||||||
| @ -11,13 +12,13 @@ namespace MesaFabApproval.API.Controllers; | |||||||
| public class ApprovalController : ControllerBase { | public class ApprovalController : ControllerBase { | ||||||
|     private readonly ILogger<ApprovalController> _logger; |     private readonly ILogger<ApprovalController> _logger; | ||||||
|     private readonly IApprovalService _approvalService; |     private readonly IApprovalService _approvalService; | ||||||
|     private readonly IMonInWorkerClient _monInClient; |     private readonly IMonInUtils _monInUtils; | ||||||
|  |  | ||||||
|     public ApprovalController(ILogger<ApprovalController> logger, IApprovalService approvalService, |     public ApprovalController(ILogger<ApprovalController> logger, IApprovalService approvalService, | ||||||
|                               IMonInWorkerClient monInClient) { |                               IMonInUtils monInUtils) { | ||||||
|         _logger = logger ?? throw new ArgumentNullException("ILogger not injected"); |         _logger = logger ?? throw new ArgumentNullException("ILogger not injected"); | ||||||
|         _approvalService = approvalService ?? throw new ArgumentNullException("IApprovalService not injected"); |         _approvalService = approvalService ?? throw new ArgumentNullException("IApprovalService not injected"); | ||||||
|         _monInClient = monInClient ?? throw new ArgumentNullException("IMonInWorkerClient not injected"); |         _monInUtils = monInUtils ?? throw new ArgumentNullException("IMonInUtils not injected"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     [HttpPost] |     [HttpPost] | ||||||
| @ -39,26 +40,19 @@ public class ApprovalController : ControllerBase { | |||||||
|         } catch (ArgumentException ex) { |         } catch (ArgumentException ex) { | ||||||
|             isArgumentError = true; |             isArgumentError = true; | ||||||
|             errorMessage = ex.Message; |             errorMessage = ex.Message; | ||||||
|  |             _logger.LogWarning($"Argument error when attempting to create approval: {errorMessage}"); | ||||||
|             return BadRequest(errorMessage); |             return BadRequest(errorMessage); | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             isInternalError = true; |             isInternalError = true; | ||||||
|             errorMessage = $"Cannot create new approval, because {ex.Message}"; |             errorMessage = $"Cannot create new approval, because {ex.Message}"; | ||||||
|  |             _logger.LogError(errorMessage); | ||||||
|             return Problem(errorMessage); |             return Problem(errorMessage); | ||||||
|         } finally { |         } finally { | ||||||
|             string metricName = "CreateApproval"; |             string metricName = "CreateApproval"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|              |              | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -81,26 +75,19 @@ public class ApprovalController : ControllerBase { | |||||||
|         } catch (ArgumentException ex) { |         } catch (ArgumentException ex) { | ||||||
|             isArgumentError = true; |             isArgumentError = true; | ||||||
|             errorMessage = ex.Message; |             errorMessage = ex.Message; | ||||||
|  |             _logger.LogWarning($"Argument error when getting approvals for issue {issueId}: {errorMessage}"); | ||||||
|             return BadRequest(errorMessage); |             return BadRequest(errorMessage); | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             isInternalError = true; |             isInternalError = true; | ||||||
|             errorMessage = $"Cannot get approvals, because {ex.Message}"; |             errorMessage = $"Cannot get approvals, because {ex.Message}"; | ||||||
|  |             _logger.LogError(errorMessage); | ||||||
|             return Problem(errorMessage); |             return Problem(errorMessage); | ||||||
|         } finally { |         } finally { | ||||||
|             string metricName = "GetApprovalsForIssueId"; |             string metricName = "GetApprovalsForIssueId"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|              |              | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -123,26 +110,19 @@ public class ApprovalController : ControllerBase { | |||||||
|         } catch (ArgumentException ex) { |         } catch (ArgumentException ex) { | ||||||
|             isArgumentError = true; |             isArgumentError = true; | ||||||
|             errorMessage = ex.Message; |             errorMessage = ex.Message; | ||||||
|  |             _logger.LogWarning($"Argument error when getting approvals for user {userId}: {errorMessage}"); | ||||||
|             return BadRequest(errorMessage); |             return BadRequest(errorMessage); | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             isInternalError = true; |             isInternalError = true; | ||||||
|             errorMessage = $"Cannot get approvals, because {ex.Message}"; |             errorMessage = $"Cannot get approvals, because {ex.Message}"; | ||||||
|  |             _logger.LogError(errorMessage); | ||||||
|             return Problem(errorMessage); |             return Problem(errorMessage); | ||||||
|         } finally { |         } finally { | ||||||
|             string metricName = "GetApprovalsForUserId"; |             string metricName = "GetApprovalsForUserId"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|              |              | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -165,26 +145,19 @@ public class ApprovalController : ControllerBase { | |||||||
|         } catch (ArgumentException ex) { |         } catch (ArgumentException ex) { | ||||||
|             isArgumentError = true; |             isArgumentError = true; | ||||||
|             errorMessage = ex.Message; |             errorMessage = ex.Message; | ||||||
|  |             _logger.LogWarning($"Argument error when getting approval group members for sub role {subRoleId}: {errorMessage}"); | ||||||
|             return BadRequest(errorMessage); |             return BadRequest(errorMessage); | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             isInternalError = true; |             isInternalError = true; | ||||||
|             errorMessage = $"Cannot get approval group members, because {ex.Message}"; |             errorMessage = $"Cannot get approval group members, because {ex.Message}"; | ||||||
|  |             _logger.LogError(errorMessage); | ||||||
|             return Problem(errorMessage); |             return Problem(errorMessage); | ||||||
|         } finally { |         } finally { | ||||||
|             string metricName = "GetApprovalsGroupMembers"; |             string metricName = "GetApprovalsGroupMembers"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|              |              | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -197,7 +170,7 @@ public class ApprovalController : ControllerBase { | |||||||
|         string errorMessage = ""; |         string errorMessage = ""; | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
|             _logger.LogInformation($"Attempting to update approval"); |             _logger.LogInformation("Attempting to update approval"); | ||||||
|  |  | ||||||
|             if (approval is null) throw new ArgumentNullException($"approval cannot be null"); |             if (approval is null) throw new ArgumentNullException($"approval cannot be null"); | ||||||
|  |  | ||||||
| @ -207,27 +180,55 @@ public class ApprovalController : ControllerBase { | |||||||
|         } catch (ArgumentException ex) { |         } catch (ArgumentException ex) { | ||||||
|             isArgumentError = true; |             isArgumentError = true; | ||||||
|             errorMessage = ex.Message; |             errorMessage = ex.Message; | ||||||
|  |             _logger.LogWarning($"Argument error when attempting to update approval: {errorMessage}"); | ||||||
|             return BadRequest(errorMessage); |             return BadRequest(errorMessage); | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             isInternalError = true; |             isInternalError = true; | ||||||
|             errorMessage = $"Cannot update approval, because {ex.Message}"; |             errorMessage = $"Cannot update approval, because {ex.Message}"; | ||||||
|  |             _logger.LogError(errorMessage); | ||||||
|             return Problem(errorMessage); |             return Problem(errorMessage); | ||||||
|         } finally { |         } finally { | ||||||
|             string metricName = "UpdateApproval"; |             string metricName = "UpdateApproval"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     [HttpDelete] | ||||||
|  |     [Route("approval")] | ||||||
|  |     public async Task<IActionResult> DeleteApproval(int approvalID) { | ||||||
|  |         DateTime start = DateTime.Now; | ||||||
|  |         bool isArgumentError = false; | ||||||
|  |         bool isInternalError = false; | ||||||
|  |         string errorMessage = ""; | ||||||
|  |  | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation($"Attempting to delete approval {approvalID}"); | ||||||
|  |  | ||||||
|  |             if (approvalID <= 0) throw new ArgumentException("Invalid approval ID"); | ||||||
|  |  | ||||||
|  |             await _approvalService.DeleteApproval(approvalID); | ||||||
|  |  | ||||||
|  |             return Ok(); | ||||||
|  |         } catch (ArgumentException ex) { | ||||||
|  |             isArgumentError = true; | ||||||
|  |             errorMessage = ex.Message; | ||||||
|  |             _logger.LogWarning($"Argument error when attempting to delete approval: {errorMessage}"); | ||||||
|  |             return BadRequest(errorMessage); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             isInternalError = true; | ||||||
|  |             errorMessage = $"Cannot delete approval, because {ex.Message}"; | ||||||
|  |             _logger.LogError(errorMessage); | ||||||
|  |             return Problem(errorMessage); | ||||||
|  |         } finally { | ||||||
|  |             string metricName = "UpdateApproval"; | ||||||
|  |             DateTime end = DateTime.Now; | ||||||
|  |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|  |  | ||||||
|  |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     [HttpPut] |     [HttpPut] | ||||||
| @ -249,26 +250,19 @@ public class ApprovalController : ControllerBase { | |||||||
|         } catch (ArgumentException ex) { |         } catch (ArgumentException ex) { | ||||||
|             isArgumentError = true; |             isArgumentError = true; | ||||||
|             errorMessage = ex.Message; |             errorMessage = ex.Message; | ||||||
|  |             _logger.LogWarning($"Argument error when attempting to approve: {errorMessage}"); | ||||||
|             return BadRequest(errorMessage); |             return BadRequest(errorMessage); | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             isInternalError = true; |             isInternalError = true; | ||||||
|             errorMessage = $"Cannot approve, because {ex.Message}"; |             errorMessage = $"Cannot approve, because {ex.Message}"; | ||||||
|  |             _logger.LogError(errorMessage); | ||||||
|             return Problem(errorMessage); |             return Problem(errorMessage); | ||||||
|         } finally { |         } finally { | ||||||
|             string metricName = "Approve"; |             string metricName = "Approve"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -291,26 +285,19 @@ public class ApprovalController : ControllerBase { | |||||||
|         } catch (ArgumentException ex) { |         } catch (ArgumentException ex) { | ||||||
|             isArgumentError = true; |             isArgumentError = true; | ||||||
|             errorMessage = ex.Message; |             errorMessage = ex.Message; | ||||||
|  |             _logger.LogWarning($"Argument error when attempting to deny approval: {errorMessage}"); | ||||||
|             return BadRequest(errorMessage); |             return BadRequest(errorMessage); | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             isInternalError = true; |             isInternalError = true; | ||||||
|             errorMessage = $"Approval denial failed, because {ex.Message}"; |             errorMessage = $"Approval denial failed, because {ex.Message}"; | ||||||
|  |             _logger.LogError(errorMessage); | ||||||
|             return Problem(errorMessage); |             return Problem(errorMessage); | ||||||
|         } finally { |         } finally { | ||||||
|             string metricName = "Deny"; |             string metricName = "Deny"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -333,26 +320,19 @@ public class ApprovalController : ControllerBase { | |||||||
|         } catch (ArgumentException ex) { |         } catch (ArgumentException ex) { | ||||||
|             isArgumentError = true; |             isArgumentError = true; | ||||||
|             errorMessage = ex.Message; |             errorMessage = ex.Message; | ||||||
|  |             _logger.LogWarning($"Argument error when attempting to get role ID by role name: {errorMessage}"); | ||||||
|             return BadRequest(errorMessage); |             return BadRequest(errorMessage); | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             isInternalError = true; |             isInternalError = true; | ||||||
|             errorMessage = $"Cannot get role ID, because {ex.Message}"; |             errorMessage = $"Cannot get role ID, because {ex.Message}"; | ||||||
|  |             _logger.LogError(errorMessage); | ||||||
|             return Problem(errorMessage); |             return Problem(errorMessage); | ||||||
|         } finally { |         } finally { | ||||||
|             string metricName = "GetRoleIdForRoleName"; |             string metricName = "GetRoleIdForRoleName"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -376,26 +356,19 @@ public class ApprovalController : ControllerBase { | |||||||
|         } catch (ArgumentException ex) { |         } catch (ArgumentException ex) { | ||||||
|             isArgumentError = true; |             isArgumentError = true; | ||||||
|             errorMessage = ex.Message; |             errorMessage = ex.Message; | ||||||
|  |             _logger.LogWarning($"Argument error when attempting to get sub roles by sub role name: {errorMessage}"); | ||||||
|             return BadRequest(errorMessage); |             return BadRequest(errorMessage); | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             isInternalError = true; |             isInternalError = true; | ||||||
|             errorMessage = $"Cannot get role ID, because {ex.Message}"; |             errorMessage = $"Cannot get role ID, because {ex.Message}"; | ||||||
|  |             _logger.LogError(errorMessage); | ||||||
|             return Problem(errorMessage); |             return Problem(errorMessage); | ||||||
|         } finally { |         } finally { | ||||||
|             string metricName = "GetSubRoleIdForSubRoleName"; |             string metricName = "GetSubRoleIdForSubRoleName"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|              |              | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -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.Services; | ||||||
|  | using MesaFabApproval.API.Utilities; | ||||||
| using MesaFabApproval.Shared.Models; | using MesaFabApproval.Shared.Models; | ||||||
| using MesaFabApproval.Shared.Services; | using MesaFabApproval.Shared.Services; | ||||||
|  |  | ||||||
| @ -13,12 +14,12 @@ namespace MesaFabApproval.API.Controllers; | |||||||
| public class PCRBController : ControllerBase { | public class PCRBController : ControllerBase { | ||||||
|     private readonly ILogger<MRBController> _logger; |     private readonly ILogger<MRBController> _logger; | ||||||
|     private readonly IPCRBService _pcrbService; |     private readonly IPCRBService _pcrbService; | ||||||
|     private readonly 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"); |         _logger = logger ?? throw new ArgumentNullException("ILogger not injected"); | ||||||
|         _pcrbService = pcrbService ?? throw new ArgumentNullException("IPCRBService 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] |     [HttpPost] | ||||||
| @ -49,17 +50,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "CreateNewPCRB"; |             string metricName = "CreateNewPCRB"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|              |              | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -84,14 +76,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "GetAllPCRBs"; |             string metricName = "GetAllPCRBs"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|              |              | ||||||
|             if (isInternalError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, false, isInternalError); | ||||||
|                 _logger.LogError(errorMessage); |  | ||||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); |  | ||||||
|             } else { |  | ||||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -123,17 +109,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "GetPCRBbyTitle"; |             string metricName = "GetPCRBbyTitle"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -165,17 +142,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "GetPCRBbyPlanNumber"; |             string metricName = "GetPCRBbyPlanNumber"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -207,17 +175,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "UpdatePCRB"; |             string metricName = "UpdatePCRB"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -249,22 +208,14 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "DeletePCRB"; |             string metricName = "DeletePCRB"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _logger.LogWarning(errorMessage); |  | ||||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); |  | ||||||
|             } else if (isInternalError) { |  | ||||||
|                 _logger.LogError(errorMessage); |  | ||||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); |  | ||||||
|             } else { |  | ||||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     [HttpPost] |     [HttpPost] | ||||||
|     [Route("pcrb/attachment")] |     [Route("pcrb/attachment")] | ||||||
|  |     [ApiExplorerSettings(IgnoreApi = true)] | ||||||
|     public async Task<IActionResult> UploadAttachment([FromForm] IFormFile file, [FromForm] PCRBAttachment attachment) { |     public async Task<IActionResult> UploadAttachment([FromForm] IFormFile file, [FromForm] PCRBAttachment attachment) { | ||||||
|         DateTime start = DateTime.Now; |         DateTime start = DateTime.Now; | ||||||
|         bool isArgumentError = false; |         bool isArgumentError = false; | ||||||
| @ -293,17 +244,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "UploadPCRBAttachment"; |             string metricName = "UploadPCRBAttachment"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -335,17 +277,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "GetPCRBAttachments"; |             string metricName = "GetPCRBAttachments"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -390,17 +323,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "GetPCRBAttachmentFile"; |             string metricName = "GetPCRBAttachmentFile"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|              |              | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -432,17 +356,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "UpdatePCRBAttachment"; |             string metricName = "UpdatePCRBAttachment"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -474,17 +389,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "DeletePCRBAttachment"; |             string metricName = "DeletePCRBAttachment"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -516,17 +422,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "CreatePCRBActionItem"; |             string metricName = "CreatePCRBActionItem"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -558,17 +455,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "UpdatePCRBActionItem"; |             string metricName = "UpdatePCRBActionItem"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -600,17 +488,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "DeletePCRBActionItem"; |             string metricName = "DeletePCRBActionItem"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -642,17 +521,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "GetPCRBActionItems"; |             string metricName = "GetPCRBActionItems"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -684,17 +554,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "CreatePCR3Document"; |             string metricName = "CreatePCR3Document"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -726,17 +587,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "UpdatePCR3Document"; |             string metricName = "UpdatePCR3Document"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -768,17 +620,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "GetPCR3Documents"; |             string metricName = "GetPCR3Documents"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -810,17 +653,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "CreatePCRBAttendee"; |             string metricName = "CreatePCRBAttendee"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|              |              | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -852,17 +686,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "UpdatePCRBAttendee"; |             string metricName = "UpdatePCRBAttendee"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -894,17 +719,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "DeletePCRBAttendee"; |             string metricName = "DeletePCRBAttendee"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -936,17 +752,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "GetPCRBAttendees"; |             string metricName = "GetPCRBAttendees"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -978,18 +785,45 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "NotifyNewPCRBApprovers"; |             string metricName = "NotifyNewPCRBApprovers"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _logger.LogWarning(errorMessage); |  | ||||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); |  | ||||||
|             } else if (isInternalError) { |  | ||||||
|                 _logger.LogError(errorMessage); |  | ||||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); |  | ||||||
|             } else { |  | ||||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     [HttpPost] | ||||||
|  |     [Route("pcrb/notify/approver")] | ||||||
|  |     public async Task<IActionResult> NotifyApprover(PCRBNotification notification) { | ||||||
|  |         DateTime start = DateTime.Now; | ||||||
|  |         bool isArgumentError = false; | ||||||
|  |         bool isInternalError = false; | ||||||
|  |         string errorMessage = ""; | ||||||
|  |  | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation("Attempting to notify an approver"); | ||||||
|  |  | ||||||
|  |             if (notification is null) throw new ArgumentNullException("notification cannot be null"); | ||||||
|  |             if (notification.PCRB is null) throw new ArgumentNullException("PCRB cannot be null"); | ||||||
|  |             if (notification.Approval is null) throw new ArgumentNullException("approval cannot be null"); | ||||||
|  |             if (string.IsNullOrWhiteSpace(notification.Message)) throw new ArgumentException("message cannot be null or empty"); | ||||||
|  |  | ||||||
|  |             await _pcrbService.NotifyApprover(notification); | ||||||
|  |  | ||||||
|  |             return Ok(); | ||||||
|  |         } catch (ArgumentException ex) { | ||||||
|  |             isArgumentError = true; | ||||||
|  |             errorMessage = ex.Message; | ||||||
|  |             return BadRequest(errorMessage); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             isInternalError = true; | ||||||
|  |             errorMessage = $"Unable to notify an approver, because {ex.Message}"; | ||||||
|  |             return Problem(errorMessage); | ||||||
|  |         } finally { | ||||||
|  |             string metricName = "NotifyPCRBApprover"; | ||||||
|  |             DateTime end = DateTime.Now; | ||||||
|  |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|  |  | ||||||
|  |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     [HttpPost] |     [HttpPost] | ||||||
| @ -1022,17 +856,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "NotifyPCRBApprovers"; |             string metricName = "NotifyPCRBApprovers"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -1066,17 +891,8 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "NotifyPCRBOriginator"; |             string metricName = "NotifyPCRBOriginator"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _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); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -1110,17 +926,272 @@ public class PCRBController : ControllerBase { | |||||||
|             string metricName = "NotifyPCRBResponsiblePerson"; |             string metricName = "NotifyPCRBResponsiblePerson"; | ||||||
|             DateTime end = DateTime.Now; |             DateTime end = DateTime.Now; | ||||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); |  | ||||||
|  |  | ||||||
|             if (isArgumentError) { |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|                 _logger.LogWarning(errorMessage); |  | ||||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); |  | ||||||
|             } else if (isInternalError) { |  | ||||||
|                 _logger.LogError(errorMessage); |  | ||||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); |  | ||||||
|             } else { |  | ||||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     [HttpPost] | ||||||
|  |     [Route("pcrb/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 follow ups for plan# {planNumber}"); | ||||||
|  |  | ||||||
|  |             if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#"); | ||||||
|  |  | ||||||
|  |             List<PCRBFollowUp> attendees = (await _pcrbService.GetFollowUpsByPlanNumber(planNumber, bypassCache)).ToList(); | ||||||
|  |  | ||||||
|  |             return Ok(attendees); | ||||||
|  |         } catch (ArgumentException ex) { | ||||||
|  |             isArgumentError = true; | ||||||
|  |             errorMessage = ex.Message; | ||||||
|  |             return BadRequest(errorMessage); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             isInternalError = true; | ||||||
|  |             errorMessage = $"Cannot get follow ups for plan# {planNumber}, because {ex.Message}"; | ||||||
|  |             return Problem(errorMessage); | ||||||
|  |         } finally { | ||||||
|  |             string metricName = "GetPCRBFollowUps"; | ||||||
|  |             DateTime end = DateTime.Now; | ||||||
|  |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|  |  | ||||||
|  |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [HttpPut] | ||||||
|  |     [Route("pcrb/followUp")] | ||||||
|  |     public async Task<IActionResult> UpdateFollowUp(PCRBFollowUp followUp) { | ||||||
|  |         DateTime start = DateTime.Now; | ||||||
|  |         bool isArgumentError = false; | ||||||
|  |         bool isInternalError = false; | ||||||
|  |         string errorMessage = ""; | ||||||
|  |  | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation("Attempting to update follow up"); | ||||||
|  |  | ||||||
|  |             if (followUp is null) throw new ArgumentNullException("follow up cannot be null"); | ||||||
|  |  | ||||||
|  |             await _pcrbService.UpdateFollowUp(followUp); | ||||||
|  |  | ||||||
|  |             return Ok(); | ||||||
|  |         } catch (ArgumentException ex) { | ||||||
|  |             isArgumentError = true; | ||||||
|  |             errorMessage = ex.Message; | ||||||
|  |             return BadRequest(errorMessage); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             isInternalError = true; | ||||||
|  |             errorMessage = $"Unable to update follow up, because {ex.Message}"; | ||||||
|  |             return Problem(errorMessage); | ||||||
|  |         } finally { | ||||||
|  |             string metricName = "UpdatePCRBFollowUp"; | ||||||
|  |             DateTime end = DateTime.Now; | ||||||
|  |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|  |  | ||||||
|  |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [HttpDelete] | ||||||
|  |     [Route("pcrb/followUp")] | ||||||
|  |     public async Task<IActionResult> DeleteFollowUp(int id) { | ||||||
|  |         DateTime start = DateTime.Now; | ||||||
|  |         bool isArgumentError = false; | ||||||
|  |         bool isInternalError = false; | ||||||
|  |         string errorMessage = ""; | ||||||
|  |  | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation("Attempting to delete follow up"); | ||||||
|  |  | ||||||
|  |             if (id <= 0) throw new ArgumentException($"{id} is not a valid PCRB follow up ID"); | ||||||
|  |  | ||||||
|  |             await _pcrbService.DeleteFollowUp(id); | ||||||
|  |  | ||||||
|  |             return Ok(); | ||||||
|  |         } catch (ArgumentException ex) { | ||||||
|  |             isArgumentError = true; | ||||||
|  |             errorMessage = ex.Message; | ||||||
|  |             return BadRequest(errorMessage); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             isInternalError = true; | ||||||
|  |             errorMessage = $"Unable to delete follow up, because {ex.Message}"; | ||||||
|  |             return Problem(errorMessage); | ||||||
|  |         } finally { | ||||||
|  |             string metricName = "DeletePCRBFollowUp"; | ||||||
|  |             DateTime end = DateTime.Now; | ||||||
|  |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|  |  | ||||||
|  |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [HttpPost] | ||||||
|  |     [Route("pcrb/followUpComment")] | ||||||
|  |     public async Task<IActionResult> CreateFollowUpComment(PCRBFollowUpComment comment) { | ||||||
|  |         DateTime start = DateTime.Now; | ||||||
|  |         bool isArgumentError = false; | ||||||
|  |         bool isInternalError = false; | ||||||
|  |         string errorMessage = ""; | ||||||
|  |  | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation("Attempting to create follow up comment"); | ||||||
|  |  | ||||||
|  |             if (comment is null) throw new ArgumentNullException("comment cannot be null"); | ||||||
|  |  | ||||||
|  |             await _pcrbService.CreateFollowUpComment(comment); | ||||||
|  |  | ||||||
|  |             return Ok(); | ||||||
|  |         } catch (ArgumentException ex) { | ||||||
|  |             isArgumentError = true; | ||||||
|  |             errorMessage = ex.Message; | ||||||
|  |             return BadRequest(errorMessage); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             isInternalError = true; | ||||||
|  |             errorMessage = $"Unable to create follow up comment, because {ex.Message}"; | ||||||
|  |             return Problem(errorMessage); | ||||||
|  |         } finally { | ||||||
|  |             string metricName = "CreatePCRBFollowUpComment"; | ||||||
|  |             DateTime end = DateTime.Now; | ||||||
|  |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|  |  | ||||||
|  |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [HttpGet] | ||||||
|  |     [Route("pcrb/followUpComments")] | ||||||
|  |     public async Task<IActionResult> GetFollowUpCommentsByPlanNumber(int planNumber, bool bypassCache) { | ||||||
|  |         DateTime start = DateTime.Now; | ||||||
|  |         bool isArgumentError = false; | ||||||
|  |         bool isInternalError = false; | ||||||
|  |         string errorMessage = ""; | ||||||
|  |  | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation($"Attempting to get follow up comments for plan# {planNumber}"); | ||||||
|  |  | ||||||
|  |             if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#"); | ||||||
|  |  | ||||||
|  |             List<PCRBFollowUpComment> comments = (await _pcrbService.GetFollowUpCommentsByPlanNumber(planNumber, bypassCache)).ToList(); | ||||||
|  |  | ||||||
|  |             return Ok(comments); | ||||||
|  |         } catch (ArgumentException ex) { | ||||||
|  |             isArgumentError = true; | ||||||
|  |             errorMessage = ex.Message; | ||||||
|  |             return BadRequest(errorMessage); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             isInternalError = true; | ||||||
|  |             errorMessage = $"Cannot get follow up comments for plan# {planNumber}, because {ex.Message}"; | ||||||
|  |             return Problem(errorMessage); | ||||||
|  |         } finally { | ||||||
|  |             string metricName = "GetPCRBFollowUpComments"; | ||||||
|  |             DateTime end = DateTime.Now; | ||||||
|  |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|  |  | ||||||
|  |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [HttpPut] | ||||||
|  |     [Route("pcrb/followUpComment")] | ||||||
|  |     public async Task<IActionResult> UpdateFollowUpComment(PCRBFollowUpComment comment) { | ||||||
|  |         DateTime start = DateTime.Now; | ||||||
|  |         bool isArgumentError = false; | ||||||
|  |         bool isInternalError = false; | ||||||
|  |         string errorMessage = ""; | ||||||
|  |  | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation("Attempting to update follow up comment"); | ||||||
|  |  | ||||||
|  |             if (comment is null) throw new ArgumentNullException("comment cannot be null"); | ||||||
|  |  | ||||||
|  |             await _pcrbService.UpdateFollowUpComment(comment); | ||||||
|  |  | ||||||
|  |             return Ok(); | ||||||
|  |         } catch (ArgumentException ex) { | ||||||
|  |             isArgumentError = true; | ||||||
|  |             errorMessage = ex.Message; | ||||||
|  |             return BadRequest(errorMessage); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             isInternalError = true; | ||||||
|  |             errorMessage = $"Unable to update follow up comment, because {ex.Message}"; | ||||||
|  |             return Problem(errorMessage); | ||||||
|  |         } finally { | ||||||
|  |             string metricName = "UpdatePCRBFollowUpComment"; | ||||||
|  |             DateTime end = DateTime.Now; | ||||||
|  |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|  |  | ||||||
|  |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [HttpDelete] | ||||||
|  |     [Route("pcrb/followUpComment")] | ||||||
|  |     public async Task<IActionResult> DeleteFollowUpComment(int id) { | ||||||
|  |         DateTime start = DateTime.Now; | ||||||
|  |         bool isArgumentError = false; | ||||||
|  |         bool isInternalError = false; | ||||||
|  |         string errorMessage = ""; | ||||||
|  |  | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation("Attempting to delete follow up comment"); | ||||||
|  |  | ||||||
|  |             if (id <= 0) throw new ArgumentException($"{id} is not a valid PCRB follow up comment ID"); | ||||||
|  |  | ||||||
|  |             await _pcrbService.DeleteFollowUpComment(id); | ||||||
|  |  | ||||||
|  |             return Ok(); | ||||||
|  |         } catch (ArgumentException ex) { | ||||||
|  |             isArgumentError = true; | ||||||
|  |             errorMessage = ex.Message; | ||||||
|  |             return BadRequest(errorMessage); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             isInternalError = true; | ||||||
|  |             errorMessage = $"Unable to delete follow up comment, because {ex.Message}"; | ||||||
|  |             return Problem(errorMessage); | ||||||
|  |         } finally { | ||||||
|  |             string metricName = "DeletePCRBFollowUpComment"; | ||||||
|  |             DateTime end = DateTime.Now; | ||||||
|  |             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||||
|  |  | ||||||
|  |             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -6,6 +6,7 @@ using dotenv.net; | |||||||
|  |  | ||||||
| using MesaFabApproval.API.Clients; | using MesaFabApproval.API.Clients; | ||||||
| using MesaFabApproval.API.Services; | using MesaFabApproval.API.Services; | ||||||
|  | using MesaFabApproval.API.Utilities; | ||||||
| using MesaFabApproval.Models; | using MesaFabApproval.Models; | ||||||
| using MesaFabApproval.Shared.Services; | using MesaFabApproval.Shared.Services; | ||||||
|  |  | ||||||
| @ -94,6 +95,7 @@ builder.Services.AddScoped<IECNService, ECNService>(); | |||||||
| builder.Services.AddScoped<ISmtpService, SmtpService>(); | builder.Services.AddScoped<ISmtpService, SmtpService>(); | ||||||
| builder.Services.AddScoped<IUserService, UserService>(); | builder.Services.AddScoped<IUserService, UserService>(); | ||||||
| builder.Services.AddScoped<IMonInWorkerClient, MonInWorkerClient>(); | builder.Services.AddScoped<IMonInWorkerClient, MonInWorkerClient>(); | ||||||
|  | builder.Services.AddScoped<IMonInUtils, MonInUtils>(); | ||||||
| builder.Services.AddScoped<IAuthenticationService, AuthenticationService>(); | builder.Services.AddScoped<IAuthenticationService, AuthenticationService>(); | ||||||
| builder.Services.AddScoped<IMRBService, MRBService>(); | builder.Services.AddScoped<IMRBService, MRBService>(); | ||||||
| builder.Services.AddScoped<IPCRBService, PCRBService>(); | builder.Services.AddScoped<IPCRBService, PCRBService>(); | ||||||
| @ -101,7 +103,6 @@ builder.Services.AddScoped<IApprovalService, ApprovalService>(); | |||||||
|  |  | ||||||
| builder.Services.AddControllers(); | builder.Services.AddControllers(); | ||||||
|  |  | ||||||
| #if DEBUG |  | ||||||
| builder.Services.AddEndpointsApiExplorer(); | builder.Services.AddEndpointsApiExplorer(); | ||||||
| builder.Services.AddSwaggerGen(c => { | builder.Services.AddSwaggerGen(c => { | ||||||
|     c.SwaggerDoc("v1", new OpenApiInfo { |     c.SwaggerDoc("v1", new OpenApiInfo { | ||||||
| @ -128,13 +129,9 @@ builder.Services.AddSwaggerGen(c => { | |||||||
|     } |     } | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
| #endif |  | ||||||
|  |  | ||||||
| WebApplication app = builder.Build(); | WebApplication app = builder.Build(); | ||||||
|  |  | ||||||
| if (Debugger.IsAttached) |  | ||||||
|     app.Services.GetRequiredService<IApprovalService>(); |  | ||||||
|  |  | ||||||
| app.UseCors(); | app.UseCors(); | ||||||
|  |  | ||||||
| // Configure the HTTP request pipeline. | // Configure the HTTP request pipeline. | ||||||
|  | |||||||
| @ -13,6 +13,7 @@ public interface IApprovalService { | |||||||
|     Task<IEnumerable<User>> GetApprovalGroupMembers(int subRoleId); |     Task<IEnumerable<User>> GetApprovalGroupMembers(int subRoleId); | ||||||
|     Task CreateApproval(Approval approval); |     Task CreateApproval(Approval approval); | ||||||
|     Task UpdateApproval(Approval approval); |     Task UpdateApproval(Approval approval); | ||||||
|  |     Task DeleteApproval(int approvalID); | ||||||
|     Task Approve(Approval approval); |     Task Approve(Approval approval); | ||||||
|     Task Deny(Approval approval); |     Task Deny(Approval approval); | ||||||
|     Task<IEnumerable<Approval>> GetApprovalsForIssueId(int issueId, bool bypassCache); |     Task<IEnumerable<Approval>> GetApprovalsForIssueId(int issueId, bool bypassCache); | ||||||
| @ -40,12 +41,11 @@ public class ApprovalService : IApprovalService { | |||||||
|  |  | ||||||
|             StringBuilder queryBuilder = new(); |             StringBuilder queryBuilder = new(); | ||||||
|             queryBuilder.Append("insert into Approval (IssueID, RoleName, SubRole, UserID, SubRoleID, ItemStatus, "); |             queryBuilder.Append("insert into Approval (IssueID, RoleName, SubRole, UserID, SubRoleID, ItemStatus, "); | ||||||
|             queryBuilder.Append("AssignedDate, DocumentTypeID, DisplayDeniedDocument, Step, TaskID) "); |             queryBuilder.Append("AssignedDate, DocumentTypeID, DisplayDeniedDocument, Step, TaskID, CompletedDate) "); | ||||||
|             queryBuilder.Append($"values ({approval.IssueID}, '{approval.RoleName}', '{approval.SubRole}', {approval.UserID}, "); |             queryBuilder.Append("values (@IssueID, @RoleName, @SubRole, @UserID, @SubRoleID, 0, @AssignedDate, 3, 0, @Step, "); | ||||||
|             queryBuilder.Append($"{approval.SubRoleID}, 0, '{approval.AssignedDate.ToString("yyyy-MM-dd HH:mm:ss")}', "); |             queryBuilder.Append("@TaskID, @CompletedDate)"); | ||||||
|             queryBuilder.Append($"3, 0, {approval.Step}, {approval.TaskID});"); |  | ||||||
|  |  | ||||||
|             int rowsCreated = await _dalService.ExecuteAsync(queryBuilder.ToString()); |             int rowsCreated = await _dalService.ExecuteAsync(queryBuilder.ToString(), approval); | ||||||
|  |  | ||||||
|             if (rowsCreated <= 0) throw new Exception("Unable to insert approval in database"); |             if (rowsCreated <= 0) throw new Exception("Unable to insert approval in database"); | ||||||
|  |  | ||||||
| @ -70,19 +70,16 @@ public class ApprovalService : IApprovalService { | |||||||
|             if (approvals is null || approvals.Count() == 0) { |             if (approvals is null || approvals.Count() == 0) { | ||||||
|                 StringBuilder queryBuilder = new(); |                 StringBuilder queryBuilder = new(); | ||||||
|                 queryBuilder.Append("select a.*, src.SubRoleCategoryItem from Approval a "); |                 queryBuilder.Append("select a.*, src.SubRoleCategoryItem from Approval a "); | ||||||
|                 queryBuilder.Append("join SubRole sr on a.SubRoleID=sr.SubRoleID "); |                 queryBuilder.Append("left outer join SubRole sr on a.SubRoleID=sr.SubRoleID "); | ||||||
|                 queryBuilder.Append("join SubRoleCategory src on sr.SubRoleCategoryID=src.SubRoleCategoryID "); |                 queryBuilder.Append("left outer join SubRoleCategory src on sr.SubRoleCategoryID=src.SubRoleCategoryID "); | ||||||
|                 queryBuilder.Append($"where a.IssueID={issueId}"); |                 queryBuilder.Append($"where a.IssueID={issueId}"); | ||||||
|  |  | ||||||
|                 approvals = (await _dalService.QueryAsync<Approval>(queryBuilder.ToString())).ToList(); |                 approvals = (await _dalService.QueryAsync<Approval>(queryBuilder.ToString())).ToList(); | ||||||
|  |  | ||||||
|                 foreach (Approval approval in approvals) { |                 foreach (Approval approval in approvals) { | ||||||
|                     int successfulUpdates = 0; |  | ||||||
|  |  | ||||||
|                     User? user = await _userService.GetUserByUserId(approval.UserID); |                     User? user = await _userService.GetUserByUserId(approval.UserID); | ||||||
|                     if (user is not null) { |                     if (user is not null) { | ||||||
|                         approval.User = user; |                         approval.User = user; | ||||||
|                         successfulUpdates++; |  | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                     if (approval.ItemStatus < 0) |                     if (approval.ItemStatus < 0) | ||||||
| @ -91,6 +88,9 @@ public class ApprovalService : IApprovalService { | |||||||
|                         approval.StatusMessage = "Assigned"; |                         approval.StatusMessage = "Assigned"; | ||||||
|                     if (approval.ItemStatus > 0) |                     if (approval.ItemStatus > 0) | ||||||
|                         approval.StatusMessage = "Approved"; |                         approval.StatusMessage = "Approved"; | ||||||
|  |  | ||||||
|  |                     if (string.IsNullOrWhiteSpace(approval.SubRoleCategoryItem)) | ||||||
|  |                         approval.SubRoleCategoryItem = approval.RoleName; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 _cache.Set($"approvals{issueId}", approvals, DateTimeOffset.Now.AddMinutes(5)); |                 _cache.Set($"approvals{issueId}", approvals, DateTimeOffset.Now.AddMinutes(5)); | ||||||
| @ -217,9 +217,12 @@ public class ApprovalService : IApprovalService { | |||||||
|             if (approvals is null) { |             if (approvals is null) { | ||||||
|                 StringBuilder queryBuilder = new(); |                 StringBuilder queryBuilder = new(); | ||||||
|                 queryBuilder.Append($"select a.*, src.SubRoleCategoryItem from Approval a "); |                 queryBuilder.Append($"select a.*, src.SubRoleCategoryItem from Approval a "); | ||||||
|                 queryBuilder.Append("join SubRole sr on a.SubRoleID=sr.SubRoleID "); |                 queryBuilder.Append("left outer join SubRole sr on a.SubRoleID=sr.SubRoleID "); | ||||||
|                 queryBuilder.Append("join SubRoleCategory src on sr.SubRoleCategoryID=src.SubRoleCategoryID "); |                 queryBuilder.Append("left outer 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 >= '{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}') or "); | ||||||
|                 queryBuilder.Append($"(CompletedDate is null));"); |                 queryBuilder.Append($"(CompletedDate is null));"); | ||||||
|                 string sql = queryBuilder.ToString(); |                 string sql = queryBuilder.ToString(); | ||||||
| @ -262,6 +265,23 @@ public class ApprovalService : IApprovalService { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public async Task DeleteApproval(int approvalID) { | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation($"Attempting to delete approval with ID: {approvalID}"); | ||||||
|  |  | ||||||
|  |             if (approvalID <= 0) throw new ArgumentException("Invalid approval ID"); | ||||||
|  |  | ||||||
|  |             string sql = "delete from Approval where ApprovalID=@ApprovalID"; | ||||||
|  |  | ||||||
|  |             int rowsDeleted = await _dalService.ExecuteAsync(sql, new { ApprovalID = approvalID }); | ||||||
|  |  | ||||||
|  |             if (rowsDeleted <= 0) throw new Exception("unable to delete approval from database"); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             _logger.LogError($"Unable to delete approval with ID: {approvalID}, because {ex.Message}"); | ||||||
|  |             throw; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public async Task Approve(Approval approval) { |     public async Task Approve(Approval approval) { | ||||||
|         try { |         try { | ||||||
|             _logger.LogInformation("Attempting to submit approval"); |             _logger.LogInformation("Attempting to submit approval"); | ||||||
|  | |||||||
| @ -144,7 +144,7 @@ public class AuthenticationService : IAuthenticationService { | |||||||
|                 Audience = _jwtAudience, |                 Audience = _jwtAudience, | ||||||
|                 Subject = identity, |                 Subject = identity, | ||||||
|                 NotBefore = DateTime.Now, |                 NotBefore = DateTime.Now, | ||||||
|                 Expires = DateTime.Now.AddHours(8), |                 Expires = DateTime.Now.AddDays(1), | ||||||
|                 SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) |                 SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) | ||||||
|             }; |             }; | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| using System.Data; | using System.Data; | ||||||
|  | using System.Text; | ||||||
|  |  | ||||||
| using Dapper; | using Dapper; | ||||||
|  |  | ||||||
| @ -6,7 +7,9 @@ namespace MesaFabApproval.API.Services; | |||||||
|  |  | ||||||
| public interface IDalService { | public interface IDalService { | ||||||
|     Task<IEnumerable<T>> QueryAsync<T>(string sql); |     Task<IEnumerable<T>> QueryAsync<T>(string sql); | ||||||
|  |     Task<IEnumerable<T>> QueryAsync<T>(string sql, object paramaters); | ||||||
|     Task<int> ExecuteAsync(string sql); |     Task<int> ExecuteAsync(string sql); | ||||||
|  |     Task<int> ExecuteAsync<T>(string sql, T paramaters); | ||||||
| } | } | ||||||
|  |  | ||||||
| public class DalService : IDalService { | public class DalService : IDalService { | ||||||
| @ -55,6 +58,45 @@ public class DalService : IDalService { | |||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public async Task<IEnumerable<T>> QueryAsync<T>(string sql, object parameters) { | ||||||
|  |         if (sql is null) throw new ArgumentNullException("sql cannot be null"); | ||||||
|  |         if (parameters is null) throw new ArgumentNullException("parameters cannot be null"); | ||||||
|  |  | ||||||
|  |         StringBuilder logBuilder = new(); | ||||||
|  |  | ||||||
|  |         int remainingRetries = RETRIES; | ||||||
|  |         bool queryWasSuccessful = false; | ||||||
|  |         Exception exception = null; | ||||||
|  |         IEnumerable<T> result = new List<T>(); | ||||||
|  |         while (!queryWasSuccessful && remainingRetries > 0) { | ||||||
|  |             int backoffSeconds = (RETRIES - remainingRetries--) * BACKOFF_SECONDS_INTERVAL; | ||||||
|  |             Task.Delay(backoffSeconds * 1000).Wait(); | ||||||
|  |  | ||||||
|  |             try { | ||||||
|  |                 logBuilder.Clear(); | ||||||
|  |                 logBuilder.Append($"Attempting to perform query with {sql} "); | ||||||
|  |                 logBuilder.Append($"and parameters {parameters.ToString()}. "); | ||||||
|  |                 logBuilder.Append($"Remaining retries: {remainingRetries}"); | ||||||
|  |                 _logger.LogInformation(logBuilder.ToString()); | ||||||
|  |  | ||||||
|  |                 using (IDbConnection conn = _dbConnectionService.GetConnection()) { | ||||||
|  |                     result = await conn.QueryAsync<T>(sql, parameters); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 queryWasSuccessful = true; | ||||||
|  |             } catch (Exception ex) { | ||||||
|  |                 _logger.LogError($"An exception occurred while attempting to perform a query. Exception: {ex.Message}"); | ||||||
|  |                 exception = ex; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (!queryWasSuccessful && exception is not null) { | ||||||
|  |             throw exception; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public async Task<int> ExecuteAsync(string sql) { |     public async Task<int> ExecuteAsync(string sql) { | ||||||
|         if (sql is null) throw new ArgumentNullException("sql cannot be null"); |         if (sql is null) throw new ArgumentNullException("sql cannot be null"); | ||||||
|  |  | ||||||
| @ -86,4 +128,36 @@ public class DalService : IDalService { | |||||||
|  |  | ||||||
|         return rowsAffected; |         return rowsAffected; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public async Task<int> ExecuteAsync<T>(string sql, T parameters) { | ||||||
|  |         if (sql is null) throw new ArgumentNullException("sql cannot be null"); | ||||||
|  |  | ||||||
|  |         int remainingRetries = RETRIES; | ||||||
|  |         bool queryWasSuccessful = false; | ||||||
|  |         Exception exception = null; | ||||||
|  |         int rowsAffected = 0; | ||||||
|  |         while (!queryWasSuccessful && remainingRetries > 0) { | ||||||
|  |             int backoffSeconds = (RETRIES - remainingRetries--) * BACKOFF_SECONDS_INTERVAL; | ||||||
|  |             Task.Delay(backoffSeconds * 1000).Wait(); | ||||||
|  |  | ||||||
|  |             try { | ||||||
|  |                 _logger.LogInformation($"Attempting to execute {sql} with parameters. Remaining retries: {remainingRetries}"); | ||||||
|  |  | ||||||
|  |                 using (IDbConnection conn = _dbConnectionService.GetConnection()) { | ||||||
|  |                     rowsAffected = await conn.ExecuteAsync(sql, parameters); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 queryWasSuccessful = true; | ||||||
|  |             } catch (Exception ex) { | ||||||
|  |                 _logger.LogError($"An exception occurred while attempting to execute a query. Exception: {ex.Message}"); | ||||||
|  |                 exception = ex; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (!queryWasSuccessful && exception is not null) { | ||||||
|  |             throw exception; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return rowsAffected; | ||||||
|  |     } | ||||||
| } | } | ||||||
| @ -4,6 +4,7 @@ namespace MesaFabApproval.API.Services; | |||||||
|  |  | ||||||
| public interface IECNService { | public interface IECNService { | ||||||
|     Task<bool> IsValidECNNumber(int number); |     Task<bool> IsValidECNNumber(int number); | ||||||
|  |     Task<IEnumerable<int>> GetAllECNNumbers(); | ||||||
| } | } | ||||||
|  |  | ||||||
| public class ECNService : IECNService { | public class ECNService : IECNService { | ||||||
| @ -43,4 +44,19 @@ public class ECNService : IECNService { | |||||||
|             throw; |             throw; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public async Task<IEnumerable<int>> GetAllECNNumbers() { | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation("Attempting to get all ECN#s"); | ||||||
|  |  | ||||||
|  |             string sql = "select ECNNumber from ECN where Deleted=0 and Cancelled=0"; | ||||||
|  |  | ||||||
|  |             IEnumerable<int> allEcnNumbers = await _dalService.QueryAsync<int>(sql); | ||||||
|  |  | ||||||
|  |             return allEcnNumbers; | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             _logger.LogError($"Unable to get all ECN#s, because {ex.Message}"); | ||||||
|  |             throw; | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| @ -212,9 +212,9 @@ public class MRBService : IMRBService { | |||||||
|                 StringBuilder queryBuilder = new(); |                 StringBuilder queryBuilder = new(); | ||||||
|                 queryBuilder.Append("select (u.FirstName + ' ' + u.LastName) as OriginatorName, m.* "); |                 queryBuilder.Append("select (u.FirstName + ' ' + u.LastName) as OriginatorName, m.* "); | ||||||
|                 queryBuilder.Append("from MRB m join Users u on m.OriginatorID = u.UserID "); |                 queryBuilder.Append("from MRB m join Users u on m.OriginatorID = u.UserID "); | ||||||
|                 queryBuilder.Append($"where m.Title = '{title}'"); |                 queryBuilder.Append("where m.Title = @Title"); | ||||||
|  |  | ||||||
|                 mrb = (await _dalService.QueryAsync<MRB>(queryBuilder.ToString())).FirstOrDefault(); |                 mrb = (await _dalService.QueryAsync<MRB>(queryBuilder.ToString(), new { Title=title })).FirstOrDefault(); | ||||||
|  |  | ||||||
|                 _cache.Set($"mrb{title}", mrb, DateTimeOffset.Now.AddHours(1)); |                 _cache.Set($"mrb{title}", mrb, DateTimeOffset.Now.AddHours(1)); | ||||||
|             } |             } | ||||||
| @ -852,8 +852,8 @@ public class MRBService : IMRBService { | |||||||
|                             convertToPart += partStr; |                             convertToPart += partStr; | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                     dt.Rows.Add(action.Action, convertFromCustomer, convertFromPart, action.Quantity.ToString(), |                     dt.Rows.Add(action.Action, convertFromCustomer, convertFromPart, action.LotNumber,  | ||||||
|                                 convertToCustomer, convertToPart, |                                 action.Quantity.ToString(), convertToCustomer, convertToPart, | ||||||
|                                 DateTimeUtilities.GetDateAsStringMinDefault(action.AssignedDate), |                                 DateTimeUtilities.GetDateAsStringMinDefault(action.AssignedDate), | ||||||
|                                 DateTimeUtilities.GetDateAsStringMaxDefault(action.CompletedDate), |                                 DateTimeUtilities.GetDateAsStringMaxDefault(action.CompletedDate), | ||||||
|                                 action.CompletedByUser is null ? "" : action.CompletedByUser.GetFullName()); |                                 action.CompletedByUser is null ? "" : action.CompletedByUser.GetFullName()); | ||||||
|  | |||||||
| @ -34,9 +34,18 @@ public interface IPCRBService { | |||||||
|     Task UpdatePCR3Document(PCR3Document document); |     Task UpdatePCR3Document(PCR3Document document); | ||||||
|     Task<IEnumerable<PCR3Document>> GetPCR3DocumentsForPlanNumber(int planNumber, bool bypassCache); |     Task<IEnumerable<PCR3Document>> GetPCR3DocumentsForPlanNumber(int planNumber, bool bypassCache); | ||||||
|     Task NotifyNewApprovals(PCRB pcrb); |     Task NotifyNewApprovals(PCRB pcrb); | ||||||
|  |     Task NotifyApprover(PCRBNotification notification); | ||||||
|     Task NotifyApprovers(PCRBNotification notification); |     Task NotifyApprovers(PCRBNotification notification); | ||||||
|     Task NotifyOriginator(PCRBNotification notification); |     Task NotifyOriginator(PCRBNotification notification); | ||||||
|     Task NotifyResponsiblePerson(PCRBActionItemNotification notification); |     Task NotifyResponsiblePerson(PCRBActionItemNotification notification); | ||||||
|  |     Task CreateFollowUp(PCRBFollowUp followUp); | ||||||
|  |     Task<IEnumerable<PCRBFollowUp>> GetFollowUpsByPlanNumber(int planNumber, bool bypassCache); | ||||||
|  |     Task UpdateFollowUp(PCRBFollowUp followUp); | ||||||
|  |     Task DeleteFollowUp(int id); | ||||||
|  |     Task CreateFollowUpComment(PCRBFollowUpComment comment); | ||||||
|  |     Task<IEnumerable<PCRBFollowUpComment>> GetFollowUpCommentsByPlanNumber(int planNumber, bool bypassCache); | ||||||
|  |     Task UpdateFollowUpComment(PCRBFollowUpComment comment); | ||||||
|  |     Task DeleteFollowUpComment(int id); | ||||||
| } | } | ||||||
|  |  | ||||||
| public class PCRBService : IPCRBService { | public class PCRBService : IPCRBService { | ||||||
| @ -74,16 +83,15 @@ public class PCRBService : IPCRBService { | |||||||
|  |  | ||||||
|             if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null"); |             if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null"); | ||||||
|  |  | ||||||
|  |             pcrb.LastUpdateDate = DateTime.Now; | ||||||
|  |  | ||||||
|             StringBuilder queryBuilder = new(); |             StringBuilder queryBuilder = new(); | ||||||
|             queryBuilder.Append("insert into CCChangeControl (OwnerID, Title, ChangeLevel, ReasonForChange, "); |             queryBuilder.Append("insert into CCChangeControl (OwnerID, Title, ChangeLevel, ReasonForChange, "); | ||||||
|             queryBuilder.Append("ChangeDescription, IsITAR, CurrentStep, InsertTimeStamp, LastUpdateDate) "); |             queryBuilder.Append("ChangeDescription, IsITAR, CurrentStep, InsertTimeStamp, LastUpdateDate, Type) "); | ||||||
|             queryBuilder.Append($"values ({pcrb.OwnerID}, '{pcrb.Title}', '{pcrb.ChangeLevel}', "); |             queryBuilder.Append("values (@OwnerID, @Title, @ChangeLevel, @ReasonForChange, @ChangeDescription, "); | ||||||
|             queryBuilder.Append($"'{pcrb.ReasonForChange}', '{pcrb.ChangeDescription}', "); |             queryBuilder.Append("@IsITAR, @CurrentStep, @InsertTimeStamp, @LastUpdateDate, @Type)"); | ||||||
|             queryBuilder.Append($"{Convert.ToInt32(pcrb.IsITAR)}, {pcrb.CurrentStep}, "); |  | ||||||
|             queryBuilder.Append($"'{pcrb.InsertTimeStamp.ToString("yyyy-MM-dd HH:mm:ss")}', "); |  | ||||||
|             queryBuilder.Append($"'{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}')"); |  | ||||||
|  |  | ||||||
|             int rowsCreated = await _dalService.ExecuteAsync(queryBuilder.ToString()); |             int rowsCreated = await _dalService.ExecuteAsync(queryBuilder.ToString(), pcrb); | ||||||
|  |  | ||||||
|             if (rowsCreated <= 0) throw new Exception("unable to insert new PCRB in the database"); |             if (rowsCreated <= 0) throw new Exception("unable to insert new PCRB in the database"); | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
| @ -107,6 +115,7 @@ public class PCRBService : IPCRBService { | |||||||
|                 foreach (PCRB pcrb in allPCRBs) { |                 foreach (PCRB pcrb in allPCRBs) { | ||||||
|                     if (string.IsNullOrWhiteSpace(pcrb.OwnerName) && pcrb.OwnerID > 0) |                     if (string.IsNullOrWhiteSpace(pcrb.OwnerName) && pcrb.OwnerID > 0) | ||||||
|                         pcrb.OwnerName = (await _userService.GetUserByUserId(pcrb.OwnerID)).GetFullName(); |                         pcrb.OwnerName = (await _userService.GetUserByUserId(pcrb.OwnerID)).GetFullName(); | ||||||
|  |                     pcrb.FollowUps = await GetFollowUpsByPlanNumber(pcrb.PlanNumber, bypassCache); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 _cache.Set("allPCRBs", allPCRBs, DateTimeOffset.Now.AddHours(1)); |                 _cache.Set("allPCRBs", allPCRBs, DateTimeOffset.Now.AddHours(1)); | ||||||
| @ -141,6 +150,8 @@ public class PCRBService : IPCRBService { | |||||||
|                     if (string.IsNullOrWhiteSpace(pcrb.OwnerName) && pcrb.OwnerID > 0) |                     if (string.IsNullOrWhiteSpace(pcrb.OwnerName) && pcrb.OwnerID > 0) | ||||||
|                         pcrb.OwnerName = (await _userService.GetUserByUserId(pcrb.OwnerID)).GetFullName(); |                         pcrb.OwnerName = (await _userService.GetUserByUserId(pcrb.OwnerID)).GetFullName(); | ||||||
|  |  | ||||||
|  |                     pcrb.FollowUps = await GetFollowUpsByPlanNumber(pcrb.PlanNumber, bypassCache); | ||||||
|  |  | ||||||
|                     _cache.Set($"pcrb{planNumber}", pcrb, DateTimeOffset.Now.AddHours(1)); |                     _cache.Set($"pcrb{planNumber}", pcrb, DateTimeOffset.Now.AddHours(1)); | ||||||
|                     _cache.Set($"pcrb{pcrb.Title}", pcrb, DateTimeOffset.Now.AddHours(1)); |                     _cache.Set($"pcrb{pcrb.Title}", pcrb, DateTimeOffset.Now.AddHours(1)); | ||||||
|                 } |                 } | ||||||
| @ -166,9 +177,9 @@ public class PCRBService : IPCRBService { | |||||||
|             if (!bypassCache) pcrb = _cache.Get<PCRB>($"pcrb{title}"); |             if (!bypassCache) pcrb = _cache.Get<PCRB>($"pcrb{title}"); | ||||||
|  |  | ||||||
|             if (pcrb is null) { |             if (pcrb is null) { | ||||||
|                 string sql = $"select * from CCChangeControl where Title='{title}'"; |                 string sql = "select * from CCChangeControl where Title=@Title"; | ||||||
|  |  | ||||||
|                 pcrb = (await _dalService.QueryAsync<PCRB>(sql)).FirstOrDefault(); |                 pcrb = (await _dalService.QueryAsync<PCRB>(sql, new { Title = title })).FirstOrDefault(); | ||||||
|  |  | ||||||
|                 if (pcrb is not null) { |                 if (pcrb is not null) { | ||||||
|                     if (string.IsNullOrWhiteSpace(pcrb.OwnerName) && pcrb.OwnerID > 0) |                     if (string.IsNullOrWhiteSpace(pcrb.OwnerName) && pcrb.OwnerID > 0) | ||||||
| @ -194,18 +205,16 @@ public class PCRBService : IPCRBService { | |||||||
|  |  | ||||||
|             if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null"); |             if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null"); | ||||||
|  |  | ||||||
|             StringBuilder queryBuilder = new(); |             pcrb.LastUpdateDate = DateTime.Now; | ||||||
|             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}"); |  | ||||||
|  |  | ||||||
|             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"); |             if (rowsAffected <= 0) throw new Exception("unable to perform update in database"); | ||||||
|  |  | ||||||
| @ -485,6 +494,20 @@ public class PCRBService : IPCRBService { | |||||||
|             int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString()); |             int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString()); | ||||||
|  |  | ||||||
|             if (rowsAffected <= 0) throw new Exception("update failed in database"); |             if (rowsAffected <= 0) throw new Exception("update failed in database"); | ||||||
|  |  | ||||||
|  |             IEnumerable<PCRBAttendee>? attendees = _cache.Get<IEnumerable<PCRBAttendee>>($"pcrbAttendees{attendee.PlanNumber}"); | ||||||
|  |             if (attendees is not null) { | ||||||
|  |                 foreach (PCRBAttendee cachedAttendee in attendees) { | ||||||
|  |                     if (cachedAttendee.ID == attendee.ID) { | ||||||
|  |                         cachedAttendee.Location = attendee.Location; | ||||||
|  |                         cachedAttendee.Attended = attendee.Attended; | ||||||
|  |                         cachedAttendee.JobTitle = attendee.JobTitle; | ||||||
|  |                         cachedAttendee.AttendeeID = attendee.AttendeeID; | ||||||
|  |                         cachedAttendee.Step = attendee.Step; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 _cache.Set($"pcrbAttendees{attendee.PlanNumber}", attendees, DateTimeOffset.Now.AddMinutes(15)); | ||||||
|  |             } | ||||||
|         } catch (Exception ex) { |         } catch (Exception ex) { | ||||||
|             _logger.LogError($"Unable to update attendee, because {ex.Message}"); |             _logger.LogError($"Unable to update attendee, because {ex.Message}"); | ||||||
|             throw; |             throw; | ||||||
| @ -644,6 +667,62 @@ public class PCRBService : IPCRBService { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public async Task NotifyApprover(PCRBNotification notification) { | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation("Attempting to send a notification to an approver"); | ||||||
|  |  | ||||||
|  |             if (notification is null) throw new ArgumentNullException("notification cannot be null"); | ||||||
|  |             if (notification.PCRB is null) throw new ArgumentNullException("PCRB cannot be null"); | ||||||
|  |             if (notification.Approval is null) throw new ArgumentNullException("approval cannot be null"); | ||||||
|  |  | ||||||
|  |             User user = await _userService.GetUserByUserId(notification.Approval.UserID); | ||||||
|  |  | ||||||
|  |             List<MailAddress> toAddresses = new(); | ||||||
|  |             toAddresses.Add(new MailAddress(user.Email)); | ||||||
|  |  | ||||||
|  |             List<string> ccEmails = new List<string>(); | ||||||
|  |  | ||||||
|  |             if (notification.NotifyQaPreApprover) { | ||||||
|  |                 IEnumerable<User> qaPreApprovers = await GetQAPreApprovers(); | ||||||
|  |  | ||||||
|  |                 foreach (User qaPreApprover in qaPreApprovers) { | ||||||
|  |                     if (!ccEmails.Contains(qaPreApprover.Email)) | ||||||
|  |                         ccEmails.Add(qaPreApprover.Email); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             List<MailAddress> ccAddresses = new(); | ||||||
|  |             foreach (string email in ccEmails) { | ||||||
|  |                 ccAddresses.Add(new MailAddress(email)); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             StringBuilder sb = new(); | ||||||
|  |  | ||||||
|  |             string subject = string.Empty; | ||||||
|  |             if (!string.IsNullOrWhiteSpace(notification.Subject)) { | ||||||
|  |                 subject = notification.Subject; | ||||||
|  |             } else { | ||||||
|  |                 sb.Append($"[Approval Update] Mesa Fab Approval - PCRB# {notification.PCRB.PlanNumber} - "); | ||||||
|  |                 sb.Append($"{notification.PCRB.Title}"); | ||||||
|  |  | ||||||
|  |                 subject = sb.ToString(); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             sb.Clear(); | ||||||
|  |             sb.Append($"{notification.Message} <br /> <br />"); | ||||||
|  |             sb.Append($"Click {_siteBaseUrl}/redirect?redirectPath=pcrb/{notification.PCRB.PlanNumber} "); | ||||||
|  |             sb.Append("to view the PCRB."); | ||||||
|  |  | ||||||
|  |             await _smtpService.SendEmail(toAddresses, ccAddresses, subject, sb.ToString()); | ||||||
|  |  | ||||||
|  |             notification.Approval.NotifyDate = DateTime.Now; | ||||||
|  |             await _approvalService.UpdateApproval(notification.Approval); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             _logger.LogError($"Unable to send notification to approver, because {ex.Message}"); | ||||||
|  |             throw; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public async Task NotifyApprovers(PCRBNotification notification) { |     public async Task NotifyApprovers(PCRBNotification notification) { | ||||||
|         try { |         try { | ||||||
|             _logger.LogInformation("Attempting to send notification to approvers"); |             _logger.LogInformation("Attempting to send notification to approvers"); | ||||||
| @ -697,9 +776,28 @@ public class PCRBService : IPCRBService { | |||||||
|             List<MailAddress> toAddresses = new(); |             List<MailAddress> toAddresses = new(); | ||||||
|             toAddresses.Add(new MailAddress(user.Email)); |             toAddresses.Add(new MailAddress(user.Email)); | ||||||
|  |  | ||||||
|             List<MailAddress> ccAddresses = new(); |             List<string> ccEmails = new List<string>(); | ||||||
|  |  | ||||||
|             string subject = $"[Update] Mesa Fab Approval - PCRB# {notification.PCRB.PlanNumber} - {notification.PCRB.Title}"; |             if (notification.NotifyQaPreApprover) { | ||||||
|  |                 IEnumerable<User> qaPreApprovers = await GetQAPreApprovers(); | ||||||
|  |  | ||||||
|  |                 foreach (User qaPreApprover in qaPreApprovers) { | ||||||
|  |                     if (!ccEmails.Contains(qaPreApprover.Email)) | ||||||
|  |                         ccEmails.Add(qaPreApprover.Email); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             List<MailAddress> ccAddresses = new(); | ||||||
|  |             foreach (string email in ccEmails) { | ||||||
|  |                 ccAddresses.Add(new MailAddress(email)); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             string subject = string.Empty; | ||||||
|  |             if (!string.IsNullOrWhiteSpace(notification.Subject)) { | ||||||
|  |                 subject = notification.Subject; | ||||||
|  |             } else { | ||||||
|  |                 subject = $"[Update] Mesa Fab Approval - PCRB# {notification.PCRB.PlanNumber} - {notification.PCRB.Title}"; | ||||||
|  |             } | ||||||
|  |  | ||||||
|             StringBuilder bodyBuilder = new(); |             StringBuilder bodyBuilder = new(); | ||||||
|             bodyBuilder.Append($"{notification.Message} <br /> <br />"); |             bodyBuilder.Append($"{notification.Message} <br /> <br />"); | ||||||
| @ -741,6 +839,174 @@ public class PCRBService : IPCRBService { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public async Task CreateFollowUp(PCRBFollowUp followUp) { | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation("Attempting to create PCRB follow up"); | ||||||
|  |  | ||||||
|  |             if (followUp is null) throw new ArgumentNullException("follow up cannot be null"); | ||||||
|  |  | ||||||
|  |             StringBuilder queryBuilder = new(); | ||||||
|  |             queryBuilder.Append("insert into CCPCRBFollowUp (PlanNumber, Step, FollowUpDate, CompletedDate, UpdateDate) "); | ||||||
|  |             queryBuilder.Append("values (@PlanNumber, @Step, @FollowUpDate, @CompletedDate, @UpdateDate)"); | ||||||
|  |  | ||||||
|  |             int rowsReturned = await _dalService.ExecuteAsync<PCRBFollowUp>(queryBuilder.ToString(), followUp); | ||||||
|  |  | ||||||
|  |             if (rowsReturned <= 0) throw new Exception("unable to insert new follow up in the database"); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             _logger.LogError($"Unable to create new follow up, because {ex.Message}"); | ||||||
|  |             throw; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public async Task<IEnumerable<PCRBFollowUp>> GetFollowUpsByPlanNumber(int planNumber, bool bypassCache) { | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation($"Attempting to fetch follow ups for PCRB {planNumber}"); | ||||||
|  |  | ||||||
|  |             if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#"); | ||||||
|  |  | ||||||
|  |             IEnumerable<PCRBFollowUp>? followUps = new List<PCRBFollowUp>(); | ||||||
|  |  | ||||||
|  |             if (!bypassCache) | ||||||
|  |                 followUps = _cache.Get<IEnumerable<PCRBFollowUp>>($"pcrbFollowUps{planNumber}"); | ||||||
|  |  | ||||||
|  |             if (followUps is null || followUps.Count() == 0) {  | ||||||
|  |                 string sql = "select * from CCPCRBFollowUp where PlanNumber=@PlanNumber"; | ||||||
|  |  | ||||||
|  |                 followUps = await _dalService.QueryAsync<PCRBFollowUp>(sql, new { PlanNumber = planNumber }); | ||||||
|  |  | ||||||
|  |                 if (followUps is not null) | ||||||
|  |                     _cache.Set($"pcrbFollowUps{planNumber}", followUps, DateTimeOffset.Now.AddHours(1)); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return followUps ?? new List<PCRBFollowUp>(); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             _logger.LogError($"Unable to fetch follow ups for PCRB {planNumber}, because {ex.Message}"); | ||||||
|  |             throw; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public async Task UpdateFollowUp(PCRBFollowUp followUp) { | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation("Attempting to update a follow up"); | ||||||
|  |  | ||||||
|  |             if (followUp is null) | ||||||
|  |                 throw new ArgumentNullException("follow up cannot be null"); | ||||||
|  |  | ||||||
|  |             StringBuilder queryBuilder = new(); | ||||||
|  |             queryBuilder.Append("update CCPCRBFollowUp set Step=@Step, FollowUpDate=@FollowUpDate, IsComplete=@IsComplete, "); | ||||||
|  |             queryBuilder.Append("IsDeleted=@IsDeleted, CompletedDate=@CompletedDate, IsPendingApproval=@IsPendingApproval, "); | ||||||
|  |             queryBuilder.Append("UpdateDate=@UpdateDate "); | ||||||
|  |             queryBuilder.Append("where ID=@ID"); | ||||||
|  |  | ||||||
|  |             int rowsAffected = await _dalService.ExecuteAsync<PCRBFollowUp>(queryBuilder.ToString(), followUp); | ||||||
|  |  | ||||||
|  |             if (rowsAffected <= 0) throw new Exception("update failed in database"); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             _logger.LogError($"Unable to update follow up, because {ex.Message}"); | ||||||
|  |             throw; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public async Task DeleteFollowUp(int id) { | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation($"Attempting to delete follow up {id}"); | ||||||
|  |  | ||||||
|  |             if (id <= 0) throw new ArgumentException($"{id} is not a valid follow up ID"); | ||||||
|  |  | ||||||
|  |             string sql = "delete from CCPCRBFollowUp where ID=@ID"; | ||||||
|  |  | ||||||
|  |             int rowsAffected = await _dalService.ExecuteAsync(sql, new { ID = id }); | ||||||
|  |  | ||||||
|  |             if (rowsAffected <= 0) throw new Exception("delete operation failed in database"); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             _logger.LogError($"Unable to delete follow up {id}, because {ex.Message}"); | ||||||
|  |             throw; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public async Task CreateFollowUpComment(PCRBFollowUpComment comment) { | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation("Attempting to create PCRB follow up"); | ||||||
|  |  | ||||||
|  |             if (comment is null) throw new ArgumentNullException("comment cannot be null"); | ||||||
|  |  | ||||||
|  |             StringBuilder queryBuilder = new(); | ||||||
|  |             queryBuilder.Append("insert into CCPCRBFollowUpComments (PlanNumber, FollowUpID, Comment, CommentDate, UserID) "); | ||||||
|  |             queryBuilder.Append("values (@PlanNumber, @FollowUpID, @Comment, @CommentDate, @UserID)"); | ||||||
|  |  | ||||||
|  |             int rowsReturned = await _dalService.ExecuteAsync<PCRBFollowUpComment>(queryBuilder.ToString(), comment); | ||||||
|  |  | ||||||
|  |             if (rowsReturned <= 0) throw new Exception("unable to insert new follow up comment in the database"); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             _logger.LogError($"Unable to create new follow up comment, because {ex.Message}"); | ||||||
|  |             throw; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public async Task<IEnumerable<PCRBFollowUpComment>> GetFollowUpCommentsByPlanNumber(int planNumber, bool bypassCache) { | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation($"Attempting to fetch follow up comments for PCRB {planNumber}"); | ||||||
|  |  | ||||||
|  |             if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#"); | ||||||
|  |  | ||||||
|  |             IEnumerable<PCRBFollowUpComment>? comments = new List<PCRBFollowUpComment>(); | ||||||
|  |  | ||||||
|  |             if (!bypassCache) | ||||||
|  |                 comments = _cache.Get<IEnumerable<PCRBFollowUpComment>>($"pcrbFollowUpComments{planNumber}"); | ||||||
|  |  | ||||||
|  |             if (comments is null || comments.Count() == 0) { | ||||||
|  |                 string sql = "select * from CCPCRBFollowUpComments where PlanNumber=@PlanNumber"; | ||||||
|  |  | ||||||
|  |                 comments = await _dalService.QueryAsync<PCRBFollowUpComment>(sql, new { PlanNumber = planNumber }); | ||||||
|  |  | ||||||
|  |                 if (comments is not null) | ||||||
|  |                     _cache.Set($"pcrbFollowUpComments{planNumber}", comments, DateTimeOffset.Now.AddHours(1)); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return comments ?? new List<PCRBFollowUpComment>(); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             _logger.LogError($"Unable to fetch follow up comments for PCRB {planNumber}, because {ex.Message}"); | ||||||
|  |             throw; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public async Task UpdateFollowUpComment(PCRBFollowUpComment comment) { | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation("Attempting to update a follow up"); | ||||||
|  |  | ||||||
|  |             if (comment is null) | ||||||
|  |                 throw new ArgumentNullException("comment cannot be null"); | ||||||
|  |  | ||||||
|  |             StringBuilder queryBuilder = new(); | ||||||
|  |             queryBuilder.Append("update CCPCRBFollowUpComments set Comment=@Comment, CommentDate=@CommentDate, "); | ||||||
|  |             queryBuilder.Append("UserID=@UserID where ID=@ID"); | ||||||
|  |  | ||||||
|  |             int rowsAffected = await _dalService.ExecuteAsync<PCRBFollowUpComment>(queryBuilder.ToString(), comment); | ||||||
|  |  | ||||||
|  |             if (rowsAffected <= 0) throw new Exception("update failed in database"); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             _logger.LogError($"Unable to update follow up comment, because {ex.Message}"); | ||||||
|  |             throw; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public async Task DeleteFollowUpComment(int id) { | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation($"Attempting to delete follow up comment {id}"); | ||||||
|  |  | ||||||
|  |             if (id <= 0) throw new ArgumentException($"{id} is not a valid follow up ID"); | ||||||
|  |  | ||||||
|  |             string sql = "delete from CCPCRBFollowUpComments where ID=@ID"; | ||||||
|  |  | ||||||
|  |             int rowsAffected = await _dalService.ExecuteAsync(sql, new { ID = id }); | ||||||
|  |  | ||||||
|  |             if (rowsAffected <= 0) throw new Exception("delete operation failed in database"); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             _logger.LogError($"Unable to delete follow up comment {id}, because {ex.Message}"); | ||||||
|  |             throw; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private async Task SaveAttachmentInDb(IFormFile file, PCRBAttachment attachment) { |     private async Task SaveAttachmentInDb(IFormFile file, PCRBAttachment attachment) { | ||||||
|         try { |         try { | ||||||
|             _logger.LogInformation($"Attempting to save attachment to database"); |             _logger.LogInformation($"Attempting to save attachment to database"); | ||||||
| @ -764,4 +1030,34 @@ public class PCRBService : IPCRBService { | |||||||
|             throw; |             throw; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private async Task<IEnumerable<User>> GetQAPreApprovers() { | ||||||
|  |         try { | ||||||
|  |             _logger.LogInformation("Attempting to fetch QA Pre-Approvers"); | ||||||
|  |  | ||||||
|  |             IEnumerable<User> qaPreApprovers = new List<User>(); | ||||||
|  |  | ||||||
|  |             int qaPreApproverRoleId = await _approvalService.GetRoleIdForRoleName("QA_PRE_APPROVAL"); | ||||||
|  |  | ||||||
|  |             if (qaPreApproverRoleId > 0) { | ||||||
|  |                 IEnumerable<SubRole> qaPreApproverSubRoles = | ||||||
|  |                     await _approvalService.GetSubRolesForSubRoleName("QA_PRE_APPROVAL", qaPreApproverRoleId); | ||||||
|  |  | ||||||
|  |                 foreach (SubRole subRole in qaPreApproverSubRoles) { | ||||||
|  |                     IEnumerable<User> members = | ||||||
|  |                         await _approvalService.GetApprovalGroupMembers(subRole.SubRoleID); | ||||||
|  |  | ||||||
|  |                     foreach (User member in members) { | ||||||
|  |                         if (!qaPreApprovers.Any(u => u.UserID == member.UserID)) | ||||||
|  |                             qaPreApprovers = qaPreApprovers.Append(member); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             return qaPreApprovers; | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             _logger.LogError($"Unable to fetch QA Pre-Approvers, because {ex.Message}"); | ||||||
|  |             throw; | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
							
								
								
									
										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" | ||||||
							
								
								
									
										95
									
								
								MesaFabApproval.Client.Test/ApprovalServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								MesaFabApproval.Client.Test/ApprovalServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,95 @@ | |||||||
|  | using System; | ||||||
|  | using System.Net; | ||||||
|  | using System.Net.Http; | ||||||
|  | using System.Threading; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | using MesaFabApproval.Client.Services; | ||||||
|  | using MesaFabApproval.Shared.Models; | ||||||
|  |  | ||||||
|  | using Microsoft.Extensions.Caching.Memory; | ||||||
|  |  | ||||||
|  | using Moq; | ||||||
|  | using Moq.Protected; | ||||||
|  |  | ||||||
|  | using Xunit; | ||||||
|  |  | ||||||
|  | namespace MesaFabApproval.Client.Test; | ||||||
|  |  | ||||||
|  | public class ApprovalServiceTests { | ||||||
|  |     private readonly Mock<IMemoryCache> _cacheMock; | ||||||
|  |     private readonly Mock<IHttpClientFactory> _httpClientFactoryMock; | ||||||
|  |     private readonly ApprovalService _approvalService; | ||||||
|  |  | ||||||
|  |     public ApprovalServiceTests() { | ||||||
|  |         _cacheMock = new Mock<IMemoryCache>(); | ||||||
|  |         _httpClientFactoryMock = new Mock<IHttpClientFactory>(); | ||||||
|  |         _approvalService = new ApprovalService(_cacheMock.Object, _httpClientFactoryMock.Object); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteApproval_ValidApprovalID_DeletesApproval() { | ||||||
|  |         int approvalID = 1; | ||||||
|  |  | ||||||
|  |         Mock<HttpMessageHandler> handlerMock = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         handlerMock | ||||||
|  |             .Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(req => req.Method == HttpMethod.Delete), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>() | ||||||
|  |             ) | ||||||
|  |             .ReturnsAsync(new HttpResponseMessage { | ||||||
|  |                 StatusCode = HttpStatusCode.OK, | ||||||
|  |             }); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(handlerMock.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _httpClientFactoryMock.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await _approvalService.DeleteApproval(approvalID); | ||||||
|  |  | ||||||
|  |         handlerMock.Protected().Verify( | ||||||
|  |             "SendAsync", | ||||||
|  |             Times.Once(), | ||||||
|  |             ItExpr.Is<HttpRequestMessage>(req => req.Method == HttpMethod.Delete), | ||||||
|  |             ItExpr.IsAny<CancellationToken>() | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteApproval_InvalidApprovalID_ThrowsArgumentException() { | ||||||
|  |         int approvalID = 0; | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<ArgumentException>(() => _approvalService.DeleteApproval(approvalID)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteApproval_DeletionFails_ThrowsException() { | ||||||
|  |         int approvalID = 1; | ||||||
|  |  | ||||||
|  |         Mock<HttpMessageHandler> handlerMock = new Mock<HttpMessageHandler>(); | ||||||
|  |         handlerMock | ||||||
|  |             .Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(req => req.Method == HttpMethod.Delete), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>() | ||||||
|  |             ) | ||||||
|  |             .ReturnsAsync(new HttpResponseMessage { | ||||||
|  |                 StatusCode = HttpStatusCode.BadRequest, | ||||||
|  |                 ReasonPhrase = "Bad Request" | ||||||
|  |             }); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(handlerMock.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _httpClientFactoryMock.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _approvalService.DeleteApproval(approvalID)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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> | ||||||
							
								
								
									
										18
									
								
								MesaFabApproval.Client.Test/MockMemoryCacheService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								MesaFabApproval.Client.Test/MockMemoryCacheService.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | using Microsoft.Extensions.Caching.Memory; | ||||||
|  |  | ||||||
|  | using Moq; | ||||||
|  |  | ||||||
|  | namespace MesaFabApproval.Client.Test; | ||||||
|  |  | ||||||
|  | public static class MockMemoryCacheService { | ||||||
|  |     public static Mock<IMemoryCache> GetMemoryCache(object expectedValue) { | ||||||
|  |         Mock<IMemoryCache> mockMemoryCache = new Mock<IMemoryCache>(); | ||||||
|  |         mockMemoryCache | ||||||
|  |             .Setup(x => x.TryGetValue(It.IsAny<object>(), out expectedValue)) | ||||||
|  |             .Returns(true); | ||||||
|  |         mockMemoryCache | ||||||
|  |             .Setup(x => x.CreateEntry(It.IsAny<object>())) | ||||||
|  |             .Returns(Mock.Of<ICacheEntry>()); | ||||||
|  |         return mockMemoryCache; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										320
									
								
								MesaFabApproval.Client.Test/PCRBFollowUpCommentTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										320
									
								
								MesaFabApproval.Client.Test/PCRBFollowUpCommentTests.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,320 @@ | |||||||
|  | using System.Net; | ||||||
|  | using System.Text.Json; | ||||||
|  |  | ||||||
|  | using MesaFabApproval.Client.Services; | ||||||
|  | using MesaFabApproval.Shared.Models; | ||||||
|  |  | ||||||
|  | using Microsoft.Extensions.Caching.Memory; | ||||||
|  |  | ||||||
|  | using Moq; | ||||||
|  | using Moq.Protected; | ||||||
|  |  | ||||||
|  | using MudBlazor; | ||||||
|  |  | ||||||
|  | namespace MesaFabApproval.Client.Test; | ||||||
|  |  | ||||||
|  | public class PCRBFollowUpCommentTests { | ||||||
|  |     private readonly Mock<IMemoryCache> _mockCache; | ||||||
|  |     private readonly Mock<IHttpClientFactory> _mockHttpClientFactory; | ||||||
|  |     private readonly Mock<ISnackbar> _mockSnackbar; | ||||||
|  |     private readonly Mock<IUserService> _mockUserService; | ||||||
|  |     private readonly PCRBService _pcrbService; | ||||||
|  |  | ||||||
|  |     private static PCRBFollowUpComment FOLLOW_UP_COMMENT = new PCRBFollowUpComment { | ||||||
|  |         ID = 1, | ||||||
|  |         PlanNumber = 123, | ||||||
|  |         FollowUpID = 1, | ||||||
|  |         Comment = "Test Comment", | ||||||
|  |         UserID = 1 | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     private static HttpResponseMessage GET_RESPONSE = new HttpResponseMessage { | ||||||
|  |         StatusCode = HttpStatusCode.OK, | ||||||
|  |         Content = new StringContent(JsonSerializer.Serialize(new List<PCRBFollowUpComment> { FOLLOW_UP_COMMENT })) | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     private static IEnumerable<PCRBFollowUpComment> FOLLOW_UPS_COMMENTS = new List<PCRBFollowUpComment>() { FOLLOW_UP_COMMENT }; | ||||||
|  |  | ||||||
|  |     private static HttpResponseMessage SUCCESSFUL_RESPONSE = new HttpResponseMessage(HttpStatusCode.OK); | ||||||
|  |     private static HttpResponseMessage UNSUCCESSFUL_RESPONSE = new HttpResponseMessage(HttpStatusCode.InternalServerError); | ||||||
|  |  | ||||||
|  |     public PCRBFollowUpCommentTests() { | ||||||
|  |         _mockCache = MockMemoryCacheService.GetMemoryCache(FOLLOW_UPS_COMMENTS); | ||||||
|  |         _mockHttpClientFactory = new Mock<IHttpClientFactory>(); | ||||||
|  |         _mockSnackbar = new Mock<ISnackbar>(); | ||||||
|  |         _mockUserService = new Mock<IUserService>(); | ||||||
|  |  | ||||||
|  |         _pcrbService = new PCRBService( | ||||||
|  |             _mockCache.Object, | ||||||
|  |             _mockHttpClientFactory.Object, | ||||||
|  |             _mockSnackbar.Object, | ||||||
|  |             _mockUserService.Object); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateFollowUpComment_WithValidParams_ShouldCallHttpPost_AndRefreshCache() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Post), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(SUCCESSFUL_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(GET_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await _pcrbService.CreateFollowUpComment(FOLLOW_UP_COMMENT); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected().Verify( | ||||||
|  |             "SendAsync", | ||||||
|  |             Times.Once(), | ||||||
|  |             ItExpr.Is<HttpRequestMessage>( | ||||||
|  |                 req =>  | ||||||
|  |                     req.Method == HttpMethod.Post && | ||||||
|  |                     req.RequestUri != null && | ||||||
|  |                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUpComment")), | ||||||
|  |             ItExpr.IsAny<CancellationToken>()); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected().Verify( | ||||||
|  |             "SendAsync", | ||||||
|  |             Times.Once(), | ||||||
|  |             ItExpr.Is<HttpRequestMessage>( | ||||||
|  |                 req =>  | ||||||
|  |                     req.Method == HttpMethod.Get && | ||||||
|  |                     req.RequestUri != null && | ||||||
|  |                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUpComments?planNumber=123&bypassCache=True")), | ||||||
|  |             ItExpr.IsAny<CancellationToken>()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateFollowUpComment_WithBadResponse_ShouldThrowException() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Post), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(UNSUCCESSFUL_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUpComment(FOLLOW_UP_COMMENT)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateFollowUpComment_WithNullParam_ShouldThrowException() { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.CreateFollowUpComment(null)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task GetFollowUpCommentsByPlanNumber_WithBypassCache_ShouldCallHttpGetAndReturnFollowUps() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(GET_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         IEnumerable<PCRBFollowUpComment> comments = await _pcrbService.GetFollowUpCommentsByPlanNumber(123, true); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected().Verify( | ||||||
|  |             "SendAsync", | ||||||
|  |             Times.Once(), | ||||||
|  |             ItExpr.Is<HttpRequestMessage>( | ||||||
|  |                 req => | ||||||
|  |                     req.Method == HttpMethod.Get && | ||||||
|  |                     req.RequestUri != null && | ||||||
|  |                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUpComments?planNumber=123&bypassCache=True")), | ||||||
|  |             ItExpr.IsAny<CancellationToken>()); | ||||||
|  |  | ||||||
|  |         Assert.Single(comments); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task GetFollowUpCommentsByPlanNumber_WithoutBypassCache_ShouldReturnFollowUpsFromCache() { | ||||||
|  |         IEnumerable<PCRBFollowUpComment> comments = await _pcrbService.GetFollowUpCommentsByPlanNumber(1, false); | ||||||
|  |         Assert.Single(comments); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task GetFollowUpCommentsByPlanNumber_WithBadResponse_ShouldThrowException() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(UNSUCCESSFUL_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.GetFollowUpCommentsByPlanNumber(1, true)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdateFollowUpComment_WithValidParams_ShouldCallHttpPut() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Put), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(SUCCESSFUL_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(GET_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await _pcrbService.UpdateFollowUpComment(FOLLOW_UP_COMMENT); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected().Verify( | ||||||
|  |             "SendAsync", | ||||||
|  |             Times.Once(), | ||||||
|  |             ItExpr.Is<HttpRequestMessage>( | ||||||
|  |                 req => | ||||||
|  |                     req.Method == HttpMethod.Put && | ||||||
|  |                     req.RequestUri != null && | ||||||
|  |                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUpComment")), | ||||||
|  |             ItExpr.IsAny<CancellationToken>()); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected().Verify( | ||||||
|  |             "SendAsync", | ||||||
|  |             Times.Once(), | ||||||
|  |             ItExpr.Is<HttpRequestMessage>( | ||||||
|  |                 req => | ||||||
|  |                     req.Method == HttpMethod.Get && | ||||||
|  |                     req.RequestUri != null && | ||||||
|  |                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUpComments?planNumber=123&bypassCache=True")), | ||||||
|  |             ItExpr.IsAny<CancellationToken>()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdateFollowUpComment_WithNullParam_ShouldThrowException() { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.UpdateFollowUpComment(null)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdateFollowUpComment_WithBadResponse_ShouldThrowException() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Put), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(UNSUCCESSFUL_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUpComment(FOLLOW_UP_COMMENT)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteFollowUpComment_WithValidParams_ShouldCallHttpDelete() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Delete), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(SUCCESSFUL_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await _pcrbService.DeleteFollowUpComment(1); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected().Verify( | ||||||
|  |             "SendAsync", | ||||||
|  |             Times.Once(), | ||||||
|  |             ItExpr.Is<HttpRequestMessage>( | ||||||
|  |                 req => | ||||||
|  |                     req.Method == HttpMethod.Delete && | ||||||
|  |                     req.RequestUri != null && | ||||||
|  |                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUpComment?id=1")), | ||||||
|  |             ItExpr.IsAny<CancellationToken>()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteFollowUpComment_WithBadId_ShouldThrowException() { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentException>(() => _pcrbService.DeleteFollowUpComment(0)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteFollowUpComment_WithBadResponse_ShouldThrowException() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Delete), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(UNSUCCESSFUL_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.DeleteFollowUpComment(1)); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										321
									
								
								MesaFabApproval.Client.Test/PCRBFollowUpTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										321
									
								
								MesaFabApproval.Client.Test/PCRBFollowUpTests.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,321 @@ | |||||||
|  | using System.Net; | ||||||
|  | using System.Text.Json; | ||||||
|  |  | ||||||
|  | using MesaFabApproval.Client.Services; | ||||||
|  | using MesaFabApproval.Shared.Models; | ||||||
|  |  | ||||||
|  | using Microsoft.Extensions.Caching.Memory; | ||||||
|  |  | ||||||
|  | using Moq; | ||||||
|  | using Moq.Protected; | ||||||
|  |  | ||||||
|  | using MudBlazor; | ||||||
|  |  | ||||||
|  | namespace MesaFabApproval.Client.Test; | ||||||
|  |  | ||||||
|  | public partial class PCRBFollowUpTests { | ||||||
|  |     private readonly Mock<IMemoryCache> _mockCache; | ||||||
|  |     private readonly Mock<IHttpClientFactory> _mockHttpClientFactory; | ||||||
|  |     private readonly Mock<ISnackbar> _mockSnackbar; | ||||||
|  |     private readonly Mock<IUserService> _mockUserService; | ||||||
|  |     private readonly PCRBService _pcrbService; | ||||||
|  |  | ||||||
|  |     private static PCRBFollowUp FOLLOW_UP = new PCRBFollowUp { | ||||||
|  |         ID = 1, | ||||||
|  |         PlanNumber = 123, | ||||||
|  |         Step = 1, | ||||||
|  |         FollowUpDate = DateTime.Now | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     private static HttpResponseMessage GET_RESPONSE = new HttpResponseMessage { | ||||||
|  |         StatusCode = HttpStatusCode.OK, | ||||||
|  |         Content = new StringContent(JsonSerializer.Serialize(new List<PCRBFollowUp> { FOLLOW_UP })) | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     private static IEnumerable<PCRBFollowUp> FOLLOW_UPS = new List<PCRBFollowUp>() { | ||||||
|  |         new PCRBFollowUp { ID = 1, PlanNumber = 1, Step = 1, FollowUpDate = DateTime.Now } | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     private static HttpResponseMessage SUCCESSFUL_RESPONSE = new HttpResponseMessage(HttpStatusCode.OK); | ||||||
|  |     private static HttpResponseMessage UNSUCCESSFUL_RESPONSE = new HttpResponseMessage(HttpStatusCode.InternalServerError); | ||||||
|  |  | ||||||
|  |     public PCRBFollowUpTests() { | ||||||
|  |         _mockCache = MockMemoryCacheService.GetMemoryCache(FOLLOW_UPS); | ||||||
|  |         _mockHttpClientFactory = new Mock<IHttpClientFactory>(); | ||||||
|  |         _mockSnackbar = new Mock<ISnackbar>(); | ||||||
|  |         _mockUserService = new Mock<IUserService>(); | ||||||
|  |  | ||||||
|  |         _pcrbService = new PCRBService( | ||||||
|  |             _mockCache.Object, | ||||||
|  |             _mockHttpClientFactory.Object, | ||||||
|  |             _mockSnackbar.Object, | ||||||
|  |             _mockUserService.Object); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateFollowUp_WithValidParams_ShouldCallHttpPost_AndRefreshCache() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Post), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(SUCCESSFUL_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(GET_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await _pcrbService.CreateFollowUp(FOLLOW_UP); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected().Verify( | ||||||
|  |             "SendAsync", | ||||||
|  |             Times.Once(), | ||||||
|  |             ItExpr.Is<HttpRequestMessage>( | ||||||
|  |                 req =>  | ||||||
|  |                     req.Method == HttpMethod.Post && | ||||||
|  |                     req.RequestUri != null && | ||||||
|  |                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUp")), | ||||||
|  |             ItExpr.IsAny<CancellationToken>()); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected().Verify( | ||||||
|  |             "SendAsync", | ||||||
|  |             Times.Once(), | ||||||
|  |             ItExpr.Is<HttpRequestMessage>( | ||||||
|  |                 req =>  | ||||||
|  |                     req.Method == HttpMethod.Get && | ||||||
|  |                     req.RequestUri != null && | ||||||
|  |                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUps?planNumber=123&bypassCache=True")), | ||||||
|  |             ItExpr.IsAny<CancellationToken>()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateFollowUp_WithBadResponse_ShouldThrowException() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Post), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(UNSUCCESSFUL_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUp(FOLLOW_UP)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task CreateFollowUp_WithNullParam_ShouldThrowException() { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.CreateFollowUp(null)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task GetFollowUpsByPlanNumber_WithBypassCache_ShouldCallHttpGetAndReturnFollowUps() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(GET_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         IEnumerable<PCRBFollowUp> followUps = await _pcrbService.GetFollowUpsByPlanNumber(123, true); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected().Verify( | ||||||
|  |             "SendAsync", | ||||||
|  |             Times.Once(), | ||||||
|  |             ItExpr.Is<HttpRequestMessage>( | ||||||
|  |                 req => | ||||||
|  |                     req.Method == HttpMethod.Get && | ||||||
|  |                     req.RequestUri != null && | ||||||
|  |                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUps?planNumber=123&bypassCache=True")), | ||||||
|  |             ItExpr.IsAny<CancellationToken>()); | ||||||
|  |  | ||||||
|  |         Assert.Single(followUps); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task GetFollowUpsByPlanNumber_WithoutBypassCache_ShouldReturnFollowUpsFromCache() { | ||||||
|  |         IEnumerable<PCRBFollowUp> followUps = await _pcrbService.GetFollowUpsByPlanNumber(1, false); | ||||||
|  |         Assert.Single(followUps); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task GetFollowUpsByPlanNumber_WithBadResponse_ShouldThrowException() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(UNSUCCESSFUL_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.GetFollowUpsByPlanNumber(1, true)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdateFollowUp_WithValidParams_ShouldCallHttpPut() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Put), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(SUCCESSFUL_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(GET_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await _pcrbService.UpdateFollowUp(FOLLOW_UP); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected().Verify( | ||||||
|  |             "SendAsync", | ||||||
|  |             Times.Once(), | ||||||
|  |             ItExpr.Is<HttpRequestMessage>( | ||||||
|  |                 req => | ||||||
|  |                     req.Method == HttpMethod.Put && | ||||||
|  |                     req.RequestUri != null && | ||||||
|  |                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUp")), | ||||||
|  |             ItExpr.IsAny<CancellationToken>()); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected().Verify( | ||||||
|  |             "SendAsync", | ||||||
|  |             Times.Once(), | ||||||
|  |             ItExpr.Is<HttpRequestMessage>( | ||||||
|  |                 req => | ||||||
|  |                     req.Method == HttpMethod.Get && | ||||||
|  |                     req.RequestUri != null && | ||||||
|  |                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUps?planNumber=123&bypassCache=True")), | ||||||
|  |             ItExpr.IsAny<CancellationToken>()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdateFollowUp_WithNullParam_ShouldThrowException() { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.UpdateFollowUp(null)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task UpdateFollowUp_WithBadResponse_ShouldThrowException() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Put), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(UNSUCCESSFUL_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUp(FOLLOW_UP)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteFollowUp_WithValidParams_ShouldCallHttpDelete() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Delete), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(SUCCESSFUL_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await _pcrbService.DeleteFollowUp(1); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected().Verify( | ||||||
|  |             "SendAsync", | ||||||
|  |             Times.Once(), | ||||||
|  |             ItExpr.Is<HttpRequestMessage>( | ||||||
|  |                 req => | ||||||
|  |                     req.Method == HttpMethod.Delete && | ||||||
|  |                     req.RequestUri != null && | ||||||
|  |                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUp?id=1")), | ||||||
|  |             ItExpr.IsAny<CancellationToken>()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteFollowUp_WithBadId_ShouldThrowException() { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentException>(() => _pcrbService.DeleteFollowUp(0)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task DeleteFollowUp_WithBadResponse_ShouldThrowException() { | ||||||
|  |         Mock<HttpMessageHandler> mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||||
|  |  | ||||||
|  |         mockHttpMessageHandler.Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Delete), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>()) | ||||||
|  |             .ReturnsAsync(UNSUCCESSFUL_RESPONSE) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<Exception>(() => _pcrbService.DeleteFollowUp(1)); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										156
									
								
								MesaFabApproval.Client.Test/PCRBServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										156
									
								
								MesaFabApproval.Client.Test/PCRBServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,156 @@ | |||||||
|  | using System.Net; | ||||||
|  | using System.Net.Http; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | using MesaFabApproval.Client.Services; | ||||||
|  | using MesaFabApproval.Shared.Models; | ||||||
|  |  | ||||||
|  | using Microsoft.Extensions.Caching.Memory; | ||||||
|  |  | ||||||
|  | using Moq; | ||||||
|  | using Moq.Protected; | ||||||
|  |  | ||||||
|  | using MudBlazor; | ||||||
|  |  | ||||||
|  | using Xunit; | ||||||
|  |  | ||||||
|  | namespace MesaFabApproval.Client.Test; | ||||||
|  |  | ||||||
|  | public class PCRBServiceTests { | ||||||
|  |     private readonly Mock<IMemoryCache> _mockCache; | ||||||
|  |     private readonly Mock<IHttpClientFactory> _mockHttpClientFactory; | ||||||
|  |     private readonly Mock<ISnackbar> _mockSnackbar; | ||||||
|  |     private readonly Mock<IUserService> _mockUserService; | ||||||
|  |     private readonly Mock<PCRB> _mockPCRB; | ||||||
|  |     private readonly Mock<Approval> _mockApproval; | ||||||
|  |  | ||||||
|  |     private readonly PCRBService _pcrbService; | ||||||
|  |  | ||||||
|  |     public PCRBServiceTests() { | ||||||
|  |         _mockCache = new Mock<IMemoryCache>(); | ||||||
|  |         _mockHttpClientFactory = new Mock<IHttpClientFactory>(); | ||||||
|  |         _mockSnackbar = new Mock<ISnackbar>(); | ||||||
|  |         _mockUserService = new Mock<IUserService>(); | ||||||
|  |         _mockPCRB = new Mock<PCRB>(); | ||||||
|  |         _mockApproval = new Mock<Approval>(); | ||||||
|  |  | ||||||
|  |         _pcrbService = new PCRBService( | ||||||
|  |             _mockCache.Object, | ||||||
|  |             _mockHttpClientFactory.Object, | ||||||
|  |             _mockSnackbar.Object, | ||||||
|  |             _mockUserService.Object | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task NotifyApprover_ShouldSendNotification() { | ||||||
|  |         PCRBNotification notification = new PCRBNotification { | ||||||
|  |             Message = "Test Message", | ||||||
|  |             PCRB = _mockPCRB.Object, | ||||||
|  |             Approval = _mockApproval.Object | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         Mock<HttpMessageHandler> handlerMock = new Mock<HttpMessageHandler>(); | ||||||
|  |         handlerMock | ||||||
|  |             .Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Post), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>() | ||||||
|  |             ) | ||||||
|  |             .ReturnsAsync(new HttpResponseMessage { | ||||||
|  |                 StatusCode = HttpStatusCode.OK | ||||||
|  |             }) | ||||||
|  |             .Verifiable(); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(handlerMock.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         await _pcrbService.NotifyApprover(notification); | ||||||
|  |  | ||||||
|  |         handlerMock.Protected().Verify( | ||||||
|  |             "SendAsync", | ||||||
|  |             Times.Once(), | ||||||
|  |             ItExpr.Is<HttpRequestMessage>(req => | ||||||
|  |                 req.Method == HttpMethod.Post && | ||||||
|  |                 req.RequestUri == new Uri("https://localhost:5000/pcrb/notify/approver") | ||||||
|  |             ), | ||||||
|  |             ItExpr.IsAny<CancellationToken>() | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task NotifyApprover_ShouldThrowException_WhenResponseIsNotSuccess() { | ||||||
|  |         PCRBNotification notification = new PCRBNotification { | ||||||
|  |             Message = "Test Message", | ||||||
|  |             PCRB = _mockPCRB.Object, | ||||||
|  |             Approval = _mockApproval.Object | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         var handlerMock = new Mock<HttpMessageHandler>(); | ||||||
|  |         handlerMock | ||||||
|  |             .Protected() | ||||||
|  |             .Setup<Task<HttpResponseMessage>>( | ||||||
|  |                 "SendAsync", | ||||||
|  |                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Post), | ||||||
|  |                 ItExpr.IsAny<CancellationToken>() | ||||||
|  |             ) | ||||||
|  |             .ReturnsAsync(new HttpResponseMessage { | ||||||
|  |                 StatusCode = HttpStatusCode.BadRequest, | ||||||
|  |                 ReasonPhrase = "Bad Request" | ||||||
|  |             }); | ||||||
|  |  | ||||||
|  |         HttpClient httpClient = new HttpClient(handlerMock.Object) { | ||||||
|  |             BaseAddress = new Uri("https://localhost:5000") | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||||
|  |  | ||||||
|  |         Exception exception = await Assert.ThrowsAsync<Exception>(() => _pcrbService.NotifyApprover(notification)); | ||||||
|  |         Assert.Equal("Unable to notify PCRB approver, because Bad Request", exception.Message); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task NotifyApprover_ShouldThrowException_WhenNotificationIsNull() { | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.NotifyApprover(null)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task NotifyApprover_ShouldThrowException_WhenPCRBIsNull() { | ||||||
|  |         PCRBNotification notification = new PCRBNotification { | ||||||
|  |             Message = "Test Message", | ||||||
|  |             PCRB = null, | ||||||
|  |             Approval = _mockApproval.Object | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.NotifyApprover(notification)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task NotifyApprover_ShouldThrowException_WhenApprovalIsNull() { | ||||||
|  |         PCRBNotification notification = new PCRBNotification { | ||||||
|  |             Message = "Test Message", | ||||||
|  |             PCRB = _mockPCRB.Object, | ||||||
|  |             Approval = null | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.NotifyApprover(notification)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Fact] | ||||||
|  |     public async Task NotifyApprover_ShouldThrowException_WhenMessageIsNullOrEmpty() { | ||||||
|  |         PCRBNotification notification = new PCRBNotification { | ||||||
|  |             Message = null, | ||||||
|  |             PCRB = _mockPCRB.Object, | ||||||
|  |             Approval = _mockApproval.Object | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         await Assert.ThrowsAsync<ArgumentException>(() => _pcrbService.NotifyApprover(notification)); | ||||||
|  |  | ||||||
|  |         notification.Message = string.Empty; | ||||||
|  |         await Assert.ThrowsAsync<ArgumentException>(() => _pcrbService.NotifyApprover(notification)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -15,19 +15,26 @@ | |||||||
|     </ItemGroup> |     </ItemGroup> | ||||||
|  |  | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.8" /> |     <PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.14" /> | ||||||
|     <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.8" /> |     <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.14" /> | ||||||
|     <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.8" PrivateAssets="all" /> |     <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.14" PrivateAssets="all" /> | ||||||
|     <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.2.5" /> |     <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.3.0" /> | ||||||
|     <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" /> |     <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.3.0" /> | ||||||
|     <PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="8.0.8" /> |     <PackageReference Include="Microsoft.AspNetCore.WebUtilities" Version="8.0.14" /> | ||||||
|     <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" /> |     <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" /> | ||||||
|     <PackageReference Include="MudBlazor" Version="7.6.0" /> |     <PackageReference Include="MudBlazor" Version="8.3.0" /> | ||||||
|     <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.0.1" /> |     <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.6.1" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|  |  | ||||||
|     <ItemGroup> |     <ItemGroup> | ||||||
|         <ProjectReference Include="..\MesaFabApproval.Shared\MesaFabApproval.Shared.csproj" /> |         <ProjectReference Include="..\MesaFabApproval.Shared\MesaFabApproval.Shared.csproj" /> | ||||||
|     </ItemGroup> |     </ItemGroup> | ||||||
|  |  | ||||||
|  |     <ItemGroup> | ||||||
|  |       <Content Update="wwwroot\appsettings.Development.json"> | ||||||
|  |         <ExcludeFromSingleFile>true</ExcludeFromSingleFile> | ||||||
|  |         <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> | ||||||
|  |       </Content> | ||||||
|  |     </ItemGroup> | ||||||
|  |  | ||||||
| </Project> | </Project> | ||||||
|  | |||||||
| @ -1,65 +1,2 @@ | |||||||
| @page "/redirect" | @page "/redirect" | ||||||
| @attribute [AllowAnonymous] | @attribute [AllowAnonymous] | ||||||
| @inject MesaFabApprovalAuthStateProvider authStateProvider |  | ||||||
| @inject IAuthenticationService authService |  | ||||||
| @inject IUserService userService |  | ||||||
| @inject ISnackbar snackbar |  | ||||||
| @inject MesaFabApprovalAuthStateProvider authStateProvider |  | ||||||
| @inject NavigationManager navigationManager |  | ||||||
|  |  | ||||||
| @code { |  | ||||||
|     private string? _jwt; |  | ||||||
|     private string? _refreshToken; |  | ||||||
|     private string? _redirectPath; |  | ||||||
|  |  | ||||||
|     protected override async Task OnParametersSetAsync() { |  | ||||||
|         try { |  | ||||||
|             Uri uri = navigationManager.ToAbsoluteUri(navigationManager.Uri); |  | ||||||
|  |  | ||||||
|             if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("jwt", out var jwt)) { |  | ||||||
|                 _jwt = System.Net.WebUtility.UrlDecode(jwt); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("refreshToken", out var refreshToken)) { |  | ||||||
|                 _refreshToken = System.Net.WebUtility.UrlDecode(refreshToken); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("redirectPath", out var redirectPath)) { |  | ||||||
|                 _redirectPath = redirectPath.ToString(); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (!string.IsNullOrWhiteSpace(_jwt) && !string.IsNullOrWhiteSpace(_refreshToken)) { |  | ||||||
|                 await authService.SetTokens(_jwt, _refreshToken); |  | ||||||
|  |  | ||||||
|                 ClaimsPrincipal principal = authService.GetClaimsPrincipalFromJwt(_jwt); |  | ||||||
|  |  | ||||||
|                 string loginId = userService.GetLoginIdFromClaimsPrincipal(principal); |  | ||||||
|  |  | ||||||
|                 await authService.ClearCurrentUser(); |  | ||||||
|                 await authService.ClearTokens(); |  | ||||||
|  |  | ||||||
|                 await authService.SetLoginId(loginId); |  | ||||||
|                 await authService.SetTokens(_jwt, _refreshToken); |  | ||||||
|                 await authService.SetCurrentUser(null); |  | ||||||
|  |  | ||||||
|                 await authStateProvider.StateHasChanged(principal); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (authStateProvider.CurrentUser is not null && !string.IsNullOrWhiteSpace(_redirectPath)) { |  | ||||||
|                 navigationManager.NavigateTo(_redirectPath); |  | ||||||
|             } else { |  | ||||||
|                 await authStateProvider.Logout(); |  | ||||||
|  |  | ||||||
|                 if (!string.IsNullOrWhiteSpace(_redirectPath)) { |  | ||||||
|                     navigationManager.NavigateTo($"login/{_redirectPath}"); |  | ||||||
|                 } else { |  | ||||||
|                     navigationManager.NavigateTo("login"); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|              |  | ||||||
|         } catch (Exception ex) { |  | ||||||
|             snackbar.Add($"Redirect failed, because {ex.Message}", Severity.Error); |  | ||||||
|             navigationManager.NavigateTo("login"); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										83
									
								
								MesaFabApproval.Client/Pages/AuthenticatedRedirect.razor.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								MesaFabApproval.Client/Pages/AuthenticatedRedirect.razor.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,83 @@ | |||||||
|  | using MesaFabApproval.Client.Services; | ||||||
|  | using MesaFabApproval.Shared.Models; | ||||||
|  |  | ||||||
|  | using Microsoft.AspNetCore.Components; | ||||||
|  | using Microsoft.AspNetCore.WebUtilities; | ||||||
|  | using Microsoft.Extensions.Caching.Memory; | ||||||
|  |  | ||||||
|  | using MudBlazor; | ||||||
|  |  | ||||||
|  | using System.Security.Claims; | ||||||
|  |  | ||||||
|  | namespace MesaFabApproval.Client.Pages; | ||||||
|  |  | ||||||
|  | public partial class AuthenticatedRedirect { | ||||||
|  |     [Inject] MesaFabApprovalAuthStateProvider authStateProvider { get; set; } | ||||||
|  |     [Inject] IAuthenticationService authService { get; set; } | ||||||
|  |     [Inject] IUserService userService { get; set; } | ||||||
|  |     [Inject] NavigationManager navigationManager { get; set; } | ||||||
|  |     [Inject] IMemoryCache cache { get; set; } | ||||||
|  |  | ||||||
|  |     private string? _jwt; | ||||||
|  |     private string? _refreshToken; | ||||||
|  |     private string? _redirectPath; | ||||||
|  |  | ||||||
|  |     protected override async Task OnParametersSetAsync() { | ||||||
|  |         try { | ||||||
|  |             Uri uri = navigationManager.ToAbsoluteUri(navigationManager.Uri); | ||||||
|  |  | ||||||
|  |             if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("jwt", out var jwt)) { | ||||||
|  |                 _jwt = System.Net.WebUtility.UrlDecode(jwt); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("refreshToken", out var refreshToken)) { | ||||||
|  |                 _refreshToken = System.Net.WebUtility.UrlDecode(refreshToken); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("redirectPath", out var redirectPath)) { | ||||||
|  |                 _redirectPath = redirectPath.ToString(); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (!string.IsNullOrWhiteSpace(_jwt) && !string.IsNullOrWhiteSpace(_refreshToken)) { | ||||||
|  |                 await authService.SetTokens(_jwt, _refreshToken); | ||||||
|  |  | ||||||
|  |                 ClaimsPrincipal principal = authService.GetClaimsPrincipalFromJwt(_jwt); | ||||||
|  |  | ||||||
|  |                 string loginId = userService.GetLoginIdFromClaimsPrincipal(principal); | ||||||
|  |  | ||||||
|  |                 await authService.ClearCurrentUser(); | ||||||
|  |                 await authService.ClearTokens(); | ||||||
|  |  | ||||||
|  |                 await authService.SetLoginId(loginId); | ||||||
|  |                 await authService.SetTokens(_jwt, _refreshToken); | ||||||
|  |                 await authService.SetCurrentUser(null); | ||||||
|  |  | ||||||
|  |                 await authStateProvider.StateHasChanged(principal); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             AuthTokens authTokens = await authService.GetAuthTokens(); | ||||||
|  |  | ||||||
|  |             if (authStateProvider.CurrentUser is not null && !string.IsNullOrWhiteSpace(_redirectPath)) { | ||||||
|  |                 navigationManager.NavigateTo(_redirectPath); | ||||||
|  |             } else { | ||||||
|  |                 await authStateProvider.Logout(); | ||||||
|  |  | ||||||
|  |                 if (!string.IsNullOrWhiteSpace(_redirectPath)) { | ||||||
|  |                     cache.Set("redirectUrl", _redirectPath); | ||||||
|  |                     navigationManager.NavigateTo($"login?redirectPath={_redirectPath}"); | ||||||
|  |                 } else { | ||||||
|  |                     navigationManager.NavigateTo("login"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             await authStateProvider.Logout(); | ||||||
|  |  | ||||||
|  |             if (!string.IsNullOrWhiteSpace(_redirectPath)) { | ||||||
|  |                 cache.Set("redirectUrl", _redirectPath); | ||||||
|  |                 navigationManager.NavigateTo($"login?redirectPath={_redirectPath}"); | ||||||
|  |             } else { | ||||||
|  |                 navigationManager.NavigateTo("login"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -37,7 +37,7 @@ | |||||||
| </MudDialog> | </MudDialog> | ||||||
|  |  | ||||||
| @code { | @code { | ||||||
|     [CascadingParameter] MudDialogInstance MudDialog { get; set; } |     [CascadingParameter] IMudDialogInstance MudDialog { get; set; } | ||||||
|  |  | ||||||
|     [Parameter] |     [Parameter] | ||||||
|     public string comments { get; set; } = ""; |     public string comments { get; set; } = ""; | ||||||
|  | |||||||
| @ -54,7 +54,7 @@ | |||||||
| </MudDialog> | </MudDialog> | ||||||
|  |  | ||||||
| @code { | @code { | ||||||
|     [CascadingParameter] MudDialogInstance MudDialog { get; set; } |     [CascadingParameter] IMudDialogInstance MudDialog { get; set; } | ||||||
|  |  | ||||||
|     [Parameter] |     [Parameter] | ||||||
|     public string comments { get; set; } = ""; |     public string comments { get; set; } = ""; | ||||||
|  | |||||||
| @ -143,7 +143,7 @@ | |||||||
| </MudDialog> | </MudDialog> | ||||||
|  |  | ||||||
| @code { | @code { | ||||||
|     [CascadingParameter] MudDialogInstance MudDialog { get; set; } |     [CascadingParameter] IMudDialogInstance MudDialog { get; set; } | ||||||
|  |  | ||||||
|     [Parameter] |     [Parameter] | ||||||
|     public MRBAction mrbAction { get; set; } |     public MRBAction mrbAction { get; set; } | ||||||
| @ -215,9 +215,7 @@ | |||||||
|         bool actionIsValid = mrbAction.Action.Equals("Block") || mrbAction.Action.Equals("Convert") || |         bool actionIsValid = mrbAction.Action.Equals("Block") || mrbAction.Action.Equals("Convert") || | ||||||
|             mrbAction.Action.Equals("Other") || mrbAction.Action.Equals("Recall") || mrbAction.Action.Equals("Scrap") || |             mrbAction.Action.Equals("Other") || mrbAction.Action.Equals("Recall") || mrbAction.Action.Equals("Scrap") || | ||||||
|             mrbAction.Action.Equals("Unblock") || mrbAction.Action.Equals("Waiver"); |             mrbAction.Action.Equals("Unblock") || mrbAction.Action.Equals("Waiver"); | ||||||
|         actionIsValid = actionIsValid && !string.IsNullOrWhiteSpace(mrbAction.Customer) && |         actionIsValid = actionIsValid && !string.IsNullOrWhiteSpace(mrbAction.LotNumber); | ||||||
|             !string.IsNullOrWhiteSpace(mrbAction.PartNumber) && |  | ||||||
|             !string.IsNullOrWhiteSpace(mrbAction.LotNumber); |  | ||||||
|         actionIsValid = actionIsValid && mrbAction.Quantity > 0; |         actionIsValid = actionIsValid && mrbAction.Quantity > 0; | ||||||
|  |  | ||||||
|         if (mrbAction.Action.Equals("Convert", StringComparison.InvariantCultureIgnoreCase)) { |         if (mrbAction.Action.Equals("Convert", StringComparison.InvariantCultureIgnoreCase)) { | ||||||
| @ -225,6 +223,9 @@ | |||||||
|                 !string.IsNullOrWhiteSpace(convertFromPart) && |                 !string.IsNullOrWhiteSpace(convertFromPart) && | ||||||
|                 !string.IsNullOrWhiteSpace(convertToCustomer) && |                 !string.IsNullOrWhiteSpace(convertToCustomer) && | ||||||
|                 !string.IsNullOrWhiteSpace(convertToPart); |                 !string.IsNullOrWhiteSpace(convertToPart); | ||||||
|  |         } else { | ||||||
|  |             actionIsValid = actionIsValid && !string.IsNullOrWhiteSpace(mrbAction.Customer) && | ||||||
|  |             !string.IsNullOrWhiteSpace(mrbAction.PartNumber); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (mrbAction.Action.Equals("Scrap", StringComparison.InvariantCultureIgnoreCase)) |         if (mrbAction.Action.Equals("Scrap", StringComparison.InvariantCultureIgnoreCase)) | ||||||
|  | |||||||
| @ -43,7 +43,7 @@ | |||||||
| </MudOverlay> | </MudOverlay> | ||||||
|  |  | ||||||
| @code { | @code { | ||||||
|     [CascadingParameter] MudDialogInstance MudDialog { get; set; } |     [CascadingParameter] IMudDialogInstance MudDialog { get; set; } | ||||||
|  |  | ||||||
|     [Parameter] |     [Parameter] | ||||||
|     public User selectedUser { get; set; } |     public User selectedUser { get; set; } | ||||||
|  | |||||||
| @ -19,6 +19,7 @@ | |||||||
|                               @bind-Value="@document.DocNumbers" |                               @bind-Value="@document.DocNumbers" | ||||||
|                               @bind-Text="@document.DocNumbers" |                               @bind-Text="@document.DocNumbers" | ||||||
|                               Immediate |                               Immediate | ||||||
|  |                               Required | ||||||
|                               AutoGrow |                               AutoGrow | ||||||
|                               AutoFocus /> |                               AutoFocus /> | ||||||
|                 @if (DocNumberIsNA()) { |                 @if (DocNumberIsNA()) { | ||||||
| @ -30,16 +31,16 @@ | |||||||
|                                   Immediate |                                   Immediate | ||||||
|                                   AutoGrow /> |                                   AutoGrow /> | ||||||
|                 } else { |                 } else { | ||||||
|                     <MudTextField @bind-Value="@document.ECNNumber" |                     <MudAutocomplete @bind-Value="@document.ECNNumber" | ||||||
|  |                                      T="int" | ||||||
|  |                                      SearchFunc="Search" | ||||||
|                                      Required |                                      Required | ||||||
|                                   RequiredError="You must provide a valid ECN#" |  | ||||||
|                                      Clearable |                                      Clearable | ||||||
|  |                                      RequiredError="You must provide a valid ECN#" | ||||||
|                                      Variant="Variant.Outlined" |                                      Variant="Variant.Outlined" | ||||||
|                                   InputType="@InputType.Number" |  | ||||||
|                                      Validation="@(new Func<int, Task<string>>(ECNNoIsValid))" |                                      Validation="@(new Func<int, Task<string>>(ECNNoIsValid))" | ||||||
|                                      Label="ECN#" |                                      Label="ECN#" | ||||||
|                                   Immediate |                                      Immediate /> | ||||||
|                                   AutoGrow /> |  | ||||||
|                 } |                 } | ||||||
|                 <MudCheckBox Label="Complete" |                 <MudCheckBox Label="Complete" | ||||||
|                              Color="Color.Tertiary" |                              Color="Color.Tertiary" | ||||||
| @ -49,8 +50,8 @@ | |||||||
|         </MudPaper> |         </MudPaper> | ||||||
|     </DialogContent> |     </DialogContent> | ||||||
|     <DialogActions> |     <DialogActions> | ||||||
|         @if ((DocNumberIsNA() && !string.IsNullOrWhiteSpace(document.Comment)) ||  |         @if (!string.IsNullOrWhiteSpace(document.DocNumbers) && ((DocNumberIsNA() && !string.IsNullOrWhiteSpace(document.Comment)) ||  | ||||||
|              (!DocNumberIsNA() && ecnNoIsValid)) { |              (!DocNumberIsNA() && ecnNoIsValid))) { | ||||||
|             <MudButton Variant="Variant.Filled" |             <MudButton Variant="Variant.Filled" | ||||||
|                        Color="Color.Tertiary" |                        Color="Color.Tertiary" | ||||||
|                        Class="m1-auto" |                        Class="m1-auto" | ||||||
| @ -73,11 +74,13 @@ | |||||||
|  |  | ||||||
| @code { | @code { | ||||||
|     [CascadingParameter]  |     [CascadingParameter]  | ||||||
|     MudDialogInstance MudDialog { get; set; } |     IMudDialogInstance MudDialog { get; set; } | ||||||
|  |  | ||||||
|     [Parameter] |     [Parameter] | ||||||
|     public required PCR3Document document { get; set; } |     public required PCR3Document document { get; set; } | ||||||
|  |  | ||||||
|  |     private IEnumerable<int> allEcnNumbers = new List<int>(); | ||||||
|  |  | ||||||
|     private string[] errors = { }; |     private string[] errors = { }; | ||||||
|  |  | ||||||
|     private bool complete = false; |     private bool complete = false; | ||||||
| @ -88,6 +91,8 @@ | |||||||
|  |  | ||||||
|     protected override async Task OnParametersSetAsync() { |     protected override async Task OnParametersSetAsync() { | ||||||
|         complete = document.CompletedByID > 0; |         complete = document.CompletedByID > 0; | ||||||
|  |  | ||||||
|  |         allEcnNumbers = await ecnService.GetAllECNNumbers(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private async Task Save() { |     private async Task Save() { | ||||||
| @ -111,6 +116,10 @@ | |||||||
|                 document.CompletedDate = DateTime.Now; |                 document.CompletedDate = DateTime.Now; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             if (string.IsNullOrWhiteSpace(document.DocNumbers)) { | ||||||
|  |                 throw new Exception("Document Numbers cannot be empty"); | ||||||
|  |             } | ||||||
|  |  | ||||||
|             if (!DocNumberIsNA() && !ecnNoIsValid)  |             if (!DocNumberIsNA() && !ecnNoIsValid)  | ||||||
|                 throw new Exception($"{document.ECNNumber} is not a valid ECN#"); |                 throw new Exception($"{document.ECNNumber} is not a valid ECN#"); | ||||||
|             if (DocNumberIsNA() && string.IsNullOrWhiteSpace(document.Comment)) |             if (DocNumberIsNA() && string.IsNullOrWhiteSpace(document.Comment)) | ||||||
| @ -135,7 +144,11 @@ | |||||||
|  |  | ||||||
|     private bool DocNumberIsNA() { |     private bool DocNumberIsNA() { | ||||||
|         if (document.DocNumbers.ToLower().Equals("na") || |         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 true; | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
| @ -148,4 +161,13 @@ | |||||||
|         StateHasChanged(); |         StateHasChanged(); | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private async Task<IEnumerable<int>> Search(string searchValue, CancellationToken token) { | ||||||
|  |         if (string.IsNullOrWhiteSpace(searchValue)) | ||||||
|  |             return allEcnNumbers; | ||||||
|  |  | ||||||
|  |         return allEcnNumbers | ||||||
|  |                 .Where(x => x.ToString().StartsWith(searchValue, StringComparison.InvariantCultureIgnoreCase)) | ||||||
|  |                 .Order(); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -73,7 +73,7 @@ | |||||||
|  |  | ||||||
| @code { | @code { | ||||||
|     [CascadingParameter]  |     [CascadingParameter]  | ||||||
|     MudDialogInstance MudDialog { get; set; } |     IMudDialogInstance MudDialog { get; set; } | ||||||
|  |  | ||||||
|     [Parameter] |     [Parameter] | ||||||
|     public int planNumber { get; set; } = 0; |     public int planNumber { get; set; } = 0; | ||||||
|  | |||||||
| @ -61,7 +61,7 @@ | |||||||
|  |  | ||||||
| @code { | @code { | ||||||
|     [CascadingParameter]  |     [CascadingParameter]  | ||||||
|     MudDialogInstance MudDialog { get; set; } |     IMudDialogInstance MudDialog { get; set; } | ||||||
|  |  | ||||||
|     [Parameter] |     [Parameter] | ||||||
|     public int planNumber { get; set; } = 0; |     public int planNumber { get; set; } = 0; | ||||||
|  | |||||||
| @ -58,7 +58,7 @@ | |||||||
| </MudDialog> | </MudDialog> | ||||||
|  |  | ||||||
| @code { | @code { | ||||||
|     [CascadingParameter] MudDialogInstance MudDialog { get; set; } |     [CascadingParameter] IMudDialogInstance MudDialog { get; set; } | ||||||
|  |  | ||||||
|     [Parameter] |     [Parameter] | ||||||
|     public int planNumber { get; set; } = 0; |     public int planNumber { get; set; } = 0; | ||||||
|  | |||||||
| @ -43,7 +43,7 @@ | |||||||
| </MudOverlay> | </MudOverlay> | ||||||
|  |  | ||||||
| @code { | @code { | ||||||
|     [CascadingParameter] MudDialogInstance MudDialog { get; set; } |     [CascadingParameter] IMudDialogInstance MudDialog { get; set; } | ||||||
|  |  | ||||||
|     [Parameter] |     [Parameter] | ||||||
|     public User selectedUser { get; set; } |     public User selectedUser { get; set; } | ||||||
|  | |||||||
| @ -1,16 +1,5 @@ | |||||||
| @page "/" | @page "/" | ||||||
| @page "/Dashboard" | @page "/Dashboard" | ||||||
| @inject IConfiguration Configuration |  | ||||||
| @inject MesaFabApprovalAuthStateProvider stateProvider |  | ||||||
| @inject IApprovalService approvalService |  | ||||||
| @inject IMemoryCache cache |  | ||||||
| @inject NavigationManager navigationManager |  | ||||||
| @inject ISnackbar snackbar |  | ||||||
| @inject IMRBService mrbService |  | ||||||
| @inject IPCRBService pcrbService |  | ||||||
| @inject IECNService ecnService |  | ||||||
| @inject ICAService caService |  | ||||||
| @inject IJSRuntime jsRuntime |  | ||||||
|  |  | ||||||
| <PageTitle>Dashboard</PageTitle> | <PageTitle>Dashboard</PageTitle> | ||||||
|  |  | ||||||
| @ -37,7 +26,7 @@ | |||||||
|                                 </MudTableSortLabel> |                                 </MudTableSortLabel> | ||||||
|                             </MudTh> |                             </MudTh> | ||||||
|                             <MudTh> |                             <MudTh> | ||||||
|                                 <MudTableSortLabel SortBy="new Func<Approval,object>(x=>x.SubRoleCategoryItem)"> |                                 <MudTableSortLabel SortBy="new Func<Approval,object>(x=>GetRoleName(x))"> | ||||||
|                                     Role |                                     Role | ||||||
|                                 </MudTableSortLabel> |                                 </MudTableSortLabel> | ||||||
|                             </MudTh> |                             </MudTh> | ||||||
| @ -58,7 +47,7 @@ | |||||||
|                                     <MudLink OnClick="@(() => FollowLink(context.IssueID))">@context.IssueID</MudLink> |                                     <MudLink OnClick="@(() => FollowLink(context.IssueID))">@context.IssueID</MudLink> | ||||||
|                                 } |                                 } | ||||||
|                             </MudTd> |                             </MudTd> | ||||||
|                             <MudTd DataLabel="Role">@context.SubRoleCategoryItem</MudTd> |                             <MudTd DataLabel="Role">@(GetRoleName(context))</MudTd> | ||||||
|                             <MudTd DataLabel="Assigned Date">@DateTimeUtilities.GetDateAsStringMinDefault(context.AssignedDate)</MudTd> |                             <MudTd DataLabel="Assigned Date">@DateTimeUtilities.GetDateAsStringMinDefault(context.AssignedDate)</MudTd> | ||||||
|                             <MudTd DataLabel="Step">@context.Step</MudTd> |                             <MudTd DataLabel="Step">@context.Step</MudTd> | ||||||
|                         </RowTemplate> |                         </RowTemplate> | ||||||
| @ -226,138 +215,3 @@ | |||||||
|         </MudTabPanel> |         </MudTabPanel> | ||||||
|     </MudTabs> |     </MudTabs> | ||||||
| </MudPaper> | </MudPaper> | ||||||
|  |  | ||||||
| @code { |  | ||||||
|     private IEnumerable<Approval> approvalList = new List<Approval>(); |  | ||||||
|     private IEnumerable<MRB> myMRBs = new List<MRB>(); |  | ||||||
|     private IEnumerable<PCRB> myPCRBs = new List<PCRB>(); |  | ||||||
|  |  | ||||||
|     private IEnumerable<int> ecnNumbers = new HashSet<int>(); |  | ||||||
|     private IEnumerable<int> caNumbers = new HashSet<int>(); |  | ||||||
|     private IEnumerable<int> mrbNumbers = new HashSet<int>(); |  | ||||||
|     private IEnumerable<int> pcrbNumbers = new HashSet<int>(); |  | ||||||
|  |  | ||||||
|     private bool myApprovalsProcessing = false; |  | ||||||
|     private bool myMrbsProcessing = false; |  | ||||||
|     private bool myPcrbsProcessing = false; |  | ||||||
|  |  | ||||||
|     private string mrbSearchString = ""; |  | ||||||
|     private string pcrbSearchString = ""; |  | ||||||
|  |  | ||||||
|     protected async override Task OnParametersSetAsync() { |  | ||||||
|         try { |  | ||||||
|             if (stateProvider.CurrentUser is not null) { |  | ||||||
|                 myApprovalsProcessing = true; |  | ||||||
|                 approvalList = (await approvalService.GetApprovalsForUserId(stateProvider.CurrentUser.UserID, true)) |  | ||||||
|                     .Where(a => a.CompletedDate > DateTime.Now && a.ItemStatus == 0) |  | ||||||
|                     .ToList() |  | ||||||
|                     .OrderByDescending(x => x.AssignedDate); |  | ||||||
|                 myApprovalsProcessing = false; |  | ||||||
|  |  | ||||||
|                 myMrbsProcessing = true; |  | ||||||
|                 myMRBs = (await mrbService.GetAllMRBs(false)).Where(m => m.OriginatorID == stateProvider.CurrentUser.UserID) |  | ||||||
|                     .ToList() |  | ||||||
|                     .OrderByDescending(x => x.SubmittedDate); |  | ||||||
|                 myMrbsProcessing = false; |  | ||||||
|  |  | ||||||
|                 myPcrbsProcessing = true; |  | ||||||
|                 myPCRBs = (await pcrbService.GetAllPCRBs(false)).Where(p => p.OwnerID == stateProvider.CurrentUser.UserID) |  | ||||||
|                     .ToList() |  | ||||||
|                     .OrderByDescending(p => p.InsertTimeStamp); |  | ||||||
|                 myPcrbsProcessing = false; |  | ||||||
|             } |  | ||||||
|         } catch (Exception ex) { |  | ||||||
|             myApprovalsProcessing = false; |  | ||||||
|             myMrbsProcessing = false; |  | ||||||
|             myPcrbsProcessing = false; |  | ||||||
|             snackbar.Add($"Unable to load the dashboard, because {ex.Message}", Severity.Error); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private async Task FollowLink(int issueId) { |  | ||||||
|         HashSet<Task> tasks = new(); |  | ||||||
|  |  | ||||||
|         bool isEcn = false; |  | ||||||
|         bool isCa = false; |  | ||||||
|         bool isMrb = false; |  | ||||||
|         bool isPcrb = false; |  | ||||||
|         if (ecnNumbers.Contains(issueId)) |  | ||||||
|             isEcn = true; |  | ||||||
|         if (caNumbers.Contains(issueId)) |  | ||||||
|             isCa = true; |  | ||||||
|         if (mrbNumbers.Contains(issueId)) |  | ||||||
|             isMrb = true; |  | ||||||
|         if (pcrbNumbers.Contains(issueId)) |  | ||||||
|             isPcrb = true; |  | ||||||
|  |  | ||||||
|         if (!isEcn && !isCa && !isMrb) { |  | ||||||
|             Task<bool> isEcnTask = ecnService.ECNNumberIsValid(issueId); |  | ||||||
|             tasks.Add(isEcnTask); |  | ||||||
|  |  | ||||||
|             Task<bool> isCaTask = caService.CANumberIsValid(issueId); |  | ||||||
|             tasks.Add(isCaTask); |  | ||||||
|  |  | ||||||
|             Task<bool> isMrbTask = mrbService.NumberIsValid(issueId); |  | ||||||
|             tasks.Add(isMrbTask); |  | ||||||
|  |  | ||||||
|             Task<bool> isPcrbTask = pcrbService.IdIsValid(issueId); |  | ||||||
|             tasks.Add(isPcrbTask); |  | ||||||
|  |  | ||||||
|             await Task.WhenAll(tasks); |  | ||||||
|  |  | ||||||
|             if (isEcnTask.Result) { |  | ||||||
|                 isEcn = true; |  | ||||||
|             } else if (isCaTask.Result) { |  | ||||||
|                 isCa = true; |  | ||||||
|             } else if (isMrbTask.Result) { |  | ||||||
|                 isMrb = true; |  | ||||||
|             } else if (isPcrbTask.Result) { |  | ||||||
|                 isPcrb = true; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (isEcn) await GoToExternal($"{Configuration["OldFabApprovalUrl"]}/ECN/Edit?IssueID={issueId}", ""); |  | ||||||
|         if (isCa) await GoToExternal($"{Configuration["OldFabApprovalUrl"]}/CorrectiveAction/Edit?IssueID={issueId}", ""); |  | ||||||
|         if (isMrb) GoTo($"mrb/{issueId}"); |  | ||||||
|         if (isPcrb) GoTo($"pcrb/{issueId}"); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private void GoTo(string page) { |  | ||||||
|         cache.Set("redirectUrl", page); |  | ||||||
|         navigationManager.NavigateTo("/" + page); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private async Task GoToExternal(string url, string content) { |  | ||||||
|         IJSObjectReference windowModule = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "./js/OpenInNewWindow.js"); |  | ||||||
|         await windowModule.InvokeAsync<object>("OpenInNewWindow", url, content); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private bool FilterFuncForMRBTable(MRB mrb) => MRBFilterFunc(mrb, mrbSearchString); |  | ||||||
|  |  | ||||||
|     private bool MRBFilterFunc(MRB mrb, string searchString) { |  | ||||||
|         if (string.IsNullOrWhiteSpace(searchString)) |  | ||||||
|             return true; |  | ||||||
|         if (mrb.Title.ToLower().Contains(searchString.Trim().ToLower())) |  | ||||||
|             return true; |  | ||||||
|         if (mrb.MRBNumber.ToString().Contains(searchString.Trim())) |  | ||||||
|             return true; |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private bool FilterFuncForPCRBTable(PCRB pcrb) => PCRBFilterFunc(pcrb, pcrbSearchString); |  | ||||||
|  |  | ||||||
|     private bool PCRBFilterFunc(PCRB pcrb, string searchString) { |  | ||||||
|         if (string.IsNullOrWhiteSpace(searchString)) |  | ||||||
|             return true; |  | ||||||
|         if (pcrb.Title.ToLower().Contains(searchString.Trim().ToLower())) |  | ||||||
|             return true; |  | ||||||
|         if (pcrb.PlanNumber.ToString().Contains(searchString.Trim())) |  | ||||||
|             return true; |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private string GetCurrentPCRBStep(int step) { |  | ||||||
|         if (step < 0 || step > (PCRB.Stages.Length - 1)) return string.Empty; |  | ||||||
|         else return PCRB.Stages[step]; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | |||||||
							
								
								
									
										165
									
								
								MesaFabApproval.Client/Pages/Dashboard.razor.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								MesaFabApproval.Client/Pages/Dashboard.razor.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,165 @@ | |||||||
|  | using MesaFabApproval.Client.Services; | ||||||
|  | using MesaFabApproval.Shared.Models; | ||||||
|  |  | ||||||
|  | using Microsoft.AspNetCore.Components; | ||||||
|  | using Microsoft.Extensions.Caching.Memory; | ||||||
|  | using Microsoft.JSInterop; | ||||||
|  |  | ||||||
|  | using MudBlazor; | ||||||
|  |  | ||||||
|  | namespace MesaFabApproval.Client.Pages; | ||||||
|  |  | ||||||
|  | public partial class Dashboard { | ||||||
|  |     [Inject] IConfiguration Configuration { get; set; } | ||||||
|  |     [Inject] MesaFabApprovalAuthStateProvider stateProvider { get; set; } | ||||||
|  |     [Inject] IApprovalService approvalService { get; set; } | ||||||
|  |     [Inject] IMemoryCache cache { get; set; } | ||||||
|  |     [Inject] NavigationManager navigationManager { get; set; } | ||||||
|  |     [Inject] ISnackbar snackbar { get; set; } | ||||||
|  |     [Inject] IMRBService mrbService { get; set; } | ||||||
|  |     [Inject] IPCRBService pcrbService { get; set; } | ||||||
|  |     [Inject] IECNService ecnService { get; set; } | ||||||
|  |     [Inject] ICAService caService { get; set; } | ||||||
|  |     [Inject] IJSRuntime jsRuntime { get; set; } | ||||||
|  |  | ||||||
|  |     private IEnumerable<Approval> approvalList = new List<Approval>(); | ||||||
|  |     private IEnumerable<MRB> myMRBs = new List<MRB>(); | ||||||
|  |     private IEnumerable<PCRB> myPCRBs = new List<PCRB>(); | ||||||
|  |  | ||||||
|  |     private IEnumerable<int> ecnNumbers = new HashSet<int>(); | ||||||
|  |     private IEnumerable<int> caNumbers = new HashSet<int>(); | ||||||
|  |     private IEnumerable<int> mrbNumbers = new HashSet<int>(); | ||||||
|  |     private IEnumerable<int> pcrbNumbers = new HashSet<int>(); | ||||||
|  |  | ||||||
|  |     private bool myApprovalsProcessing = false; | ||||||
|  |     private bool myMrbsProcessing = false; | ||||||
|  |     private bool myPcrbsProcessing = false; | ||||||
|  |  | ||||||
|  |     private string mrbSearchString = ""; | ||||||
|  |     private string pcrbSearchString = ""; | ||||||
|  |  | ||||||
|  |     protected async override Task OnParametersSetAsync() { | ||||||
|  |         try { | ||||||
|  |             if (stateProvider.CurrentUser is not null) { | ||||||
|  |                 myApprovalsProcessing = true; | ||||||
|  |                 approvalList = (await approvalService.GetApprovalsForUserId(stateProvider.CurrentUser.UserID, true)) | ||||||
|  |                     .Where(a => a.CompletedDate > DateTime.Now && a.ItemStatus == 0) | ||||||
|  |                     .ToList() | ||||||
|  |                     .OrderByDescending(x => x.AssignedDate); | ||||||
|  |                 myApprovalsProcessing = false; | ||||||
|  |  | ||||||
|  |                 myMrbsProcessing = true; | ||||||
|  |                 myMRBs = (await mrbService.GetAllMRBs(false)).Where(m => m.OriginatorID == stateProvider.CurrentUser.UserID) | ||||||
|  |                     .ToList() | ||||||
|  |                     .OrderByDescending(x => x.SubmittedDate); | ||||||
|  |                 myMrbsProcessing = false; | ||||||
|  |  | ||||||
|  |                 myPcrbsProcessing = true; | ||||||
|  |                 myPCRBs = (await pcrbService.GetAllPCRBs(false)).Where(p => p.OwnerID == stateProvider.CurrentUser.UserID) | ||||||
|  |                     .ToList() | ||||||
|  |                     .OrderByDescending(p => p.InsertTimeStamp); | ||||||
|  |                 myPcrbsProcessing = false; | ||||||
|  |             } | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             myApprovalsProcessing = false; | ||||||
|  |             myMrbsProcessing = false; | ||||||
|  |             myPcrbsProcessing = false; | ||||||
|  |             snackbar.Add(ex.Message, Severity.Error); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private async Task FollowLink(int issueId) { | ||||||
|  |         HashSet<Task> tasks = new(); | ||||||
|  |  | ||||||
|  |         bool isEcn = false; | ||||||
|  |         bool isCa = false; | ||||||
|  |         bool isMrb = false; | ||||||
|  |         bool isPcrb = false; | ||||||
|  |         if (ecnNumbers.Contains(issueId)) | ||||||
|  |             isEcn = true; | ||||||
|  |         if (caNumbers.Contains(issueId)) | ||||||
|  |             isCa = true; | ||||||
|  |         if (mrbNumbers.Contains(issueId)) | ||||||
|  |             isMrb = true; | ||||||
|  |         if (pcrbNumbers.Contains(issueId)) | ||||||
|  |             isPcrb = true; | ||||||
|  |  | ||||||
|  |         if (!isEcn && !isCa && !isMrb) { | ||||||
|  |             Task<bool> isEcnTask = ecnService.ECNNumberIsValid(issueId); | ||||||
|  |             tasks.Add(isEcnTask); | ||||||
|  |  | ||||||
|  |             Task<bool> isCaTask = caService.CANumberIsValid(issueId); | ||||||
|  |             tasks.Add(isCaTask); | ||||||
|  |  | ||||||
|  |             Task<bool> isMrbTask = mrbService.NumberIsValid(issueId); | ||||||
|  |             tasks.Add(isMrbTask); | ||||||
|  |  | ||||||
|  |             Task<bool> isPcrbTask = pcrbService.IdIsValid(issueId); | ||||||
|  |             tasks.Add(isPcrbTask); | ||||||
|  |  | ||||||
|  |             await Task.WhenAll(tasks); | ||||||
|  |  | ||||||
|  |             if (isEcnTask.Result) { | ||||||
|  |                 isEcn = true; | ||||||
|  |             } else if (isCaTask.Result) { | ||||||
|  |                 isCa = true; | ||||||
|  |             } else if (isMrbTask.Result) { | ||||||
|  |                 isMrb = true; | ||||||
|  |             } else if (isPcrbTask.Result) { | ||||||
|  |                 isPcrb = true; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (isEcn) await GoToExternal($"{Configuration["OldFabApprovalUrl"]}/ECN/Edit?IssueID={issueId}", ""); | ||||||
|  |         if (isCa) await GoToExternal($"{Configuration["OldFabApprovalUrl"]}/CorrectiveAction/Edit?IssueID={issueId}", ""); | ||||||
|  |         if (isMrb) GoTo($"mrb/{issueId}"); | ||||||
|  |         if (isPcrb) GoTo($"pcrb/{issueId}"); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void GoTo(string page) { | ||||||
|  |         cache.Set("redirectUrl", page); | ||||||
|  |         navigationManager.NavigateTo(page); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private async Task GoToExternal(string url, string content) { | ||||||
|  |         IJSObjectReference windowModule = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "./js/OpenInNewWindow.js"); | ||||||
|  |         await windowModule.InvokeAsync<object>("OpenInNewWindow", url, content); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private bool FilterFuncForMRBTable(MRB mrb) => MRBFilterFunc(mrb, mrbSearchString); | ||||||
|  |  | ||||||
|  |     private bool MRBFilterFunc(MRB mrb, string searchString) { | ||||||
|  |         if (string.IsNullOrWhiteSpace(searchString)) | ||||||
|  |             return true; | ||||||
|  |         if (mrb.Title.ToLower().Contains(searchString.Trim().ToLower())) | ||||||
|  |             return true; | ||||||
|  |         if (mrb.MRBNumber.ToString().Contains(searchString.Trim())) | ||||||
|  |             return true; | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private bool FilterFuncForPCRBTable(PCRB pcrb) => PCRBFilterFunc(pcrb, pcrbSearchString); | ||||||
|  |  | ||||||
|  |     private bool PCRBFilterFunc(PCRB pcrb, string searchString) { | ||||||
|  |         if (string.IsNullOrWhiteSpace(searchString)) | ||||||
|  |             return true; | ||||||
|  |         if (pcrb.Title.ToLower().Contains(searchString.Trim().ToLower())) | ||||||
|  |             return true; | ||||||
|  |         if (pcrb.PlanNumber.ToString().Contains(searchString.Trim())) | ||||||
|  |             return true; | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private string GetCurrentPCRBStep(int step) { | ||||||
|  |         if (step < 0 || step > (PCRB.Stages.Length - 1)) return string.Empty; | ||||||
|  |         else return PCRB.Stages[step]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private string GetRoleName(Approval approval) { | ||||||
|  |         string roleName = approval.SubRoleCategoryItem; | ||||||
|  |         if (string.IsNullOrWhiteSpace(roleName)) { | ||||||
|  |             roleName = approval.RoleName; | ||||||
|  |         } | ||||||
|  |         return roleName; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,6 +1,4 @@ | |||||||
| @page "/login" | @page "/login" | ||||||
| @page "/login/{redirectUrl}" |  | ||||||
| @page "/login/{redirectUrl}/{redirectUrlSub}" |  | ||||||
| @attribute [AllowAnonymous] | @attribute [AllowAnonymous] | ||||||
| @inject MesaFabApprovalAuthStateProvider authStateProvider | @inject MesaFabApprovalAuthStateProvider authStateProvider | ||||||
| @inject NavigationManager navManager | @inject NavigationManager navManager | ||||||
| @ -46,68 +44,5 @@ | |||||||
|             } |             } | ||||||
|         </MudButton> |         </MudButton> | ||||||
|         <MudDivider /> |         <MudDivider /> | ||||||
|         @* <MudButton |  | ||||||
|             Variant="Variant.Filled" |  | ||||||
|             Color="Color.Tertiary" |  | ||||||
|             Class="m-1" |  | ||||||
|             OnClick="LoginLocal" > |  | ||||||
|         @if (processingLocal) { |  | ||||||
|             <MudProgressCircular Class="m-1" Size="Size.Small" Indeterminate="true" /> |  | ||||||
|             <MudText>Processing</MudText> |  | ||||||
|         } else { |  | ||||||
|             <MudText>Log In (SSO)</MudText> |  | ||||||
|         } |  | ||||||
|         </MudButton> *@ |  | ||||||
|     </MudForm> |     </MudForm> | ||||||
| </MudPaper> | </MudPaper> | ||||||
|  |  | ||||||
| @code { |  | ||||||
|     [Parameter] |  | ||||||
|     public string? redirectUrl { get; set; } |  | ||||||
|     [Parameter] |  | ||||||
|     public string? redirectUrlSub { get; set; } |  | ||||||
|     private bool success; |  | ||||||
|     private bool processing = false; |  | ||||||
|     private bool processingLocal = false; |  | ||||||
|     private string[] errors = { }; |  | ||||||
|     private string? username; |  | ||||||
|     private string? password; |  | ||||||
|  |  | ||||||
|     private async Task SubmitLogin() { |  | ||||||
|         processing = true; |  | ||||||
|         if (string.IsNullOrWhiteSpace(username)) snackbar.Add("Username is required!", Severity.Error); |  | ||||||
|         else if (string.IsNullOrWhiteSpace(password)) snackbar.Add("Password is required!", Severity.Error); |  | ||||||
|         else { |  | ||||||
|             await authStateProvider.LoginAsync(username, password); |  | ||||||
|             if (!string.IsNullOrWhiteSpace(redirectUrl) && !string.IsNullOrWhiteSpace(redirectUrlSub)) { |  | ||||||
|                 navManager.NavigateTo($"{redirectUrl}/{redirectUrlSub}"); |  | ||||||
|             } else if (!string.IsNullOrWhiteSpace(redirectUrl)) { |  | ||||||
|                 navManager.NavigateTo(redirectUrl); |  | ||||||
|             } else { |  | ||||||
|                 navManager.NavigateTo("dashboard"); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         processing = false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private async Task SubmitIfEnter(KeyboardEventArgs e) { |  | ||||||
|         if (e.Key == "Enter" && success) { |  | ||||||
|             SubmitLogin(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private async Task LoginLocal() { |  | ||||||
|         processingLocal = true; |  | ||||||
|  |  | ||||||
|         await authStateProvider.LoginLocal(); |  | ||||||
|         if (!string.IsNullOrWhiteSpace(redirectUrl) && !string.IsNullOrWhiteSpace(redirectUrlSub)) { |  | ||||||
|             navManager.NavigateTo($"{redirectUrl}/{redirectUrlSub}"); |  | ||||||
|         } else if (!string.IsNullOrWhiteSpace(redirectUrl)) { |  | ||||||
|             navManager.NavigateTo(redirectUrl); |  | ||||||
|         } else { |  | ||||||
|             navManager.NavigateTo("dashboard"); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         processingLocal = false; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	