Compare commits
	
		
			30 Commits
		
	
	
		
			origin/Pro
			...
			65a433e9ab
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 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", | ||||
|     "Winsock", | ||||
|     "worlflow" | ||||
|   ] | ||||
|   ], | ||||
|   "dotnet.preferCSharpExtension": true | ||||
| } | ||||
							
								
								
									
										17
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							| @ -2,7 +2,7 @@ | ||||
|     "version": "2.0.0", | ||||
|     "tasks": [ | ||||
|         { | ||||
|             "label": "MSBuild", | ||||
|             "label": "MSBuild-Debug", | ||||
|             "command": "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe", | ||||
|             "type": "process", | ||||
|             "args": [ | ||||
| @ -16,6 +16,21 @@ | ||||
|             ], | ||||
|             "problemMatcher": "$msCompile" | ||||
|         }, | ||||
|         { | ||||
|             "label": "MSBuild-Release", | ||||
|             "command": "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe", | ||||
|             "type": "process", | ||||
|             "args": [ | ||||
|                 "/target:Build", | ||||
|                 "/restore:True", | ||||
|                 "/p:RestoreSources=https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/%3Bhttps://packagemanagement.eu.infineon.com:4430/api/v2/%3Bhttps://api.nuget.org/v3/index.json", | ||||
|                 "/detailedsummary", | ||||
|                 "/consoleloggerparameters:PerformanceSummary;ErrorsOnly;", | ||||
|                 "/property:Configuration=Release;TargetFrameworkVersion=v4.8", | ||||
|                 "Fab2ApprovalSystem/Fab2ApprovalSystem.csproj" | ||||
|             ], | ||||
|             "problemMatcher": "$msCompile" | ||||
|         }, | ||||
|         { | ||||
|             "label": "Fab2ApprovalMKLink-User Secrets Init", | ||||
|             "command": "dotnet", | ||||
|  | ||||
| @ -367,6 +367,7 @@ dotnet_diagnostic.IDE0065.severity = none # Question - | ||||
| dotnet_diagnostic.IDE0066.severity = none # Question - Use  | ||||
| dotnet_diagnostic.IDE0078.severity = none # Question - Use pattern matching (may change code meaning) | ||||
| dotnet_diagnostic.IDE0090.severity = warning # Question - Simplify new expression | ||||
| dotnet_diagnostic.IDE0100.severity = error # Question - Remove redundant equality | ||||
| dotnet_diagnostic.IDE0160.severity = warning # Question - Use block-scoped namespace | ||||
| dotnet_diagnostic.IDE0161.severity = warning # Question - Namespace declaration preferences | ||||
| dotnet_diagnostic.IDE0270.severity = none # Question - Null check can be simplified | ||||
|  | ||||
							
								
								
									
										12
									
								
								Fab2ApprovalMKLink/.vscode/mklink.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								Fab2ApprovalMKLink/.vscode/mklink.md
									
									
									
									
										vendored
									
									
								
							| @ -35,3 +35,15 @@ mklink /J "L:\DevOps\Mesa_FI\MesaFabApproval\Fab2ApprovalMKLink\PdfGenerator" "L | ||||
| mklink /J "L:\DevOps\Mesa_FI\MesaFabApproval\Fab2ApprovalMKLink\Jobs" "L:\DevOps\Mesa_FI\MesaFabApproval\Fab2ApprovalSystem\Jobs" | ||||
| mklink /J "L:\DevOps\Mesa_FI\MesaFabApproval\Fab2ApprovalMKLink\JobSchedules" "L:\DevOps\Mesa_FI\MesaFabApproval\Fab2ApprovalSystem\JobSchedules" | ||||
| ``` | ||||
|  | ||||
| ```bash 1734015544321 = 638696123443210000 = Thu Dec 12 2024 07:59:03 GMT-0700 (Mountain Standard Time) | ||||
| mklink /J ".vscode\.UserSecrets" "%AppData%\Microsoft\UserSecrets\f2da5035-aba9-4676-9f8d-d6689f84663d" | ||||
| mklink /J "DMO" "..\Fab2ApprovalSystem\DMO" | ||||
| mklink /J "Jobs" "..\Fab2ApprovalSystem\Jobs" | ||||
| mklink /J "JobSchedules" "..\Fab2ApprovalSystem\JobSchedules" | ||||
| mklink /J "Misc" "..\Fab2ApprovalSystem\Misc" | ||||
| mklink /J "Models" "..\Fab2ApprovalSystem\Models" | ||||
| mklink /J "PdfGenerator" "..\Fab2ApprovalSystem\PdfGenerator" | ||||
| mklink /J "Utilities" "..\Fab2ApprovalSystem\Utilities" | ||||
| mklink /J "ViewModels" "..\Fab2ApprovalSystem\ViewModels" | ||||
| ``` | ||||
|  | ||||
| @ -18,9 +18,15 @@ | ||||
|   <PropertyGroup Condition="'$(TargetFramework)' == 'net8.0'"> | ||||
|     <DefineConstants>NET8</DefineConstants> | ||||
|   </PropertyGroup> | ||||
|   <ItemGroup> | ||||
|     <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo"> | ||||
|       <_Parameter1>Fab2ApprovalTests</_Parameter1> | ||||
|     </AssemblyAttribute> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="Dapper.Contrib" Version="2.0.78" /> | ||||
|     <PackageReference Include="Dapper" Version="2.1.44" /> | ||||
|     <PackageReference Include="DocumentFormat.OpenXml" Version="3.3.0" /> | ||||
|     <PackageReference Include="EntityFramework" Version="6.5.1" /> | ||||
|     <PackageReference Include="ExcelDataReader" Version="3.7.0" /> | ||||
|     <PackageReference Include="jQuery" Version="3.7.1" /> | ||||
|  | ||||
| @ -1,105 +0,0 @@ | ||||
| trigger: | ||||
|   branches: | ||||
|     include: | ||||
|       - Development | ||||
|   paths: | ||||
|     include: | ||||
|       - "Fab2ApprovalSystem/*" | ||||
|     exclude: | ||||
|       - "**/*.yaml" | ||||
|       - "**/*.yml" | ||||
|       - "SQL/*" | ||||
|       - "references/*" | ||||
|       - "packages/*" | ||||
|       - "Kendo/*" | ||||
|  | ||||
| pool: | ||||
|   name: Mesa-IIS | ||||
|   demands: Fab2ApprovalSystem-Development | ||||
|  | ||||
| variables: | ||||
|   # solution: '**/*.sln' | ||||
|   # buildPlatform: 'Any CPU' | ||||
|   buildConfiguration: "Debug" | ||||
|   ASPNETCORE_ENVIRONMENT: "Development" | ||||
|  | ||||
| steps: | ||||
|   - script: | | ||||
|       set assemblyTitle=Fab2ApprovalSystem | ||||
|       echo %assemblyTitle% | ||||
|       echo ##vso[task.setvariable variable=AssemblyTitle;]%assemblyTitle% | ||||
|       echo $(AssemblyTitle) | ||||
|     displayName: AssemblyTitle | ||||
|  | ||||
|   - script: | | ||||
|       set targetFrameworkVersion=v4.8 | ||||
|       echo %targetFrameworkVersion% | ||||
|       echo ##vso[task.setvariable variable=TargetFrameworkVersion;]%targetFrameworkVersion% | ||||
|       echo $(TargetFrameworkVersion) | ||||
|     displayName: TargetFrameworkVersion | ||||
|  | ||||
|   - script: | | ||||
|       set coreVersion=na | ||||
|       echo %coreVersion% | ||||
|       echo ##vso[task.setvariable variable=CoreVersion;]%coreVersion% | ||||
|       echo $(CoreVersion) | ||||
|     displayName: CoreVersion | ||||
|  | ||||
|   - script: | | ||||
|       set configuration=Debug | ||||
|       echo %configuration% | ||||
|       echo ##vso[task.setvariable variable=Configuration;]%configuration% | ||||
|       echo $(Configuration) | ||||
|     displayName: Configuration | ||||
|  | ||||
|   - script: | | ||||
|       REM set nugetSource=https://messa017.infineon.com/v3/index.json | ||||
|       set nugetSource=https://eaf-prod.mes.infineon.com/v3/index.json | ||||
|       echo %nugetSource% | ||||
|       echo ##vso[task.setvariable variable=NugetSource;]%nugetSource% | ||||
|       echo $(NugetSource) | ||||
|     displayName: NugetSource | ||||
|  | ||||
|   - script: | | ||||
|       set gitCommit=$(Build.SourceVersion) | ||||
|       set gitCommitSeven=%gitCommit:~0,7% | ||||
|       echo %gitCommitSeven% | ||||
|       echo ##vso[task.setvariable variable=GitCommitSeven;]%gitCommitSeven% | ||||
|       echo $(GitCommitSeven) | ||||
|     displayName: GitCommitSeven | ||||
|  | ||||
|   - script: | | ||||
|       echo $(AssemblyTitle) | ||||
|       echo $(Build.BuildId) | ||||
|       echo $(Build.Reason) | ||||
|       echo $(Build.Repository.Id) | ||||
|       echo $(Build.Repository.Name) | ||||
|       echo $(Build.SourceVersion) | ||||
|       echo $(CoreVersion) | ||||
|       echo $(Configuration) | ||||
|       echo $(NugetSource) | ||||
|       echo $(GitCommitSeven) | ||||
|       echo $(TargetFrameworkVersion) | ||||
|       REM echo $(pipelinePassword) | ||||
|     displayName: "Echo Check" | ||||
|  | ||||
|   - script: '"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" /target:Restore /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:RestoreSources=$(NugetSource) $(AssemblyTitle).csproj' | ||||
|     workingDirectory: Fab2ApprovalSystem | ||||
|     displayName: "Framework Restore" | ||||
|  | ||||
|   - script: '"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" /target:Build /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj' | ||||
|     workingDirectory: Fab2ApprovalSystem | ||||
|     displayName: "Framework Build" | ||||
|  | ||||
|   - script: '"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:DebugSymbols=false /p:DeleteExistingFiles=true /p:DeployOnBuild=true /p:EnableUpdateAble=true /p:ExcludeApp_Data=true /p:LastUsedBuildConfiguration=$(Configuration) /p:LastUsedPlatform="Any CPU" /p:LaunchSiteAfterPublish=true /p:OutputPath="D:\$(TargetFrameworkVersion)\$(Build.Repository.Name)\$(GitCommitSeven)-$(Build.BuildId)-$(Build.Repository.Name)-$(Configuration)" /p:PreCompileBeforePublish=true /p:PublishProvider=FileSystem /p:PublishUrl="D:/PublishUrl" /p:SiteUrlToLaunchAfterPublish="" /p:WDPMergeOption=DoNotMerge /p:WebPublishMethod=FileSystem $(AssemblyTitle).csproj' | ||||
|     workingDirectory: Fab2ApprovalSystem | ||||
|     displayName: "Framework Pack" | ||||
|  | ||||
|   - script: '"C:/Program Files (x86)/IIS/Microsoft Web Deploy V3/MSDeploy.exe" -AllowUntrusted -dest:auto -disableLink:AppPoolExtension -disableLink:CertificateExtension -disableLink:ContentExtension -setParam:name="IIS Web Application Name",value=$(Build.Repository.Name) -setParamFile:"D:\$(TargetFrameworkVersion)\$(Build.Repository.Name)\$(GitCommitSeven)-$(Build.BuildId)-$(Build.Repository.Name)-$(Configuration)" "/_PublishedWebsites/$(Build.Repository.Name)_Package/$(Build.Repository.Name).SetParameters.xml" -source:package="D:\$(TargetFrameworkVersion)\$(Build.Repository.Name)\$(GitCommitSeven)-$(Build.BuildId)-$(Build.Repository.Name)-$(Configuration)" "/_PublishedWebsites/$(AssemblyTitle)_Package/$(AssemblyTitle).zip" -verb:sync' | ||||
|     workingDirectory: Fab2ApprovalSystem | ||||
|     displayName: "Framework Deploy" | ||||
|     enabled: false | ||||
|  | ||||
|   - script: 'echo $(Build.SourceVersion)-$(Build.BuildId)>bin_x_x_\$(Configuration)\$(CoreVersion)\win-x64\$(Build.Repository.Name).txt' | ||||
|     displayName: "Force Fail" | ||||
|     enabled: false | ||||
| @ -6,6 +6,9 @@ MinimumVisualStudioVersion = 10.0.40219.1 | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fab2ApprovalSystem", "Fab2ApprovalSystem\Fab2ApprovalSystem.csproj", "{AAE52608-4DD1-4732-92BD-CC8915DEC71E}" | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MesaFabApproval.API", "MesaFabApproval.API\MesaFabApproval.API.csproj", "{852E528D-015A-43B5-999D-F281E3359E5E}" | ||||
| 	ProjectSection(ProjectDependencies) = postProject | ||||
| 		{2C16014D-B04E-46AF-AB4C-D2691D44A339} = {2C16014D-B04E-46AF-AB4C-D2691D44A339} | ||||
| 	EndProjectSection | ||||
| EndProject | ||||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MesaFabApproval.Shared", "MesaFabApproval.Shared\MesaFabApproval.Shared.csproj", "{2C16014D-B04E-46AF-AB4C-D2691D44A339}" | ||||
| EndProject | ||||
| @ -14,6 +17,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MesaFabApproval.Client", "M | ||||
| 		{2C16014D-B04E-46AF-AB4C-D2691D44A339} = {2C16014D-B04E-46AF-AB4C-D2691D44A339} | ||||
| 	EndProjectSection | ||||
| EndProject | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MesaFabApproval.API.Test", "MesaFabApproval.API.Test\MesaFabApproval.API.Test.csproj", "{D03AB305-BA29-4EB1-AC66-ABBF76FBF5C1}" | ||||
| 	ProjectSection(ProjectDependencies) = postProject | ||||
| 		{2C16014D-B04E-46AF-AB4C-D2691D44A339} = {2C16014D-B04E-46AF-AB4C-D2691D44A339} | ||||
| 		{852E528D-015A-43B5-999D-F281E3359E5E} = {852E528D-015A-43B5-999D-F281E3359E5E} | ||||
| 	EndProjectSection | ||||
| EndProject | ||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MesaFabApproval.Client.Test", "MesaFabApproval.Client.Test\MesaFabApproval.Client.Test.csproj", "{A0E5BD7D-3910-43BD-BBA3-3820AD524423}" | ||||
| 	ProjectSection(ProjectDependencies) = postProject | ||||
| 		{2C16014D-B04E-46AF-AB4C-D2691D44A339} = {2C16014D-B04E-46AF-AB4C-D2691D44A339} | ||||
| 		{34D52F44-A81F-4247-8180-16E204824A07} = {34D52F44-A81F-4247-8180-16E204824A07} | ||||
| 	EndProjectSection | ||||
| EndProject | ||||
| Global | ||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| 		Debug|Any CPU = Debug|Any CPU | ||||
| @ -36,6 +51,14 @@ Global | ||||
| 		{34D52F44-A81F-4247-8180-16E204824A07}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| 		{34D52F44-A81F-4247-8180-16E204824A07}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| 		{34D52F44-A81F-4247-8180-16E204824A07}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| 		{D03AB305-BA29-4EB1-AC66-ABBF76FBF5C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||
| 		{D03AB305-BA29-4EB1-AC66-ABBF76FBF5C1}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| 		{D03AB305-BA29-4EB1-AC66-ABBF76FBF5C1}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| 		{D03AB305-BA29-4EB1-AC66-ABBF76FBF5C1}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| 		{A0E5BD7D-3910-43BD-BBA3-3820AD524423}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||
| 		{A0E5BD7D-3910-43BD-BBA3-3820AD524423}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||
| 		{A0E5BD7D-3910-43BD-BBA3-3820AD524423}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||
| 		{A0E5BD7D-3910-43BD-BBA3-3820AD524423}.Release|Any CPU.Build.0 = Release|Any CPU | ||||
| 	EndGlobalSection | ||||
| 	GlobalSection(SolutionProperties) = preSolution | ||||
| 		HideSolutionNode = FALSE | ||||
|  | ||||
| @ -1,18 +1,19 @@ | ||||
|     /*vertical height between form-groups*/ | ||||
|     .my-form .form-group { | ||||
|         margin-bottom: 4px; | ||||
| /*vertical height between form-groups*/ | ||||
| .my-form .form-group { | ||||
|     margin-bottom: 4px; | ||||
| } | ||||
|  | ||||
| @media (min-width:768px) { | ||||
|     .my-form .row { | ||||
|         margin-left: -1px; | ||||
|         margin-right: -1px; | ||||
|     } | ||||
|  | ||||
|     @media (min-width:768px) { | ||||
|         .my-form .row { | ||||
|             margin-left: -1px; | ||||
|             margin-right: -1px; | ||||
|         } | ||||
|  | ||||
|         .my-form [class*="col-"] { | ||||
|             padding: 0 2px; | ||||
|         } | ||||
|     .my-form [class*="col-"] { | ||||
|         padding: 0 2px; | ||||
|     } | ||||
| } | ||||
|  | ||||
| body { | ||||
|     padding-top: 50px; | ||||
|     padding-bottom: 20px; | ||||
| @ -29,12 +30,12 @@ body { | ||||
| /*input, | ||||
| select | ||||
| { | ||||
|     max-width: 280px; | ||||
| max-width: 280px; | ||||
| }*/ | ||||
|  | ||||
| .row{ | ||||
|   margin-top: 2px; | ||||
|   margin-bottom: 2px | ||||
| .row { | ||||
|     margin-top: 2px; | ||||
|     margin-bottom: 2px | ||||
| } | ||||
|  | ||||
| textarea { | ||||
| @ -68,28 +69,28 @@ input[type="checkbox"].input-validation-error { | ||||
| } | ||||
|  | ||||
| .navbar-inner { | ||||
|   padding-left: 20px; | ||||
|   padding-right: 20px; | ||||
|   background-color: #87b3de; | ||||
|   background-image: -moz-linear-gradient(top,#87b3de, #4d79a5); | ||||
|   background-image: -ms-linear-gradient(top,#87b3de, #4d79a5); | ||||
|   background-image: -webkit-gradient(linear, 0 0, 0 50%, from( #87b3de), to(#4d79a5)); | ||||
|   background-image: -webkit-linear-gradient(top,#87b3de, #4d79a5); | ||||
|   background-image: -o-linear-gradient(top, #87b3de, #4d79a5); | ||||
|   background-image: linear-gradient(top, #87b3de, #4d79a5); | ||||
|   background-repeat: repeat-x; | ||||
|   filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#87b3de', endColorstr='#4d79a5', GradientType=0); | ||||
|   -webkit-border-radius: 4px; | ||||
|   -moz-border-radius: 4px; | ||||
|   border-radius: 4px; | ||||
|   -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); | ||||
|   -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); | ||||
|   box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); | ||||
|     padding-left: 20px; | ||||
|     padding-right: 20px; | ||||
|     background-color: #87b3de; | ||||
|     background-image: -moz-linear-gradient(top, #87b3de, #4d79a5); | ||||
|     background-image: -ms-linear-gradient(top, #87b3de, #4d79a5); | ||||
|     background-image: -webkit-gradient(linear, 0 0, 0 50%, from(#87b3de), to(#4d79a5)); | ||||
|     background-image: -webkit-linear-gradient(top, #87b3de, #4d79a5); | ||||
|     background-image: -o-linear-gradient(top, #87b3de, #4d79a5); | ||||
|     background-image: linear-gradient(top, #87b3de, #4d79a5); | ||||
|     background-repeat: repeat-x; | ||||
|     filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#87b3de', endColorstr='#4d79a5', GradientType=0); | ||||
|     -webkit-border-radius: 4px; | ||||
|     -moz-border-radius: 4px; | ||||
|     border-radius: 4px; | ||||
|     -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); | ||||
|     -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); | ||||
|     box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25), inset 0 -1px 0 rgba(0, 0, 0, 0.1); | ||||
| } | ||||
|  | ||||
| .label-color { | ||||
|         background-color: #e5e0e0; | ||||
|     } | ||||
|     background-color: #e5e0e0; | ||||
| } | ||||
|  | ||||
| .linkbutton { | ||||
|     display: inline-block; | ||||
| @ -101,6 +102,17 @@ input[type="checkbox"].input-validation-error { | ||||
|     border: 0; | ||||
|     vertical-align: middle; | ||||
| } | ||||
|  | ||||
| .linkbutton.edit { | ||||
|     background: url('/Content/icons/edit.gif'); | ||||
| } | ||||
|  | ||||
| .modal-dialog { | ||||
|     margin-top: 80px; | ||||
| } | ||||
|  | ||||
| .affix { | ||||
|   position: fixed; | ||||
|   top: 55px; | ||||
|   left: 25px; | ||||
| } | ||||
| @ -24,12 +24,9 @@ namespace Fab2ApprovalSystem.Controllers; | ||||
|  | ||||
| [Authorize] | ||||
| public class AccountController : Controller { | ||||
|     private string _apiBaseUrl; | ||||
|  | ||||
|     public AccountController() | ||||
|         : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()))) { | ||||
|         _apiBaseUrl = Environment.GetEnvironmentVariable("FabApprovalApiBaseUrl") ?? | ||||
|             throw new ArgumentNullException("FabApprovalApiBaseUrl environment variable not found"); | ||||
|     } | ||||
|  | ||||
|     public AccountController(UserManager<ApplicationUser> userManager) { | ||||
| @ -69,7 +66,7 @@ public class AccountController : Controller { | ||||
|             bool isLoginValid; | ||||
|  | ||||
|             HttpClient httpClient = HttpClientFactory.Create(); | ||||
|             httpClient.BaseAddress = new Uri(_apiBaseUrl); | ||||
|             httpClient.BaseAddress = new Uri(GlobalVars.AppSettings.ApiBaseUrl); | ||||
|  | ||||
|             LoginResult loginResult = await AccountDMO.LoginAsync(httpClient, model); | ||||
|  | ||||
| @ -121,7 +118,7 @@ public class AccountController : Controller { | ||||
|             bool isLoginValid; | ||||
|  | ||||
|             HttpClient httpClient = HttpClientFactory.Create(); | ||||
|             httpClient.BaseAddress = new Uri(_apiBaseUrl); | ||||
|             httpClient.BaseAddress = new Uri(GlobalVars.AppSettings.ApiBaseUrl); | ||||
|  | ||||
|             LoginResult loginResult = await AccountDMO.ExternalAuthSetupAsync(httpClient, authAttempt); | ||||
|  | ||||
|  | ||||
| @ -58,6 +58,7 @@ public class AuditController : Controller { | ||||
|         try { | ||||
|             bool isAdmin = (bool)Session[GlobalVars.IS_ADMIN]; | ||||
|             int userId = (int)Session[GlobalVars.SESSION_USERID]; | ||||
|             audit = auditDMO.GetAuditItem(issueID, userId); | ||||
|             AuditEdit auditEdit = auditDMO.GetAuditEdit(issueID, audit, isAdmin, userId); | ||||
|             if (auditEdit.RedirectToAction) | ||||
|                 return RedirectToAction("ReadOnlyAudit", new { auditNo = audit.AuditNo }); | ||||
|  | ||||
| @ -48,60 +48,23 @@ public class ChangeControlController : Controller { | ||||
|     } | ||||
|  | ||||
|     public ActionResult Edit(int issueID) { | ||||
|         int isITARCompliant = 1; | ||||
|         ChangeControlViewModel cc = new ChangeControlViewModel(); | ||||
|         cc = ccDMO.GetChangeControlRead(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]); | ||||
|         string jwt = Session["JWT"].ToString(); | ||||
|         string encodedJwt = System.Net.WebUtility.UrlEncode(jwt); | ||||
|         string refreshToken = Session["RefreshToken"].ToString(); | ||||
|         string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); | ||||
|         string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=pcrb/{issueID}"; | ||||
|  | ||||
|         List<ApproversListViewModel> userList = MiscDMO.GetApproversListByDocument(cc.PlanNumber, cc.CurrentStep, (int)GlobalVars.DocumentType.ChangeControl); | ||||
|         ApproversListViewModel appUser = userList.Find(delegate (ApproversListViewModel al) { return al.UserID == (int)Session[GlobalVars.SESSION_USERID]; }); | ||||
|         if (appUser != null) { | ||||
|             ViewBag.IsApprover = "true"; | ||||
|         } | ||||
|         // TODO locked functionality | ||||
|  | ||||
|         if (isITARCompliant == 0) // not ITAR Compliant | ||||
|         { | ||||
|             return View("UnAuthorizedAccess"); | ||||
|         } else { | ||||
|             if ((int)Session[GlobalVars.SESSION_USERID] == cc.OwnerID) | ||||
|                 ViewBag.IsOriginator = "true"; | ||||
|             else | ||||
|                 ViewBag.IsOriginator = "false"; | ||||
|  | ||||
|             if ((cc.RecordLockIndicator && cc.RecordLockedBy != (int)Session[GlobalVars.SESSION_USERID]) || | ||||
|                 cc.ClosedDate != null) { | ||||
|                 return RedirectToAction("ReadOnlyCC", new { issueID = issueID }); | ||||
|             } else { | ||||
|                 cc = ccDMO.GetChangeControl(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]); | ||||
|                 ViewBag.Attendees = ccDMO.GetUsers(); | ||||
|                 ViewBag.Generations = ccDMO.GetGenerations(); | ||||
|                 ViewBag.PartNumbers = ccDMO.GetPartNumbers(); | ||||
|                 ViewBag.Processes = ccDMO.GetProcesses(); | ||||
|                 ViewBag.Logistics = ccDMO.GetLogistics(); | ||||
|                 ViewBag.AIResponsibles = ccDMO.GetActionItemResponsible(); | ||||
|                 ViewBag.Sites = ccDMO.GetSites(); | ||||
|                 return View(cc); | ||||
|             } | ||||
|         } | ||||
|         return Redirect(mrbUrl); | ||||
|     } | ||||
|  | ||||
|     public ActionResult ReadOnlyCC(int issueID) { | ||||
|         int isITARCompliant = 1; | ||||
|         ChangeControlViewModel cc = new ChangeControlViewModel(); | ||||
|         cc = ccDMO.GetChangeControlRead(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]); | ||||
|         // TODO locked functionality | ||||
|         string jwt = Session["JWT"].ToString(); | ||||
|         string encodedJwt = System.Net.WebUtility.UrlEncode(jwt); | ||||
|         string refreshToken = Session["RefreshToken"].ToString(); | ||||
|         string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); | ||||
|         string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=pcrb/{issueID}"; | ||||
|  | ||||
|         if (isITARCompliant == 0) // not ITAR Compliant | ||||
|         { | ||||
|             return View("UnAuthorizedAccess"); | ||||
|         } else { | ||||
|             ViewBag.MeetingList = ccDMO.GetMeetingList(issueID); | ||||
|             ViewBag.Generations = ccDMO.GetGenerations(); | ||||
|             ViewBag.PartNumbers = ccDMO.GetPartNumbers(); | ||||
|             ViewBag.Processes = ccDMO.GetProcesses(); | ||||
|             ViewBag.Logistics = ccDMO.GetLogistics(); | ||||
|             return View(cc); | ||||
|         } | ||||
|         return Redirect(mrbUrl); | ||||
|     } | ||||
|  | ||||
|     [HttpPost] | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Configuration; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Web; | ||||
| using System.Web.Mvc; | ||||
| @ -21,7 +22,7 @@ namespace Fab2ApprovalSystem.Controllers; | ||||
| [Authorize] | ||||
| [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")] | ||||
| [SessionExpireFilter] | ||||
| public class ECNController : PdfViewController { | ||||
| public class ECNController : Controller { | ||||
|  | ||||
|     private const string ECN_PREFIX = "ECN_"; | ||||
|     private const string TECN_PREFIX = "TECN_"; | ||||
| @ -601,7 +602,7 @@ public class ECNController : PdfViewController { | ||||
|         try { | ||||
|             string emailSentList = ""; | ||||
|             ECN ecn = ecnDMO.GetECN(ecnNumber); | ||||
|                 emailSentList = ECNHelper.NotifySubmitter(_AppSettings, ecnNumber, ecnTypeString, ecn); | ||||
|             emailSentList = ECNHelper.NotifySubmitter(_AppSettings, ecnNumber, ecnTypeString, ecn); | ||||
|             try { | ||||
|                 EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + ":" + emailSentList }); | ||||
|             } catch { } | ||||
| @ -625,7 +626,7 @@ public class ECNController : PdfViewController { | ||||
|             ECN ecn = ecnDMO.GetECN(ecnNumber); | ||||
|             IEnumerable<int> ecnAdminIDs = MiscDMO.GetUserIDsBySubRoleID(383); | ||||
|             foreach (int id in ecnAdminIDs) { | ||||
|                         emailSentList = ECNHelper.NotifyAdmin(_AppSettings, ecnNumber, ecnTypeString, ecn, id); | ||||
|                 emailSentList = ECNHelper.NotifyAdmin(_AppSettings, ecnNumber, ecnTypeString, ecn, id); | ||||
|                 try { | ||||
|                     EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + ":" + emailSentList }); | ||||
|                 } catch { } | ||||
| @ -650,7 +651,7 @@ public class ECNController : PdfViewController { | ||||
|             string emailSentList = ""; | ||||
|             ECN ecn = ecnDMO.GetECN(ecnNumber); | ||||
|             List<string> emailIst = MiscDMO.GetApproverEmailListByDocument(@ecnNumber, currentStep, documentType).Distinct().ToList(); | ||||
|                 emailSentList = ECNHelper.NotifyApprovers(_AppSettings, ecnNumber, ecnTypeString, emailSentList, ecn, emailIst); | ||||
|             emailSentList = ECNHelper.NotifyApprovers(_AppSettings, ecnNumber, ecnTypeString, emailSentList, ecn, emailIst); | ||||
|             try { | ||||
|                 EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + currentStep.ToString() + ":" + emailSentList }); | ||||
|             } catch { } | ||||
| @ -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) { | ||||
|         int isITARCompliant = 0; | ||||
|         ECN ecn = new ECN(); | ||||
| @ -883,6 +881,8 @@ public class ECNController : PdfViewController { | ||||
|  | ||||
|             string outputFileName = ""; | ||||
|             ecn = ecnDMO.GetECNPdf(ecnNumber); | ||||
|             ViewBag.Category = ecnDMO.GetCategoryID(ecn); | ||||
|             ViewBag.TrainingNotificationTo = ecnDMO.GetTrainingNotificationTo(ecn, trainingDMO); | ||||
|             outputFileName = ecnNumber.ToString() + ".pdf"; | ||||
|  | ||||
|             string ecnFolderPath = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString(); | ||||
| @ -891,10 +891,12 @@ public class ECNController : PdfViewController { | ||||
|             if (!di.Exists) | ||||
|                 di.Create(); | ||||
|  | ||||
|             // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This | ||||
|             // requires the controller to be inherited from MyController instead of MVC's Controller. | ||||
|             SavePdf(ecnFolderPath + "\\ECNForm_" + outputFileName, "ECNPdf", ecn); | ||||
|             SavePdf(ecnFolderPath + "\\ECNApprovalLog_" + outputFileName, "ECNApprovalPdf", ecn); | ||||
|             string htmlText; | ||||
|             string pageTitle = string.Empty; | ||||
|             htmlText = RenderViewToString("ECNPdf", ecn); | ||||
|             StandardPdfRenderer.WritePortableDocumentFormatToFile(pageTitle, htmlText, $"{ecnFolderPath}\\ECNForm_{outputFileName}"); | ||||
|             htmlText = RenderViewToString("ECNApprovalPdf", ecn); | ||||
|             StandardPdfRenderer.WritePortableDocumentFormatToFile(pageTitle, htmlText, $"{ecnFolderPath}\\ECNApprovalLog_{outputFileName}"); | ||||
|         } catch (Exception ex) { | ||||
|             EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Generate PDF", Comments = ex.Message }); | ||||
|             ecn = null; | ||||
| @ -904,12 +906,32 @@ public class ECNController : PdfViewController { | ||||
|         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) { | ||||
|         ECNPdf ecn = new ECNPdf(); | ||||
|         try { | ||||
|             string outputFileName = ""; | ||||
|  | ||||
|             ecn = ecnDMO.GetECNPdf(ecnNumber); | ||||
|             ViewBag.Category = ecnDMO.GetCategoryID(ecn); | ||||
|             ViewBag.TrainingNotificationTo = ecnDMO.GetTrainingNotificationTo(ecn, trainingDMO); | ||||
|             outputFileName = ecnNumber.ToString() + ".pdf"; | ||||
|  | ||||
|             string ecnFolderPath = _AppSettings.AttachmentFolder + "ECN\\" + folderName.ToString(); | ||||
| @ -919,9 +941,9 @@ public class ECNController : PdfViewController { | ||||
|             if (!di.Exists) | ||||
|                 di.Create(); | ||||
|  | ||||
|             // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This | ||||
|             // requires the controller to be inherited from MyController instead of MVC's Controller. | ||||
|             SavePdf(ecnFolderPath + "\\ECNForm_" + outputFileName, "ECNPdf", ecn); | ||||
|             string pageTitle = string.Empty; | ||||
|             string htmlText = RenderViewToString("ECNPdf", ecn); | ||||
|             StandardPdfRenderer.WritePortableDocumentFormatToFile(pageTitle, htmlText, $"{ecnFolderPath}\\ECNForm_{outputFileName}"); | ||||
|         } catch (Exception ex) { | ||||
|             EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Generate PDF", Comments = ex.Message }); | ||||
|             ecn = null; | ||||
| @ -935,13 +957,20 @@ public class ECNController : PdfViewController { | ||||
|         ECNPdf ecn; | ||||
|         try { | ||||
|             ecn = ecnDMO.GetECNPdf(ecnNumber); | ||||
|             // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This | ||||
|             // requires the controller to be inherited from MyController instead of MVC's Controller. | ||||
|             return this.ViewPdf("", "ECNPdf", ecn); | ||||
|             ViewBag.Category = ecnDMO.GetCategoryID(ecn); | ||||
|             ViewBag.TrainingNotificationTo = ecnDMO.GetTrainingNotificationTo(ecn, trainingDMO); | ||||
|             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) { | ||||
|             EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Print PDF", Comments = ex.Message }); | ||||
|             ecn = null; | ||||
|             return Content(""); | ||||
|             return Content("An unexpected error has occurred!"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -953,8 +982,7 @@ public class ECNController : PdfViewController { | ||||
|         } catch { } | ||||
|     } | ||||
|  | ||||
|     public void NotifyApproversForCancellation(int ecnNumber, byte currentStep, int documentType, string ecnTypeString) { | ||||
|         ECN ecn = ecnDMO.GetECN(ecnNumber); | ||||
|     public void NotifyApproversForCancellation(int ecnNumber, ECN ecn, byte currentStep, int documentType, string ecnTypeString) { | ||||
|         string emailSentList = ECNHelper.NotifyApproversForCancellation(_AppSettings, ecnNumber, currentStep, documentType, ecnTypeString, ecn); | ||||
|         try { | ||||
|             EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + currentStep.ToString() + ":" + emailSentList }); | ||||
| @ -977,10 +1005,10 @@ public class ECNController : PdfViewController { | ||||
|         } catch { } | ||||
|     } | ||||
|  | ||||
|     public void NotifyTECNCancellation(int ecnNumber, string ecnFolderPath) { | ||||
|     public void NotifyTECNCancellation(int ecnNumber, string ecnFolderPath, string comments) { | ||||
|         ECN ecn = ecnDMO.GetECN(ecnNumber); | ||||
|         List<int> notificationUserList = ecnDMO.GetTECNNotificationUsers().ToList(); | ||||
|         string emailSentList = ECNHelper.NotifyTECNCancellation(_AppSettings, userDMO, ecnNumber, ecnFolderPath, ecn, notificationUserList); | ||||
|         string emailSentList = ECNHelper.NotifyTECNCancellation(_AppSettings, userDMO, ecnNumber, ecnFolderPath, comments, ecn, notificationUserList); | ||||
|         try { | ||||
|             EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "E-TECN", OperationType = "Email", Comments = "Approvers for Cancellation :" + emailSentList }); | ||||
|         } catch { } | ||||
| @ -1157,22 +1185,24 @@ public class ECNController : PdfViewController { | ||||
|         return Content(ecnDMO.PCRBExists(pcrb).ToString()); | ||||
|     } | ||||
|  | ||||
|     public ActionResult CancelDocument(int ecnNumber, byte currentStep, int documentType, string ecnTypeString) { | ||||
|     public ActionResult CancelDocument(int ecnNumber, byte currentStep, int documentType, string ecnTypeString, string comments = "") { | ||||
|         ECN ecn = ecnDMO.GetECN(ecnNumber); | ||||
|         bool lastApproverAndLastStep = false; | ||||
|         if (ecn.SubmitedDate is not null && currentStep >= 1) | ||||
|             wfDMO.Approve(_AppSettings, ecnNumber, currentStep, comments, out bool lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType, ecn.WorkFlowNumber); | ||||
|         int appoverCount = ecnDMO.SubmitForCancellation(ecnNumber, (byte)GlobalVars.WorkFLowStepNumber.Step1, (int)Session[GlobalVars.SESSION_USERID], documentType, ecnTypeString, (int)GlobalVars.TECNExpirationCancellation.Cancellation); | ||||
|         if (appoverCount > 0) { | ||||
|             NotifyApproversForCancellation(ecnNumber, currentStep, documentType, ecnTypeString); | ||||
|         } else // TODO Automatically close the | ||||
|           { | ||||
|             lastApproverAndLastStep = ApproveCancellation(ecnNumber, currentStep, "", documentType, ecnTypeString); | ||||
|             NotifyApproversForCancellation(ecnNumber, ecn, currentStep, documentType, ecnTypeString); | ||||
|         } else { // TODO Automatically close the | ||||
|             lastApproverAndLastStep = ApproveCancellation(ecnNumber, currentStep, comments, documentType, ecnTypeString); | ||||
|         } | ||||
|  | ||||
|         if (!lastApproverAndLastStep) { | ||||
|             try { | ||||
|                 lastApproverAndLastStep = true; | ||||
|  | ||||
|                 ECNPdf ecn = new ECNPdf(); | ||||
|                 GenerateECNPdf(ecnNumber, out ecn); | ||||
|                 ECNPdf ecnPDF = new ECNPdf(); | ||||
|                 GenerateECNPdf(ecnNumber, out ecnPDF); | ||||
|  | ||||
|                 string sourceDirectory = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString() + "\\"; | ||||
|                 string outputFullFilePath = ""; | ||||
| @ -1184,7 +1214,7 @@ public class ECNController : PdfViewController { | ||||
|  | ||||
|                 Zipper zip = new Zipper(); | ||||
|                 zip.CreateZip(outputFullFilePath, sourceDirectory); | ||||
|                 NotifyTECNCancellation(ecnNumber, outputFullFilePath); | ||||
|                 NotifyTECNCancellation(ecnNumber, outputFullFilePath, comments); | ||||
|  | ||||
|             } catch (Exception ex) { | ||||
|                 EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "TECN", OperationType = "Error", Comments = ex.Message }); | ||||
| @ -1208,19 +1238,26 @@ public class ECNController : PdfViewController { | ||||
|     public bool ApproveCancellation(int ecnNumber, byte currentStep, string comments, int documentType, string ecnTypeString) { | ||||
|         bool lastApproverAndLastStep = false; | ||||
|         bool lastStep = false; | ||||
|         ECN ecn = ecnDMO.GetECN(ecnNumber); | ||||
|         bool lastApprover = ecnDMO.ECNApproveCancelled_ExpiredDocument(ecnNumber, currentStep, comments, out lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType); | ||||
|         while (lastApprover && !lastStep) { | ||||
|             currentStep++; | ||||
|             lastApprover = ecnDMO.ECNApproveCancelled_ExpiredDocument(ecnNumber, currentStep, comments, out lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType); | ||||
|             NotifyApproversForCancellation(ecnNumber, currentStep, documentType, ecnTypeString); | ||||
|             NotifyApproversForCancellation(ecnNumber, ecn, currentStep, documentType, ecnTypeString); | ||||
|         } | ||||
|  | ||||
|         if (lastApprover && lastStep) { | ||||
|             try { | ||||
|                 lastApproverAndLastStep = true; | ||||
|  | ||||
|                 ECNPdf ecn = new ECNPdf(); | ||||
|                 GenerateECNPdf(ecnNumber, out ecn); | ||||
|                 ecn.CancellationDate = DateTime.Now; | ||||
|                 ecn.CancellationApprovalDate = DateTime.Now; | ||||
|                 ecn.CancellationApproved = true; | ||||
|                 ecn.Cancelled = true; | ||||
|                 ecnDMO.UpdateECN(ecn); | ||||
|  | ||||
|                 ECNPdf ecnPDF = new ECNPdf(); | ||||
|                 GenerateECNPdf(ecnNumber, out ecnPDF); | ||||
|  | ||||
|                 string sourceDirectory = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString() + "\\"; | ||||
|                 string outputFullFilePath = ""; | ||||
| @ -1232,7 +1269,7 @@ public class ECNController : PdfViewController { | ||||
|  | ||||
|                 Zipper zip = new Zipper(); | ||||
|                 zip.CreateZip(outputFullFilePath, sourceDirectory); | ||||
|                 NotifyTECNCancellation(ecnNumber, outputFullFilePath); | ||||
|                 NotifyTECNCancellation(ecnNumber, outputFullFilePath, comments); | ||||
|  | ||||
|             } catch (Exception ex) { | ||||
|                 EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "TECN", OperationType = "Error", Comments = ex.Message }); | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Configuration; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Threading; | ||||
| using System.Web; | ||||
| @ -20,7 +21,7 @@ namespace Fab2ApprovalSystem.Controllers; | ||||
| [Authorize] | ||||
| [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")] | ||||
| [SessionExpireFilter] | ||||
| public class LotTravelerController : PdfViewController { | ||||
| public class LotTravelerController : Controller { | ||||
|  | ||||
|     LotTravelerDMO LotTravDMO = new LotTravelerDMO(); | ||||
|     string docTypeString = "LotTraveler"; | ||||
| @ -199,9 +200,14 @@ public class LotTravelerController : PdfViewController { | ||||
|         try { | ||||
|             workRequest = LotTravDMO.GetLTWorkRequestItemPDF(workRequestID); | ||||
|  | ||||
|             // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This | ||||
|             // requires the controller to be inherited from MyController instead of MVC's Controller. | ||||
|             return this.ViewPdf("", "WorkRequestPDF", workRequest); | ||||
|             string pageTitle = string.Empty; | ||||
|             string htmlText = RenderViewToString("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) { | ||||
|             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 }); | ||||
| @ -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) { | ||||
|         int isITARCompliant = 1; | ||||
|         LTWorkRequest workRequest = new LTWorkRequest(); | ||||
| @ -251,9 +275,7 @@ public class LotTravelerController : PdfViewController { | ||||
|  | ||||
|         return Content("Successfully Saved"); | ||||
|     } | ||||
|     /// <summary> | ||||
|     ///  | ||||
|     /// </summary> | ||||
|  | ||||
|     public JsonResult GetBaseFlowLocations(string baseFlow) { | ||||
|         List<BaseFlowLocation> loclist = LotTravDMO.GetBaseFlowLocations(baseFlow); | ||||
|         return Json(loclist, JsonRequestBehavior.AllowGet); | ||||
| @ -332,9 +354,6 @@ public class LotTravelerController : PdfViewController { | ||||
|         return Content(newWorkRequestID.ToString()); | ||||
|     } | ||||
|  | ||||
|     /// <summary> | ||||
|     /// For the Revison | ||||
|     /// </summary> | ||||
|     public ActionResult UpdateMaterialDetailRevision(LTWorkRequest model) { | ||||
|         var modelMaterialDetail = model.LTMaterial; | ||||
|         int previousMaterialID = model.LTMaterial.ID; | ||||
| @ -1232,15 +1251,19 @@ public class LotTravelerController : PdfViewController { | ||||
|         LotTravDMO.DeleteLot(ltLotID); | ||||
|     } | ||||
|  | ||||
|     /// | ||||
|     public ActionResult DisplayLotTravlerPdf(int ltLotID, int revisionNumber) { | ||||
|         LotTravelerPdf traveler = new LotTravelerPdf(); | ||||
|         try { | ||||
|             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 | ||||
|             // requires the controller to be inherited from MyController instead of MVC's Controller. | ||||
|             return this.ViewPdf("", "LotTravelerPDF", traveler); | ||||
|             string pageTitle = string.Empty; | ||||
|             string htmlText = RenderViewToString("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) { | ||||
|             EventLogDMO.Add(new WinEventLog() { IssueID = traveler.SWRNumber, UserID = @User.Identity.Name, DocumentType = "LotTraveler", OperationType = "Generate PDF", Comments = ex.Message }); | ||||
|             traveler = null; | ||||
|  | ||||
| @ -79,9 +79,7 @@ public class MRBController : Controller { | ||||
|         string encodedJwt = System.Net.WebUtility.UrlEncode(jwt); | ||||
|         string refreshToken = Session["RefreshToken"].ToString(); | ||||
|         string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); | ||||
|         string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? | ||||
|             "https://localhost:7255"; | ||||
|         string mrbUrl = $"{wasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=/mrb/{issueID}"; | ||||
|         string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=mrb/{issueID}"; | ||||
|  | ||||
|         return Redirect(mrbUrl); | ||||
|     } | ||||
| @ -104,9 +102,7 @@ public class MRBController : Controller { | ||||
|         string encodedJwt = System.Net.WebUtility.UrlEncode(jwt); | ||||
|         string refreshToken = Session["RefreshToken"].ToString(); | ||||
|         string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); | ||||
|         string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? | ||||
|             "https://localhost:7255"; | ||||
|         string mrbUrl = $"{wasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=/mrb/{issueID}"; | ||||
|         string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=mrb/{issueID}"; | ||||
|  | ||||
|         return Redirect(mrbUrl); | ||||
|     } | ||||
|  | ||||
							
								
								
									
										20
									
								
								Fab2ApprovalSystem/Controllers/PCRBController.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Fab2ApprovalSystem/Controllers/PCRBController.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| using System; | ||||
| using System.Web.Mvc; | ||||
|  | ||||
| using Fab2ApprovalSystem.Misc; | ||||
|  | ||||
| namespace Fab2ApprovalSystem.Controllers; | ||||
|  | ||||
| [Authorize] | ||||
| [SessionExpireFilter] | ||||
| public class PCRBController : Controller { | ||||
|     public ActionResult Edit(int issueID) { | ||||
|         string jwt = Session["JWT"].ToString(); | ||||
|         string encodedJwt = System.Net.WebUtility.UrlEncode(jwt); | ||||
|         string refreshToken = Session["RefreshToken"].ToString(); | ||||
|         string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); | ||||
|         string mrbUrl = $"{GlobalVars.AppSettings.WasmClientUrl}/redirect?jwt={encodedJwt}&refreshToken={encodedRefreshToken}&redirectPath=/pcrb/{issueID}"; | ||||
|  | ||||
|         return Redirect(mrbUrl); | ||||
|     } | ||||
| } | ||||
| @ -37,7 +37,7 @@ public class AdminDMO { | ||||
|             foreach (SubRole sr in r.SubRoles) { | ||||
|                 if (sr.Inactive) { | ||||
|                     // hide inactive roles unless parameter says otherwise | ||||
|                     if (showInactiveRoles.Equals("true") == false) | ||||
|                     if (!showInactiveRoles.Equals("true")) | ||||
|                         continue; | ||||
|                 } | ||||
|  | ||||
|  | ||||
| @ -401,7 +401,6 @@ public class AuditDMO { | ||||
|             result.Is8DQA = "true"; | ||||
|         } | ||||
|  | ||||
|         audit = GetAuditItem(issueID, userId); | ||||
|         // transform audit users from string to list, delimited by a comma. | ||||
|         if (audit.Auditees == null) { | ||||
|             result.AuditeeNames = new List<string>(); | ||||
| @ -414,7 +413,7 @@ public class AuditDMO { | ||||
|         if (audit.OriginatorID == userId) { | ||||
|             result.IsSubmitter = true; | ||||
|         } | ||||
|         if (isAdmin != true) { | ||||
|         if (!isAdmin) { | ||||
|             result.IsAdmin = false; | ||||
|         } else { | ||||
|             result.IsAdmin = true; | ||||
| @ -424,7 +423,7 @@ public class AuditDMO { | ||||
|         { | ||||
|             result.RedirectToAction = true; | ||||
|         } | ||||
|         if (result.IsAdmin == false && result.IsSubmitter == false) { | ||||
|         if (!result.IsAdmin && !result.IsSubmitter) { | ||||
|             result.RedirectToAction = true; | ||||
|         } else { | ||||
|             result.UserList = GetUserList(); | ||||
|  | ||||
| @ -90,6 +90,7 @@ public class CorrectiveActionDMO { | ||||
|                 parameters.Add("@EscapePoint", model.EscapePoint); | ||||
|                 parameters.Add("@FollowUpDate", model.FollowUpDate); | ||||
|                 parameters.Add("@CASubmitted", model.CASubmitted); | ||||
|                 parameters.Add("@CAStandardType", model.CAStandardType); | ||||
|  | ||||
|                 db.Execute("_8DUpdateCorrectiveAction", parameters, commandType: CommandType.StoredProcedure); | ||||
|                 EventLogDMO.Add(new WinEventLog { UserID = "System", Comments = "Saved Corrective Action", DocumentType = "9", IssueID = model.CANo, OperationType = "Status", SysDocumentID = 1 }); | ||||
| @ -323,7 +324,7 @@ public class CorrectiveActionDMO { | ||||
|         bool isAssignee = false; | ||||
|         int aiIndex = 0; | ||||
|         List<D5D6CorrectivetAction> actionItems = GetD5D6CorrectivetActions(caId).ToList(); | ||||
|         while (isAssignee == false && aiIndex < actionItems.Count) { | ||||
|         while (!isAssignee && aiIndex < actionItems.Count) { | ||||
|             D5D6CorrectivetAction actionItem = actionItems[aiIndex]; | ||||
|             if (actionItem.ResponsibilityOwnerID == userId && actionItem.ImplementedDate == null && actionItem.Approved) { | ||||
|                 isAssignee = true; | ||||
|  | ||||
| @ -15,6 +15,7 @@ using Fab2ApprovalSystem.ViewModels; | ||||
| namespace Fab2ApprovalSystem.DMO; | ||||
|  | ||||
| public class ECN_DMO { | ||||
|  | ||||
|     private readonly IDbConnection db = new SqlConnection(GlobalVars.DB_CONNECTION_STRING); | ||||
|     private readonly WorkflowDMO wfDMO = new(); | ||||
|  | ||||
| @ -41,6 +42,9 @@ public class ECN_DMO { | ||||
|             parameters.Add("@ExpirationDate", ecn.ExpirationDate); | ||||
|             parameters.Add("@ExtensionDate", ecn.ExtensionDate); | ||||
|             parameters.Add("@CancellationDate", ecn.CancellationDate); | ||||
|             parameters.Add("@CancellationApprovalDate", ecn.CancellationApprovalDate); | ||||
|             parameters.Add("@CancellationApproved", ecn.CancellationApproved); | ||||
|             parameters.Add("@Cancelled", ecn.Cancelled); | ||||
|             parameters.Add("@AcknowledgementRequired", ecn.AcknowledgementRequired); | ||||
|             parameters.Add("@TrainingRequired", ecn.TrainingRequired); | ||||
|             parameters.Add("@AreaID", ecn.AreaID); | ||||
| @ -352,14 +356,17 @@ public class ECN_DMO { | ||||
|             List<string> affectedAreas = multipleResultItems.Read<string>().ToList(); | ||||
|             List<string> affectedTechnologies = multipleResultItems.Read<string>().ToList(); | ||||
|             List<string> acknowledgementBy = multipleResultItems.Read<string>().ToList(); | ||||
|             List<string> trainingBy = multipleResultItems.Read<string>().ToList(); | ||||
|             List<int> trainingby = multipleResultItems.Read<int>().ToList(); | ||||
|             if (ecnItem != null && trainingby != null) { | ||||
|                 if (trainingby.Count > 0) | ||||
|                     ecnItem.TrainingByIDs.AddRange(trainingby); | ||||
|             } | ||||
|             List<string> productfamilies = multipleResultItems.Read<string>().ToList(); | ||||
|  | ||||
|             ecnItem.AffectedModules = string.Join(", ", modules); | ||||
|             ecnItem.AffectedDepartments = string.Join(", ", departments); | ||||
|             ecnItem.AffectedAreas = string.Join(",", affectedAreas); | ||||
|             ecnItem.AffectedTechnologies = string.Join(",", affectedTechnologies); | ||||
|             ecnItem.TrainingBy = string.Join(",", trainingBy); | ||||
|             ecnItem.AcknowledgementBy = string.Join(",", acknowledgementBy); | ||||
|             ecnItem.AffectedProductFamilies = string.Join(",", productfamilies); | ||||
|  | ||||
| @ -367,7 +374,7 @@ public class ECN_DMO { | ||||
|         return ecnItem; | ||||
|     } | ||||
|  | ||||
|     internal ECN GetECN(int ecnNumber) { | ||||
|     public ECN GetECN(int ecnNumber) { | ||||
|         ECN ecnItem = new(); | ||||
|         DynamicParameters parameters = new(); | ||||
|         parameters.Add("@ECNNumber", value: ecnNumber); | ||||
| @ -389,7 +396,7 @@ public class ECN_DMO { | ||||
|  | ||||
|     internal List<ECNCategory> GetCategories() { | ||||
|         List<ECNCategory> r = db.Query<ECNCategory>("ECNGetCategories", null, commandType: CommandType.StoredProcedure).ToList(); | ||||
|         return r; | ||||
|         return r.OrderBy(l => l.CategoryName).ToList(); | ||||
|     } | ||||
|  | ||||
|     internal List<ECNArea> GetECNAreas() { | ||||
| @ -710,4 +717,26 @@ public class ECN_DMO { | ||||
|         return r; | ||||
|     } | ||||
|  | ||||
|     internal string GetCategoryID(ECNPdf ecn) { | ||||
|         string result; | ||||
|         if (ecn.CategoryID is null) { | ||||
|             result = string.Empty; | ||||
|         } else { | ||||
|             List<ECNCategory> categories = GetCategories(); | ||||
|             result = (from l in categories where l.CategoryID == ecn.CategoryID.Value select l.CategoryName).FirstOrDefault(); | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     internal string GetTrainingNotificationTo(ECNPdf ecn, TrainingDMO trainingDMO) { | ||||
|         string result; | ||||
|         if (ecn.TrainingByIDs is null) { | ||||
|             result = string.Empty; | ||||
|         } else { | ||||
|             List<TrainingGroup> trainingGroups = trainingDMO.GetTrainingGroups(); | ||||
|             result = string.Join(", ", (from l in trainingGroups where ecn.TrainingByIDs.Contains(l.TrainingGroupID) select l.TrainingGroupName).ToArray()); | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -266,9 +266,9 @@ public class MRB_DMO { | ||||
|         DateTime? issueStartDate = tempMRBInfo.IssueStartDate; | ||||
|         DateTime? issueEndDate = tempMRBInfo.IssueEndDate; | ||||
|  | ||||
|         if (issueStartDate.HasValue == false) | ||||
|         if (!issueStartDate.HasValue) | ||||
|             throw new Exception("MRB Issue Start Date cannot be blank"); | ||||
|         if (issueEndDate.HasValue == false) | ||||
|         if (!issueEndDate.HasValue) | ||||
|             throw new Exception("MRB Issue End Date cannot be blank"); | ||||
|  | ||||
|         MRB mrbData = new() { MRBNumber = mrbNumber, ToolCSV = tempMRBInfo.ToolCSV, IssueStartDate = tempMRBInfo.IssueStartDate, IssueEndDate = tempMRBInfo.IssueEndDate }; | ||||
|  | ||||
| @ -166,7 +166,7 @@ public class WorkflowDMO { | ||||
|             sqlString.Append("SELECT COUNT(*) FROM LotDisposition LD INNER JOIN Lot L  ON LD.IssueID = L.IssueID "); | ||||
|             sqlString.Append("WHERE (PERequired = 1 OR Location = 'QDB' OR Location = 'EDB' ) AND LD.IssueID = @IssueID "); | ||||
|             recordCount = db.Query<int>(sqlString.ToString(), new { IssueID = issueID }).Single(); | ||||
|             if ((recordCount > 0) && (allLotsAreScrap == false)) { | ||||
|             if ((recordCount > 0) && (!allLotsAreScrap)) { | ||||
|                 // check if there any IG Medical products | ||||
|                 if (recordCountForIG_MA > 0) { | ||||
|                     sqlString = new StringBuilder(); | ||||
|  | ||||
| @ -2,10 +2,12 @@ | ||||
| *****Please DO NOT reply to this email*****  | ||||
| <br/><br/> | ||||
| {3}# {0} has been Cancelled. Please remove posted TECN from point of use. The cancellation date is {4}  | ||||
| Please review the cancelled TECN form in the attachment. | ||||
| Please review comments below and ensure process has been returned to normal. | ||||
| <br/><br/> | ||||
| https://messa016ec.infineon.com/ECN/Edit?issueID={1} | ||||
| <br/><br/> | ||||
| Comments: {5} | ||||
| <br/><br/> | ||||
|  | ||||
| If you have any questions or trouble logging on please contact a site administrator. | ||||
| <br/><br/> | ||||
|  | ||||
							
								
								
									
										17
									
								
								Fab2ApprovalSystem/EmailTemplates/TECNReturnedToProcess.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Fab2ApprovalSystem/EmailTemplates/TECNReturnedToProcess.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | ||||
| <font size="2" face="verdana"> | ||||
| *****Please DO NOT reply to this email*****  | ||||
| <br/><br/> | ||||
| {3}# {0} has been returned to process. Please remove posted TECN from point of use. The returned to process date is {4}  | ||||
| Please review comments below and ensure process has been returned to normal. | ||||
| <br/><br/> | ||||
| https://messa016ec.infineon.com/ECN/Edit?issueID={1} | ||||
| <br/><br/> | ||||
| Comments: {5} | ||||
| <br/><br/> | ||||
|  | ||||
| If you have any questions or trouble logging on please contact a site administrator. | ||||
| <br/><br/> | ||||
| Thank you!  | ||||
|  | ||||
|  | ||||
| </font> | ||||
| @ -255,6 +255,7 @@ | ||||
|     <Compile Include="Controllers\TrainingController.cs" /> | ||||
|     <Compile Include="Controllers\WebAPIController.cs" /> | ||||
|     <Compile Include="Controllers\WorkflowController.cs" /> | ||||
|     <Compile Include="Controllers\PCRBController.cs" /> | ||||
|     <Compile Include="DMO\AccountDMO.cs" /> | ||||
|     <Compile Include="DMO\AdminDMO.cs" /> | ||||
|     <Compile Include="DMO\ApprovalLogDMO.cs" /> | ||||
| @ -324,9 +325,6 @@ | ||||
|     <Compile Include="Models\WinEventLogModel.cs" /> | ||||
|     <Compile Include="Models\WorkFlowModels.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\StandardPdfRenderer.cs" /> | ||||
|     <Compile Include="Properties\AssemblyInfo.cs" /> | ||||
| @ -387,8 +385,10 @@ | ||||
|     <Content Include="Views\CorrectiveAction\_D7PAAttachment.cshtml" /> | ||||
|     <Content Include="Views\CorrectiveAction\Edit.cshtml" /> | ||||
|     <Content Include="Views\CorrectiveAction\ReadOnlyCA.cshtml" /> | ||||
|     <Content Include="Views\ECN\_ECNCancel.cshtml" /> | ||||
|     <Content Include="Views\ECN\_ECNLayout.cshtml" /> | ||||
|     <Content Include="Views\ECN\_ECNReassignOriginator.cshtml" /> | ||||
|     <Content Include="Views\ECN\_ECNReturnToProcess.cshtml" /> | ||||
|     <Content Include="Views\ECN\Acknowledge.cshtml" /> | ||||
|     <Content Include="Views\ECN\ECNApprovalPdf.cshtml" /> | ||||
|     <Content Include="Views\ECN\ECNPdf.cshtml" /> | ||||
| @ -513,6 +513,7 @@ | ||||
|     <Content Include="EmailTemplates\TECNExpirationApproval.txt" /> | ||||
|     <Content Include="EmailTemplates\TECNExpired.txt" /> | ||||
|     <Content Include="EmailTemplates\TECNExtensionReject.txt" /> | ||||
|     <Content Include="EmailTemplates\TECNReturnedToProcess.txt" /> | ||||
|     <Content Include="EmailTemplates\WorkRequestApproval.txt" /> | ||||
|     <Content Include="EmailTemplates\WorkRequestAssigned.txt" /> | ||||
|     <Content Include="EmailTemplates\WorkRequestReAssigned.txt" /> | ||||
|  | ||||
| @ -126,7 +126,7 @@ public class ECNHelper { | ||||
|         return emailSentList; | ||||
|     } | ||||
|  | ||||
|     public static string NotifyTECNCancellation(AppSettings appSettings, UserAccountDMO userDMO, int ecnNumber, string ecnFolderPath, ECN ecn, List<int> notificationUserList) { | ||||
|     public static string NotifyTECNCancellation(AppSettings appSettings, UserAccountDMO userDMO, int ecnNumber, string ecnFolderPath, string comments, ECN ecn, List<int> notificationUserList) { | ||||
|         string emailSentList = ""; | ||||
|         List<string> emailIst = MiscDMO.GetTECNCancelledApprovalNotifyList(ecnNumber).Distinct().ToList(); | ||||
|         foreach (int userId in notificationUserList) { | ||||
| @ -135,23 +135,27 @@ public class ECNHelper { | ||||
|                 emailIst.Add(email); | ||||
|         } | ||||
|  | ||||
|         string subject = string.Empty; | ||||
|         string userEmail = string.Empty; | ||||
|         string emailTemplate = "TECNCancelled.txt"; | ||||
|         if (ecn.CancellationApprovalDate == null) { | ||||
|             subject = "TECN Cancellation Initiated  Notice - " + ecnNumber + " for " + ecn.Title + ", Cancellation Initiated on:" + DateTime.Now; | ||||
|         } else { | ||||
|             subject = "TECN Cancellation Approved Notice - " + ecnNumber + " for " + ecn.Title + ", Cancelled:" + ecn.CancellationApprovalDate; | ||||
|         } | ||||
|         string subject; | ||||
|         string emailTemplate; | ||||
|         string senderName = "ECN"; | ||||
|         string userEmail = string.Empty; | ||||
|         DateTime dateTime = ecn.CancellationApprovalDate is null ? DateTime.Now : ecn.CancellationApprovalDate.Value; | ||||
|         if (ecn.ExpirationDate > DateTime.Today || ecn.ExtensionDate > DateTime.Today) { | ||||
|             emailTemplate = "TECNCancelled.txt"; | ||||
|             subject = "TECN Cancellation Approved Notice - " + ecnNumber + " for " + ecn.Title + ", Cancelled:" + dateTime; | ||||
|         } else { | ||||
|             emailTemplate = "TECNReturnedToProcess.txt"; | ||||
|             subject = "TECN Return to Process Approved Notice - " + ecnNumber + " for " + ecn.Title + ", Returned:" + dateTime; | ||||
|         } | ||||
|  | ||||
|         EmailNotification en = new(appSettings, subject); | ||||
|         string[] emailparams = new string[5]; | ||||
|         string[] emailparams = new string[6]; | ||||
|         emailparams[0] = ecnNumber.ToString(); | ||||
|         emailparams[1] = ecnNumber.ToString(); | ||||
|         emailparams[2] = GlobalVars.hostURL; | ||||
|         emailparams[3] = "TECN"; | ||||
|         emailparams[4] = DateTime.Now.ToString(); | ||||
|         emailparams[5] = comments; | ||||
|  | ||||
| #if (DEBUG) | ||||
|         userEmail = GlobalVars.SENDER_EMAIL; | ||||
|  | ||||
| @ -1,104 +1,109 @@ | ||||
| #if !NET8 | ||||
| #if NET8 | ||||
|  | ||||
| using ExcelDataReader; | ||||
|  | ||||
| #else  | ||||
|  | ||||
| using Excel; | ||||
|  | ||||
| #endif | ||||
|  | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Data; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Web; | ||||
|  | ||||
| namespace Fab2ApprovalSystem.Misc { | ||||
| namespace Fab2ApprovalSystem.Misc; | ||||
|  | ||||
|     public class ExcelData { | ||||
|         string _path; | ||||
|         public ExcelData(string path) { | ||||
|             _path = path; | ||||
|         } | ||||
| public class ExcelData { | ||||
|  | ||||
|         public IExcelDataReader getExcelReader() { | ||||
|             // ExcelDataReader works with the binary Excel file, so it needs a FileStream | ||||
|             // to get started. This is how we avoid dependencies on ACE or Interop: | ||||
|  | ||||
|             FileStream stream = File.Open(_path, FileMode.Open, FileAccess.Read); | ||||
|             // We return the interface, so that  | ||||
|             IExcelDataReader reader = null; | ||||
|  | ||||
|             try { | ||||
|                 if (_path.EndsWith(".xls")) { | ||||
|                     reader = ExcelReaderFactory.CreateBinaryReader(stream); | ||||
|                 } | ||||
|                 if (_path.EndsWith(".xlsx")) { | ||||
|                     reader = ExcelReaderFactory.CreateOpenXmlReader(stream); | ||||
|                 } | ||||
|                 return reader; | ||||
|             } catch (Exception) { | ||||
|                 throw; | ||||
|             } | ||||
|  | ||||
|         } | ||||
|  | ||||
|         public class ExcelLotInfo { | ||||
|             public string LotNo { get; set; } | ||||
|             public string LotDispo { get; set; } | ||||
|         } | ||||
|  | ||||
|         public IEnumerable<ExcelLotInfo> ReadData() { | ||||
|             var r = new List<ExcelLotInfo>(); | ||||
|             var excelData = new ExcelData(_path); | ||||
|             var lots = excelData.getData().ToList(); | ||||
|  | ||||
|             int lotDispoColumnIndex = -1; | ||||
|             foreach (DataColumn col in lots[0].Table.Columns) { | ||||
|                 if (col.ColumnName.ToLower().Contains("dispo")) { | ||||
|                     lotDispoColumnIndex = col.Ordinal; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             foreach (var row in lots) { | ||||
|                 string temValue = row[0].ToString(); | ||||
|                 if (temValue.Trim().Length > 0 && temValue.Trim().Length <= 10) { | ||||
|                     r.Add(new ExcelLotInfo() { | ||||
|                         LotNo = row[0].ToString(), | ||||
|                         LotDispo = (lotDispoColumnIndex >= 0 ? row[lotDispoColumnIndex].ToString() : "") | ||||
|                     }); | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|             return r; | ||||
|         } | ||||
|  | ||||
|         public IEnumerable<string> ReadQDBFlagData() { | ||||
|             List<string> s = new List<string>(); | ||||
|             // We return the interface, so that          | ||||
|             var excelData = new ExcelData(_path); | ||||
|             var lotNos = excelData.getData(); | ||||
|             foreach (var row in lotNos) { | ||||
|                 string temValue = row[0].ToString(); | ||||
|                 if (temValue.Trim().Length > 0 && temValue.Trim().Length == 9) { | ||||
|                     if (row[2].ToString().ToUpper() != "YES" && row[2].ToString().ToUpper() != "NO") { | ||||
|                         throw new Exception("Invalid data in the file"); | ||||
|                     } else { | ||||
|                         s.Add(row[0].ToString() + "~" + row[1] + "~" + row[2]); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|             return s; | ||||
|         } | ||||
|  | ||||
|         public IEnumerable<DataRow> getData(bool firstRowIsColumnNames = true) { | ||||
|             var reader = this.getExcelReader(); | ||||
|             reader.IsFirstRowAsColumnNames = firstRowIsColumnNames; | ||||
|             var workSheet = reader.AsDataSet().Tables[0]; | ||||
|             var rows = from DataRow a in workSheet.Rows select a; | ||||
|             return rows; | ||||
|  | ||||
|         } | ||||
|     private readonly string _Path; | ||||
|  | ||||
|     public ExcelData(string path) { | ||||
|         _Path = path; | ||||
|     } | ||||
|  | ||||
|     public IExcelDataReader getExcelReader() { | ||||
|         FileStream stream = File.Open(_Path, FileMode.Open, FileAccess.Read); | ||||
|         IExcelDataReader reader = null; | ||||
|         try { | ||||
|             if (_Path.EndsWith(".xls")) { | ||||
|                 reader = ExcelReaderFactory.CreateBinaryReader(stream); | ||||
|             } | ||||
|             if (_Path.EndsWith(".xlsx")) { | ||||
|                 reader = ExcelReaderFactory.CreateOpenXmlReader(stream); | ||||
|             } | ||||
|             return reader; | ||||
|         } catch (Exception) { | ||||
|             throw; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public class ExcelLotInfo { | ||||
|         public string? LotNo { get; set; } | ||||
|         public string? LotDispo { get; set; } | ||||
|     } | ||||
|  | ||||
|     public IEnumerable<ExcelLotInfo> ReadData() { | ||||
|         List<ExcelLotInfo> r = new(); | ||||
|         ExcelData excelData = new(_Path); | ||||
|         List<DataRow> lots = excelData.getData().ToList(); | ||||
|  | ||||
|         int lotDispoColumnIndex = -1; | ||||
|         foreach (DataColumn col in lots[0].Table.Columns) { | ||||
|             if (col.ColumnName.ToLower().Contains("dispo")) { | ||||
|                 lotDispoColumnIndex = col.Ordinal; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         foreach (DataRow row in lots) { | ||||
|             string temValue = row[0].ToString(); | ||||
|             if (temValue.Trim().Length > 0 && temValue.Trim().Length <= 10) { | ||||
|                 r.Add(new ExcelLotInfo() { | ||||
|                     LotNo = row[0].ToString(), | ||||
|                     LotDispo = (lotDispoColumnIndex >= 0 ? row[lotDispoColumnIndex].ToString() : "") | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|         } | ||||
|         return r; | ||||
|     } | ||||
|  | ||||
|     public IEnumerable<string> ReadQDBFlagData() { | ||||
|         List<string> s = new(); | ||||
|         ExcelData excelData = new(_Path); | ||||
|         IEnumerable<DataRow> lotNos = excelData.getData(); | ||||
|         foreach (DataRow row in lotNos) { | ||||
|             string temValue = row[0].ToString(); | ||||
|             if (temValue.Trim().Length > 0 && temValue.Trim().Length == 9) { | ||||
|                 if (row[2].ToString().ToUpper() != "YES" && row[2].ToString().ToUpper() != "NO") { | ||||
|                     throw new Exception("Invalid data in the file"); | ||||
|                 } else { | ||||
|                     s.Add(row[0].ToString() + "~" + row[1] + "~" + row[2]); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         } | ||||
|         return s; | ||||
|     } | ||||
|  | ||||
| #if NET8 | ||||
|  | ||||
|     public IEnumerable<DataRow> getData(bool firstRowIsColumnNames = true) => | ||||
|         throw new NotImplementedException(); | ||||
|  | ||||
| #else | ||||
|  | ||||
|     public IEnumerable<DataRow> getData(bool firstRowIsColumnNames = true) { | ||||
|         IExcelDataReader reader = getExcelReader(); | ||||
|         reader.IsFirstRowAsColumnNames = firstRowIsColumnNames; | ||||
|         var workSheet = reader.AsDataSet().Tables[0]; | ||||
|         var rows = from DataRow a in workSheet.Rows select a; | ||||
|         return rows; | ||||
|     } | ||||
| } | ||||
|  | ||||
| #endif | ||||
|  | ||||
| } | ||||
| @ -117,8 +117,8 @@ public class LotDispositionHelper { | ||||
|     public static void AttachSave(AppSettings appSettings, LotDispositionDMO lotDispositionDMO, int issueID, int userId, string fullFileName, Stream stream) { | ||||
|         // Some browsers send file names with full path. | ||||
|         // We are only interested in the file name. | ||||
|         var fileName = Path.GetFileName(fullFileName); | ||||
|         var physicalPath = Path.Combine(appSettings.AttachmentFolder + "LotDisposition", fileName); | ||||
|         string fileName = Path.GetFileName(fullFileName); | ||||
|         string physicalPath = Path.Combine(appSettings.AttachmentFolder + "LotDisposition", fileName); | ||||
|  | ||||
|         using (FileStream fileStream = new(physicalPath, FileMode.Create, FileAccess.Write)) { | ||||
|             stream.CopyTo(fileStream); | ||||
| @ -134,7 +134,7 @@ public class LotDispositionHelper { | ||||
|     public static string ExcelLotOpen(LotDispositionDMO lotDispositionDMO, int issueID, string userIdentityName, string lotTempPipeLine, string fullFileName, Stream stream) { | ||||
|         string physicalPath; | ||||
|  | ||||
|         var fileExtension = Path.GetExtension(fullFileName); | ||||
|         string fileExtension = Path.GetExtension(fullFileName); | ||||
|         string fName = userIdentityName + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString(); | ||||
|  | ||||
|         physicalPath = Path.Combine(lotTempPipeLine, fName + "." + fileExtension); | ||||
| @ -142,20 +142,18 @@ public class LotDispositionHelper { | ||||
|             stream.CopyTo(fileStream); | ||||
|         } | ||||
|  | ||||
| #if !NET8 | ||||
|         ExcelData x = new ExcelData(physicalPath); | ||||
|         var lotNumbers = x.ReadData(); | ||||
|         ExcelData x = new (physicalPath); | ||||
|         IEnumerable<ExcelData.ExcelLotInfo> lotNumbers = x.ReadData(); | ||||
|  | ||||
|         foreach (var lotInfo in lotNumbers) { | ||||
|             Lot l = new Lot(); | ||||
|             l.LotNumber = lotInfo.LotNo; | ||||
|         foreach (ExcelData.ExcelLotInfo lotInfo in lotNumbers) { | ||||
|             Lot l = new(); | ||||
|             l.LotNumber = lotInfo.LotNo ?? string.Empty; | ||||
|             l.IssueID = issueID; | ||||
|             if (l.LotStatusOptionID == 0) | ||||
|                 l.LotStatusOption.LotStatusOptionID = (int)GlobalVars.LotStatusOption.Release; | ||||
|  | ||||
|             lotDispositionDMO.InsertLot(l, true); | ||||
|         } | ||||
| #endif | ||||
|  | ||||
|         FileInfo f = new(physicalPath); | ||||
|         if (f.Exists) | ||||
|  | ||||
| @ -46,14 +46,12 @@ public class MRBHelper { | ||||
|             stream.CopyTo(fileStream); | ||||
|         } | ||||
|  | ||||
| #if !NET8 | ||||
|         ExcelData x = new ExcelData(physicalPath); | ||||
|         ExcelData x = new(physicalPath); | ||||
|         lotDataList = x.ReadQDBFlagData(); | ||||
|  | ||||
|         foreach (string lotData in lotDataList) { | ||||
|             mrbDMO.InsertMRB_QDB_HoldFlag(guid, lotData, operation); | ||||
|         } | ||||
| #endif | ||||
|  | ||||
|         FileInfo f = new(physicalPath); | ||||
|         if (f.Exists) | ||||
| @ -170,14 +168,12 @@ public class MRBHelper { | ||||
|             stream.CopyTo(fileStream); | ||||
|         } | ||||
|  | ||||
| #if !NET8 | ||||
|         ExcelData x = new ExcelData(physicalPath); | ||||
|         ExcelData x = new(physicalPath); | ||||
|         lotDataList = x.ReadQDBFlagData(); | ||||
|  | ||||
|         foreach (string lotData in lotDataList) { | ||||
|             mrbDMO.InsertMRB_QDB_HoldFlag(guid, lotData, operation); | ||||
|         } | ||||
| #endif | ||||
|  | ||||
|         FileInfo f = new(physicalPath); | ||||
|         if (f.Exists) | ||||
| @ -246,17 +242,16 @@ public class MRBHelper { | ||||
|         string fName = userIdentityName + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString(); | ||||
|         string physicalPath = Path.Combine(lotTempPipeLine, fName + "." + fileExtension); | ||||
|  | ||||
| #if !NET8 | ||||
|         IEnumerable<ExcelData.ExcelLotInfo> lotNumbers; | ||||
|  | ||||
|         try { | ||||
|             using (var fileStream = new FileStream(physicalPath, FileMode.Create, FileAccess.Write)) { | ||||
|             using (FileStream fileStream = new(physicalPath, FileMode.Create, FileAccess.Write)) { | ||||
|                 stream.CopyTo(fileStream); | ||||
|             } | ||||
|             ExcelData x = new ExcelData(physicalPath); | ||||
|             ExcelData x = new(physicalPath); | ||||
|             lotNumbers = x.ReadData(); | ||||
|         } catch (Exception ex) { | ||||
|             throw new Exception(String.Format("Invalid file format for {0}: {1}", fileName, ex.Message)); | ||||
|             throw new Exception(string.Format("Invalid file format for {0}: {1}", fileName, ex.Message)); | ||||
|         } | ||||
|  | ||||
|         // Get Tool, Issue Start and End Date | ||||
| @ -266,7 +261,7 @@ public class MRBHelper { | ||||
|         foreach (var lotInfo in lotNumbers) { | ||||
|             if (lotInfo.LotDispo.Length == 1) { | ||||
|                 if (dispos.Count(d => d.DispositionType.Trim().ToUpper() == lotInfo.LotDispo.Trim().ToUpper()) == 0) { | ||||
|                     throw new Exception(String.Format("Invalid lot disposition {0} for lot no {1}", | ||||
|                     throw new Exception(string.Format("Invalid lot disposition {0} for lot no {1}", | ||||
|                         lotInfo.LotDispo, lotInfo.LotNo)); | ||||
|                 } | ||||
|             } | ||||
| @ -276,8 +271,8 @@ public class MRBHelper { | ||||
|         if (!mrbInfo.ToolCSV.ToUpper().Equals("NA")) { | ||||
|             foreach (var lotInfo in lotNumbers) { | ||||
|                 bool existingLotUpdated; | ||||
|                 Lot l = new Lot(); | ||||
|                 l.LotNumber = lotInfo.LotNo; | ||||
|                 Lot l = new(); | ||||
|                 l.LotNumber = lotInfo.LotNo ?? string.Empty; | ||||
|                 if (lotInfo.LotDispo.Length == 1) { | ||||
|                     l.DispoType = lotInfo.LotDispo[0]; | ||||
|                 } | ||||
| @ -298,8 +293,8 @@ public class MRBHelper { | ||||
|             // Only find the child Splits when a Tool or a list of Tools is provided | ||||
|             foreach (var lotInfo in lotNumbers) { | ||||
|                 bool existingLotUpdated; | ||||
|                 Lot l = new Lot(); | ||||
|                 l.LotNumber = lotInfo.LotNo; | ||||
|                 Lot l = new(); | ||||
|                 l.LotNumber = lotInfo.LotNo ?? string.Empty; | ||||
|                 if (lotInfo.LotDispo.Length == 1) { | ||||
|                     l.DispoType = lotInfo.LotDispo[0]; | ||||
|                 } | ||||
| @ -308,7 +303,6 @@ public class MRBHelper { | ||||
|                 mrbDMO.InsertLot(l, true, out existingLotUpdated); | ||||
|             } | ||||
|         } | ||||
| #endif | ||||
|  | ||||
|         FileInfo f = new(physicalPath); | ||||
|         if (f.Exists) | ||||
|  | ||||
| @ -8,7 +8,7 @@ namespace Fab2ApprovalSystem.Models; | ||||
| public class AppSettings { | ||||
|  | ||||
|     public AppSettings(string adminNotificationRecepient, | ||||
|                        string? apiBaseUrl, | ||||
|                        string apiBaseUrl, | ||||
|                        string attachmentFolder, | ||||
|                        string? attachmentUrl, | ||||
|                        string caBlankFormsLocation, | ||||
| @ -46,6 +46,7 @@ public class AppSettings { | ||||
|                        string urls, | ||||
|                        int userId, | ||||
|                        bool userIsAdmin, | ||||
|                        string wasmClientUrl, | ||||
|                        string wsr_URL, | ||||
|                        string? workingDirectoryName) { | ||||
|         AdminNotificationRecepient = adminNotificationRecepient; | ||||
| @ -88,11 +89,12 @@ public class AppSettings { | ||||
|         UserId = userId; | ||||
|         UserIsAdmin = userIsAdmin; | ||||
|         WSR_URL = wsr_URL; | ||||
|         WasmClientUrl = wasmClientUrl; | ||||
|         WorkingDirectoryName = workingDirectoryName; | ||||
|     } | ||||
|  | ||||
|     public string AdminNotificationRecepient { get; } | ||||
|     public string? ApiBaseUrl { get; } | ||||
|     public string ApiBaseUrl { get; } | ||||
|     public string AttachmentFolder { get; } | ||||
|     public string? AttachmentUrl { get; } | ||||
|     public string CABlankFormsLocation { get; } | ||||
| @ -130,6 +132,7 @@ public class AppSettings { | ||||
|     public string URLs { get; } | ||||
|     public int UserId { get; } | ||||
|     public bool UserIsAdmin { get; } | ||||
|     public string WasmClientUrl { get; } | ||||
|     public string WSR_URL { get; } | ||||
|     public string? WorkingDirectoryName { get; } | ||||
|  | ||||
| @ -211,12 +214,15 @@ public class AppSettings { | ||||
|                 throw new ArgumentNullException("SSRSPassword environment variable not found"); | ||||
|             string testEmailRecipients = ConfigurationManager.AppSettings["Test Email Recipients"] ?? | ||||
|                 throw new ArgumentNullException("Test Email Recipients environment variable not found"); | ||||
|             string? apiBaseUrl = ConfigurationManager.AppSettings["FabApprovalApiBaseUrl"]?.ToString(); | ||||
|             string apiBaseUrl = Environment.GetEnvironmentVariable("FabApprovalApiBaseUrl") ?? | ||||
|                 throw new ArgumentNullException("FabApprovalApiBaseUrl environment variable not found"); | ||||
|             string? attachmentUrl = ConfigurationManager.AppSettings["AttachmentUrl"]?.ToString(); | ||||
|             string? company = ConfigurationManager.AppSettings["Company"]?.ToString(); | ||||
|             string? smtpServer = ConfigurationManager.AppSettings["SMTP Server"]?.ToString(); | ||||
|             string? urls = ConfigurationManager.AppSettings["URLs"]?.ToString(); | ||||
|             string? workingDirectoryName = ConfigurationManager.AppSettings["WorkingDirectoryName"]?.ToString(); | ||||
|             string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? | ||||
|                 "https://localhost:7255"; | ||||
|             result = new(adminNotificationRecepient: adminNotificationRecepient, | ||||
|                          apiBaseUrl: apiBaseUrl, | ||||
|                          attachmentFolder: attachmentFolder, | ||||
| @ -256,6 +262,7 @@ public class AppSettings { | ||||
|                          urls: urls, | ||||
|                          userId: userId, | ||||
|                          userIsAdmin: Misc.GlobalVars.USER_ISADMIN, | ||||
|                          wasmClientUrl: wasmClientUrl, | ||||
|                          wsr_URL: Misc.GlobalVars.WSR_URL, | ||||
|                          workingDirectoryName: workingDirectoryName); | ||||
|             return result; | ||||
|  | ||||
| @ -231,6 +231,7 @@ public class CorrectiveAction { | ||||
|     public DateTime? NextDueDate { get; set; } | ||||
|     public DateTime? FollowUpDate { get; set; } | ||||
|     public bool CASubmitted { get; set; } | ||||
|     public string CAStandardType { get; set; } | ||||
|     public DateTime? ClosedDate { get; set; } | ||||
|     public CorrectiveAction() { | ||||
|         TeamMemberIDs = new List<int>(); | ||||
|  | ||||
| @ -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.html.simpleparser; | ||||
| using iTextSharp.text.pdf; | ||||
| #endif | ||||
|  | ||||
| using System.IO; | ||||
|  | ||||
| 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 { | ||||
|  | ||||
|     private const int HorizontalMargin = 40; | ||||
|     private const int VerticalMargin = 40; | ||||
|  | ||||
|     public byte[] Render(string htmlText, string pageTitle) { | ||||
|         byte[] renderedBuffer; | ||||
|     public static byte[] GetPortableDocumentFormatBytes(string pageTitle, string htmlText) { | ||||
|         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()) { | ||||
| #if !NET8 | ||||
|             using (Document pdfDocument = new Document(PageSize.A4, HorizontalMargin, HorizontalMargin, VerticalMargin, VerticalMargin)) { | ||||
|                 PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDocument, outputMemoryStream); | ||||
|     public static void WritePortableDocumentFormatToFile(string pageTitle, string htmlText, string path) { | ||||
|         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 (PdfWriter pdfWriter = PdfWriter.GetInstance(pdfDocument, result)) { | ||||
|                 pdfWriter.CloseStream = false; | ||||
|                 pdfWriter.PageEvent = new PrintHeaderFooter { Title = pageTitle }; | ||||
|                 pdfDocument.Open(); | ||||
| @ -30,15 +41,9 @@ public class StandardPdfRenderer { | ||||
|                         htmlWorker.Parse(htmlViewReader); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|             } | ||||
| #endif | ||||
|  | ||||
|             renderedBuffer = new byte[outputMemoryStream.Position]; | ||||
|             outputMemoryStream.Position = 0; | ||||
|             outputMemoryStream.Read(renderedBuffer, 0, renderedBuffer.Length); | ||||
|         } | ||||
|  | ||||
|         return renderedBuffer; | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -30,7 +30,7 @@ public class ECNPdf { | ||||
|     public string AffectedDepartments { get; set; } | ||||
|     public string AffectedAreas { get; set; } | ||||
|     public string AffectedTechnologies { get; set; } | ||||
|     public string TrainingBy { get; set; } | ||||
|     public List<int> TrainingByIDs { get; set; } | ||||
|     public string AcknowledgementBy { get; set; } | ||||
|     public bool IsECN { get; set; } | ||||
|     public bool IsTECN { get; set; } | ||||
| @ -79,6 +79,7 @@ public class ECNPdf { | ||||
|     public int? ConvertedToNumber { get; set; } | ||||
|     public int? ConvertedFromNumber { get; set; } | ||||
|     public int WorkFlowNumber { get; set; } | ||||
|     public int? CategoryID { get; set; } | ||||
|     public bool FIChangeRequired { get; set; } | ||||
|     public string NumberOfLotsAffected { get; set; } | ||||
|     public string RecipeChange { get; set; } | ||||
| @ -87,6 +88,7 @@ public class ECNPdf { | ||||
|     public ECNPdf() { | ||||
|         Approvalog = new List<ECNApprovalLog>(); | ||||
|         Attachments = new List<string>(); | ||||
|         TrainingByIDs = new List<int>(); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -380,6 +380,43 @@ | ||||
|                             </div> | ||||
|                         </div> | ||||
|                     </div> | ||||
|  | ||||
|                     <div class="col-sm-3"> | ||||
|                         <div class="row"> | ||||
|                             <div class="col-sm-3"> | ||||
|                                 <label class="control-label pull-right">CA Standard Type:</label> | ||||
|                             </div> | ||||
|                             <div class="col-sm-9"> | ||||
|                                 @(Html.Kendo().DropDownList() | ||||
|                                     .Name("CAStandardTypeList") | ||||
|  | ||||
|                                     .DataTextField("Text") | ||||
|                                     .DataValueField("Value") | ||||
|                                         .BindTo(new List<SelectListItem>() | ||||
|                                         { | ||||
|                                             new SelectListItem() | ||||
|                                             { | ||||
|                                                 Text = "IATF16949", | ||||
|                                                 Value = "IATF16949" | ||||
|                                             }, | ||||
|                                             new SelectListItem() | ||||
|                                             { | ||||
|                                                 Text = "ISO14001", | ||||
|                                                 Value = "ISO14001" | ||||
|                                             }, | ||||
|                                             new SelectListItem() | ||||
|                                             { | ||||
|                                                 Text = "ISO45001", | ||||
|                                                 Value = "ISO45001" | ||||
|                                             } | ||||
|                                         } | ||||
|                                     ) | ||||
|                                     .OptionLabel("Select") | ||||
|                                     .Value(Model.CAStandardType) | ||||
|                                 ) | ||||
|                             </div> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <div class="col-sm-3"> | ||||
| @ -2176,6 +2213,7 @@ | ||||
|             $('#txtApprovedDate').attr("disabled", true); | ||||
|             $('#txtRelatedMRB').attr("disabled", true); | ||||
|             $('#CATypeList').data("kendoDropDownList").enable(false); | ||||
|             $('#CAStandardTypeList').data("kendoDropDownList").enable(false); | ||||
|             $('#d0Comments').attr("disabled", true); | ||||
|         } | ||||
|  | ||||
| @ -3689,6 +3727,7 @@ | ||||
|             TeamCaptainID: $("#TeamCaptainList").data("kendoDropDownList").value(), | ||||
|             CASponsorID: $("#CASponsorList").data("kendoDropDownList").value(), | ||||
|             CASubmitted: isCASubmitted, | ||||
|             CAStandardType : $("#CAStandardTypeList").data("kendoDropDownList").value(), | ||||
|  | ||||
|             //D0 | ||||
|             D0Comments : $("#d0Comments").val(), | ||||
|  | ||||
| @ -325,6 +325,16 @@ | ||||
|                             </div> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                     <div class="col-sm-3"> | ||||
|                         <div class="row"> | ||||
|                             <div class="col-sm-3"> | ||||
|                                 <label class="control-label pull-right">CA Standard Type:</label> | ||||
|                             </div> | ||||
|                             <div class="col-sm-9"> | ||||
|                                 @Html.TextBoxFor(model => model.CAStandardType, new { id = "txtCAStandardType", @class = "k-textbox", Readonly = "Readonly", style = "background-color:lightblue" }) | ||||
|                             </div> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|                 <div class="row"> | ||||
|                     <div class="col-sm-3"> | ||||
|  | ||||
| @ -210,10 +210,10 @@ | ||||
|                             @Html.TextBoxFor(model => model.Title, new { id = "txtTitle", @class = "k-textbox", style = "width:100%", disabled = "disabled" }) | ||||
|                         </div> | ||||
|                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> | ||||
|                             *(DO NOT USE Rev I, O, Q, S, X, and Z) | ||||
|                             * (DO NOT USE Rev I, O, S, X, and Z) | ||||
|                         </div> | ||||
|                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> | ||||
|                             Revision Y is followed by AA. YY is followed by AAA | ||||
|                             Revision Y is followed by AA-AY, AY is followed by BA-BY etc. YY is followed by AAA | ||||
|                         </div> | ||||
|                     </div> | ||||
|                     <div class="form-group"> | ||||
|  | ||||
| @ -1,497 +1,506 @@ | ||||
| @model Fab2ApprovalSystem.ViewModels.ECNPdf | ||||
| <table style="width:100%;"> | ||||
|     <tr> | ||||
|         <td> | ||||
|             <table cellpadding="3" cellspacing="3" border="1"> | ||||
|                 <tr bgcolor="#c4baba" color="#000000"> | ||||
|                     <td colspan="2"> | ||||
|                         @Model.Title | ||||
|                     </td> | ||||
| @{ | ||||
|     Layout = null; | ||||
| } | ||||
|  | ||||
|                 </tr> | ||||
|                 <tr> | ||||
|                     <td> | ||||
|                         <table border="0"> | ||||
|                             @if (@Model.ConvertedFromNumber != null) | ||||
|                             { | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         ECN# @Model.ECNNumber (Converted from TECN#:@Model.ConvertedFromNumber) | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                             } | ||||
|                             @if (@Model.ConvertedToNumber != null) | ||||
|                             { | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         ECN# @Model.ECNNumber (Converted to ECN#:@Model.ConvertedToNumber) | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                             } | ||||
|                             @if (@Model.ConvertedFromNumber == null && @Model.ConvertedToNumber == null) | ||||
|                             {  | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     ECN# @Model.ECNNumber | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                             } | ||||
| <!DOCTYPE html> | ||||
|  | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         Submit Date#:  | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                         @Model.SubmitedDate | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         Originator Name:  | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                         @Model.OriginatorName | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
| <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> | ||||
|  | ||||
|                         </table> | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         <table border="0"> | ||||
|                             @*<tr> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         Affected Department:  | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                         @Model.AffectedDepartments | ||||
|                                     </font> | ||||
|                                 </td> | ||||
| <body class="navbar-inner"> | ||||
|     <table style="width:100%;"> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <table cellpadding="3" cellspacing="3" border="1"> | ||||
|                     <tr bgcolor="#c4baba" color="#000000"> | ||||
|                         <td colspan="2"> | ||||
|                             @Model.Title | ||||
|                         </td> | ||||
|  | ||||
|                             </tr>*@ | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         Affected Area:  | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                         @Model.AffectedModules | ||||
|                                         @*@Model.AffectedAreas*@ | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         ITAR/EC:  | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                         @(Model.IsDocEC ? "Yes" : "No") | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                         </table> | ||||
|                     </td> | ||||
|                 </tr> | ||||
|                  | ||||
|             </table> | ||||
|         </td> | ||||
|     </tr> | ||||
|         | ||||
|     <tr> | ||||
|         <td> | ||||
|             <table border="1"> | ||||
|                 <tr bgcolor="#c4baba" color="#000000"> | ||||
|                     <td> ECN - TECN Details</td> | ||||
|                 </tr> | ||||
|                 <tr> | ||||
|                     <td> | ||||
|                         <table border="0"> | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         ECN:   | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                         @(Model.IsECN ? "Yes" : "No") | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         TECN:  | ||||
|                                         @(Model.IsTECN ? "Yes" : "No") | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         Emergency:   | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                         @(Model.IsEmergencyTECN ? "Yes" : "No") | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         Expiration Date: | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                          | ||||
|                                         @Convert.ToString(string.Format("{0:MM/dd/yyyy}", Model.ExpirationDate)) | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         Extension Date: | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                          | ||||
|                                         @Convert.ToString(string.Format("{0:MM/dd/yyyy}", @Model.ExtensionDate)) | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         Cancellation Date: | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                         @Model.CancellationApprovalDate | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         # lots affected: | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                         @Model.NumberOfLotsAffected | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         Recipe Or/And Flow Change: | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                         @Model.RecipeChange | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         Affected product families: | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                         @Model.AffectedProductFamilies | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                         </table> | ||||
|                     </td> | ||||
|                 </tr>                 | ||||
|                 <tr> | ||||
|                     <td> | ||||
|                         <table border="0"> | ||||
|                             <tr> | ||||
|                                 <td colspan="3" style="background-color:ActiveCaption"> | ||||
|                                     <font size="2"> | ||||
|                                         Affected Documents:  | ||||
|                                     </font> | ||||
|  | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                             <tr> | ||||
|                                 @foreach (string attachmentName in Model.Attachments) | ||||
|                     </tr> | ||||
|                     <tr> | ||||
|                         <td> | ||||
|                             <table border="0"> | ||||
|                                 @if (@Model.ConvertedFromNumber != null) | ||||
|                                 { | ||||
|                                     <td colspan="3"> | ||||
|                                     <tr> | ||||
|                                         <td> | ||||
|                                             ECN# @Model.ECNNumber (Converted from TECN#:@Model.ConvertedFromNumber) | ||||
|                                         </td> | ||||
|                                     </tr> | ||||
|                                 } | ||||
|                                 @if (@Model.ConvertedToNumber != null) | ||||
|                                 { | ||||
|                                     <tr> | ||||
|                                         <td> | ||||
|                                             ECN# @Model.ECNNumber (Converted to ECN#:@Model.ConvertedToNumber) | ||||
|                                         </td> | ||||
|                                     </tr> | ||||
|                                 } | ||||
|                                 @if (@Model.ConvertedFromNumber == null && @Model.ConvertedToNumber == null) | ||||
|                                 { | ||||
|                                     <tr> | ||||
|                                         <td> | ||||
|                                             ECN# @Model.ECNNumber | ||||
|                                         </td> | ||||
|                                     </tr> | ||||
|                                 } | ||||
|  | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             Submit Date#:  | ||||
|                                         </font> | ||||
|                                         <font size="1"> | ||||
|                                             @attachmentName | ||||
|                                             @Model.SubmitedDate | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                 } | ||||
|                             </tr> | ||||
|                         </table> | ||||
|                     </td> | ||||
|                 </tr> | ||||
|                 | ||||
|                  | ||||
|             </table> | ||||
|         </td> | ||||
|     </tr> | ||||
|  | ||||
|     <tr> | ||||
|         <td> | ||||
|             <table border="1" > | ||||
|                 <tr bgcolor="#c4baba" color="#000000"> | ||||
|                     <td> Description of Change</td> | ||||
|                     <td> Reason for Change</td> | ||||
|                 </tr> | ||||
|                 <tr> | ||||
|                     <td> | ||||
|                         <font size="1"> | ||||
|                             @Html.Raw(@Model.DescriptionOfChange) | ||||
|                         </font> | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         <font size="1"> | ||||
|                             @Html.Raw(@Model.ReasonForChange) | ||||
|                         </font> | ||||
|                     </td> | ||||
|                 </tr> | ||||
|             </table> | ||||
|         </td> | ||||
|     </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> | ||||
|         <td> | ||||
|  | ||||
|             <table border="1"> | ||||
|                 <tr bgcolor="#c4baba" color="#000000"> | ||||
|                     <td colspan="5">Systems</td> | ||||
|                 </tr> | ||||
|                 <tr style="display:block;"> | ||||
|                     <td> | ||||
|                         <font size="2"> | ||||
|                             PCRB: | ||||
|                         </font> | ||||
|                         <font size="1"> | ||||
|                             @(Model.PCRBRequired ? "Yes": "No") | ||||
|                         </font> | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         <font size="2"> | ||||
|                             PCRB#:   | ||||
|                             @Model.PCRBNumber | ||||
|                         </font> | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         <font size="2"> | ||||
|                             Metrology Change:    | ||||
|                         </font> | ||||
|                         <font size="1"> | ||||
|                             @(Model.MetrologyChangeRequired ? "Yes": "No") | ||||
|                         </font> | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         <font size="2"> | ||||
|                             SPC Change: | ||||
|                         </font> | ||||
|                         <font size="1"> | ||||
|                             @(Model.SPCChangeRequired ? "Yes": "No") | ||||
|                         </font> | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         <font size="2"> | ||||
|                             FI Change: | ||||
|                         </font> | ||||
|                         <font size="1"> | ||||
|                            @(Model.FIChangeRequired ? "Yes" : "No") | ||||
|                         </font> | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         <font size="2"> | ||||
|                             OI Change: | ||||
|                         </font> | ||||
|                         <font size="1"> | ||||
|                             @(Model.SPNChangeRequired ? "Yes" : "No") | ||||
|                         </font> | ||||
|                     </td> | ||||
|                     <td></td> | ||||
|                 </tr> | ||||
|                  | ||||
|             </table> | ||||
|  | ||||
|  | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td> | ||||
|             <table border="1"> | ||||
|                 <tr bgcolor="#c4baba" color="#000000"> | ||||
|                     <td colspan="4"> Change Impact</td> | ||||
|                 </tr> | ||||
|                 <tr> | ||||
|                     <td> | ||||
|                         <table border="0"> | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         Impact On ESH: | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                         @if (Model.ImpactOnEnvironment == 1) | ||||
|                                         { | ||||
|                                             @: Positive | ||||
|                                         } | ||||
|                                         else if (Model.ImpactOnEnvironment == 2) | ||||
|                                         {  | ||||
|                                             @: Negative | ||||
|                                         } | ||||
|                                         else | ||||
|                                         {  | ||||
|                                             @: N/A | ||||
|                                         } | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     <font size="1"> | ||||
|                                         @Html.Raw(@Model.ImpactOnEnvironmentDescription) | ||||
|                                 </tr> | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             Originator Name:  | ||||
|                                         </font> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                         </table> | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         <table border="0"> | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         Impact On Capacity: | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                         @(Model.ImpactOnCapacity == 1 ? "Yes" : "No") | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     <font size="1"> | ||||
|                                         @Html.Raw(@Model.ImpactOnCapacityDescription) | ||||
|                                         <font size="1"> | ||||
|                                             @Model.OriginatorName | ||||
|                                         </font> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                         </table> | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         @*<table border="0"> | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         RH(ITAR): | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                         @(Model.IsRH ? "Yes" : "No") | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                         </table>*@ | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         <table border="0"> | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     <font size="2"> | ||||
|                                         Material Consumption Change: | ||||
|                                     </font> | ||||
|                                     <font size="1"> | ||||
|                                         @(Model.MaterialConsumptionChangeRequired == 1 ? "Yes" : "No") | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                             <tr> | ||||
|                                 <td> | ||||
|                                     <font size="1"> | ||||
|                                         @Html.Raw(@Model.MaterialConsumptionChangeDescription) | ||||
|                                     </font> | ||||
|                                 </td> | ||||
|                             </tr> | ||||
|                         </table> | ||||
|                     </td> | ||||
|                 </tr> | ||||
|             </table> | ||||
|         </td> | ||||
|     </tr> | ||||
|     <tr> | ||||
|         <td> | ||||
|             <table border="1"> | ||||
|                 <tr bgcolor="#c4baba" color="#ffffff"> | ||||
|                     <td> | ||||
|                         Full Name | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         Role | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         Approved/Denied | ||||
|                     </td> | ||||
|                     <td> | ||||
|                         Date Time | ||||
|                     </td> | ||||
|                 </tr> | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|  | ||||
|                 @foreach (Fab2ApprovalSystem.ViewModels.ECNApprovalLog ecnApp in Model.Approvalog) | ||||
|                 { | ||||
|                             </table> | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             <table border="0"> | ||||
|                                 @*<tr> | ||||
|                                 <td> | ||||
|                                 <font size="2"> | ||||
|                                 Affected Department:  | ||||
|                                 </font> | ||||
|                                 <font size="1"> | ||||
|                                 @Model.AffectedDepartments | ||||
|                                 </font> | ||||
|                                 </td> | ||||
|  | ||||
|                                 </tr>*@ | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             Affected Area:  | ||||
|                                         </font> | ||||
|                                         <font size="1"> | ||||
|                                             @Model.AffectedModules | ||||
|                                             @*@Model.AffectedAreas*@ | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             Category:  | ||||
|                                         </font> | ||||
|                                         <font size="1"> | ||||
|                                             @(ViewBag.Category) | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             ITAR/EC:  | ||||
|                                         </font> | ||||
|                                         <font size="1"> | ||||
|                                             @(Model.IsDocEC ? "Yes" : "No") | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                             </table> | ||||
|                         </td> | ||||
|                     </tr> | ||||
|                 </table> | ||||
|             </td> | ||||
|         </tr> | ||||
|  | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <table border="1"> | ||||
|                     <tr bgcolor="#c4baba" color="#000000"> | ||||
|                         <td> ECN - TECN Details</td> | ||||
|                     </tr> | ||||
|                     <tr> | ||||
|                         <td> | ||||
|                             <table border="0"> | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             ECN:   | ||||
|                                         </font> | ||||
|                                         <font size="1"> | ||||
|                                             @(Model.IsECN ? "Yes" : "No") | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             TECN:  | ||||
|                                             @(Model.IsTECN ? "Yes" : "No") | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             Emergency:   | ||||
|                                         </font> | ||||
|                                         <font size="1"> | ||||
|                                             @(Model.IsEmergencyTECN ? "Yes" : "No") | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             Expiration Date: | ||||
|                                         </font> | ||||
|                                         <font size="1"> | ||||
|  | ||||
|                                             @Convert.ToString(string.Format("{0:MM/dd/yyyy}", Model.ExpirationDate)) | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             Extension Date: | ||||
|                                         </font> | ||||
|                                         <font size="1"> | ||||
|  | ||||
|                                             @Convert.ToString(string.Format("{0:MM/dd/yyyy}", @Model.ExtensionDate)) | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             Cancellation Date: | ||||
|                                         </font> | ||||
|                                         <font size="1"> | ||||
|                                             @Model.CancellationApprovalDate | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             # lots affected: | ||||
|                                         </font> | ||||
|                                         <font size="1"> | ||||
|                                             @Model.NumberOfLotsAffected | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             Recipe Or/And Flow Change: | ||||
|                                         </font> | ||||
|                                         <font size="1"> | ||||
|                                             @Model.RecipeChange | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             Affected product families: | ||||
|                                         </font> | ||||
|                                         <font size="1"> | ||||
|                                             @Model.AffectedProductFamilies | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                             </table> | ||||
|                         </td> | ||||
|                     </tr> | ||||
|                     <tr> | ||||
|                         <td> | ||||
|                             <table border="0"> | ||||
|                                 <tr> | ||||
|                                     <td colspan="3" style="background-color:ActiveCaption"> | ||||
|                                         <font size="2"> | ||||
|                                             Affected Documents:  | ||||
|                                         </font> | ||||
|  | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                                 <tr> | ||||
|                                     @foreach (string attachmentName in Model.Attachments) | ||||
|                                     { | ||||
|                                         <td colspan="3"> | ||||
|                                             <font size="1"> | ||||
|                                                 @attachmentName | ||||
|                                             </font> | ||||
|                                         </td> | ||||
|                                     } | ||||
|                                 </tr> | ||||
|                             </table> | ||||
|                         </td> | ||||
|                     </tr> | ||||
|  | ||||
|                 </table> | ||||
|             </td> | ||||
|         </tr> | ||||
|  | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <table border="1"> | ||||
|                     <tr bgcolor="#c4baba" color="#000000"> | ||||
|                         <td> Description of Change</td> | ||||
|                         <td> Reason for Change</td> | ||||
|                     </tr> | ||||
|                     <tr> | ||||
|                         <td> | ||||
|                             <font size="1"> | ||||
|                                 @ecnApp.FullName | ||||
|                                 @Html.Raw(@Model.DescriptionOfChange) | ||||
|                             </font> | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             <font size="1"> | ||||
|                                 @ecnApp.SubRole | ||||
|                             </font> | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             <font size="1"> | ||||
|                                 @ecnApp.Operation | ||||
|                             </font> | ||||
|                         </td> | ||||
|  | ||||
|                         <td> | ||||
|                             <font size="1"> | ||||
|                                 @ecnApp.OperationTime | ||||
|                                 @Html.Raw(@Model.ReasonForChange) | ||||
|                             </font> | ||||
|                         </td> | ||||
|                     </tr> | ||||
|                 } | ||||
|  | ||||
|  | ||||
|             </table> | ||||
|         </td> | ||||
|     </tr> | ||||
|      | ||||
|  | ||||
| </table> <!--main table --> | ||||
|                 </table> | ||||
|             </td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|  | ||||
|                 <table border="1"> | ||||
|                     <tr bgcolor="#c4baba" color="#000000"> | ||||
|                         <td colspan="5">Systems</td> | ||||
|                     </tr> | ||||
|                     <tr style="display:block;"> | ||||
|                         <td> | ||||
|                             <font size="2"> | ||||
|                                 PCRB: | ||||
|                             </font> | ||||
|                             <font size="1"> | ||||
|                                 @(Model.PCRBRequired ? "Yes" : "No") | ||||
|                             </font> | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             <font size="2"> | ||||
|                                 PCRB#:   | ||||
|                                 @Model.PCRBNumber | ||||
|                             </font> | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             <font size="2"> | ||||
|                                 Metrology Change:    | ||||
|                             </font> | ||||
|                             <font size="1"> | ||||
|                                 @(Model.MetrologyChangeRequired ? "Yes" : "No") | ||||
|                             </font> | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             <font size="2"> | ||||
|                                 SPC Change: | ||||
|                             </font> | ||||
|                             <font size="1"> | ||||
|                                 @(Model.SPCChangeRequired ? "Yes" : "No") | ||||
|                             </font> | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             <font size="2"> | ||||
|                                 FI Change: | ||||
|                             </font> | ||||
|                             <font size="1"> | ||||
|                                 @(Model.FIChangeRequired ? "Yes" : "No") | ||||
|                             </font> | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             <font size="2"> | ||||
|                                 OI Change: | ||||
|                             </font> | ||||
|                             <font size="1"> | ||||
|                                 @(Model.SPNChangeRequired ? "Yes" : "No") | ||||
|                             </font> | ||||
|                         </td> | ||||
|                     </tr> | ||||
|                 </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> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <table border="1"> | ||||
|                     <tr bgcolor="#c4baba" color="#000000"> | ||||
|                         <td colspan="4"> Change Impact</td> | ||||
|                     </tr> | ||||
|                     <tr> | ||||
|                         <td> | ||||
|                             <table border="0"> | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             Impact On ESH: | ||||
|                                         </font> | ||||
|                                         <font size="1"> | ||||
|                                             @if (Model.ImpactOnEnvironment == 1) | ||||
|                                             { | ||||
|                                                 @: Positive | ||||
|                                             } | ||||
|                                             else if (Model.ImpactOnEnvironment == 2) | ||||
|                                             { | ||||
|                                                 @: Negative | ||||
|                                             } | ||||
|                                             else | ||||
|                                             { | ||||
|                                                 @: N/A | ||||
|                                             } | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         <font size="1"> | ||||
|                                             @Html.Raw(@Model.ImpactOnEnvironmentDescription) | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                             </table> | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             <table border="0"> | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             Impact On Capacity: | ||||
|                                         </font> | ||||
|                                         <font size="1"> | ||||
|                                             @(Model.ImpactOnCapacity == 1 ? "Yes" : "No") | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         <font size="1"> | ||||
|                                             @Html.Raw(@Model.ImpactOnCapacityDescription) | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                             </table> | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             @*<table border="0"> | ||||
|                             <tr> | ||||
|                             <td> | ||||
|                             <font size="2"> | ||||
|                             RH(ITAR): | ||||
|                             </font> | ||||
|                             <font size="1"> | ||||
|                             @(Model.IsRH ? "Yes" : "No") | ||||
|                             </font> | ||||
|                             </td> | ||||
|                             </tr> | ||||
|                             </table>*@ | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             <table border="0"> | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         <font size="2"> | ||||
|                                             Material Consumption Change: | ||||
|                                         </font> | ||||
|                                         <font size="1"> | ||||
|                                             @(Model.MaterialConsumptionChangeRequired == 1 ? "Yes" : "No") | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                                 <tr> | ||||
|                                     <td> | ||||
|                                         <font size="1"> | ||||
|                                             @Html.Raw(@Model.MaterialConsumptionChangeDescription) | ||||
|                                         </font> | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|                             </table> | ||||
|                         </td> | ||||
|                     </tr> | ||||
|                 </table> | ||||
|             </td> | ||||
|         </tr> | ||||
|         <tr> | ||||
|             <td> | ||||
|                 <table border="1"> | ||||
|                     <tr bgcolor="#c4baba" color="#ffffff"> | ||||
|                         <td> | ||||
|                             Full Name | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             Role | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             Approved/Denied | ||||
|                         </td> | ||||
|                         <td> | ||||
|                             Date Time | ||||
|                         </td> | ||||
|                     </tr> | ||||
|  | ||||
|                     @foreach (Fab2ApprovalSystem.ViewModels.ECNApprovalLog ecnApp in Model.Approvalog) | ||||
|                     { | ||||
|                         <tr> | ||||
|                             <td> | ||||
|                                 <font size="1"> | ||||
|                                     @ecnApp.FullName | ||||
|                                 </font> | ||||
|                             </td> | ||||
|                             <td> | ||||
|                                 <font size="1"> | ||||
|                                     @ecnApp.SubRole | ||||
|                                 </font> | ||||
|                             </td> | ||||
|                             <td> | ||||
|                                 <font size="1"> | ||||
|                                     @ecnApp.Operation | ||||
|                                 </font> | ||||
|                             </td> | ||||
|  | ||||
|                             <td> | ||||
|                                 <font size="1"> | ||||
|                                     @ecnApp.OperationTime | ||||
|                                 </font> | ||||
|                             </td> | ||||
|                         </tr> | ||||
|                     } | ||||
|  | ||||
|                 </table> | ||||
|             </td> | ||||
|         </tr> | ||||
|  | ||||
|     </table> | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
| @ -154,10 +154,10 @@ | ||||
|                             @Html.TextBoxFor(model => model.Title, new { id = "txtTitle", @class = "k-textbox", style = "width:100%" }) | ||||
|                         </div> | ||||
|                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> | ||||
|                             *(DO NOT USE Rev I, O, Q, S, X, and Z) | ||||
|                             * (DO NOT USE Rev I, O, S, X, and Z) | ||||
|                         </div> | ||||
|                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> | ||||
|                             Revision Y is followed by AA. YY is followed by AAA | ||||
|                             Revision Y is followed by AA-AY, AY is followed by BA-BY etc. YY is followed by AAA | ||||
|                         </div> | ||||
|                     </div> | ||||
|                     <div class="form-group"> | ||||
|  | ||||
| @ -86,29 +86,47 @@ | ||||
|  | ||||
|                 if (Model.IsTECN && !Model.CancellationInProgress && !Model.CancellationApproved && !Model.ExpirationInProgress | ||||
|                     && !Model.ExpirationProcessed && !Model.Converted | ||||
|                     && !Model.LockedForConversion | ||||
|                     && (Model.ExpirationDate > DateTime.Today || Model.ExtensionDate > DateTime.Today)) | ||||
|                     && !Model.LockedForConversion) | ||||
|                 { | ||||
|                     ViewBag.CanResubmit = "true"; | ||||
|                     <input type="button" value="Change Type" class="btn btn-primary btn-xs" id="ReSubmitDocument" disabled="disabled" /> | ||||
|                     <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" /> | ||||
|                     if (Model.ExpirationDate > DateTime.Today || Model.ExtensionDate > DateTime.Today) | ||||
|                     { | ||||
|                         <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" /> | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         <input type="button" value="Return to Process" class="btn btn-primary btn-xs" id="ReturnToProcessDocument" /> | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 else if (Model.IsTECN && !Model.CancellationInProgress && !Model.CancellationApproved && !Model.ExpirationInProgress | ||||
|                     && !Model.ExpirationProcessed | ||||
|                     && Model.ConversionApprovalInProgress == false | ||||
|                     && (Model.ExpirationDate >= DateTime.Today || Model.ExtensionDate >= DateTime.Today)) | ||||
|                     && Model.ConversionApprovalInProgress == false) | ||||
|                 { | ||||
|                     <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" /> | ||||
|                     if (Model.ExpirationDate > DateTime.Today || Model.ExtensionDate > DateTime.Today) | ||||
|                     { | ||||
|                         <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" /> | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         <input type="button" value="Return to Process" class="btn btn-primary btn-xs" id="ReturnToProcessDocument" /> | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 else if (Model.IsEmergencyTECN && !Model.CancellationInProgress && !Model.CancellationApproved && !Model.ExpirationInProgress | ||||
|                     && !Model.ExpirationProcessed && !Model.Converted | ||||
|                         && (Model.ExpirationDate > DateTime.Today || Model.ExtensionDate > DateTime.Today)) | ||||
|                     && !Model.ExpirationProcessed && !Model.Converted) | ||||
|                 { | ||||
|                     ViewBag.CanResubmit = "true"; | ||||
|                     <input type="button" value="Change Type" class="btn btn-primary btn-xs" id="ReSubmitDocument" disabled="disabled" /> | ||||
|                     <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" /> | ||||
|                     if (Model.ExpirationDate > DateTime.Today || Model.ExtensionDate > DateTime.Today) | ||||
|                     { | ||||
|                         <input type="button" value="Cancel Document" class="btn btn-primary btn-xs" id="CancelDocument" /> | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         <input type="button" value="Return to Process" class="btn btn-primary btn-xs" id="ReturnToProcessDocument" /> | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @ -242,10 +260,10 @@ | ||||
|                             @Html.TextBoxFor(model => model.Title, new { id = "txtTitle", @class = "k-textbox", style = "width:100%", disabled = "disabled" }) | ||||
|                         </div> | ||||
|                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> | ||||
|                             *(DO NOT USE Rev I, O, Q, S, X, and Z) | ||||
|                             * (DO NOT USE Rev I, O, S, X, and Z) | ||||
|                         </div> | ||||
|                         <div class="col-sm-6 col-sm-offset-4" style="color: red;"> | ||||
|                             Revision Y is followed by AA. YY is followed by AAA | ||||
|                             Revision Y is followed by AA-AY, AY is followed by BA-BY etc. YY is followed by AAA | ||||
|                         </div> | ||||
|                     </div> | ||||
|                     <div class="form-group"> | ||||
| @ -1251,6 +1269,9 @@ | ||||
|     </div> | ||||
| </div> | ||||
|  | ||||
| @Html.Partial("_ECNCancel") | ||||
| @Html.Partial("_ECNReturnToProcess") | ||||
|  | ||||
| @Html.Partial("_ECNReassignOriginator") | ||||
|  | ||||
| <script type="text/javascript"> | ||||
| @ -2188,40 +2209,6 @@ | ||||
|         return false; | ||||
|     }); | ||||
|  | ||||
|     $('#CancelDocument').on('click', function () { | ||||
|         docType = 5; | ||||
|         if (confirm("Are you sure you want to Cancel this document?")) { | ||||
|             $.ajax({ | ||||
|                 url: "/ECN/CancelDocument", | ||||
|                 type: "GET", | ||||
|                 datatype: "json", | ||||
|                 data: { | ||||
|                     ecnNumber: $("#txtECNNumber").val(), | ||||
|                     currentStep: 1, | ||||
|                     documentType: docType, | ||||
|                     ecnTypeString: ecnTypeString | ||||
|                 }, | ||||
|                 success: function (data) { | ||||
|  | ||||
|                     if (data == 'Redirect') { | ||||
|                         var url = '@Url.Action("ReadOnly", "ECN", new { issueID = "__id__" })'; | ||||
|                         url = url.replace('amp;', ''); | ||||
|                         window.location.href = url.replace('__id__', $("#txtECNNumber").val()); | ||||
|  | ||||
|                     } | ||||
|                     else { | ||||
|                         // TODO alert an error message | ||||
|                     } | ||||
|                 }, | ||||
|                 error: function (result) { | ||||
|                     alert("Failed on Cancel" + result); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         return false; | ||||
|     }); | ||||
|  | ||||
|     var returnNoOfDays = function () { | ||||
|         //var start = new Date($('#txSubmitDate').val()); | ||||
|         var start = new Date(); | ||||
|  | ||||
							
								
								
									
										75
									
								
								Fab2ApprovalSystem/Views/ECN/_ECNCancel.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								Fab2ApprovalSystem/Views/ECN/_ECNCancel.cshtml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,75 @@ | ||||
| <div class="modal fade" id="Cancel" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static"> | ||||
|     <div class="modal-dialog"> | ||||
|         <div class="modal-content"> | ||||
|             <div class="modal-header"> | ||||
|                 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> | ||||
|                 <h4 class="modal-title" id="myModalLabel"><center>Has the process returned to the original state?</center></h4> | ||||
|  | ||||
|             </div> | ||||
|             <div class="modal-body"> | ||||
|                 <div class="control-group"> | ||||
|                     <div class="row"> | ||||
|                         <div class="col-sm-13"> | ||||
|                             <h4 class="modal-title">Comments (Required):</h4> | ||||
|                             <textarea class="form-control" rows="5" id="comments" style="resize: none;"></textarea> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|             <div class="modal-footer"> | ||||
|                 <button type="button" class="btn btn-default" data-dismiss="modal">No</button> | ||||
|                 <button type="button" class="btn btn-primary" id="ConfirmCancel">Confirm Cancel (Yes)</button> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| <script language="javascript" type="text/javascript"> | ||||
|  | ||||
|     $(document).ready(function () { | ||||
|  | ||||
|         $("#CancelDocument").click(function (e) { | ||||
|  | ||||
|             $("#comments").val(""); | ||||
|  | ||||
|             $("#Cancel").modal('show'); | ||||
|         }); | ||||
|  | ||||
|         $('#ConfirmCancel').on('click', function () { | ||||
|  | ||||
|             if ($("#comments").val() == "") { | ||||
|                 alert("Comments are required"); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             $('#ConfirmCancel').attr("disabled", true); | ||||
|  | ||||
|             $.ajax({ | ||||
|                 url: "/ECN/CancelDocument", | ||||
|                 type: "GET", | ||||
|                 datatype: "json", | ||||
|                 data: { | ||||
|                     ecnNumber: $("#txtECNNumber").val(), | ||||
|                     currentStep: 1, | ||||
|                     documentType: 5, | ||||
|                     ecnTypeString: ecnTypeString, | ||||
|                     comments: $("#comments").val(), | ||||
|                 }, | ||||
|                 success: function (data) { | ||||
|  | ||||
|                     $("#Cancel").modal('hide'); | ||||
|  | ||||
|                     var url = '@Url.Action("ReadOnly", "ECN", new { issueID = "__id__" })'; | ||||
|                     url = url.replace('amp;', ''); | ||||
|                     window.location.href = url.replace('__id__', $("#txtECNNumber").val()); | ||||
|  | ||||
|                 }, | ||||
|                 error: function (result) { | ||||
|                     $('#ConfirmCancel').attr("disabled", false); | ||||
|                     alert("Server error while canceling document"); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|  | ||||
|     }); | ||||
| </script> | ||||
							
								
								
									
										75
									
								
								Fab2ApprovalSystem/Views/ECN/_ECNReturnToProcess.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								Fab2ApprovalSystem/Views/ECN/_ECNReturnToProcess.cshtml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,75 @@ | ||||
| <div class="modal fade" id="ReturnToProcess" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="static"> | ||||
|     <div class="modal-dialog"> | ||||
|         <div class="modal-content"> | ||||
|             <div class="modal-header"> | ||||
|                 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> | ||||
|                 <h4 class="modal-title" id="myModalLabel"><center>Has the process returned to the original state?</center></h4> | ||||
|  | ||||
|             </div> | ||||
|             <div class="modal-body"> | ||||
|                 <div class="control-group"> | ||||
|                     <div class="row"> | ||||
|                         <div class="col-sm-13"> | ||||
|                             <h4 class="modal-title">Comments (Required):</h4> | ||||
|                             <textarea class="form-control" rows="5" id="ReturnToProcessComments" style="resize: none;"></textarea> | ||||
|                         </div> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|             <div class="modal-footer"> | ||||
|                 <button type="button" class="btn btn-default" data-dismiss="modal">No</button> | ||||
|                 <button type="button" class="btn btn-primary" id="ConfirmReturnToProcess">Confirm Return to Process (Yes)</button> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
| </div> | ||||
| <script language="javascript" type="text/javascript"> | ||||
|  | ||||
|     $(document).ready(function () { | ||||
|  | ||||
|         $("#ReturnToProcessDocument").click(function (e) { | ||||
|  | ||||
|             $("#ReturnToProcessComments").val(""); | ||||
|  | ||||
|             $("#ReturnToProcess").modal('show'); | ||||
|         }); | ||||
|  | ||||
|         $('#ConfirmReturnToProcess').on('click', function () { | ||||
|  | ||||
|             if ($("#ReturnToProcessComments").val() == "") { | ||||
|                 alert("Comments are required"); | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             $('#ConfirmReturnToProcess').attr("disabled", true); | ||||
|  | ||||
|             $.ajax({ | ||||
|                 url: "/ECN/CancelDocument", | ||||
|                 type: "GET", | ||||
|                 datatype: "json", | ||||
|                 data: { | ||||
|                     ecnNumber: $("#txtECNNumber").val(), | ||||
|                     currentStep: 1, | ||||
|                     documentType: 5, | ||||
|                     ecnTypeString: ecnTypeString, | ||||
|                     comments: $("#ReturnToProcessComments").val(), | ||||
|                 }, | ||||
|                 success: function (data) { | ||||
|  | ||||
|                     $("#ReturnToProcess").modal('hide'); | ||||
|  | ||||
|                     var url = '@Url.Action("ReadOnly", "ECN", new { issueID = "__id__" })'; | ||||
|                     url = url.replace('amp;', ''); | ||||
|                     window.location.href = url.replace('__id__', $("#txtECNNumber").val()); | ||||
|  | ||||
|                 }, | ||||
|                 error: function (result) { | ||||
|                     $('#ConfirmReturnToProcess').attr("disabled", false); | ||||
|                     alert("Server error while ReturnToProcessing document"); | ||||
|                 } | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|  | ||||
|     }); | ||||
| </script> | ||||
| @ -90,17 +90,17 @@ | ||||
|                             string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); | ||||
|                             string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? | ||||
|                                 "https://localhost:7255"; | ||||
|                             string mrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=/mrb/new"; | ||||
|                             string mrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=mrb/new"; | ||||
|                             <li><a href="@mrbUrl">Create MRB</a></li> | ||||
|                             @*string pcrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=/pcrb/new"; | ||||
|                             <li><a href="@pcrbUrl">Create PCRB</a></li>*@ | ||||
|                             string pcrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=pcrb/new"; | ||||
|                             <li><a href="@pcrbUrl">Create PCRB</a></li> | ||||
|                         } else { | ||||
|                             string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? | ||||
|                                                         "https://localhost:7255"; | ||||
|                             string mrbUrl = wasmClientUrl + "/redirect?redirectPath=/mrb/new"; | ||||
|                             string mrbUrl = wasmClientUrl + "/redirect?redirectPath=mrb/new"; | ||||
|                             <li><a href="@mrbUrl">Create MRB</a></li> | ||||
|                             @*string pcrbUrl = wasmClientUrl + "/redirect?redirectPath=/pcrb/new"; | ||||
|                             <li><a href="@pcrbUrl">Create PCRB</a></li>*@ | ||||
|                             string pcrbUrl = wasmClientUrl + "/redirect?redirectPath=pcrb/new"; | ||||
|                             <li><a href="@pcrbUrl">Create PCRB</a></li> | ||||
|                         } | ||||
|                         @*<li><a href=@Url.Action("CreateWorkRequest", "LotTraveler")>Create Special Work Request</a></li>*@ | ||||
|                         @*<li><a href=@Url.Action("Create", "ChangeControl")>Create PCR</a></li>*@ | ||||
| @ -150,10 +150,10 @@ | ||||
|             string encodedRefreshToken = System.Net.WebUtility.UrlEncode(refreshToken); | ||||
|             string wasmClientUrl = Environment.GetEnvironmentVariable("FabApprovalWasmClientUrl") ?? | ||||
|                 "https://localhost:7255"; | ||||
|             string mrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=/mrb/all"; | ||||
|             string mrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=mrb/all"; | ||||
|             menu.Add().Text("MRB").Url(mrbUrl); | ||||
|             //string pcrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=/pcrb/all"; | ||||
|             //menu.Add().Text("PCRB").Url(pcrbUrl); | ||||
|             string pcrbUrl = wasmClientUrl + "/redirect?jwt=" + encodedJwt + "&refreshToken=" + encodedRefreshToken + "&redirectPath=pcrb/all"; | ||||
|             menu.Add().Text("PCRB").Url(pcrbUrl); | ||||
|             //menu.Add().Text("Special Work Requests").Action("SpecialWorkRequestList", "Home"); | ||||
|             //menu.Add().Text("PCRB").Action("ChangeControlList", "Home"); | ||||
|             //menu.Add().Text("MRB").Action("MRBList", "Home"); | ||||
|  | ||||
							
								
								
									
										232
									
								
								Fab2ApprovalSystem/pipelines-manual.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								Fab2ApprovalSystem/pipelines-manual.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,232 @@ | ||||
| trigger: | ||||
|   branches: | ||||
|     include: | ||||
|       - master | ||||
|   paths: | ||||
|     include: | ||||
|       - Fab2ApprovalSystem | ||||
|  | ||||
| variables: | ||||
|   coreVersion: "net8.0" | ||||
|   targetFrameworkVersion: "v4.8" | ||||
|   nugetSource: "https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/" | ||||
|   msBuild: "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" | ||||
|  | ||||
| stages: | ||||
|   - stage: Development | ||||
|     displayName: Development | ||||
|     pool: | ||||
|       name: MesaFabApproval | ||||
|       demands: Fab2ApprovalSystem-Dev | ||||
|     variables: | ||||
|       ASPNETCORE_ENVIRONMENT: "Development" | ||||
|       assemblyTitle: "Fab2ApprovalSystem" | ||||
|       configuration: "Debug" | ||||
|     jobs: | ||||
|       - job: DebugDotnet | ||||
|         steps: | ||||
|           - script: | | ||||
|               echo BuildId: $(Build.BuildId) | ||||
|               echo Build reason: $(Build.Reason) | ||||
|               echo Repo Id: $(Build.Repository.Id) | ||||
|               echo Repo name: $(Build.Repository.Name) | ||||
|               echo Source version: $(Build.SourceVersion) | ||||
|               echo Core version: $(CoreVersion) | ||||
|               echo Configuration: $(Configuration) | ||||
|               echo Target Framework version: $(TargetFrameworkVersion) | ||||
|               echo Assembly title: $(AssemblyTitle) | ||||
|               echo MicrosoftBuildEngine: $(msBuild) | ||||
|               echo NugetSource: $(NugetSource) | ||||
|             displayName: "Echo Check" | ||||
|  | ||||
|           - script: | | ||||
|               mklink /J ".vscode\.UserSecrets" "%AppData%\Microsoft\UserSecrets\f2da5035-aba9-4676-9f8d-d6689f84663d" | ||||
|               mklink /J "DMO" "..\Fab2ApprovalSystem\DMO" | ||||
|               mklink /J "Jobs" "..\Fab2ApprovalSystem\Jobs" | ||||
|               mklink /J "JobSchedules" "..\Fab2ApprovalSystem\JobSchedules" | ||||
|               mklink /J "Misc" "..\Fab2ApprovalSystem\Misc" | ||||
|               mklink /J "Models" "..\Fab2ApprovalSystem\Models" | ||||
|               mklink /J "PdfGenerator" "..\Fab2ApprovalSystem\PdfGenerator" | ||||
|               mklink /J "Utilities" "..\Fab2ApprovalSystem\Utilities" | ||||
|               mklink /J "ViewModels" "..\Fab2ApprovalSystem\ViewModels" | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Symbolic Link of Type Junction" | ||||
|  | ||||
|           - script: | | ||||
|               dotnet user-secrets init | ||||
|               dotnet user-secrets set BuildNumber $(Build.BuildId) | ||||
|               dotnet user-secrets set "GitCommit" "$(Build.SourceVersion)" | ||||
|               dotnet user-secrets list | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Safe storage of app secrets" | ||||
|  | ||||
|           - script: dotnet build --configuration $(Configuration) --source $(NugetSource) | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Build" | ||||
|  | ||||
|           - script: dotnet build --configuration $(Configuration) --source $(NugetSource) | ||||
|             workingDirectory: Fab2ApprovalTests | ||||
|             displayName: "Tests - Build" | ||||
|  | ||||
|           - script: dotnet test --configuration $(Configuration) | ||||
|             workingDirectory: Fab2ApprovalTests | ||||
|             displayName: "Tests - Test" | ||||
|  | ||||
|           - script: dotnet clean --configuration $(Configuration) | ||||
|             workingDirectory: Fab2ApprovalTests | ||||
|             displayName: "Tests - Clean" | ||||
|  | ||||
|           - script: dotnet clean --configuration $(Configuration) | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Clean" | ||||
|  | ||||
|       - job: DebugMicrosoftBuildEngine | ||||
|         steps: | ||||
|           - script: | | ||||
|               echo BuildId: $(Build.BuildId) | ||||
|               echo Build reason: $(Build.Reason) | ||||
|               echo Repo Id: $(Build.Repository.Id) | ||||
|               echo Repo name: $(Build.Repository.Name) | ||||
|               echo Source version: $(Build.SourceVersion) | ||||
|               echo Core version: $(CoreVersion) | ||||
|               echo Configuration: $(Configuration) | ||||
|               echo Target Framework version: $(TargetFrameworkVersion) | ||||
|               echo Assembly title: $(AssemblyTitle) | ||||
|               echo MicrosoftBuildEngine: $(msBuild) | ||||
|               echo NugetSource: $(NugetSource) | ||||
|             displayName: "Echo Check" | ||||
|  | ||||
|           - script: '"$(msBuild)" /target:Restore /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:RestoreSources=$(NugetSource) $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Restore" | ||||
|  | ||||
|           - script: '"$(msBuild)" /target:Build /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Build" | ||||
|  | ||||
|           - script: '"$(msBuild)" /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:DebugSymbols=false /p:DeleteExistingFiles=true /p:DeployOnBuild=true /p:EnableUpdateAble=true /p:ExcludeApp_Data=true /p:LastUsedconfiguration=$(Configuration) /p:LastUsedPlatform="Any CPU" /p:LaunchSiteAfterPublish=true /p:OutputPath=bin/$(Configuration) /p:PreCompileBeforePublish=true /p:PublishProvider=FileSystem /p:PublishUrl="D:/PublishUrl" /p:SiteUrlToLaunchAfterPublish="" /p:WDPMergeOption=DoNotMerge /p:WebPublishMethod=FileSystem $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Package (.zip for msdeploy.exe)" | ||||
|  | ||||
|           - task: CopyFiles@2 | ||||
|             displayName: 'Copy Files to: D:\' | ||||
|             inputs: | ||||
|               Contents: "*" | ||||
|               SourceFolder: '$(AssemblyTitle)\bin\$(Configuration)\_PublishedWebsites\$(AssemblyTitle)_Package' | ||||
|               TargetFolder: 'D:\$(TargetFrameworkVersion)\$(Build.Repository.Name)\$(Build.BuildId)\$(Configuration)-$(AssemblyTitle)-Package' | ||||
|               OverWrite: true | ||||
|  | ||||
|           - script: '"$(msBuild)" /target:Clean /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Clean" | ||||
|  | ||||
|   - stage: Release | ||||
|     displayName: Release | ||||
|     pool: | ||||
|       name: MesaFabApproval | ||||
|       demands: Fab2ApprovalSystem | ||||
|     variables: | ||||
|       ASPNETCORE_ENVIRONMENT: "Production" | ||||
|       assemblyTitle: "Fab2ApprovalSystem" | ||||
|       configuration: "Release" | ||||
|     jobs: | ||||
|       - job: ReleaseDotnet | ||||
|         steps: | ||||
|           - script: | | ||||
|               echo BuildId: $(Build.BuildId) | ||||
|               echo Build reason: $(Build.Reason) | ||||
|               echo Repo Id: $(Build.Repository.Id) | ||||
|               echo Repo name: $(Build.Repository.Name) | ||||
|               echo Source version: $(Build.SourceVersion) | ||||
|               echo Core version: $(CoreVersion) | ||||
|               echo Configuration: $(Configuration) | ||||
|               echo Target Framework version: $(TargetFrameworkVersion) | ||||
|               echo Assembly title: $(AssemblyTitle) | ||||
|               echo MicrosoftBuildEngine: $(msBuild) | ||||
|               echo NugetSource: $(NugetSource) | ||||
|             displayName: "Echo Check" | ||||
|  | ||||
|           - script: | | ||||
|               mklink /J ".vscode\.UserSecrets" "%AppData%\Microsoft\UserSecrets\f2da5035-aba9-4676-9f8d-d6689f84663d" | ||||
|               mklink /J "DMO" "..\Fab2ApprovalSystem\DMO" | ||||
|               mklink /J "Jobs" "..\Fab2ApprovalSystem\Jobs" | ||||
|               mklink /J "JobSchedules" "..\Fab2ApprovalSystem\JobSchedules" | ||||
|               mklink /J "Misc" "..\Fab2ApprovalSystem\Misc" | ||||
|               mklink /J "Models" "..\Fab2ApprovalSystem\Models" | ||||
|               mklink /J "PdfGenerator" "..\Fab2ApprovalSystem\PdfGenerator" | ||||
|               mklink /J "Utilities" "..\Fab2ApprovalSystem\Utilities" | ||||
|               mklink /J "ViewModels" "..\Fab2ApprovalSystem\ViewModels" | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Symbolic Link of Type Junction" | ||||
|  | ||||
|           - script: | | ||||
|               dotnet user-secrets init | ||||
|               dotnet user-secrets set BuildNumber $(Build.BuildId) | ||||
|               dotnet user-secrets set "GitCommit" "$(Build.SourceVersion)" | ||||
|               dotnet user-secrets list | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Safe storage of app secrets" | ||||
|  | ||||
|           - script: dotnet build --configuration $(Configuration) --source $(NugetSource) | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Build" | ||||
|  | ||||
|           - script: dotnet build --configuration $(Configuration) --source $(NugetSource) | ||||
|             workingDirectory: Fab2ApprovalTests | ||||
|             displayName: "Tests - Build" | ||||
|  | ||||
|           - script: dotnet test --configuration $(Configuration) | ||||
|             workingDirectory: Fab2ApprovalTests | ||||
|             displayName: "Tests - Test" | ||||
|  | ||||
|           - script: dotnet clean --configuration $(Configuration) | ||||
|             workingDirectory: Fab2ApprovalTests | ||||
|             displayName: "Tests - Clean" | ||||
|  | ||||
|           - script: dotnet clean --configuration $(Configuration) | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Clean" | ||||
|  | ||||
|       - job: ReleaseMicrosoftBuildEngine | ||||
|         steps: | ||||
|           - script: | | ||||
|               echo BuildId: $(Build.BuildId) | ||||
|               echo Build reason: $(Build.Reason) | ||||
|               echo Repo Id: $(Build.Repository.Id) | ||||
|               echo Repo name: $(Build.Repository.Name) | ||||
|               echo Source version: $(Build.SourceVersion) | ||||
|               echo Core version: $(CoreVersion) | ||||
|               echo Configuration: $(Configuration) | ||||
|               echo Target Framework version: $(TargetFrameworkVersion) | ||||
|               echo Assembly title: $(AssemblyTitle) | ||||
|               echo MicrosoftBuildEngine: $(msBuild) | ||||
|               echo NugetSource: $(NugetSource) | ||||
|             displayName: "Echo Check" | ||||
|  | ||||
|           - script: '"$(msBuild)" /target:Restore /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:RestoreSources=$(NugetSource) $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Restore" | ||||
|  | ||||
|           - script: '"$(msBuild)" /target:Build /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Build" | ||||
|  | ||||
|           - script: '"$(msBuild)" /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:DebugSymbols=false /p:DeleteExistingFiles=true /p:DeployOnBuild=true /p:EnableUpdateAble=true /p:ExcludeApp_Data=true /p:LastUsedconfiguration=$(Configuration) /p:LastUsedPlatform="Any CPU" /p:LaunchSiteAfterPublish=true /p:OutputPath=bin/$(Configuration) /p:PreCompileBeforePublish=true /p:PublishProvider=FileSystem /p:PublishUrl="D:/PublishUrl" /p:SiteUrlToLaunchAfterPublish="" /p:WDPMergeOption=DoNotMerge /p:WebPublishMethod=FileSystem $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Package (.zip for msdeploy.exe)" | ||||
|  | ||||
|           - task: CopyFiles@2 | ||||
|             displayName: 'Copy Files to: D:\' | ||||
|             inputs: | ||||
|               Contents: "*" | ||||
|               SourceFolder: '$(AssemblyTitle)\bin\$(Configuration)\_PublishedWebsites\$(AssemblyTitle)_Package' | ||||
|               TargetFolder: 'D:\$(TargetFrameworkVersion)\$(Build.Repository.Name)\$(Build.BuildId)\$(Configuration)-$(AssemblyTitle)-Package' | ||||
|               OverWrite: true | ||||
|  | ||||
|           - script: '"$(msBuild)" /target:Clean /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Clean" | ||||
|  | ||||
|           - script: 'echo $(Build.BuildId)-$(Build.SourceVersion)-bin_x_x_\$(Configuration)\$(CoreVersion)\win-x64\$(Build.Repository.Name).txt' | ||||
|             displayName: "Force Fail" | ||||
|             enabled: true | ||||
							
								
								
									
										239
									
								
								Fab2ApprovalSystem/pipelines.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										239
									
								
								Fab2ApprovalSystem/pipelines.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,239 @@ | ||||
| trigger: | ||||
|   branches: | ||||
|     include: | ||||
|       - master | ||||
|   paths: | ||||
|     include: | ||||
|       - "Fab2ApprovalSystem/*" | ||||
|     exclude: | ||||
|       - "**/*.yaml" | ||||
|       - "**/*.yml" | ||||
|       - "SQL/*" | ||||
|       - "references/*" | ||||
|       - "packages/*" | ||||
|       - "Kendo/*" | ||||
|  | ||||
| variables: | ||||
|   coreVersion: "net8.0" | ||||
|   targetFrameworkVersion: "v4.8" | ||||
|   nugetSource: "https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/" | ||||
|   msBuild: "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" | ||||
|  | ||||
| stages: | ||||
|   - stage: Development | ||||
|     displayName: Development | ||||
|     pool: | ||||
|       name: MesaFabApproval | ||||
|       demands: Fab2ApprovalSystem-Dev | ||||
|     variables: | ||||
|       ASPNETCORE_ENVIRONMENT: "Development" | ||||
|       assemblyTitle: "Fab2ApprovalSystem" | ||||
|       configuration: "Debug" | ||||
|     jobs: | ||||
|       - job: DebugDotnet | ||||
|         steps: | ||||
|           - script: | | ||||
|               echo BuildId: $(Build.BuildId) | ||||
|               echo Build reason: $(Build.Reason) | ||||
|               echo Repo Id: $(Build.Repository.Id) | ||||
|               echo Repo name: $(Build.Repository.Name) | ||||
|               echo Source version: $(Build.SourceVersion) | ||||
|               echo Core version: $(CoreVersion) | ||||
|               echo Configuration: $(Configuration) | ||||
|               echo Target Framework version: $(TargetFrameworkVersion) | ||||
|               echo Assembly title: $(AssemblyTitle) | ||||
|               echo MicrosoftBuildEngine: $(msBuild) | ||||
|               echo NugetSource: $(NugetSource) | ||||
|             displayName: "Echo Check" | ||||
|  | ||||
|           - script: | | ||||
|               mklink /J ".vscode\.UserSecrets" "%AppData%\Microsoft\UserSecrets\f2da5035-aba9-4676-9f8d-d6689f84663d" | ||||
|               mklink /J "DMO" "..\Fab2ApprovalSystem\DMO" | ||||
|               mklink /J "Jobs" "..\Fab2ApprovalSystem\Jobs" | ||||
|               mklink /J "JobSchedules" "..\Fab2ApprovalSystem\JobSchedules" | ||||
|               mklink /J "Misc" "..\Fab2ApprovalSystem\Misc" | ||||
|               mklink /J "Models" "..\Fab2ApprovalSystem\Models" | ||||
|               mklink /J "PdfGenerator" "..\Fab2ApprovalSystem\PdfGenerator" | ||||
|               mklink /J "Utilities" "..\Fab2ApprovalSystem\Utilities" | ||||
|               mklink /J "ViewModels" "..\Fab2ApprovalSystem\ViewModels" | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Symbolic Link of Type Junction" | ||||
|  | ||||
|           - script: | | ||||
|               dotnet user-secrets init | ||||
|               dotnet user-secrets set BuildNumber $(Build.BuildId) | ||||
|               dotnet user-secrets set "GitCommit" "$(Build.SourceVersion)" | ||||
|               dotnet user-secrets list | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Safe storage of app secrets" | ||||
|  | ||||
|           - script: dotnet build --configuration $(Configuration) --source $(NugetSource) | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Build" | ||||
|  | ||||
|           - script: dotnet build --configuration $(Configuration) --source $(NugetSource) | ||||
|             workingDirectory: Fab2ApprovalTests | ||||
|             displayName: "Tests - Build" | ||||
|  | ||||
|           - script: dotnet test --configuration $(Configuration) | ||||
|             workingDirectory: Fab2ApprovalTests | ||||
|             displayName: "Tests - Test" | ||||
|  | ||||
|           - script: dotnet clean --configuration $(Configuration) | ||||
|             workingDirectory: Fab2ApprovalTests | ||||
|             displayName: "Tests - Clean" | ||||
|  | ||||
|           - script: dotnet clean --configuration $(Configuration) | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Clean" | ||||
|  | ||||
|       - job: DebugMicrosoftBuildEngine | ||||
|         steps: | ||||
|           - script: | | ||||
|               echo BuildId: $(Build.BuildId) | ||||
|               echo Build reason: $(Build.Reason) | ||||
|               echo Repo Id: $(Build.Repository.Id) | ||||
|               echo Repo name: $(Build.Repository.Name) | ||||
|               echo Source version: $(Build.SourceVersion) | ||||
|               echo Core version: $(CoreVersion) | ||||
|               echo Configuration: $(Configuration) | ||||
|               echo Target Framework version: $(TargetFrameworkVersion) | ||||
|               echo Assembly title: $(AssemblyTitle) | ||||
|               echo MicrosoftBuildEngine: $(msBuild) | ||||
|               echo NugetSource: $(NugetSource) | ||||
|             displayName: "Echo Check" | ||||
|  | ||||
|           - script: '"$(msBuild)" /target:Restore /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:RestoreSources=$(NugetSource) $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Restore" | ||||
|  | ||||
|           - script: '"$(msBuild)" /target:Build /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Build" | ||||
|  | ||||
|           - script: '"$(msBuild)" /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:DebugSymbols=false /p:DeleteExistingFiles=true /p:DeployOnBuild=true /p:EnableUpdateAble=true /p:ExcludeApp_Data=true /p:LastUsedconfiguration=$(Configuration) /p:LastUsedPlatform="Any CPU" /p:LaunchSiteAfterPublish=true /p:OutputPath=bin/$(Configuration) /p:PreCompileBeforePublish=true /p:PublishProvider=FileSystem /p:PublishUrl="D:/PublishUrl" /p:SiteUrlToLaunchAfterPublish="" /p:WDPMergeOption=DoNotMerge /p:WebPublishMethod=FileSystem $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Package (.zip for msdeploy.exe)" | ||||
|  | ||||
|           - task: CopyFiles@2 | ||||
|             displayName: 'Copy Files to: D:\' | ||||
|             inputs: | ||||
|               Contents: "*" | ||||
|               SourceFolder: '$(AssemblyTitle)\bin\$(Configuration)\_PublishedWebsites\$(AssemblyTitle)_Package' | ||||
|               TargetFolder: 'D:\$(TargetFrameworkVersion)\$(Build.Repository.Name)\$(Build.BuildId)\$(Configuration)-$(AssemblyTitle)-Package' | ||||
|               OverWrite: true | ||||
|  | ||||
|           - script: '"$(msBuild)" /target:Clean /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Clean" | ||||
|  | ||||
|   - stage: Release | ||||
|     displayName: Release | ||||
|     pool: | ||||
|       name: MesaFabApproval | ||||
|       demands: Fab2ApprovalSystem | ||||
|     variables: | ||||
|       ASPNETCORE_ENVIRONMENT: "Production" | ||||
|       assemblyTitle: "Fab2ApprovalSystem" | ||||
|       configuration: "Release" | ||||
|     jobs: | ||||
|       - job: ReleaseDotnet | ||||
|         steps: | ||||
|           - script: | | ||||
|               echo BuildId: $(Build.BuildId) | ||||
|               echo Build reason: $(Build.Reason) | ||||
|               echo Repo Id: $(Build.Repository.Id) | ||||
|               echo Repo name: $(Build.Repository.Name) | ||||
|               echo Source version: $(Build.SourceVersion) | ||||
|               echo Core version: $(CoreVersion) | ||||
|               echo Configuration: $(Configuration) | ||||
|               echo Target Framework version: $(TargetFrameworkVersion) | ||||
|               echo Assembly title: $(AssemblyTitle) | ||||
|               echo MicrosoftBuildEngine: $(msBuild) | ||||
|               echo NugetSource: $(NugetSource) | ||||
|             displayName: "Echo Check" | ||||
|  | ||||
|           - script: | | ||||
|               mklink /J ".vscode\.UserSecrets" "%AppData%\Microsoft\UserSecrets\f2da5035-aba9-4676-9f8d-d6689f84663d" | ||||
|               mklink /J "DMO" "..\Fab2ApprovalSystem\DMO" | ||||
|               mklink /J "Jobs" "..\Fab2ApprovalSystem\Jobs" | ||||
|               mklink /J "JobSchedules" "..\Fab2ApprovalSystem\JobSchedules" | ||||
|               mklink /J "Misc" "..\Fab2ApprovalSystem\Misc" | ||||
|               mklink /J "Models" "..\Fab2ApprovalSystem\Models" | ||||
|               mklink /J "PdfGenerator" "..\Fab2ApprovalSystem\PdfGenerator" | ||||
|               mklink /J "Utilities" "..\Fab2ApprovalSystem\Utilities" | ||||
|               mklink /J "ViewModels" "..\Fab2ApprovalSystem\ViewModels" | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Symbolic Link of Type Junction" | ||||
|  | ||||
|           - script: | | ||||
|               dotnet user-secrets init | ||||
|               dotnet user-secrets set BuildNumber $(Build.BuildId) | ||||
|               dotnet user-secrets set "GitCommit" "$(Build.SourceVersion)" | ||||
|               dotnet user-secrets list | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Safe storage of app secrets" | ||||
|  | ||||
|           - script: dotnet build --configuration $(Configuration) --source $(NugetSource) | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Build" | ||||
|  | ||||
|           - script: dotnet build --configuration $(Configuration) --source $(NugetSource) | ||||
|             workingDirectory: Fab2ApprovalTests | ||||
|             displayName: "Tests - Build" | ||||
|  | ||||
|           - script: dotnet test --configuration $(Configuration) | ||||
|             workingDirectory: Fab2ApprovalTests | ||||
|             displayName: "Tests - Test" | ||||
|  | ||||
|           - script: dotnet clean --configuration $(Configuration) | ||||
|             workingDirectory: Fab2ApprovalTests | ||||
|             displayName: "Tests - Clean" | ||||
|  | ||||
|           - script: dotnet clean --configuration $(Configuration) | ||||
|             workingDirectory: Fab2ApprovalMKLink | ||||
|             displayName: "MKLink - Clean" | ||||
|  | ||||
|       - job: ReleaseMicrosoftBuildEngine | ||||
|         steps: | ||||
|           - script: | | ||||
|               echo BuildId: $(Build.BuildId) | ||||
|               echo Build reason: $(Build.Reason) | ||||
|               echo Repo Id: $(Build.Repository.Id) | ||||
|               echo Repo name: $(Build.Repository.Name) | ||||
|               echo Source version: $(Build.SourceVersion) | ||||
|               echo Core version: $(CoreVersion) | ||||
|               echo Configuration: $(Configuration) | ||||
|               echo Target Framework version: $(TargetFrameworkVersion) | ||||
|               echo Assembly title: $(AssemblyTitle) | ||||
|               echo MicrosoftBuildEngine: $(msBuild) | ||||
|               echo NugetSource: $(NugetSource) | ||||
|             displayName: "Echo Check" | ||||
|  | ||||
|           - script: '"$(msBuild)" /target:Restore /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:RestoreSources=$(NugetSource) $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Restore" | ||||
|  | ||||
|           - script: '"$(msBuild)" /target:Build /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Build" | ||||
|  | ||||
|           - script: '"$(msBuild)" /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) /p:DebugSymbols=false /p:DeleteExistingFiles=true /p:DeployOnBuild=true /p:EnableUpdateAble=true /p:ExcludeApp_Data=true /p:LastUsedconfiguration=$(Configuration) /p:LastUsedPlatform="Any CPU" /p:LaunchSiteAfterPublish=true /p:OutputPath=bin/$(Configuration) /p:PreCompileBeforePublish=true /p:PublishProvider=FileSystem /p:PublishUrl="D:/PublishUrl" /p:SiteUrlToLaunchAfterPublish="" /p:WDPMergeOption=DoNotMerge /p:WebPublishMethod=FileSystem $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Package (.zip for msdeploy.exe)" | ||||
|  | ||||
|           - task: CopyFiles@2 | ||||
|             displayName: 'Copy Files to: D:\' | ||||
|             inputs: | ||||
|               Contents: "*" | ||||
|               SourceFolder: '$(AssemblyTitle)\bin\$(Configuration)\_PublishedWebsites\$(AssemblyTitle)_Package' | ||||
|               TargetFolder: 'D:\$(TargetFrameworkVersion)\$(Build.Repository.Name)\$(Build.BuildId)\$(Configuration)-$(AssemblyTitle)-Package' | ||||
|               OverWrite: true | ||||
|  | ||||
|           - script: '"$(msBuild)" /target:Clean /DetailedSummary /ConsoleLoggerParameters:PerformanceSummary;ErrorsOnly; /p:Configuration=$(Configuration);TargetFrameworkVersion=$(TargetFrameworkVersion) $(AssemblyTitle).csproj' | ||||
|             workingDirectory: Fab2ApprovalSystem | ||||
|             displayName: "Framework - Clean" | ||||
|  | ||||
|           - script: 'echo $(Build.BuildId)-$(Build.SourceVersion)-bin_x_x_\$(Configuration)\$(CoreVersion)\win-x64\$(Build.Repository.Name).txt' | ||||
|             displayName: "Force Fail" | ||||
|             enabled: true | ||||
| @ -54,7 +54,7 @@ public class HomeControllerTests { | ||||
|  | ||||
|     private static void GetMyOpenActionItems(ILogger? logger, AppSettings appSettings) { | ||||
|         SetGlobalVars(logger, appSettings); | ||||
|         LotDispositionDMO lotDispositionDMO = new(appSettings); | ||||
|         LotDispositionDMO lotDispositionDMO = new(); | ||||
|         OpenActionItemViewModel[] openActionItemViewModels = lotDispositionDMO.GetMyOpenActionItems(appSettings.UserId).ToArray(); | ||||
|         if (openActionItemViewModels.Length == 0) { } | ||||
|     } | ||||
| @ -76,7 +76,7 @@ public class HomeControllerTests { | ||||
|  | ||||
|     private static void GetTaskList(ILogger? logger, AppSettings appSettings) { | ||||
|         SetGlobalVars(logger, appSettings); | ||||
|         LotDispositionDMO lotDispositionDMO = new(appSettings); | ||||
|         LotDispositionDMO lotDispositionDMO = new(); | ||||
|         IssuesViewModel[] issuesViewModels = lotDispositionDMO.GetTaskList(appSettings.UserId).ToArray(); | ||||
|         if (issuesViewModels.Length == 0) { } | ||||
|     } | ||||
|  | ||||
| @ -56,8 +56,8 @@ public class AdminDMOTests { | ||||
|         AdminDMO adminDMO = new(); | ||||
|         // void AddNewTrainingGroup(string groupName); | ||||
|         // void AddUserRoles(int subRole, string userids); | ||||
|         // void AddUserToGroup(int userId, int groupId); | ||||
|         // void DeleteFromGroup(int userId, int groupId); | ||||
|         // void AddUserToGroup(appSettings.UserId, int groupId); | ||||
|         // void DeleteFromGroup(appSettings.UserId, int groupId); | ||||
|         // void DeleteTrainingGroup(int groupID); | ||||
|         // adminDMO.DeleteUserFromAllTrainingGroups(appSettings.UserId); | ||||
|         // void DeleteUserRoles(int subRole, string userids); | ||||
|  | ||||
| @ -51,7 +51,7 @@ public class AuditDMOTests { | ||||
|         try { throw new Exception(); } catch (Exception) { } | ||||
|     } | ||||
|  | ||||
|     private static void AuditDMO(ILogger? logger, AppSettings appSettings) { | ||||
|     private static void AuditDMO(ILogger? logger, AppSettings appSettings, int auditNo, bool isAdmin) { | ||||
| #pragma warning disable IDE0059 | ||||
|         SetGlobalVars(logger, appSettings); | ||||
|         AuditDMO auditDMO = new(appSettings); | ||||
| @ -61,25 +61,25 @@ public class AuditDMOTests { | ||||
|         AuditedArea[] auditedAreas = auditDMO.GetAuditAreaList().ToArray(); | ||||
|         // IEnumerable<int> GetAuditFindingCategoryIdsByFindingId(int auditFindingsID); | ||||
|         // AuditFindings GetAuditFindingsByID(int auditFindingsID); | ||||
|         // IEnumerable<AuditFindings> GetAuditFindingsList(int auditNo); | ||||
|         // Audit GetAuditItem(int auditNo, int userID); | ||||
|         // Audit GetAuditItemReadOnly(int auditNo, int userID); | ||||
|         AuditFindings[] auditFindings = auditDMO.GetAuditFindingsList(auditNo).ToArray(); | ||||
|         Audit auditB = auditDMO.GetAuditItem(auditNo, appSettings.UserId); | ||||
|         Audit auditC = new(); | ||||
|         AuditEdit auditEdit = auditDMO.GetAuditEdit(auditNo, auditC, isAdmin, appSettings.UserId); | ||||
|         Audit auditD = auditDMO.GetAuditItemReadOnly(auditNo, appSettings.UserId); | ||||
|         Auditor[] auditors = auditDMO.GetAuditorList().ToArray(); | ||||
|         // IEnumerable<AuditReportAttachment> GetAuditReportAttachments(int auditNo); | ||||
|         AuditReportAttachment[] auditReportAttachments = auditDMO.GetAuditReportAttachments(auditNo).ToArray(); | ||||
|         // C_8DAuditedStandard[] c_8DAuditedStandards = auditDMO.GetAuditStandardList().ToArray(); | ||||
|         AuditType[] auditTypes = auditDMO.GetAuditTypeList().ToArray(); | ||||
|         // CAFindings GetCAFindingsItem(int caFindingsID); | ||||
|         // IEnumerable<AuditReportAttachment> GetCAFindingsItemAttachments(int caFindingsID); | ||||
|         // IEnumerable<CAFindings> GetCAFindingsList(int auditNo); | ||||
|         CAFindings[] caFindings = auditDMO.GetCAFindingsList(auditNo).ToArray(); | ||||
|         CANoList[] cANoLists = auditDMO.GetCorrectiveActionNoList().ToArray(); | ||||
|         // int GetOpenCACountByAuditNo(int auditNo); | ||||
|         int openCACountByAuditNo = auditDMO.GetOpenCACountByAuditNo(auditNo); | ||||
|         CAUserList[] cAUserLists = auditDMO.GetUserList().ToArray(); | ||||
|         // Audit InsertAudit(Audit audit); | ||||
|         // void InsertAuditReportAttachment(AuditReportAttachment attach); | ||||
|         // void InsertCAFindings(CAFindings model); | ||||
|         // int IsCAAssignedToAudit(int CANo, int auditNo); | ||||
|         // void ReleaseLockOnDocument(int userID, int issueID); | ||||
|         // void UpdateAudit(Audit audit, int userID); | ||||
|         // void ReleaseLockOnDocument(appSettings.UserId, int issueID); | ||||
|         // void UpdateCAFindings(CAFindings model); | ||||
|         if (auditDMO is null) { } | ||||
| #pragma warning restore IDE0059 | ||||
| @ -89,13 +89,14 @@ public class AuditDMOTests { | ||||
|     [Ignore] | ||||
| #endif | ||||
|     [TestMethod] | ||||
|     public void AuditDMOIsAttachedOnly() { | ||||
|     [DataRow(250, true)] | ||||
|     public void AuditDMOIsAttachedOnly(int auditNo, bool isAdmin) { | ||||
|         _Logger?.LogInformation("Starting Web Application"); | ||||
|         IServiceProvider? serviceProvider = _WebApplicationFactory?.Services.CreateScope().ServiceProvider; | ||||
|         AppSettings? appSettings = serviceProvider?.GetRequiredService<AppSettings>(); | ||||
|         Assert.IsTrue(appSettings is not null); | ||||
|         if (System.Diagnostics.Debugger.IsAttached) | ||||
|             AuditDMO(_Logger, appSettings); | ||||
|             AuditDMO(_Logger, appSettings, auditNo, isAdmin); | ||||
|         _Logger?.LogInformation("{TestName} completed", _TestContext?.TestName); | ||||
|         NonThrowTryCatch(); | ||||
|     } | ||||
|  | ||||
| @ -53,12 +53,12 @@ public class ChangeControlDMOTests { | ||||
|     private static void ChangeControlDMO(ILogger? logger, AppSettings appSettings) { | ||||
| #pragma warning disable IDE0059 | ||||
|         SetGlobalVars(logger, appSettings); | ||||
|         ChangeControlDMO changeControlDMO = new(appSettings); | ||||
|         ChangeControlDMO changeControlDMO = new(); | ||||
|         // IEnumerable<CCAttachment> GetCCAttachment(int planNumber); | ||||
|         // IEnumerable<CCMeetingAttachment> GetMeetingAttachments(int meetingID); | ||||
|         // IEnumerable<MeetingDecisionSummaryList> GetMeetingDecisionSummaryList(int planNumber); | ||||
|         // IEnumerable<CCMeeting> GetMeetingList(int planNumber); | ||||
|         // void ReassignOwner(int planNumber, int newOwnerID, string comments, int userID); | ||||
|         // void ReassignOwner(int planNumber, int newOwnerID, string comments, appSettings.UserId); | ||||
|         if (changeControlDMO is null) { } | ||||
| #pragma warning restore IDE0059 | ||||
|     } | ||||
|  | ||||
| @ -55,8 +55,8 @@ public class CorrectiveActionDMOTests { | ||||
|     private static void CorrectiveActionDMO(ILogger? logger, AppSettings appSettings) { | ||||
| #pragma warning disable IDE0059 | ||||
|         SetGlobalVars(logger, appSettings); | ||||
|         CorrectiveActionDMO correctiveActionDMO = new(appSettings); | ||||
|         // void ApproveSection(int issueID, int userID, string DSection); | ||||
|         CorrectiveActionDMO correctiveActionDMO = new(); | ||||
|         // void ApproveSection(int issueID, appSettings.UserId, string DSection); | ||||
|         // void DeleteCAAttachment(int attachmentID); | ||||
|         // void DeleteD3ContainmentActionItem(int d3ContainmentActionID); | ||||
|         // void DeleteD5D6CorrectivetAction(int d5d6CAID); | ||||
| @ -67,8 +67,8 @@ public class CorrectiveActionDMOTests { | ||||
|         // IEnumerable<CA_Attachment> GetCAAttachmentsList(int caNo, string section); | ||||
|         CAD3D5D7Due[] cAD3D5D7Dues = correctiveActionDMO.GetCAD3D5D7Due().ToArray(); | ||||
|         // IEnumerable<CA_Attachment> GetCAFindingsItemAttachments(int caFindingsID); | ||||
|         // CorrectiveAction GetCAItem(int caNo, int userID); | ||||
|         // CorrectiveAction GetCAItemReadOnly(int caNo, int userID); | ||||
|         // CorrectiveAction GetCAItem(int caNo, appSettings.UserId); | ||||
|         // CorrectiveAction GetCAItemReadOnly(int caNo, appSettings.UserId); | ||||
|         // IEnumerable<CASectionApproval> GetCASectionApprovalLog(int caNo); | ||||
|         CASource[] cASources = correctiveActionDMO.GetCASourceList().ToArray(); | ||||
|         // IEnumerable<D3ContainmentAction> GetD3ContainmentActions(int caNo); | ||||
| @ -89,17 +89,17 @@ public class CorrectiveActionDMOTests { | ||||
|         // void InsertD3ContainmentAction(D3ContainmentAction model); | ||||
|         // void InsertD5D6CorrectivetAction(D5D6CorrectivetAction model); | ||||
|         // void InsertD7PreventiveAction(D7PreventiveAction model); | ||||
|         // bool IsAIAssignee(int userId, int caId); | ||||
|         // bool IsAIAssignee(appSettings.UserId, int caId); | ||||
|         // bool IsLastSectionApprover(int caNo, string dSection); | ||||
|         // bool IsUserSectionApprover(int issueId, int userId); | ||||
|         // void RejectSection(int issueID, int userID, string DSection, string comments); | ||||
|         // void ReleaseLockOnDocument(int userID, int issueID); | ||||
|         // bool IsUserSectionApprover(int issueId, appSettings.UserId); | ||||
|         // void RejectSection(int issueID, appSettings.UserId, string DSection, string comments); | ||||
|         // void ReleaseLockOnDocument(appSettings.UserId, int issueID); | ||||
|         // DateTime SetCAComplete(int issueID); | ||||
|         // DateTime SetCAD3DueDate(int issueID); | ||||
|         // DateTime SetCAD5D7DueDate(int issueID); | ||||
|         // void SetD3D5D7NotificationDate(int caNo, string section); | ||||
|         // int StartApproval(int issueID, int userID, int worlflowNumber); | ||||
|         // void StartSectionApproval(int issueID, int userID, string DSection); | ||||
|         // int StartApproval(int issueID, appSettings.UserId, int worlflowNumber); | ||||
|         // void StartSectionApproval(int issueID, appSettings.UserId, string DSection); | ||||
|         // void UpdateCorrectiveAction(CorrectiveAction model); | ||||
|         // void UpdateD3ContainmentAction(D3ContainmentAction model); | ||||
|         // void UpdateD5D6CorrectivetAction(D5D6CorrectivetAction model); | ||||
|  | ||||
| @ -58,30 +58,30 @@ public class EngChangeNoticeDMOTests { | ||||
|         ECN_DMO ecnDMO = new(); | ||||
|         // void CancelECN(int? ecnNumber); | ||||
|         // bool CanSubmitECN(int ecnNumber); | ||||
|         // void DeleteDocument(int ecnNumber, int userid, string ecnTypeString); | ||||
|         // void DeleteDocument(int ecnNumber, appSettings.UserId, string ecnTypeString); | ||||
|         // void DeleteECNAttachment(int attachmentID); | ||||
|         // bool ECNApproveCancelled_ExpiredDocument(int issueID, byte step, string comments, out bool lastStep, int userID, int documentType); | ||||
|         // void ECNResetTECNAtRejection(int ecnNumber, int userID, int docType); | ||||
|         // bool ECNApproveCancelled_ExpiredDocument(int issueID, byte step, string comments, out bool lastStep, appSettings.UserId, int documentType); | ||||
|         // void ECNResetTECNAtRejection(int ecnNumber, appSettings.UserId, int docType); | ||||
|         IssuesViewModel[] issuesViewModels = ecnDMO.GetAllTECNs().ToArray(); | ||||
|         // IEnumerable<ApprovalLogHistory> GetECNApprovalLogHistory(int ecnNumber); | ||||
|         // IEnumerable<ECNAttachment> GetECNAttachments(int ecnNumber); | ||||
|         IssuesViewModel[] issuesViewModelsB = ecnDMO.GetECN_TECNPendingApprovals(appSettings.UserId).ToArray(); | ||||
|         // string GetFileName(string attachmentID); | ||||
|         // IEnumerable<IssuesViewModel> GetMyConvertedTECNsToECNs(int userID, int maxDays); | ||||
|         // IEnumerable<IssuesViewModel> GetMyExpiredTECNs(int userID, int maxDays); | ||||
|         // IEnumerable<IssuesViewModel> GetMyExpiringTECNs(int userID, int maxDays); | ||||
|         // IEnumerable<IssuesViewModel> GetMyConvertedTECNsToECNs(appSettings.UserId, int maxDays); | ||||
|         // IEnumerable<IssuesViewModel> GetMyExpiredTECNs(appSettings.UserId, int maxDays); | ||||
|         // IEnumerable<IssuesViewModel> GetMyExpiringTECNs(appSettings.UserId, int maxDays); | ||||
|         // List<string> GetRejectionOrginatorEmailList(int ecnNumber); | ||||
|         int[] ints = ecnDMO.GetTECNNotificationUsers().ToArray(); | ||||
|         // void InsertECNAttachment(ECNAttachment attach); | ||||
|         // int PCRBExists(int pcrb); | ||||
|         // void ReassignOriginatorECN(int ecnNumber, int newOriginatorID, string comments, int userID); | ||||
|         // void ReleaseLockOnDocument(int userID, int issueID); | ||||
|         // int ReSubmitDocument(int issueID, int userID, int documentType, out int allowedITAR, string descriptionOfChange, string reasonForChange, string ecnTypeString, out int newECNNumber, int categoryId); | ||||
|         // void ReassignOriginatorECN(int ecnNumber, int newOriginatorID, string comments, appSettings.UserId); | ||||
|         // void ReleaseLockOnDocument(appSettings.UserId, int issueID); | ||||
|         // int ReSubmitDocument(int issueID, appSettings.UserId, int documentType, out int allowedITAR, string descriptionOfChange, string reasonForChange, string ecnTypeString, out int newECNNumber, int categoryId); | ||||
|         // void SaveAfterSubmitByApprover(int ecnNumber, string implementationDetails); | ||||
|         // void SetToExecutionStep(int ecnNumber, int userid, int documentType, string ecnTypeString); | ||||
|         // int SubmitDocument(int issueID, int userID, int documentType, out int allowedITAR); | ||||
|         // int SubmitForCancellation(int issueID, byte currentStep, int userID, int documentType, string ecnType, int TECNOperationType); | ||||
|         // int SubmitTECNExtensionDocument(int issueID, int userID, int documentType, DateTime extensionDate); | ||||
|         // void SetToExecutionStep(int ecnNumber, appSettings.UserId, int documentType, string ecnTypeString); | ||||
|         // int SubmitDocument(int issueID, appSettings.UserId, int documentType, out int allowedITAR); | ||||
|         // int SubmitForCancellation(int issueID, byte currentStep, appSettings.UserId, int documentType, string ecnType, int TECNOperationType); | ||||
|         // int SubmitTECNExtensionDocument(int issueID, appSettings.UserId, int documentType, DateTime extensionDate); | ||||
|         // void TECNExtensionLog(int ecnNumber, DateTime extensionDate); | ||||
|         // void UpdateECNType(int ecnNumber, string ecnType); | ||||
|         if (ecnDMO is null) { } | ||||
|  | ||||
							
								
								
									
										120
									
								
								Fab2ApprovalTests/DMO/EngineeringChangeNoticeDMOTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								Fab2ApprovalTests/DMO/EngineeringChangeNoticeDMOTests.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,120 @@ | ||||
| using System; | ||||
| using System.Linq; | ||||
|  | ||||
| using Fab2ApprovalSystem.DMO; | ||||
| using Fab2ApprovalSystem.Models; | ||||
| using Fab2ApprovalSystem.ViewModels; | ||||
|  | ||||
| using Microsoft.AspNetCore.Mvc.Testing; | ||||
| using Microsoft.Extensions.DependencyInjection; | ||||
| using Microsoft.Extensions.Logging; | ||||
|  | ||||
| namespace Fab2ApprovalTests.DMO; | ||||
|  | ||||
| [TestClass] | ||||
| public class EngineeringChangeNoticeDMOTests { | ||||
|  | ||||
| #pragma warning disable CS8618 | ||||
|  | ||||
|     private static ILogger? _Logger; | ||||
|     private static TestContext _TestContext; | ||||
|     private static WebApplicationFactory<Fab2ApprovalMKLink.Program> _WebApplicationFactory; | ||||
|  | ||||
| #pragma warning restore | ||||
|  | ||||
|     public static void SetGlobalVars(ILogger? logger, AppSettings appSettings) { | ||||
|         logger?.LogDebug("Starting to set Fab2ApprovalSystem.Misc.GlobalVars"); | ||||
|         Fab2ApprovalSystem.Misc.GlobalVars.AppSettings = appSettings; | ||||
|         Fab2ApprovalSystem.Misc.GlobalVars.AttachmentUrl = appSettings.AttachmentUrl is null ? string.Empty : appSettings.AttachmentUrl; | ||||
|         Fab2ApprovalSystem.Misc.GlobalVars.CA_BlankFormsLocation = appSettings.CABlankFormsLocation; | ||||
|         Fab2ApprovalSystem.Misc.GlobalVars.DBConnection = appSettings.DBConnection; | ||||
|         Fab2ApprovalSystem.Misc.GlobalVars.DB_CONNECTION_STRING = appSettings.DBConnectionString; | ||||
|         Fab2ApprovalSystem.Misc.GlobalVars.hostURL = appSettings.HostURL; | ||||
|         Fab2ApprovalSystem.Misc.GlobalVars.IS_INFINEON_DOMAIN = appSettings.IsInfineonDomain; | ||||
|         Fab2ApprovalSystem.Misc.GlobalVars.MesaTemplateFiles = appSettings.MesaTemplateFiles; | ||||
|         Fab2ApprovalSystem.Misc.GlobalVars.NDriveURL = appSettings.NDriveURL; | ||||
|         Fab2ApprovalSystem.Misc.GlobalVars.SENDER_EMAIL = appSettings.SenderEmail; | ||||
|         Fab2ApprovalSystem.Misc.GlobalVars.USER_ID = appSettings.UserId; | ||||
|         Fab2ApprovalSystem.Misc.GlobalVars.USER_ISADMIN = appSettings.UserIsAdmin; | ||||
|         Fab2ApprovalSystem.Misc.GlobalVars.WSR_URL = appSettings.WSR_URL; | ||||
|         logger?.LogDebug("Finished setting Fab2ApprovalSystem.Misc.GlobalVars"); | ||||
|     } | ||||
|  | ||||
|     [ClassInitialize] | ||||
|     public static void ClassInitAsync(TestContext testContext) { | ||||
|         _TestContext = testContext; | ||||
|         _WebApplicationFactory = new WebApplicationFactory<Fab2ApprovalMKLink.Program>(); | ||||
|         IServiceProvider serviceProvider = _WebApplicationFactory.Services.CreateScope().ServiceProvider; | ||||
|         _Logger = serviceProvider.GetRequiredService<ILogger<Fab2ApprovalMKLink.Program>>(); | ||||
|     } | ||||
|  | ||||
|     private static void NonThrowTryCatch() { | ||||
|         try { throw new Exception(); } catch (Exception) { } | ||||
|     } | ||||
|  | ||||
|     private static void EngineeringChangeNoticeDMO(ILogger? logger, AppSettings appSettings, int maxDays, int ecnNumber) { | ||||
| #pragma warning disable IDE0059 | ||||
|         SetGlobalVars(logger, appSettings); | ||||
|         ECN_DMO ecnDMO = new(); | ||||
|         ECN ecn = ecnDMO.GetECN(ecnNumber); | ||||
|         // void CancelECN(int? ecnNumber); | ||||
|         bool canSubmitECN = ecnDMO.CanSubmitECN(ecnNumber); | ||||
|         // void DeleteDocument(int ecnNumber, appSettings.UserId, string ecnTypeString); | ||||
|         // void DeleteECNAttachment(int attachmentID); | ||||
|         // bool ECNApproveCancelled_ExpiredDocument(int issueID, byte step, string comments, out bool lastStep, appSettings.UserId, int documentType); | ||||
|         // void ECNResetTECNAtRejection(int ecnNumber, appSettings.UserId, int docType); | ||||
|         IssuesViewModel[] issuesViewModels = ecnDMO.GetAllTECNs().ToArray(); | ||||
|         ApprovalLogHistory[] approvalLogHistories = ecnDMO.GetECNApprovalLogHistory(ecnNumber).ToArray(); | ||||
|         ECNAttachment[] eCNAttachments = ecnDMO.GetECNAttachments(ecnNumber).ToArray(); | ||||
|         IssuesViewModel[] issuesViewModelsB = ecnDMO.GetECN_TECNPendingApprovals(appSettings.UserId).ToArray(); | ||||
|         // string GetFileName(string attachmentID); | ||||
|         IssuesViewModel[] issuesViewModelsC = ecnDMO.GetMyConvertedTECNsToECNs(appSettings.UserId, maxDays).ToArray(); | ||||
|         IssuesViewModel[] issuesViewModelsD = ecnDMO.GetMyExpiredTECNs(appSettings.UserId, maxDays).ToArray(); | ||||
|         IssuesViewModel[] issuesViewModelsE = ecnDMO.GetMyExpiringTECNs(appSettings.UserId, maxDays).ToArray(); | ||||
|         // List<string> GetRejectionOrginatorEmailList(int ecnNumber); | ||||
|         int[] ints = ecnDMO.GetTECNNotificationUsers().ToArray(); | ||||
|         // void InsertECNAttachment(ECNAttachment attach); | ||||
|         // int PCRBExists(int pcrb); | ||||
|         // void ReassignOriginatorECN(int ecnNumber, int newOriginatorID, string comments, appSettings.UserId); | ||||
|         // void ReleaseLockOnDocument(appSettings.UserId, int issueID); | ||||
|         // int ReSubmitDocument(int issueID, appSettings.UserId, int documentType, out int allowedITAR, string descriptionOfChange, string reasonForChange, string ecnTypeString, out int newECNNumber, int categoryId); | ||||
|         // void SaveAfterSubmitByApprover(int ecnNumber, string implementationDetails); | ||||
|         // void SetToExecutionStep(int ecnNumber, appSettings.UserId, int documentType, string ecnTypeString); | ||||
|         // int SubmitDocument(int issueID, appSettings.UserId, int documentType, out int allowedITAR); | ||||
|         // int SubmitForCancellation(int issueID, byte currentStep, appSettings.UserId, int documentType, string ecnType, int TECNOperationType); | ||||
|         // int SubmitTECNExtensionDocument(int issueID, appSettings.UserId, int documentType, DateTime extensionDate); | ||||
|         // void TECNExtensionLog(int ecnNumber, DateTime extensionDate); | ||||
|         // void UpdateECNType(int ecnNumber, string ecnType); | ||||
|         // ECN InsertECN(ECN ecn) | ||||
|         // void UpdateECN(ECN ecn) | ||||
|         // ECN GetECN(int ecnNumber, out int isITAR, int userID) | ||||
|         // ECN GetECNForRead(int ecnNumber, out int isITAR, int userID) | ||||
|         // ECNPdf GetECNPdf(int ecnNumber) | ||||
|         ECNAffectedDeparmtent[] departments = ecnDMO.GetDepartments().ToArray(); | ||||
|         ECNAffectedModule[] modules = ecnDMO.GetModules().ToArray(); | ||||
|         ECNCategory[] categories = ecnDMO.GetCategories().ToArray(); | ||||
|         ECNArea[] eCNAreas = ecnDMO.GetECNAreas().ToArray(); | ||||
|         ECNTechnology[] eCNTechnologies = ecnDMO.GetECNTechnologies().ToArray(); | ||||
|         ECNAcknowledgementTrainingBy[] eCNAcknowledgementTrainingBy = ecnDMO.GetECNAcknowledgementTrainingBy().ToArray(); | ||||
|         ProductFamilies[] productFamilies = ecnDMO.GetProductFamilies().ToArray(); | ||||
|         if (ecnDMO is null) { } | ||||
| #pragma warning restore IDE0059 | ||||
|     } | ||||
|  | ||||
| #if Release | ||||
|     [Ignore] | ||||
| #endif | ||||
|     [TestMethod] | ||||
|     [DataRow(1, 82700)] | ||||
|     public void EngineeringChangeNoticeIsAttachedOnlyDMO(int maxDays, int ecnNumber) { | ||||
|         _Logger?.LogInformation("Starting Web Application"); | ||||
|         IServiceProvider? serviceProvider = _WebApplicationFactory?.Services.CreateScope().ServiceProvider; | ||||
|         AppSettings? appSettings = serviceProvider?.GetRequiredService<AppSettings>(); | ||||
|         Assert.IsTrue(appSettings is not null); | ||||
|         if (System.Diagnostics.Debugger.IsAttached) | ||||
|             EngineeringChangeNoticeDMO(_Logger, appSettings, maxDays, ecnNumber); | ||||
|         _Logger?.LogInformation("{TestName} completed", _TestContext?.TestName); | ||||
|         NonThrowTryCatch(); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -55,9 +55,9 @@ public class LotDispositionDMOTests { | ||||
|     private static void LotDispositionDMO(ILogger? logger, AppSettings appSettings) { | ||||
| #pragma warning disable IDE0059 | ||||
|         SetGlobalVars(logger, appSettings); | ||||
|         LotDispositionDMO lotDispositionDMO = new(appSettings); | ||||
|         LotDispositionDMO lotDispositionDMO = new(); | ||||
|         // void DeleteAllLotDispoLot(int issueID); | ||||
|         // void DeleteCADocument(int CANo, int userID, string caTypeString); | ||||
|         // void DeleteCADocument(int CANo, appSettings.UserId, string caTypeString); | ||||
|         // void DeleteLotDispoAttachment(int attachmentID); | ||||
|         // void DeleteLotDispoLot(int lotID); | ||||
|         AuditList[] auditLists = lotDispositionDMO.GetAuditList(appSettings.UserId).ToArray(); | ||||
| @ -68,8 +68,8 @@ public class LotDispositionDMOTests { | ||||
|         IssuesViewModel[] issuesViewModelsB = lotDispositionDMO.GetECNList(appSettings.UserId).ToArray(); | ||||
|         // string GetFileName(string attachmentID); | ||||
|         // Attachment[] GetLotDispoAttachments(int issueID); | ||||
|         // LotDisposition GetLotDispositionItem(int issueID, out int isITAR, int userID); | ||||
|         // LotDisposition GetLotDispositionItemForRead(int issueID, out int isITAR, int userID); | ||||
|         // LotDisposition GetLotDispositionItem(int issueID, out int isITAR, appSettings.UserId); | ||||
|         // LotDisposition GetLotDispositionItemForRead(int issueID, out int isITAR, appSettings.UserId); | ||||
|         IssuesViewModel[] issuesViewModelsC = lotDispositionDMO.GetLotDispositionList(appSettings.UserId).ToArray(); | ||||
|         // Lot[] GetLotDispositionLots(int issueID); | ||||
|         // LotDispositionLotSummaryViewModel GetLotDispositionLotSummary(int issueID); | ||||
| @ -91,9 +91,9 @@ public class LotDispositionDMOTests { | ||||
|         // int InsertLot(Lot lot, bool getLotInfo); | ||||
|         // LotDisposition InsertLotDisposition(LotDisposition lotDispo); | ||||
|         // void InsertLotDispositionAttachment(Attachment attach); | ||||
|         // void ReleaseLockOnDocument(int userID, int issueID); | ||||
|         // void ReleaseLockOnDocument(appSettings.UserId, int issueID); | ||||
|         // Lot[] SearchLots(string searchText); | ||||
|         // int SubmitDocument(int issueID, bool peRequired, bool mrbRequired, int userID); | ||||
|         // int SubmitDocument(int issueID, bool peRequired, bool mrbRequired, appSettings.UserId); | ||||
|         // void UpdateLotDispoLot(Lot lot); | ||||
|         // void UpdateLotDisposition(LotDisposition lotDispo); | ||||
|         // void UpdateLotScrapReleaseStatus(ScrapLot scrap); | ||||
|  | ||||
| @ -53,17 +53,17 @@ public class LotTravelerDMOTests { | ||||
|     private static void LotTravelerDMO(ILogger? logger, AppSettings appSettings) { | ||||
| #pragma warning disable IDE0059 | ||||
|         SetGlobalVars(logger, appSettings); | ||||
|         LotTravelerDMO lotTravelerDMO = new(appSettings); | ||||
|         LotTravelerDMO lotTravelerDMO = new(); | ||||
|         // int CanAddLocationOperation(LTLotTravelerHoldSteps model); | ||||
|         // int CreateLotTravelerRevision(LTLotTravelerHoldSteps model, int userID); | ||||
|         // void CreateTraveler(int ltLotID, int workRequestID, int UserID); | ||||
|         // int CreateWorkRequestRevision(LTWorkRequest data, int userID); | ||||
|         // int CreateLotTravelerRevision(LTLotTravelerHoldSteps model, appSettings.UserId); | ||||
|         // void CreateTraveler(int ltLotID, int workRequestID, appSettings.UserId); | ||||
|         // int CreateWorkRequestRevision(LTWorkRequest data, appSettings.UserId); | ||||
|         // void DeleteLot(int ltLotID); | ||||
|         // IEnumerable<LTLot> GetLotList(int workRequestID); | ||||
|         // IEnumerable<LTLot> GetLotListBasedOnSWRNumber(int swrNumber); | ||||
|         // IEnumerable<LotWithTraveler> GetLotsWithTraveler(int workRequestID); | ||||
|         // LTLotTravelerHeaderViewModel GetLotTravelerHeaderForReadOnly(int ltLotID, int revisionNumber); | ||||
|         // LTLotTravelerHeaderViewModel GetLotTravelerHeaderForUpdate(int ltLotID, int UserID); | ||||
|         // LTLotTravelerHeaderViewModel GetLotTravelerHeaderForUpdate(int ltLotID, appSettings.UserId); | ||||
|         // IEnumerable<LTLotTravelerHoldSteps> GetLotTravelerHolStepsByRevision(int ltLotID, int revisionNumber); | ||||
|         // IEnumerable<RevisionHistory> GetLotTravelerRevisionHistory(int lotID); | ||||
|         // IEnumerable<LTLotTravelerHoldSteps> GetLotTravHoldSteps(int ltLotID); | ||||
| @ -76,15 +76,15 @@ public class LotTravelerDMOTests { | ||||
|         // IEnumerable<RevisionHistory> GetWorkReqRevisionHistory(int swrNumber); | ||||
|         // List<Revision> GetWorkReqRevisions(int swrNumber); | ||||
|         // void InsertLot(LTLot lot); | ||||
|         // int InsertLotTravelerHoldStep(LTLotTravelerHoldSteps model, int userID); | ||||
|         // void ReassignOriginator(int workRequestID, int newOriginatorID, string comments, int userID); | ||||
|         // void ReleaseLockOnDocument(int userID, int workRequestID); | ||||
|         // void ReleaseLockOnLotTravelerUpdateDoc(int userID, int ltLotID); | ||||
|         // int InsertLotTravelerHoldStep(LTLotTravelerHoldSteps model, appSettings.UserId); | ||||
|         // void ReassignOriginator(int workRequestID, int newOriginatorID, string comments, appSettings.UserId); | ||||
|         // void ReleaseLockOnDocument(appSettings.UserId, int workRequestID); | ||||
|         // void ReleaseLockOnLotTravelerUpdateDoc(appSettings.UserId, int ltLotID); | ||||
|         // void RestoreLotTravToPrevRevision(int prevLotTravRevID, int newLotTravRevID); | ||||
|         // int SubmitDocument(int workRequestID, int userID, int documentType, out int allowedITAR); | ||||
|         // int UpdateLotTravelerHoldStep(LTLotTravelerHoldSteps model, int userID); | ||||
|         // void UpdateLotTravlerExecution(int lotTravHoldStepID, string taskComments, bool CompletedFlag, int userID); | ||||
|         // int UpdateRevisedLotTravelerHoldStep(LTLotTravelerHoldSteps model, int userID); | ||||
|         // int SubmitDocument(int workRequestID, appSettings.UserId, int documentType, out int allowedITAR); | ||||
|         // int UpdateLotTravelerHoldStep(LTLotTravelerHoldSteps model, appSettings.UserId); | ||||
|         // void UpdateLotTravlerExecution(int lotTravHoldStepID, string taskComments, bool CompletedFlag, appSettings.UserId); | ||||
|         // int UpdateRevisedLotTravelerHoldStep(LTLotTravelerHoldSteps model, appSettings.UserId); | ||||
|         if (lotTravelerDMO is null) { } | ||||
| #pragma warning restore IDE0059 | ||||
|     } | ||||
|  | ||||
| @ -54,9 +54,9 @@ public class PartsRequestDMOTests { | ||||
|     private static void PartsRequestDMO(ILogger? logger, AppSettings appSettings) { | ||||
| #pragma warning disable IDE0059 | ||||
|         SetGlobalVars(logger, appSettings); | ||||
|         PartsRequestDMO partsRequestDMO = new(appSettings); | ||||
|         PartsRequestDMO partsRequestDMO = new(); | ||||
|         // void DeleteAttachment(int attachmentID); | ||||
|         // void DeleteDocument(int prNumber, int userid); | ||||
|         // void DeleteDocument(int prNumber, appSettings.UserId); | ||||
|         // PartsRequest Get(int PRNumber); | ||||
|         // IEnumerable<ApprovalLogHistory> GetApprovalLogHistory(int prNumber); | ||||
|         // IEnumerable<PartsRequestAttachmentList> GetAttachments(int prNumber); | ||||
| @ -65,7 +65,7 @@ public class PartsRequestDMOTests { | ||||
|         PartsRequestList[] partsRequestLists = partsRequestDMO.GetPartsRequestList().ToArray(); | ||||
|         // void Insert(PartsRequest pr); | ||||
|         // void InsertAttachment(PartsRequestAttachment attach); | ||||
|         // void Submit(int prNumber, int userID); | ||||
|         // void Submit(int prNumber, appSettings.UserId); | ||||
|         // void Update(PartsRequest pr); | ||||
|         if (partsRequestDMO is null) { } | ||||
| #pragma warning restore IDE0059 | ||||
|  | ||||
| @ -60,8 +60,8 @@ public class TrainingDMOTests { | ||||
|         // bool CheckTrainingStatus(int trainingAssignmentID); | ||||
|         // bool CheckValidDocAck(int docAckId); | ||||
|         // int Create(int issueId); | ||||
|         // int CreateAssignment(int trainingId, int userId); | ||||
|         // void DeleteAssignmentByUserId(int userId); | ||||
|         // int CreateAssignment(int trainingId, appSettings.UserId); | ||||
|         // void DeleteAssignmentByUserId(appSettings.UserId); | ||||
|         // void DeleteTraining(int trainingId); | ||||
|         // void DeleteTrainingAssignment(int trainingAssignmentId); | ||||
|         // void DeleteTrainingDocAck(int trainingAssignmentId); | ||||
| @ -75,15 +75,15 @@ public class TrainingDMOTests { | ||||
|         // List<int> GetTrainees(int groupId); | ||||
|         // Training GetTraining(int trainingId); | ||||
|         // List<TrainingAssignment> GetTrainingAssignments(int TrainingID); | ||||
|         // List<TrainingAssignment> GetTrainingAssignmentsByUser(int TrainingID, int userID); | ||||
|         // List<TrainingAssignment> GetTrainingAssignmentsByUserID(int userID); | ||||
|         // List<TrainingAssignment> GetTrainingAssignmentsByUser(int TrainingID, appSettings.UserId); | ||||
|         // List<TrainingAssignment> GetTrainingAssignmentsByUserID(appSettings.UserId); | ||||
|         // TrainingGroup GetTrainingGroupByID(int groupId); | ||||
|         // TrainingGroup[] trainingGroups = trainingDMO.GetTrainingGroups().ToArray(); | ||||
|         // int GetTrainingId(int issueId); | ||||
|         // int GetTrainingIdByAssignment(int trainingAssignmentID); | ||||
|         // Training[] trainingsC = trainingDMO.GetTrainings().ToArray(); | ||||
|         // bool IsUserAssigned(int userId, int trainingId); | ||||
|         // bool isUserTrainingMember(int groupId, int userId); | ||||
|         // bool IsUserAssigned(appSettings.UserId, int trainingId); | ||||
|         // bool isUserTrainingMember(int groupId, appSettings.UserId); | ||||
|         // void reOpenTraining(int trainingId); | ||||
|         // void SetTrainingFlag(int ECNNumber); | ||||
|         // void UpdateAssignmentStatus(int trainingAssignmentID); | ||||
|  | ||||
| @ -50,22 +50,25 @@ public class WorkflowDMOTests { | ||||
|         try { throw new Exception(); } catch (Exception) { } | ||||
|     } | ||||
|  | ||||
|     private static void WorkflowDMO(ILogger? logger, AppSettings appSettings) { | ||||
|     private static void WorkflowDMO(ILogger? logger, AppSettings appSettings, int issueID, string comments, int documentType) { | ||||
| #pragma warning disable IDE0059 | ||||
|         bool isLastStep; | ||||
|         SetGlobalVars(logger, appSettings); | ||||
|         ECN_DMO ecnDMO = new(); | ||||
|         ECN ecn = ecnDMO.GetECN(issueID); | ||||
|         WorkflowDMO workflowDMO = new();         | ||||
|         // string AddAdditionalApproval(int issueID, string userIDs, byte step, int documentType); | ||||
|         // string AddEECNApproval(int ecnNumber, byte step, int documentType, string engUserIDs, string opUserIDs); | ||||
|         // bool Approve(int issueID, byte step, string comments, out bool lastStep, int userID, int documentType, int workFlowNumber); | ||||
|         bool check = workflowDMO.Approve(appSettings, issueID, ecn.CurrentStep, comments, out isLastStep, appSettings.UserId, documentType, ecn.WorkFlowNumber); | ||||
|         // string DelegateDocumentApproval(int issueID, int delegateFromUser, int delegateToUser); | ||||
|         // string GetApproversForCancelled_ExpiredTECNDocs(int ecnNumber); | ||||
|         // string GetSubRoleItems(int issueID, int docType); | ||||
|         // string GetSubRolesForPartsRequestNextStep(int prNumber); | ||||
|         // WorkflowSteps GetWorkflowStep(int docTypeID, int wfNumber, int stepNumber); | ||||
|         // string ReAssignApproval(int issueID, int assignedFromUser, int assignedToUser, byte step, int docType); | ||||
|         // bool Recall(int issueID, byte step, string comments, int userID, int docType); | ||||
|         // bool Reject(int issueID, byte step, string comments, int userID, int docType); | ||||
|         // void RejectTECNExtension(int ecnNumber, byte step, string comments, int userID, int docType); | ||||
|         // bool Recall(int issueID, byte step, string comments, appSettings.UserId, int docType); | ||||
|         // bool Reject(int issueID, byte step, string comments, appSettings.UserId, int docType); | ||||
|         // void RejectTECNExtension(int ecnNumber, byte step, string comments, appSettings.UserId, int docType); | ||||
|         if (workflowDMO is null) { } | ||||
| #pragma warning restore IDE0059 | ||||
|     } | ||||
| @ -74,13 +77,14 @@ public class WorkflowDMOTests { | ||||
|     [Ignore] | ||||
| #endif | ||||
|     [TestMethod] | ||||
|     public void WorkflowDMOIsAttachedOnly() { | ||||
|     [DataRow(82700, "comment", 3)] | ||||
|     public void WorkflowDMOIsAttachedOnly(int issueID, string comments, int documentType) { | ||||
|         _Logger?.LogInformation("Starting Web Application"); | ||||
|         IServiceProvider? serviceProvider = _WebApplicationFactory?.Services.CreateScope().ServiceProvider; | ||||
|         AppSettings? appSettings = serviceProvider?.GetRequiredService<AppSettings>(); | ||||
|         Assert.IsTrue(appSettings is not null); | ||||
|         if (System.Diagnostics.Debugger.IsAttached) | ||||
|             WorkflowDMO(_Logger, appSettings); | ||||
|             WorkflowDMO(_Logger, appSettings, issueID, comments, documentType); | ||||
|         _Logger?.LogInformation("{TestName} completed", _TestContext?.TestName); | ||||
|         NonThrowTryCatch(); | ||||
|     } | ||||
|  | ||||
| @ -102,7 +102,7 @@ public class CorrectiveActionTests { | ||||
|     internal static void TestCorrectiveAction(ILogger? logger, AppSettings appSettings, int caNo) { | ||||
|         SetGlobalVars(logger, appSettings); | ||||
|         CorrectiveAction ca; | ||||
|         CorrectiveActionDMO caDMO = new(appSettings); | ||||
|         CorrectiveActionDMO caDMO = new(); | ||||
|         ca = caDMO.GetCAItemReadOnly(caNo, appSettings.UserId); | ||||
|         if (ca is null) | ||||
|             throw new Exception($"{nameof(ca)}"); | ||||
|  | ||||
							
								
								
									
										32
									
								
								MesaFabApproval.API.Test/MesaFabApproval.API.Test.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								MesaFabApproval.API.Test/MesaFabApproval.API.Test.csproj
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
|  | ||||
|   <PropertyGroup> | ||||
|     <TargetFramework>net8.0</TargetFramework> | ||||
|     <ImplicitUsings>enable</ImplicitUsings> | ||||
|     <Nullable>enable</Nullable> | ||||
|  | ||||
|     <IsPackable>false</IsPackable> | ||||
|     <IsTestProject>true</IsTestProject> | ||||
|   </PropertyGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="coverlet.collector" Version="6.0.0" /> | ||||
|     <PackageReference Include="Dapper" Version="2.1.66" /> | ||||
|     <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" /> | ||||
|     <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.2" /> | ||||
|     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" /> | ||||
|     <PackageReference Include="Moq" Version="4.20.72" /> | ||||
|     <PackageReference Include="xunit" Version="2.5.3" /> | ||||
|     <PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <Using Include="Xunit" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|     <ItemGroup> | ||||
|         <ProjectReference Include="..\MesaFabApproval.Shared\MesaFabApproval.Shared.csproj" /> | ||||
|         <ProjectReference Include="..\MesaFabApproval.API\MesaFabApproval.API.csproj" /> | ||||
|     </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
							
								
								
									
										63
									
								
								MesaFabApproval.API.Test/MonInUtilsTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								MesaFabApproval.API.Test/MonInUtilsTests.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | ||||
| using Moq; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using MesaFabApproval.API.Utilities; | ||||
| using MesaFabApproval.Shared.Models; | ||||
| using MesaFabApproval.Shared.Services; | ||||
|  | ||||
| namespace MesaFabApproval.API.Test; | ||||
|  | ||||
| public class MonInUtilsTests { | ||||
|     private readonly Mock<IMonInWorkerClient> _mockMonInClient; | ||||
|     private readonly Mock<ILogger<MonInUtils>> _mockLogger; | ||||
|     private readonly MonInUtils _monInUtils; | ||||
|  | ||||
|     public MonInUtilsTests() { | ||||
|         _mockMonInClient = new Mock<IMonInWorkerClient>(); | ||||
|         _mockMonInClient | ||||
|             .Setup(client => client.PostAverage(It.IsAny<string>(), It.IsAny<double>())) | ||||
|             .Verifiable(); | ||||
|  | ||||
|         _mockLogger = new Mock<ILogger<MonInUtils>>(); | ||||
|  | ||||
|         _monInUtils = new MonInUtils(_mockMonInClient.Object, _mockLogger.Object); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public void PostMetrics_ShouldPostAverageAndStatusOk_WhenNoErrors() { | ||||
|         string metricName = "TestMetric"; | ||||
|         double latency = 100; | ||||
|         bool isArgumentError = false; | ||||
|         bool isInternalError = false; | ||||
|  | ||||
|         _monInUtils.PostMetrics(metricName, latency, isArgumentError, isInternalError); | ||||
|  | ||||
|         _mockMonInClient.Verify(client => client.PostAverage(metricName + "Latency", latency), Times.Once); | ||||
|         _mockMonInClient.Verify(client => client.PostStatus(metricName, StatusValue.Ok), Times.Once); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public void PostMetrics_ShouldPostAverageAndStatusOk_WhenArgumentError() { | ||||
|         string metricName = "TestMetric"; | ||||
|         double latency = 100; | ||||
|         bool isArgumentError = true; | ||||
|         bool isInternalError = false; | ||||
|  | ||||
|         _monInUtils.PostMetrics(metricName, latency, isArgumentError, isInternalError); | ||||
|  | ||||
|         _mockMonInClient.Verify(client => client.PostAverage(metricName + "Latency", latency), Times.Once); | ||||
|         _mockMonInClient.Verify(client => client.PostStatus(metricName, StatusValue.Ok), Times.Once); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public void PostMetrics_ShouldPostAverageAndStatusCritical_WhenInternalError() { | ||||
|         string metricName = "TestMetric"; | ||||
|         double latency = 100; | ||||
|         bool isArgumentError = false; | ||||
|         bool isInternalError = true; | ||||
|  | ||||
|         _monInUtils.PostMetrics(metricName, latency, isArgumentError, isInternalError); | ||||
|  | ||||
|         _mockMonInClient.Verify(client => client.PostAverage(metricName + "Latency", latency), Times.Once); | ||||
|         _mockMonInClient.Verify(client => client.PostStatus(metricName, StatusValue.Critical), Times.Once); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										414
									
								
								MesaFabApproval.API.Test/PCRBServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										414
									
								
								MesaFabApproval.API.Test/PCRBServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,414 @@ | ||||
| using MesaFabApproval.API.Services; | ||||
| using MesaFabApproval.Models; | ||||
| using MesaFabApproval.Shared.Models; | ||||
|  | ||||
| using Microsoft.Extensions.Caching.Memory; | ||||
| using Microsoft.Extensions.Logging; | ||||
|  | ||||
| using Moq; | ||||
|  | ||||
| namespace MesaFabApproval.API.Test; | ||||
|  | ||||
| public static class MockMemoryCacheService { | ||||
|     public static Mock<IMemoryCache> GetMemoryCache(object expectedValue) { | ||||
|         Mock<IMemoryCache> mockMemoryCache = new Mock<IMemoryCache>(); | ||||
|         mockMemoryCache | ||||
|             .Setup(x => x.TryGetValue(It.IsAny<object>(), out expectedValue)) | ||||
|             .Returns(true); | ||||
|         mockMemoryCache | ||||
|             .Setup(x => x.CreateEntry(It.IsAny<object>())) | ||||
|             .Returns(Mock.Of<ICacheEntry>()); | ||||
|         return mockMemoryCache; | ||||
|     } | ||||
| } | ||||
|  | ||||
| public class PCRBServiceTests { | ||||
|     private readonly Mock<ILogger<PCRBService>> _loggerMock; | ||||
|     private readonly Mock<IDalService> _dalServiceMock; | ||||
|     private Mock<IMemoryCache> _cacheMock; | ||||
|     private readonly Mock<IUserService> _userServiceMock; | ||||
|     private readonly Mock<IApprovalService> _approvalServiceMock; | ||||
|     private readonly Mock<ISmtpService> _smtpServiceMock; | ||||
|     private PCRBService _pcrbService; | ||||
|  | ||||
|     private static IEnumerable<PCRB> PCRBS = new List<PCRB>() { | ||||
|         new PCRB { | ||||
|             PlanNumber = 1, | ||||
|             OwnerID = 1, | ||||
|             Title = "Test Title", | ||||
|             ChangeLevel = "Level 1", | ||||
|             ReasonForChange = "Test Reason", | ||||
|             ChangeDescription = "Test Description", | ||||
|             IsITAR = false, | ||||
|             CurrentStep = 1, | ||||
|             InsertTimeStamp = DateTime.Now, | ||||
|             LastUpdateDate = DateTime.Now, | ||||
|             Type = "Type 1" | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     private static IEnumerable<PCRBFollowUp> FOLLOW_UPS = new List<PCRBFollowUp>() {  | ||||
|         new PCRBFollowUp { ID = 1, PlanNumber = 1, Step = 1, FollowUpDate = DateTime.Now } | ||||
|     }; | ||||
|  | ||||
|     private static AppSettings appSettings = new AppSettings( | ||||
|             Company: "Infineon", | ||||
|             DbConnectionString: "connectionString", | ||||
|             JwtAudience: "audience", | ||||
|             JwtIssuer: "issuer", | ||||
|             JwtKey: "key", | ||||
|             MrbAttachmentPath: "mrbAttachmentPath", | ||||
|             PcrbAttachmentPath: "pcrbAttachmentPath", | ||||
|             ShouldSendEmail: false, | ||||
|             SiteBaseUrl: "siteBaseUrl", | ||||
|             WorkingDirectoryName: "workingDirectoryName" | ||||
|         ); | ||||
|  | ||||
|     public PCRBServiceTests() { | ||||
|         _loggerMock = new Mock<ILogger<PCRBService>>(); | ||||
|         _dalServiceMock = new Mock<IDalService>(); | ||||
|         _userServiceMock = new Mock<IUserService>(); | ||||
|         _approvalServiceMock = new Mock<IApprovalService>(); | ||||
|         _smtpServiceMock = new Mock<ISmtpService>(); | ||||
|         _cacheMock = MockMemoryCacheService.GetMemoryCache(FOLLOW_UPS); | ||||
|  | ||||
|         _pcrbService = new PCRBService( | ||||
|             _loggerMock.Object, | ||||
|             _dalServiceMock.Object, | ||||
|             _cacheMock.Object, | ||||
|             _userServiceMock.Object, | ||||
|             _approvalServiceMock.Object, | ||||
|             _smtpServiceMock.Object, | ||||
|             appSettings | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task CreateNewPCRB_WithValidParam_ShouldCreatePCRB() { | ||||
|         var pcrb = new PCRB { | ||||
|             OwnerID = 1, | ||||
|             Title = "Test Title", | ||||
|             ChangeLevel = "Level 1", | ||||
|             ReasonForChange = "Test Reason", | ||||
|             ChangeDescription = "Test Description", | ||||
|             IsITAR = false, | ||||
|             CurrentStep = 1, | ||||
|             InsertTimeStamp = DateTime.Now, | ||||
|             LastUpdateDate = DateTime.Now, | ||||
|             Type = "Type 1" | ||||
|         }; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb)) | ||||
|             .ReturnsAsync(1); | ||||
|  | ||||
|         await _pcrbService.CreateNewPCRB(pcrb); | ||||
|  | ||||
|         _dalServiceMock.Verify(d => d.ExecuteAsync(It.IsAny<string>(), pcrb), Times.Once); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task CreateNewPCRB_WithNullParam_ShouldThrowException() { | ||||
|         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.CreateNewPCRB(null)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task CreateNewPCRB_WithDatabaseFailure_ShouldThrowException() { | ||||
|         var pcrb = new PCRB { | ||||
|             OwnerID = 1, | ||||
|             Title = "Test Title", | ||||
|             ChangeLevel = "Level 1", | ||||
|             ReasonForChange = "Test Reason", | ||||
|             ChangeDescription = "Test Description", | ||||
|             IsITAR = false, | ||||
|             CurrentStep = 1, | ||||
|             InsertTimeStamp = DateTime.Now, | ||||
|             LastUpdateDate = DateTime.Now, | ||||
|             Type = "Type 1" | ||||
|         }; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb)) | ||||
|             .ReturnsAsync(0); | ||||
|  | ||||
|         await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateNewPCRB(pcrb)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task CreateNewPCRB_WithDatabaseException_ShouldThrowException() { | ||||
|         var pcrb = new PCRB { | ||||
|             OwnerID = 1, | ||||
|             Title = "Test Title", | ||||
|             ChangeLevel = "Level 1", | ||||
|             ReasonForChange = "Test Reason", | ||||
|             ChangeDescription = "Test Description", | ||||
|             IsITAR = false, | ||||
|             CurrentStep = 1, | ||||
|             InsertTimeStamp = DateTime.Now, | ||||
|             LastUpdateDate = DateTime.Now, | ||||
|             Type = "Type 1" | ||||
|         }; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb)) | ||||
|             .Throws<Exception>(); | ||||
|  | ||||
|         await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateNewPCRB(pcrb)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task UpdatePCRB_WithValidParam_ShouldUpdatePCRB() { | ||||
|         _cacheMock = MockMemoryCacheService.GetMemoryCache(PCRBS); | ||||
|  | ||||
|         _pcrbService = new PCRBService( | ||||
|             _loggerMock.Object, | ||||
|             _dalServiceMock.Object, | ||||
|             _cacheMock.Object, | ||||
|             _userServiceMock.Object, | ||||
|             _approvalServiceMock.Object, | ||||
|             _smtpServiceMock.Object, | ||||
|             appSettings | ||||
|         ); | ||||
|  | ||||
|         var pcrb = new PCRB { | ||||
|             PlanNumber = 1, | ||||
|             OwnerID = 1, | ||||
|             Title = "Test Title", | ||||
|             ChangeLevel = "Level 1", | ||||
|             ReasonForChange = "Test Reason", | ||||
|             ChangeDescription = "Test Description", | ||||
|             IsITAR = false, | ||||
|             CurrentStep = 1, | ||||
|             LastUpdateDate = DateTime.Now, | ||||
|             ClosedDate = DateTime.Now, | ||||
|             Type = "Type 1" | ||||
|         }; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb)) | ||||
|             .ReturnsAsync(1); | ||||
|  | ||||
|         await _pcrbService.UpdatePCRB(pcrb); | ||||
|  | ||||
|         _dalServiceMock.Verify(d => d.ExecuteAsync(It.IsAny<string>(), pcrb), Times.Once); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task UpdatePCRB_WithNullParam_ShouldThrowException() { | ||||
|         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.UpdatePCRB(null)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task UpdatePCRB_WithDatabaseFailure_ShouldThrowException() { | ||||
|         var pcrb = new PCRB { | ||||
|             PlanNumber = 1, | ||||
|             OwnerID = 1, | ||||
|             Title = "Test Title", | ||||
|             ChangeLevel = "Level 1", | ||||
|             ReasonForChange = "Test Reason", | ||||
|             ChangeDescription = "Test Description", | ||||
|             IsITAR = false, | ||||
|             CurrentStep = 1, | ||||
|             LastUpdateDate = DateTime.Now, | ||||
|             ClosedDate = DateTime.Now, | ||||
|             Type = "Type 1" | ||||
|         }; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb)) | ||||
|             .ReturnsAsync(0); | ||||
|  | ||||
|         await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdatePCRB(pcrb)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task UpdatePCRB_WithDatabaseException_ShouldThrowException() { | ||||
|         var pcrb = new PCRB { | ||||
|             PlanNumber = 1, | ||||
|             OwnerID = 1, | ||||
|             Title = "Test Title", | ||||
|             ChangeLevel = "Level 1", | ||||
|             ReasonForChange = "Test Reason", | ||||
|             ChangeDescription = "Test Description", | ||||
|             IsITAR = false, | ||||
|             CurrentStep = 1, | ||||
|             LastUpdateDate = DateTime.Now, | ||||
|             ClosedDate = DateTime.Now, | ||||
|             Type = "Type 1" | ||||
|         }; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), pcrb)) | ||||
|             .Throws<Exception>(); | ||||
|  | ||||
|         await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdatePCRB(pcrb)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task CreateFollowUp_WithValidParam_ShouldCreateFollowUp() { | ||||
|         var followUp = new PCRBFollowUp { | ||||
|             PlanNumber = 1, | ||||
|             Step = 1, | ||||
|             FollowUpDate = DateTime.Now | ||||
|         }; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp)) | ||||
|             .ReturnsAsync(1); | ||||
|  | ||||
|         await _pcrbService.CreateFollowUp(followUp); | ||||
|  | ||||
|         _dalServiceMock.Verify(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp), Times.Once); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task CreateFollowUp_WithNullParam_ShouldThrowException() { | ||||
|         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.CreateFollowUp(null)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task CreateFollowUp_WithDatabaseFailure_ShouldThrowException() { | ||||
|         var followUp = new PCRBFollowUp { | ||||
|             PlanNumber = 1, | ||||
|             Step = 1, | ||||
|             FollowUpDate = DateTime.Now | ||||
|         }; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp)) | ||||
|             .ReturnsAsync(0); | ||||
|  | ||||
|         await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUp(followUp)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task CreateFollowUp_WithDatabaseException_ShouldThrowException() { | ||||
|         var followUp = new PCRBFollowUp { | ||||
|             PlanNumber = 1, | ||||
|             Step = 1, | ||||
|             FollowUpDate = DateTime.Now | ||||
|         }; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp)) | ||||
|             .Throws<Exception>(); | ||||
|  | ||||
|         await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUp(followUp)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task GetFollowUpsByPlanNumber_WithCacheBypass_ShouldReturnFollowUps() { | ||||
|         int planNumber = 1; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.QueryAsync<PCRBFollowUp>(It.IsAny<string>(), It.IsAny<object>())) | ||||
|             .ReturnsAsync(FOLLOW_UPS); | ||||
|  | ||||
|         IEnumerable<PCRBFollowUp> result = await _pcrbService.GetFollowUpsByPlanNumber(planNumber, true); | ||||
|  | ||||
|         Assert.NotNull(result); | ||||
|         Assert.Single(result); | ||||
|         Assert.Equal(FOLLOW_UPS, result); | ||||
|         _dalServiceMock.Verify(d => d.QueryAsync<PCRBFollowUp>(It.IsAny<string>(), It.IsAny<object>()), Times.Once); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task GetFollowUpsByPlanNumber_WithCacheBypass_AndDatabaseException_ShouldThrowException() { | ||||
|         int planNumber = 1; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.QueryAsync<PCRBFollowUp>(It.IsAny<string>(), It.IsAny<object>())) | ||||
|             .Throws<Exception>(); | ||||
|  | ||||
|         await Assert.ThrowsAsync<Exception>(() => _pcrbService.GetFollowUpsByPlanNumber(planNumber, true)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task GetFollowUpsByPlanNumber_WithoutCacheBypass_ShouldReturnFollowUps() { | ||||
|         int planNumber = 1; | ||||
|  | ||||
|         IEnumerable<PCRBFollowUp> result = await _pcrbService.GetFollowUpsByPlanNumber(planNumber, false); | ||||
|  | ||||
|         Assert.NotNull(result); | ||||
|         Assert.Single(result); | ||||
|         Assert.Equal(FOLLOW_UPS, result); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task UpdateFollowUp_WithValidParam_ShouldUpdateFollowUp() { | ||||
|         var followUp = new PCRBFollowUp { | ||||
|             ID = 1, | ||||
|             PlanNumber = 1, | ||||
|             Step = 1, | ||||
|             FollowUpDate = DateTime.Now | ||||
|         }; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp)) | ||||
|             .ReturnsAsync(1); | ||||
|  | ||||
|         await _pcrbService.UpdateFollowUp(followUp); | ||||
|  | ||||
|         _dalServiceMock.Verify(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp), Times.Once); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task UpdateFollowUp_WithNullParam_ShouldThrowException() { | ||||
|         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.UpdateFollowUp(null)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task UpdateFollowUp_WithDatabaseFailure_ShouldThrowException() { | ||||
|         var followUp = new PCRBFollowUp { | ||||
|             ID = 1, | ||||
|             PlanNumber = 1, | ||||
|             Step = 1, | ||||
|             FollowUpDate = DateTime.Now | ||||
|         }; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp)) | ||||
|             .ReturnsAsync(0); | ||||
|  | ||||
|         await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUp(followUp)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task UpdateFollowUp_WithDatabaseException_ShouldThrowException() { | ||||
|         var followUp = new PCRBFollowUp { | ||||
|             ID = 1, | ||||
|             PlanNumber = 1, | ||||
|             Step = 1, | ||||
|             FollowUpDate = DateTime.Now | ||||
|         }; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.ExecuteAsync<PCRBFollowUp>(It.IsAny<string>(), followUp)) | ||||
|             .Throws<Exception>(); | ||||
|  | ||||
|         await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUp(followUp)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task DeleteFollowUp_WithValidId_ShouldDeleteFollowUp() { | ||||
|         int followUpId = 1; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>())) | ||||
|             .ReturnsAsync(1); | ||||
|  | ||||
|         await _pcrbService.DeleteFollowUp(followUpId); | ||||
|  | ||||
|         _dalServiceMock.Verify(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>()), Times.Once); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task DeleteFollowUp_WithInvalidId_ShouldThrowException() { | ||||
|         await Assert.ThrowsAsync<ArgumentException>(() => _pcrbService.DeleteFollowUp(0)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task DeleteFollowUp_WithDatabaseFailure_ShouldThrowException() { | ||||
|         int followUpId = 1; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>())) | ||||
|             .ReturnsAsync(0); | ||||
|  | ||||
|         await Assert.ThrowsAsync<Exception>(() => _pcrbService.DeleteFollowUp(followUpId)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task DeleteFollowUp_WithDatabaseException_ShouldThrowException() { | ||||
|         int followUpId = 1; | ||||
|  | ||||
|         _dalServiceMock.Setup(d => d.ExecuteAsync(It.IsAny<string>(), It.IsAny<object>())) | ||||
|             .Throws<Exception>(); | ||||
|  | ||||
|         await Assert.ThrowsAsync<Exception>(() => _pcrbService.DeleteFollowUp(followUpId)); | ||||
|     } | ||||
| } | ||||
| @ -15,6 +15,8 @@ public class SmtpClientWrapper : ISmtpClientWrapper { | ||||
|     } | ||||
|  | ||||
|     public void Send(MailMessage message) { | ||||
|         message.Subject = message.Subject.Replace('\r', ' ').Replace('\n', ' '); | ||||
|  | ||||
|         _client.Send(message); | ||||
|     } | ||||
| } | ||||
| @ -53,4 +53,36 @@ public class ECNController : ControllerBase { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     [HttpGet] | ||||
|     [Route("ecn/allNumbers")] | ||||
|     public async Task<IActionResult> GetAllECNNumbers() { | ||||
|         DateTime start = DateTime.Now; | ||||
|         bool isInternalError = false; | ||||
|         string errorMessage = ""; | ||||
|  | ||||
|         try { | ||||
|             _logger.LogInformation($"Attempting to get all ECN#s"); | ||||
|              | ||||
|             IEnumerable<int> allEcnNumbers = await _ecnService.GetAllECNNumbers(); | ||||
|  | ||||
|             return Ok(allEcnNumbers); | ||||
|         } catch (Exception ex) { | ||||
|             isInternalError = true; | ||||
|             errorMessage = $"Cannot get all ECN#s, because {ex.Message}"; | ||||
|             return Problem(errorMessage); | ||||
|         } finally { | ||||
|             string metricName = "GetAllECNNumbers"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -1,4 +1,5 @@ | ||||
| using MesaFabApproval.API.Services; | ||||
| using MesaFabApproval.API.Utilities; | ||||
| using MesaFabApproval.Shared.Models; | ||||
| using MesaFabApproval.Shared.Services; | ||||
|  | ||||
| @ -13,12 +14,12 @@ namespace MesaFabApproval.API.Controllers; | ||||
| public class PCRBController : ControllerBase { | ||||
|     private readonly ILogger<MRBController> _logger; | ||||
|     private readonly IPCRBService _pcrbService; | ||||
|     private readonly IMonInWorkerClient _monInClient; | ||||
|     private readonly IMonInUtils _monInUtils; | ||||
|  | ||||
|     public PCRBController(ILogger<MRBController> logger, IPCRBService pcrbService, IMonInWorkerClient monInClient) { | ||||
|     public PCRBController(ILogger<MRBController> logger, IPCRBService pcrbService, IMonInUtils monInUtils) { | ||||
|         _logger = logger ?? throw new ArgumentNullException("ILogger not injected"); | ||||
|         _pcrbService = pcrbService ?? throw new ArgumentNullException("IPCRBService not injected"); | ||||
|         _monInClient = monInClient ?? throw new ArgumentNullException("IMonInWorkerClient not injected"); | ||||
|         _monInUtils = monInUtils ?? throw new ArgumentNullException("IMonInUtils not injected"); | ||||
|     } | ||||
|  | ||||
|     [HttpPost] | ||||
| @ -49,17 +50,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "CreateNewPCRB"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|              | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -84,14 +76,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "GetAllPCRBs"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|              | ||||
|             if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, false, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -123,17 +109,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "GetPCRBbyTitle"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -165,17 +142,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "GetPCRBbyPlanNumber"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -207,17 +175,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "UpdatePCRB"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -249,22 +208,14 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "DeletePCRB"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     [HttpPost] | ||||
|     [Route("pcrb/attachment")] | ||||
|     [ApiExplorerSettings(IgnoreApi = true)] | ||||
|     public async Task<IActionResult> UploadAttachment([FromForm] IFormFile file, [FromForm] PCRBAttachment attachment) { | ||||
|         DateTime start = DateTime.Now; | ||||
|         bool isArgumentError = false; | ||||
| @ -293,17 +244,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "UploadPCRBAttachment"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -335,17 +277,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "GetPCRBAttachments"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -390,17 +323,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "GetPCRBAttachmentFile"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|              | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -432,17 +356,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "UpdatePCRBAttachment"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -474,17 +389,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "DeletePCRBAttachment"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -516,17 +422,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "CreatePCRBActionItem"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -558,17 +455,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "UpdatePCRBActionItem"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -600,17 +488,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "DeletePCRBActionItem"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -642,17 +521,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "GetPCRBActionItems"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -684,17 +554,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "CreatePCR3Document"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -726,17 +587,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "UpdatePCR3Document"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -768,17 +620,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "GetPCR3Documents"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -810,17 +653,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "CreatePCRBAttendee"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|              | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -852,17 +686,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "UpdatePCRBAttendee"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -894,17 +719,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "DeletePCRBAttendee"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -936,17 +752,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "GetPCRBAttendees"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -978,17 +785,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "NotifyNewPCRBApprovers"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -1022,17 +820,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "NotifyPCRBApprovers"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -1066,17 +855,8 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "NotifyPCRBOriginator"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -1110,17 +890,140 @@ public class PCRBController : ControllerBase { | ||||
|             string metricName = "NotifyPCRBResponsiblePerson"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|             _monInClient.PostAverage(metricName + "Latency", millisecondsDiff); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _logger.LogWarning(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _logger.LogError(errorMessage); | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     [HttpPost] | ||||
|     [Route("pcrb/followUp")] | ||||
|     public async Task<IActionResult> CreateFollowUp(PCRBFollowUp followUp) { | ||||
|         DateTime start = DateTime.Now; | ||||
|         bool isArgumentError = false; | ||||
|         bool isInternalError = false; | ||||
|         string errorMessage = ""; | ||||
|  | ||||
|         try { | ||||
|             _logger.LogInformation("Attempting to create follow up"); | ||||
|  | ||||
|             if (followUp is null) throw new ArgumentNullException("follow up cannot be null"); | ||||
|  | ||||
|             await _pcrbService.CreateFollowUp(followUp); | ||||
|  | ||||
|             return Ok(); | ||||
|         } catch (ArgumentException ex) { | ||||
|             isArgumentError = true; | ||||
|             errorMessage = ex.Message; | ||||
|             return BadRequest(errorMessage); | ||||
|         } catch (Exception ex) { | ||||
|             isInternalError = true; | ||||
|             errorMessage = $"Unable to create follow up, because {ex.Message}"; | ||||
|             return Problem(errorMessage); | ||||
|         } finally { | ||||
|             string metricName = "CreatePCRBFollowUp"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|  | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     [HttpGet] | ||||
|     [Route("pcrb/followUps")] | ||||
|     public async Task<IActionResult> GetFollowUpsByPlanNumber(int planNumber, bool bypassCache) { | ||||
|         DateTime start = DateTime.Now; | ||||
|         bool isArgumentError = false; | ||||
|         bool isInternalError = false; | ||||
|         string errorMessage = ""; | ||||
|  | ||||
|         try { | ||||
|             _logger.LogInformation($"Attempting to get attendees for plan# {planNumber}"); | ||||
|  | ||||
|             if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#"); | ||||
|  | ||||
|             List<PCRBFollowUp> attendees = (await _pcrbService.GetFollowUpsByPlanNumber(planNumber, bypassCache)).ToList(); | ||||
|  | ||||
|             return Ok(attendees); | ||||
|         } catch (ArgumentException ex) { | ||||
|             isArgumentError = true; | ||||
|             errorMessage = ex.Message; | ||||
|             return BadRequest(errorMessage); | ||||
|         } catch (Exception ex) { | ||||
|             isInternalError = true; | ||||
|             errorMessage = $"Cannot get follow ups for plan# {planNumber}, because {ex.Message}"; | ||||
|             return Problem(errorMessage); | ||||
|         } finally { | ||||
|             string metricName = "GetPCRBFollowUps"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|  | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     [HttpPut] | ||||
|     [Route("pcrb/followUp")] | ||||
|     public async Task<IActionResult> UpdateFollowUp(PCRBFollowUp followUp) { | ||||
|         DateTime start = DateTime.Now; | ||||
|         bool isArgumentError = false; | ||||
|         bool isInternalError = false; | ||||
|         string errorMessage = ""; | ||||
|  | ||||
|         try { | ||||
|             _logger.LogInformation("Attempting to update follow up"); | ||||
|  | ||||
|             if (followUp is null) throw new ArgumentNullException("follow up cannot be null"); | ||||
|  | ||||
|             await _pcrbService.UpdateFollowUp(followUp); | ||||
|  | ||||
|             return Ok(); | ||||
|         } catch (ArgumentException ex) { | ||||
|             isArgumentError = true; | ||||
|             errorMessage = ex.Message; | ||||
|             return BadRequest(errorMessage); | ||||
|         } catch (Exception ex) { | ||||
|             isInternalError = true; | ||||
|             errorMessage = $"Unable to update follow up, because {ex.Message}"; | ||||
|             return Problem(errorMessage); | ||||
|         } finally { | ||||
|             string metricName = "UpdatePCRBFollowUp"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|  | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     [HttpDelete] | ||||
|     [Route("pcrb/followUp")] | ||||
|     public async Task<IActionResult> DeleteFollowUp(int id) { | ||||
|         DateTime start = DateTime.Now; | ||||
|         bool isArgumentError = false; | ||||
|         bool isInternalError = false; | ||||
|         string errorMessage = ""; | ||||
|  | ||||
|         try { | ||||
|             _logger.LogInformation("Attempting to delete follow up"); | ||||
|  | ||||
|             if (id <= 0) throw new ArgumentException($"{id} is not a valid PCRB follow up ID"); | ||||
|  | ||||
|             await _pcrbService.DeleteFollowUp(id); | ||||
|  | ||||
|             return Ok(); | ||||
|         } catch (ArgumentException ex) { | ||||
|             isArgumentError = true; | ||||
|             errorMessage = ex.Message; | ||||
|             return BadRequest(errorMessage); | ||||
|         } catch (Exception ex) { | ||||
|             isInternalError = true; | ||||
|             errorMessage = $"Unable to delete follow up, because {ex.Message}"; | ||||
|             return Problem(errorMessage); | ||||
|         } finally { | ||||
|             string metricName = "DeletePCRBFollowUp"; | ||||
|             DateTime end = DateTime.Now; | ||||
|             double millisecondsDiff = (end - start).TotalMilliseconds; | ||||
|  | ||||
|             _monInUtils.PostMetrics(metricName, millisecondsDiff, isArgumentError, isInternalError); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -6,6 +6,7 @@ using dotenv.net; | ||||
|  | ||||
| using MesaFabApproval.API.Clients; | ||||
| using MesaFabApproval.API.Services; | ||||
| using MesaFabApproval.API.Utilities; | ||||
| using MesaFabApproval.Models; | ||||
| using MesaFabApproval.Shared.Services; | ||||
|  | ||||
| @ -94,6 +95,7 @@ builder.Services.AddScoped<IECNService, ECNService>(); | ||||
| builder.Services.AddScoped<ISmtpService, SmtpService>(); | ||||
| builder.Services.AddScoped<IUserService, UserService>(); | ||||
| builder.Services.AddScoped<IMonInWorkerClient, MonInWorkerClient>(); | ||||
| builder.Services.AddScoped<IMonInUtils, MonInUtils>(); | ||||
| builder.Services.AddScoped<IAuthenticationService, AuthenticationService>(); | ||||
| builder.Services.AddScoped<IMRBService, MRBService>(); | ||||
| builder.Services.AddScoped<IPCRBService, PCRBService>(); | ||||
| @ -101,7 +103,6 @@ builder.Services.AddScoped<IApprovalService, ApprovalService>(); | ||||
|  | ||||
| builder.Services.AddControllers(); | ||||
|  | ||||
| #if DEBUG | ||||
| builder.Services.AddEndpointsApiExplorer(); | ||||
| builder.Services.AddSwaggerGen(c => { | ||||
|     c.SwaggerDoc("v1", new OpenApiInfo { | ||||
| @ -128,13 +129,9 @@ builder.Services.AddSwaggerGen(c => { | ||||
|     } | ||||
|   }); | ||||
| }); | ||||
| #endif | ||||
|  | ||||
| WebApplication app = builder.Build(); | ||||
|  | ||||
| if (Debugger.IsAttached) | ||||
|     app.Services.GetRequiredService<IApprovalService>(); | ||||
|  | ||||
| app.UseCors(); | ||||
|  | ||||
| // Configure the HTTP request pipeline. | ||||
|  | ||||
| @ -219,7 +219,10 @@ public class ApprovalService : IApprovalService { | ||||
|                 queryBuilder.Append($"select a.*, src.SubRoleCategoryItem from Approval a "); | ||||
|                 queryBuilder.Append("join SubRole sr on a.SubRoleID=sr.SubRoleID "); | ||||
|                 queryBuilder.Append("join SubRoleCategory src on sr.SubRoleCategoryID=src.SubRoleCategoryID "); | ||||
|                 queryBuilder.Append($"where UserID={userId} and "); | ||||
|                 queryBuilder.Append($"where UserID={userId} and ItemStatus=0 and "); | ||||
|                 queryBuilder.Append($"(AssignedDate is not null and "); | ||||
|                 queryBuilder.Append($"AssignedDate <= '{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}' and "); | ||||
|                 queryBuilder.Append($"AssignedDate > '{DateTimeOffset.Now.AddYears(-2).DateTime.ToString("yyyy-MM-dd HH:mm:ss")}') and "); | ||||
|                 queryBuilder.Append($"((CompletedDate >= '{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}') or "); | ||||
|                 queryBuilder.Append($"(CompletedDate is null));"); | ||||
|                 string sql = queryBuilder.ToString(); | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| using System.Data; | ||||
| using System.Text; | ||||
|  | ||||
| using Dapper; | ||||
|  | ||||
| @ -6,7 +7,9 @@ namespace MesaFabApproval.API.Services; | ||||
|  | ||||
| public interface IDalService { | ||||
|     Task<IEnumerable<T>> QueryAsync<T>(string sql); | ||||
|     Task<IEnumerable<T>> QueryAsync<T>(string sql, object paramaters); | ||||
|     Task<int> ExecuteAsync(string sql); | ||||
|     Task<int> ExecuteAsync<T>(string sql, T paramaters); | ||||
| } | ||||
|  | ||||
| public class DalService : IDalService { | ||||
| @ -55,6 +58,45 @@ public class DalService : IDalService { | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     public async Task<IEnumerable<T>> QueryAsync<T>(string sql, object parameters) { | ||||
|         if (sql is null) throw new ArgumentNullException("sql cannot be null"); | ||||
|         if (parameters is null) throw new ArgumentNullException("parameters cannot be null"); | ||||
|  | ||||
|         StringBuilder logBuilder = new(); | ||||
|  | ||||
|         int remainingRetries = RETRIES; | ||||
|         bool queryWasSuccessful = false; | ||||
|         Exception exception = null; | ||||
|         IEnumerable<T> result = new List<T>(); | ||||
|         while (!queryWasSuccessful && remainingRetries > 0) { | ||||
|             int backoffSeconds = (RETRIES - remainingRetries--) * BACKOFF_SECONDS_INTERVAL; | ||||
|             Task.Delay(backoffSeconds * 1000).Wait(); | ||||
|  | ||||
|             try { | ||||
|                 logBuilder.Clear(); | ||||
|                 logBuilder.Append($"Attempting to perform query with {sql} "); | ||||
|                 logBuilder.Append($"and parameters {parameters.ToString()}. "); | ||||
|                 logBuilder.Append($"Remaining retries: {remainingRetries}"); | ||||
|                 _logger.LogInformation(logBuilder.ToString()); | ||||
|  | ||||
|                 using (IDbConnection conn = _dbConnectionService.GetConnection()) { | ||||
|                     result = await conn.QueryAsync<T>(sql, parameters); | ||||
|                 } | ||||
|  | ||||
|                 queryWasSuccessful = true; | ||||
|             } catch (Exception ex) { | ||||
|                 _logger.LogError($"An exception occurred while attempting to perform a query. Exception: {ex.Message}"); | ||||
|                 exception = ex; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!queryWasSuccessful && exception is not null) { | ||||
|             throw exception; | ||||
|         } | ||||
|  | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     public async Task<int> ExecuteAsync(string sql) { | ||||
|         if (sql is null) throw new ArgumentNullException("sql cannot be null"); | ||||
|  | ||||
| @ -86,4 +128,36 @@ public class DalService : IDalService { | ||||
|  | ||||
|         return rowsAffected; | ||||
|     } | ||||
|  | ||||
|     public async Task<int> ExecuteAsync<T>(string sql, T parameters) { | ||||
|         if (sql is null) throw new ArgumentNullException("sql cannot be null"); | ||||
|  | ||||
|         int remainingRetries = RETRIES; | ||||
|         bool queryWasSuccessful = false; | ||||
|         Exception exception = null; | ||||
|         int rowsAffected = 0; | ||||
|         while (!queryWasSuccessful && remainingRetries > 0) { | ||||
|             int backoffSeconds = (RETRIES - remainingRetries--) * BACKOFF_SECONDS_INTERVAL; | ||||
|             Task.Delay(backoffSeconds * 1000).Wait(); | ||||
|  | ||||
|             try { | ||||
|                 _logger.LogInformation($"Attempting to execute {sql} with parameters. Remaining retries: {remainingRetries}"); | ||||
|  | ||||
|                 using (IDbConnection conn = _dbConnectionService.GetConnection()) { | ||||
|                     rowsAffected = await conn.ExecuteAsync(sql, parameters); | ||||
|                 } | ||||
|  | ||||
|                 queryWasSuccessful = true; | ||||
|             } catch (Exception ex) { | ||||
|                 _logger.LogError($"An exception occurred while attempting to execute a query. Exception: {ex.Message}"); | ||||
|                 exception = ex; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (!queryWasSuccessful && exception is not null) { | ||||
|             throw exception; | ||||
|         } | ||||
|  | ||||
|         return rowsAffected; | ||||
|     } | ||||
| } | ||||
| @ -4,6 +4,7 @@ namespace MesaFabApproval.API.Services; | ||||
|  | ||||
| public interface IECNService { | ||||
|     Task<bool> IsValidECNNumber(int number); | ||||
|     Task<IEnumerable<int>> GetAllECNNumbers(); | ||||
| } | ||||
|  | ||||
| public class ECNService : IECNService { | ||||
| @ -43,4 +44,19 @@ public class ECNService : IECNService { | ||||
|             throw; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public async Task<IEnumerable<int>> GetAllECNNumbers() { | ||||
|         try { | ||||
|             _logger.LogInformation("Attempting to get all ECN#s"); | ||||
|  | ||||
|             string sql = "select ECNNumber from ECN where Deleted=0 and Cancelled=0"; | ||||
|  | ||||
|             IEnumerable<int> allEcnNumbers = await _dalService.QueryAsync<int>(sql); | ||||
|  | ||||
|             return allEcnNumbers; | ||||
|         } catch (Exception ex) { | ||||
|             _logger.LogError($"Unable to get all ECN#s, because {ex.Message}"); | ||||
|             throw; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -852,8 +852,8 @@ public class MRBService : IMRBService { | ||||
|                             convertToPart += partStr; | ||||
|                     } | ||||
|  | ||||
|                     dt.Rows.Add(action.Action, convertFromCustomer, convertFromPart, action.Quantity.ToString(), | ||||
|                                 convertToCustomer, convertToPart, | ||||
|                     dt.Rows.Add(action.Action, convertFromCustomer, convertFromPart, action.LotNumber,  | ||||
|                                 action.Quantity.ToString(), convertToCustomer, convertToPart, | ||||
|                                 DateTimeUtilities.GetDateAsStringMinDefault(action.AssignedDate), | ||||
|                                 DateTimeUtilities.GetDateAsStringMaxDefault(action.CompletedDate), | ||||
|                                 action.CompletedByUser is null ? "" : action.CompletedByUser.GetFullName()); | ||||
|  | ||||
| @ -37,6 +37,10 @@ public interface IPCRBService { | ||||
|     Task NotifyApprovers(PCRBNotification notification); | ||||
|     Task NotifyOriginator(PCRBNotification notification); | ||||
|     Task NotifyResponsiblePerson(PCRBActionItemNotification notification); | ||||
|     Task CreateFollowUp(PCRBFollowUp followUp); | ||||
|     Task<IEnumerable<PCRBFollowUp>> GetFollowUpsByPlanNumber(int planNumber, bool bypassCache); | ||||
|     Task UpdateFollowUp(PCRBFollowUp followUp); | ||||
|     Task DeleteFollowUp(int id); | ||||
| } | ||||
|  | ||||
| public class PCRBService : IPCRBService { | ||||
| @ -74,16 +78,15 @@ public class PCRBService : IPCRBService { | ||||
|  | ||||
|             if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null"); | ||||
|  | ||||
|             pcrb.LastUpdateDate = DateTime.Now; | ||||
|  | ||||
|             StringBuilder queryBuilder = new(); | ||||
|             queryBuilder.Append("insert into CCChangeControl (OwnerID, Title, ChangeLevel, ReasonForChange, "); | ||||
|             queryBuilder.Append("ChangeDescription, IsITAR, CurrentStep, InsertTimeStamp, LastUpdateDate) "); | ||||
|             queryBuilder.Append($"values ({pcrb.OwnerID}, '{pcrb.Title}', '{pcrb.ChangeLevel}', "); | ||||
|             queryBuilder.Append($"'{pcrb.ReasonForChange}', '{pcrb.ChangeDescription}', "); | ||||
|             queryBuilder.Append($"{Convert.ToInt32(pcrb.IsITAR)}, {pcrb.CurrentStep}, "); | ||||
|             queryBuilder.Append($"'{pcrb.InsertTimeStamp.ToString("yyyy-MM-dd HH:mm:ss")}', "); | ||||
|             queryBuilder.Append($"'{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}')"); | ||||
|             queryBuilder.Append("ChangeDescription, IsITAR, CurrentStep, InsertTimeStamp, LastUpdateDate, Type) "); | ||||
|             queryBuilder.Append("values (@OwnerID, @Title, @ChangeLevel, @ReasonForChange, @ChangeDescription, "); | ||||
|             queryBuilder.Append("@IsITAR, @CurrentStep, @InsertTimeStamp, @LastUpdateDate, @Type)"); | ||||
|  | ||||
|             int rowsCreated = await _dalService.ExecuteAsync(queryBuilder.ToString()); | ||||
|             int rowsCreated = await _dalService.ExecuteAsync(queryBuilder.ToString(), pcrb); | ||||
|  | ||||
|             if (rowsCreated <= 0) throw new Exception("unable to insert new PCRB in the database"); | ||||
|         } catch (Exception ex) { | ||||
| @ -194,18 +197,16 @@ public class PCRBService : IPCRBService { | ||||
|  | ||||
|             if (pcrb is null) throw new ArgumentNullException("PCRB cannot be null"); | ||||
|  | ||||
|             StringBuilder queryBuilder = new(); | ||||
|             queryBuilder.Append($"update CCChangeControl set OwnerID={pcrb.OwnerID}, "); | ||||
|             queryBuilder.Append($"Title='{pcrb.Title.Replace("'", "''")}', ChangeLevel='{pcrb.ChangeLevel}', "); | ||||
|             queryBuilder.Append($"CurrentStep={pcrb.CurrentStep}, ReasonForChange='{pcrb.ReasonForChange.Replace("'", "''")}', "); | ||||
|             queryBuilder.Append($"ChangeDescription='{pcrb.ChangeDescription.Replace("'", "''")}', "); | ||||
|             queryBuilder.Append($"IsITAR={Convert.ToInt32(pcrb.IsITAR)}, "); | ||||
|             queryBuilder.Append($"InsertTimeStamp='{pcrb.InsertTimeStamp.ToString("yyyy-MM-dd HH:mm:ss")}', "); | ||||
|             queryBuilder.Append($"ClosedDate='{pcrb.ClosedDate.ToString("yyyy-MM-dd HH:mm:ss")}', "); | ||||
|             queryBuilder.Append($"LastUpdateDate='{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}' "); | ||||
|             queryBuilder.Append($"where PlanNumber={pcrb.PlanNumber}"); | ||||
|             pcrb.LastUpdateDate = DateTime.Now; | ||||
|  | ||||
|             int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString()); | ||||
|             StringBuilder queryBuilder = new(); | ||||
|             queryBuilder.Append("update CCChangeControl set OwnerID=@OwnerID, Title=@Title, ChangeLevel=@ChangeLevel, "); | ||||
|             queryBuilder.Append("Type=@Type, CurrentStep=@CurrentStep, ReasonForChange=@ReasonForChange, "); | ||||
|             queryBuilder.Append("ChangeDescription=@ChangeDescription, IsITAR=@IsITAR, ClosedDate=@ClosedDate, "); | ||||
|             queryBuilder.Append("LastUpdateDate=@LastUpdateDate "); | ||||
|             queryBuilder.Append($"where PlanNumber=@PlanNumber"); | ||||
|  | ||||
|             int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString(), pcrb); | ||||
|  | ||||
|             if (rowsAffected <= 0) throw new Exception("unable to perform update in database"); | ||||
|  | ||||
| @ -485,6 +486,20 @@ public class PCRBService : IPCRBService { | ||||
|             int rowsAffected = await _dalService.ExecuteAsync(queryBuilder.ToString()); | ||||
|  | ||||
|             if (rowsAffected <= 0) throw new Exception("update failed in database"); | ||||
|  | ||||
|             IEnumerable<PCRBAttendee>? attendees = _cache.Get<IEnumerable<PCRBAttendee>>($"pcrbAttendees{attendee.PlanNumber}"); | ||||
|             if (attendees is not null) { | ||||
|                 foreach (PCRBAttendee cachedAttendee in attendees) { | ||||
|                     if (cachedAttendee.ID == attendee.ID) { | ||||
|                         cachedAttendee.Location = attendee.Location; | ||||
|                         cachedAttendee.Attended = attendee.Attended; | ||||
|                         cachedAttendee.JobTitle = attendee.JobTitle; | ||||
|                         cachedAttendee.AttendeeID = attendee.AttendeeID; | ||||
|                         cachedAttendee.Step = attendee.Step; | ||||
|                     } | ||||
|                 } | ||||
|                 _cache.Set($"pcrbAttendees{attendee.PlanNumber}", attendees, DateTimeOffset.Now.AddMinutes(15)); | ||||
|             } | ||||
|         } catch (Exception ex) { | ||||
|             _logger.LogError($"Unable to update attendee, because {ex.Message}"); | ||||
|             throw; | ||||
| @ -741,6 +756,90 @@ public class PCRBService : IPCRBService { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public async Task CreateFollowUp(PCRBFollowUp followUp) { | ||||
|         try { | ||||
|             _logger.LogInformation("Attempting to create PCRB follow up"); | ||||
|  | ||||
|             if (followUp is null) throw new ArgumentNullException("follow up cannot be null"); | ||||
|  | ||||
|             StringBuilder queryBuilder = new(); | ||||
|             queryBuilder.Append("insert into CCPCRBFollowUp (PlanNumber, Step, FollowUpDate, CompletedDate) "); | ||||
|             queryBuilder.Append("values (@PlanNumber, @Step, @FollowUpDate, @CompletedDate)"); | ||||
|  | ||||
|             int rowsReturned = await _dalService.ExecuteAsync<PCRBFollowUp>(queryBuilder.ToString(), followUp); | ||||
|  | ||||
|             if (rowsReturned <= 0) throw new Exception("unable to insert new follow up in the database"); | ||||
|         } catch (Exception ex) { | ||||
|             _logger.LogError($"Unable to create new follow up, because {ex.Message}"); | ||||
|             throw; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public async Task<IEnumerable<PCRBFollowUp>> GetFollowUpsByPlanNumber(int planNumber, bool bypassCache) { | ||||
|         try { | ||||
|             _logger.LogInformation($"Attempting to fetch follow ups for PCRB {planNumber}"); | ||||
|  | ||||
|             if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#"); | ||||
|  | ||||
|             IEnumerable<PCRBFollowUp>? followUps = new List<PCRBFollowUp>(); | ||||
|  | ||||
|             if (!bypassCache) | ||||
|                 followUps = _cache.Get<IEnumerable<PCRBFollowUp>>($"pcrbFollowUps{planNumber}"); | ||||
|  | ||||
|             if (followUps is null || followUps.Count() == 0) {  | ||||
|                 string sql = "select * from CCPCRBFollowUp where PlanNumber=@PlanNumber"; | ||||
|  | ||||
|                 followUps = await _dalService.QueryAsync<PCRBFollowUp>(sql, new { PlanNumber = planNumber }); | ||||
|  | ||||
|                 if (followUps is not null) | ||||
|                     _cache.Set($"pcrbFollowUps{planNumber}", followUps, DateTimeOffset.Now.AddMinutes(15)); | ||||
|             } | ||||
|  | ||||
|             return followUps ?? new List<PCRBFollowUp>(); | ||||
|         } catch (Exception ex) { | ||||
|             _logger.LogError($"Unable to fetch follow ups for PCRB {planNumber}, because {ex.Message}"); | ||||
|             throw; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public async Task UpdateFollowUp(PCRBFollowUp followUp) { | ||||
|         try { | ||||
|             _logger.LogInformation("Attempting to update a follow up"); | ||||
|  | ||||
|             if (followUp is null) | ||||
|                 throw new ArgumentNullException("follow up cannot be null"); | ||||
|  | ||||
|             StringBuilder queryBuilder = new(); | ||||
|             queryBuilder.Append("update CCPCRBFollowUp set Step=@Step, FollowUpDate=@FollowUpDate, IsComplete=@IsComplete, "); | ||||
|             queryBuilder.Append("IsDeleted=@IsDeleted, CompletedDate=@CompletedDate, Comments=@Comments "); | ||||
|             queryBuilder.Append("where ID=@ID"); | ||||
|  | ||||
|             int rowsAffected = await _dalService.ExecuteAsync<PCRBFollowUp>(queryBuilder.ToString(), followUp); | ||||
|  | ||||
|             if (rowsAffected <= 0) throw new Exception("update failed in database"); | ||||
|         } catch (Exception ex) { | ||||
|             _logger.LogError($"Unable to update follow up, because {ex.Message}"); | ||||
|             throw; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public async Task DeleteFollowUp(int id) { | ||||
|         try { | ||||
|             _logger.LogInformation($"Attempting to delete follow up {id}"); | ||||
|  | ||||
|             if (id <= 0) throw new ArgumentException($"{id} is not a valid follow up ID"); | ||||
|  | ||||
|             string sql = "delete from CCPCRBFollowUp where ID=@ID"; | ||||
|  | ||||
|             int rowsAffected = await _dalService.ExecuteAsync(sql, new { ID = id }); | ||||
|  | ||||
|             if (rowsAffected <= 0) throw new Exception("delete operation failed in database"); | ||||
|         } catch (Exception ex) { | ||||
|             _logger.LogError($"Unable to delete follow up {id}, because {ex.Message}"); | ||||
|             throw; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private async Task SaveAttachmentInDb(IFormFile file, PCRBAttachment attachment) { | ||||
|         try { | ||||
|             _logger.LogInformation($"Attempting to save attachment to database"); | ||||
|  | ||||
							
								
								
									
										48
									
								
								MesaFabApproval.API/Utilities/MonInUtils.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								MesaFabApproval.API/Utilities/MonInUtils.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| using MesaFabApproval; | ||||
| using MesaFabApproval.API; | ||||
| using MesaFabApproval.API.Services; | ||||
| using MesaFabApproval.API.Utilities; | ||||
| using MesaFabApproval.Shared.Models; | ||||
| using MesaFabApproval.Shared.Services; | ||||
|  | ||||
| namespace MesaFabApproval.API.Utilities; | ||||
|  | ||||
| public interface IMonInUtils { | ||||
|     public void PostMetrics(string metricName, | ||||
|                             double latency, | ||||
|                             bool isArgumentError, | ||||
|                             bool isInternalError); | ||||
| } | ||||
|  | ||||
| public class MonInUtils : IMonInUtils { | ||||
|     private readonly IMonInWorkerClient _monInClient; | ||||
|     private readonly ILogger<MonInUtils> _logger; | ||||
|  | ||||
|     public MonInUtils(IMonInWorkerClient monInClient, ILogger<MonInUtils> logger) { | ||||
|         _monInClient = monInClient ?? | ||||
|             throw new ArgumentNullException("IMonInWorkerClient not injected"); | ||||
|         _logger = logger ?? | ||||
|             throw new ArgumentNullException("ILogger not injected"); | ||||
|     } | ||||
|  | ||||
|     public void PostMetrics(string metricName, | ||||
|                             double latency, | ||||
|                             bool isArgumentError, | ||||
|                             bool isInternalError) { | ||||
|         try { | ||||
|             _logger.LogInformation("Attempting to post metrics to MonIn"); | ||||
|  | ||||
|             _monInClient.PostAverage(metricName + "Latency", latency); | ||||
|  | ||||
|             if (isArgumentError) { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } else if (isInternalError) { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Critical); | ||||
|             } else { | ||||
|                 _monInClient.PostStatus(metricName, StatusValue.Ok); | ||||
|             } | ||||
|         } catch (Exception ex) { | ||||
|             _logger.LogError($"Unable to post metrics to MonIn, because {ex.Message}"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										100
									
								
								MesaFabApproval.API/pipeline.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								MesaFabApproval.API/pipeline.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,100 @@ | ||||
| trigger: | ||||
|   branches: | ||||
|     include: | ||||
|       - master | ||||
|   paths: | ||||
|     include: | ||||
|       - MesaFabApproval.API | ||||
|       - MesaFabApproval.Shared | ||||
|  | ||||
| variables: | ||||
|   buildConfiguration: "Release" | ||||
|  | ||||
| stages: | ||||
|   - stage: Test | ||||
|     displayName: "Test" | ||||
|     pool: | ||||
|       name: MesaFabApproval | ||||
|       demands: Fab2ApprovalSystem-Dev | ||||
|     jobs: | ||||
|       - job: BuildPublish | ||||
|         steps: | ||||
|           - script: | | ||||
|               echo build configuration: $(BuildConfiguration) | ||||
|             displayName: "Echo Check" | ||||
|  | ||||
|           - task: DotNetCoreCLI@2 | ||||
|             displayName: "Build" | ||||
|             inputs: | ||||
|               command: "build" | ||||
|               configuration: $(BuildConfiguration) | ||||
|               projects: MesaFabApproval.API | ||||
|  | ||||
|           - task: DotNetCoreCLI@2 | ||||
|             displayName: "Test" | ||||
|             inputs: | ||||
|               command: "test" | ||||
|               configuration: $(BuildConfiguration) | ||||
|               publishTestResults: true | ||||
|               projects: MesaFabApproval.API.Test | ||||
|  | ||||
|           - task: DotNetCoreCLI@2 | ||||
|             displayName: "Publish" | ||||
|             inputs: | ||||
|               command: "publish" | ||||
|               publishWebProjects: false | ||||
|               projects: MesaFabApproval.API | ||||
|               zipAfterPublish: true | ||||
|               arguments: "-c $(BuildConfiguration) -o $(Build.ArtifactStagingDirectory) -r win-x64 --self-contained" | ||||
|  | ||||
|           - task: CopyFiles@2 | ||||
|             displayName: "Copy Files" | ||||
|             inputs: | ||||
|               SourceFolder: "$(Build.ArtifactStagingDirectory)" | ||||
|               TargetFolder: 'D:\$(Build.Repository.Name)\API\$(Build.BuildId)\$(BuildConfiguration)' | ||||
|               CleanTargetFolder: true | ||||
|               retryCount: "3" | ||||
|  | ||||
|   - stage: Prod | ||||
|     displayName: "Prod" | ||||
|     pool: | ||||
|       name: MesaFabApproval | ||||
|       demands: Fab2ApprovalSystem | ||||
|     jobs: | ||||
|       - job: BuildPublish | ||||
|         steps: | ||||
|           - script: | | ||||
|               echo build configuration: $(BuildConfiguration) | ||||
|             displayName: "Echo Check" | ||||
|  | ||||
|           - task: DotNetCoreCLI@2 | ||||
|             displayName: "Build" | ||||
|             inputs: | ||||
|               command: "build" | ||||
|               configuration: $(BuildConfiguration) | ||||
|               projects: MesaFabApproval.API | ||||
|  | ||||
|           - task: DotNetCoreCLI@2 | ||||
|             displayName: "Test" | ||||
|             inputs: | ||||
|               command: "test" | ||||
|               configuration: $(BuildConfiguration) | ||||
|               publishTestResults: true | ||||
|               projects: MesaFabApproval.API.Test | ||||
|  | ||||
|           - task: DotNetCoreCLI@2 | ||||
|             displayName: "Publish" | ||||
|             inputs: | ||||
|               command: "publish" | ||||
|               publishWebProjects: false | ||||
|               projects: MesaFabApproval.API | ||||
|               zipAfterPublish: true | ||||
|               arguments: "-c $(BuildConfiguration) -o $(Build.ArtifactStagingDirectory) -r win-x64 --self-contained" | ||||
|  | ||||
|           - task: CopyFiles@2 | ||||
|             displayName: "Copy Files" | ||||
|             inputs: | ||||
|               SourceFolder: "$(Build.ArtifactStagingDirectory)" | ||||
|               TargetFolder: 'D:\$(Build.Repository.Name)\API\$(Build.BuildId)\$(BuildConfiguration)' | ||||
|               CleanTargetFolder: true | ||||
|               retryCount: "3" | ||||
| @ -0,0 +1,31 @@ | ||||
| <Project Sdk="Microsoft.NET.Sdk"> | ||||
|  | ||||
|   <PropertyGroup> | ||||
|     <TargetFramework>net8.0</TargetFramework> | ||||
|     <ImplicitUsings>enable</ImplicitUsings> | ||||
|     <Nullable>enable</Nullable> | ||||
|  | ||||
|     <IsPackable>false</IsPackable> | ||||
|     <IsTestProject>true</IsTestProject> | ||||
|   </PropertyGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <PackageReference Include="coverlet.collector" Version="6.0.0" /> | ||||
|     <PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" /> | ||||
|     <PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0" /> | ||||
|     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" /> | ||||
|     <PackageReference Include="Moq" Version="4.20.72" /> | ||||
|     <PackageReference Include="MudBlazor" Version="8.3.0" /> | ||||
|     <PackageReference Include="xunit" Version="2.5.3" /> | ||||
|     <PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\MesaFabApproval.Client\MesaFabApproval.Client.csproj" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
|   <ItemGroup> | ||||
|     <Using Include="Xunit" /> | ||||
|   </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
							
								
								
									
										347
									
								
								MesaFabApproval.Client.Test/PCRBServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										347
									
								
								MesaFabApproval.Client.Test/PCRBServiceTests.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,347 @@ | ||||
| using System.Net; | ||||
| using System.Text.Json; | ||||
|  | ||||
| using MesaFabApproval.Client.Services; | ||||
| using MesaFabApproval.Shared.Models; | ||||
|  | ||||
| using Microsoft.Extensions.Caching.Memory; | ||||
|  | ||||
| using Moq; | ||||
| using Moq.Protected; | ||||
|  | ||||
| using MudBlazor; | ||||
|  | ||||
| namespace MesaFabApproval.Client.Test; | ||||
|  | ||||
| public class PCRBServiceTests { | ||||
|     private readonly Mock<IMemoryCache> _mockCache; | ||||
|     private readonly Mock<IHttpClientFactory> _mockHttpClientFactory; | ||||
|     private readonly Mock<ISnackbar> _mockSnackbar; | ||||
|     private readonly Mock<IUserService> _mockUserService; | ||||
|     private readonly PCRBService _pcrbService; | ||||
|  | ||||
|     private static IEnumerable<PCRBFollowUp> FOLLOW_UPS = new List<PCRBFollowUp>() { | ||||
|         new PCRBFollowUp { ID = 1, PlanNumber = 1, Step = 1, FollowUpDate = DateTime.Now } | ||||
|     }; | ||||
|  | ||||
|     private static HttpResponseMessage SUCCESSFUL_RESPONSE = new HttpResponseMessage(HttpStatusCode.OK); | ||||
|     private static HttpResponseMessage UNSUCCESSFUL_RESPONSE = new HttpResponseMessage(HttpStatusCode.InternalServerError); | ||||
|  | ||||
|     public static class MockMemoryCacheService { | ||||
|         public static Mock<IMemoryCache> GetMemoryCache(object expectedValue) { | ||||
|             Mock<IMemoryCache> mockMemoryCache = new Mock<IMemoryCache>(); | ||||
|             mockMemoryCache | ||||
|                 .Setup(x => x.TryGetValue(It.IsAny<object>(), out expectedValue)) | ||||
|                 .Returns(true); | ||||
|             mockMemoryCache | ||||
|                 .Setup(x => x.CreateEntry(It.IsAny<object>())) | ||||
|                 .Returns(Mock.Of<ICacheEntry>()); | ||||
|             return mockMemoryCache; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public PCRBServiceTests() { | ||||
|         _mockCache = MockMemoryCacheService.GetMemoryCache(FOLLOW_UPS); | ||||
|         _mockHttpClientFactory = new Mock<IHttpClientFactory>(); | ||||
|         _mockSnackbar = new Mock<ISnackbar>(); | ||||
|         _mockUserService = new Mock<IUserService>(); | ||||
|  | ||||
|         _pcrbService = new PCRBService( | ||||
|             _mockCache.Object, | ||||
|             _mockHttpClientFactory.Object, | ||||
|             _mockSnackbar.Object, | ||||
|             _mockUserService.Object); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task CreateFollowUp_WithValidParams_ShouldCallHttpPost_AndRefreshCache() { | ||||
|         PCRBFollowUp followUp = new PCRBFollowUp { | ||||
|             ID = 1, | ||||
|             PlanNumber = 123, | ||||
|             Step = 1, | ||||
|             FollowUpDate = DateTime.Now, | ||||
|             Comments = "Test" | ||||
|         }; | ||||
|  | ||||
|         HttpResponseMessage getResponse = new HttpResponseMessage { | ||||
|             StatusCode = HttpStatusCode.OK, | ||||
|             Content = new StringContent(JsonSerializer.Serialize(new List<PCRBFollowUp> { followUp })) | ||||
|         }; | ||||
|  | ||||
|         var mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||
|         mockHttpMessageHandler.Protected() | ||||
|             .Setup<Task<HttpResponseMessage>>( | ||||
|                 "SendAsync", | ||||
|                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Post), | ||||
|                 ItExpr.IsAny<CancellationToken>()) | ||||
|             .ReturnsAsync(SUCCESSFUL_RESPONSE) | ||||
|             .Verifiable(); | ||||
|  | ||||
|         mockHttpMessageHandler.Protected() | ||||
|             .Setup<Task<HttpResponseMessage>>( | ||||
|                 "SendAsync", | ||||
|                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get), | ||||
|                 ItExpr.IsAny<CancellationToken>()) | ||||
|             .ReturnsAsync(getResponse) | ||||
|             .Verifiable(); | ||||
|  | ||||
|         var httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||
|             BaseAddress = new Uri("https://localhost:5000") | ||||
|         }; | ||||
|         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||
|  | ||||
|         await _pcrbService.CreateFollowUp(followUp); | ||||
|  | ||||
|         mockHttpMessageHandler.Protected().Verify( | ||||
|             "SendAsync", | ||||
|             Times.Once(), | ||||
|             ItExpr.Is<HttpRequestMessage>( | ||||
|                 req =>  | ||||
|                     req.Method == HttpMethod.Post && | ||||
|                     req.RequestUri != null && | ||||
|                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUp")), | ||||
|             ItExpr.IsAny<CancellationToken>()); | ||||
|  | ||||
|         mockHttpMessageHandler.Protected().Verify( | ||||
|             "SendAsync", | ||||
|             Times.Once(), | ||||
|             ItExpr.Is<HttpRequestMessage>( | ||||
|                 req =>  | ||||
|                     req.Method == HttpMethod.Get && | ||||
|                     req.RequestUri != null && | ||||
|                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUps?planNumber=123&bypassCache=True")), | ||||
|             ItExpr.IsAny<CancellationToken>()); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task CreateFollowUp_WithBadResponse_ShouldThrowException() { | ||||
|         PCRBFollowUp followUp = new PCRBFollowUp { | ||||
|             ID = 1, | ||||
|             PlanNumber = 123, | ||||
|             Step = 1, | ||||
|             FollowUpDate = DateTime.Now, | ||||
|             Comments = "Test" | ||||
|         }; | ||||
|  | ||||
|         var mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||
|         mockHttpMessageHandler.Protected() | ||||
|             .Setup<Task<HttpResponseMessage>>( | ||||
|                 "SendAsync", | ||||
|                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Post), | ||||
|                 ItExpr.IsAny<CancellationToken>()) | ||||
|             .ReturnsAsync(UNSUCCESSFUL_RESPONSE) | ||||
|             .Verifiable(); | ||||
|  | ||||
|         var httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||
|             BaseAddress = new Uri("https://localhost:5000") | ||||
|         }; | ||||
|         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||
|  | ||||
|         await Assert.ThrowsAsync<Exception>(() => _pcrbService.CreateFollowUp(followUp)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task CreateFollowUp_WithNullParam_ShouldThrowException() { | ||||
|         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.CreateFollowUp(null)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task GetFollowUpsByPlanNumber_WithBypassCache_ShouldCallHttpGetAndReturnFollowUps() { | ||||
|         PCRBFollowUp followUp = new PCRBFollowUp { | ||||
|             ID = 1, | ||||
|             PlanNumber = 123, | ||||
|             Step = 1, | ||||
|             FollowUpDate = DateTime.Now, | ||||
|             Comments = "Test" | ||||
|         }; | ||||
|  | ||||
|         HttpResponseMessage getResponse = new HttpResponseMessage { | ||||
|             StatusCode = HttpStatusCode.OK, | ||||
|             Content = new StringContent(JsonSerializer.Serialize(new List<PCRBFollowUp> { followUp })) | ||||
|         }; | ||||
|  | ||||
|         var mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||
|  | ||||
|         mockHttpMessageHandler.Protected() | ||||
|             .Setup<Task<HttpResponseMessage>>( | ||||
|                 "SendAsync", | ||||
|                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get), | ||||
|                 ItExpr.IsAny<CancellationToken>()) | ||||
|             .ReturnsAsync(getResponse) | ||||
|             .Verifiable(); | ||||
|  | ||||
|         var httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||
|             BaseAddress = new Uri("https://localhost:5000") | ||||
|         }; | ||||
|         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||
|  | ||||
|         IEnumerable<PCRBFollowUp> followUps = await _pcrbService.GetFollowUpsByPlanNumber(123, true); | ||||
|  | ||||
|         mockHttpMessageHandler.Protected().Verify( | ||||
|             "SendAsync", | ||||
|             Times.Once(), | ||||
|             ItExpr.Is<HttpRequestMessage>( | ||||
|                 req => | ||||
|                     req.Method == HttpMethod.Get && | ||||
|                     req.RequestUri != null && | ||||
|                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUps?planNumber=123&bypassCache=True")), | ||||
|             ItExpr.IsAny<CancellationToken>()); | ||||
|  | ||||
|         Assert.Single(followUps); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task GetFollowUpsByPlanNumber_WithoutBypassCache_ShouldReturnFollowUpsFromCache() { | ||||
|         IEnumerable<PCRBFollowUp> followUps = await _pcrbService.GetFollowUpsByPlanNumber(1, false); | ||||
|         Assert.Single(followUps); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task GetFollowUpsByPlanNumber_WithBadResponse_ShouldThrowException() { | ||||
|         var mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||
|  | ||||
|         mockHttpMessageHandler.Protected() | ||||
|             .Setup<Task<HttpResponseMessage>>( | ||||
|                 "SendAsync", | ||||
|                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Get), | ||||
|                 ItExpr.IsAny<CancellationToken>()) | ||||
|             .ReturnsAsync(UNSUCCESSFUL_RESPONSE) | ||||
|             .Verifiable(); | ||||
|  | ||||
|         var httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||
|             BaseAddress = new Uri("https://localhost:5000") | ||||
|         }; | ||||
|  | ||||
|         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||
|  | ||||
|         await Assert.ThrowsAsync<Exception>(() => _pcrbService.GetFollowUpsByPlanNumber(1, true)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task UpdateFollowUp_WithValidParams_ShouldCallHttpPut() { | ||||
|         PCRBFollowUp followUp = new PCRBFollowUp { | ||||
|             ID = 1, | ||||
|             PlanNumber = 123, | ||||
|             Step = 1, | ||||
|             FollowUpDate = DateTime.Now, | ||||
|             Comments = "Test" | ||||
|         }; | ||||
|  | ||||
|         var mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||
|  | ||||
|         mockHttpMessageHandler.Protected() | ||||
|             .Setup<Task<HttpResponseMessage>>( | ||||
|                 "SendAsync", | ||||
|                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Put), | ||||
|                 ItExpr.IsAny<CancellationToken>()) | ||||
|             .ReturnsAsync(SUCCESSFUL_RESPONSE) | ||||
|             .Verifiable(); | ||||
|  | ||||
|         var httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||
|             BaseAddress = new Uri("https://localhost:5000") | ||||
|         }; | ||||
|         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||
|  | ||||
|         await _pcrbService.UpdateFollowUp(followUp); | ||||
|  | ||||
|         mockHttpMessageHandler.Protected().Verify( | ||||
|             "SendAsync", | ||||
|             Times.Once(), | ||||
|             ItExpr.Is<HttpRequestMessage>( | ||||
|                 req => | ||||
|                     req.Method == HttpMethod.Put && | ||||
|                     req.RequestUri != null && | ||||
|                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUp")), | ||||
|             ItExpr.IsAny<CancellationToken>()); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task UpdateFollowUp_WithNullParam_ShouldThrowException() { | ||||
|         await Assert.ThrowsAsync<ArgumentNullException>(() => _pcrbService.UpdateFollowUp(null)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task UpdateFollowUp_WithBadResponse_ShouldThrowException() { | ||||
|         PCRBFollowUp followUp = new PCRBFollowUp { | ||||
|             ID = 1, | ||||
|             PlanNumber = 123, | ||||
|             Step = 1, | ||||
|             FollowUpDate = DateTime.Now, | ||||
|             Comments = "Test" | ||||
|         }; | ||||
|  | ||||
|         var mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||
|  | ||||
|         mockHttpMessageHandler.Protected() | ||||
|             .Setup<Task<HttpResponseMessage>>( | ||||
|                 "SendAsync", | ||||
|                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Put), | ||||
|                 ItExpr.IsAny<CancellationToken>()) | ||||
|             .ReturnsAsync(UNSUCCESSFUL_RESPONSE) | ||||
|             .Verifiable(); | ||||
|  | ||||
|         var httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||
|             BaseAddress = new Uri("https://localhost:5000") | ||||
|         }; | ||||
|  | ||||
|         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||
|  | ||||
|         await Assert.ThrowsAsync<Exception>(() => _pcrbService.UpdateFollowUp(followUp)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task DeleteFollowUp_WithValidParams_ShouldCallHttpDelete() { | ||||
|         var mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||
|  | ||||
|         mockHttpMessageHandler.Protected() | ||||
|             .Setup<Task<HttpResponseMessage>>( | ||||
|                 "SendAsync", | ||||
|                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Delete), | ||||
|                 ItExpr.IsAny<CancellationToken>()) | ||||
|             .ReturnsAsync(SUCCESSFUL_RESPONSE) | ||||
|             .Verifiable(); | ||||
|  | ||||
|         var httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||
|             BaseAddress = new Uri("https://localhost:5000") | ||||
|         }; | ||||
|         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||
|  | ||||
|         await _pcrbService.DeleteFollowUp(1); | ||||
|  | ||||
|         mockHttpMessageHandler.Protected().Verify( | ||||
|             "SendAsync", | ||||
|             Times.Once(), | ||||
|             ItExpr.Is<HttpRequestMessage>( | ||||
|                 req => | ||||
|                     req.Method == HttpMethod.Delete && | ||||
|                     req.RequestUri != null && | ||||
|                     req.RequestUri.AbsoluteUri.Equals("https://localhost:5000/pcrb/followUp?id=1")), | ||||
|             ItExpr.IsAny<CancellationToken>()); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task DeleteFollowUp_WithBadId_ShouldThrowException() { | ||||
|         await Assert.ThrowsAsync<ArgumentException>(() => _pcrbService.DeleteFollowUp(0)); | ||||
|     } | ||||
|  | ||||
|     [Fact] | ||||
|     public async Task DeleteFollowUp_WithBadResponse_ShouldThrowException() { | ||||
|         var mockHttpMessageHandler = new Mock<HttpMessageHandler>(); | ||||
|  | ||||
|         mockHttpMessageHandler.Protected() | ||||
|             .Setup<Task<HttpResponseMessage>>( | ||||
|                 "SendAsync", | ||||
|                 ItExpr.Is<HttpRequestMessage>(_ => _.Method == HttpMethod.Delete), | ||||
|                 ItExpr.IsAny<CancellationToken>()) | ||||
|             .ReturnsAsync(UNSUCCESSFUL_RESPONSE) | ||||
|             .Verifiable(); | ||||
|  | ||||
|         var httpClient = new HttpClient(mockHttpMessageHandler.Object) { | ||||
|             BaseAddress = new Uri("https://localhost:5000") | ||||
|         }; | ||||
|  | ||||
|         _mockHttpClientFactory.Setup(_ => _.CreateClient(It.IsAny<string>())).Returns(httpClient); | ||||
|  | ||||
|         await Assert.ThrowsAsync<Exception>(() => _pcrbService.DeleteFollowUp(1)); | ||||
|     } | ||||
| } | ||||
| @ -30,4 +30,11 @@ | ||||
|         <ProjectReference Include="..\MesaFabApproval.Shared\MesaFabApproval.Shared.csproj" /> | ||||
|     </ItemGroup> | ||||
|  | ||||
|     <ItemGroup> | ||||
|       <Content Update="wwwroot\appsettings.Development.json"> | ||||
|         <ExcludeFromSingleFile>true</ExcludeFromSingleFile> | ||||
|         <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> | ||||
|       </Content> | ||||
|     </ItemGroup> | ||||
|  | ||||
| </Project> | ||||
|  | ||||
| @ -1,65 +1,2 @@ | ||||
| @page "/redirect" | ||||
| @attribute [AllowAnonymous] | ||||
| @inject MesaFabApprovalAuthStateProvider authStateProvider | ||||
| @inject IAuthenticationService authService | ||||
| @inject IUserService userService | ||||
| @inject ISnackbar snackbar | ||||
| @inject MesaFabApprovalAuthStateProvider authStateProvider | ||||
| @inject NavigationManager navigationManager | ||||
|  | ||||
| @code { | ||||
|     private string? _jwt; | ||||
|     private string? _refreshToken; | ||||
|     private string? _redirectPath; | ||||
|  | ||||
|     protected override async Task OnParametersSetAsync() { | ||||
|         try { | ||||
|             Uri uri = navigationManager.ToAbsoluteUri(navigationManager.Uri); | ||||
|  | ||||
|             if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("jwt", out var jwt)) { | ||||
|                 _jwt = System.Net.WebUtility.UrlDecode(jwt); | ||||
|             } | ||||
|  | ||||
|             if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("refreshToken", out var refreshToken)) { | ||||
|                 _refreshToken = System.Net.WebUtility.UrlDecode(refreshToken); | ||||
|             } | ||||
|  | ||||
|             if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("redirectPath", out var redirectPath)) { | ||||
|                 _redirectPath = redirectPath.ToString(); | ||||
|             } | ||||
|  | ||||
|             if (!string.IsNullOrWhiteSpace(_jwt) && !string.IsNullOrWhiteSpace(_refreshToken)) { | ||||
|                 await authService.SetTokens(_jwt, _refreshToken); | ||||
|  | ||||
|                 ClaimsPrincipal principal = authService.GetClaimsPrincipalFromJwt(_jwt); | ||||
|  | ||||
|                 string loginId = userService.GetLoginIdFromClaimsPrincipal(principal); | ||||
|  | ||||
|                 await authService.ClearCurrentUser(); | ||||
|                 await authService.ClearTokens(); | ||||
|  | ||||
|                 await authService.SetLoginId(loginId); | ||||
|                 await authService.SetTokens(_jwt, _refreshToken); | ||||
|                 await authService.SetCurrentUser(null); | ||||
|  | ||||
|                 await authStateProvider.StateHasChanged(principal); | ||||
|             } | ||||
|  | ||||
|             if (authStateProvider.CurrentUser is not null && !string.IsNullOrWhiteSpace(_redirectPath)) { | ||||
|                 navigationManager.NavigateTo(_redirectPath); | ||||
|             } else { | ||||
|                 await authStateProvider.Logout(); | ||||
|  | ||||
|                 if (!string.IsNullOrWhiteSpace(_redirectPath)) { | ||||
|                     navigationManager.NavigateTo($"login/{_redirectPath}"); | ||||
|                 } else { | ||||
|                     navigationManager.NavigateTo("login"); | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|         } catch (Exception ex) { | ||||
|             snackbar.Add($"Redirect failed, because {ex.Message}", Severity.Error); | ||||
|             navigationManager.NavigateTo("login"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										77
									
								
								MesaFabApproval.Client/Pages/AuthenticatedRedirect.razor.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								MesaFabApproval.Client/Pages/AuthenticatedRedirect.razor.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | ||||
| using MesaFabApproval.Client.Services; | ||||
|  | ||||
| using Microsoft.AspNetCore.Components; | ||||
| using Microsoft.AspNetCore.WebUtilities; | ||||
|  | ||||
| using MudBlazor; | ||||
|  | ||||
| using System.Security.Claims; | ||||
|  | ||||
| namespace MesaFabApproval.Client.Pages; | ||||
|  | ||||
| public partial class AuthenticatedRedirect { | ||||
|     [Inject] MesaFabApprovalAuthStateProvider authStateProvider { get; set; } | ||||
|     [Inject] IAuthenticationService authService { get; set; } | ||||
|     [Inject] IUserService userService { get; set; } | ||||
|     [Inject] ISnackbar snackbar { get; set; } | ||||
|     [Inject] NavigationManager navigationManager { get; set; } | ||||
|  | ||||
|     private string? _jwt; | ||||
|     private string? _refreshToken; | ||||
|     private string? _redirectPath; | ||||
|  | ||||
|     protected override async Task OnParametersSetAsync() { | ||||
|         try { | ||||
|             Uri uri = navigationManager.ToAbsoluteUri(navigationManager.Uri); | ||||
|  | ||||
|             if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("jwt", out var jwt)) { | ||||
|                 _jwt = System.Net.WebUtility.UrlDecode(jwt); | ||||
|             } | ||||
|  | ||||
|             if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("refreshToken", out var refreshToken)) { | ||||
|                 _refreshToken = System.Net.WebUtility.UrlDecode(refreshToken); | ||||
|             } | ||||
|  | ||||
|             if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("redirectPath", out var redirectPath)) { | ||||
|                 _redirectPath = redirectPath.ToString(); | ||||
|             } | ||||
|  | ||||
|             if (!string.IsNullOrWhiteSpace(_jwt) && !string.IsNullOrWhiteSpace(_refreshToken)) { | ||||
|                 await authService.SetTokens(_jwt, _refreshToken); | ||||
|  | ||||
|                 ClaimsPrincipal principal = authService.GetClaimsPrincipalFromJwt(_jwt); | ||||
|  | ||||
|                 string loginId = userService.GetLoginIdFromClaimsPrincipal(principal); | ||||
|  | ||||
|                 await authService.ClearCurrentUser(); | ||||
|                 await authService.ClearTokens(); | ||||
|  | ||||
|                 await authService.SetLoginId(loginId); | ||||
|                 await authService.SetTokens(_jwt, _refreshToken); | ||||
|                 await authService.SetCurrentUser(null); | ||||
|  | ||||
|                 await authStateProvider.StateHasChanged(principal); | ||||
|             } | ||||
|  | ||||
|             if (authStateProvider.CurrentUser is not null && !string.IsNullOrWhiteSpace(_redirectPath)) { | ||||
|                 navigationManager.NavigateTo(_redirectPath); | ||||
|             } else { | ||||
|                 await authStateProvider.Logout(); | ||||
|  | ||||
|                 if (!string.IsNullOrWhiteSpace(_redirectPath)) { | ||||
|                     navigationManager.NavigateTo($"login/{_redirectPath}"); | ||||
|                 } else { | ||||
|                     navigationManager.NavigateTo("login"); | ||||
|                 } | ||||
|             } | ||||
|         } catch (Exception ex) { | ||||
|             await authStateProvider.Logout(); | ||||
|  | ||||
|             if (!string.IsNullOrWhiteSpace(_redirectPath)) { | ||||
|                 navigationManager.NavigateTo($"login/{_redirectPath}"); | ||||
|             } else { | ||||
|                 navigationManager.NavigateTo("login"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -215,9 +215,7 @@ | ||||
|         bool actionIsValid = mrbAction.Action.Equals("Block") || mrbAction.Action.Equals("Convert") || | ||||
|             mrbAction.Action.Equals("Other") || mrbAction.Action.Equals("Recall") || mrbAction.Action.Equals("Scrap") || | ||||
|             mrbAction.Action.Equals("Unblock") || mrbAction.Action.Equals("Waiver"); | ||||
|         actionIsValid = actionIsValid && !string.IsNullOrWhiteSpace(mrbAction.Customer) && | ||||
|             !string.IsNullOrWhiteSpace(mrbAction.PartNumber) && | ||||
|             !string.IsNullOrWhiteSpace(mrbAction.LotNumber); | ||||
|         actionIsValid = actionIsValid && !string.IsNullOrWhiteSpace(mrbAction.LotNumber); | ||||
|         actionIsValid = actionIsValid && mrbAction.Quantity > 0; | ||||
|  | ||||
|         if (mrbAction.Action.Equals("Convert", StringComparison.InvariantCultureIgnoreCase)) { | ||||
| @ -225,6 +223,9 @@ | ||||
|                 !string.IsNullOrWhiteSpace(convertFromPart) && | ||||
|                 !string.IsNullOrWhiteSpace(convertToCustomer) && | ||||
|                 !string.IsNullOrWhiteSpace(convertToPart); | ||||
|         } else { | ||||
|             actionIsValid = actionIsValid && !string.IsNullOrWhiteSpace(mrbAction.Customer) && | ||||
|             !string.IsNullOrWhiteSpace(mrbAction.PartNumber); | ||||
|         } | ||||
|  | ||||
|         if (mrbAction.Action.Equals("Scrap", StringComparison.InvariantCultureIgnoreCase)) | ||||
|  | ||||
| @ -19,6 +19,7 @@ | ||||
|                               @bind-Value="@document.DocNumbers" | ||||
|                               @bind-Text="@document.DocNumbers" | ||||
|                               Immediate | ||||
|                               Required | ||||
|                               AutoGrow | ||||
|                               AutoFocus /> | ||||
|                 @if (DocNumberIsNA()) { | ||||
| @ -30,16 +31,16 @@ | ||||
|                                   Immediate | ||||
|                                   AutoGrow /> | ||||
|                 } else { | ||||
|                     <MudTextField @bind-Value="@document.ECNNumber" | ||||
|                                   Required | ||||
|                                   RequiredError="You must provide a valid ECN#" | ||||
|                                   Clearable | ||||
|                                   Variant="Variant.Outlined" | ||||
|                                   InputType="@InputType.Number" | ||||
|                                   Validation="@(new Func<int, Task<string>>(ECNNoIsValid))" | ||||
|                                   Label="ECN#" | ||||
|                                   Immediate | ||||
|                                   AutoGrow /> | ||||
|                     <MudAutocomplete @bind-Value="@document.ECNNumber" | ||||
|                                      T="int" | ||||
|                                      SearchFunc="Search" | ||||
|                                      Required | ||||
|                                      Clearable | ||||
|                                      RequiredError="You must provide a valid ECN#" | ||||
|                                      Variant="Variant.Outlined" | ||||
|                                      Validation="@(new Func<int, Task<string>>(ECNNoIsValid))" | ||||
|                                      Label="ECN#" | ||||
|                                      Immediate /> | ||||
|                 } | ||||
|                 <MudCheckBox Label="Complete" | ||||
|                              Color="Color.Tertiary" | ||||
| @ -49,8 +50,8 @@ | ||||
|         </MudPaper> | ||||
|     </DialogContent> | ||||
|     <DialogActions> | ||||
|         @if ((DocNumberIsNA() && !string.IsNullOrWhiteSpace(document.Comment)) ||  | ||||
|              (!DocNumberIsNA() && ecnNoIsValid)) { | ||||
|         @if (!string.IsNullOrWhiteSpace(document.DocNumbers) && ((DocNumberIsNA() && !string.IsNullOrWhiteSpace(document.Comment)) ||  | ||||
|              (!DocNumberIsNA() && ecnNoIsValid))) { | ||||
|             <MudButton Variant="Variant.Filled" | ||||
|                        Color="Color.Tertiary" | ||||
|                        Class="m1-auto" | ||||
| @ -78,6 +79,8 @@ | ||||
|     [Parameter] | ||||
|     public required PCR3Document document { get; set; } | ||||
|  | ||||
|     private IEnumerable<int> allEcnNumbers = new List<int>(); | ||||
|  | ||||
|     private string[] errors = { }; | ||||
|  | ||||
|     private bool complete = false; | ||||
| @ -88,6 +91,8 @@ | ||||
|  | ||||
|     protected override async Task OnParametersSetAsync() { | ||||
|         complete = document.CompletedByID > 0; | ||||
|  | ||||
|         allEcnNumbers = await ecnService.GetAllECNNumbers(); | ||||
|     } | ||||
|  | ||||
|     private async Task Save() { | ||||
| @ -111,6 +116,10 @@ | ||||
|                 document.CompletedDate = DateTime.Now; | ||||
|             } | ||||
|  | ||||
|             if (string.IsNullOrWhiteSpace(document.DocNumbers)) { | ||||
|                 throw new Exception("Document Numbers cannot be empty"); | ||||
|             } | ||||
|  | ||||
|             if (!DocNumberIsNA() && !ecnNoIsValid)  | ||||
|                 throw new Exception($"{document.ECNNumber} is not a valid ECN#"); | ||||
|             if (DocNumberIsNA() && string.IsNullOrWhiteSpace(document.Comment)) | ||||
| @ -135,7 +144,11 @@ | ||||
|  | ||||
|     private bool DocNumberIsNA() { | ||||
|         if (document.DocNumbers.ToLower().Equals("na") || | ||||
|             document.DocNumbers.ToLower().Equals("n/a")) { | ||||
|             document.DocNumbers.ToLower().Equals("n/a") || | ||||
|             document.DocNumbers.ToLower().Equals("n a") || | ||||
|             document.DocNumbers.ToLower().Equals("not applicable")) { | ||||
|             if (string.IsNullOrWhiteSpace(document.Comment)) | ||||
|                 document.Comment = "Not required"; | ||||
|             return true; | ||||
|         } | ||||
|         return false; | ||||
| @ -148,4 +161,13 @@ | ||||
|         StateHasChanged(); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     private async Task<IEnumerable<int>> Search(string searchValue, CancellationToken token) { | ||||
|         if (string.IsNullOrWhiteSpace(searchValue)) | ||||
|             return allEcnNumbers; | ||||
|  | ||||
|         return allEcnNumbers | ||||
|                 .Where(x => x.ToString().StartsWith(searchValue, StringComparison.InvariantCultureIgnoreCase)) | ||||
|                 .Order(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,16 +1,5 @@ | ||||
| @page "/" | ||||
| @page "/Dashboard" | ||||
| @inject IConfiguration Configuration | ||||
| @inject MesaFabApprovalAuthStateProvider stateProvider | ||||
| @inject IApprovalService approvalService | ||||
| @inject IMemoryCache cache | ||||
| @inject NavigationManager navigationManager | ||||
| @inject ISnackbar snackbar | ||||
| @inject IMRBService mrbService | ||||
| @inject IPCRBService pcrbService | ||||
| @inject IECNService ecnService | ||||
| @inject ICAService caService | ||||
| @inject IJSRuntime jsRuntime | ||||
|  | ||||
| <PageTitle>Dashboard</PageTitle> | ||||
|  | ||||
| @ -226,138 +215,3 @@ | ||||
|         </MudTabPanel> | ||||
|     </MudTabs> | ||||
| </MudPaper> | ||||
|  | ||||
| @code { | ||||
|     private IEnumerable<Approval> approvalList = new List<Approval>(); | ||||
|     private IEnumerable<MRB> myMRBs = new List<MRB>(); | ||||
|     private IEnumerable<PCRB> myPCRBs = new List<PCRB>(); | ||||
|  | ||||
|     private IEnumerable<int> ecnNumbers = new HashSet<int>(); | ||||
|     private IEnumerable<int> caNumbers = new HashSet<int>(); | ||||
|     private IEnumerable<int> mrbNumbers = new HashSet<int>(); | ||||
|     private IEnumerable<int> pcrbNumbers = new HashSet<int>(); | ||||
|  | ||||
|     private bool myApprovalsProcessing = false; | ||||
|     private bool myMrbsProcessing = false; | ||||
|     private bool myPcrbsProcessing = false; | ||||
|  | ||||
|     private string mrbSearchString = ""; | ||||
|     private string pcrbSearchString = ""; | ||||
|  | ||||
|     protected async override Task OnParametersSetAsync() { | ||||
|         try { | ||||
|             if (stateProvider.CurrentUser is not null) { | ||||
|                 myApprovalsProcessing = true; | ||||
|                 approvalList = (await approvalService.GetApprovalsForUserId(stateProvider.CurrentUser.UserID, true)) | ||||
|                     .Where(a => a.CompletedDate > DateTime.Now && a.ItemStatus == 0) | ||||
|                     .ToList() | ||||
|                     .OrderByDescending(x => x.AssignedDate); | ||||
|                 myApprovalsProcessing = false; | ||||
|  | ||||
|                 myMrbsProcessing = true; | ||||
|                 myMRBs = (await mrbService.GetAllMRBs(false)).Where(m => m.OriginatorID == stateProvider.CurrentUser.UserID) | ||||
|                     .ToList() | ||||
|                     .OrderByDescending(x => x.SubmittedDate); | ||||
|                 myMrbsProcessing = false; | ||||
|  | ||||
|                 myPcrbsProcessing = true; | ||||
|                 myPCRBs = (await pcrbService.GetAllPCRBs(false)).Where(p => p.OwnerID == stateProvider.CurrentUser.UserID) | ||||
|                     .ToList() | ||||
|                     .OrderByDescending(p => p.InsertTimeStamp); | ||||
|                 myPcrbsProcessing = false; | ||||
|             } | ||||
|         } catch (Exception ex) { | ||||
|             myApprovalsProcessing = false; | ||||
|             myMrbsProcessing = false; | ||||
|             myPcrbsProcessing = false; | ||||
|             snackbar.Add($"Unable to load the dashboard, because {ex.Message}", Severity.Error); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private async Task FollowLink(int issueId) { | ||||
|         HashSet<Task> tasks = new(); | ||||
|  | ||||
|         bool isEcn = false; | ||||
|         bool isCa = false; | ||||
|         bool isMrb = false; | ||||
|         bool isPcrb = false; | ||||
|         if (ecnNumbers.Contains(issueId)) | ||||
|             isEcn = true; | ||||
|         if (caNumbers.Contains(issueId)) | ||||
|             isCa = true; | ||||
|         if (mrbNumbers.Contains(issueId)) | ||||
|             isMrb = true; | ||||
|         if (pcrbNumbers.Contains(issueId)) | ||||
|             isPcrb = true; | ||||
|  | ||||
|         if (!isEcn && !isCa && !isMrb) { | ||||
|             Task<bool> isEcnTask = ecnService.ECNNumberIsValid(issueId); | ||||
|             tasks.Add(isEcnTask); | ||||
|  | ||||
|             Task<bool> isCaTask = caService.CANumberIsValid(issueId); | ||||
|             tasks.Add(isCaTask); | ||||
|  | ||||
|             Task<bool> isMrbTask = mrbService.NumberIsValid(issueId); | ||||
|             tasks.Add(isMrbTask); | ||||
|  | ||||
|             Task<bool> isPcrbTask = pcrbService.IdIsValid(issueId); | ||||
|             tasks.Add(isPcrbTask); | ||||
|  | ||||
|             await Task.WhenAll(tasks); | ||||
|  | ||||
|             if (isEcnTask.Result) { | ||||
|                 isEcn = true; | ||||
|             } else if (isCaTask.Result) { | ||||
|                 isCa = true; | ||||
|             } else if (isMrbTask.Result) { | ||||
|                 isMrb = true; | ||||
|             } else if (isPcrbTask.Result) { | ||||
|                 isPcrb = true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (isEcn) await GoToExternal($"{Configuration["OldFabApprovalUrl"]}/ECN/Edit?IssueID={issueId}", ""); | ||||
|         if (isCa) await GoToExternal($"{Configuration["OldFabApprovalUrl"]}/CorrectiveAction/Edit?IssueID={issueId}", ""); | ||||
|         if (isMrb) GoTo($"mrb/{issueId}"); | ||||
|         if (isPcrb) GoTo($"pcrb/{issueId}"); | ||||
|     } | ||||
|  | ||||
|     private void GoTo(string page) { | ||||
|         cache.Set("redirectUrl", page); | ||||
|         navigationManager.NavigateTo("/" + page); | ||||
|     } | ||||
|  | ||||
|     private async Task GoToExternal(string url, string content) { | ||||
|         IJSObjectReference windowModule = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "./js/OpenInNewWindow.js"); | ||||
|         await windowModule.InvokeAsync<object>("OpenInNewWindow", url, content); | ||||
|     } | ||||
|  | ||||
|     private bool FilterFuncForMRBTable(MRB mrb) => MRBFilterFunc(mrb, mrbSearchString); | ||||
|  | ||||
|     private bool MRBFilterFunc(MRB mrb, string searchString) { | ||||
|         if (string.IsNullOrWhiteSpace(searchString)) | ||||
|             return true; | ||||
|         if (mrb.Title.ToLower().Contains(searchString.Trim().ToLower())) | ||||
|             return true; | ||||
|         if (mrb.MRBNumber.ToString().Contains(searchString.Trim())) | ||||
|             return true; | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     private bool FilterFuncForPCRBTable(PCRB pcrb) => PCRBFilterFunc(pcrb, pcrbSearchString); | ||||
|  | ||||
|     private bool PCRBFilterFunc(PCRB pcrb, string searchString) { | ||||
|         if (string.IsNullOrWhiteSpace(searchString)) | ||||
|             return true; | ||||
|         if (pcrb.Title.ToLower().Contains(searchString.Trim().ToLower())) | ||||
|             return true; | ||||
|         if (pcrb.PlanNumber.ToString().Contains(searchString.Trim())) | ||||
|             return true; | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     private string GetCurrentPCRBStep(int step) { | ||||
|         if (step < 0 || step > (PCRB.Stages.Length - 1)) return string.Empty; | ||||
|         else return PCRB.Stages[step]; | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										157
									
								
								MesaFabApproval.Client/Pages/Dashboard.razor.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								MesaFabApproval.Client/Pages/Dashboard.razor.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,157 @@ | ||||
| using MesaFabApproval.Client.Services; | ||||
| using MesaFabApproval.Shared.Models; | ||||
|  | ||||
| using Microsoft.AspNetCore.Components; | ||||
| using Microsoft.Extensions.Caching.Memory; | ||||
| using Microsoft.JSInterop; | ||||
|  | ||||
| using MudBlazor; | ||||
|  | ||||
| namespace MesaFabApproval.Client.Pages; | ||||
|  | ||||
| public partial class Dashboard { | ||||
|     [Inject] IConfiguration Configuration { get; set; } | ||||
|     [Inject] MesaFabApprovalAuthStateProvider stateProvider { get; set; } | ||||
|     [Inject] IApprovalService approvalService { get; set; } | ||||
|     [Inject] IMemoryCache cache { get; set; } | ||||
|     [Inject] NavigationManager navigationManager { get; set; } | ||||
|     [Inject] ISnackbar snackbar { get; set; } | ||||
|     [Inject] IMRBService mrbService { get; set; } | ||||
|     [Inject] IPCRBService pcrbService { get; set; } | ||||
|     [Inject] IECNService ecnService { get; set; } | ||||
|     [Inject] ICAService caService { get; set; } | ||||
|     [Inject] IJSRuntime jsRuntime { get; set; } | ||||
|  | ||||
|     private IEnumerable<Approval> approvalList = new List<Approval>(); | ||||
|     private IEnumerable<MRB> myMRBs = new List<MRB>(); | ||||
|     private IEnumerable<PCRB> myPCRBs = new List<PCRB>(); | ||||
|  | ||||
|     private IEnumerable<int> ecnNumbers = new HashSet<int>(); | ||||
|     private IEnumerable<int> caNumbers = new HashSet<int>(); | ||||
|     private IEnumerable<int> mrbNumbers = new HashSet<int>(); | ||||
|     private IEnumerable<int> pcrbNumbers = new HashSet<int>(); | ||||
|  | ||||
|     private bool myApprovalsProcessing = false; | ||||
|     private bool myMrbsProcessing = false; | ||||
|     private bool myPcrbsProcessing = false; | ||||
|  | ||||
|     private string mrbSearchString = ""; | ||||
|     private string pcrbSearchString = ""; | ||||
|  | ||||
|     protected async override Task OnParametersSetAsync() { | ||||
|         try { | ||||
|             if (stateProvider.CurrentUser is not null) { | ||||
|                 myApprovalsProcessing = true; | ||||
|                 approvalList = (await approvalService.GetApprovalsForUserId(stateProvider.CurrentUser.UserID, true)) | ||||
|                     .Where(a => a.CompletedDate > DateTime.Now && a.ItemStatus == 0) | ||||
|                     .ToList() | ||||
|                     .OrderByDescending(x => x.AssignedDate); | ||||
|                 myApprovalsProcessing = false; | ||||
|  | ||||
|                 myMrbsProcessing = true; | ||||
|                 myMRBs = (await mrbService.GetAllMRBs(false)).Where(m => m.OriginatorID == stateProvider.CurrentUser.UserID) | ||||
|                     .ToList() | ||||
|                     .OrderByDescending(x => x.SubmittedDate); | ||||
|                 myMrbsProcessing = false; | ||||
|  | ||||
|                 myPcrbsProcessing = true; | ||||
|                 myPCRBs = (await pcrbService.GetAllPCRBs(false)).Where(p => p.OwnerID == stateProvider.CurrentUser.UserID) | ||||
|                     .ToList() | ||||
|                     .OrderByDescending(p => p.InsertTimeStamp); | ||||
|                 myPcrbsProcessing = false; | ||||
|             } | ||||
|         } catch (Exception ex) { | ||||
|             myApprovalsProcessing = false; | ||||
|             myMrbsProcessing = false; | ||||
|             myPcrbsProcessing = false; | ||||
|             snackbar.Add(ex.Message, Severity.Error); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private async Task FollowLink(int issueId) { | ||||
|         HashSet<Task> tasks = new(); | ||||
|  | ||||
|         bool isEcn = false; | ||||
|         bool isCa = false; | ||||
|         bool isMrb = false; | ||||
|         bool isPcrb = false; | ||||
|         if (ecnNumbers.Contains(issueId)) | ||||
|             isEcn = true; | ||||
|         if (caNumbers.Contains(issueId)) | ||||
|             isCa = true; | ||||
|         if (mrbNumbers.Contains(issueId)) | ||||
|             isMrb = true; | ||||
|         if (pcrbNumbers.Contains(issueId)) | ||||
|             isPcrb = true; | ||||
|  | ||||
|         if (!isEcn && !isCa && !isMrb) { | ||||
|             Task<bool> isEcnTask = ecnService.ECNNumberIsValid(issueId); | ||||
|             tasks.Add(isEcnTask); | ||||
|  | ||||
|             Task<bool> isCaTask = caService.CANumberIsValid(issueId); | ||||
|             tasks.Add(isCaTask); | ||||
|  | ||||
|             Task<bool> isMrbTask = mrbService.NumberIsValid(issueId); | ||||
|             tasks.Add(isMrbTask); | ||||
|  | ||||
|             Task<bool> isPcrbTask = pcrbService.IdIsValid(issueId); | ||||
|             tasks.Add(isPcrbTask); | ||||
|  | ||||
|             await Task.WhenAll(tasks); | ||||
|  | ||||
|             if (isEcnTask.Result) { | ||||
|                 isEcn = true; | ||||
|             } else if (isCaTask.Result) { | ||||
|                 isCa = true; | ||||
|             } else if (isMrbTask.Result) { | ||||
|                 isMrb = true; | ||||
|             } else if (isPcrbTask.Result) { | ||||
|                 isPcrb = true; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (isEcn) await GoToExternal($"{Configuration["OldFabApprovalUrl"]}/ECN/Edit?IssueID={issueId}", ""); | ||||
|         if (isCa) await GoToExternal($"{Configuration["OldFabApprovalUrl"]}/CorrectiveAction/Edit?IssueID={issueId}", ""); | ||||
|         if (isMrb) GoTo($"mrb/{issueId}"); | ||||
|         if (isPcrb) GoTo($"pcrb/{issueId}"); | ||||
|     } | ||||
|  | ||||
|     private void GoTo(string page) { | ||||
|         cache.Set("redirectUrl", page); | ||||
|         navigationManager.NavigateTo("/" + page); | ||||
|     } | ||||
|  | ||||
|     private async Task GoToExternal(string url, string content) { | ||||
|         IJSObjectReference windowModule = await jsRuntime.InvokeAsync<IJSObjectReference>("import", "./js/OpenInNewWindow.js"); | ||||
|         await windowModule.InvokeAsync<object>("OpenInNewWindow", url, content); | ||||
|     } | ||||
|  | ||||
|     private bool FilterFuncForMRBTable(MRB mrb) => MRBFilterFunc(mrb, mrbSearchString); | ||||
|  | ||||
|     private bool MRBFilterFunc(MRB mrb, string searchString) { | ||||
|         if (string.IsNullOrWhiteSpace(searchString)) | ||||
|             return true; | ||||
|         if (mrb.Title.ToLower().Contains(searchString.Trim().ToLower())) | ||||
|             return true; | ||||
|         if (mrb.MRBNumber.ToString().Contains(searchString.Trim())) | ||||
|             return true; | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     private bool FilterFuncForPCRBTable(PCRB pcrb) => PCRBFilterFunc(pcrb, pcrbSearchString); | ||||
|  | ||||
|     private bool PCRBFilterFunc(PCRB pcrb, string searchString) { | ||||
|         if (string.IsNullOrWhiteSpace(searchString)) | ||||
|             return true; | ||||
|         if (pcrb.Title.ToLower().Contains(searchString.Trim().ToLower())) | ||||
|             return true; | ||||
|         if (pcrb.PlanNumber.ToString().Contains(searchString.Trim())) | ||||
|             return true; | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     private string GetCurrentPCRBStep(int step) { | ||||
|         if (step < 0 || step > (PCRB.Stages.Length - 1)) return string.Empty; | ||||
|         else return PCRB.Stages[step]; | ||||
|     } | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1025
									
								
								MesaFabApproval.Client/Pages/MRBSingle.razor.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1025
									
								
								MesaFabApproval.Client/Pages/MRBSingle.razor.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1139
									
								
								MesaFabApproval.Client/Pages/PCRBSingle.razor.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1139
									
								
								MesaFabApproval.Client/Pages/PCRBSingle.razor.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -5,6 +5,7 @@ namespace MesaFabApproval.Client.Services; | ||||
| public interface IECNService { | ||||
|     Task<string> ECNNumberIsValidStr(int ecnNumber); | ||||
|     Task<bool> ECNNumberIsValid(int number); | ||||
|     Task<IEnumerable<int>> GetAllECNNumbers(); | ||||
| } | ||||
|  | ||||
| public class ECNService : IECNService { | ||||
| @ -49,4 +50,32 @@ public class ECNService : IECNService { | ||||
|             throw new Exception($"Unable to determine if {number} is a valid ECN#, because {ex.Message}"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public async Task<IEnumerable<int>> GetAllECNNumbers() { | ||||
|         try { | ||||
|             HttpClient httpClient = _httpClientFactory.CreateClient("API"); | ||||
|  | ||||
|             HttpRequestMessage requestMessage = new(HttpMethod.Get, $"ecn/allNumbers"); | ||||
|  | ||||
|             HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage); | ||||
|  | ||||
|             if (responseMessage.IsSuccessStatusCode) { | ||||
|                 string responseContent = await responseMessage.Content.ReadAsStringAsync(); | ||||
|  | ||||
|                 JsonSerializerOptions jsonSerializerOptions = new() { | ||||
|                     PropertyNameCaseInsensitive = true | ||||
|                 }; | ||||
|  | ||||
|                 IEnumerable<int> allEcnNumbers = | ||||
|                     JsonSerializer.Deserialize<IEnumerable<int>>(responseContent, jsonSerializerOptions) ?? | ||||
|                     new List<int>(); | ||||
|  | ||||
|                 return allEcnNumbers; | ||||
|             } else { | ||||
|                 throw new Exception(responseMessage.ReasonPhrase); | ||||
|             } | ||||
|         } catch (Exception ex) { | ||||
|             throw new Exception($"Unable to get all ECN#s, because {ex.Message}"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -4,7 +4,6 @@ using System.Text.Json; | ||||
|  | ||||
| using MesaFabApproval.Shared.Models; | ||||
|  | ||||
| using Microsoft.AspNetCore.Components.Forms; | ||||
| using Microsoft.AspNetCore.StaticFiles; | ||||
| using Microsoft.Extensions.Caching.Memory; | ||||
|  | ||||
| @ -40,6 +39,10 @@ public interface IPCRBService { | ||||
|     Task NotifyApprovers(PCRBNotification notification); | ||||
|     Task NotifyOriginator(PCRBNotification notification); | ||||
|     Task NotifyResponsiblePerson(PCRBActionItemNotification notification); | ||||
|     Task CreateFollowUp(PCRBFollowUp followUp); | ||||
|     Task<IEnumerable<PCRBFollowUp>> GetFollowUpsByPlanNumber(int planNumber, bool bypassCache); | ||||
|     Task UpdateFollowUp(PCRBFollowUp followUp); | ||||
|     Task DeleteFollowUp(int id); | ||||
| } | ||||
|  | ||||
| public class PCRBService : IPCRBService { | ||||
| @ -764,4 +767,86 @@ public class PCRBService : IPCRBService { | ||||
|         if (!responseMessage.IsSuccessStatusCode) | ||||
|             throw new Exception($"Unable to notify PCRB responsible person, because {responseMessage.ReasonPhrase}"); | ||||
|     } | ||||
|  | ||||
|     public async Task CreateFollowUp(PCRBFollowUp followUp) { | ||||
|         if (followUp is null) throw new ArgumentNullException("follow up cannot be null"); | ||||
|  | ||||
|         HttpClient httpClient = _httpClientFactory.CreateClient("API"); | ||||
|  | ||||
|         HttpRequestMessage requestMessage = new(HttpMethod.Post, $"pcrb/followUp") { | ||||
|             Content = new StringContent(JsonSerializer.Serialize(followUp), | ||||
|                                                Encoding.UTF8, | ||||
|                                                "application/json") | ||||
|         }; | ||||
|  | ||||
|         HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage); | ||||
|  | ||||
|         if (!responseMessage.IsSuccessStatusCode) | ||||
|             throw new Exception(responseMessage.ReasonPhrase); | ||||
|  | ||||
|         await GetFollowUpsByPlanNumber(followUp.PlanNumber, true); | ||||
|     } | ||||
|  | ||||
|     public async Task<IEnumerable<PCRBFollowUp>> GetFollowUpsByPlanNumber(int planNumber, bool bypassCache) { | ||||
|         if (planNumber <= 0) throw new ArgumentException($"{planNumber} is not a valid PCRB Plan#"); | ||||
|  | ||||
|         IEnumerable<PCRBFollowUp>? followUps = null; | ||||
|         if (!bypassCache) | ||||
|             followUps = _cache.Get<IEnumerable<PCRBFollowUp>>($"pcrbFollowUps{planNumber}"); | ||||
|  | ||||
|         if (followUps is null) { | ||||
|             HttpClient httpClient = _httpClientFactory.CreateClient("API"); | ||||
|  | ||||
|             HttpRequestMessage requestMessage = new(HttpMethod.Get, $"pcrb/followUps?planNumber={planNumber}&bypassCache={bypassCache}"); | ||||
|  | ||||
|             HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage); | ||||
|  | ||||
|             if (responseMessage.IsSuccessStatusCode) { | ||||
|                 string responseContent = await responseMessage.Content.ReadAsStringAsync(); | ||||
|  | ||||
|                 JsonSerializerOptions jsonSerializerOptions = new() { | ||||
|                     PropertyNameCaseInsensitive = true | ||||
|                 }; | ||||
|  | ||||
|                 followUps = JsonSerializer.Deserialize<IEnumerable<PCRBFollowUp>>(responseContent, jsonSerializerOptions) ?? | ||||
|                     new List<PCRBFollowUp>(); | ||||
|  | ||||
|                 if (followUps.Count() > 0) | ||||
|                     _cache.Set($"pcrbFollowUps{planNumber}", followUps, DateTimeOffset.Now.AddMinutes(5)); | ||||
|             } else { | ||||
|                 throw new Exception(responseMessage.ReasonPhrase); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return followUps; | ||||
|     } | ||||
|      | ||||
|     public async Task UpdateFollowUp(PCRBFollowUp followUp) { | ||||
|         if (followUp is null) throw new ArgumentNullException("follow up cannot be null"); | ||||
|  | ||||
|         HttpClient httpClient = _httpClientFactory.CreateClient("API"); | ||||
|  | ||||
|         HttpRequestMessage requestMessage = new(HttpMethod.Put, $"pcrb/followUp") { | ||||
|             Content = new StringContent(JsonSerializer.Serialize(followUp), | ||||
|                                                    Encoding.UTF8, | ||||
|                                                    "application/json") | ||||
|         }; | ||||
|  | ||||
|         HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage); | ||||
|  | ||||
|         if (!responseMessage.IsSuccessStatusCode) | ||||
|             throw new Exception(responseMessage.ReasonPhrase); | ||||
|     } | ||||
|  | ||||
|     public async Task DeleteFollowUp(int id) { | ||||
|         if (id <= 0) throw new ArgumentException($"{id} is not a valid PCRB follow up ID"); | ||||
|  | ||||
|         HttpClient httpClient = _httpClientFactory.CreateClient("API"); | ||||
|  | ||||
|         HttpRequestMessage requestMessage = new(HttpMethod.Delete, $"pcrb/followUp?id={id}"); | ||||
|  | ||||
|         HttpResponseMessage responseMessage = await httpClient.SendAsync(requestMessage); | ||||
|  | ||||
|         if (!responseMessage.IsSuccessStatusCode) throw new Exception(responseMessage.ReasonPhrase); | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										100
									
								
								MesaFabApproval.Client/pipeline.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								MesaFabApproval.Client/pipeline.yml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,100 @@ | ||||
| trigger: | ||||
|   branches: | ||||
|     include: | ||||
|       - master | ||||
|   paths: | ||||
|     include: | ||||
|       - MesaFabApproval.Client | ||||
|       - MesaFabApproval.Shared | ||||
|  | ||||
| variables: | ||||
|   buildConfiguration: "Release" | ||||
|  | ||||
| stages: | ||||
|   - stage: Test | ||||
|     displayName: "Test" | ||||
|     pool: | ||||
|       name: MesaFabApproval | ||||
|       demands: Fab2ApprovalSystem-Dev | ||||
|     jobs: | ||||
|       - job: BuildPublish | ||||
|         steps: | ||||
|           - script: | | ||||
|               echo build configuration: $(BuildConfiguration) | ||||
|             displayName: "Echo Check" | ||||
|  | ||||
|           - task: DotNetCoreCLI@2 | ||||
|             displayName: "Build" | ||||
|             inputs: | ||||
|               command: "build" | ||||
|               configuration: $(BuildConfiguration) | ||||
|               projects: MesaFabApproval.Client | ||||
|  | ||||
|           - task: DotNetCoreCLI@2 | ||||
|             displayName: "Test" | ||||
|             inputs: | ||||
|               command: "test" | ||||
|               configuration: $(BuildConfiguration) | ||||
|               publishTestResults: true | ||||
|               projects: MesaFabApproval.Client.Test | ||||
|  | ||||
|           - task: DotNetCoreCLI@2 | ||||
|             displayName: "Publish" | ||||
|             inputs: | ||||
|               command: "publish" | ||||
|               publishWebProjects: false | ||||
|               projects: MesaFabApproval.Client | ||||
|               zipAfterPublish: true | ||||
|               arguments: "-c $(BuildConfiguration) -o $(Build.ArtifactStagingDirectory) -r win-x64 --self-contained" | ||||
|  | ||||
|           - task: CopyFiles@2 | ||||
|             displayName: "Copy Files" | ||||
|             inputs: | ||||
|               SourceFolder: "$(Build.ArtifactStagingDirectory)" | ||||
|               TargetFolder: 'D:\$(Build.Repository.Name)\Client\$(Build.BuildId)\$(BuildConfiguration)' | ||||
|               CleanTargetFolder: true | ||||
|               retryCount: "3" | ||||
|  | ||||
|   - stage: Prod | ||||
|     displayName: "Prod" | ||||
|     pool: | ||||
|       name: MesaFabApproval | ||||
|       demands: Fab2ApprovalSystem | ||||
|     jobs: | ||||
|       - job: BuildPublish | ||||
|         steps: | ||||
|           - script: | | ||||
|               echo build configuration: $(BuildConfiguration) | ||||
|             displayName: "Echo Check" | ||||
|  | ||||
|           - task: DotNetCoreCLI@2 | ||||
|             displayName: "Build" | ||||
|             inputs: | ||||
|               command: "build" | ||||
|               configuration: $(BuildConfiguration) | ||||
|               projects: MesaFabApproval.Client | ||||
|  | ||||
|           - task: DotNetCoreCLI@2 | ||||
|             displayName: "Test" | ||||
|             inputs: | ||||
|               command: "test" | ||||
|               configuration: $(BuildConfiguration) | ||||
|               publishTestResults: true | ||||
|               projects: MesaFabApproval.Client.Test | ||||
|  | ||||
|           - task: DotNetCoreCLI@2 | ||||
|             displayName: "Publish" | ||||
|             inputs: | ||||
|               command: "publish" | ||||
|               publishWebProjects: false | ||||
|               projects: MesaFabApproval.Client | ||||
|               zipAfterPublish: true | ||||
|               arguments: "-c $(BuildConfiguration) -o $(Build.ArtifactStagingDirectory) -r win-x64 --self-contained" | ||||
|  | ||||
|           - task: CopyFiles@2 | ||||
|             displayName: "Copy Files" | ||||
|             inputs: | ||||
|               SourceFolder: "$(Build.ArtifactStagingDirectory)" | ||||
|               TargetFolder: 'D:\$(Build.Repository.Name)\Client\$(Build.BuildId)\$(BuildConfiguration)' | ||||
|               CleanTargetFolder: true | ||||
|               retryCount: "3" | ||||
| @ -0,0 +1,4 @@ | ||||
| { | ||||
|   "OldFabApprovalUrl": "https://mesaapproval-test.mes.infineon.com", | ||||
|   "FabApprovalApiBaseUrl": "https://mesaapproval-test.mes.infineon.com:7114" | ||||
| } | ||||
| @ -1,4 +1,4 @@ | ||||
| { | ||||
|   "OldFabApprovalUrl": "https://mesaapproval-test.mes.infineon.com", | ||||
|   "FabApprovalApiBaseUrl": "https://mesaapproval-test.mes.infineon.com:7114" | ||||
|   "OldFabApprovalUrl": "https://mesaapproval.mes.infineon.com", | ||||
|   "FabApprovalApiBaseUrl": "https://mesaapproval.mes.infineon.com:7114" | ||||
| } | ||||
| @ -6,7 +6,7 @@ public class PCR3Document { | ||||
|     public int ID { get; set; } | ||||
|     public required int PlanNumber { get; set; } | ||||
|     public required string DocType { get; set; } | ||||
|     public string DocNumbers { get; set; } = "N/A"; | ||||
|     public string DocNumbers { get; set; } = string.Empty; | ||||
|     public DateTime CompletedDate { get; set; } = DateTimeUtilities.MAX_DT; | ||||
|     public int CompletedByID { get; set; } = 0; | ||||
|     public User? CompletedBy { get; set; } | ||||
|  | ||||
| @ -23,4 +23,5 @@ public class PCRB { | ||||
|     public DateTime InsertTimeStamp { get; set; } = DateTimeUtilities.MIN_DT; | ||||
|     public DateTime LastUpdateDate { get; set; } = DateTimeUtilities.MIN_DT; | ||||
|     public DateTime ClosedDate { get; set; } = DateTimeUtilities.MAX_DT; | ||||
|     public string Type { get; set; } = ""; | ||||
| } | ||||
							
								
								
									
										14
									
								
								MesaFabApproval.Shared/Models/PCRBFollowUp.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								MesaFabApproval.Shared/Models/PCRBFollowUp.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| using MesaFabApproval.Shared.Utilities; | ||||
|  | ||||
| namespace MesaFabApproval.Shared.Models; | ||||
|  | ||||
| public class PCRBFollowUp { | ||||
|     public int ID { get; set; } | ||||
|     public required int PlanNumber { get; set; } | ||||
|     public required int Step { get; set; } | ||||
|     public required DateTime FollowUpDate { get; set; } | ||||
|     public bool IsComplete { get; set; } = false; | ||||
|     public bool IsDeleted { get; set; } = false; | ||||
|     public DateTime CompletedDate { get; set; } = DateTimeUtilities.MAX_DT; | ||||
|     public string Comments { get; set; } = string.Empty; | ||||
| } | ||||
| @ -1,16 +0,0 @@ | ||||
| USE [FabApprovalSystem] | ||||
| GO | ||||
|   /****** Object:  UserDefinedFunction [dbo].[EncodeHtml]    Script Date: 11/21/2024 11:31:55 AM ******/ | ||||
| SET | ||||
|   ANSI_NULLS ON | ||||
| GO | ||||
| SET | ||||
|   QUOTED_IDENTIFIER ON | ||||
| GO | ||||
|   CREATE FUNCTION [dbo].[EncodeHtml] (@RawStr varchar(max)) RETURNS varchar(max) AS BEGIN RETURN REPLACE( | ||||
|     REPLACE(REPLACE(@RawStr, '&', '&'), '<', '<'), | ||||
|     '>', | ||||
|     '>' | ||||
|   ) | ||||
| END | ||||
| GO | ||||
| @ -1,33 +0,0 @@ | ||||
| USE [FabApprovalSystem] | ||||
| GO | ||||
| 	/****** Object:  UserDefinedFunction [dbo].[fn8DConvertCANoToCADisplayFormat]    Script Date: 11/21/2024 11:31:55 AM ******/ | ||||
| SET | ||||
| 	ANSI_NULLS ON | ||||
| GO | ||||
| SET | ||||
| 	QUOTED_IDENTIFIER ON | ||||
| GO | ||||
| 	-- ============================================= | ||||
| 	-- Author:		<Author,,Name> | ||||
| 	-- Create date: <Create Date, ,> | ||||
| 	-- Description:	<Description, ,> | ||||
| 	-- ============================================= | ||||
| 	CREATE FUNCTION [dbo].[fn8DConvertCANoToCADisplayFormat] ( | ||||
| 		-- Add the parameters for the function here | ||||
| 		@CANo INT | ||||
| 	) RETURNS VARCHAR(10) AS BEGIN -- Declare the return variable here | ||||
| 	DECLARE @CADisplay VARCHAR(10) -- Add the T-SQL statements to compute the return value here | ||||
| SET | ||||
| 	@CADisplay = LTRIM( | ||||
| 		RTRIM( | ||||
| 			CAST( | ||||
| 				'C' + RIGHT( | ||||
| 					'00000' + ISNULL(CAST(@CANo AS VARCHAR(10)), ''), | ||||
| 					5 | ||||
| 				) AS VARCHAR(50) | ||||
| 			) | ||||
| 		) | ||||
| 	) -- Return the result of the function | ||||
| 	RETURN @CADisplay | ||||
| END | ||||
| GO | ||||
| @ -1,28 +0,0 @@ | ||||
| USE [FabApprovalSystem] | ||||
| GO | ||||
| 	/****** Object:  UserDefinedFunction [dbo].[fnAuditConvertAuditNoToDisplayFormat]    Script Date: 11/21/2024 11:31:55 AM ******/ | ||||
| SET | ||||
| 	ANSI_NULLS ON | ||||
| GO | ||||
| SET | ||||
| 	QUOTED_IDENTIFIER ON | ||||
| GO | ||||
| 	CREATE FUNCTION [dbo].[fnAuditConvertAuditNoToDisplayFormat] ( | ||||
| 		-- Add the parameters for the function here | ||||
| 		@AuditNo INT | ||||
| 	) RETURNS VARCHAR(10) AS BEGIN -- Declare the return variable here | ||||
| 	DECLARE @Display VARCHAR(10) -- Add the T-SQL statements to compute the return value here | ||||
| SET | ||||
| 	@Display = LTRIM( | ||||
| 		RTRIM( | ||||
| 			CAST( | ||||
| 				'A' + RIGHT( | ||||
| 					'00000' + ISNULL(CAST(@AuditNo AS VARCHAR(10)), ''), | ||||
| 					5 | ||||
| 				) AS VARCHAR(50) | ||||
| 			) | ||||
| 		) | ||||
| 	) -- Return the result of the function | ||||
| 	RETURN @Display | ||||
| END | ||||
| GO | ||||
| @ -1,64 +0,0 @@ | ||||
| USE [FabApprovalSystem] | ||||
| GO | ||||
| 	/****** Object:  UserDefinedFunction [dbo].[fnGetApprovalFullNames]    Script Date: 11/21/2024 11:31:55 AM ******/ | ||||
| SET | ||||
| 	ANSI_NULLS ON | ||||
| GO | ||||
| SET | ||||
| 	QUOTED_IDENTIFIER ON | ||||
| GO | ||||
| 	CREATE FUNCTION [dbo].[fnGetApprovalFullNames] ( | ||||
| 		@IssueID int, | ||||
| 		@DocumentTypeID int, | ||||
| 		@Separator varchar(10), | ||||
| 		@IncludeRole bit, | ||||
| 		@IncludeSubRole bit, | ||||
| 		@IncludePending bit, | ||||
| 		@IncludeApproved bit, | ||||
| 		@IncludeOthers bit | ||||
| 	) RETURNS varchar(max) AS BEGIN DECLARE @r varchar(max) DECLARE @t TABLE(u varchar(200)) | ||||
| INSERT INTO | ||||
| 	@t | ||||
| SELECT | ||||
| 	@Separator + ISNULL(U.FirstName, '') + ' ' + ISNULL(U.LastName, '') + CASE | ||||
| 		WHEN @IncludeRole <> 0 THEN ' (' + A.RoleName + ')' | ||||
| 		ELSE '' | ||||
| 	END + CASE | ||||
| 		WHEN @IncludeSubRole <> 0 THEN ' (' + A.SubRole + ')' | ||||
| 		ELSE '' | ||||
| 	END | ||||
| FROM | ||||
| 	Approval A | ||||
| 	LEFT OUTER JOIN Users U ON A.UserID = U.UserID | ||||
| WHERE | ||||
| 	A.IssueID = @IssueID | ||||
| 	AND A.DocumentTypeID = @DocumentTypeID | ||||
| 	AND ( | ||||
| 		( | ||||
| 			@IncludeOthers <> 0 | ||||
| 			AND A.ItemStatus NOT IN (0, 1) | ||||
| 		) | ||||
| 		OR ( | ||||
| 			@IncludePending <> 0 | ||||
| 			AND A.ItemStatus = 0 | ||||
| 		) | ||||
| 		OR ( | ||||
| 			@IncludeApproved <> 0 | ||||
| 			AND A.ItemStatus = 1 | ||||
| 		) | ||||
| 	) | ||||
| ORDER BY | ||||
| 	A.Step, | ||||
| 	U.FirstName, | ||||
| 	U.LastName | ||||
| SELECT | ||||
| 	@r = ( | ||||
| 		SELECT | ||||
| 			u + '' | ||||
| 		FROM | ||||
| 			@t FOR XML PATH('') | ||||
| 	) IF @r <> '' | ||||
| SET | ||||
| 	@r = STUFF(@r, 1, LEN(@Separator), '') RETURN @r | ||||
| END | ||||
| GO | ||||
| @ -1,24 +0,0 @@ | ||||
| USE [FabApprovalSystem] | ||||
| GO | ||||
| 	/****** Object:  UserDefinedFunction [dbo].[fnGetITARUsers]    Script Date: 11/21/2024 11:31:55 AM ******/ | ||||
| SET | ||||
| 	ANSI_NULLS ON | ||||
| GO | ||||
| SET | ||||
| 	QUOTED_IDENTIFIER ON | ||||
| GO | ||||
| 	-- ============================================= | ||||
| 	-- Author:		<Author,,Name> | ||||
| 	-- Create date: <Create Date,,> | ||||
| 	-- Description:	<Description,,> | ||||
| 	-- ============================================= | ||||
| 	CREATE FUNCTION [dbo].[fnGetITARUsers] () RETURNS TABLE AS RETURN ( | ||||
| 		SELECT | ||||
| 			UserID, | ||||
| 			HasITARAccess | ||||
| 		FROM | ||||
| 			SAMUsers | ||||
| 		WHERE | ||||
| 			HasITARAccess = 1 | ||||
| 	) | ||||
| GO | ||||
| @ -1,33 +0,0 @@ | ||||
| USE [FabApprovalSystem] | ||||
| GO | ||||
| 	/****** Object:  UserDefinedFunction [dbo].[fnGetLotCount_Fab]    Script Date: 11/21/2024 11:31:55 AM ******/ | ||||
| SET | ||||
| 	ANSI_NULLS ON | ||||
| GO | ||||
| SET | ||||
| 	QUOTED_IDENTIFIER ON | ||||
| GO | ||||
| 	-- ============================================= | ||||
| 	-- Author:		<Author,,Name> | ||||
| 	-- Create date: <Create Date, ,> | ||||
| 	-- Description:	<Description, ,> | ||||
| 	-- ============================================= | ||||
| 	CREATE FUNCTION [dbo].[fnGetLotCount_Fab] ( | ||||
| 		-- Add the parameters for the function here | ||||
| 		@IssueID INT | ||||
| 	) RETURNS FLOAT AS BEGIN DECLARE @FabCount INT -- Declare the return variable here | ||||
| SET | ||||
| 	@FabCount = 0 | ||||
| SET | ||||
| 	@FabCount = ( | ||||
| 		SELECT | ||||
| 			COUNT(*) | ||||
| 		FROM | ||||
| 			Lot L | ||||
| 		WHERE | ||||
| 			L.IssueID = @IssueID | ||||
| 			AND L.Location NOT IN ('6300', '6400 ', '6600', 'QDB') | ||||
| 	) -- Return the result of the function | ||||
| 	RETURN @FabCount | ||||
| END | ||||
| GO | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	