Compare commits
	
		
			28 Commits
		
	
	
		
			7e38c565f3
			...
			10-20-a
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9e0499a73e | |||
| 94215def9c | |||
| d9cf8d2aae | |||
| 68c3a8b5f3 | |||
| 3c072d177a | |||
| 74461c147d | |||
| c5d86f3c43 | |||
| 58ce014b10 | |||
| 6e31dceb4c | |||
| 7df7d5f4d6 | |||
| 736a39245f | |||
| e6a223492c | |||
| 9c5e6fddf2 | |||
| 3e8f5931e2 | |||
| 906868540b | |||
| 2fc83bb54d | |||
| 40177bfb51 | |||
| e02b70e258 | |||
| 534d0ccc5c | |||
| 9769e1e106 | |||
| c3b309347c | |||
| 0f23ba19cc | |||
| a343243576 | |||
| 304bf04afe | |||
| 08a23114c9 | |||
| ca4ebff54c | |||
| 2d82216d25 | |||
| 7bcb87c5e5 | 
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -338,6 +338,10 @@ ASALocalRun/ | ||||
| !**/.vscode/settings.json | ||||
| !**/.vscode/tasks.json | ||||
| !**/.vscode/mklink.md | ||||
| !**/.vscode/*.http | ||||
| **/.vscode/2025-*.http | ||||
| **/.vscode/2026-*.http | ||||
|  | ||||
|  | ||||
| *.lnk | ||||
|  | ||||
|  | ||||
| @ -109,7 +109,7 @@ dotnet_diagnostic.CA2254.severity = none # CA2254: The logging message template | ||||
| dotnet_diagnostic.IDE0001.severity = warning # IDE0001: Simplify name | ||||
| dotnet_diagnostic.IDE0002.severity = warning # Simplify (member access) - System.Version.Equals("1", "2"); Version.Equals("1", "2"); | ||||
| dotnet_diagnostic.IDE0004.severity = warning # IDE0004: Cast is redundant. | ||||
| dotnet_diagnostic.IDE0005.severity = warning # Using directive is unnecessary | ||||
| dotnet_diagnostic.IDE0005.severity = none # Using directive is unnecessary | ||||
| dotnet_diagnostic.IDE0028.severity = none # IDE0028: Collection initialization can be simplified | ||||
| dotnet_diagnostic.IDE0031.severity = warning # Use null propagation (IDE0031) | ||||
| dotnet_diagnostic.IDE0047.severity = warning # IDE0047: Parentheses can be removed | ||||
| @ -121,6 +121,8 @@ dotnet_diagnostic.IDE0290.severity = none # Use primary constructor [Distance]cs | ||||
| dotnet_diagnostic.IDE0300.severity = none # IDE0300: Collection initialization can be simplified | ||||
| dotnet_diagnostic.IDE0301.severity = none #IDE0301: Collection initialization can be simplified | ||||
| dotnet_diagnostic.IDE0305.severity = none # IDE0305: Collection initialization can be simplified | ||||
| dotnet_diagnostic.MSTEST0015.severity = none # MSTEST0015: Test method {method} should not be ignored | ||||
| dotnet_diagnostic.MSTEST0037.severity = error # MSTEST0037: Use proper 'Assert' methods | ||||
| dotnet_diagnostic.SYSLIB1045.severity = none # SYSLIB1045: diagnostics for regex source generation | ||||
| dotnet_naming_rule.abstract_method_should_be_pascal_case.severity = warning | ||||
| dotnet_naming_rule.abstract_method_should_be_pascal_case.style = pascal_case | ||||
|  | ||||
							
								
								
									
										21
									
								
								Adaptation/.vscode/format-report.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								Adaptation/.vscode/format-report.json
									
									
									
									
										vendored
									
									
								
							| @ -1 +1,20 @@ | ||||
| [] | ||||
| [ | ||||
|   { | ||||
|     "DocumentId": { | ||||
|       "ProjectId": { | ||||
|         "Id": "88b6bb05-fef2-487e-bb6c-9ae68922c0bb" | ||||
|       }, | ||||
|       "Id": "63c5cda5-30ee-4e20-9ec8-d45777057452" | ||||
|     }, | ||||
|     "FileName": "MonIn.cs", | ||||
|     "FilePath": "L:\\DevOps\\EAF-Mesa-Integration\\mesafibacklog\\Adaptation\\Infineon\\Monitoring\\MonA\\MonIn.cs", | ||||
|     "FileChanges": [ | ||||
|       { | ||||
|         "LineNumber": 268, | ||||
|         "CharNumber": 17, | ||||
|         "DiagnosticId": "CA1816", | ||||
|         "FormatDescription": "warning CA1816: Change MonIn.Dispose() to call GC.SuppressFinalize(object). This will prevent derived types that introduce a finalizer from needing to re-implement \u0027IDisposable\u0027 to call it." | ||||
|       } | ||||
|     ] | ||||
|   } | ||||
| ] | ||||
							
								
								
									
										39
									
								
								Adaptation/.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										39
									
								
								Adaptation/.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							| @ -1,10 +1,43 @@ | ||||
| { | ||||
|   "configurations": [ | ||||
|     { | ||||
|       "mode": "debug", | ||||
|       "name": "Go launch file", | ||||
|       "program": "${file}", | ||||
|       "request": "launch", | ||||
|       "type": "go" | ||||
|     }, | ||||
|     { | ||||
|       "name": "node Launch Current Opened File", | ||||
|       "program": "${file}", | ||||
|       "request": "launch", | ||||
|       "type": "node" | ||||
|     }, | ||||
|     { | ||||
|       "cwd": "${workspaceFolder}", | ||||
|       "internalConsoleOptions": "neverOpen", | ||||
|       "name": "Debug File", | ||||
|       "program": "${file}", | ||||
|       "request": "launch", | ||||
|       "stopOnEntry": false, | ||||
|       "type": "bun", | ||||
|       "watchMode": false | ||||
|     }, | ||||
|     { | ||||
|       "cwd": "${workspaceFolder}", | ||||
|       "internalConsoleOptions": "neverOpen", | ||||
|       "name": "Run File", | ||||
|       "noDebug": true, | ||||
|       "program": "${file}", | ||||
|       "request": "launch", | ||||
|       "type": "bun", | ||||
|       "watchMode": false | ||||
|     }, | ||||
|     { | ||||
|       "name": ".NET Core Attach", | ||||
|       "type": "coreclr", | ||||
|       "processId": 32760, | ||||
|       "request": "attach", | ||||
|       "processId": 25140 | ||||
|       "type": "coreclr" | ||||
|     } | ||||
|   ] | ||||
| } | ||||
| } | ||||
							
								
								
									
										20
									
								
								Adaptation/.vscode/localhost.http
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Adaptation/.vscode/localhost.http
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| @host = http://localhost:8071 | ||||
|  | ||||
| GET {{host}}/api/v1/ado | ||||
| Accept: application/json | ||||
|  | ||||
| ### | ||||
|  | ||||
| POST {{host}}/api/v1/ado | ||||
| Content-Type: application/json | ||||
| Accept: application/json | ||||
|  | ||||
| { | ||||
|     "id": 109734, | ||||
|     "machineId": "", | ||||
|     "page": "risk", | ||||
|     "site": "MES", | ||||
|     "time": 1743438398094, | ||||
|     "username": "", | ||||
|     "value": "3" | ||||
| } | ||||
							
								
								
									
										31
									
								
								Adaptation/.vscode/priority.http
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								Adaptation/.vscode/priority.http
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| @host = https://eaf-dev.mes.infineon.com | ||||
| @page = api/v1/ado/ | ||||
|  | ||||
| ###  | ||||
|  | ||||
| GET {{host}}/api/v1/ado?id=null&machineId=na&page=business&sessionId=035f3090-2e4d-4b2e-a254-081561c0d438&site=MES&time=1744652058982&username=anonymous&value=null | ||||
| # https://eaf-dev.mes.infineon.com/api/v1/ado/?id=null& | ||||
| # machineId=na& | ||||
| # page=business& | ||||
| # sessionId=035f3090-2e4d-4b2e-a254-081561c0d438& | ||||
| # site=MES& | ||||
| # time=1744652058982& | ||||
| # username=anonymous& | ||||
| # value=null | ||||
|  | ||||
| ### | ||||
|  | ||||
| POST {{host}}/{{page}}/ | ||||
| Accept: application/json | ||||
|  | ||||
| { | ||||
|     "id": "110738", | ||||
|     "machineId": "30ef1b54e075c5370ce74eea2042cb750be659696b170f8758d219a8f9a88e10", | ||||
|     "page": "time", | ||||
|     "site": "MES", | ||||
|     "time": "1744339499677", | ||||
|     "username": "phares", | ||||
|     "value": "3" | ||||
| } | ||||
|  | ||||
| ### | ||||
							
								
								
									
										18
									
								
								Adaptation/.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								Adaptation/.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @ -1,4 +1,11 @@ | ||||
| { | ||||
|     "files.associations": { | ||||
|         "*.ffs_gui": "xml", | ||||
|         "*.hurl": "http", | ||||
|         "*.org": "ini", | ||||
|         "*.net": "ini", | ||||
|         "default": "ini" | ||||
|     }, | ||||
|     "[markdown]": { | ||||
|         "editor.wordWrap": "off" | ||||
|     }, | ||||
| @ -8,10 +15,12 @@ | ||||
|         "EQPT", | ||||
|         "headerid", | ||||
|         "Idrv", | ||||
|         "Infineon", | ||||
|         "ipdsf", | ||||
|         "Irng", | ||||
|         "ISMTP", | ||||
|         "JOBID", | ||||
|         "kanbn", | ||||
|         "messa", | ||||
|         "messv", | ||||
|         "pdsf", | ||||
| @ -20,9 +29,13 @@ | ||||
|         "Rcpe", | ||||
|         "RESIMAPCDE", | ||||
|         "Rsens", | ||||
|         "signalr", | ||||
|         "Smpl", | ||||
|         "Villach", | ||||
|         "Vrng" | ||||
|         "Vrng", | ||||
|         "VSTS", | ||||
|         "Weightest", | ||||
|         "WSJF" | ||||
|     ], | ||||
|     "coverage-gutters.coverageBaseDir": "../../../../MESAFIBACKLOG/05_TestResults/TestResults/**", | ||||
|     "workbench.colorCustomizations": { | ||||
| @ -45,6 +58,5 @@ | ||||
|         "titleBar.inactiveForeground": "#e7e7e799", | ||||
|         "commandCenter.border": "#e7e7e799" | ||||
|     }, | ||||
|     "peacock.color": "#4a727e", | ||||
|     "cSpell.enabled": false | ||||
|     "peacock.color": "#4a727e" | ||||
| } | ||||
							
								
								
									
										161
									
								
								Adaptation/.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										161
									
								
								Adaptation/.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							| @ -1,19 +1,134 @@ | ||||
| { | ||||
|     "version": "2.0.0", | ||||
|     "inputs": [ | ||||
|         { | ||||
|             "default": "Development", | ||||
|             "description": "Which ASP Net Core Environment?", | ||||
|             "id": "ASPNETCORE_ENVIRONMENT", | ||||
|             "options": [ | ||||
|                 "Development", | ||||
|                 "Production" | ||||
|             ], | ||||
|             "type": "pickString" | ||||
|         }, | ||||
|         { | ||||
|             "default": "{AssemblyTitle}", | ||||
|             "description": "What Assembly Title?", | ||||
|             "id": "AssemblyTitle", | ||||
|             "type": "promptString" | ||||
|         }, | ||||
|         { | ||||
|             "default": "{Build.BuildId}", | ||||
|             "description": "Which Build BuildId?", | ||||
|             "id": "Build.BuildId", | ||||
|             "type": "promptString" | ||||
|         }, | ||||
|         { | ||||
|             "default": "{Build.Reason}", | ||||
|             "description": "Which Build Reason?", | ||||
|             "id": "Build.Reason", | ||||
|             "type": "promptString" | ||||
|         }, | ||||
|         { | ||||
|             "default": "{Build.Repository.Id}", | ||||
|             "description": "Which Build Repository Id?", | ||||
|             "id": "Build.Repository.Id", | ||||
|             "type": "promptString" | ||||
|         }, | ||||
|         { | ||||
|             "default": "{Build.Repository.Name}", | ||||
|             "description": "Which Build Repository Name?", | ||||
|             "id": "Build.Repository.Name", | ||||
|             "type": "promptString" | ||||
|         }, | ||||
|         { | ||||
|             "default": "{Build.SourceVersion}", | ||||
|             "description": "Which Build Source Version?", | ||||
|             "id": "Build.SourceVersion", | ||||
|             "type": "promptString" | ||||
|         }, | ||||
|         { | ||||
|             "default": "Debug", | ||||
|             "description": "Which Configuration?", | ||||
|             "id": "Configuration", | ||||
|             "options": [ | ||||
|                 "Debug", | ||||
|                 "Release" | ||||
|             ], | ||||
|             "type": "pickString" | ||||
|         }, | ||||
|         { | ||||
|             "default": "net8.0", | ||||
|             "description": "Which Core Version?", | ||||
|             "id": "CoreVersion", | ||||
|             "options": [ | ||||
|                 "net8.0" | ||||
|             ], | ||||
|             "type": "pickString" | ||||
|         }, | ||||
|         { | ||||
|             "default": "C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe", | ||||
|             "description": "Which MS Build?", | ||||
|             "id": "MSBuild", | ||||
|             "type": "promptString" | ||||
|         }, | ||||
|         { | ||||
|             "default": "https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/", | ||||
|             "description": "Which Nuget Source?", | ||||
|             "id": "NugetSource", | ||||
|             "type": "promptString" | ||||
|         }, | ||||
|         { | ||||
|             "default": "win-x64", | ||||
|             "description": "Which Runtime?", | ||||
|             "id": "Runtime", | ||||
|             "options": [ | ||||
|                 "win-x64", | ||||
|                 "win-x32", | ||||
|                 "linux-x64", | ||||
|                 "linux-x32" | ||||
|             ], | ||||
|             "type": "pickString" | ||||
|         }, | ||||
|         { | ||||
|             "default": "L:/", | ||||
|             "description": "Which System DefaultWorkingDirectory?", | ||||
|             "id": "System.DefaultWorkingDirectory", | ||||
|             "options": [ | ||||
|                 "L:/", | ||||
|                 "D:/", | ||||
|                 "C:/" | ||||
|             ], | ||||
|             "type": "pickString" | ||||
|         }, | ||||
|         { | ||||
|             "default": "v4.8", | ||||
|             "description": "Which Core Target Framework Version?", | ||||
|             "id": "TargetFrameworkVersion", | ||||
|             "options": [ | ||||
|                 "v4.8" | ||||
|             ], | ||||
|             "type": "pickString" | ||||
|         }, | ||||
|         { | ||||
|             "default": "{UserSecretsId}", | ||||
|             "description": "Which Core User Secrets Id?", | ||||
|             "id": "UserSecretsId", | ||||
|             "type": "promptString" | ||||
|         } | ||||
|     ], | ||||
|     "tasks": [ | ||||
|         { | ||||
|             "label": "Build", | ||||
|             "command": "dotnet", | ||||
|             "type": "process", | ||||
|             "args": [ | ||||
|                 "build", | ||||
|                 "/property:GenerateFullPaths=true", | ||||
|                 "/consoleloggerparameters:NoSummary" | ||||
|                 "build" | ||||
|             ], | ||||
|             "problemMatcher": "$msCompile" | ||||
|         }, | ||||
|         { | ||||
|             "label": "Test-Debug", | ||||
|             "label": "Test Debug", | ||||
|             "command": "dotnet", | ||||
|             "type": "process", | ||||
|             "args": [ | ||||
| @ -24,7 +139,7 @@ | ||||
|             "problemMatcher": "$msCompile" | ||||
|         }, | ||||
|         { | ||||
|             "label": "Test-Release", | ||||
|             "label": "Test Release", | ||||
|             "command": "dotnet", | ||||
|             "type": "process", | ||||
|             "args": [ | ||||
| @ -50,7 +165,7 @@ | ||||
|             "problemMatcher": "$msCompile" | ||||
|         }, | ||||
|         { | ||||
|             "label": "Format-Whitespaces", | ||||
|             "label": "Format Whitespaces", | ||||
|             "command": "dotnet", | ||||
|             "type": "process", | ||||
|             "args": [ | ||||
| @ -78,7 +193,7 @@ | ||||
|             "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://tfs.intra.infineon.com/tfs/FactoryIntegration/_packaging/EAF/nuget/v3/index.json%3Bhttps://tfs.intra.infineon.com/tfs/FactoryIntegration/_packaging/EAF%40Local/nuget/v3/index.json%3Bhttps://api.nuget.org/v3/index.json", | ||||
|                 "/p:RestoreSources=https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/%3Bhttps://tfs.intra.infineon.com/tfs/FactoryIntegration/_packaging/EAF/nuget/v3/index.json%3Bhttps://tfs.intra.infineon.com/tfs/FactoryIntegration/_packaging/EAF%40Local/nuget/v3/index.json%3Bhttps://api.nuget.org/v3/index.json", | ||||
|                 "/detailedsummary", | ||||
|                 "/consoleloggerparameters:PerformanceSummary;ErrorsOnly;", | ||||
|                 "/property:Configuration=Debug;TargetFrameworkVersion=v4.8", | ||||
| @ -86,6 +201,38 @@ | ||||
|             ], | ||||
|             "problemMatcher": "$msCompile" | ||||
|         }, | ||||
|         { | ||||
|             "label": "Code Project", | ||||
|             "type": "shell", | ||||
|             "command": "code ../MESAFIBACKLOG.csproj", | ||||
|             "problemMatcher": [] | ||||
|         }, | ||||
|         { | ||||
|             "label": "Code Read Me", | ||||
|             "type": "shell", | ||||
|             "command": "code ../README.md", | ||||
|             "problemMatcher": [] | ||||
|         }, | ||||
|         { | ||||
|             "label": "File-Folder-Helper AOT s X Day-Helper-2025-03-20", | ||||
|             "type": "shell", | ||||
|             "command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe", | ||||
|             "args": [ | ||||
|                 "s", | ||||
|                 "X", | ||||
|                 "L:/DevOps/EAF-Mesa-Integration/MESAFIBACKLOG", | ||||
|                 "Day-Helper-2025-03-20", | ||||
|                 "false", | ||||
|                 "4" | ||||
|             ], | ||||
|             "problemMatcher": [] | ||||
|         }, | ||||
|         { | ||||
|             "label": "Code Git Config", | ||||
|             "type": "shell", | ||||
|             "command": "code ../.git/config", | ||||
|             "problemMatcher": [] | ||||
|         }, | ||||
|         { | ||||
|             "label": "Kanbn Console", | ||||
|             "type": "npm", | ||||
|  | ||||
							
								
								
									
										160
									
								
								Adaptation/.vscode/tfs.http
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										160
									
								
								Adaptation/.vscode/tfs.http
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,160 @@ | ||||
| @Manufacturing-IT = https://tfs.intra.infineon.com/tfs/ManufacturingIT | ||||
| @Factory-Integration = https://tfs.intra.infineon.com/tfs/FactoryIntegration | ||||
| @userId = phares | ||||
| @ids = 126018, 224543 | ||||
| @Unauthorized-Chase = asdf | ||||
| @Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E = asdf | ||||
|  | ||||
| ### Work Items Expand Relations | ||||
|  | ||||
| GET {{Factory-Integration}}/_apis/wit/workitems?ids={{ids}}&$expand=Relations | ||||
| Accept: application/json | ||||
| Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||
|  | ||||
| ### Work Items Updates | ||||
|  | ||||
| GET {{Factory-Integration}}/_apis/wit/workitems/{{ids}}/updates | ||||
| Accept: application/json | ||||
| Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||
|  | ||||
| ### Iterations | ||||
|  | ||||
| GET {{Factory-Integration}}/ART%20SPS/cea9f426-6fb1-4d65-93d5-dbf471056212/_apis/work/teamsettings/iterations? | ||||
| Accept: application/json | ||||
| Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||
|  | ||||
| ### User Entitlements | ||||
|  | ||||
| GET {{Factory-Integration}}/_apis/userEntitlements/{{userId}}?api-version=6.0-preview.3 | ||||
| Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||
| Accept: application/json | ||||
|  | ||||
| ### User Entitlements | ||||
|  | ||||
| GET {{Factory-Integration}}/_apis/userEntitlements?api-version=5.1-preview.2 | ||||
| Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||
| Accept: application/json | ||||
|  | ||||
| ### Work Item Patch | ||||
|  | ||||
| patch {{Manufacturing-IT}}/Mesa_FI/_apis/wit/workitems/382290?api-version=7.0 | ||||
| Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||
| Content-Type: application/json-patch+json | ||||
|  | ||||
| [ | ||||
|   { | ||||
|     "op": "test", | ||||
|     "path": "/rev", | ||||
|     "value": 1 | ||||
|   }, | ||||
|   { | ||||
|     "op": "test", | ||||
|     "path": "/fields/System.CreatedDate", | ||||
|     "value": "2023-10-07T18:51:52.783Z" | ||||
|   }, | ||||
|   { | ||||
|     "op": "replace", | ||||
|     "path": "/fields/System.CreatedDate", | ||||
|     "value": "2023-10-07T18:41:52.783Z" | ||||
|   } | ||||
| ] | ||||
|  | ||||
| ### Post Comment | ||||
|  | ||||
| POST {{Manufacturing-IT}}/Mesa_FI/_apis/wit/workitems/382005/comments?api-version=5.1-preview.3 | ||||
| Authorization: Basic {{Unauthorized-Chase}} | ||||
| Content-Type: application/json | ||||
|  | ||||
| { | ||||
|   "text": "Force updated by" | ||||
| } | ||||
|  | ||||
| ### Delete Comment | ||||
|  | ||||
| DELETE {{Manufacturing-IT}}/Mesa_FI/_apis/wit/workitems/382005/comments?api-version=5.1-preview.3 | ||||
| Authorization: Basic {{Unauthorized-Chase}} | ||||
| Content-Type: application/json | ||||
|  | ||||
| ### Work Item Patch WSJF | ||||
|  | ||||
| patch {{Factory-Integration}}/_apis/wit/workitems/292309?api-version=7.0 | ||||
| Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||
| Content-Type: application/json-patch+json | ||||
|  | ||||
| [ | ||||
|   { | ||||
|     "op": "replace", | ||||
|     "path": "/fields/Custom.WSJF", | ||||
|     "value": "5" | ||||
|   } | ||||
| ] | ||||
|  | ||||
| ### Work Item Patch WSJF-B 100+300+400=800 800/200=4 | ||||
|  | ||||
| patch {{Factory-Integration}}/_apis/wit/workitems/292309?api-version=7.0 | ||||
| Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||
| Content-Type: application/json-patch+json | ||||
|  | ||||
| [ | ||||
|   { | ||||
|     "op": "replace", | ||||
|     "path": "/fields/Microsoft.VSTS.Common.BusinessValue", | ||||
|     "value": "100" | ||||
|   }, | ||||
|   { | ||||
|     "op": "replace", | ||||
|     "path": "/fields/Microsoft.VSTS.Scheduling.Effort", | ||||
|     "value": "200" | ||||
|   }, | ||||
|   { | ||||
|     "op": "replace", | ||||
|     "path": "/fields/Custom.RRminusOE", | ||||
|     "value": "300" | ||||
|   }, | ||||
|   { | ||||
|     "op": "replace", | ||||
|     "path": "/fields/Microsoft.VSTS.Common.TimeCriticality", | ||||
|     "value": "400" | ||||
|   }, | ||||
|   { | ||||
|     "op": "replace", | ||||
|     "path": "/fields/Custom.WSJF", | ||||
|     "value": "4" | ||||
|   } | ||||
| ] | ||||
|  | ||||
| ### Work Item Patch WSJF-B 400+400+400=1200 1200/200=6 | ||||
|  | ||||
| patch {{Factory-Integration}}/_apis/wit/workitems/110781?api-version=7.0 | ||||
| Authorization: Basic {{Factory-Integration-Phares-1CB1AEFED90C2A4A9A96F9ED9140A95E}} | ||||
| Content-Type: application/json-patch+json | ||||
|  | ||||
| [ | ||||
|   { | ||||
|     "op": "replace", | ||||
|     "path": "/fields/Microsoft.VSTS.Common.BusinessValue", | ||||
|     "value": "400" | ||||
|   }, | ||||
|   { | ||||
|     "op": "replace", | ||||
|     "path": "/fields/Microsoft.VSTS.Scheduling.Effort", | ||||
|     "value": "200" | ||||
|   }, | ||||
|   { | ||||
|     "op": "replace", | ||||
|     "path": "/fields/Custom.RRminusOE", | ||||
|     "value": "400" | ||||
|   }, | ||||
|   { | ||||
|     "op": "replace", | ||||
|     "path": "/fields/Microsoft.VSTS.Common.TimeCriticality", | ||||
|     "value": "400" | ||||
|   }, | ||||
|   { | ||||
|     "op": "replace", | ||||
|     "path": "/fields/Custom.WSJF", | ||||
|     "value": "6" | ||||
|   } | ||||
| ] | ||||
|  | ||||
| ### | ||||
| @ -16,7 +16,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     private long? _TickOffset; | ||||
|     private readonly string _URL; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -103,7 +103,9 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results = new(string.Empty, null, null, new List<FileInfo>()); | ||||
|         _TickOffset ??= 0; // new FileInfo(reportFullPath).LastWriteTime.Ticks - dateTime.Ticks; | ||||
|         _Logistics = new Logistics(reportFullPath, $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};"); | ||||
|         string[] lines = new string[] { string.Empty, "NUM_DATA_ROWS", $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};" }; | ||||
|         ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines); | ||||
|         _Logistics = new Logistics(reportFullPath, processDataStandardFormat); | ||||
|         SetFileParameterLotIDToLogisticsMID(); | ||||
|         if (_Logistics.FileInfo.Length < _MinFileLength) | ||||
|             results.Item4.Add(_Logistics.FileInfo); | ||||
| @ -111,8 +113,9 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         { | ||||
|             IProcessData iProcessData = new ProcessData(this, _Logistics, _FileConnectorConfiguration.TargetFileLocation, _URL, results.Item4); | ||||
|             if (iProcessData.Details.Count == 0) | ||||
|                 throw new Exception(string.Concat("B) No Data - ", dateTime.Ticks)); | ||||
|             results = iProcessData.GetResults(this, _Logistics, results.Item4); | ||||
|                 results = new(string.Concat("B) No Data - ", dateTime.Ticks), Array.Empty<Test>(), Array.Empty<JsonElement>(), results.Item4); | ||||
|             else | ||||
|                 results = iProcessData.GetResults(this, _Logistics, results.Item4); | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| @ -28,7 +28,6 @@ public class ProcessData : IProcessData | ||||
|         { } | ||||
|         if (url is null) | ||||
|             throw new ArgumentNullException(nameof(url)); | ||||
|         fileInfoCollection.Clear(); | ||||
|         _Details = new List<object>(); | ||||
|         _Log = LogManager.GetLogger(typeof(ProcessData)); | ||||
|         WriteFiles(fileRead, logistics, targetFileLocation, fileInfoCollection); | ||||
| @ -46,12 +45,11 @@ public class ProcessData : IProcessData | ||||
|     { | ||||
|         List<Description> results = new(); | ||||
|         Description? description; | ||||
|         JsonSerializerOptions jsonSerializerOptions = new() { NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString }; | ||||
|         foreach (JsonElement jsonElement in jsonElements) | ||||
|         { | ||||
|             if (jsonElement.ValueKind != JsonValueKind.Object) | ||||
|                 throw new Exception(); | ||||
|             description = JsonSerializer.Deserialize<Description>(jsonElement.ToString(), jsonSerializerOptions); | ||||
|             description = JsonSerializer.Deserialize(jsonElement.ToString(), SharedDescriptionSourceGenerationContext.Default.Description); | ||||
|             if (description is null) | ||||
|                 continue; | ||||
|             results.Add(description); | ||||
| @ -70,7 +68,6 @@ public class ProcessData : IProcessData | ||||
|             throw new Exception(nameof(workItems)); | ||||
|         _Details.Add(workItems); | ||||
|         ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations); | ||||
|         WriteFileStructure(destinationDirectory, keyValuePairs); | ||||
|         WriteFiles(fileRead, destinationDirectory, fileInfoCollection, keyValuePairs); | ||||
|     } | ||||
|  | ||||
| @ -84,18 +81,6 @@ public class ProcessData : IProcessData | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private static void WriteFileStructure(string destinationDirectory, ReadOnlyDictionary<int, Record> keyValuePairs) | ||||
|     { | ||||
|         ReadOnlyCollection<string> collection = GetDirectories(destinationDirectory, keyValuePairs); | ||||
|         foreach (string directory in collection) | ||||
|         { | ||||
|             if (directory.Length > 222) | ||||
|                 continue; | ||||
|             if (!Directory.Exists(directory)) | ||||
|                 _ = Directory.CreateDirectory(directory); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static void WriteFiles(IFileRead fileRead, string destinationDirectory, List<FileInfo> fileInfoCollection, ReadOnlyDictionary<int, Record> keyValuePairs) | ||||
|     { | ||||
|         string old; | ||||
| @ -113,10 +98,10 @@ public class ProcessData : IProcessData | ||||
|             workItem = keyValuePair.Value.WorkItem; | ||||
|             workItemType = workItem.WorkItemType.Replace(" ", "-"); | ||||
|             json = JsonSerializer.Serialize(workItem, WorkItemSourceGenerationContext.Default.WorkItem); | ||||
|             singletonDirectory = Path.Combine(rootDirectory, workItemType, $"{workItem.Id}-{workItemType}", $"{workItem.Id}"); | ||||
|             singletonDirectory = Path.Combine(rootDirectory, workItemType, $"{workItem.Id}"); | ||||
|             if (!Directory.Exists(singletonDirectory)) | ||||
|                 _ = Directory.CreateDirectory(singletonDirectory); | ||||
|             checkFile = Path.Combine(singletonDirectory, ".json"); | ||||
|             checkFile = Path.Combine(singletonDirectory, $"{workItem.Id}-{workItemType.ToLower()}.json"); | ||||
|             old = File.Exists(checkFile) ? File.ReadAllText(checkFile) : string.Empty; | ||||
|             if (old == json) | ||||
|                 continue; | ||||
| @ -152,40 +137,14 @@ public class ProcessData : IProcessData | ||||
|             } | ||||
|             catch (Exception) | ||||
|             { | ||||
|                 record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>()); | ||||
|                 Dictionary<string, string>? tag = null; | ||||
|                 record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>(), tag); | ||||
|             } | ||||
|             results.Add(keyValuePair.Key, record); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<string> GetDirectories(string destinationDirectory, ReadOnlyDictionary<int, Record> keyValuePairs) | ||||
|     { | ||||
|         List<string> results = new(); | ||||
|         Record record; | ||||
|         string directory; | ||||
|         List<bool> nests = new(); | ||||
|         ReadOnlyCollection<string> childrenDirectories; | ||||
|         string dateDirectory = Path.Combine(destinationDirectory, "_", DateTime.Now.ToString("yyyy-MM-dd")); | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             record = keyValuePair.Value; | ||||
|             if (record.Parent is not null && (record.WorkItem.Parent is null || record.Parent.Id != record.WorkItem.Parent.Value)) | ||||
|                 continue; | ||||
|             if (record.Parent is not null) | ||||
|                 continue; | ||||
|             // if (record.WorkItem.Id == 110730) | ||||
|             //     continue; | ||||
|             // if (record.WorkItem.Id == 110732) | ||||
|             //     continue; | ||||
|             nests.Clear(); | ||||
|             directory = Path.Combine(dateDirectory, $"{record.WorkItem.WorkItemType.Substring(0, 1)}-{record.WorkItem.Id}-{record.WorkItem.Title.Trim().Substring(0, 1)}"); | ||||
|             childrenDirectories = GetChildrenDirectories(keyValuePairs, nests, directory, record); | ||||
|             results.AddRange(childrenDirectories); | ||||
|         } | ||||
|         return new(results.Distinct().ToArray()); | ||||
|     } | ||||
|  | ||||
|     private static string GetIndexLines(ReadOnlyCollection<string> frontMatterLines, Record record) | ||||
|     { | ||||
|         List<string> results = new(); | ||||
| @ -235,32 +194,4 @@ public class ProcessData : IProcessData | ||||
|         return string.Join(Environment.NewLine, results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<string> GetChildrenDirectories(ReadOnlyDictionary<int, Record> keyValuePairs, List<bool> nests, string parentDirectory, Record record) | ||||
|     { | ||||
|         List<string> results = new(); | ||||
|         nests.Add(true); | ||||
|         string directory; | ||||
|         Record? childRecord; | ||||
|         ReadOnlyCollection<string> childrenDirectories; | ||||
|         if (record.Children is not null) | ||||
|         { | ||||
|             foreach (Record r in record.Children) | ||||
|             { | ||||
|                 // if (record.WorkItem.Id == 110730) | ||||
|                 //     continue; | ||||
|                 // if (record.WorkItem.Id == 110732) | ||||
|                 //     continue; | ||||
|                 directory = Path.Combine(parentDirectory, $"{r.WorkItem.WorkItemType.Substring(0, 1)}-{r.WorkItem.Id}-{r.WorkItem.Title.Trim().Substring(0, 1)}"); | ||||
|                 results.Add(directory); | ||||
|                 if (!keyValuePairs.TryGetValue(r.WorkItem.Id, out childRecord)) | ||||
|                     continue; | ||||
|                 if (nests.Count > 99) | ||||
|                     break; | ||||
|                 childrenDirectories = GetChildrenDirectories(keyValuePairs, nests, directory, childRecord); | ||||
|                 results.AddRange(childrenDirectories); | ||||
|             } | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -1,135 +0,0 @@ | ||||
| using Adaptation.Eaf.Management.ConfigurationData.CellAutomation; | ||||
| using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration; | ||||
| using Adaptation.Shared; | ||||
| using Adaptation.Shared.Duplicator; | ||||
| using Adaptation.Shared.Methods; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.APC; | ||||
|  | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
|         _NullData = string.Empty; | ||||
|         _Logistics = new(this); | ||||
|         if (_FileParameter is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (_ModelObjectParameterDefinitions is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (!_IsDuplicator) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|     } | ||||
|  | ||||
|     void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) | ||||
|     { | ||||
|         bool isErrorFile = exception is not null; | ||||
|         if (!isErrorFile && !string.IsNullOrEmpty(_Logistics.ReportFullPath)) | ||||
|         { | ||||
|             FileInfo fileInfo = new(_Logistics.ReportFullPath); | ||||
|             if (fileInfo.Exists && fileInfo.LastWriteTime < fileInfo.CreationTime) | ||||
|                 File.SetLastWriteTime(_Logistics.ReportFullPath, fileInfo.CreationTime); | ||||
|         } | ||||
|         Move(extractResults); | ||||
|     } | ||||
|  | ||||
|     void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null); | ||||
|  | ||||
|     string IFileRead.GetEventDescription() | ||||
|     { | ||||
|         string result = _Description.GetEventDescription(); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     List<string> IFileRead.GetHeaderNames() | ||||
|     { | ||||
|         List<string> results = _Description.GetHeaderNames(); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     string[] IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, string to, string from, string resolvedFileLocation, Exception exception) | ||||
|     { | ||||
|         string[] results = Move(extractResults, to, from, resolvedFileLocation, exception); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     JsonProperty[] IFileRead.GetDefault() | ||||
|     { | ||||
|         JsonProperty[] results = _Description.GetDefault(this, _Logistics); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Dictionary<string, string> IFileRead.GetDisplayNamesJsonElement() | ||||
|     { | ||||
|         Dictionary<string, string> results = _Description.GetDisplayNamesJsonElement(this); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     List<IDescription> IFileRead.GetDescriptions(IFileRead fileRead, List<Test> tests, IProcessData processData) | ||||
|     { | ||||
|         List<IDescription> results = _Description.GetDescriptions(fileRead, _Logistics, tests, processData); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.GetExtractResult(string reportFullPath, string eventName) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         if (string.IsNullOrEmpty(eventName)) | ||||
|             throw new Exception(); | ||||
|         _ReportFullPath = reportFullPath; | ||||
|         DateTime dateTime = DateTime.Now; | ||||
|         results = GetExtractResult(reportFullPath, dateTime); | ||||
|         if (results.Item3 is null) | ||||
|             results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]"), results.Item4); | ||||
|         if (results.Item3.Length > 0 && _IsEAFHosted) | ||||
|             WritePDSF(this, results.Item3); | ||||
|         UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.ReExtract() | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         List<string> headerNames = _Description.GetHeaderNames(); | ||||
|         Dictionary<string, string> keyValuePairs = _Description.GetDisplayNamesJsonElement(this); | ||||
|         results = ReExtract(this, headerNames, keyValuePairs); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private void FileCopy<T>(string reportFullPath, DateTime dateTime, List<T> descriptions) where T : Shared.Properties.IDescription | ||||
|     { | ||||
|         bool isDummyRun = false; | ||||
|         List<(Shared.Properties.IScopeInfo, string)> collection = new(); | ||||
|         string successDirectory = _FileConnectorConfiguration.AlternateTargetFolder; | ||||
|         string fileNameAfterUnderscoreSplit = GetFileNameAfterUnderscoreSplit(reportFullPath); | ||||
|         string duplicateDirectory = Path.Combine(_FileConnectorConfiguration.TargetFileLocation, fileNameAfterUnderscoreSplit); | ||||
|         if (!Directory.Exists(duplicateDirectory)) | ||||
|             _ = Directory.CreateDirectory(duplicateDirectory); | ||||
|         string duplicateFile = Path.Combine(duplicateDirectory, Path.GetFileName(reportFullPath)); | ||||
|         File.Copy(reportFullPath, duplicateFile, overwrite: true); | ||||
|         WaitForFileConsumption(dateTime, descriptions, isDummyRun, successDirectory, duplicateDirectory, collection, duplicateFile); | ||||
|     } | ||||
|  | ||||
|     private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath); | ||||
|         _Logistics = new Logistics(reportFullPath, pdsf.Item1); | ||||
|         SetFileParameterLotIDToLogisticsMID(); | ||||
|         JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf); | ||||
|         List<Shared.Properties.IDescription> descriptions = GetDuplicatorDescriptions(jsonElements); | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             FileCopy(reportFullPath, dateTime, descriptions); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>()); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -1,159 +0,0 @@ | ||||
| using Adaptation.Eaf.Management.ConfigurationData.CellAutomation; | ||||
| using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration; | ||||
| using Adaptation.Shared; | ||||
| using Adaptation.Shared.Duplicator; | ||||
| using Adaptation.Shared.Methods; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Globalization; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.Archive; | ||||
|  | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
|  | ||||
|     private readonly string _JobIdParentDirectory; | ||||
|     private readonly string _JobIdArchiveParentDirectory; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
|         _NullData = string.Empty; | ||||
|         _Logistics = new(this); | ||||
|         if (_FileParameter is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (_ModelObjectParameterDefinitions is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (!_IsDuplicator) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         _JobIdParentDirectory = GetJobIdParentDirectory(_FileConnectorConfiguration.SourceFileLocation); | ||||
|         _JobIdArchiveParentDirectory = GetJobIdParentDirectory(_FileConnectorConfiguration.TargetFileLocation); | ||||
|     } | ||||
|  | ||||
|     void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) => Move(extractResults); | ||||
|  | ||||
|     void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null); | ||||
|  | ||||
|     string IFileRead.GetEventDescription() | ||||
|     { | ||||
|         string result = _Description.GetEventDescription(); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     List<string> IFileRead.GetHeaderNames() | ||||
|     { | ||||
|         List<string> results = _Description.GetHeaderNames(); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     string[] IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, string to, string from, string resolvedFileLocation, Exception exception) | ||||
|     { | ||||
|         string[] results = Move(extractResults, to, from, resolvedFileLocation, exception); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     JsonProperty[] IFileRead.GetDefault() | ||||
|     { | ||||
|         JsonProperty[] results = _Description.GetDefault(this, _Logistics); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Dictionary<string, string> IFileRead.GetDisplayNamesJsonElement() | ||||
|     { | ||||
|         Dictionary<string, string> results = _Description.GetDisplayNamesJsonElement(this); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     List<IDescription> IFileRead.GetDescriptions(IFileRead fileRead, List<Test> tests, IProcessData processData) | ||||
|     { | ||||
|         List<IDescription> results = _Description.GetDescriptions(fileRead, _Logistics, tests, processData); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.GetExtractResult(string reportFullPath, string eventName) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         if (string.IsNullOrEmpty(eventName)) | ||||
|             throw new Exception(); | ||||
|         _ReportFullPath = reportFullPath; | ||||
|         DateTime dateTime = DateTime.Now; | ||||
|         results = GetExtractResult(reportFullPath, dateTime); | ||||
|         if (results.Item3 is null) | ||||
|             results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]"), results.Item4); | ||||
|         if (results.Item3.Length > 0 && _IsEAFHosted) | ||||
|             WritePDSF(this, results.Item3); | ||||
|         UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.ReExtract() | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         List<string> headerNames = _Description.GetHeaderNames(); | ||||
|         Dictionary<string, string> keyValuePairs = _Description.GetDisplayNamesJsonElement(this); | ||||
|         results = ReExtract(this, headerNames, keyValuePairs); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private static IEnumerable<string> GetDirectoriesRecursively(string path, string directoryNameSegment = null) | ||||
|     { | ||||
|         Queue<string> queue = new(); | ||||
|         queue.Enqueue(path); | ||||
|         while (queue.Count > 0) | ||||
|         { | ||||
|             path = queue.Dequeue(); | ||||
|             foreach (string subDirectory in Directory.GetDirectories(path)) | ||||
|             { | ||||
|                 queue.Enqueue(subDirectory); | ||||
|                 if (string.IsNullOrEmpty(directoryNameSegment) || Path.GetFileName(subDirectory).Contains(directoryNameSegment)) | ||||
|                     yield return subDirectory; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void MoveArchive(string reportFullPath, DateTime dateTime) | ||||
|     { | ||||
|         if (dateTime == DateTime.MinValue) | ||||
|             throw new ArgumentNullException(nameof(dateTime)); | ||||
|         string logisticsSequence = _Logistics.Sequence.ToString(); | ||||
|         string weekOfYear = _Calendar.GetWeekOfYear(_Logistics.DateTimeFromSequence, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); | ||||
|         string weekDirectory = $"{_Logistics.DateTimeFromSequence:yyyy}_Week_{weekOfYear}{@"\"}{_Logistics.DateTimeFromSequence:yyyy-MM-dd}"; | ||||
|         string destinationArchiveDirectory = Path.Combine(_JobIdArchiveParentDirectory, _Logistics.JobID, weekDirectory); | ||||
|         if (!Directory.Exists(destinationArchiveDirectory)) | ||||
|             _ = Directory.CreateDirectory(destinationArchiveDirectory); | ||||
|         string jobIdDirectory = Path.Combine(_JobIdParentDirectory, _Logistics.JobID); | ||||
|         if (!Directory.Exists(jobIdDirectory)) | ||||
|             _ = Directory.CreateDirectory(jobIdDirectory); | ||||
|         if (Directory.GetDirectories(jobIdDirectory).Length == 0) | ||||
|             File.Copy(reportFullPath, Path.Combine(destinationArchiveDirectory, Path.GetFileName(reportFullPath))); | ||||
|         else | ||||
|         { | ||||
|             string[] matchDirectories = GetDirectoriesRecursively(jobIdDirectory, logisticsSequence).ToArray(); | ||||
|             if (matchDirectories.Length != 1) | ||||
|                 throw new Exception("Didn't find directory by logistics sequence"); | ||||
|             string sourceDirectory = Path.GetDirectoryName(matchDirectories[0]); | ||||
|             destinationArchiveDirectory = Path.Combine(destinationArchiveDirectory, Path.GetFileName(sourceDirectory)); | ||||
|             Directory.Move(sourceDirectory, destinationArchiveDirectory); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath); | ||||
|         _Logistics = new Logistics(reportFullPath, pdsf.Item1); | ||||
|         SetFileParameterLotIDToLogisticsMID(); | ||||
|         JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf); | ||||
|         List<Shared.Properties.IDescription> descriptions = GetDuplicatorDescriptions(jsonElements); | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             MoveArchive(reportFullPath, dateTime); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>()); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -9,26 +9,17 @@ namespace Adaptation.FileHandlers; | ||||
| public class CellInstanceConnectionName | ||||
| { | ||||
|  | ||||
|     internal static IFileRead Get(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, int? connectionCount) | ||||
|     internal static IFileRead Get(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, int? connectionCount) | ||||
|     { | ||||
|         IFileRead result = cellInstanceConnectionName switch | ||||
|         { | ||||
|             nameof(ADO) => new ADO.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(APC) => new APC.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(Archive) => new Archive.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(DownloadWorkItems) => new DownloadWorkItems.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(Dummy) => new Dummy.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(IQSSi) => new IQSSi.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(json) => new json.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(Kanban) => new Kanban.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(Markdown) => new Markdown.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(MoveMatchingFiles) => new MoveMatchingFiles.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(OpenInsight) => new OpenInsight.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(OpenInsightMetrologyViewer) => new OpenInsightMetrologyViewer.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(OpenInsightMetrologyViewerAttachments) => new OpenInsightMetrologyViewerAttachments.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(Priority) => new Priority.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(Processed) => new Processed.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(SPaCe) => new SPaCe.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             nameof(Violation) => new Violation.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null), | ||||
|             _ => throw new Exception($"\"{cellInstanceConnectionName}\" not mapped") | ||||
|         }; | ||||
|         return result; | ||||
|  | ||||
| @ -29,7 +29,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     private readonly string _BasePage; | ||||
|     private readonly HttpClient _HttpClient; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -224,7 +224,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|             string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace); | ||||
|             try | ||||
|             { | ||||
|                 _SMTP.SendHighPriorityEmailMessage(subject, body);  | ||||
|                 _SMTP.SendHighPriorityEmailMessage(subject, body); | ||||
|                 File.WriteAllText(".email", body); | ||||
|             } | ||||
|             catch (Exception) { } | ||||
| @ -242,7 +242,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|             string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace); | ||||
|             try | ||||
|             { | ||||
|                 _SMTP.SendHighPriorityEmailMessage(subject, body);  | ||||
|                 _SMTP.SendHighPriorityEmailMessage(subject, body); | ||||
|                 File.WriteAllText(".email", body); | ||||
|             } | ||||
|             catch (Exception) { } | ||||
|  | ||||
| @ -1,295 +0,0 @@ | ||||
| using Adaptation.Eaf.Management.ConfigurationData.CellAutomation; | ||||
| using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration; | ||||
| using Adaptation.Shared; | ||||
| using Adaptation.Shared.Duplicator; | ||||
| using Adaptation.Shared.Methods; | ||||
| using Infineon.Monitoring.MonA; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Diagnostics; | ||||
| using System.Globalization; | ||||
| using System.IO; | ||||
| using System.IO.Compression; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
| using System.Threading; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.Dummy; | ||||
|  | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
|  | ||||
|     private readonly Timer _Timer; | ||||
|     private int _LastDummyRunIndex; | ||||
|     private readonly string[] _CellNames; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
|         _NullData = string.Empty; | ||||
|         _Logistics = new(this); | ||||
|         if (_FileParameter is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (_ModelObjectParameterDefinitions is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (!_IsDuplicator) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         _LastDummyRunIndex = -1; | ||||
|         List<string> cellNames = new(); | ||||
|         _Timer = new Timer(Callback, null, Timeout.Infinite, Timeout.Infinite); | ||||
|         ModelObjectParameterDefinition[] cellInstanceCollection = GetProperties(cellInstanceConnectionName, modelObjectParameters, "CellInstance.", ".Alias"); | ||||
|         foreach (ModelObjectParameterDefinition modelObjectParameterDefinition in cellInstanceCollection) | ||||
|             cellNames.Add(modelObjectParameterDefinition.Name.Split('.')[1]); | ||||
|         _CellNames = cellNames.ToArray(); | ||||
|         if (Debugger.IsAttached || fileConnectorConfiguration.PreProcessingMode == FileConnectorConfiguration.PreProcessingModeEnum.Process) | ||||
|             Callback(null); | ||||
|         else | ||||
|         { | ||||
|             TimeSpan timeSpan = new(DateTime.Now.AddSeconds(_FileConnectorConfiguration.FileScanningIntervalInSeconds.Value).Ticks - DateTime.Now.Ticks); | ||||
|             _ = _Timer.Change((long)timeSpan.TotalMilliseconds, Timeout.Infinite); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) => Move(extractResults); | ||||
|  | ||||
|     void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null); | ||||
|  | ||||
|     string IFileRead.GetEventDescription() | ||||
|     { | ||||
|         string result = _Description.GetEventDescription(); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     List<string> IFileRead.GetHeaderNames() | ||||
|     { | ||||
|         List<string> results = _Description.GetHeaderNames(); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     string[] IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, string to, string from, string resolvedFileLocation, Exception exception) | ||||
|     { | ||||
|         string[] results = Move(extractResults, to, from, resolvedFileLocation, exception); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     JsonProperty[] IFileRead.GetDefault() | ||||
|     { | ||||
|         JsonProperty[] results = _Description.GetDefault(this, _Logistics); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Dictionary<string, string> IFileRead.GetDisplayNamesJsonElement() | ||||
|     { | ||||
|         Dictionary<string, string> results = _Description.GetDisplayNamesJsonElement(this); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     List<IDescription> IFileRead.GetDescriptions(IFileRead fileRead, List<Test> tests, IProcessData processData) | ||||
|     { | ||||
|         List<IDescription> results = _Description.GetDescriptions(fileRead, _Logistics, tests, processData); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.GetExtractResult(string reportFullPath, string eventName) => throw new Exception(string.Concat("See ", nameof(CallbackFileExists))); | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.ReExtract() => throw new Exception(string.Concat("See ", nameof(CallbackFileExists))); | ||||
|  | ||||
|     private void CallbackInProcessCleared(string sourceArchiveFile, string traceDummyFile, string targetFileLocation, string monARessource, string inProcessDirectory, long sequence, bool warning) | ||||
|     { | ||||
|         const string site = "sjc"; | ||||
|         string stateName = string.Concat("Dummy_", _EventName); | ||||
|         const string monInURL = "http://moninhttp.sjc.infineon.com/input/text"; | ||||
|         MonIn monIn = MonIn.GetInstance(monInURL); | ||||
|         try | ||||
|         { | ||||
|             if (warning) | ||||
|             { | ||||
|                 File.AppendAllLines(traceDummyFile, new string[] { site, monARessource, stateName, State.Warning.ToString() }); | ||||
|                 _ = monIn.SendStatus(site, monARessource, stateName, State.Warning); | ||||
|                 for (int i = 1; i < 12; i++) | ||||
|                     Thread.Sleep(500); | ||||
|             } | ||||
|             ZipFile.ExtractToDirectory(sourceArchiveFile, inProcessDirectory); | ||||
|             string[] files = Directory.GetFiles(inProcessDirectory, "*", SearchOption.TopDirectoryOnly); | ||||
|             if (files.Length > 250) | ||||
|                 throw new Exception("Safety net!"); | ||||
|             foreach (string file in files) | ||||
|                 File.SetLastWriteTime(file, new DateTime(sequence)); | ||||
|             if (!_FileConnectorConfiguration.IncludeSubDirectories.Value) | ||||
|             { | ||||
|                 foreach (string file in files) | ||||
|                     File.Move(file, Path.Combine(targetFileLocation, Path.GetFileName(file))); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 string[] directories = Directory.GetDirectories(inProcessDirectory, "*", SearchOption.AllDirectories); | ||||
|                 foreach (string directory in directories) | ||||
|                     _ = Directory.CreateDirectory(string.Concat(targetFileLocation, directory.Substring(inProcessDirectory.Length))); | ||||
|                 foreach (string file in files) | ||||
|                     File.Move(file, string.Concat(targetFileLocation, file.Substring(inProcessDirectory.Length))); | ||||
|             } | ||||
|             File.AppendAllLines(traceDummyFile, new string[] { site, monARessource, stateName, State.Ok.ToString() }); | ||||
|             _ = monIn.SendStatus(site, monARessource, stateName, State.Ok); | ||||
|         } | ||||
|         catch (Exception exception) | ||||
|         { | ||||
|             string subject = string.Concat("Exception:", _CellInstanceConnectionName); | ||||
|             string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace); | ||||
|             try | ||||
|             { | ||||
|                 _SMTP.SendHighPriorityEmailMessage(subject, body);  | ||||
|                 File.WriteAllText(".email", body); | ||||
|             } | ||||
|             catch (Exception) { } | ||||
|             File.AppendAllLines(traceDummyFile, new string[] { site, monARessource, stateName, State.Critical.ToString(), exception.Message, exception.StackTrace }); | ||||
|             _ = monIn.SendStatus(site, monARessource, stateName, State.Critical); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void CallbackFileExists(string sourceArchiveFile, string traceDummyFile, string targetFileLocation, string monARessource, long sequence) | ||||
|     { | ||||
|         string[] files; | ||||
|         bool warning = false; | ||||
|         if (!_DummyRuns.ContainsKey(monARessource)) | ||||
|             _DummyRuns.Add(monARessource, new List<long>()); | ||||
|         if (!_DummyRuns[monARessource].Contains(sequence)) | ||||
|             _DummyRuns[monARessource].Add(sequence); | ||||
|         File.AppendAllLines(traceDummyFile, new string[] { sourceArchiveFile }); | ||||
|         string inProcessDirectory = Path.Combine("_ProgressPath", "Dummy In-Process", sequence.ToString()); | ||||
|         if (!Directory.Exists(inProcessDirectory)) | ||||
|             _ = Directory.CreateDirectory(inProcessDirectory); | ||||
|         files = Directory.GetFiles(inProcessDirectory, "*", SearchOption.AllDirectories); | ||||
|         if (files.Length != 0) | ||||
|         { | ||||
|             if (files.Length > 250) | ||||
|                 throw new Exception("Safety net!"); | ||||
|             try | ||||
|             { | ||||
|                 foreach (string file in files) | ||||
|                     File.Delete(file); | ||||
|             } | ||||
|             catch (Exception) { } | ||||
|         } | ||||
|         if (_FileConnectorConfiguration.IncludeSubDirectories.Value) | ||||
|             files = Directory.GetFiles(targetFileLocation, "*", SearchOption.AllDirectories); | ||||
|         else | ||||
|             files = Directory.GetFiles(targetFileLocation, "*", SearchOption.TopDirectoryOnly); | ||||
|         foreach (string file in files) | ||||
|         { | ||||
|             if (new FileInfo(file).LastWriteTime.Ticks == sequence) | ||||
|             { | ||||
|                 warning = true; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         CallbackInProcessCleared(sourceArchiveFile, traceDummyFile, targetFileLocation, monARessource, inProcessDirectory, sequence, warning); | ||||
|     } | ||||
|  | ||||
|     private string GetCellName(string pathSegment) | ||||
|     { | ||||
|         string result = string.Empty; | ||||
|         foreach (string cellName in _CellNames) | ||||
|         { | ||||
|             if (pathSegment.ToLower().Contains(cellName.ToLower())) | ||||
|             { | ||||
|                 result = cellName; | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         if (string.IsNullOrEmpty(result)) | ||||
|         { | ||||
|             int count; | ||||
|             List<(string CellName, int Count)> cellNames = new(); | ||||
|             foreach (string cellName in _CellNames) | ||||
|             { | ||||
|                 count = 0; | ||||
|                 foreach (char @char in cellName.ToLower()) | ||||
|                     count += pathSegment.Length - pathSegment.ToLower().Replace(@char.ToString(), string.Empty).Length; | ||||
|                 cellNames.Add(new(cellName, count)); | ||||
|             } | ||||
|             result = (from l in cellNames orderby l.CellName.Length, l.Count descending select l.CellName).First(); | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     private void Callback(object state) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             string sourceParentDirectory; | ||||
|             string targetParentDirectory; | ||||
|             DateTime dateTime = DateTime.Now; | ||||
|             if (!string.IsNullOrEmpty(Path.GetFileName(_FileConnectorConfiguration.SourceFileLocation))) | ||||
|                 sourceParentDirectory = Path.GetDirectoryName(_FileConnectorConfiguration.SourceFileLocation); | ||||
|             else | ||||
|                 sourceParentDirectory = GetParentParent(_FileConnectorConfiguration.SourceFileLocation); | ||||
|             if (!string.IsNullOrEmpty(Path.GetFileName(_FileConnectorConfiguration.TargetFileLocation))) | ||||
|                 targetParentDirectory = Path.GetDirectoryName(_FileConnectorConfiguration.TargetFileLocation); | ||||
|             else | ||||
|                 targetParentDirectory = GetParentParent(_FileConnectorConfiguration.TargetFileLocation); | ||||
|             if (sourceParentDirectory != targetParentDirectory) | ||||
|                 throw new Exception("Target and source must have the same parent for Si Dummy FileConnectorConfiguration!"); | ||||
|             bool check = dateTime.Hour > 7 && dateTime.Hour < 18 && dateTime.DayOfWeek != DayOfWeek.Sunday && dateTime.DayOfWeek != DayOfWeek.Saturday; | ||||
|             if (!_IsEAFHosted || check) | ||||
|             { | ||||
|                 string monARessource; | ||||
|                 string sourceFileFilter; | ||||
|                 string sourceArchiveFile; | ||||
|                 string weekOfYear = _Calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); | ||||
|                 string traceDummyDirectory = Path.Combine(Path.GetPathRoot(_TracePath), "TracesDummy", _CellInstanceName, "Source", $"{dateTime:yyyy}___Week_{weekOfYear}"); | ||||
|                 if (!Directory.Exists(traceDummyDirectory)) | ||||
|                     _ = Directory.CreateDirectory(traceDummyDirectory); | ||||
|                 string traceDummyFile = Path.Combine(traceDummyDirectory, $"{dateTime.Ticks} - {_CellInstanceName}.txt"); | ||||
|                 File.AppendAllText(traceDummyFile, string.Empty); | ||||
|                 for (int i = 0; i < _FileConnectorConfiguration.SourceFileFilters.Count; i++) | ||||
|                 { | ||||
|                     _LastDummyRunIndex += 1; | ||||
|                     if (_LastDummyRunIndex >= _FileConnectorConfiguration.SourceFileFilters.Count) | ||||
|                         _LastDummyRunIndex = 0; | ||||
|                     sourceFileFilter = _FileConnectorConfiguration.SourceFileFilters[_LastDummyRunIndex]; | ||||
|                     sourceArchiveFile = Path.Combine(_FileConnectorConfiguration.SourceFileLocation, sourceFileFilter); | ||||
|                     if (File.Exists(sourceArchiveFile)) | ||||
|                     { | ||||
|                         if (!long.TryParse(Path.GetFileNameWithoutExtension(sourceArchiveFile).Replace("x", string.Empty), out long sequence)) | ||||
|                             throw new Exception("Invalid file name for source archive file!"); | ||||
|                         monARessource = GetCellName(sourceArchiveFile); | ||||
|                         if (string.IsNullOrEmpty(monARessource)) | ||||
|                             throw new Exception("Could not determine which cell archive file is associated with!"); | ||||
|                         if (_IsEAFHosted) | ||||
|                             CallbackFileExists(sourceArchiveFile, traceDummyFile, _FileConnectorConfiguration.TargetFileLocation, monARessource, sequence); | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         catch (Exception exception) | ||||
|         { | ||||
|             string subject = string.Concat("Exception:", _CellInstanceConnectionName); | ||||
|             string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace); | ||||
|             try | ||||
|             { | ||||
|                 _SMTP.SendHighPriorityEmailMessage(subject, body);  | ||||
|                 File.WriteAllText(".email", body); | ||||
|             } | ||||
|             catch (Exception) { } | ||||
|         } | ||||
|         try | ||||
|         { | ||||
|             TimeSpan timeSpan = new(DateTime.Now.AddSeconds(_FileConnectorConfiguration.FileScanningIntervalInSeconds.Value).Ticks - DateTime.Now.Ticks); | ||||
|             _ = _Timer.Change((long)timeSpan.TotalMilliseconds, Timeout.Infinite); | ||||
|         } | ||||
|         catch (Exception exception) | ||||
|         { | ||||
|             string subject = string.Concat("Exception:", _CellInstanceConnectionName); | ||||
|             string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace); | ||||
|             try | ||||
|             { | ||||
|                 _SMTP.SendHighPriorityEmailMessage(subject, body);  | ||||
|                 File.WriteAllText(".email", body); | ||||
|             } | ||||
|             catch (Exception) { } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -1,134 +0,0 @@ | ||||
| using Adaptation.Eaf.Management.ConfigurationData.CellAutomation; | ||||
| using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration; | ||||
| using Adaptation.Shared; | ||||
| using Adaptation.Shared.Duplicator; | ||||
| using Adaptation.Shared.Methods; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.IQSSi; | ||||
|  | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
|         _NullData = string.Empty; | ||||
|         _Logistics = new(this); | ||||
|         if (_FileParameter is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (_ModelObjectParameterDefinitions is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (!_IsDuplicator) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|     } | ||||
|  | ||||
|     void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) | ||||
|     { | ||||
|         bool isErrorFile = exception is not null; | ||||
|         if (!isErrorFile && !string.IsNullOrEmpty(_Logistics.ReportFullPath)) | ||||
|         { | ||||
|             FileInfo fileInfo = new(_Logistics.ReportFullPath); | ||||
|             if (fileInfo.Exists && fileInfo.LastWriteTime < fileInfo.CreationTime) | ||||
|                 File.SetLastWriteTime(_Logistics.ReportFullPath, fileInfo.CreationTime); | ||||
|         } | ||||
|         Move(extractResults); | ||||
|     } | ||||
|  | ||||
|     void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null); | ||||
|  | ||||
|     string IFileRead.GetEventDescription() | ||||
|     { | ||||
|         string result = _Description.GetEventDescription(); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     List<string> IFileRead.GetHeaderNames() | ||||
|     { | ||||
|         List<string> results = _Description.GetHeaderNames(); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     string[] IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, string to, string from, string resolvedFileLocation, Exception exception) | ||||
|     { | ||||
|         string[] results = Move(extractResults, to, from, resolvedFileLocation, exception); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     JsonProperty[] IFileRead.GetDefault() | ||||
|     { | ||||
|         JsonProperty[] results = _Description.GetDefault(this, _Logistics); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Dictionary<string, string> IFileRead.GetDisplayNamesJsonElement() | ||||
|     { | ||||
|         Dictionary<string, string> results = _Description.GetDisplayNamesJsonElement(this); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     List<IDescription> IFileRead.GetDescriptions(IFileRead fileRead, List<Test> tests, IProcessData processData) | ||||
|     { | ||||
|         List<IDescription> results = _Description.GetDescriptions(fileRead, _Logistics, tests, processData); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.GetExtractResult(string reportFullPath, string eventName) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         if (string.IsNullOrEmpty(eventName)) | ||||
|             throw new Exception(); | ||||
|         _ReportFullPath = reportFullPath; | ||||
|         DateTime dateTime = DateTime.Now; | ||||
|         results = GetExtractResult(reportFullPath, dateTime); | ||||
|         if (results.Item3 is null) | ||||
|             results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]"), results.Item4); | ||||
|         if (results.Item3.Length > 0 && _IsEAFHosted) | ||||
|             WritePDSF(this, results.Item3); | ||||
|         UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.ReExtract() | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         List<string> headerNames = _Description.GetHeaderNames(); | ||||
|         Dictionary<string, string> keyValuePairs = _Description.GetDisplayNamesJsonElement(this); | ||||
|         results = ReExtract(this, headerNames, keyValuePairs); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private void FileCopy<T>(string reportFullPath, DateTime dateTime, List<T> descriptions) where T : Shared.Properties.IDescription | ||||
|     { | ||||
|         bool isDummyRun = false; | ||||
|         string successDirectory = string.Empty; | ||||
|         List<(Shared.Properties.IScopeInfo, string)> collection = new(); | ||||
|         string duplicateDirectory = Path.Combine(_FileConnectorConfiguration.SourceFileLocation, _CellInstanceName); | ||||
|         if (!Directory.Exists(duplicateDirectory)) | ||||
|             _ = Directory.CreateDirectory(duplicateDirectory); | ||||
|         string duplicateFile = Path.Combine(duplicateDirectory, Path.GetFileName(reportFullPath)); | ||||
|         File.Copy(reportFullPath, duplicateFile, overwrite: true); | ||||
|         WaitForFileConsumption(dateTime, descriptions, isDummyRun, successDirectory, duplicateDirectory, collection, duplicateFile); | ||||
|     } | ||||
|  | ||||
|     private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath); | ||||
|         _Logistics = new Logistics(reportFullPath, pdsf.Item1); | ||||
|         SetFileParameterLotIDToLogisticsMID(); | ||||
|         JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf); | ||||
|         List<Shared.Properties.IDescription> descriptions = GetDuplicatorDescriptions(jsonElements); | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             FileCopy(reportFullPath, dateTime, descriptions); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>()); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -16,7 +16,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     private long? _TickOffset; | ||||
|     private readonly string _URL; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -103,16 +103,19 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results = new(string.Empty, null, null, new List<FileInfo>()); | ||||
|         _TickOffset ??= 0; // new FileInfo(reportFullPath).LastWriteTime.Ticks - dateTime.Ticks; | ||||
|         _Logistics = new Logistics(reportFullPath, $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};"); | ||||
|         string[] lines = new string[] { string.Empty, "NUM_DATA_ROWS", $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};" }; | ||||
|         ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines); | ||||
|         _Logistics = new Logistics(reportFullPath, processDataStandardFormat); | ||||
|         SetFileParameterLotIDToLogisticsMID(); | ||||
|         if (_Logistics.FileInfo.Length < _MinFileLength) | ||||
|             results.Item4.Add(_Logistics.FileInfo); | ||||
|         else | ||||
|         { | ||||
|             IProcessData iProcessData = new ProcessData(this, _Logistics, _FileConnectorConfiguration.TargetFileLocation, _URL, results.Item4); | ||||
|             IProcessData iProcessData = new ProcessData(this, _Logistics, _Calendar, _FileConnectorConfiguration.TargetFileLocation, _URL, results.Item4); | ||||
|             if (iProcessData.Details.Count == 0) | ||||
|                 throw new Exception(string.Concat("B) No Data - ", dateTime.Ticks)); | ||||
|             results = iProcessData.GetResults(this, _Logistics, results.Item4); | ||||
|                 results = new(string.Concat("B) No Data - ", dateTime.Ticks), Array.Empty<Test>(), Array.Empty<JsonElement>(), results.Item4); | ||||
|             else | ||||
|                 results = iProcessData.GetResults(this, _Logistics, results.Item4); | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| @ -6,6 +6,7 @@ using log4net; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.ObjectModel; | ||||
| using System.Globalization; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
| @ -13,6 +14,8 @@ using System.Text.Json.Serialization; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.Kanban; | ||||
|  | ||||
| #nullable enable | ||||
|  | ||||
| public class ProcessData : IProcessData | ||||
| { | ||||
|  | ||||
| @ -22,47 +25,82 @@ public class ProcessData : IProcessData | ||||
|  | ||||
|     private readonly ILog _Log; | ||||
|  | ||||
|     public ProcessData(IFileRead fileRead, Logistics logistics, string targetFileLocation, string url, List<FileInfo> fileInfoCollection) | ||||
|     { | ||||
|         if (fileRead.IsEAFHosted) | ||||
|         { } | ||||
|         if (url is null) | ||||
|             throw new ArgumentNullException(nameof(url)); | ||||
|         fileInfoCollection.Clear(); | ||||
|         _Details = new List<object>(); | ||||
|         _Log = LogManager.GetLogger(typeof(ProcessData)); | ||||
|         WriteFiles(fileRead, logistics, targetFileLocation, fileInfoCollection); | ||||
|     } | ||||
|  | ||||
|     string IProcessData.GetCurrentReactor(IFileRead fileRead, Logistics logistics, Dictionary<string, string> reactors) => | ||||
|         throw new Exception(string.Concat("See ", nameof(WriteFiles))); | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IProcessData.GetResults(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection) => | ||||
|         new(logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), fileInfoCollection); | ||||
|  | ||||
| #nullable enable | ||||
|  | ||||
|     internal static List<Description> GetDescriptions(JsonElement[] jsonElements) | ||||
|     public ProcessData(IFileRead fileRead, Logistics logistics, Calendar calendar, string targetFileLocation, string url, List<FileInfo> fileInfoCollection) | ||||
|     { | ||||
|         List<Description> results = new(); | ||||
|         Description? description; | ||||
|         JsonSerializerOptions jsonSerializerOptions = new() { NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString }; | ||||
|         foreach (JsonElement jsonElement in jsonElements) | ||||
|         if (fileRead.IsEAFHosted) | ||||
|         { | ||||
|             if (jsonElement.ValueKind != JsonValueKind.Object) | ||||
|                 throw new Exception(); | ||||
|             description = JsonSerializer.Deserialize<Description>(jsonElement.ToString(), jsonSerializerOptions); | ||||
|             if (description is null) | ||||
|                 continue; | ||||
|             results.Add(description); | ||||
|  | ||||
|         } | ||||
|         return results; | ||||
|         if (url is null) | ||||
|             throw new ArgumentNullException(nameof(url)); | ||||
|         _Details = new List<object>(); | ||||
|         _Log = LogManager.GetLogger(typeof(ProcessData)); | ||||
|         WriteFiles(fileRead, logistics, calendar, targetFileLocation, fileInfoCollection); | ||||
|     } | ||||
|  | ||||
|     private void WriteFiles(IFileRead fileRead, Logistics logistics, string destinationDirectory, List<FileInfo> fileInfoCollection) | ||||
|     private static void WriteFiles(IFileRead fileRead, Calendar calendar, string destinationDirectory, bool keepRelations, WorkItem[] workItems) | ||||
|     { | ||||
|         string json; | ||||
|         string text; | ||||
|         string jsonOld; | ||||
|         string jsonFile; | ||||
|         string textFile; | ||||
|         string weekOfYear; | ||||
|         WorkItem workItem; | ||||
|         DirectoryInfo directory; | ||||
|         DirectoryInfo kanbnDirectory; | ||||
|         DirectoryInfo tasksDirectory; | ||||
|         DirectoryInfo visualStudioCodeDirectory; | ||||
|         ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations); | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             workItem = keyValuePair.Value.WorkItem; | ||||
|             json = JsonSerializer.Serialize(workItem, WorkItemSourceGenerationContext.Default.WorkItem); | ||||
|             weekOfYear = calendar.GetWeekOfYear(workItem.CreatedDate, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); | ||||
|             directory = new(Path.Combine(destinationDirectory, "{}", $"{workItem.CreatedDate:yyyy}", $"{workItem.CreatedDate:yyyy}_Week_{weekOfYear}", $"{workItem.Id}")); | ||||
|             text = GetTaskText(directory.FullName); | ||||
|             visualStudioCodeDirectory = new(Path.Combine(directory.FullName, ".vscode")); | ||||
|             if (!visualStudioCodeDirectory.Exists) | ||||
|                 _ = Directory.CreateDirectory(visualStudioCodeDirectory.FullName); | ||||
|             textFile = Path.Combine(visualStudioCodeDirectory.FullName, "tasks.json"); | ||||
|             if (fileRead.IsEAFHosted && !File.Exists(textFile)) | ||||
|                 File.WriteAllText(textFile, text); | ||||
|             kanbnDirectory = new(Path.Combine(directory.FullName, ".kanbn")); | ||||
|             tasksDirectory = new(Path.Combine(kanbnDirectory.FullName, "tasks")); | ||||
|             if (!tasksDirectory.Exists) | ||||
|                 _ = Directory.CreateDirectory(tasksDirectory.FullName); | ||||
|             jsonFile = Path.Combine(kanbnDirectory.FullName, $"{workItem.Id}.json"); | ||||
|             jsonOld = File.Exists(jsonFile) ? File.ReadAllText(jsonFile) : string.Empty; | ||||
|             if (fileRead.IsEAFHosted && jsonOld != json) | ||||
|                 File.WriteAllText(jsonFile, json); | ||||
|             if (keyValuePair.Value.Children is not null && keyValuePair.Value.Children.Length > 0) | ||||
|                 WriteFiles(fileRead, tasksDirectory, keyValuePair.Value.Children); | ||||
|             if (visualStudioCodeDirectory.LastWriteTime != workItem.CreatedDate) | ||||
|                 Directory.SetLastWriteTime(visualStudioCodeDirectory.FullName, workItem.CreatedDate); | ||||
|             if (kanbnDirectory.LastWriteTime != workItem.CreatedDate) | ||||
|                 Directory.SetLastWriteTime(kanbnDirectory.FullName, workItem.CreatedDate); | ||||
|             if (directory.LastWriteTime != workItem.CreatedDate) | ||||
|                 Directory.SetLastWriteTime(directory.FullName, workItem.CreatedDate); | ||||
|             if (visualStudioCodeDirectory.CreationTime != workItem.CreatedDate) | ||||
|                 Directory.SetCreationTime(visualStudioCodeDirectory.FullName, workItem.CreatedDate); | ||||
|             if (kanbnDirectory.CreationTime != workItem.CreatedDate) | ||||
|                 Directory.SetCreationTime(kanbnDirectory.FullName, workItem.CreatedDate); | ||||
|             if (directory.CreationTime != workItem.CreatedDate) | ||||
|                 Directory.SetCreationTime(directory.FullName, workItem.CreatedDate); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void WriteFiles(IFileRead fileRead, Logistics logistics, Calendar calendar, string destinationDirectory, List<FileInfo> fileInfoCollection) | ||||
|     { | ||||
|         if (fileInfoCollection is null) | ||||
|             throw new ArgumentNullException(nameof(fileInfoCollection)); | ||||
|         bool keepRelations = true; | ||||
|         const string taskWorkItemType = "Task"; | ||||
|         string json = File.ReadAllText(logistics.ReportFullPath); | ||||
|         WorkItem[]? workItems = JsonSerializer.Deserialize<WorkItem[]>(json); | ||||
|         if (workItems is null) | ||||
| @ -70,10 +108,30 @@ public class ProcessData : IProcessData | ||||
|         _Details.Add(workItems); | ||||
|         if (!Directory.Exists(destinationDirectory)) | ||||
|             _ = Directory.CreateDirectory(destinationDirectory); | ||||
|         ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations); | ||||
|         ReadOnlyCollection<string> bugUserStoryTaskWorkItemTypes = new(new string[] { "Bug", "User Story", "Task" }); | ||||
|         ReadOnlyDictionary<int, string> collection = MoveCurrentAndGetExpectedDirectoriesAndFileCopy(taskWorkItemType, destinationDirectory, json, bugUserStoryTaskWorkItemTypes, keyValuePairs); | ||||
|         WriteFiles(fileRead, fileInfoCollection, taskWorkItemType, destinationDirectory, keyValuePairs, collection); | ||||
|         WriteFiles(fileRead, calendar, destinationDirectory, workItems); | ||||
|         WriteFiles(fileRead, calendar, destinationDirectory, keepRelations, workItems); | ||||
|     } | ||||
|  | ||||
|     private static void WriteFiles(IFileRead fileRead, Calendar calendar, string destinationDirectory, WorkItem[] workItems) | ||||
|     { | ||||
|         string old; | ||||
|         string json; | ||||
|         string directory; | ||||
|         string checkFile; | ||||
|         string weekOfYear; | ||||
|         foreach (WorkItem workItem in workItems) | ||||
|         { | ||||
|             weekOfYear = calendar.GetWeekOfYear(workItem.CreatedDate, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); | ||||
|             directory = Path.Combine(destinationDirectory, "[]", $"{workItem.CreatedDate:yyyy}", $"{workItem.CreatedDate:yyyy}_Week_{weekOfYear}", $"{workItem.Id}"); | ||||
|             if (!Directory.Exists(directory)) | ||||
|                 _ = Directory.CreateDirectory(directory); | ||||
|             json = JsonSerializer.Serialize(workItem, WorkItemSourceGenerationContext.Default.WorkItem); | ||||
|             checkFile = Path.Combine(directory, $"{workItem.Id}.json"); | ||||
|             old = File.Exists(checkFile) ? File.ReadAllText(checkFile) : string.Empty; | ||||
|             if (!fileRead.IsEAFHosted || old == json) | ||||
|                 continue; | ||||
|             File.WriteAllText(checkFile, json); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyDictionary<int, Record> GetWorkItems(WorkItem[] workItems, bool keepRelations) | ||||
| @ -86,68 +144,6 @@ public class ProcessData : IProcessData | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyDictionary<int, string> MoveCurrentAndGetExpectedDirectoriesAndFileCopy(string taskWorkItemType, string destinationDirectory, string json, ReadOnlyCollection<string> bugUserStoryTaskWorkItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs) | ||||
|     { | ||||
|         ReadOnlyDictionary<int, string> results; | ||||
|         string? directory; | ||||
|         ReadOnlyDictionary<int, string> collection = GetCurrentDirectories(destinationDirectory, bugUserStoryTaskWorkItemTypes); | ||||
|         results = GetExpectedDirectoriesAndFileCopy(taskWorkItemType, destinationDirectory, json, bugUserStoryTaskWorkItemTypes, keyValuePairs); | ||||
|         foreach (KeyValuePair<int, string> keyValuePair in collection) | ||||
|         { | ||||
|             if (!results.TryGetValue(keyValuePair.Key, out directory)) | ||||
|                 MoveToUnknown(destinationDirectory, keyValuePair.Key, keyValuePair.Value); | ||||
|             else | ||||
|             { | ||||
|                 if (keyValuePair.Value == directory) | ||||
|                     continue; | ||||
|                 else | ||||
|                     MoveToNew(destinationDirectory, keyValuePair.Key, keyValuePair.Value, directory); | ||||
|             } | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private static FileInfo GetFileInfoAndMaybeWriteFile(string directory, WorkItem workItem) | ||||
|     { | ||||
|         FileInfo result; | ||||
|         string json = JsonSerializer.Serialize(workItem, WorkItemSourceGenerationContext.Default.WorkItem); | ||||
|         string singletonDirectory = Path.Combine(directory, $"{workItem.Id}"); | ||||
|         if (Directory.Exists(singletonDirectory)) | ||||
|         { | ||||
|             List<string> files = Directory.GetFiles(singletonDirectory, "*", SearchOption.AllDirectories).ToList(); | ||||
|             string checkFile = Path.Combine(singletonDirectory, ".json"); | ||||
|             if (files.Remove(checkFile)) | ||||
|                 File.Delete(checkFile); | ||||
|             if (files.Count == 0) | ||||
|                 Directory.Delete(singletonDirectory); | ||||
|         } | ||||
|         result = new(Path.Combine(directory, $"{workItem.Id}.json")); | ||||
|         string old = result.Exists ? File.ReadAllText(result.FullName) : string.Empty; | ||||
|         if (old != json) | ||||
|             File.WriteAllText(result.FullName, json); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     private static void WriteFiles(IFileRead fileRead, List<FileInfo> fileInfoCollection, string taskWorkItemType, string destinationDirectory, ReadOnlyDictionary<int, Record> keyValuePairs, ReadOnlyDictionary<int, string> collection) | ||||
|     { | ||||
|         string? directory; | ||||
|         FileInfo fileInfo; | ||||
|         WorkItem workItem; | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             workItem = keyValuePair.Value.WorkItem; | ||||
|             if (!collection.TryGetValue(keyValuePair.Key, out directory)) | ||||
|             { | ||||
|                 if (workItem.WorkItemType != taskWorkItemType || workItem.Parent is not null) | ||||
|                     continue; | ||||
|                 directory = GetDirectory(destinationDirectory, workItem); | ||||
|             } | ||||
|             fileInfo = GetFileInfoAndMaybeWriteFile(directory, workItem); | ||||
|             if (!fileRead.IsEAFHosted) | ||||
|                 fileInfoCollection.Add(fileInfo); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyDictionary<int, Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, bool keepRelations) | ||||
|     { | ||||
|         Dictionary<int, Record> results = new(); | ||||
| @ -174,123 +170,68 @@ public class ProcessData : IProcessData | ||||
|             } | ||||
|             catch (Exception) | ||||
|             { | ||||
|                 record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>()); | ||||
|                 Dictionary<string, string>? tag = null; | ||||
|                 record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>(), tag); | ||||
|             } | ||||
|             results.Add(keyValuePair.Key, record); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyDictionary<int, string> GetCurrentDirectories(string destinationDirectory, ReadOnlyCollection<string> bugUserStoryTaskWorkItemTypes) | ||||
|     { | ||||
|         Dictionary<int, string> results = new(); | ||||
|         int id; | ||||
|         string idCheck; | ||||
|         string? fileName; | ||||
|         string[] directories; | ||||
|         string[] split = new string[] { "-" }; | ||||
|         foreach (string w in bugUserStoryTaskWorkItemTypes) | ||||
|     private static string GetTaskText(string directory) => | ||||
|         string.Join(Environment.NewLine, new string[] | ||||
|         { | ||||
|             directories = Directory.GetDirectories(destinationDirectory, $"*-{w.Replace(" ", "-")}", SearchOption.AllDirectories); | ||||
|             foreach (string directory in directories) | ||||
|             { | ||||
|                 fileName = Path.GetFileName(directory); | ||||
|                 if (string.IsNullOrEmpty(fileName)) | ||||
|                     continue; | ||||
|                 idCheck = fileName.Split(split, StringSplitOptions.None)[0]; | ||||
|                 if (!int.TryParse(idCheck, out id)) | ||||
|                     continue; | ||||
|                 if (!results.ContainsKey(id)) | ||||
|                     results.Add(id, directory); | ||||
|                 else | ||||
|                     MoveToDuplicate(destinationDirectory, directory); | ||||
|             } | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|             "{", | ||||
|             "\"version\": \"2.0.0\",", | ||||
|             "\"tasks\": [", | ||||
|             "{", | ||||
|             "\"label\": \"File-Folder-Helper AOT s X Day-Helper-2025-02-04\",", | ||||
|             "\"type\": \"shell\",", | ||||
|             "\"command\": \"L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe\",", | ||||
|             "\"args\": [", | ||||
|             "\"s\",", | ||||
|             "\"X\",", | ||||
|             $"\"{directory.Replace('\\', '/')}\",", | ||||
|             "\"Day-Helper-2025-02-04\",", | ||||
|             "],", | ||||
|             "\"problemMatcher\": []", | ||||
|             "}", | ||||
|             "]", | ||||
|             "}", | ||||
|         }); | ||||
|  | ||||
|     private static void FileCopy(string destinationDirectory, string json, List<string> distinct) | ||||
|     private static void WriteFiles(IFileRead fileRead, DirectoryInfo tasksDirectory, Record[] records) | ||||
|     { | ||||
|         string old; | ||||
|         string json; | ||||
|         string checkFile; | ||||
|         foreach (string iterationPath in distinct) | ||||
|         { | ||||
|             checkFile = Path.Combine(destinationDirectory, iterationPath, "[].json"); | ||||
|             old = File.Exists(checkFile) ? File.ReadAllText(checkFile) : string.Empty; | ||||
|             if (old != json) | ||||
|                 File.WriteAllText(checkFile, json); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyDictionary<int, string> GetExpectedDirectoriesAndFileCopy(string taskWorkItemType, string destinationDirectory, string json, ReadOnlyCollection<string> bugUserStoryTaskWorkItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs) | ||||
|     { | ||||
|         Dictionary<int, string> results = new(); | ||||
|         string directory; | ||||
|         WorkItem workItem; | ||||
|         string iterationPath; | ||||
|         List<string> distinct = new(); | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         foreach (Record record in records) | ||||
|         { | ||||
|             workItem = keyValuePair.Value.WorkItem; | ||||
|             iterationPath = workItem.IterationPath.Replace(" ", "-"); | ||||
|             if (!distinct.Contains(iterationPath)) | ||||
|                 distinct.Add(iterationPath); | ||||
|             if (!bugUserStoryTaskWorkItemTypes.Contains(workItem.WorkItemType)) | ||||
|             workItem = record.WorkItem; | ||||
|             json = JsonSerializer.Serialize(workItem, WorkItemSourceGenerationContext.Default.WorkItem); | ||||
|             checkFile = Path.Combine(tasksDirectory.FullName, $"{workItem.Id}.json"); | ||||
|             old = File.Exists(checkFile) ? File.ReadAllText(checkFile) : string.Empty; | ||||
|             if (!fileRead.IsEAFHosted || old == json) | ||||
|                 continue; | ||||
|             if (workItem.WorkItemType == taskWorkItemType && workItem.Parent is not null) | ||||
|                 continue; | ||||
|             directory = GetDirectory(destinationDirectory, workItem); | ||||
|             results.Add(workItem.Id, directory); | ||||
|         } | ||||
|         if (distinct.Count > 0) | ||||
|             FileCopy(destinationDirectory, json, distinct); | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static void MoveToUnknown(string destinationDirectory, int id, string directory) | ||||
|     { | ||||
|         if (string.IsNullOrEmpty(destinationDirectory)) | ||||
|             throw new ArgumentException($"'{nameof(destinationDirectory)}' {id} cannot be null or empty.", nameof(destinationDirectory)); | ||||
|         if (string.IsNullOrEmpty(directory)) | ||||
|             throw new ArgumentException($"'{nameof(directory)}' cannot be null or empty.", nameof(directory)); | ||||
|     } | ||||
|  | ||||
|     private static void MoveToNew(string destinationDirectory, int id, string oldDirectory, string newDirectory) | ||||
|     { | ||||
|         if (Directory.Exists(newDirectory)) | ||||
|             MoveToDuplicate(destinationDirectory, id, oldDirectory); | ||||
|         else | ||||
|         { | ||||
|             string directory = Path.GetDirectoryName(newDirectory) ?? throw new NotImplementedException(); | ||||
|             if (!Directory.Exists(directory)) | ||||
|                 _ = Directory.CreateDirectory(directory); | ||||
|             Directory.Move(oldDirectory, newDirectory); | ||||
|             File.WriteAllText(checkFile, json); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static string GetDirectory(string destinationDirectory, WorkItem workItem) | ||||
|     internal static List<Description> GetDescriptions(JsonElement[] jsonElements) | ||||
|     { | ||||
|         string result; | ||||
|         string workItemType = workItem.WorkItemType.Replace(" ", "-"); | ||||
|         string iterationPath = workItem.IterationPath.Replace(" ", "-"); | ||||
|         result = Path.Combine(destinationDirectory, iterationPath, $"{workItem.Id}-{workItemType}"); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     private static void MoveToDuplicate(string destinationDirectory, string directory) | ||||
|     { | ||||
|         if (string.IsNullOrEmpty(destinationDirectory)) | ||||
|             throw new ArgumentException($"'{nameof(destinationDirectory)}' cannot be null or empty.", nameof(destinationDirectory)); | ||||
|         if (string.IsNullOrEmpty(directory)) | ||||
|             throw new ArgumentException($"'{nameof(directory)}' cannot be null or empty.", nameof(directory)); | ||||
|     } | ||||
|  | ||||
|     private static void MoveToDuplicate(string destinationDirectory, int id, string oldDirectory) | ||||
|     { | ||||
|         if (string.IsNullOrEmpty(destinationDirectory)) | ||||
|             throw new ArgumentException($"'{nameof(destinationDirectory)}' {id} cannot be null or empty.", nameof(destinationDirectory)); | ||||
|         if (string.IsNullOrEmpty(oldDirectory)) | ||||
|             throw new ArgumentException($"'{nameof(oldDirectory)}' cannot be null or empty.", nameof(oldDirectory)); | ||||
|         List<Description> results = new(); | ||||
|         Description? description; | ||||
|         foreach (JsonElement jsonElement in jsonElements) | ||||
|         { | ||||
|             if (jsonElement.ValueKind != JsonValueKind.Object) | ||||
|                 throw new Exception(); | ||||
|             description = JsonSerializer.Deserialize(jsonElement.ToString(), SharedDescriptionSourceGenerationContext.Default.Description); | ||||
|             if (description is null) | ||||
|                 continue; | ||||
|             results.Add(description); | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -18,7 +18,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     private readonly string _URL; | ||||
|     private readonly ReadOnlyCollection<string> _WorkItemTypes; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -107,7 +107,9 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results = new(string.Empty, null, null, new List<FileInfo>()); | ||||
|         _TickOffset ??= 0; // new FileInfo(reportFullPath).LastWriteTime.Ticks - dateTime.Ticks; | ||||
|         _Logistics = new Logistics(reportFullPath, $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};"); | ||||
|         string[] lines = new string[] { string.Empty, "NUM_DATA_ROWS", $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};" }; | ||||
|         ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines); | ||||
|         _Logistics = new Logistics(reportFullPath, processDataStandardFormat); | ||||
|         SetFileParameterLotIDToLogisticsMID(); | ||||
|         if (_Logistics.FileInfo.Length < _MinFileLength) | ||||
|             results.Item4.Add(_Logistics.FileInfo); | ||||
| @ -115,8 +117,9 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         { | ||||
|             IProcessData iProcessData = new ProcessData(this, _Logistics, _FileConnectorConfiguration.TargetFileLocation, _URL, _WorkItemTypes, results.Item4); | ||||
|             if (iProcessData.Details.Count == 0) | ||||
|                 throw new Exception(string.Concat("B) No Data - ", dateTime.Ticks)); | ||||
|             results = iProcessData.GetResults(this, _Logistics, results.Item4); | ||||
|                 results = new(string.Concat("B) No Data - ", dateTime.Ticks), Array.Empty<Test>(), Array.Empty<JsonElement>(), results.Item4); | ||||
|             else | ||||
|                 results = iProcessData.GetResults(this, _Logistics, results.Item4); | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| @ -13,6 +13,8 @@ using System.Text.Json.Serialization; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.Markdown; | ||||
|  | ||||
| #nullable enable | ||||
|  | ||||
| public class ProcessData : IProcessData | ||||
| { | ||||
|  | ||||
| @ -22,39 +24,46 @@ public class ProcessData : IProcessData | ||||
|  | ||||
|     private readonly ILog _Log; | ||||
|  | ||||
|     public ProcessData(IFileRead fileRead, Logistics logistics, string targetFileLocation, string url, ReadOnlyCollection<string> workItemTypes, List<FileInfo> fileInfoCollection) | ||||
|     { | ||||
|         if (fileRead.IsEAFHosted) | ||||
|         { } | ||||
|         fileInfoCollection.Clear(); | ||||
|         _Details = new List<object>(); | ||||
|         _Log = LogManager.GetLogger(typeof(ProcessData)); | ||||
|         WriteFiles(fileRead, logistics, url, workItemTypes, targetFileLocation, fileInfoCollection); | ||||
|     } | ||||
|  | ||||
|     string IProcessData.GetCurrentReactor(IFileRead fileRead, Logistics logistics, Dictionary<string, string> reactors) => | ||||
|         throw new Exception(string.Concat("See ", nameof(WriteFiles))); | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IProcessData.GetResults(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection) => | ||||
|         new(logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), fileInfoCollection); | ||||
|  | ||||
| #nullable enable | ||||
|     private static string GetClosed(WorkItem workItem) => | ||||
|         workItem.State != "Closed" ? "[ ]" : "[x]"; | ||||
|  | ||||
|     internal static List<Description> GetDescriptions(JsonElement[] jsonElements) | ||||
|     public ProcessData(IFileRead fileRead, Logistics logistics, string targetFileLocation, string url, ReadOnlyCollection<string> workItemTypes, List<FileInfo> fileInfoCollection) | ||||
|     { | ||||
|         List<Description> results = new(); | ||||
|         Description? description; | ||||
|         JsonSerializerOptions jsonSerializerOptions = new() { NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString }; | ||||
|         foreach (JsonElement jsonElement in jsonElements) | ||||
|         { | ||||
|             if (jsonElement.ValueKind != JsonValueKind.Object) | ||||
|                 throw new Exception(); | ||||
|             description = JsonSerializer.Deserialize<Description>(jsonElement.ToString(), jsonSerializerOptions); | ||||
|             if (description is null) | ||||
|                 continue; | ||||
|             results.Add(description); | ||||
|         } | ||||
|         return results; | ||||
|         _Details = new List<object>(); | ||||
|         _Log = LogManager.GetLogger(typeof(ProcessData)); | ||||
|         if (fileRead.IsEAFHosted) | ||||
|             WriteFiles(fileRead, logistics, url, workItemTypes, targetFileLocation, fileInfoCollection); | ||||
|     } | ||||
|  | ||||
|     private static void WriteFiles(IFileRead fileRead, string destinationDirectory, List<FileInfo> fileInfoCollection, ReadOnlyCollection<string> lines, ReadOnlyCollection<Record> records, string fileName) | ||||
|     { | ||||
|         string markdown = string.Join(Environment.NewLine, lines); | ||||
|         string markdownFile = Path.Combine(destinationDirectory, $"{fileName}.md"); | ||||
|         string markdownOld = !File.Exists(markdownFile) ? string.Empty : File.ReadAllText(markdownFile); | ||||
|         if (markdown != markdownOld) | ||||
|             File.WriteAllText(markdownFile, markdown); | ||||
|         if (!fileRead.IsEAFHosted) | ||||
|             fileInfoCollection.Add(new(markdownFile)); | ||||
|         string html = CommonMark.CommonMarkConverter.Convert(markdown).Replace("<a href", "<a target='_blank' href"); | ||||
|         string htmlFile = Path.Combine(destinationDirectory, $"{fileName}.html"); | ||||
|         string htmlOld = !File.Exists(htmlFile) ? string.Empty : File.ReadAllText(htmlFile); | ||||
|         if (html != htmlOld) | ||||
|             File.WriteAllText(htmlFile, html); | ||||
|         if (!fileRead.IsEAFHosted) | ||||
|             fileInfoCollection.Add(new(htmlFile)); | ||||
|         string json = JsonSerializer.Serialize(records, new JsonSerializerOptions() { WriteIndented = true }); | ||||
|         string jsonFile = Path.Combine(destinationDirectory, $"{fileName}.json"); | ||||
|         string jsonOld = !File.Exists(jsonFile) ? string.Empty : File.ReadAllText(jsonFile); | ||||
|         if (json != jsonOld) | ||||
|             File.WriteAllText(jsonFile, json); | ||||
|         if (!fileRead.IsEAFHosted) | ||||
|             fileInfoCollection.Add(new(jsonFile)); | ||||
|     } | ||||
|  | ||||
|     private void WriteFiles(IFileRead fileRead, Logistics logistics, string url, ReadOnlyCollection<string> workItemTypes, string destinationDirectory, List<FileInfo> fileInfoCollection) | ||||
| @ -84,12 +93,12 @@ public class ProcessData : IProcessData | ||||
|         ReadOnlyCollection<Record> results; | ||||
|         ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations); | ||||
|         ReadOnlyCollection<Record> records = new(keyValuePairs.Values.ToArray()); | ||||
|         ReadOnlyCollection<string> userStoryWorkItemTypes = new(new string[] { "User Story" }); | ||||
|         ReadOnlyCollection<string> bugFeatureWorkItemTypes = new(new string[] { "Bug", "Feature" }); | ||||
|         ReadOnlyCollection<string> bugUserStoryWorkItemTypes = new(new string[] { "Bug", "User Story" }); | ||||
|         ReadOnlyCollection<string> bugUserStoryTaskWorkItemTypes = new(new string[] { "Bug", "User Story", "Task" }); | ||||
|         messages.AddRange(WriteFile(fileRead, destinationDirectory, fileInfoCollection, records, "records")); | ||||
|         messages.AddRange(WriteWithPartentsFile(fileRead, destinationDirectory, fileInfoCollection, records, bugFeatureWorkItemTypes, "bugs-features-with-parents")); | ||||
|         messages.AddRange(WriteWithPartentsFile(fileRead, destinationDirectory, fileInfoCollection, records, bugUserStoryWorkItemTypes, "bugs-user-stories-with-parents")); | ||||
|         messages.AddRange(WriteWithParentsFile(fileRead, destinationDirectory, fileInfoCollection, records, bugFeatureWorkItemTypes, "bugs-features-with-parents")); | ||||
|         messages.AddRange(WriteWithParentsFile(fileRead, destinationDirectory, fileInfoCollection, records, bugUserStoryWorkItemTypes, "bugs-user-stories-with-parents")); | ||||
|         foreach (string workItemType in workItemTypes) | ||||
|         { | ||||
|             lines.Clear(); | ||||
| @ -102,87 +111,17 @@ public class ProcessData : IProcessData | ||||
|         } | ||||
|         { | ||||
|             lines.Clear(); | ||||
|             string workItemType = "Feature"; | ||||
|             lines.Add($"# {nameof(FeatureCheckIterationPath122508)}"); | ||||
|             string workItemType = "User Story"; | ||||
|             lines.Add($"# Total User Story Points by Site - Iteration - Assigned To (Initials)"); | ||||
|             lines.Add(string.Empty); | ||||
|             results = FeatureCheckIterationPath122508(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType); | ||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, "check-122508"); | ||||
|             _Details.Add(results); | ||||
|         } | ||||
|         { | ||||
|             lines.Clear(); | ||||
|             string workItemType = "Feature"; | ||||
|             lines.Add($"# {nameof(FeatureCheckTag122514)}"); | ||||
|             lines.Add(string.Empty); | ||||
|             results = FeatureCheckTag122514(url, lines, bugUserStoryWorkItemTypes, keyValuePairs, workItemType); | ||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, "check-122514"); | ||||
|             _Details.Add(results); | ||||
|         } | ||||
|         { | ||||
|             lines.Clear(); | ||||
|             string workItemType = "Feature"; | ||||
|             lines.Add($"# {nameof(FeatureCheckPriority126169)}"); | ||||
|             lines.Add(string.Empty); | ||||
|             results = FeatureCheckPriority126169(url, lines, bugUserStoryWorkItemTypes, keyValuePairs, workItemType); | ||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, "check-126169"); | ||||
|             _Details.Add(results); | ||||
|         } | ||||
|         { | ||||
|             lines.Clear(); | ||||
|             string workItemType = "Feature"; | ||||
|             lines.Add($"# {nameof(FeatureCheckState123066)}"); | ||||
|             lines.Add(string.Empty); | ||||
|             results = FeatureCheckState123066(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType); | ||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, "check-123066"); | ||||
|             _Details.Add(results); | ||||
|         } | ||||
|         { | ||||
|             lines.Clear(); | ||||
|             string workItemType = "Feature"; | ||||
|             lines.Add($"# {nameof(FeatureCheckState123067)}"); | ||||
|             lines.Add(string.Empty); | ||||
|             results = FeatureCheckState123067(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType); | ||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, "check-123067"); | ||||
|             _Details.Add(results); | ||||
|         } | ||||
|         { | ||||
|             lines.Clear(); | ||||
|             string workItemType = "Feature"; | ||||
|             lines.Add($"# {nameof(FeatureCheckStart122517)}"); | ||||
|             lines.Add(string.Empty); | ||||
|             results = FeatureCheckStart122517(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType); | ||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, "check-122517"); | ||||
|             results = UserStoryCheckIterationPath228385(url, lines, userStoryWorkItemTypes, keyValuePairs, workItemType); | ||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, $"{workItemType} check 228385"); | ||||
|             _Details.Add(results); | ||||
|         } | ||||
|         if (messages.Count > 0) | ||||
|             throw new Exception($"{messages.Count}{Environment.NewLine}{string.Join(Environment.NewLine, messages)}"); | ||||
|     } | ||||
|  | ||||
|     private static void WriteFiles(IFileRead fileRead, string destinationDirectory, List<FileInfo> fileInfoCollection, ReadOnlyCollection<string> lines, ReadOnlyCollection<Record> records, string fileName) | ||||
|     { | ||||
|         string markdown = string.Join(Environment.NewLine, lines); | ||||
|         string markdownFile = Path.Combine(destinationDirectory, $"{fileName}.md"); | ||||
|         string markdownOld = !File.Exists(markdownFile) ? string.Empty : File.ReadAllText(markdownFile); | ||||
|         if (markdown != markdownOld) | ||||
|             File.WriteAllText(markdownFile, markdown); | ||||
|         if (!fileRead.IsEAFHosted) | ||||
|             fileInfoCollection.Add(new(markdownFile)); | ||||
|         string html = CommonMark.CommonMarkConverter.Convert(markdown).Replace("<a href", "<a target='_blank' href"); | ||||
|         string htmlFile = Path.Combine(destinationDirectory, $"{fileName}.html"); | ||||
|         string htmlOld = !File.Exists(htmlFile) ? string.Empty : File.ReadAllText(htmlFile); | ||||
|         if (html != htmlOld) | ||||
|             File.WriteAllText(htmlFile, html); | ||||
|         if (!fileRead.IsEAFHosted) | ||||
|             fileInfoCollection.Add(new(htmlFile)); | ||||
|         string json = JsonSerializer.Serialize(records, new JsonSerializerOptions() { WriteIndented = true }); | ||||
|         string jsonFile = Path.Combine(destinationDirectory, $"{fileName}.json"); | ||||
|         string jsonOld = !File.Exists(jsonFile) ? string.Empty : File.ReadAllText(jsonFile); | ||||
|         if (json != jsonOld) | ||||
|             File.WriteAllText(jsonFile, json); | ||||
|         if (!fileRead.IsEAFHosted) | ||||
|             fileInfoCollection.Add(new(jsonFile)); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyDictionary<int, Record> GetWorkItems(IEnumerable<WorkItem> workItems, bool keepRelations) | ||||
|     { | ||||
|         ReadOnlyDictionary<int, Record> results; | ||||
| @ -193,6 +132,75 @@ public class ProcessData : IProcessData | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyDictionary<int, Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, bool keepRelations) | ||||
|     { | ||||
|         Dictionary<int, Record> results = new(); | ||||
|         Record record; | ||||
|         List<bool> nests = new(); | ||||
|         WorkItem? parentWorkItem; | ||||
|         ReadOnlyCollection<Record> childRecords; | ||||
|         ReadOnlyCollection<Record> relatedRecords; | ||||
|         ReadOnlyCollection<Record> successorRecords; | ||||
|         foreach (KeyValuePair<int, WorkItem> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             nests.Clear(); | ||||
|             if (keyValuePair.Value.Parent is null) | ||||
|                 parentWorkItem = null; | ||||
|             else | ||||
|                 _ = keyValuePairs.TryGetValue(keyValuePair.Value.Parent.Value, out parentWorkItem); | ||||
|             try | ||||
|             { | ||||
|                 childRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Child", nests, keepRelations); // Forward | ||||
|                 relatedRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Related", nests, keepRelations); // Related | ||||
|                 successorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Successor", nests, keepRelations); // Forward | ||||
|                 // predecessorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Predecessor", nests, keepRelations); // Reverse | ||||
|                 record = Record.Get(keyValuePair.Value, parentWorkItem, childRecords, relatedRecords, successorRecords, keepRelations); | ||||
|             } | ||||
|             catch (Exception) | ||||
|             { | ||||
|                 Dictionary<string, string>? tag = null; | ||||
|                 record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>(), tag); | ||||
|             } | ||||
|             results.Add(keyValuePair.Key, record); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<string> WriteFile(IFileRead fileRead, string destinationDirectory, List<FileInfo> fileInfoCollection, ReadOnlyCollection<Record> records, string fileName) | ||||
|     { | ||||
|         List<string> results = new(); | ||||
|         string? json = GetJson(records, results); | ||||
|         string jsonFile = Path.Combine(destinationDirectory, $"{fileName}.json"); | ||||
|         string jsonOld = !File.Exists(jsonFile) ? string.Empty : File.ReadAllText(jsonFile); | ||||
|         if (!string.IsNullOrEmpty(json) && json != jsonOld) | ||||
|             File.WriteAllText(jsonFile, json); | ||||
|         if (!fileRead.IsEAFHosted) | ||||
|             fileInfoCollection.Add(new(jsonFile)); | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<string> WriteWithParentsFile(IFileRead fileRead, string destinationDirectory, List<FileInfo> fileInfoCollection, ReadOnlyCollection<Record> records, ReadOnlyCollection<string> workItemTypes, string fileName) | ||||
|     { | ||||
|         List<string> results = new(); | ||||
|         Record record; | ||||
|         List<Record> filtered = new(); | ||||
|         foreach (Record r in records) | ||||
|         { | ||||
|             if (r.WorkItem.State == "Removed" || !workItemTypes.Contains(r.WorkItem.WorkItemType)) | ||||
|                 continue; | ||||
|             record = new(r.WorkItem, r.Parent, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>(), r.Tag); | ||||
|             filtered.Add(record); | ||||
|         } | ||||
|         string? json = GetJson(filtered, results); | ||||
|         string jsonFile = Path.Combine(destinationDirectory, $"{fileName}.json"); | ||||
|         string jsonOld = !File.Exists(jsonFile) ? string.Empty : File.ReadAllText(jsonFile); | ||||
|         if (!string.IsNullOrEmpty(json) && json != jsonOld) | ||||
|             File.WriteAllText(jsonFile, json); | ||||
|         if (!fileRead.IsEAFHosted) | ||||
|             fileInfoCollection.Add(new(jsonFile)); | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static string? GetJson(IEnumerable<Record> records, List<string> results) | ||||
|     { | ||||
|         string? result; | ||||
| @ -212,39 +220,22 @@ public class ProcessData : IProcessData | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<string> WriteFile(IFileRead fileRead, string destinationDirectory, List<FileInfo> fileInfoCollection, ReadOnlyCollection<Record> records, string fileName) | ||||
|     private static void AppendLines(List<char> spaces, List<string> lines, Record record, bool condensed, bool sprintOnly) | ||||
|     { | ||||
|         List<string> results = new(); | ||||
|         string? json = GetJson(records, results); | ||||
|         string jsonFile = Path.Combine(destinationDirectory, $"{fileName}.json"); | ||||
|         string jsonOld = !File.Exists(jsonFile) ? string.Empty : File.ReadAllText(jsonFile); | ||||
|         if (!string.IsNullOrEmpty(json) && json != jsonOld) | ||||
|             File.WriteAllText(jsonFile, json); | ||||
|         if (!fileRead.IsEAFHosted) | ||||
|             fileInfoCollection.Add(new(jsonFile)); | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<string> WriteWithPartentsFile(IFileRead fileRead, string destinationDirectory, List<FileInfo> fileInfoCollection, ReadOnlyCollection<Record> records, ReadOnlyCollection<string> workItemTypes, string fileName) | ||||
|     { | ||||
|         List<string> results = new(); | ||||
|         List<Record> filtered = new(); | ||||
|         Record record; | ||||
|         foreach (Record r in records) | ||||
|         string line; | ||||
|         spaces.Add('\t'); | ||||
|         WorkItem workItem; | ||||
|         if (record.Children is not null) | ||||
|         { | ||||
|             if (r.WorkItem.State == "Removed" || !workItemTypes.Contains(r.WorkItem.WorkItemType)) | ||||
|                 continue; | ||||
|             record = new(r.WorkItem, r.Parent, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>()); | ||||
|             filtered.Add(record); | ||||
|             foreach (Record child in record.Children) | ||||
|             { | ||||
|                 workItem = child.WorkItem; | ||||
|                 line = GetLine(spaces, workItem, child, condensed, sprintOnly).TrimEnd(); | ||||
|                 lines.Add(line); | ||||
|                 AppendLines(spaces, lines, child, condensed, sprintOnly); | ||||
|             } | ||||
|         } | ||||
|         string? json = GetJson(filtered, results); | ||||
|         string jsonFile = Path.Combine(destinationDirectory, $"{fileName}.json"); | ||||
|         string jsonOld = !File.Exists(jsonFile) ? string.Empty : File.ReadAllText(jsonFile); | ||||
|         if (!string.IsNullOrEmpty(json) && json != jsonOld) | ||||
|             File.WriteAllText(jsonFile, json); | ||||
|         if (!fileRead.IsEAFHosted) | ||||
|             fileInfoCollection.Add(new(jsonFile)); | ||||
|         return new(results); | ||||
|         spaces.RemoveAt(0); | ||||
|     } | ||||
|  | ||||
|     private static void AppendLines(string url, List<char> spaces, List<string> lines, ReadOnlyCollection<Record> records, string workItemType) | ||||
| @ -295,57 +286,6 @@ public class ProcessData : IProcessData | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static void AppendLines(List<char> spaces, List<string> lines, Record record, bool condensed, bool sprintOnly) | ||||
|     { | ||||
|         string line; | ||||
|         spaces.Add('\t'); | ||||
|         WorkItem workItem; | ||||
|         if (record.Children is not null) | ||||
|         { | ||||
|             foreach (Record child in record.Children) | ||||
|             { | ||||
|                 workItem = child.WorkItem; | ||||
|                 line = GetLine(spaces, workItem, child, condensed, sprintOnly).TrimEnd(); | ||||
|                 lines.Add(line); | ||||
|                 AppendLines(spaces, lines, child, condensed, sprintOnly); | ||||
|             } | ||||
|         } | ||||
|         spaces.RemoveAt(0); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyDictionary<int, Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, bool keepRelations) | ||||
|     { | ||||
|         Dictionary<int, Record> results = new(); | ||||
|         Record record; | ||||
|         List<bool> nests = new(); | ||||
|         WorkItem? parentWorkItem; | ||||
|         ReadOnlyCollection<Record> childRecords; | ||||
|         ReadOnlyCollection<Record> relatedRecords; | ||||
|         ReadOnlyCollection<Record> successorRecords; | ||||
|         foreach (KeyValuePair<int, WorkItem> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             nests.Clear(); | ||||
|             if (keyValuePair.Value.Parent is null) | ||||
|                 parentWorkItem = null; | ||||
|             else | ||||
|                 _ = keyValuePairs.TryGetValue(keyValuePair.Value.Parent.Value, out parentWorkItem); | ||||
|             try | ||||
|             { | ||||
|                 childRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Child", nests, keepRelations); // Forward | ||||
|                 relatedRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Related", nests, keepRelations); // Related | ||||
|                 successorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Successor", nests, keepRelations); // Forward | ||||
|                 // predecessorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Predecessor", nests, keepRelations); // Reverse | ||||
|                 record = Record.Get(keyValuePair.Value, parentWorkItem, childRecords, relatedRecords, successorRecords, keepRelations); | ||||
|             } | ||||
|             catch (Exception) | ||||
|             { | ||||
|                 record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>()); | ||||
|             } | ||||
|             results.Add(keyValuePair.Key, record); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static string GetLine(List<char> spaces, WorkItem workItem, Record record, bool condensed, bool sprintOnly) | ||||
|     { | ||||
|         string result; | ||||
| @ -356,406 +296,119 @@ public class ProcessData : IProcessData | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     private static string GetClosed(WorkItem workItem) => | ||||
|         workItem.State != "Closed" ? "[ ]" : "[x]"; | ||||
|  | ||||
|     private static void FilterChildren(ReadOnlyCollection<string> workItemTypes, Record record, List<Record> results) | ||||
|     { | ||||
|         if (record.Children is not null) | ||||
|         { | ||||
|             foreach (Record r in record.Children) | ||||
|             { | ||||
|                 if (!workItemTypes.Contains(r.WorkItem.WorkItemType)) | ||||
|                     continue; | ||||
|                 results.Add(r); | ||||
|                 FilterChildren(workItemTypes, r, results); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> FilterChildren(ReadOnlyCollection<string> workItemTypes, Record record) | ||||
|     private static ReadOnlyCollection<Record> UserStoryCheckIterationPath228385(string url, List<string> lines, ReadOnlyCollection<string> _, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         FilterChildren(workItemTypes, record, results); | ||||
|         long totalStoryPoints; | ||||
|         List<long> collection = new(); | ||||
|         ReadOnlyDictionary<string, List<Record>> records = GetWorkItemsMatching228385(keyValuePairs, workItemType); | ||||
|         lines.Add("<table border='1'>"); | ||||
|         lines.Add($"<tr><td>{string.Join("</td><td>", records.Select(l => l.Key))}</td></tr>"); | ||||
|         foreach (KeyValuePair<string, List<Record>> keyValuePair in records) | ||||
|         { | ||||
|             totalStoryPoints = 0; | ||||
|             foreach (Record record in keyValuePair.Value) | ||||
|             { | ||||
|                 if (record.WorkItem.StoryPoints is null) | ||||
|                     continue; | ||||
|                 totalStoryPoints += record.WorkItem.StoryPoints.Value; | ||||
|             } | ||||
|             collection.Add(totalStoryPoints); | ||||
|         } | ||||
|         lines.Add($"<tr><td>{string.Join("</td><td>", collection)}</td></tr>"); | ||||
|         lines.Add("</table>"); | ||||
|         lines.Add(string.Empty); | ||||
|         foreach (KeyValuePair<string, List<Record>> keyValuePair in records) | ||||
|         { | ||||
|             totalStoryPoints = 0; | ||||
|             foreach (Record record in keyValuePair.Value) | ||||
|             { | ||||
|                 if (record.WorkItem.StoryPoints is null) | ||||
|                     continue; | ||||
|                 totalStoryPoints += record.WorkItem.StoryPoints.Value; | ||||
|             } | ||||
|             lines.Add(string.Empty); | ||||
|             lines.Add($"## {keyValuePair.Key} => {totalStoryPoints}"); | ||||
|             lines.Add(string.Empty); | ||||
|             foreach (Record record in keyValuePair.Value) | ||||
|                 lines.Add($"- [ ] [{record.WorkItem.Id}]({url}{record.WorkItem.Id}) - {record.WorkItem.Title}"); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static int GetState(WorkItem workItem) => | ||||
|         workItem.State switch | ||||
|         { | ||||
|             "New" => 1, | ||||
|             "Active" => 2, | ||||
|             "Resolved" => 3, | ||||
|             "Closed" => 4, | ||||
|             "Removed" => 5, | ||||
|             _ => 8 | ||||
|         }; | ||||
|  | ||||
|     private static string? GetMaxIterationPath122508(ReadOnlyCollection<Record> records) | ||||
|     private static ReadOnlyDictionary<string, List<Record>> GetWorkItemsMatching228385(ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||
|     { | ||||
|         string? result; | ||||
|         List<string> results = new(); | ||||
|         ReadOnlyDictionary<string, List<Record>> results; | ||||
|         Record record; | ||||
|         List<Record> records = new(); | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             record = keyValuePair.Value; | ||||
|             if (record.WorkItem.State is "Removed" or "Closed") | ||||
|                 continue; | ||||
|             if (!record.WorkItem.IterationPath.Contains('\\')) | ||||
|                 continue; | ||||
|             if (record.WorkItem.StoryPoints is null) | ||||
|                 continue; | ||||
|             if (record.WorkItem.WorkItemType != workItemType) | ||||
|                 continue; | ||||
|             records.Add(record); | ||||
|         } | ||||
|         Record[] sorted = (from l in records orderby l.WorkItem.AreaPath, l.WorkItem.IterationPath, l.WorkItem.AssignedTo select l).ToArray(); | ||||
|         results = GetWorkItemsMatching228385(new(sorted)); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyDictionary<string, List<Record>> GetWorkItemsMatching228385(ReadOnlyCollection<Record> records) | ||||
|     { | ||||
|         Dictionary<string, List<Record>> results = new(); | ||||
|         string key; | ||||
|         string[] segments; | ||||
|         List<Record>? collection; | ||||
|         foreach (Record record in records) | ||||
|         { | ||||
|             if (results.Contains(record.WorkItem.IterationPath)) | ||||
|                 continue; | ||||
|             results.Add(record.WorkItem.IterationPath); | ||||
|         } | ||||
|         result = results.Count == 0 ? null : results.Max(); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> FeatureCheckIterationPath122508(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         Record record; | ||||
|         string? maxIterationPath; | ||||
|         List<string> collection = new(); | ||||
|         ReadOnlyCollection<Record> records; | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             record = keyValuePair.Value; | ||||
|             if (record.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             if (record.WorkItem.WorkItemType != workItemType) | ||||
|                 continue; | ||||
|             collection.Clear(); | ||||
|             if (record.Children is null || record.Children.Length == 0) | ||||
|                 continue; | ||||
|             records = FilterChildren(workItemTypes, record); | ||||
|             maxIterationPath = GetMaxIterationPath122508(records); | ||||
|             if (string.IsNullOrEmpty(maxIterationPath) || record.WorkItem.IterationPath == maxIterationPath) | ||||
|                 continue; | ||||
|             collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}"); | ||||
|             collection.Add(string.Empty); | ||||
|             collection.Add($"- [ ] [{record.WorkItem.Id}]({url}{record.WorkItem.Id}) => {record.WorkItem.IterationPath} != {maxIterationPath}"); | ||||
|             collection.Add(string.Empty); | ||||
|             lines.AddRange(collection); | ||||
|             results.Add(Record.GetWithoutNesting(record, $"IterationPath:<a target='_blank' href='{url}{record.WorkItem.Id}'>{record.WorkItem.Id}</a>;{record.WorkItem.IterationPath} != {maxIterationPath}")); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> GetWorkItemsNotMatching122514(Record record, ReadOnlyCollection<Record> records) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         string[] segments; | ||||
|         string[] parentTags = record.WorkItem.Tags.Split(';').Select(l => l.Trim()).ToArray(); | ||||
|         foreach (Record r in records) | ||||
|         { | ||||
|             segments = string.IsNullOrEmpty(r.WorkItem.Tags) ? Array.Empty<string>() : r.WorkItem.Tags.Split(';').Select(l => l.Trim()).ToArray(); | ||||
|             if (segments.Length > 0 && parentTags.Any(l => segments.Contains(l))) | ||||
|                 continue; | ||||
|             results.Add(r); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> FeatureCheckTag122514(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         Record record; | ||||
|         List<string> collection = new(); | ||||
|         List<string> violations = new(); | ||||
|         ReadOnlyCollection<Record> records; | ||||
|         ReadOnlyCollection<Record> recordsNotMatching; | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             record = keyValuePair.Value; | ||||
|             if (record.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             if (record.WorkItem.WorkItemType != workItemType) | ||||
|                 continue; | ||||
|             collection.Clear(); | ||||
|             violations.Clear(); | ||||
|             if (record.Children is null || record.Children.Length == 0) | ||||
|                 continue; | ||||
|             if (string.IsNullOrEmpty(record.WorkItem.Tags)) | ||||
|                 recordsNotMatching = new(new Record[] { record }); | ||||
|             else | ||||
|             key = $"{record.WorkItem.AreaPath.Split('\\').Last()}-{record.WorkItem.IterationPath.Split('\\').Last().Split(' ').Last()}"; | ||||
|             if (!results.TryGetValue(key, out collection)) | ||||
|             { | ||||
|                 records = FilterChildren(workItemTypes, record); | ||||
|                 recordsNotMatching = GetWorkItemsNotMatching122514(record, records); | ||||
|                 if (!string.IsNullOrEmpty(record.WorkItem.Tags) && recordsNotMatching.Count == 0) | ||||
|                     continue; | ||||
|                 results.Add(key, new()); | ||||
|                 if (!results.TryGetValue(key, out collection)) | ||||
|                     throw new Exception(); | ||||
|             } | ||||
|             collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}"); | ||||
|             collection.Add(string.Empty); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 collection.Add($"- [ ] [{r.WorkItem}]({url}{r.WorkItem}) {nameof(record.WorkItem.Tags)} != {record.WorkItem.Tags}"); | ||||
|             collection.Add(string.Empty); | ||||
|             lines.AddRange(collection); | ||||
|             violations.Add($"Tag:{record.WorkItem.Tags};"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.Tags};"); | ||||
|             results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations))); | ||||
|             collection.Add(record); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> GetWorkItemsNotMatching126169(Record record, ReadOnlyCollection<Record> records) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         foreach (Record r in records) | ||||
|         foreach (Record record in records) | ||||
|         { | ||||
|             if (record.WorkItem.Priority is null) | ||||
|             if (string.IsNullOrEmpty(record.WorkItem.AssignedTo)) | ||||
|                 continue; | ||||
|             segments = record.WorkItem.AssignedTo.Split(' '); | ||||
|             if (segments.Length < 3) | ||||
|                 continue; | ||||
|             key = $"{record.WorkItem.IterationPath.Split('\\').Last().Split(' ').Last()}-{segments[0][0]}{segments[1][0]}"; | ||||
|             if (!results.TryGetValue(key, out collection)) | ||||
|             { | ||||
|                 results.Add(record); | ||||
|                 break; | ||||
|                 results.Add(key, new()); | ||||
|                 if (!results.TryGetValue(key, out collection)) | ||||
|                     throw new Exception(); | ||||
|             } | ||||
|             if (r.WorkItem.Priority == record.WorkItem.Priority.Value) | ||||
|                 continue; | ||||
|             results.Add(r); | ||||
|             collection.Add(record); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> FeatureCheckPriority126169(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||
|     internal static List<Description> GetDescriptions(JsonElement[] jsonElements) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         Record record; | ||||
|         List<string> collection = new(); | ||||
|         List<string> violations = new(); | ||||
|         ReadOnlyCollection<Record> records; | ||||
|         ReadOnlyCollection<Record> recordsNotMatching; | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         List<Description> results = new(); | ||||
|         Description? description; | ||||
|         foreach (JsonElement jsonElement in jsonElements) | ||||
|         { | ||||
|             record = keyValuePair.Value; | ||||
|             if (record.WorkItem.State is "Removed") | ||||
|             if (jsonElement.ValueKind != JsonValueKind.Object) | ||||
|                 throw new Exception(); | ||||
|             description = JsonSerializer.Deserialize(jsonElement.ToString(), SharedDescriptionSourceGenerationContext.Default.Description); | ||||
|             if (description is null) | ||||
|                 continue; | ||||
|             if (record.WorkItem.WorkItemType != workItemType) | ||||
|                 continue; | ||||
|             collection.Clear(); | ||||
|             violations.Clear(); | ||||
|             if (record.Children is null || record.Children.Length == 0) | ||||
|                 continue; | ||||
|             records = FilterChildren(workItemTypes, record); | ||||
|             recordsNotMatching = GetWorkItemsNotMatching126169(record, records); | ||||
|             if (recordsNotMatching.Count == 0) | ||||
|                 continue; | ||||
|             collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}"); | ||||
|             collection.Add(string.Empty); | ||||
|             collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.Priority)} != {record.WorkItem.Priority}"); | ||||
|             collection.Add(string.Empty); | ||||
|             lines.AddRange(collection); | ||||
|             violations.Add($"Priority:{record.WorkItem.Priority};"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.Priority};"); | ||||
|             results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations))); | ||||
|             results.Add(description); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> GetWorkItemsNotMatching123066(Record record, ReadOnlyCollection<Record> records) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         int check; | ||||
|         int state = GetState(record.WorkItem); | ||||
|         List<KeyValuePair<int, Record>> collection = new(); | ||||
|         foreach (Record r in records) | ||||
|         { | ||||
|             if (r.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             check = GetState(r.WorkItem); | ||||
|             if (check == state) | ||||
|                 continue; | ||||
|             collection.Add(new(check, r)); | ||||
|         } | ||||
|         if (collection.Count > 0) | ||||
|         { | ||||
|             KeyValuePair<int, Record>[] notNewState = (from l in collection where l.Value.WorkItem.State != "New" select l).ToArray(); | ||||
|             if (notNewState.Length == 0 && record.WorkItem.State is "New" or "Active") | ||||
|                 collection.Clear(); | ||||
|             else if (notNewState.Length > 0) | ||||
|             { | ||||
|                 int minimum = notNewState.Min(l => l.Key); | ||||
|                 if (minimum == state) | ||||
|                     collection.Clear(); | ||||
|                 else if (minimum == 1 && record.WorkItem.State == "New") | ||||
|                     collection.Clear(); | ||||
|                 else if (notNewState.Length > 0 && record.WorkItem.State == "Active") | ||||
|                     collection.Clear(); | ||||
|             } | ||||
|         } | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in collection.OrderByDescending(l => l.Key)) | ||||
|             results.Add(keyValuePair.Value); | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> GetWorkItemsNotMatching123067(Record record, ReadOnlyCollection<Record> records) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         int check; | ||||
|         int state = GetState(record.WorkItem); | ||||
|         List<KeyValuePair<int, Record>> collection = new(); | ||||
|         foreach (Record r in records) | ||||
|         { | ||||
|             if (r.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             check = GetState(r.WorkItem); | ||||
|             if (check == state) | ||||
|                 continue; | ||||
|             collection.Add(new(check, r)); | ||||
|         } | ||||
|         if (collection.Count > 0) | ||||
|         { | ||||
|             KeyValuePair<int, Record>[] notNewState = (from l in collection where l.Value.WorkItem.State != "New" select l).ToArray(); | ||||
|             if (notNewState.Length == 0 && record.WorkItem.State is "New" or "Active") | ||||
|                 collection.Clear(); | ||||
|             else if (notNewState.Length > 0) | ||||
|             { | ||||
|                 int minimum = notNewState.Min(l => l.Key); | ||||
|                 if (minimum == state) | ||||
|                     collection.Clear(); | ||||
|                 else if (minimum == 1 && record.WorkItem.State == "New") | ||||
|                     collection.Clear(); | ||||
|                 else if (notNewState.Length > 0 && record.WorkItem.State == "Active") | ||||
|                     collection.Clear(); | ||||
|             } | ||||
|         } | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in collection.OrderByDescending(l => l.Key)) | ||||
|             results.Add(keyValuePair.Value); | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> GetWorkItemsNotMatching122517(Record record, ReadOnlyCollection<Record> records) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         if (record.WorkItem.StartDate is null) | ||||
|             throw new Exception(); | ||||
|         DateTime dateTime = record.WorkItem.StartDate.Value; | ||||
|         List<KeyValuePair<long, Record>> collection = new(); | ||||
|         foreach (Record r in records) | ||||
|         { | ||||
|             if (r.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             if (r.WorkItem.ActivatedDate is null) | ||||
|                 continue; | ||||
|             if (dateTime >= r.WorkItem.ActivatedDate.Value) | ||||
|                 continue; | ||||
|             collection.Add(new(r.WorkItem.ActivatedDate.Value.Ticks, r)); | ||||
|         } | ||||
|         foreach (KeyValuePair<long, Record> keyValuePair in collection.OrderBy(l => l.Key)) | ||||
|             results.Add(keyValuePair.Value); | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> FeatureCheckState123066(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         Record record; | ||||
|         List<string> collection = new(); | ||||
|         List<string> violations = new(); | ||||
|         ReadOnlyCollection<Record> records; | ||||
|         ReadOnlyCollection<Record> recordsNotMatching; | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             record = keyValuePair.Value; | ||||
|             if (record.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             if (record.WorkItem.WorkItemType != workItemType) | ||||
|                 continue; | ||||
|             collection.Clear(); | ||||
|             violations.Clear(); | ||||
|             if (record.Children is null || record.Children.Length == 0) | ||||
|                 continue; | ||||
|             records = FilterChildren(workItemTypes, record); | ||||
|             recordsNotMatching = GetWorkItemsNotMatching123066(record, records); | ||||
|             if (recordsNotMatching.Count == 0) | ||||
|                 continue; | ||||
|             collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}"); | ||||
|             collection.Add(string.Empty); | ||||
|             collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.State)} != {record.WorkItem.State}"); | ||||
|             collection.Add(string.Empty); | ||||
|             lines.AddRange(collection); | ||||
|             violations.Add($"State:{record.WorkItem.State};"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.State};"); | ||||
|             results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations))); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> FeatureCheckState123067(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         Record record; | ||||
|         List<string> collection = new(); | ||||
|         List<string> violations = new(); | ||||
|         ReadOnlyCollection<Record> records; | ||||
|         ReadOnlyCollection<Record> recordsNotMatching; | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             record = keyValuePair.Value; | ||||
|             if (record.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             if (record.WorkItem.WorkItemType != workItemType) | ||||
|                 continue; | ||||
|             collection.Clear(); | ||||
|             violations.Clear(); | ||||
|             if (record.Children is null || record.Children.Length == 0) | ||||
|                 continue; | ||||
|             records = FilterChildren(workItemTypes, record); | ||||
|             recordsNotMatching = GetWorkItemsNotMatching123067(record, records); | ||||
|             if (recordsNotMatching.Count == 0) | ||||
|                 continue; | ||||
|             collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}"); | ||||
|             collection.Add(string.Empty); | ||||
|             collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.State)} != {record.WorkItem.State}"); | ||||
|             collection.Add(string.Empty); | ||||
|             lines.AddRange(collection); | ||||
|             violations.Add($"State:{record.WorkItem.State};"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.State};"); | ||||
|             results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations))); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> FeatureCheckStart122517(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         Record record; | ||||
|         List<string> collection = new(); | ||||
|         List<string> violations = new(); | ||||
|         ReadOnlyCollection<Record> records; | ||||
|         ReadOnlyCollection<Record> recordsNotMatching; | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             record = keyValuePair.Value; | ||||
|             if (record.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             if (record.WorkItem.WorkItemType != workItemType) | ||||
|                 continue; | ||||
|             collection.Clear(); | ||||
|             violations.Clear(); | ||||
|             if (record.Children is null || record.Children.Length == 0) | ||||
|                 continue; | ||||
|             if (record.WorkItem.StartDate is null) | ||||
|                 continue; | ||||
|             records = FilterChildren(workItemTypes, record); | ||||
|             recordsNotMatching = GetWorkItemsNotMatching122517(record, records); | ||||
|             if (recordsNotMatching.Count == 0) | ||||
|                 continue; | ||||
|             collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}"); | ||||
|             collection.Add(string.Empty); | ||||
|             collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.ActivatedDate)} != {record.WorkItem.ActivatedDate}"); | ||||
|             collection.Add(string.Empty); | ||||
|             lines.AddRange(collection); | ||||
|             violations.Add($"StartDate:{record.WorkItem.StartDate};"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.ActivatedDate};"); | ||||
|             results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations))); | ||||
|         } | ||||
|         return new(results); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -1,265 +0,0 @@ | ||||
| using Adaptation.Eaf.Management.ConfigurationData.CellAutomation; | ||||
| using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration; | ||||
| using Adaptation.Shared; | ||||
| using Adaptation.Shared.Duplicator; | ||||
| using Adaptation.Shared.Methods; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Text; | ||||
| using System.Text.Json; | ||||
| using System.Threading; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.MoveMatchingFiles; | ||||
|  | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
|         _NullData = string.Empty; | ||||
|         _Logistics = new(this); | ||||
|         if (_FileParameter is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (_ModelObjectParameterDefinitions is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (!_IsDuplicator) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|     } | ||||
|  | ||||
|     void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) | ||||
|     { | ||||
|         bool isErrorFile = exception is not null; | ||||
|         if (!isErrorFile && !string.IsNullOrEmpty(_Logistics.ReportFullPath)) | ||||
|         { | ||||
|             FileInfo fileInfo = new(_Logistics.ReportFullPath); | ||||
|             if (fileInfo.Exists && fileInfo.LastWriteTime < fileInfo.CreationTime) | ||||
|                 File.SetLastWriteTime(_Logistics.ReportFullPath, fileInfo.CreationTime); | ||||
|         } | ||||
|         Move(extractResults); | ||||
|     } | ||||
|  | ||||
|     void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null); | ||||
|  | ||||
|     string IFileRead.GetEventDescription() | ||||
|     { | ||||
|         string result = _Description.GetEventDescription(); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     List<string> IFileRead.GetHeaderNames() | ||||
|     { | ||||
|         List<string> results = _Description.GetHeaderNames(); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     string[] IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, string to, string from, string resolvedFileLocation, Exception exception) | ||||
|     { | ||||
|         string[] results = Move(extractResults, to, from, resolvedFileLocation, exception); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     JsonProperty[] IFileRead.GetDefault() | ||||
|     { | ||||
|         JsonProperty[] results = _Description.GetDefault(this, _Logistics); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Dictionary<string, string> IFileRead.GetDisplayNamesJsonElement() | ||||
|     { | ||||
|         Dictionary<string, string> results = _Description.GetDisplayNamesJsonElement(this); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     List<IDescription> IFileRead.GetDescriptions(IFileRead fileRead, List<Test> tests, IProcessData processData) | ||||
|     { | ||||
|         List<IDescription> results = _Description.GetDescriptions(fileRead, _Logistics, tests, processData); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.GetExtractResult(string reportFullPath, string eventName) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         if (string.IsNullOrEmpty(eventName)) | ||||
|             throw new Exception(); | ||||
|         _ReportFullPath = reportFullPath; | ||||
|         DateTime dateTime = DateTime.Now; | ||||
|         results = GetExtractResult(reportFullPath, dateTime); | ||||
|         if (results.Item3 is null) | ||||
|             results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]"), results.Item4); | ||||
|         if (results.Item3.Length > 0 && _IsEAFHosted) | ||||
|             WritePDSF(this, results.Item3); | ||||
|         UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.ReExtract() | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         List<string> headerNames = _Description.GetHeaderNames(); | ||||
|         Dictionary<string, string> keyValuePairs = _Description.GetDisplayNamesJsonElement(this); | ||||
|         results = ReExtract(this, headerNames, keyValuePairs); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private static List<string> GetSearchDirectories(int numberLength, string parentDirectory) | ||||
|     { | ||||
|         List<string> results = new(); | ||||
|         string[] directories = Directory.GetDirectories(parentDirectory, "*", SearchOption.TopDirectoryOnly); | ||||
|         foreach (string directory in directories) | ||||
|         { | ||||
|             if (Path.GetFileName(directory).Length != numberLength) | ||||
|                 continue; | ||||
|             results.Add(directory); | ||||
|         } | ||||
|         results.Sort(); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private List<string> GetMatchingFiles(long ticks, string reportFullPath, List<string> searchDirectories) | ||||
|     { | ||||
|         List<string> results = new(); | ||||
|         string[] found; | ||||
|         string fileName = Path.GetFileName(reportFullPath); | ||||
|         foreach (string searchDirectory in searchDirectories) | ||||
|         { | ||||
|             for (int i = 0; i < int.MaxValue; i++) | ||||
|             { | ||||
|                 found = Directory.GetFiles(searchDirectory, fileName, SearchOption.AllDirectories); | ||||
|                 if (found.Length != 0) | ||||
|                 { | ||||
|                     results.AddRange(found); | ||||
|                     break; | ||||
|                 } | ||||
|                 if (new TimeSpan(DateTime.Now.Ticks - ticks).TotalSeconds > _BreakAfterSeconds) | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private static List<(string matchingFile, string checkFile)> GetCollection(int numberLength, string parentDirectory, List<string> matchingFiles) | ||||
|     { | ||||
|         List<(string matchingFile, string checkFile)> results = new(); | ||||
|         string checkFile; | ||||
|         int parentDirectoryLength = parentDirectory.Length; | ||||
|         foreach (string matchingFile in matchingFiles) | ||||
|         { | ||||
|             checkFile = $"{matchingFile[0]}{matchingFile.Substring(parentDirectoryLength + numberLength + 1)}"; | ||||
|             results.Add(new(matchingFile, checkFile)); | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private static List<(string, string, string, string, string)> GetCollection(List<(string matchingFile, string checkFile)> collection) | ||||
|     { | ||||
|         List<(string, string, string, string, string)> results = new(); | ||||
|         string errFile; | ||||
|         string checkDirectory; | ||||
|         string noWaitDirectory; | ||||
|         foreach ((string matchingFile, string checkFile) in collection) | ||||
|         { | ||||
|             errFile = string.Concat(checkFile, ".err"); | ||||
|             checkDirectory = Path.GetDirectoryName(checkFile); | ||||
|             if (!Directory.Exists(checkDirectory)) | ||||
|                 _ = Directory.CreateDirectory(checkDirectory); | ||||
|             noWaitDirectory = Path.Combine(checkDirectory, "NoWaitDirectory"); | ||||
|             results.Add(new(matchingFile, checkFile, errFile, checkDirectory, noWaitDirectory)); | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private void MoveCollection(DateTime dateTime, List<(string matchingFile, string checkFile)> collection) | ||||
|     { | ||||
|         long preWait; | ||||
|         List<(string checkFile, string errFile)> postCollection = new(); | ||||
|         foreach ((string matchingFile, string checkFile, string errFile, string checkDirectory, string noWaitDirectory) in GetCollection(collection)) | ||||
|         { | ||||
|             File.Move(matchingFile, checkFile); | ||||
|             if (Directory.Exists(noWaitDirectory)) | ||||
|             { | ||||
|                 postCollection.Add(new(checkFile, errFile)); | ||||
|                 continue; | ||||
|             } | ||||
|             if (_FileConnectorConfiguration?.FileHandleWaitTime is null) | ||||
|                 preWait = DateTime.Now.AddMilliseconds(1234).Ticks; | ||||
|             else | ||||
|                 preWait = DateTime.Now.AddMilliseconds(_FileConnectorConfiguration.FileHandleWaitTime.Value).Ticks; | ||||
|             for (short i = 0; i < short.MaxValue; i++) | ||||
|             { | ||||
|                 if (DateTime.Now.Ticks > preWait) | ||||
|                     break; | ||||
|                 Thread.Sleep(500); | ||||
|             } | ||||
|             for (int i = 0; i < int.MaxValue; i++) | ||||
|             { | ||||
|                 if (File.Exists(errFile)) | ||||
|                     throw new Exception(File.ReadAllText(errFile)); | ||||
|                 if (!File.Exists(checkFile)) | ||||
|                     break; | ||||
|                 if (new TimeSpan(DateTime.Now.Ticks - dateTime.Ticks).TotalSeconds > _BreakAfterSeconds) | ||||
|                     throw new Exception($"Not all files were consumed after {_BreakAfterSeconds} second(s)!"); | ||||
|                 Thread.Sleep(500); | ||||
|             } | ||||
|         } | ||||
|         if (postCollection.Count != 0) | ||||
|         { | ||||
|             Thread.Sleep(500); | ||||
|             StringBuilder stringBuilder = new(); | ||||
|             foreach ((string checkFile, string errFile) in postCollection) | ||||
|             { | ||||
|                 if (File.Exists(errFile)) | ||||
|                     _ = stringBuilder.AppendLine(File.ReadAllText(errFile)); | ||||
|                 if (File.Exists(checkFile)) | ||||
|                     _ = stringBuilder.AppendLine($"<{checkFile}> was not consumed by the end!"); | ||||
|             } | ||||
|             if (stringBuilder.Length > 0) | ||||
|                 throw new Exception(stringBuilder.ToString()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static void CreatePointerFile(int numberLength, string parentDirectory, List<string> matchingFiles) | ||||
|     { | ||||
| #nullable enable | ||||
|         string checkFile; | ||||
|         string writeFile; | ||||
|         string? directoryName; | ||||
|         int parentDirectoryLength = parentDirectory.Length; | ||||
|         foreach (string matchingFile in matchingFiles) | ||||
|         { | ||||
|             directoryName = Path.GetDirectoryName(matchingFile); | ||||
|             if (directoryName is null) | ||||
|                 continue; | ||||
|             checkFile = $"{matchingFile[0]}{directoryName.Substring(parentDirectoryLength + numberLength + 1)}"; | ||||
|             writeFile = Path.Combine(parentDirectory, $"{directoryName.Substring(parentDirectory.Length + 1, numberLength)}.txt"); | ||||
|             if (File.Exists(writeFile)) | ||||
|                 continue; | ||||
|             File.AppendAllLines(writeFile, new string[] { parentDirectory, matchingFile, directoryName, checkFile }); | ||||
|         } | ||||
| #nullable disable | ||||
|     } | ||||
|  | ||||
|     private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results = new(string.Empty, null, null, new List<FileInfo>()); | ||||
|         Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath); | ||||
|         _Logistics = new Logistics(reportFullPath, pdsf.Item1); | ||||
|         SetFileParameterLotIDToLogisticsMID(); | ||||
|         int numberLength = 2; | ||||
|         long ticks = dateTime.Ticks; | ||||
|         string parentParentDirectory = GetParentParent(reportFullPath); | ||||
|         List<string> searchDirectories = GetSearchDirectories(numberLength, parentParentDirectory); | ||||
|         List<string> matchingFiles = GetMatchingFiles(ticks, reportFullPath, searchDirectories); | ||||
|         if (matchingFiles.Count != searchDirectories.Count) | ||||
|             throw new Exception($"Didn't find all files after {_BreakAfterSeconds} second(s)!"); | ||||
|         try | ||||
|         { CreatePointerFile(numberLength, parentParentDirectory, matchingFiles); } | ||||
|         catch (Exception) { } | ||||
|         List<(string matchingFile, string checkFile)> collection = GetCollection(numberLength, parentParentDirectory, matchingFiles); | ||||
|         MoveCollection(dateTime, collection); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -1,144 +0,0 @@ | ||||
| using Adaptation.Eaf.Management.ConfigurationData.CellAutomation; | ||||
| using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration; | ||||
| using Adaptation.Shared; | ||||
| using Adaptation.Shared.Duplicator; | ||||
| using Adaptation.Shared.Methods; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.OpenInsightMetrologyViewer; | ||||
|  | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
|         _NullData = string.Empty; | ||||
|         _Logistics = new(this); | ||||
|         if (_FileParameter is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (_ModelObjectParameterDefinitions is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (!_IsDuplicator) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|     } | ||||
|  | ||||
|     void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) | ||||
|     { | ||||
|         bool isErrorFile = exception is not null; | ||||
|         if (!isErrorFile && !string.IsNullOrEmpty(_Logistics.ReportFullPath)) | ||||
|         { | ||||
|             FileInfo fileInfo = new(_Logistics.ReportFullPath); | ||||
|             if (fileInfo.Exists && fileInfo.LastWriteTime < fileInfo.CreationTime) | ||||
|                 File.SetLastWriteTime(_Logistics.ReportFullPath, fileInfo.CreationTime); | ||||
|         } | ||||
|         Move(extractResults); | ||||
|     } | ||||
|  | ||||
|     void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null); | ||||
|  | ||||
|     string IFileRead.GetEventDescription() | ||||
|     { | ||||
|         string result = _Description.GetEventDescription(); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     List<string> IFileRead.GetHeaderNames() | ||||
|     { | ||||
|         List<string> results = _Description.GetHeaderNames(); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     string[] IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, string to, string from, string resolvedFileLocation, Exception exception) | ||||
|     { | ||||
|         string[] results = Move(extractResults, to, from, resolvedFileLocation, exception); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     JsonProperty[] IFileRead.GetDefault() | ||||
|     { | ||||
|         JsonProperty[] results = _Description.GetDefault(this, _Logistics); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Dictionary<string, string> IFileRead.GetDisplayNamesJsonElement() | ||||
|     { | ||||
|         Dictionary<string, string> results = _Description.GetDisplayNamesJsonElement(this); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     List<IDescription> IFileRead.GetDescriptions(IFileRead fileRead, List<Test> tests, IProcessData processData) | ||||
|     { | ||||
|         List<IDescription> results = _Description.GetDescriptions(fileRead, _Logistics, tests, processData); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.GetExtractResult(string reportFullPath, string eventName) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         if (string.IsNullOrEmpty(eventName)) | ||||
|             throw new Exception(); | ||||
|         _ReportFullPath = reportFullPath; | ||||
|         DateTime dateTime = DateTime.Now; | ||||
|         results = GetExtractResult(reportFullPath, dateTime); | ||||
|         if (results.Item3 is null) | ||||
|             results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]"), results.Item4); | ||||
|         if (results.Item3.Length > 0 && _IsEAFHosted) | ||||
|             WritePDSF(this, results.Item3); | ||||
|         UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.ReExtract() | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         List<string> headerNames = _Description.GetHeaderNames(); | ||||
|         Dictionary<string, string> keyValuePairs = _Description.GetDisplayNamesJsonElement(this); | ||||
|         results = ReExtract(this, headerNames, keyValuePairs); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| #pragma warning disable IDE0060, CA1822 | ||||
|     private void SendData(string reportFullPath, DateTime dateTime, List<Description> descriptions) | ||||
| #pragma warning restore IDE0060, CA1822 | ||||
|     { | ||||
|         // WSRequest wsRequest = new(this, _Logistics, descriptions); | ||||
|         // int weekOfYear = _Calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday); | ||||
|         // string directory = Path.Combine(_OpenInsightMetrologyViewerFileShare, dateTime.Year.ToString(), $"WW{weekOfYear:00}"); | ||||
|         // (string jsonResults, WS.Results wsResults) = WS.SendData(_OpenInsightMetrologyViewerAPI, _Logistics.Sequence, directory, wsRequest); | ||||
|         // if (!wsResults.Success) | ||||
|         //     throw new Exception(wsResults.ToString()); | ||||
|         // _Log.Debug(wsResults.HeaderID); | ||||
|         // lock (_StaticRuns) | ||||
|         // { | ||||
|         //     if (!_StaticRuns.ContainsKey(_Logistics.Sequence)) | ||||
|         //         _StaticRuns.Add(_Logistics.Sequence, new()); | ||||
|         //     _StaticRuns[_Logistics.Sequence].Add(jsonResults); | ||||
|         // } | ||||
|         // string checkDirectory = Path.Combine(directory, wsResults.HeaderID.ToString()); | ||||
|         // if (!Directory.Exists(checkDirectory)) | ||||
|         //     _ = Directory.CreateDirectory(checkDirectory); | ||||
|         // File.Copy(reportFullPath, Path.Combine(checkDirectory, Path.GetFileName(reportFullPath)), overwrite: true); | ||||
|     } | ||||
|  | ||||
|     private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath); | ||||
|         _Logistics = new Logistics(reportFullPath, pdsf.Item1); | ||||
|         SetFileParameterLotIDToLogisticsMID(); | ||||
|         JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf); | ||||
|         List<Description> descriptions = json.ProcessData.GetDescriptions(jsonElements); | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             SendData(reportFullPath, dateTime, descriptions); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>()); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -1,161 +0,0 @@ | ||||
| using Adaptation.Eaf.Management.ConfigurationData.CellAutomation; | ||||
| using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration; | ||||
| using Adaptation.Shared; | ||||
| using Adaptation.Shared.Duplicator; | ||||
| using Adaptation.Shared.Methods; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Globalization; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.OpenInsightMetrologyViewerAttachments; | ||||
|  | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
|  | ||||
|     private readonly string _OpenInsightMetrologyViewerAPI; | ||||
|     private readonly string _OpenInsightMetrologyViewerFileShare; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
|         _NullData = string.Empty; | ||||
|         _Logistics = new(this); | ||||
|         if (_FileParameter is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (_ModelObjectParameterDefinitions is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (!_IsDuplicator) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         _OpenInsightMetrologyViewerAPI = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, "OpenInsight.MetrologyViewerAPI"); | ||||
|         _OpenInsightMetrologyViewerFileShare = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, "OpenInsight.MetrologyViewerFileShare"); | ||||
|     } | ||||
|  | ||||
|     void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) | ||||
|     { | ||||
|         bool isErrorFile = exception is not null; | ||||
|         if (!isErrorFile && !string.IsNullOrEmpty(_Logistics.ReportFullPath)) | ||||
|         { | ||||
|             FileInfo fileInfo = new(_Logistics.ReportFullPath); | ||||
|             if (fileInfo.Exists && fileInfo.LastWriteTime < fileInfo.CreationTime) | ||||
|                 File.SetLastWriteTime(_Logistics.ReportFullPath, fileInfo.CreationTime); | ||||
|         } | ||||
|         Move(extractResults); | ||||
|     } | ||||
|  | ||||
|     void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null); | ||||
|  | ||||
|     string IFileRead.GetEventDescription() | ||||
|     { | ||||
|         string result = _Description.GetEventDescription(); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     List<string> IFileRead.GetHeaderNames() | ||||
|     { | ||||
|         List<string> results = _Description.GetHeaderNames(); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     string[] IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, string to, string from, string resolvedFileLocation, Exception exception) | ||||
|     { | ||||
|         string[] results = Move(extractResults, to, from, resolvedFileLocation, exception); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     JsonProperty[] IFileRead.GetDefault() | ||||
|     { | ||||
|         JsonProperty[] results = _Description.GetDefault(this, _Logistics); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Dictionary<string, string> IFileRead.GetDisplayNamesJsonElement() | ||||
|     { | ||||
|         Dictionary<string, string> results = _Description.GetDisplayNamesJsonElement(this); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     List<IDescription> IFileRead.GetDescriptions(IFileRead fileRead, List<Test> tests, IProcessData processData) | ||||
|     { | ||||
|         List<IDescription> results = _Description.GetDescriptions(fileRead, _Logistics, tests, processData); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.GetExtractResult(string reportFullPath, string eventName) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         if (string.IsNullOrEmpty(eventName)) | ||||
|             throw new Exception(); | ||||
|         _ReportFullPath = reportFullPath; | ||||
|         DateTime dateTime = DateTime.Now; | ||||
|         results = GetExtractResult(reportFullPath, dateTime); | ||||
|         if (results.Item3 is null) | ||||
|             results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]"), results.Item4); | ||||
|         if (results.Item3.Length > 0 && _IsEAFHosted) | ||||
|             WritePDSF(this, results.Item3); | ||||
|         UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.ReExtract() | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         List<string> headerNames = _Description.GetHeaderNames(); | ||||
|         Dictionary<string, string> keyValuePairs = _Description.GetDisplayNamesJsonElement(this); | ||||
|         results = ReExtract(this, headerNames, keyValuePairs); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| #nullable enable | ||||
|  | ||||
|     private string? GetHeaderIdDirectory(long headerId) | ||||
|     { | ||||
|         string? result = null; | ||||
|         int weekNum; | ||||
|         string year; | ||||
|         string weekDirectory; | ||||
|         string checkDirectory; | ||||
|         DateTime[] dateTimes = new DateTime[] { _Logistics.DateTimeFromSequence, _Logistics.DateTimeFromSequence.AddDays(-6.66) }; | ||||
|         foreach (DateTime dateTime in dateTimes) | ||||
|         { | ||||
|             year = dateTime.Year.ToString(); | ||||
|             weekNum = _Calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday); | ||||
|             weekDirectory = Path.Combine(_OpenInsightMetrologyViewerFileShare, dateTime.Year.ToString(), $"WW{weekNum:00}"); | ||||
|             if (!Directory.Exists(weekDirectory)) | ||||
|                 _ = Directory.CreateDirectory(weekDirectory); | ||||
|             checkDirectory = Path.Combine(weekDirectory, $"-{headerId}"); | ||||
|             if (!Directory.Exists(checkDirectory)) | ||||
|                 continue; | ||||
|             result = checkDirectory; | ||||
|             break; | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     private static void PostOpenInsightMetrologyViewerAttachments(List<Description> descriptions) | ||||
|     { | ||||
|         if (descriptions is null) | ||||
|             throw new ArgumentNullException(nameof(descriptions)); | ||||
|     } | ||||
|  | ||||
|     private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime) | ||||
|     { | ||||
|         if (dateTime == DateTime.MinValue) | ||||
|             throw new ArgumentNullException(nameof(dateTime)); | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath); | ||||
|         _Logistics = new Logistics(reportFullPath, pdsf.Item1); | ||||
|         SetFileParameterLotIDToLogisticsMID(); | ||||
|         JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf); | ||||
|         List<Description> descriptions = json.ProcessData.GetDescriptions(jsonElements); | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             PostOpenInsightMetrologyViewerAttachments(descriptions); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>()); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -1,38 +1,205 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.ObjectModel; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
| using System.Text.Json.Serialization; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.Priority; | ||||
|  | ||||
| #nullable enable | ||||
|  | ||||
| public class Aggregation | ||||
| { | ||||
|  | ||||
|     [JsonConstructor] | ||||
|     public Aggregation( | ||||
|         string average, | ||||
|         int count, | ||||
|         int? inverse, | ||||
|         int maximum, | ||||
|         int minimum, | ||||
|         ReadOnlyCollection<Record> records, | ||||
|         int sum | ||||
|     ) | ||||
|     public Aggregation(double inverseAverage, | ||||
|                        int valueCount, | ||||
|                        double fibonacciAverage, | ||||
|                        int? inverseValue, | ||||
|                        int valueMaximum, | ||||
|                        int valueMinimum, | ||||
|                        Notification[] notifications, | ||||
|                        int valueSum) | ||||
|     { | ||||
|         Average = average; | ||||
|         Count = count; | ||||
|         Inverse = inverse; | ||||
|         Maximum = maximum; | ||||
|         Minimum = minimum; | ||||
|         Records = records; | ||||
|         Sum = sum; | ||||
|         InverseAverage = inverseAverage; | ||||
|         ValueCount = valueCount; | ||||
|         FibonacciAverage = fibonacciAverage; | ||||
|         InverseValue = inverseValue; | ||||
|         ValueMaximum = valueMaximum; | ||||
|         ValueMinimum = valueMinimum; | ||||
|         Notifications = notifications; | ||||
|         ValueSum = valueSum; | ||||
|     } | ||||
|  | ||||
|     [JsonPropertyName("Average")] public string Average { get; } | ||||
|     [JsonPropertyName("Count")] public int Count { get; } | ||||
|     [JsonPropertyName("Inverse")] public int? Inverse { get; } | ||||
|     [JsonPropertyName("Maximum")] public int Maximum { get; } | ||||
|     [JsonPropertyName("Minimum")] public int Minimum { get; } | ||||
|     [JsonPropertyName("Records")] public ReadOnlyCollection<Record> Records { get; } | ||||
|     [JsonPropertyName("Sum")] public int Sum { get; } | ||||
|     public double InverseAverage { get; } // [JsonPropertyName("InverseAverage")] | ||||
|     public int ValueCount { get; } // [JsonPropertyName("ValueCount")] | ||||
|     public double FibonacciAverage { get; } // [JsonPropertyName("Fibonacci")] | ||||
|     public int? InverseValue { get; } // [JsonPropertyName("InverseValue")] | ||||
|     public int ValueMaximum { get; } // [JsonPropertyName("ValueMaximum")] | ||||
|     public int ValueMinimum { get; } // [JsonPropertyName("ValueMinimum")] | ||||
|     public Notification[] Notifications { get; } // [JsonPropertyName("Notifications")] | ||||
|     public int ValueSum { get; } // [JsonPropertyName("ValueSum")] | ||||
|  | ||||
|     private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Dictionary<int, List<Notification>> keyValuePairs) | ||||
|     { | ||||
|         Dictionary<int, Aggregation> results = new(); | ||||
|         int value; | ||||
|         int? inverseValue; | ||||
|         double inverseAverage; | ||||
|         Aggregation aggregation; | ||||
|         double fibonacciAverage; | ||||
|         List<int> collection = new(); | ||||
|         int averageFromInverseCeiling; | ||||
|         List<int> inverseCollection = new(); | ||||
|         List<int> fibonacciCollection = new(); | ||||
|         foreach (KeyValuePair<int, List<Notification>> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             collection.Clear(); | ||||
|             inverseCollection.Clear(); | ||||
|             fibonacciCollection.Clear(); | ||||
|             foreach (Notification notification in keyValuePair.Value) | ||||
|             { | ||||
|                 if (!int.TryParse(notification.Value, out value)) | ||||
|                     continue; | ||||
|                 collection.Add(value); | ||||
|                 if (notification.Inverse is null) | ||||
|                     continue; | ||||
|                 inverseCollection.Add(notification.Inverse.Value); | ||||
|                 if (notification.Fibonacci is null) | ||||
|                     continue; | ||||
|                 fibonacciCollection.Add(notification.Fibonacci.Value); | ||||
|             } | ||||
|             if (inverseCollection.Count == 0 || fibonacciCollection.Count == 0) | ||||
|                 continue; | ||||
|             inverseAverage = Math.Round(inverseCollection.Average(), settings.Digits); | ||||
|             averageFromInverseCeiling = (int)Math.Ceiling(inverseAverage); | ||||
|             inverseValue = Notification.GetInverse(averageFromInverseCeiling.ToString()); | ||||
|             fibonacciAverage = Math.Round(fibonacciCollection.Average(), settings.Digits); | ||||
|             aggregation = new(inverseAverage: inverseAverage, | ||||
|                               valueCount: collection.Count, | ||||
|                               fibonacciAverage: fibonacciAverage, | ||||
|                               inverseValue: inverseValue, | ||||
|                               valueMaximum: collection.Max(), | ||||
|                               valueMinimum: collection.Min(), | ||||
|                               notifications: keyValuePair.Value.ToArray(), | ||||
|                               valueSum: collection.Sum()); | ||||
|             results.Add(keyValuePair.Key, aggregation); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Notification> GetNotifications(Settings settings, string directory) | ||||
|     { | ||||
|         List<Notification> results = new(); | ||||
|         string? key; | ||||
|         string text; | ||||
|         string[] files; | ||||
|         Notification? notification; | ||||
|         List<Notification>? collection; | ||||
|         Dictionary<string, List<Notification>> keyValuePairs = new(); | ||||
|         string[] directories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly); | ||||
|         foreach (string subDirectory in directories) | ||||
|         { | ||||
|             keyValuePairs.Clear(); | ||||
|             files = Directory.GetFiles(subDirectory, settings.SourceFileFilter, SearchOption.TopDirectoryOnly); | ||||
|             foreach (string file in files) | ||||
|             { | ||||
|                 text = File.ReadAllText(file); | ||||
|                 if (string.IsNullOrEmpty(text) || text[0] == '[') | ||||
|                     continue; | ||||
|                 notification = JsonSerializer.Deserialize(text, NotificationSourceGenerationContext.Default.Notification); | ||||
|                 if (notification is null || string.IsNullOrEmpty(notification.Id)) | ||||
|                     continue; | ||||
|                 key = !string.IsNullOrEmpty(notification.Username) ? notification.Username : throw new Exception(); | ||||
|                 if (string.IsNullOrEmpty(key)) | ||||
|                     continue; | ||||
|                 if (!keyValuePairs.TryGetValue(key, out collection)) | ||||
|                 { | ||||
|                     keyValuePairs.Add(key, new()); | ||||
|                     if (!keyValuePairs.TryGetValue(key, out collection)) | ||||
|                         throw new Exception(); | ||||
|                 } | ||||
|                 collection.Add(notification); | ||||
|             } | ||||
|             foreach (KeyValuePair<string, List<Notification>> keyValuePair in keyValuePairs) | ||||
|             { | ||||
|                 if (keyValuePair.Value.Count == 1) | ||||
|                     results.Add(keyValuePair.Value[0]); | ||||
|                 else | ||||
|                 { | ||||
|                     notification = keyValuePair.Value.Select(record => new KeyValuePair<string, Notification>(record.Time, record)).OrderBy(pair => pair.Key).Last().Value; | ||||
|                     results.Add(notification); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, string directory) | ||||
|     { | ||||
|         ReadOnlyDictionary<int, Aggregation> results; | ||||
|         int id; | ||||
|         List<Notification>? collection; | ||||
|         Dictionary<int, List<Notification>> keyValuePairs = new(); | ||||
|         ReadOnlyCollection<Notification> notifications = GetNotifications(settings, directory); | ||||
|         foreach (Notification notification in notifications) | ||||
|         { | ||||
|             if (!int.TryParse(notification.Id, out id)) | ||||
|                 continue; | ||||
|             if (!keyValuePairs.TryGetValue(id, out collection)) | ||||
|             { | ||||
|                 keyValuePairs.Add(id, new()); | ||||
|                 if (!keyValuePairs.TryGetValue(id, out collection)) | ||||
|                     throw new Exception(); | ||||
|             } | ||||
|             collection.Add(notification); | ||||
|         } | ||||
|         results = GetKeyValuePairs(settings, keyValuePairs); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     internal static ReadOnlyDictionary<string, ReadOnlyDictionary<int, Aggregation>> GetKeyValuePairsAndWriteFiles(Settings settings) | ||||
|     { | ||||
|         Dictionary<string, ReadOnlyDictionary<int, Aggregation>> results = new(); | ||||
|         string json; | ||||
|         string jsonOld; | ||||
|         string jsonFile; | ||||
|         string directoryName; | ||||
|         ReadOnlyDictionary<int, Aggregation> keyValuePairs; | ||||
|         if (!Directory.Exists(settings.SourceFileLocation)) | ||||
|             _ = Directory.CreateDirectory(settings.SourceFileLocation); | ||||
|         if (!Directory.Exists(settings.TargetFileLocation)) | ||||
|             _ = Directory.CreateDirectory(settings.TargetFileLocation); | ||||
|         string[] directories = Directory.GetDirectories(settings.SourceFileLocation, "*", SearchOption.TopDirectoryOnly); | ||||
|         foreach (string directory in directories) | ||||
|         { | ||||
|             directoryName = Path.GetFileName(directory); | ||||
|             keyValuePairs = GetKeyValuePairs(settings, directory); | ||||
|             jsonFile = Path.Combine(settings.TargetFileLocation, $"{directoryName}.json"); | ||||
|             json = JsonSerializer.Serialize(keyValuePairs, AggregationReadOnlyDictionarySourceGenerationContext.Default.ReadOnlyDictionaryInt32Aggregation); | ||||
|             // keyValuePairs = JsonSerializer.Deserialize(json, AggregationReadOnlyDictionarySourceGenerationContext.Default.ReadOnlyDictionaryInt32Aggregation); | ||||
|             jsonOld = File.Exists(jsonFile) ? File.ReadAllText(jsonFile) : string.Empty; | ||||
|             if (json != jsonOld) | ||||
|                 File.WriteAllText(jsonFile, json); | ||||
|             results.Add(directoryName, keyValuePairs); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     internal static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Notification notification) | ||||
|     { | ||||
|         ReadOnlyDictionary<int, Aggregation> results; | ||||
|         if (string.IsNullOrEmpty(notification.Id) || !int.TryParse(notification.Id, out int id)) | ||||
|             results = new(new Dictionary<int, Aggregation>()); | ||||
|         else | ||||
|         { | ||||
|             Dictionary<int, List<Notification>> keyValuePairs = new() { { id, new Notification[] { notification }.ToList() } }; | ||||
|             results = GetKeyValuePairs(settings, keyValuePairs); | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -46,4 +213,10 @@ internal partial class AggregationSourceGenerationContext : JsonSerializerContex | ||||
| [JsonSerializable(typeof(Aggregation[]))] | ||||
| internal partial class AggregationCollectionSourceGenerationContext : JsonSerializerContext | ||||
| { | ||||
| } | ||||
|  | ||||
| [JsonSourceGenerationOptions(WriteIndented = true)] | ||||
| [JsonSerializable(typeof(ReadOnlyDictionary<int, Aggregation>))] | ||||
| internal partial class AggregationReadOnlyDictionarySourceGenerationContext : JsonSerializerContext | ||||
| { | ||||
| } | ||||
| @ -3,28 +3,36 @@ using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration; | ||||
| using Adaptation.Shared; | ||||
| using Adaptation.Shared.Duplicator; | ||||
| using Adaptation.Shared.Methods; | ||||
| using log4net; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.ObjectModel; | ||||
| using System.Diagnostics; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
| using System.Threading; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.Priority; | ||||
|  | ||||
| #nullable enable | ||||
|  | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
|  | ||||
|     private readonly Timer _Timer; | ||||
|     internal static ILog? Log { get; private set; } | ||||
|     internal static Settings? Settings { get; private set; } | ||||
|     internal static Dictionary<int, WorkItem>? WorkItems { get; private set; } | ||||
|     internal static Dictionary<string, Queue<KeyValuePair<string, WorkItem>>>? Queue { get; private set; } | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         Queue = new(); | ||||
|         WorkItems = new(); | ||||
|         _MinFileLength = 10; | ||||
|         _NullData = string.Empty; | ||||
|         _Logistics = new(this); | ||||
|         _NullData = string.Empty; | ||||
|         Log = LogManager.GetLogger(typeof(FileRead)); | ||||
|         if (_FileParameter is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (_ModelObjectParameterDefinitions is null) | ||||
| @ -33,12 +41,29 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (_IsEAFHosted) | ||||
|             NestExistingFiles(_FileConnectorConfiguration); | ||||
|         if (!Debugger.IsAttached && fileConnectorConfiguration.PreProcessingMode != FileConnectorConfiguration.PreProcessingModeEnum.Process) | ||||
|             _Timer = new Timer(Callback, null, (int)(fileConnectorConfiguration.FileScanningIntervalInSeconds * 1000), Timeout.Infinite); | ||||
|         string parentDirectory = Path.GetDirectoryName(_FileConnectorConfiguration.TargetFileLocation) ?? throw new Exception(); | ||||
|         Settings = new(digits: 5, | ||||
|                         parentDirectory: parentDirectory, | ||||
|                         priorities: 3, | ||||
|                         priorityGroups: 9, | ||||
|                         sourceFileFilter: _FileConnectorConfiguration.SourceFileFilter, | ||||
|                         sourceFileLocation: _FileConnectorConfiguration.SourceFileLocation, | ||||
|                         targetFileLocation: _FileConnectorConfiguration.TargetFileLocation); | ||||
|         _Timer = new Timer(Callback, null, Timeout.Infinite, Timeout.Infinite); | ||||
|         string cellInstanceNamed = string.Concat("CellInstance.", _EquipmentType); | ||||
|         string url = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.Microsoft.Owin.Hosting.WebApp.Start.URL"); | ||||
|         if (_IsEAFHosted) | ||||
|         { | ||||
|             _ = Microsoft.Owin.Hosting.WebApp.Start<Startup>(url); | ||||
|             _Log.Info($"Server running on {url}"); | ||||
|         } | ||||
|         if (Debugger.IsAttached || fileConnectorConfiguration.PreProcessingMode == FileConnectorConfiguration.PreProcessingModeEnum.Process) | ||||
|             Callback(null); | ||||
|         else | ||||
|         { | ||||
|             _Timer = new Timer(Callback, null, Timeout.Infinite, Timeout.Infinite); | ||||
|             Callback(null); | ||||
|             long fileScanningIntervalInSeconds = _FileConnectorConfiguration.FileScanningIntervalInSeconds is null ? 0 : _FileConnectorConfiguration.FileScanningIntervalInSeconds.Value; | ||||
|             TimeSpan timeSpan = new(DateTime.Now.AddSeconds(fileScanningIntervalInSeconds).Ticks - DateTime.Now.Ticks); | ||||
|             _ = _Timer.Change((long)timeSpan.TotalMilliseconds, Timeout.Infinite); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -91,7 +116,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         DateTime dateTime = DateTime.Now; | ||||
|         results = GetExtractResult(reportFullPath, dateTime); | ||||
|         if (results.Item3 is null) | ||||
|             results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]"), results.Item4); | ||||
|             results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]") ?? throw new Exception(), results.Item4); | ||||
|         if (results.Item3.Length > 0 && _IsEAFHosted) | ||||
|             WritePDSF(this, results.Item3); | ||||
|         UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks); | ||||
| @ -107,195 +132,44 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| #nullable enable | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> GetRecords(string directory, string searchPattern) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         string text; | ||||
|         Record? record; | ||||
|         string[] files; | ||||
|         List<Record>? collection; | ||||
|         Dictionary<string, List<Record>> keyValuePairs = new(); | ||||
|         string[] directories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly); | ||||
|         foreach (string subDirectory in directories) | ||||
|         { | ||||
|             keyValuePairs.Clear(); | ||||
|             files = Directory.GetFiles(subDirectory, searchPattern, SearchOption.TopDirectoryOnly); | ||||
|             foreach (string file in files) | ||||
|             { | ||||
|                 text = File.ReadAllText(file); | ||||
|                 if (string.IsNullOrEmpty(text) || text[0] == '[') | ||||
|                     continue; | ||||
|                 record = JsonSerializer.Deserialize<Record>(text); | ||||
|                 if (record is null || record.Id == 0) | ||||
|                     continue; | ||||
|                 if (!keyValuePairs.TryGetValue(record.RemoteIpAddress, out collection)) | ||||
|                 { | ||||
|                     keyValuePairs.Add(record.RemoteIpAddress, new()); | ||||
|                     if (!keyValuePairs.TryGetValue(record.RemoteIpAddress, out collection)) | ||||
|                         throw new Exception(); | ||||
|                 } | ||||
|                 collection.Add(record); | ||||
|             } | ||||
|             foreach (KeyValuePair<string, List<Record>> keyValuePair in keyValuePairs) | ||||
|             { | ||||
|                 if (keyValuePair.Value.Count == 1) | ||||
|                     results.Add(keyValuePair.Value[0]); | ||||
|                 else | ||||
|                 { | ||||
|                     record = keyValuePair.Value.Select(record => new KeyValuePair<long, Record>(record.Time, record)).OrderBy(pair => pair.Key).Last().Value; | ||||
|                     results.Add(record); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static int? GetInverse(int value) => | ||||
|         value switch | ||||
|         { | ||||
|             1 => 3, | ||||
|             2 => 2, | ||||
|             3 => 1, | ||||
|             _ => null | ||||
|         }; | ||||
|  | ||||
|     private static int? GetInverse(double value) | ||||
|     { | ||||
|         int? result; | ||||
|         if (value > 3) | ||||
|             result = null; | ||||
|         else if (value > 2) | ||||
|             result = 1; | ||||
|         else if (value > 1) | ||||
|             result = 2; | ||||
|         else if (value > 0) | ||||
|             result = 3; | ||||
|         else | ||||
|             result = null; | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Dictionary<int, List<Record>> keyValuePairs) | ||||
|     { | ||||
|         Dictionary<int, Aggregation> results = new(); | ||||
|         Aggregation aggregation; | ||||
|         int? inverse; | ||||
|         double average; | ||||
|         List<int> collection = new(); | ||||
|         foreach (KeyValuePair<int, List<Record>> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             collection.Clear(); | ||||
|             foreach (Record record in keyValuePair.Value) | ||||
|             { | ||||
|                 inverse = GetInverse(record.Value); | ||||
|                 if (inverse is null) | ||||
|                     continue; | ||||
|                 collection.Add(inverse.Value); | ||||
|             } | ||||
|             average = collection.Average(); | ||||
|             inverse = GetInverse(average); | ||||
|             aggregation = new(average.ToString("0.000"), | ||||
|                               keyValuePair.Value.Count, | ||||
|                               inverse, | ||||
|                               keyValuePair.Value.Max(record => record.Value), | ||||
|                               keyValuePair.Value.Min(record => record.Value), | ||||
|                               new(keyValuePair.Value), | ||||
|                               keyValuePair.Value.Sum(record => record.Value)); | ||||
|             results.Add(keyValuePair.Key, aggregation); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(string directory, string searchPattern) | ||||
|     { | ||||
|         ReadOnlyDictionary<int, Aggregation> results; | ||||
|         List<Record>? collection; | ||||
|         Dictionary<int, List<Record>> keyValuePairs = new(); | ||||
|         ReadOnlyCollection<Record> records = GetRecords(directory, searchPattern); | ||||
|         foreach (Record record in records) | ||||
|         { | ||||
|             if (!keyValuePairs.TryGetValue(record.Id, out collection)) | ||||
|             { | ||||
|                 keyValuePairs.Add(record.Id, new()); | ||||
|                 if (!keyValuePairs.TryGetValue(record.Id, out collection)) | ||||
|                     throw new Exception(); | ||||
|             } | ||||
|             collection.Add(record); | ||||
|         } | ||||
|         results = GetKeyValuePairs(keyValuePairs); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private static void WriteFiles(string sourceFileLocation, string sourceFileFilter, string targetFileLocation) | ||||
|     { | ||||
|         string json; | ||||
|         string jsonFile; | ||||
|         string directoryName; | ||||
|         if (!Directory.Exists(sourceFileLocation)) | ||||
|             _ = Directory.CreateDirectory(sourceFileLocation); | ||||
|         if (!Directory.Exists(targetFileLocation)) | ||||
|             _ = Directory.CreateDirectory(targetFileLocation); | ||||
|         ReadOnlyDictionary<int, Aggregation> keyValuePairs; | ||||
|         JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true }; | ||||
|         string[] directories = Directory.GetDirectories(sourceFileLocation, "*", SearchOption.TopDirectoryOnly); | ||||
|         foreach (string directory in directories) | ||||
|         { | ||||
|             directoryName = Path.GetFileName(directory); | ||||
|             keyValuePairs = GetKeyValuePairs(directory, sourceFileFilter); | ||||
|             jsonFile = Path.Combine(targetFileLocation, $"{directoryName}.json"); | ||||
|             json = JsonSerializer.Serialize(keyValuePairs, jsonSerializerOptions); | ||||
|             File.WriteAllText(jsonFile, json); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void Callback(object state) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             if (_IsEAFHosted) | ||||
|                 WriteFiles(_FileConnectorConfiguration.SourceFileLocation, _FileConnectorConfiguration.SourceFileFilter, _FileConnectorConfiguration.TargetFileLocation); | ||||
|         } | ||||
|         catch (Exception exception) | ||||
|         { | ||||
|             string subject = string.Concat("Exception:", _CellInstanceConnectionName); | ||||
|             string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace); | ||||
|             try | ||||
|             { | ||||
|                 _SMTP.SendHighPriorityEmailMessage(subject, body);  | ||||
|                 File.WriteAllText(".email", body); | ||||
|             } | ||||
|             catch (Exception) { } | ||||
|         } | ||||
|         try | ||||
|         { | ||||
|             if (_FileConnectorConfiguration?.FileScanningIntervalInSeconds is null) | ||||
|                 throw new Exception(); | ||||
|             TimeSpan timeSpan = new(DateTime.Now.AddSeconds(_FileConnectorConfiguration.FileScanningIntervalInSeconds.Value).Ticks - DateTime.Now.Ticks); | ||||
|             _ = _Timer.Change((long)timeSpan.TotalMilliseconds, Timeout.Infinite); | ||||
|         } | ||||
|         catch (Exception exception) | ||||
|         { | ||||
|             string subject = string.Concat("Exception:", _CellInstanceConnectionName); | ||||
|             string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace); | ||||
|             try | ||||
|             { | ||||
|                 _SMTP.SendHighPriorityEmailMessage(subject, body);  | ||||
|                 File.WriteAllText(".email", body); | ||||
|             } | ||||
|             catch (Exception) { } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         if (dateTime == DateTime.MinValue) | ||||
|             throw new ArgumentNullException(nameof(dateTime)); | ||||
|         _Logistics = new Logistics(reportFullPath, $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};"); | ||||
|         results = new(_Logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), new List<FileInfo>()); | ||||
|         string[] lines = new string[] { string.Empty, "NUM_DATA_ROWS", $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};" }; | ||||
|         ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines); | ||||
|         _Logistics = new Logistics(reportFullPath, processDataStandardFormat); | ||||
|         results = new(string.Join(Environment.NewLine, _Logistics.Logistics1), Array.Empty<Test>(), Array.Empty<JsonElement>(), new List<FileInfo>()); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private void Callback(object? state) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             if (Settings is null) | ||||
|                 throw new NullReferenceException(nameof(Settings)); | ||||
|             if (WorkItems is null) | ||||
|                 throw new NullReferenceException(nameof(WorkItems)); | ||||
|             _Log.Info($"Enter-{nameof(WeightedShortestJobFirstModule.PopulatedWorkItemsAndGetJson)}"); | ||||
|             string? json = WeightedShortestJobFirstModule.PopulatedWorkItemsAndGetJson(Settings, WorkItems); | ||||
|             if (!string.IsNullOrEmpty(json)) | ||||
|                 WeightedShortestJobFirstModule.WriteJson(Settings, json); | ||||
|             _Log.Info($"End-{nameof(WeightedShortestJobFirstModule.PopulatedWorkItemsAndGetJson)}"); | ||||
|         } | ||||
|         catch (Exception exception) | ||||
|         { | ||||
|             string subject = string.Concat("Exception:", _CellInstanceConnectionName); | ||||
|             string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace); | ||||
|             _Log.Fatal($"Exception-{nameof(WeightedShortestJobFirstModule.PopulatedWorkItemsAndGetJson)}{Environment.NewLine}{body}"); | ||||
|             try | ||||
|             { | ||||
|                 _SMTP.SendHighPriorityEmailMessage(subject, body); | ||||
|                 File.WriteAllText(".email", body); | ||||
|             } | ||||
|             catch (Exception) { } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										126
									
								
								Adaptation/FileHandlers/Priority/Notification.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								Adaptation/FileHandlers/Priority/Notification.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,126 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text.Json.Serialization; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.Priority; | ||||
|  | ||||
| #nullable enable | ||||
|  | ||||
| public class Notification | ||||
| { | ||||
|  | ||||
|     [JsonConstructor] | ||||
|     public Notification(int? fibonacci, | ||||
|                         string? id, | ||||
|                         int? inverse, | ||||
|                         string? machineId, | ||||
|                         string page, | ||||
|                         string? site, | ||||
|                         string? sessionId, | ||||
|                         string time, | ||||
|                         string? username, | ||||
|                         string? value) | ||||
|     { | ||||
|         int? i = inverse is not null ? inverse : GetInverse(value); | ||||
|         Fibonacci = fibonacci is not null ? fibonacci : i is null ? null : GetFibonacci(i.Value); | ||||
|         Id = id; | ||||
|         Inverse = i; | ||||
|         MachineId = machineId; | ||||
|         Page = page; | ||||
|         Site = site is not null ? site : "MES"; | ||||
|         SessionId = sessionId; | ||||
|         Time = time; | ||||
|         Username = username; | ||||
|         Value = value; | ||||
|     } | ||||
|  | ||||
|     [JsonPropertyName("id")] public string? Id { get; } | ||||
|     [JsonPropertyName("fibonacci")] public int? Fibonacci { get; } | ||||
|     [JsonPropertyName("inverse")] public int? Inverse { get; } | ||||
|     [JsonPropertyName("machineId")] public string? MachineId { get; } | ||||
|     [JsonPropertyName("page")] public string Page { get; } | ||||
|     [JsonPropertyName("site")] public string? Site { get; } | ||||
|     [JsonPropertyName("sessionId")] public string? SessionId { get; } | ||||
|     [JsonPropertyName("time")] public string Time { get; } | ||||
|     [JsonPropertyName("username")] public string? Username { get; } | ||||
|     [JsonPropertyName("value")] public string? Value { get; } | ||||
|  | ||||
|     internal static Notification Get(Dictionary<string, string?> keyValuePairs) | ||||
|     { | ||||
|         Notification results; | ||||
|         string? id; | ||||
|         string? fibonacci; | ||||
|         string? inverse; | ||||
|         string? machineId; | ||||
|         string? page; | ||||
|         string? site; | ||||
|         string? sessionId; | ||||
|         string? username; | ||||
|         string? time; | ||||
|         string? value; | ||||
|         if (!keyValuePairs.TryGetValue(nameof(id), out id)) | ||||
|             id = null; | ||||
|         if (!keyValuePairs.TryGetValue(nameof(fibonacci), out fibonacci)) | ||||
|             fibonacci = null; | ||||
|         if (!keyValuePairs.TryGetValue(nameof(inverse), out inverse)) | ||||
|             inverse = null; | ||||
|         if (!keyValuePairs.TryGetValue(nameof(machineId), out machineId)) | ||||
|             machineId = null; | ||||
|         if (!keyValuePairs.TryGetValue(nameof(page), out page)) | ||||
|             throw new Exception(); | ||||
|         if (!keyValuePairs.TryGetValue(nameof(site), out site)) | ||||
|             site = null; | ||||
|         if (!keyValuePairs.TryGetValue(nameof(sessionId), out sessionId)) | ||||
|             sessionId = null; | ||||
|         if (!keyValuePairs.TryGetValue(nameof(username), out username)) | ||||
|             username = null; | ||||
|         if (!keyValuePairs.TryGetValue(nameof(time), out time)) | ||||
|             throw new Exception(); | ||||
|         if (!keyValuePairs.TryGetValue(nameof(value), out value)) | ||||
|             value = null; | ||||
|         results = new(fibonacci: fibonacci is null ? null : int.Parse(fibonacci), | ||||
|                       id: id, | ||||
|                       inverse: inverse is null ? null : int.Parse(inverse), | ||||
|                       machineId: machineId, | ||||
|                       page: page ?? throw new Exception(), | ||||
|                       site: site, | ||||
|                       sessionId: sessionId, | ||||
|                       time: time ?? throw new Exception(), | ||||
|                       username: username, | ||||
|                       value: value); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     internal static int? GetInverse(string? value) => | ||||
|         value switch | ||||
|         { | ||||
|             "1" => 5, | ||||
|             "2" => 4, | ||||
|             "3" => 3, | ||||
|             "4" => 2, | ||||
|             "5" => 1, | ||||
|             _ => null | ||||
|         }; | ||||
|  | ||||
|     private static int? GetFibonacci(int value) => | ||||
|         value switch | ||||
|         { | ||||
|             9 => 55, | ||||
|             8 => 34, | ||||
|             7 => 21, | ||||
|             6 => 13, | ||||
|             5 => 8, | ||||
|             4 => 5, | ||||
|             3 => 3, | ||||
|             2 => 2, | ||||
|             1 => 1, | ||||
|             _ => null | ||||
|         }; | ||||
|  | ||||
| } | ||||
|  | ||||
| [JsonSourceGenerationOptions(WriteIndented = true)] | ||||
| [JsonSerializable(typeof(Notification))] | ||||
| public partial class NotificationSourceGenerationContext : JsonSerializerContext | ||||
| { | ||||
| } | ||||
| @ -1,37 +0,0 @@ | ||||
| using System.Collections.ObjectModel; | ||||
| using System.Text.Json.Serialization; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.Priority; | ||||
|  | ||||
| public class Record | ||||
| { | ||||
|  | ||||
|     [JsonConstructor] | ||||
|     public Record( | ||||
|         string json, | ||||
|         int id, | ||||
|         string page, | ||||
|         string queryString, | ||||
|         string remoteIpAddress, | ||||
|         long time, | ||||
|         int value | ||||
|     ) | ||||
|     { | ||||
|         Json = json; | ||||
|         Id = id; | ||||
|         Page = page; | ||||
|         QueryString = queryString; | ||||
|         RemoteIpAddress = remoteIpAddress; | ||||
|         Time = time; | ||||
|         Value = value; | ||||
|     } | ||||
|  | ||||
|     [JsonPropertyName("Json")] public string Json { get; } | ||||
|     [JsonPropertyName("id")] public int Id { get; } | ||||
|     [JsonPropertyName("page")] public string Page { get; } | ||||
|     [JsonPropertyName("QueryString")] public string QueryString { get; } | ||||
|     [JsonPropertyName("RemoteIpAddress")] public string RemoteIpAddress { get; } | ||||
|     [JsonPropertyName("time")] public long Time { get; } | ||||
|     [JsonPropertyName("value")] public int Value { get; } | ||||
|  | ||||
| } | ||||
							
								
								
									
										43
									
								
								Adaptation/FileHandlers/Priority/Settings.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								Adaptation/FileHandlers/Priority/Settings.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| using System.Collections.Generic; | ||||
| using System.Text.Json.Serialization; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.Priority; | ||||
|  | ||||
| #nullable enable | ||||
|  | ||||
| public class Settings | ||||
| { | ||||
|  | ||||
|     [JsonConstructor] | ||||
|     public Settings(int digits, | ||||
|                     string parentDirectory, | ||||
|                     int priorities, | ||||
|                     int priorityGroups, | ||||
|                     string sourceFileFilter, | ||||
|                     string sourceFileLocation, | ||||
|                     string targetFileLocation) | ||||
|     { | ||||
|         Digits = digits; | ||||
|         ParentDirectory = parentDirectory; | ||||
|         Priorities = priorities; | ||||
|         PriorityGroups = priorityGroups; | ||||
|         SourceFileFilter = sourceFileFilter; | ||||
|         SourceFileLocation = sourceFileLocation; | ||||
|         TargetFileLocation = targetFileLocation; | ||||
|     } | ||||
|  | ||||
|     public int Digits { get; } // [JsonPropertyName("Digits")] | ||||
|     public string ParentDirectory { get; } // [JsonPropertyName("ParentDirectory")] | ||||
|     public int Priorities { get; } // [JsonPropertyName("Priorities")] | ||||
|     public int PriorityGroups { get; } // [JsonPropertyName("PriorityGroups")] | ||||
|     public string SourceFileFilter { get; } // [JsonPropertyName("SourceFileFilter")] | ||||
|     public string SourceFileLocation { get; } // [JsonPropertyName("SourceFileLocation")] | ||||
|     public string TargetFileLocation { get; } // [JsonPropertyName("TargetFileLocation")] | ||||
|  | ||||
| } | ||||
|  | ||||
| [JsonSourceGenerationOptions(WriteIndented = true)] | ||||
| [JsonSerializable(typeof(Dictionary<int, Settings>))] | ||||
| internal partial class SettingsDictionarySourceGenerationContext : JsonSerializerContext | ||||
| { | ||||
| } | ||||
							
								
								
									
										14
									
								
								Adaptation/FileHandlers/Priority/Startup.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Adaptation/FileHandlers/Priority/Startup.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| using Microsoft.Owin.Cors; | ||||
| using Nancy.Owin; | ||||
| using Owin; | ||||
|  | ||||
| public class Startup | ||||
| { | ||||
|  | ||||
|     public void Configuration(IAppBuilder app) | ||||
|     { | ||||
|         _ = app.UseCors(CorsOptions.AllowAll); | ||||
|         _ = app.UseNancy(); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,262 @@ | ||||
| using log4net; | ||||
| using Nancy; | ||||
| using Nancy.Extensions; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.ObjectModel; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
|  | ||||
| #nullable enable | ||||
|  | ||||
| #pragma warning disable CA1822 | ||||
|  | ||||
| namespace Adaptation.FileHandlers.Priority; | ||||
|  | ||||
| public class WeightedShortestJobFirstModule : NancyModule | ||||
| { | ||||
|  | ||||
|     public WeightedShortestJobFirstModule() | ||||
|     { | ||||
|         Get("/api/v1/ado/", _ => | ||||
|         { | ||||
|             string json; | ||||
|             ILog log = LogManager.GetLogger(typeof(WeightedShortestJobFirstModule)); | ||||
|             log.Info($"Enter-{nameof(GetKeyValuePairs)}"); | ||||
|             try | ||||
|             { | ||||
|                 string query = Request.Url.Query; | ||||
|                 IDictionary<string, IEnumerable<string>> collection = Nancy.Helpers.HttpUtility.ParseQueryString(query).ToDictionary(); | ||||
|                 KeyValuePair<string, WorkItem>? workItem = GetWorkItem(collection); | ||||
|                 json = workItem is null ? string.Empty : JsonSerializer.Serialize(workItem, KeyValuePairStringWorkItemSourceGenerationContext.Default.KeyValuePairStringWorkItem); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 log.Fatal($"Exception-{nameof(GetKeyValuePairs)}{Environment.NewLine}{ex.Message}{Environment.NewLine}{Environment.NewLine}{ex.StackTrace}"); | ||||
|                 throw; | ||||
|             } | ||||
|             log.Info($"Return-{nameof(GetKeyValuePairs)}"); | ||||
|             return json; | ||||
|         }); | ||||
|         base.Post("/api/v1/ado/", _ => | ||||
|         { | ||||
|             Notification notification; | ||||
|             ILog log = LogManager.GetLogger(typeof(WeightedShortestJobFirstModule)); | ||||
|             log.Info($"Enter-{nameof(Post)}"); | ||||
|             try | ||||
|             { | ||||
|                 string body = Request.Body.AsString(); | ||||
|                 DynamicDictionary form = Request.Form; | ||||
|                 Dictionary<string, object> keyValuePairs = form.ToDictionary(); | ||||
|                 notification = GetNotification(body, keyValuePairs); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 log.Fatal($"Exception-{nameof(Post)}{Environment.NewLine}{ex.Message}{Environment.NewLine}{Environment.NewLine}{ex.StackTrace}"); | ||||
|                 throw; | ||||
|             } | ||||
|             log.Info($"Return-{nameof(Post)}"); | ||||
|             return notification.Time.ToString(); | ||||
|         }); | ||||
|     } | ||||
|  | ||||
|     private static Dictionary<string, string?> GetKeyValuePairs(IDictionary<string, IEnumerable<string>> collection) | ||||
|     { | ||||
|         Dictionary<string, string?> results = new(); | ||||
|         string[] array; | ||||
|         foreach (KeyValuePair<string, IEnumerable<string>> keyValuePair in collection) | ||||
|         { | ||||
|             array = keyValuePair.Value.ToArray(); | ||||
|             if (array.Length != 1) | ||||
|                 continue; | ||||
|             if (array.Length == 1 && array[0] == "null") | ||||
|                 results.Add(keyValuePair.Key, null); | ||||
|             else | ||||
|                 results.Add(keyValuePair.Key, array[0]); | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     internal static Notification GetNotification(string body, Dictionary<string, object> keyValuePairs) | ||||
|     { | ||||
|         Notification result; | ||||
|         if (FileRead.Queue is null) | ||||
|             throw new NullReferenceException(nameof(FileRead.Queue)); | ||||
|         if (FileRead.Settings is null) | ||||
|             throw new NullReferenceException(nameof(FileRead.Settings)); | ||||
|         if (FileRead.WorkItems is null) | ||||
|             throw new NullReferenceException(nameof(FileRead.WorkItems)); | ||||
|         string? json; | ||||
|         if (!string.IsNullOrEmpty(body) && body[0] == '{') | ||||
|         { | ||||
|             File.WriteAllText(".json", body); | ||||
|             result = JsonSerializer.Deserialize(body, NotificationSourceGenerationContext.Default.Notification) ?? throw new NullReferenceException(); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             json = JsonSerializer.Serialize(keyValuePairs); | ||||
|             File.WriteAllText(".json", json); | ||||
|             result = JsonSerializer.Deserialize(json, NotificationSourceGenerationContext.Default.Notification) ?? throw new NullReferenceException(); | ||||
|         } | ||||
|         if (!string.IsNullOrEmpty(result.Id)) | ||||
|             FileWriteAllText(FileRead.Settings, result); | ||||
|         json = PopulatedWorkItemsAndGetJson(FileRead.Settings, FileRead.WorkItems); | ||||
|         if (!string.IsNullOrEmpty(json)) | ||||
|             WriteJson(FileRead.Settings, json); | ||||
|         if (!string.IsNullOrEmpty(result.SessionId)) | ||||
|         { | ||||
|             string key = GetKey(result); | ||||
|             Queue<KeyValuePair<string, WorkItem>>? queue; | ||||
|             lock (FileRead.Queue) | ||||
|             { | ||||
|                 if (!FileRead.Queue.TryGetValue(key, out queue)) | ||||
|                 { | ||||
|                     FileRead.Queue.Add(key, new()); | ||||
|                     if (!FileRead.Queue.TryGetValue(key, out queue)) | ||||
|                         throw new Exception(); | ||||
|                 } | ||||
|             } | ||||
|             WorkItem? workItem = GetWorkItem(FileRead.WorkItems, result); | ||||
|             if (workItem is not null) | ||||
|             { | ||||
|                 lock (FileRead.Queue) | ||||
|                 { | ||||
|                     foreach (KeyValuePair<string, Queue<KeyValuePair<string, WorkItem>>> keyValuePair in FileRead.Queue) | ||||
|                         keyValuePair.Value.Enqueue(new(result.Page, workItem)); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     internal static KeyValuePair<string, WorkItem>? GetWorkItem(IDictionary<string, IEnumerable<string>> collection) | ||||
|     { | ||||
|         KeyValuePair<string, WorkItem>? result; | ||||
|         Dictionary<string, string?> keyValuePairs = GetKeyValuePairs(collection); | ||||
|         Notification notification = Notification.Get(keyValuePairs); | ||||
|         if (FileRead.Queue is null) | ||||
|             result = null; | ||||
|         else | ||||
|         { | ||||
|             Queue<KeyValuePair<string, WorkItem>>? queue; | ||||
|             string key = GetKey(notification); | ||||
|             lock (FileRead.Queue) | ||||
|             { | ||||
|                 if (!FileRead.Queue.TryGetValue(key, out queue)) | ||||
|                 { | ||||
|                     FileRead.Queue.Add(key, new()); | ||||
|                     if (!FileRead.Queue.TryGetValue(key, out queue)) | ||||
|                         throw new Exception(); | ||||
|                 } | ||||
|                 result = queue.Count == 0 ? null : queue.Dequeue(); | ||||
|             } | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     private static string GetKey(Notification notification) => | ||||
|         $"{notification.SessionId}-{notification.MachineId}-{notification.Username}"; | ||||
|  | ||||
|     private static void FileWriteAllText(Settings settings, Notification notification) | ||||
|     { | ||||
|         if (string.IsNullOrEmpty(notification.Id)) | ||||
|             throw new NullReferenceException(nameof(notification.Id)); | ||||
|         string json = JsonSerializer.Serialize(notification, NotificationSourceGenerationContext.Default.Notification); | ||||
|         string directory = Path.Combine(settings.SourceFileLocation, notification.Page, notification.Id.ToString()); | ||||
|         if (!Directory.Exists(directory)) | ||||
|             _ = Directory.CreateDirectory(directory); | ||||
|         string checkFile = Path.Combine(directory, $"{notification.Time}.json"); | ||||
|         File.WriteAllText(checkFile, json); | ||||
|     } | ||||
|  | ||||
|     internal static string? PopulatedWorkItemsAndGetJson(Settings settings, Dictionary<int, WorkItem> workItems) | ||||
|     { | ||||
|         string? result = null; | ||||
|         ReadOnlyDictionary<int, WorkItem?> keyValuePairs = WorkItem.GetKeyValuePairs(settings); | ||||
|         int useCount = (from l in keyValuePairs where l.Value.CostOfDelay is not null select true).Count(); | ||||
|         double prioritySize = useCount / settings.Priorities; | ||||
|         double priorityGroupSize = useCount / settings.PriorityGroups; | ||||
|         WorkItem[] sorted = (from l in keyValuePairs | ||||
|                              where l.Value is not null | ||||
|                              orderby l.Value.Site is not null, | ||||
|                                      l.Value.Site descending, | ||||
|                                      l.Value.CostOfDelay is not null, | ||||
|                                      l.Value.CostOfDelay descending, | ||||
|                                      l.Value.BusinessValue?.FibonacciAverage is not null, | ||||
|                                      l.Value.BusinessValue?.FibonacciAverage descending, | ||||
|                                      l.Key | ||||
|                              select l.Value).ToArray(); | ||||
|         lock (workItems) | ||||
|         { | ||||
|             int j = 0; | ||||
|             WorkItem w; | ||||
|             double value; | ||||
|             int lastId = -1; | ||||
|             int? sortBeforeId; | ||||
|             WorkItem workItem; | ||||
|             int? sortPriority; | ||||
|             workItems.Clear(); | ||||
|             int? sortPriorityGroup; | ||||
|             for (int i = 0; i < sorted.Length; i++) | ||||
|             { | ||||
|                 w = sorted[i]; | ||||
|                 if (w.CostOfDelay is null) | ||||
|                 { | ||||
|                     sortBeforeId = null; | ||||
|                     sortPriority = null; | ||||
|                     sortPriorityGroup = null; | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     j += 1; | ||||
|                     sortBeforeId = lastId; | ||||
|                     value = (j / prioritySize) + 1; | ||||
|                     sortPriority = (int)Math.Floor(value); | ||||
|                     if (sortPriority > settings.Priorities) | ||||
|                         sortPriority = settings.Priorities; | ||||
|                     value = (j / priorityGroupSize) + 1; | ||||
|                     sortPriorityGroup = (int)Math.Floor(value); | ||||
|                     if (sortPriorityGroup > settings.PriorityGroups) | ||||
|                         sortPriorityGroup = settings.PriorityGroups; | ||||
|                 } | ||||
|                 workItem = WorkItem.GetWorkItem(w, i, sortBeforeId, sortPriority, sortPriorityGroup); | ||||
|                 workItems.Add(workItem.Id, workItem); | ||||
|                 lastId = w.Id; | ||||
|             } | ||||
|             result = JsonSerializer.Serialize(workItems, WorkItemDictionarySourceGenerationContext.Default.DictionaryInt32WorkItem); | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     private static WorkItem? GetWorkItem(Dictionary<int, WorkItem> workItems, Notification notification) | ||||
|     { | ||||
|         WorkItem? result; | ||||
|         if (string.IsNullOrEmpty(notification.Id) || !int.TryParse(notification.Id, out int id)) | ||||
|             result = null; | ||||
|         else | ||||
|         { | ||||
|             lock (workItems) | ||||
|             { | ||||
|                 if (!workItems.TryGetValue(id, out result)) | ||||
|                     throw new Exception(); | ||||
|             } | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     internal static void WriteJson(Settings settings, string json) | ||||
|     { | ||||
|         string jsonFile = Path.Combine(settings.ParentDirectory, "{}.json"); | ||||
|         string jsonFileWith = Path.Combine(settings.ParentDirectory, "{[]}.json"); | ||||
|         string jsonOld = File.Exists(jsonFileWith) ? File.ReadAllText(jsonFileWith) : string.Empty; | ||||
|         if (json != jsonOld) | ||||
|         { | ||||
|             File.WriteAllText(jsonFileWith, json); | ||||
|             Dictionary<int, WorkItem> w = JsonSerializer.Deserialize(json.Replace($"\"{nameof(Aggregation.Notifications)}\":", "\"ignore\":"), WorkItemDictionarySourceGenerationContext.Default.DictionaryInt32WorkItem) ?? throw new Exception(); | ||||
|             json = JsonSerializer.Serialize(w, WorkItemDictionarySourceGenerationContext.Default.DictionaryInt32WorkItem); | ||||
|             File.WriteAllText(jsonFile, json); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										211
									
								
								Adaptation/FileHandlers/Priority/WorkItem.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								Adaptation/FileHandlers/Priority/WorkItem.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,211 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.ObjectModel; | ||||
| using System.Text.Json.Serialization; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.Priority; | ||||
|  | ||||
| #nullable enable | ||||
|  | ||||
| public class WorkItem | ||||
| { | ||||
|  | ||||
|     [JsonConstructor] | ||||
|     public WorkItem(double? costOfDelay, | ||||
|                     Aggregation? businessValue, | ||||
|                     Aggregation? effort, | ||||
|                     int id, | ||||
|                     int? sortBeforeId, | ||||
|                     int? sortPriority, | ||||
|                     int? sortPriorityGroup, | ||||
|                     Aggregation? riskReductionOpportunityEnablement, | ||||
|                     string? site, | ||||
|                     int? sortOrder, | ||||
|                     Aggregation? timeCriticality, | ||||
|                     double? weightedShortestJobFirst) | ||||
|     { | ||||
|         CostOfDelay = costOfDelay; | ||||
|         BusinessValue = businessValue; | ||||
|         Effort = effort; | ||||
|         Id = id; | ||||
|         Site = site; | ||||
|         SortBeforeId = sortBeforeId; | ||||
|         SortPriority = sortPriority; | ||||
|         SortPriorityGroup = sortPriorityGroup; | ||||
|         RiskReductionOpportunityEnablement = riskReductionOpportunityEnablement; | ||||
|         SortOrder = sortOrder; | ||||
|         TimeCriticality = timeCriticality; | ||||
|         WeightedShortestJobFirst = weightedShortestJobFirst; | ||||
|     } | ||||
|  | ||||
|     const string _PageEffort = "effort"; | ||||
|     const string _PageTimeCriticality = "time"; | ||||
|     const string _PageBusinessValue = "business"; | ||||
|     const string _PageRiskReductionOpportunityEnablement = "risk"; | ||||
|  | ||||
|     public double? CostOfDelay { get; } // [JsonPropertyName("CostOfDelay")] | ||||
|     public Aggregation? BusinessValue { get; } // [JsonPropertyName("BusinessValue")] | ||||
|     public Aggregation? Effort { get; } // [JsonPropertyName("Effort")] | ||||
|     public int Id { get; } // [JsonPropertyName("Id")] | ||||
|     public string? Site { get; } // [JsonPropertyName("Site")] | ||||
|     public int? SortBeforeId { get; } // [JsonPropertyName("SortBeforeId")] | ||||
|     public int? SortPriority { get; } // [JsonPropertyName("SortPriority")] | ||||
|     public int? SortPriorityGroup { get; } // [JsonPropertyName("SortPriorityGroup")] | ||||
|     public Aggregation? RiskReductionOpportunityEnablement { get; } // [JsonPropertyName("RiskReductionOpportunityEnablement")] | ||||
|     public int? SortOrder { get; } // [JsonPropertyName("SortOrder")] | ||||
|     public Aggregation? TimeCriticality { get; } // [JsonPropertyName("TimeCriticality")] | ||||
|     public double? WeightedShortestJobFirst { get; } // [JsonPropertyName("WeightedShortestJobFirst")] | ||||
|  | ||||
|     internal static WorkItem GetWorkItem(WorkItem workItem, int i, int? sortBeforeId, int? sortPriority, int? sortPriorityGroup) => | ||||
|         new(workItem.CostOfDelay, | ||||
|             workItem.BusinessValue, | ||||
|             workItem.Effort, | ||||
|             workItem.Id, | ||||
|             sortBeforeId, | ||||
|             sortPriority, | ||||
|             sortPriorityGroup, | ||||
|             workItem.RiskReductionOpportunityEnablement, | ||||
|             workItem.Site, | ||||
|             i, | ||||
|             workItem.TimeCriticality, | ||||
|             workItem.WeightedShortestJobFirst); | ||||
|  | ||||
|     private static string? GetSite(Aggregation? effort, Aggregation? businessValue, Aggregation? timeCriticality, Aggregation? riskReductionOpportunityEnablement) | ||||
|     { | ||||
|         string? result = null; | ||||
|         if (result is null && effort is not null) | ||||
|         { | ||||
|             foreach (Notification notification in effort.Notifications) | ||||
|             { | ||||
|                 if (notification.Site is not null) | ||||
|                 { | ||||
|                     result = notification.Site; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (result is null && businessValue is not null) | ||||
|         { | ||||
|             foreach (Notification notification in businessValue.Notifications) | ||||
|             { | ||||
|                 if (notification.Site is not null) | ||||
|                 { | ||||
|                     result = notification.Site; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (result is null && timeCriticality is not null) | ||||
|         { | ||||
|             foreach (Notification notification in timeCriticality.Notifications) | ||||
|             { | ||||
|                 if (notification.Site is not null) | ||||
|                 { | ||||
|                     result = notification.Site; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (result is null && riskReductionOpportunityEnablement is not null) | ||||
|         { | ||||
|             foreach (Notification notification in riskReductionOpportunityEnablement.Notifications) | ||||
|             { | ||||
|                 if (notification.Site is not null) | ||||
|                 { | ||||
|                     result = notification.Site; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     internal static ReadOnlyDictionary<int, WorkItem?> GetWorkItems(Settings settings, ReadOnlyDictionary<string, ReadOnlyDictionary<int, Aggregation>> keyValuePairs) | ||||
|     { | ||||
|         Dictionary<int, WorkItem?> results = new(); | ||||
|         string? site; | ||||
|         WorkItem? workItem; | ||||
|         double? costOfDelay; | ||||
|         Aggregation? effort; | ||||
|         List<int> ids = new(); | ||||
|         Aggregation? businessValue; | ||||
|         Aggregation? timeCriticality; | ||||
|         double? weightedShortestJobFirst; | ||||
|         Aggregation? riskReductionOpportunityEnablement; | ||||
|         Dictionary<int, Aggregation?> effortCollection = new(); | ||||
|         Dictionary<int, Aggregation?> businessValueCollection = new(); | ||||
|         Dictionary<int, Aggregation?> timeCriticalityCollection = new(); | ||||
|         Dictionary<int, Aggregation?> riskReductionOpportunityEnablementCollection = new(); | ||||
|         foreach (KeyValuePair<string, ReadOnlyDictionary<int, Aggregation>> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             foreach (KeyValuePair<int, Aggregation> keyValue in keyValuePair.Value) | ||||
|             { | ||||
|                 if (!ids.Contains(keyValue.Key)) | ||||
|                     ids.Add(keyValue.Key); | ||||
|                 if (keyValuePair.Key == _PageEffort) | ||||
|                     effortCollection.Add(keyValue.Key, keyValue.Value); | ||||
|                 else if (keyValuePair.Key == _PageTimeCriticality) | ||||
|                     timeCriticalityCollection.Add(keyValue.Key, keyValue.Value); | ||||
|                 else if (keyValuePair.Key == _PageBusinessValue) | ||||
|                     businessValueCollection.Add(keyValue.Key, keyValue.Value); | ||||
|                 else if (keyValuePair.Key == _PageRiskReductionOpportunityEnablement) | ||||
|                     riskReductionOpportunityEnablementCollection.Add(keyValue.Key, keyValue.Value); | ||||
|                 else | ||||
|                     throw new NotImplementedException(); | ||||
|             } | ||||
|         } | ||||
|         foreach (int id in ids) | ||||
|         { | ||||
|             if (!effortCollection.TryGetValue(id, out effort)) | ||||
|                 effort = null; | ||||
|             if (!businessValueCollection.TryGetValue(id, out businessValue)) | ||||
|                 businessValue = null; | ||||
|             if (!timeCriticalityCollection.TryGetValue(id, out timeCriticality)) | ||||
|                 timeCriticality = null; | ||||
|             if (!riskReductionOpportunityEnablementCollection.TryGetValue(id, out riskReductionOpportunityEnablement)) | ||||
|                 riskReductionOpportunityEnablement = null; | ||||
|             site = GetSite(effort, businessValue, timeCriticality, riskReductionOpportunityEnablement); | ||||
|             costOfDelay = businessValue is null | ||||
|                 || timeCriticality is null | ||||
|                 || riskReductionOpportunityEnablement is null ? null : businessValue.FibonacciAverage | ||||
|                 + timeCriticality.FibonacciAverage | ||||
|                 + riskReductionOpportunityEnablement.FibonacciAverage; | ||||
|             weightedShortestJobFirst = costOfDelay is null || effort is null ? null : Math.Round(costOfDelay.Value / effort.FibonacciAverage, settings.Digits); | ||||
|             workItem = new(costOfDelay: costOfDelay, | ||||
|                            businessValue: businessValue, | ||||
|                            effort: effort, | ||||
|                            id: id, | ||||
|                            sortBeforeId: null, | ||||
|                            sortPriority: null, | ||||
|                            sortPriorityGroup: null, | ||||
|                            riskReductionOpportunityEnablement: riskReductionOpportunityEnablement, | ||||
|                            site: site, | ||||
|                            sortOrder: null, | ||||
|                            timeCriticality: timeCriticality, | ||||
|                            weightedShortestJobFirst: weightedShortestJobFirst); | ||||
|             results.Add(id, workItem); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     internal static ReadOnlyDictionary<int, WorkItem?> GetKeyValuePairs(Settings settings) | ||||
|     { | ||||
|         ReadOnlyDictionary<int, WorkItem?> results; | ||||
|         ReadOnlyDictionary<string, ReadOnlyDictionary<int, Aggregation>> keyValuePairs = Aggregation.GetKeyValuePairsAndWriteFiles(settings); | ||||
|         results = GetWorkItems(settings, keyValuePairs); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| [JsonSourceGenerationOptions(WriteIndented = true)] | ||||
| [JsonSerializable(typeof(Dictionary<int, WorkItem>))] | ||||
| internal partial class WorkItemDictionarySourceGenerationContext : JsonSerializerContext | ||||
| { | ||||
| } | ||||
|  | ||||
| [JsonSourceGenerationOptions(WriteIndented = true)] | ||||
| [JsonSerializable(typeof(KeyValuePair<string, WorkItem>))] | ||||
| internal partial class KeyValuePairStringWorkItemSourceGenerationContext : JsonSerializerContext | ||||
| { | ||||
| } | ||||
| @ -1,168 +0,0 @@ | ||||
| using Adaptation.Eaf.Management.ConfigurationData.CellAutomation; | ||||
| using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration; | ||||
| using Adaptation.Shared; | ||||
| using Adaptation.Shared.Duplicator; | ||||
| using Adaptation.Shared.Methods; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.Processed; | ||||
|  | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
|  | ||||
|     private readonly string _JobIdParentDirectory; | ||||
|     private readonly string _JobIdProcessParentDirectory; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
|         _NullData = string.Empty; | ||||
|         _Logistics = new(this); | ||||
|         if (_FileParameter is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (_ModelObjectParameterDefinitions is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (!_IsDuplicator) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         _JobIdParentDirectory = GetJobIdParentDirectory(_FileConnectorConfiguration.SourceFileLocation); | ||||
|         _JobIdProcessParentDirectory = GetJobIdParentDirectory(_FileConnectorConfiguration.TargetFileLocation); | ||||
|     } | ||||
|  | ||||
|     void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) | ||||
|     { | ||||
|         bool isErrorFile = exception is not null; | ||||
|         if (!isErrorFile && !string.IsNullOrEmpty(_Logistics.ReportFullPath)) | ||||
|         { | ||||
|             FileInfo fileInfo = new(_Logistics.ReportFullPath); | ||||
|             if (fileInfo.Exists && fileInfo.LastWriteTime < fileInfo.CreationTime) | ||||
|                 File.SetLastWriteTime(_Logistics.ReportFullPath, fileInfo.CreationTime); | ||||
|         } | ||||
|         Move(extractResults); | ||||
|     } | ||||
|  | ||||
|     void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null); | ||||
|  | ||||
|     string IFileRead.GetEventDescription() | ||||
|     { | ||||
|         string result = _Description.GetEventDescription(); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     List<string> IFileRead.GetHeaderNames() | ||||
|     { | ||||
|         List<string> results = _Description.GetHeaderNames(); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     string[] IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, string to, string from, string resolvedFileLocation, Exception exception) | ||||
|     { | ||||
|         string[] results = Move(extractResults, to, from, resolvedFileLocation, exception); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     JsonProperty[] IFileRead.GetDefault() | ||||
|     { | ||||
|         JsonProperty[] results = _Description.GetDefault(this, _Logistics); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Dictionary<string, string> IFileRead.GetDisplayNamesJsonElement() | ||||
|     { | ||||
|         Dictionary<string, string> results = _Description.GetDisplayNamesJsonElement(this); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     List<IDescription> IFileRead.GetDescriptions(IFileRead fileRead, List<Test> tests, IProcessData processData) | ||||
|     { | ||||
|         List<IDescription> results = _Description.GetDescriptions(fileRead, _Logistics, tests, processData); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.GetExtractResult(string reportFullPath, string eventName) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         if (string.IsNullOrEmpty(eventName)) | ||||
|             throw new Exception(); | ||||
|         _ReportFullPath = reportFullPath; | ||||
|         DateTime dateTime = DateTime.Now; | ||||
|         results = GetExtractResult(reportFullPath, dateTime); | ||||
|         if (results.Item3 is null) | ||||
|             results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]"), results.Item4); | ||||
|         if (results.Item3.Length > 0 && _IsEAFHosted) | ||||
|             WritePDSF(this, results.Item3); | ||||
|         UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.ReExtract() | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         List<string> headerNames = _Description.GetHeaderNames(); | ||||
|         Dictionary<string, string> keyValuePairs = _Description.GetDisplayNamesJsonElement(this); | ||||
|         results = ReExtract(this, headerNames, keyValuePairs); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private void DirectoryMove(string reportFullPath, DateTime dateTime, List<Description> descriptions) | ||||
|     { | ||||
|         if (dateTime == DateTime.MinValue) | ||||
|             throw new ArgumentNullException(nameof(dateTime)); | ||||
|         if (descriptions is null) | ||||
|             throw new ArgumentNullException(nameof(descriptions)); | ||||
|         FileInfo fileInfo = new(reportFullPath); | ||||
|         _ = _Logistics.Sequence.ToString(); | ||||
|         string jobIdDirectory = Path.Combine(_JobIdParentDirectory, _Logistics.JobID); | ||||
|         if (!Directory.Exists(jobIdDirectory)) | ||||
|             _ = Directory.CreateDirectory(jobIdDirectory); | ||||
|         string[] matchDirectories = GetInProcessDirectory(jobIdDirectory); | ||||
|         if (matchDirectories.Length != 1) | ||||
|             throw new Exception("Didn't find directory by logistics sequence"); | ||||
|         if (fileInfo.Exists && fileInfo.LastWriteTime < fileInfo.CreationTime) | ||||
|             File.SetLastWriteTime(reportFullPath, fileInfo.CreationTime); | ||||
|         if (_JobIdProcessParentDirectory is null) | ||||
|         { } | ||||
|         // OpenInsightMetrologyViewer.WSRequest wsRequest = new(this, _Logistics, descriptions); | ||||
|         // JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true }; | ||||
|         // string json = JsonSerializer.Serialize(wsRequest, wsRequest.GetType(), jsonSerializerOptions); | ||||
|         // string directoryName = $"{Path.GetFileName(matchDirectories[0]).Split(new string[] { logisticsSequence }, StringSplitOptions.None)[0]}{_Logistics.DateTimeFromSequence:yyyy-MM-dd_hh;mm_tt_}{DateTime.Now.Ticks - _Logistics.Sequence}"; | ||||
|         // string destinationJobIdDirectory = Path.Combine(_JobIdProcessParentDirectory, _Logistics.JobID, directoryName); | ||||
|         // string sequenceDirectory = Path.Combine(destinationJobIdDirectory, logisticsSequence); | ||||
|         // string jsonFileName = Path.Combine(sequenceDirectory, $"{Path.GetFileNameWithoutExtension(reportFullPath)}.json"); | ||||
|         // Directory.Move(matchDirectories[0], destinationJobIdDirectory); | ||||
|         // if (!Directory.Exists(sequenceDirectory)) | ||||
|         //     _ = Directory.CreateDirectory(sequenceDirectory); | ||||
|         // File.Copy(reportFullPath, Path.Combine(sequenceDirectory, Path.GetFileName(reportFullPath)), overwrite: true); | ||||
|         // File.WriteAllText(jsonFileName, json); | ||||
|     } | ||||
|  | ||||
|     private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath); | ||||
|         _Logistics = new Logistics(reportFullPath, pdsf.Item1); | ||||
|         SetFileParameterLotIDToLogisticsMID(); | ||||
|         JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf); | ||||
|         List<Description> descriptions = json.ProcessData.GetDescriptions(jsonElements); | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>()); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             DirectoryMove(reportFullPath, dateTime, descriptions); | ||||
|         else if (!_IsEAFHosted) | ||||
|         { | ||||
|             // OpenInsightMetrologyViewer.WSRequest wsRequest = new(this, _Logistics, descriptions); | ||||
|             // JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true }; | ||||
|             // string json = JsonSerializer.Serialize(wsRequest, wsRequest.GetType(), jsonSerializerOptions); | ||||
|             // string jsonFileName = Path.ChangeExtension(reportFullPath, ".json"); | ||||
|             // string historicalText = File.ReadAllText(jsonFileName); | ||||
|             // if (json != historicalText) | ||||
|             //     throw new Exception("File doesn't match historical!"); | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -1,132 +0,0 @@ | ||||
| using Adaptation.Eaf.Management.ConfigurationData.CellAutomation; | ||||
| using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration; | ||||
| using Adaptation.Shared; | ||||
| using Adaptation.Shared.Duplicator; | ||||
| using Adaptation.Shared.Methods; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.SPaCe; | ||||
|  | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
|         _NullData = string.Empty; | ||||
|         _Logistics = new(this); | ||||
|         if (_FileParameter is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (_ModelObjectParameterDefinitions is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (!_IsDuplicator) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|     } | ||||
|  | ||||
|     void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) | ||||
|     { | ||||
|         bool isErrorFile = exception is not null; | ||||
|         if (!isErrorFile && !string.IsNullOrEmpty(_Logistics.ReportFullPath)) | ||||
|         { | ||||
|             FileInfo fileInfo = new(_Logistics.ReportFullPath); | ||||
|             if (fileInfo.Exists && fileInfo.LastWriteTime < fileInfo.CreationTime) | ||||
|                 File.SetLastWriteTime(_Logistics.ReportFullPath, fileInfo.CreationTime); | ||||
|         } | ||||
|         Move(extractResults); | ||||
|     } | ||||
|  | ||||
|     void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null); | ||||
|  | ||||
|     string IFileRead.GetEventDescription() | ||||
|     { | ||||
|         string result = _Description.GetEventDescription(); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     List<string> IFileRead.GetHeaderNames() | ||||
|     { | ||||
|         List<string> results = _Description.GetHeaderNames(); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     string[] IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, string to, string from, string resolvedFileLocation, Exception exception) | ||||
|     { | ||||
|         string[] results = Move(extractResults, to, from, resolvedFileLocation, exception); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     JsonProperty[] IFileRead.GetDefault() | ||||
|     { | ||||
|         JsonProperty[] results = _Description.GetDefault(this, _Logistics); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Dictionary<string, string> IFileRead.GetDisplayNamesJsonElement() | ||||
|     { | ||||
|         Dictionary<string, string> results = _Description.GetDisplayNamesJsonElement(this); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     List<IDescription> IFileRead.GetDescriptions(IFileRead fileRead, List<Test> tests, IProcessData processData) | ||||
|     { | ||||
|         List<IDescription> results = _Description.GetDescriptions(fileRead, _Logistics, tests, processData); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.GetExtractResult(string reportFullPath, string eventName) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         if (string.IsNullOrEmpty(eventName)) | ||||
|             throw new Exception(); | ||||
|         _ReportFullPath = reportFullPath; | ||||
|         DateTime dateTime = DateTime.Now; | ||||
|         results = GetExtractResult(reportFullPath, dateTime); | ||||
|         if (results.Item3 is null) | ||||
|             results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]"), results.Item4); | ||||
|         if (results.Item3.Length > 0 && _IsEAFHosted) | ||||
|             WritePDSF(this, results.Item3); | ||||
|         UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.ReExtract() | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         List<string> headerNames = _Description.GetHeaderNames(); | ||||
|         Dictionary<string, string> keyValuePairs = _Description.GetDisplayNamesJsonElement(this); | ||||
|         results = ReExtract(this, headerNames, keyValuePairs); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private void FileCopy<T>(string reportFullPath, DateTime dateTime, List<T> descriptions) where T : Shared.Properties.IDescription | ||||
|     { | ||||
|         bool isDummyRun = false; | ||||
|         string successDirectory = string.Empty; | ||||
|         List<(Shared.Properties.IScopeInfo, string)> collection = new(); | ||||
|         string duplicateDirectory = _FileConnectorConfiguration.TargetFileLocation; | ||||
|         string duplicateFile = Path.Combine(duplicateDirectory, Path.GetFileName(reportFullPath)); | ||||
|         File.Copy(reportFullPath, duplicateFile, overwrite: true); | ||||
|         WaitForFileConsumption(dateTime, descriptions, isDummyRun, successDirectory, duplicateDirectory, collection, duplicateFile); | ||||
|     } | ||||
|  | ||||
|     private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath); | ||||
|         _Logistics = new Logistics(reportFullPath, pdsf.Item1); | ||||
|         SetFileParameterLotIDToLogisticsMID(); | ||||
|         JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf); | ||||
|         List<Shared.Properties.IDescription> descriptions = GetDuplicatorDescriptions(jsonElements); | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             FileCopy(reportFullPath, dateTime, descriptions); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>()); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -5,16 +5,20 @@ using Adaptation.Shared.Duplicator; | ||||
| using Adaptation.Shared.Methods; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.ObjectModel; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
| 
 | ||||
| namespace Adaptation.FileHandlers.OpenInsight; | ||||
| namespace Adaptation.FileHandlers.Violation; | ||||
| 
 | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
| 
 | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     private long? _TickOffset; | ||||
|     private readonly string _URL; | ||||
|     private readonly ReadOnlyCollection<string> _WorkItemTypes; | ||||
| 
 | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -26,19 +30,15 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (!_IsDuplicator) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         string cellInstanceNamed = string.Concat("CellInstance.", _EquipmentType); | ||||
|         _URL = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.URL"); | ||||
|         string workItemTypes = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.WorkItemTypes"); | ||||
|         _WorkItemTypes = new(workItemTypes.Split('|')); | ||||
|         if (_IsEAFHosted) | ||||
|             NestExistingFiles(_FileConnectorConfiguration); | ||||
|     } | ||||
| 
 | ||||
|     void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) | ||||
|     { | ||||
|         bool isErrorFile = exception is not null; | ||||
|         if (!isErrorFile && !string.IsNullOrEmpty(_Logistics.ReportFullPath)) | ||||
|         { | ||||
|             FileInfo fileInfo = new(_Logistics.ReportFullPath); | ||||
|             if (fileInfo.Exists && fileInfo.LastWriteTime < fileInfo.CreationTime) | ||||
|                 File.SetLastWriteTime(_Logistics.ReportFullPath, fileInfo.CreationTime); | ||||
|         } | ||||
|         Move(extractResults); | ||||
|     } | ||||
|     void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) => Move(extractResults); | ||||
| 
 | ||||
|     void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null); | ||||
| 
 | ||||
| @ -103,30 +103,24 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         return results; | ||||
|     } | ||||
| 
 | ||||
|     private static void SaveOpenInsightFile(string reportFullPath, DateTime dateTime, List<Description> descriptions, Test[] tests) | ||||
|     { | ||||
|         if (string.IsNullOrEmpty(reportFullPath)) | ||||
|             throw new ArgumentException($"'{nameof(reportFullPath)}' cannot be null or empty.", nameof(reportFullPath)); | ||||
|         if (dateTime == DateTime.MinValue) | ||||
|             throw new ArgumentNullException(nameof(dateTime)); | ||||
|         if (descriptions is null) | ||||
|             throw new ArgumentNullException(nameof(descriptions)); | ||||
|         if (tests is null) | ||||
|             throw new ArgumentNullException(nameof(tests)); | ||||
|     } | ||||
| 
 | ||||
|     private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath); | ||||
|         _Logistics = new Logistics(reportFullPath, pdsf.Item1); | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results = new(string.Empty, null, null, new List<FileInfo>()); | ||||
|         _TickOffset ??= 0; // new FileInfo(reportFullPath).LastWriteTime.Ticks - dateTime.Ticks; | ||||
|         string[] lines = new string[] { string.Empty, "NUM_DATA_ROWS", $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};" }; | ||||
|         ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines); | ||||
|         _Logistics = new Logistics(reportFullPath, processDataStandardFormat); | ||||
|         SetFileParameterLotIDToLogisticsMID(); | ||||
|         JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf); | ||||
|         List<Description> descriptions = json.ProcessData.GetDescriptions(jsonElements); | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             SaveOpenInsightFile(reportFullPath, dateTime, descriptions, tests); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>()); | ||||
|         if (_Logistics.FileInfo.Length < _MinFileLength) | ||||
|             results.Item4.Add(_Logistics.FileInfo); | ||||
|         else | ||||
|         { | ||||
|             IProcessData iProcessData = new ProcessData(this, _Logistics, _FileConnectorConfiguration.TargetFileLocation, _URL, _WorkItemTypes, results.Item4); | ||||
|             if (iProcessData.Details.Count == 0) | ||||
|                 results = new(string.Concat("B) No Data - ", dateTime.Ticks), Array.Empty<Test>(), Array.Empty<JsonElement>(), results.Item4); | ||||
|             else | ||||
|                 results = iProcessData.GetResults(this, _Logistics, results.Item4); | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
| 
 | ||||
							
								
								
									
										630
									
								
								Adaptation/FileHandlers/Violation/ProcessData.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										630
									
								
								Adaptation/FileHandlers/Violation/ProcessData.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,630 @@ | ||||
| using Adaptation.FileHandlers.json.WorkItems; | ||||
| using Adaptation.Shared; | ||||
| using Adaptation.Shared.Duplicator; | ||||
| using Adaptation.Shared.Methods; | ||||
| using log4net; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.ObjectModel; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
| using System.Text.Json.Serialization; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.Violation; | ||||
|  | ||||
| #nullable enable | ||||
|  | ||||
| public class ProcessData : IProcessData | ||||
| { | ||||
|  | ||||
|     private readonly List<object> _Details; | ||||
|  | ||||
|     List<object> Shared.Properties.IProcessData.Details => _Details; | ||||
|  | ||||
|     private readonly ILog _Log; | ||||
|  | ||||
|     string IProcessData.GetCurrentReactor(IFileRead fileRead, Logistics logistics, Dictionary<string, string> reactors) => | ||||
|         throw new Exception(string.Concat("See ", nameof(WriteFiles))); | ||||
|  | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IProcessData.GetResults(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection) => | ||||
|         new(logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), fileInfoCollection); | ||||
|  | ||||
|     private static int GetState(WorkItem workItem) => | ||||
|         workItem.State switch | ||||
|         { | ||||
|             "New" => 1, | ||||
|             "Active" => 2, | ||||
|             "Resolved" => 3, | ||||
|             "Closed" => 4, | ||||
|             "Removed" => 5, | ||||
|             _ => 8 | ||||
|         }; | ||||
|  | ||||
|     public ProcessData(IFileRead fileRead, Logistics logistics, string targetFileLocation, string url, ReadOnlyCollection<string> workItemTypes, List<FileInfo> fileInfoCollection) | ||||
|     { | ||||
|         if (fileRead.IsEAFHosted) | ||||
|         { } | ||||
|         _Details = new List<object>(); | ||||
|         _Log = LogManager.GetLogger(typeof(ProcessData)); | ||||
|         WriteFiles(fileRead, logistics, targetFileLocation, url, fileInfoCollection, workItemTypes); | ||||
|     } | ||||
|  | ||||
|     private void WriteFiles(IFileRead fileRead, Logistics logistics, string destinationDirectory, string url, List<FileInfo> fileInfoCollection, ReadOnlyCollection<string> __) | ||||
|     { | ||||
|         if (!Directory.Exists(destinationDirectory)) | ||||
|             _ = Directory.CreateDirectory(destinationDirectory); | ||||
|         string json = File.ReadAllText(logistics.ReportFullPath); | ||||
|         // WorkItem[]? workItems = JsonSerializer.Deserialize<WorkItem[]>(json); | ||||
|         // if (workItems is null) | ||||
|         //     throw new Exception(nameof(workItems)); | ||||
|         JsonElement[]? jsonElements = JsonSerializer.Deserialize<JsonElement[]>(json); | ||||
|         if (jsonElements is null) | ||||
|             throw new Exception(nameof(jsonElements)); | ||||
|         WorkItem? workItem; | ||||
|         List<WorkItem> workItems = new(); | ||||
|         foreach (JsonElement jsonElement in jsonElements) | ||||
|         { | ||||
|             workItem = JsonSerializer.Deserialize<WorkItem>(jsonElement.ToString()); | ||||
|             if (workItem is null) | ||||
|                 continue; | ||||
|             workItems.Add(workItem); | ||||
|         } | ||||
|         List<char> spaces = new(); | ||||
|         bool keepRelations = false; | ||||
|         List<string> lines = new(); | ||||
|         List<string> messages = new(); | ||||
|         ReadOnlyCollection<Record> results; | ||||
|         ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations); | ||||
|         ReadOnlyCollection<Record> records = new(keyValuePairs.Values.ToArray()); | ||||
|         ReadOnlyCollection<string> bugUserStoryWorkItemTypes = new(new string[] { "Bug", "User Story" }); | ||||
|         ReadOnlyCollection<string> bugUserStoryTaskWorkItemTypes = new(new string[] { "Bug", "User Story", "Task" }); | ||||
|         { | ||||
|             lines.Clear(); | ||||
|             string workItemType = "Feature"; | ||||
|             lines.Add($"# {nameof(FeatureCheckIterationPath122508)}"); | ||||
|             lines.Add(string.Empty); | ||||
|             results = FeatureCheckIterationPath122508(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType); | ||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-122508"); | ||||
|             _Details.Add(results); | ||||
|         } | ||||
|         { | ||||
|             lines.Clear(); | ||||
|             string workItemType = "Feature"; | ||||
|             lines.Add($"# {nameof(FeatureCheckTag122514)}"); | ||||
|             lines.Add(string.Empty); | ||||
|             results = FeatureCheckTag122514(url, lines, bugUserStoryWorkItemTypes, keyValuePairs, workItemType); | ||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-122514"); | ||||
|             _Details.Add(results); | ||||
|         } | ||||
|         { | ||||
|             lines.Clear(); | ||||
|             string workItemType = "Feature"; | ||||
|             lines.Add($"# {nameof(FeatureCheckPriority126169)}"); | ||||
|             lines.Add(string.Empty); | ||||
|             results = FeatureCheckPriority126169(url, lines, bugUserStoryWorkItemTypes, keyValuePairs, workItemType); | ||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-126169"); | ||||
|             _Details.Add(results); | ||||
|         } | ||||
|         { | ||||
|             lines.Clear(); | ||||
|             string workItemType = "Feature"; | ||||
|             lines.Add($"# {nameof(FeatureCheckState123066)}"); | ||||
|             lines.Add(string.Empty); | ||||
|             results = FeatureCheckState123066(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType); | ||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-123066"); | ||||
|             _Details.Add(results); | ||||
|         } | ||||
|         { | ||||
|             lines.Clear(); | ||||
|             string workItemType = "Feature"; | ||||
|             lines.Add($"# {nameof(FeatureCheckState123067)}"); | ||||
|             lines.Add(string.Empty); | ||||
|             results = FeatureCheckState123067(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType); | ||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-123067"); | ||||
|             _Details.Add(results); | ||||
|         } | ||||
|         { | ||||
|             lines.Clear(); | ||||
|             string workItemType = "Feature"; | ||||
|             lines.Add($"# {nameof(FeatureCheckStart122517)}"); | ||||
|             lines.Add(string.Empty); | ||||
|             results = FeatureCheckStart122517(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType); | ||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-122517"); | ||||
|             _Details.Add(results); | ||||
|         } | ||||
|         if (messages.Count > 0) | ||||
|             throw new Exception($"{messages.Count}{Environment.NewLine}{string.Join(Environment.NewLine, messages)}"); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyDictionary<int, Record> GetWorkItems(IEnumerable<WorkItem> workItems, bool keepRelations) | ||||
|     { | ||||
|         ReadOnlyDictionary<int, Record> results; | ||||
|         Dictionary<int, WorkItem> keyValuePairs = new(); | ||||
|         foreach (WorkItem workItem in workItems) | ||||
|             keyValuePairs.Add(workItem.Id, workItem); | ||||
|         results = GetKeyValuePairs(new(keyValuePairs), keepRelations); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyDictionary<int, Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, bool keepRelations) | ||||
|     { | ||||
|         Dictionary<int, Record> results = new(); | ||||
|         Record record; | ||||
|         List<bool> nests = new(); | ||||
|         WorkItem? parentWorkItem; | ||||
|         ReadOnlyCollection<Record> childRecords; | ||||
|         ReadOnlyCollection<Record> relatedRecords; | ||||
|         ReadOnlyCollection<Record> successorRecords; | ||||
|         foreach (KeyValuePair<int, WorkItem> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             nests.Clear(); | ||||
|             if (keyValuePair.Value.Parent is null) | ||||
|                 parentWorkItem = null; | ||||
|             else | ||||
|                 _ = keyValuePairs.TryGetValue(keyValuePair.Value.Parent.Value, out parentWorkItem); | ||||
|             try | ||||
|             { | ||||
|                 childRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Child", nests, keepRelations); // Forward | ||||
|                 relatedRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Related", nests, keepRelations); // Related | ||||
|                 successorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Successor", nests, keepRelations); // Forward | ||||
|                 // predecessorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Predecessor", nests, keepRelations); // Reverse | ||||
|                 record = Record.Get(keyValuePair.Value, parentWorkItem, childRecords, relatedRecords, successorRecords, keepRelations); | ||||
|             } | ||||
|             catch (Exception) | ||||
|             { | ||||
|                 Dictionary<string, string>? tag = null; | ||||
|                 record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>(), tag); | ||||
|             } | ||||
|             results.Add(keyValuePair.Key, record); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> FeatureCheckIterationPath122508(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         Record record; | ||||
|         List<string> violations = new(); | ||||
|         List<string> collection = new(); | ||||
|         ReadOnlyCollection<Record> records; | ||||
|         ReadOnlyCollection<Record> maxIterationPaths; | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             record = keyValuePair.Value; | ||||
|             if (record.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             if (!record.WorkItem.IterationPath.Contains('\\')) | ||||
|                 continue; | ||||
|             if (record.WorkItem.WorkItemType != workItemType) | ||||
|                 continue; | ||||
|             collection.Clear(); | ||||
|             violations.Clear(); | ||||
|             if (record.Children is null || record.Children.Length == 0) | ||||
|                 continue; | ||||
|             records = FilterChildren(workItemTypes, record); | ||||
|             maxIterationPaths = GetMaxIterationPaths122508(records); | ||||
|             foreach (Record r in maxIterationPaths) | ||||
|             { | ||||
|                 if (string.IsNullOrEmpty(r.WorkItem.IterationPath) || record.WorkItem.IterationPath == r.WorkItem.IterationPath) | ||||
|                     continue; | ||||
|                 violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.IterationPath};"); | ||||
|             } | ||||
|             if (violations.Count > 0) | ||||
|             { | ||||
|                 collection.Insert(0, string.Empty); | ||||
|                 collection.Insert(0, $"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}"); | ||||
|                 lines.AddRange(collection); | ||||
|                 violations.Insert(0, $"<a target='_blank' href='{url}{record.WorkItem.Id}'>IterationPath</a>:{record.WorkItem.IterationPath};"); | ||||
|                 results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations))); | ||||
|             } | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> GetMaxIterationPaths122508(ReadOnlyCollection<Record> records) | ||||
|     { | ||||
|         List<Record> results; | ||||
|         List<Record>? collection; | ||||
|         Dictionary<string, List<Record>> keyValuePairs = new(); | ||||
|         foreach (Record record in records) | ||||
|         { | ||||
|             if (!keyValuePairs.TryGetValue(record.WorkItem.IterationPath, out collection)) | ||||
|             { | ||||
|                 keyValuePairs.Add(record.WorkItem.IterationPath, new()); | ||||
|                 if (!keyValuePairs.TryGetValue(record.WorkItem.IterationPath, out collection)) | ||||
|                     throw new Exception(); | ||||
|  | ||||
|             } | ||||
|             collection.Add(record); | ||||
|         } | ||||
|         string? max = keyValuePairs.Keys.Max(); | ||||
|         results = string.IsNullOrEmpty(max) ? new() : keyValuePairs[max]; | ||||
|         return results.AsReadOnly(); | ||||
|     } | ||||
|  | ||||
|     private static void WriteFiles(IFileRead fileRead, string destinationDirectory, List<FileInfo> fileInfoCollection, ReadOnlyCollection<string> lines, string _, ReadOnlyCollection<Record> records, string fileName) | ||||
|     { | ||||
|         string markdown = string.Join(Environment.NewLine, lines); | ||||
|         string markdownFile = Path.Combine(destinationDirectory, $"{fileName}.md"); | ||||
|         string markdownOld = !File.Exists(markdownFile) ? string.Empty : File.ReadAllText(markdownFile); | ||||
|         if (markdown != markdownOld) | ||||
|             File.WriteAllText(markdownFile, markdown); | ||||
|         if (!fileRead.IsEAFHosted) | ||||
|             fileInfoCollection.Add(new(markdownFile)); | ||||
|         string html = CommonMark.CommonMarkConverter.Convert(markdown).Replace("<a href", "<a target='_blank' href"); | ||||
|         string htmlFile = Path.Combine(destinationDirectory, $"{fileName}.html"); | ||||
|         string htmlOld = !File.Exists(htmlFile) ? string.Empty : File.ReadAllText(htmlFile); | ||||
|         if (html != htmlOld) | ||||
|             File.WriteAllText(htmlFile, html); | ||||
|         if (!fileRead.IsEAFHosted) | ||||
|             fileInfoCollection.Add(new(htmlFile)); | ||||
|         string json = JsonSerializer.Serialize(records, new JsonSerializerOptions() { WriteIndented = true }); | ||||
|         string jsonFile = Path.Combine(destinationDirectory, $"{fileName}.json"); | ||||
|         string jsonOld = !File.Exists(jsonFile) ? string.Empty : File.ReadAllText(jsonFile); | ||||
|         if (json != jsonOld) | ||||
|             File.WriteAllText(jsonFile, json); | ||||
|         if (!fileRead.IsEAFHosted) | ||||
|             fileInfoCollection.Add(new(jsonFile)); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> FeatureCheckTag122514(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         Record record; | ||||
|         List<string> collection = new(); | ||||
|         List<string> violations = new(); | ||||
|         ReadOnlyCollection<Record> records; | ||||
|         ReadOnlyCollection<Record> recordsNotMatching; | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             record = keyValuePair.Value; | ||||
|             if (record.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             if (record.WorkItem.WorkItemType != workItemType) | ||||
|                 continue; | ||||
|             collection.Clear(); | ||||
|             violations.Clear(); | ||||
|             if (record.Children is null || record.Children.Length == 0) | ||||
|                 continue; | ||||
|             if (string.IsNullOrEmpty(record.WorkItem.Tags)) | ||||
|                 recordsNotMatching = new(new Record[] { record }); | ||||
|             else | ||||
|             { | ||||
|                 records = FilterChildren(workItemTypes, record); | ||||
|                 recordsNotMatching = GetWorkItemsNotMatching122514(record, records); | ||||
|                 if (!string.IsNullOrEmpty(record.WorkItem.Tags) && recordsNotMatching.Count == 0) | ||||
|                     continue; | ||||
|             } | ||||
|             collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}"); | ||||
|             collection.Add(string.Empty); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 collection.Add($"- [ ] [{r.WorkItem}]({url}{r.WorkItem}) {nameof(record.WorkItem.Tags)} != {record.WorkItem.Tags}"); | ||||
|             collection.Add(string.Empty); | ||||
|             lines.AddRange(collection); | ||||
|             violations.Add($"<a target='_blank' href='{url}{record.WorkItem.Id}'>Tag</a>:{record.WorkItem.Tags};"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.Tags};"); | ||||
|             results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations))); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> FilterChildren(ReadOnlyCollection<string> workItemTypes, Record record) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         FilterChildren(workItemTypes, record, results); | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static void FilterChildren(ReadOnlyCollection<string> workItemTypes, Record record, List<Record> results) | ||||
|     { | ||||
|         if (record.Children is not null) | ||||
|         { | ||||
|             foreach (Record r in record.Children) | ||||
|             { | ||||
|                 if (!workItemTypes.Contains(r.WorkItem.WorkItemType)) | ||||
|                     continue; | ||||
|                 results.Add(r); | ||||
|                 FilterChildren(workItemTypes, r, results); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> GetWorkItemsNotMatching122514(Record record, ReadOnlyCollection<Record> records) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         string[] segments; | ||||
|         string[] parentTags = record.WorkItem.Tags.Split(';').Select(l => l.Trim()).ToArray(); | ||||
|         foreach (Record r in records) | ||||
|         { | ||||
|             segments = string.IsNullOrEmpty(r.WorkItem.Tags) ? Array.Empty<string>() : r.WorkItem.Tags.Split(';').Select(l => l.Trim()).ToArray(); | ||||
|             if (segments.Length > 0 && parentTags.Any(l => segments.Contains(l))) | ||||
|                 continue; | ||||
|             results.Add(r); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> FeatureCheckPriority126169(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         Record record; | ||||
|         List<string> collection = new(); | ||||
|         List<string> violations = new(); | ||||
|         ReadOnlyCollection<Record> records; | ||||
|         ReadOnlyCollection<Record> recordsNotMatching; | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             record = keyValuePair.Value; | ||||
|             if (record.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             if (record.WorkItem.WorkItemType != workItemType) | ||||
|                 continue; | ||||
|             collection.Clear(); | ||||
|             violations.Clear(); | ||||
|             if (record.Children is null || record.Children.Length == 0) | ||||
|                 continue; | ||||
|             records = FilterChildren(workItemTypes, record); | ||||
|             recordsNotMatching = GetWorkItemsNotMatching126169(record, records); | ||||
|             if (recordsNotMatching.Count == 0) | ||||
|                 continue; | ||||
|             collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}"); | ||||
|             collection.Add(string.Empty); | ||||
|             collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.Priority)} != {record.WorkItem.Priority}"); | ||||
|             collection.Add(string.Empty); | ||||
|             lines.AddRange(collection); | ||||
|             violations.Add($"<a target='_blank' href='{url}{record.WorkItem.Id}'>Priority</a>:{record.WorkItem.Priority};"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.Priority};"); | ||||
|             results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations))); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> GetWorkItemsNotMatching126169(Record record, ReadOnlyCollection<Record> records) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         foreach (Record r in records) | ||||
|         { | ||||
|             if (record.WorkItem.Priority is null) | ||||
|             { | ||||
|                 results.Add(record); | ||||
|                 break; | ||||
|             } | ||||
|             if (r.WorkItem.Priority == record.WorkItem.Priority.Value) | ||||
|                 continue; | ||||
|             results.Add(r); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> FeatureCheckState123066(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         Record record; | ||||
|         List<string> collection = new(); | ||||
|         List<string> violations = new(); | ||||
|         ReadOnlyCollection<Record> records; | ||||
|         ReadOnlyCollection<Record> recordsNotMatching; | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             record = keyValuePair.Value; | ||||
|             if (record.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             if (record.WorkItem.WorkItemType != workItemType) | ||||
|                 continue; | ||||
|             collection.Clear(); | ||||
|             violations.Clear(); | ||||
|             if (record.Children is null || record.Children.Length == 0) | ||||
|                 continue; | ||||
|             records = FilterChildren(workItemTypes, record); | ||||
|             recordsNotMatching = GetWorkItemsNotMatching123066(record, records); | ||||
|             if (recordsNotMatching.Count == 0) | ||||
|                 continue; | ||||
|             collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}"); | ||||
|             collection.Add(string.Empty); | ||||
|             collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.State)} != {record.WorkItem.State}"); | ||||
|             collection.Add(string.Empty); | ||||
|             lines.AddRange(collection); | ||||
|             violations.Add($"<a target='_blank' href='{url}{record.WorkItem.Id}'>State</a>:{record.WorkItem.State};"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.State};"); | ||||
|             results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations))); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> GetWorkItemsNotMatching123066(Record record, ReadOnlyCollection<Record> records) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         int check; | ||||
|         int state = GetState(record.WorkItem); | ||||
|         List<KeyValuePair<int, Record>> collection = new(); | ||||
|         foreach (Record r in records) | ||||
|         { | ||||
|             if (r.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             check = GetState(r.WorkItem); | ||||
|             if (check == state) | ||||
|                 continue; | ||||
|             collection.Add(new(check, r)); | ||||
|         } | ||||
|         if (collection.Count > 0) | ||||
|         { | ||||
|             KeyValuePair<int, Record>[] notNewState = (from l in collection where l.Value.WorkItem.State != "New" select l).ToArray(); | ||||
|             if (notNewState.Length == 0 && record.WorkItem.State is "New" or "Active") | ||||
|                 collection.Clear(); | ||||
|             else if (notNewState.Length > 0) | ||||
|             { | ||||
|                 int minimum = notNewState.Min(l => l.Key); | ||||
|                 if (minimum == state) | ||||
|                     collection.Clear(); | ||||
|                 else if (minimum == 1 && record.WorkItem.State == "New") | ||||
|                     collection.Clear(); | ||||
|                 else if (notNewState.Length > 0 && record.WorkItem.State == "Active") | ||||
|                     collection.Clear(); | ||||
|             } | ||||
|         } | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in collection.OrderByDescending(l => l.Key)) | ||||
|             results.Add(keyValuePair.Value); | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> FeatureCheckState123067(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         Record record; | ||||
|         List<string> collection = new(); | ||||
|         List<string> violations = new(); | ||||
|         ReadOnlyCollection<Record> records; | ||||
|         ReadOnlyCollection<Record> recordsNotMatching; | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             record = keyValuePair.Value; | ||||
|             if (record.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             if (record.WorkItem.WorkItemType != workItemType) | ||||
|                 continue; | ||||
|             collection.Clear(); | ||||
|             violations.Clear(); | ||||
|             if (record.Children is null || record.Children.Length == 0) | ||||
|                 continue; | ||||
|             records = FilterChildren(workItemTypes, record); | ||||
|             recordsNotMatching = GetWorkItemsNotMatching123067(record, records); | ||||
|             if (recordsNotMatching.Count == 0) | ||||
|                 continue; | ||||
|             collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}"); | ||||
|             collection.Add(string.Empty); | ||||
|             collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.State)} != {record.WorkItem.State}"); | ||||
|             collection.Add(string.Empty); | ||||
|             lines.AddRange(collection); | ||||
|             violations.Add($"<a target='_blank' href='{url}{record.WorkItem.Id}'>State</a>:{record.WorkItem.State};"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.State};"); | ||||
|             results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations))); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> GetWorkItemsNotMatching123067(Record record, ReadOnlyCollection<Record> records) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         int check; | ||||
|         int state = GetState(record.WorkItem); | ||||
|         List<KeyValuePair<int, Record>> collection = new(); | ||||
|         foreach (Record r in records) | ||||
|         { | ||||
|             if (r.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             check = GetState(r.WorkItem); | ||||
|             if (check == state) | ||||
|                 continue; | ||||
|             collection.Add(new(check, r)); | ||||
|         } | ||||
|         if (collection.Count > 0) | ||||
|         { | ||||
|             KeyValuePair<int, Record>[] notNewState = (from l in collection where l.Value.WorkItem.State != "New" select l).ToArray(); | ||||
|             if (notNewState.Length == 0 && record.WorkItem.State is "New" or "Active") | ||||
|                 collection.Clear(); | ||||
|             else if (notNewState.Length > 0) | ||||
|             { | ||||
|                 int minimum = notNewState.Min(l => l.Key); | ||||
|                 if (minimum == state) | ||||
|                     collection.Clear(); | ||||
|                 else if (minimum == 1 && record.WorkItem.State == "New") | ||||
|                     collection.Clear(); | ||||
|                 else if (notNewState.Length > 0 && record.WorkItem.State == "Active") | ||||
|                     collection.Clear(); | ||||
|             } | ||||
|         } | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in collection.OrderByDescending(l => l.Key)) | ||||
|             results.Add(keyValuePair.Value); | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> FeatureCheckStart122517(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         Record record; | ||||
|         List<string> collection = new(); | ||||
|         List<string> violations = new(); | ||||
|         ReadOnlyCollection<Record> records; | ||||
|         ReadOnlyCollection<Record> recordsNotMatching; | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             record = keyValuePair.Value; | ||||
|             if (record.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             if (record.WorkItem.WorkItemType != workItemType) | ||||
|                 continue; | ||||
|             collection.Clear(); | ||||
|             violations.Clear(); | ||||
|             if (record.Children is null || record.Children.Length == 0) | ||||
|                 continue; | ||||
|             if (record.WorkItem.StartDate is null) | ||||
|                 continue; | ||||
|             records = FilterChildren(workItemTypes, record); | ||||
|             recordsNotMatching = GetWorkItemsNotMatching122517(record, records); | ||||
|             if (recordsNotMatching.Count == 0) | ||||
|                 continue; | ||||
|             collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}"); | ||||
|             collection.Add(string.Empty); | ||||
|             collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.ActivatedDate)} != {record.WorkItem.ActivatedDate}"); | ||||
|             collection.Add(string.Empty); | ||||
|             lines.AddRange(collection); | ||||
|             violations.Add($"<a target='_blank' href='{url}{record.WorkItem.Id}'>StartDate</a>:{record.WorkItem.StartDate};"); | ||||
|             foreach (Record r in recordsNotMatching) | ||||
|                 violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.ActivatedDate};"); | ||||
|             results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations))); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<Record> GetWorkItemsNotMatching122517(Record record, ReadOnlyCollection<Record> records) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
|         if (record.WorkItem.StartDate is null) | ||||
|             throw new Exception(); | ||||
|         DateTime dateTime = record.WorkItem.StartDate.Value; | ||||
|         List<KeyValuePair<long, Record>> collection = new(); | ||||
|         foreach (Record r in records) | ||||
|         { | ||||
|             if (r.WorkItem.State is "Removed") | ||||
|                 continue; | ||||
|             if (r.WorkItem.ActivatedDate is null) | ||||
|                 continue; | ||||
|             if (dateTime >= r.WorkItem.ActivatedDate.Value) | ||||
|                 continue; | ||||
|             collection.Add(new(r.WorkItem.ActivatedDate.Value.Ticks, r)); | ||||
|         } | ||||
|         foreach (KeyValuePair<long, Record> keyValuePair in collection.OrderBy(l => l.Key)) | ||||
|             results.Add(keyValuePair.Value); | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     internal static List<Description> GetDescriptions(JsonElement[] jsonElements) | ||||
|     { | ||||
|         List<Description> results = new(); | ||||
|         Description? description; | ||||
|         foreach (JsonElement jsonElement in jsonElements) | ||||
|         { | ||||
|             if (jsonElement.ValueKind != JsonValueKind.Object) | ||||
|                 throw new Exception(); | ||||
|             description = JsonSerializer.Deserialize(jsonElement.ToString(), SharedDescriptionSourceGenerationContext.Default.Description); | ||||
|             if (description is null) | ||||
|                 continue; | ||||
|             results.Add(description); | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -23,7 +23,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|  | ||||
|     private readonly Timer _Timer; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -161,34 +161,37 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|                     relations.Add(relation); | ||||
|                 } | ||||
|             } | ||||
|             workItem = new(fields.MicrosoftVSTSCommonActivatedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonActivatedDate, | ||||
|                            fields.SystemAreaPath, | ||||
|                            fields.SystemAssignedTo?.DisplayName, | ||||
|                            fields.MicrosoftVSTSCommonBusinessValue is null or 0 ? null : (long)fields.MicrosoftVSTSCommonBusinessValue, | ||||
|                            fields.SystemChangedDate, | ||||
|                            fields.MicrosoftVSTSCommonClosedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonClosedDate, | ||||
|                            fields.SystemCommentCount, | ||||
|                            fields.SystemCreatedDate, | ||||
|                            fields.SystemDescription, | ||||
|                            fields.MicrosoftVSTSSchedulingEffort is null or 0 ? null : (long)fields.MicrosoftVSTSSchedulingEffort, | ||||
|                            value.Id, | ||||
|                            fields.SystemIterationPath, | ||||
|                            fields.SystemParent == 0 ? null : fields.SystemParent, | ||||
|                            fields.MicrosoftVSTSCommonPriority == 0 ? null : fields.MicrosoftVSTSCommonPriority, | ||||
|                            relations.ToArray(), | ||||
|                            fields.CustomRequester?.DisplayName, | ||||
|                            fields.MicrosoftVSTSCommonResolvedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonResolvedDate, | ||||
|                            value.Rev, | ||||
|                            fields.CustomRRminusOE is null or 0 ? null : (long)fields.CustomRRminusOE, | ||||
|                            fields.MicrosoftVSTSSchedulingStartDate == DateTime.MinValue ? null : fields.MicrosoftVSTSSchedulingStartDate, | ||||
|                            fields.SystemState, | ||||
|                            fields.SystemTags, | ||||
|                            fields.MicrosoftVSTSSchedulingTargetDate == DateTime.MinValue ? null : fields.MicrosoftVSTSSchedulingTargetDate, | ||||
|                            fields.MicrosoftVSTSCommonTimeCriticality is null or 0 ? null : (long)fields.MicrosoftVSTSCommonTimeCriticality, | ||||
|                            fields.SystemTitle.Trim(), | ||||
|                            null, | ||||
|                            fields.CustomWSJF is null or 0 ? null : (long)fields.CustomWSJF, | ||||
|                            fields.SystemWorkItemType); | ||||
|             workItem = new(activatedDate: fields.MicrosoftVSTSCommonActivatedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonActivatedDate, | ||||
|                            areaPath: fields.SystemAreaPath, | ||||
|                            assignedTo: fields.SystemAssignedTo?.DisplayName, | ||||
|                            businessValue: fields.MicrosoftVSTSCommonBusinessValue is null or 0 ? null : (long)fields.MicrosoftVSTSCommonBusinessValue, | ||||
|                            changedDate: fields.SystemChangedDate, | ||||
|                            closedDate: fields.MicrosoftVSTSCommonClosedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonClosedDate, | ||||
|                            commentCount: fields.SystemCommentCount, | ||||
|                            createdDate: fields.SystemCreatedDate, | ||||
|                            description: fields.SystemDescription, | ||||
|                            effort: fields.MicrosoftVSTSSchedulingEffort is null or 0 ? null : (long)fields.MicrosoftVSTSSchedulingEffort, | ||||
|                            id: value.Id, | ||||
|                            iterationPath: fields.SystemIterationPath, | ||||
|                            parent: fields.SystemParent == 0 ? null : fields.SystemParent, | ||||
|                            priority: fields.MicrosoftVSTSCommonPriority == 0 ? null : fields.MicrosoftVSTSCommonPriority, | ||||
|                            relations: relations.ToArray(), | ||||
|                            remainingWork: fields.MicrosoftVSTSSchedulingRemainingWork is null ? null : (long)fields.MicrosoftVSTSSchedulingRemainingWork, | ||||
|                            requester: fields.CustomRequester?.DisplayName, | ||||
|                            resolvedDate: fields.MicrosoftVSTSCommonResolvedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonResolvedDate, | ||||
|                            revision: value.Rev, | ||||
|                            riskReductionMinusOpportunityEnablement: fields.CustomRRminusOE is null or 0 ? null : (long)fields.CustomRRminusOE, | ||||
|                            startDate: fields.MicrosoftVSTSSchedulingStartDate == DateTime.MinValue ? null : fields.MicrosoftVSTSSchedulingStartDate, | ||||
|                            state: fields.SystemState, | ||||
|                            storyPoints: fields.MicrosoftVSTSSchedulingStoryPoints is null ? null : (long)fields.MicrosoftVSTSSchedulingStoryPoints, | ||||
|                            tags: fields.SystemTags, | ||||
|                            targetDate: fields.MicrosoftVSTSSchedulingTargetDate == DateTime.MinValue ? null : fields.MicrosoftVSTSSchedulingTargetDate, | ||||
|                            timeCriticality: fields.MicrosoftVSTSCommonTimeCriticality is null or 0 ? null : (long)fields.MicrosoftVSTSCommonTimeCriticality, | ||||
|                            title: fields.SystemTitle.Trim(), | ||||
|                            violation: null, | ||||
|                            weightedShortestJobFirst: fields.CustomWSJF is null or 0 ? null : fields.CustomWSJF, | ||||
|                            weightedShortestJobFirstFibonacci: fields.CustomWSJFFib is null or 0 ? null : fields.CustomWSJFFib, | ||||
|                            workItemType: fields.SystemWorkItemType); | ||||
|             results.Add(workItem.Id, workItem); | ||||
|         } | ||||
|         return new(results); | ||||
| @ -356,10 +359,12 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
|         _Logistics = new Logistics(reportFullPath, $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};"); | ||||
|         string[] lines = new string[] { string.Empty, "NUM_DATA_ROWS", $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};" }; | ||||
|         ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines); | ||||
|         _Logistics = new Logistics(reportFullPath, processDataStandardFormat); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             MoveJson(reportFullPath, dateTime); | ||||
|         results = new(_Logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), new List<FileInfo>()); | ||||
|         results = new(string.Join(Environment.NewLine, _Logistics.Logistics1), Array.Empty<Test>(), Array.Empty<JsonElement>(), new List<FileInfo>()); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -19,7 +19,6 @@ public class ProcessData : IProcessData | ||||
|                        Logistics logistics, | ||||
|                        List<FileInfo> fileInfoCollection) | ||||
|     { | ||||
|         fileInfoCollection.Clear(); | ||||
|         _Details = new List<object>(); | ||||
|         Parse(); | ||||
|     } | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - 122508 - Feature iteration should be set to max of children</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/122508.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/122508.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/122508.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -56,7 +56,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/check-122508.json?v=2024-10-07-18-50"); | ||||
|             initIndex("/markdown/check-122508.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - 122514 - Features and children must have a Tag</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/122514.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/122514.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/122514.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -56,7 +56,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/check-122514.json?v=2024-10-07-18-50"); | ||||
|             initIndex("/markdown/check-122514.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - 122517 - Feature start date should be min activated date of children</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/122517.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/122517.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/122517.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -56,7 +56,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/check-122517.json?v=2024-10-07-18-50"); | ||||
|             initIndex("/markdown/check-122517.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - 123066 - When children of a Feature are not New Feature must also not be New</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/123066.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/123066.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/123066.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -56,7 +56,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/check-123066.json?v=2024-10-07-18-50"); | ||||
|             initIndex("/markdown/check-123066.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - 123067 - WIP</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/123067.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/123067.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/123067.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -56,7 +56,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/check-123067.json?v=2024-10-07-18-50"); | ||||
|             initIndex("/markdown/check-123067.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - 126169 - Children of a Feature should have the same priority</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/126169.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/126169.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/126169.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -56,7 +56,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/check-126169.json?v=2024-10-07-18-50"); | ||||
|             initIndex("/markdown/check-126169.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - Business Value</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/business.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/business.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/business.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -59,7 +59,7 @@ What is the relative value to the Customer or business? | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2024-10-07-18-50", "https://oi-metrology-viewer-prod.mes.infineon.com:4438/api/v1/ado/", "business", "Value", "Business Value", "/markdown/PI4-Results/business.json?v=2024-10-07-18-50"); | ||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2025-04-14-08-10", "https://eaf-dev.mes.infineon.com/api/v1/ado/", "business", "Value", "Business Value", "/markdown/PI5-Results/business.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
							
								
								
									
										110
									
								
								Adaptation/FileHandlers/json/StaticSite/html/cod-b.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								Adaptation/FileHandlers/json/StaticSite/html/cod-b.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,110 @@ | ||||
| <!DOCTYPE html> | ||||
| <html lang="en"> | ||||
|  | ||||
| <head> | ||||
|     <meta charset="utf-8" /> | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - Cost of Delay (CoD) (see @SCALE formula)</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/styles/cod.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/scripts/jquery-1.6.4.min.js"></script> | ||||
|     <script src="/js/scripts/jquery.signalR-2.4.3.min.js"></script> | ||||
|     <script src="/js/cod-1-122-0.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|     <div class="navbar navbar-fixed-top"> | ||||
|         <div class="container-fluid"> | ||||
|             <div class="navbar-header"> | ||||
|                 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> | ||||
|                     <span class="icon-bar"></span> | ||||
|                     <span class="icon-bar"></span> | ||||
|                     <span class="icon-bar"></span> | ||||
|                 </button> | ||||
|                 <div class="navbar-brand"> | ||||
|                     <span id="siteHeader"> </span> - | ||||
|                     <span id="th-span"> </span> | ||||
|                     <button id="toggle">Toggle</button> | ||||
|                 </div> | ||||
|             </div> | ||||
|             <div class="navbar-collapse collapse"> | ||||
|                 <ul class="nav navbar-nav"> | ||||
|                 </ul> | ||||
|                 <p class="navbar-text navbar-right"> | ||||
|                       | ||||
|                 </p> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="container-fluid body-content" style="margin-top: 40px; margin-left: 15px;"> | ||||
|         <div id="HeaderGridDiv"> | ||||
|             <table id="HeaderGrid" border="1"></table> | ||||
|         </div> | ||||
|  | ||||
|         <br />  | ||||
|  | ||||
|         <div id="AllGridDiv"> | ||||
|             <table id="AllGrid"></table> | ||||
|         </div> | ||||
|  | ||||
|         <textarea id="AllTextarea" rows="20" cols="147"></textarea> | ||||
|     </div> | ||||
|  | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             const fromHtml = true; | ||||
|             const machineId = 'na'; | ||||
|             const username = 'anonymous'; | ||||
|             const baseUri = 'https://eaf-dev.mes.infineon.com'; | ||||
|             const apiUrl = 'https://eaf-dev.mes.infineon.com/api/v1/ado/'; | ||||
|             const windowLocationHRef = window.location.href; | ||||
|             const signalRUrl = baseUri + '/signalr'; | ||||
|             const workItems = { | ||||
|                 a: baseUri + '/markdown/bugs-features-with-parents.json?v=2025-04-14-08-10', | ||||
|                 b: baseUri + '/markdown/{[]}.json?v=2025-04-14-08-10', | ||||
|                 timeout: 3000, | ||||
|             }; | ||||
|             const b = { | ||||
|                 page: 'business', | ||||
|                 description: 'Value', | ||||
|                 th: 'Business Value', | ||||
|                 span: 'What is the relative value to the Customer or business?<br>• Do our users prefer this over that?<br>• What is the revenue impact on our business?<br>• Is there a potential penalty or other negative effects if we delay?' | ||||
|             }; | ||||
|             const r = { | ||||
|                 page: 'risk', | ||||
|                 description: 'Risk', | ||||
|                 th: 'Risk Reduction and/or Opportunity Enablement', | ||||
|                 span: 'What else does this do for our business?<br>• Reduce the risk of this or future delivery?<br>• Is there value in the information we will receive?<br>• Enable new business opportunities?' | ||||
|             }; | ||||
|             const t = { | ||||
|                 page: 'time', | ||||
|                 description: 'Critical', | ||||
|                 th: 'Time Criticality', | ||||
|                 span: 'How does user/business value decay over time?<br>• Is there a fixed deadline?<br>• Will they wait for us or move to another Solution?<br>• What is the current effect on Customer satisfaction?' | ||||
|             }; | ||||
|             const c = { | ||||
|                 page: 'cod', | ||||
|                 description: 'CoD', | ||||
|                 th: 'Cost of Delay (CoD)', | ||||
|                 span: "Cost of Delay (CoD) is the money lost by delaying or not doing a job for a specific time. It's a measure of the economic value of a job over time." | ||||
|             }; | ||||
|             const e = { | ||||
|                 page: 'effort', | ||||
|                 description: 'Effort', | ||||
|                 th: 'Effort', | ||||
|                 span: 'Effort' | ||||
|             }; | ||||
|             const w = { | ||||
|                 page: 'wsjf', | ||||
|                 description: 'WSJF', | ||||
|                 th: 'Weightest Shortest Job First calculation (WSJF)', | ||||
|                 span: 'Weightest Shortest Job First calculation (see @SCALE formula)' | ||||
|             }; | ||||
|             initIndex(fromHtml, username, machineId, windowLocationHRef, workItems, b, r, t, c, e, w, apiUrl, signalRUrl); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - Effort</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/effort.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/effort.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/effort.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -55,7 +55,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2024-10-07-18-50", "https://oi-metrology-viewer-prod.mes.infineon.com:4438/api/v1/ado/", "effort", "Effort", "Effort", "/markdown/PI4-Results/effort.json?v=2024-10-07-18-50"); | ||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2025-04-14-08-10", "https://eaf-dev.mes.infineon.com/api/v1/ado/", "effort", "Effort", "Effort", "/markdown/PI5-Results/effort.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - Risk Reduction and/or Opportunity Enablement</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/risk.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/risk.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/risk.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -59,7 +59,7 @@ What else does this do for our business? | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2024-10-07-18-50", "https://oi-metrology-viewer-prod.mes.infineon.com:4438/api/v1/ado/", "risk", "Risk", "Risk Reduction and/or Opportunity Enablement", "/markdown/PI4-Results/risk.json?v=2024-10-07-18-50"); | ||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2025-04-14-08-10", "https://eaf-dev.mes.infineon.com/api/v1/ado/", "risk", "Risk", "Risk Reduction and/or Opportunity Enablement", "/markdown/PI5-Results/risk.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
							
								
								
									
										34
									
								
								Adaptation/FileHandlers/json/StaticSite/html/simple.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								Adaptation/FileHandlers/json/StaticSite/html/simple.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
| <head> | ||||
|     <title>SignalR Simple Chat</title> | ||||
|     <style type="text/css"> | ||||
|         .container { | ||||
|             background-color: #99CCFF; | ||||
|             border: thick solid #808080; | ||||
|             padding: 20px; | ||||
|             margin: 20px; | ||||
|         } | ||||
|     </style> | ||||
| </head> | ||||
| <body> | ||||
|     <div class="container"> | ||||
|         <input type="text" id="message" /> | ||||
|         <input type="button" id="sendmessage" value="Send" /> | ||||
|         <input type="hidden" id="displayname" /> | ||||
|         <ul id="discussion"></ul> | ||||
|     </div> | ||||
|     <script src="/js/scripts/jquery-1.6.4.min.js"></script> | ||||
|     <script src="/js/scripts/jquery.signalR-2.4.3.min.js"></script> | ||||
|     <script src="/signalr/hubs"></script> | ||||
|     <script src="/js/simple.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|  | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/signalr", "https://eaf-dev.mes.infineon.com/api/v1/ado/"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
| </body> | ||||
| </html> | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - Time Criticality</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/time.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/time.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/time.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -32,7 +32,6 @@ How does user/business value decay over time? | ||||
| • Is there a fixed deadline? | ||||
| • Will they wait for us or move to another Solution? | ||||
| • What is the current effect on Customer satisfaction? | ||||
|  | ||||
|                 </div> | ||||
|             </div> | ||||
|             <div class="navbar-collapse collapse"> | ||||
| @ -60,7 +59,7 @@ How does user/business value decay over time? | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2024-10-07-18-50", "https://oi-metrology-viewer-prod.mes.infineon.com:4438/api/v1/ado/", "time", "Critical", "Time Criticality", "/markdown/PI4-Results/time.json?v=2024-10-07-18-50"); | ||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2025-04-14-08-10", "https://eaf-dev.mes.infineon.com/api/v1/ado/", "time", "Critical", "Time Criticality", "/markdown/PI5-Results/time.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - User Stor(ies) with parents</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/with-parents.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/with-parents.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/with-parents.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -55,7 +55,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/bugs-user-stories-with-parents.json?v=2024-10-07-18-50"); | ||||
|             initIndex("/markdown/bugs-user-stories-with-parents.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
							
								
								
									
										64
									
								
								Adaptation/FileHandlers/json/StaticSite/html/wsjf-b.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								Adaptation/FileHandlers/json/StaticSite/html/wsjf-b.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
|  | ||||
| <head> | ||||
|     <meta charset="utf-8" /> | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - Result of Weightest Shortest Job First calculation (see @SCALE formula)</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/wsjf.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/wsjf-b.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
|     <div class="navbar navbar-fixed-top"> | ||||
|         <div class="container-fluid"> | ||||
|             <div class="navbar-header"> | ||||
|                 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> | ||||
|                     <span class="icon-bar"></span> | ||||
|                     <span class="icon-bar"></span> | ||||
|                     <span class="icon-bar"></span> | ||||
|                 </button> | ||||
|                 <div class="navbar-brand"> | ||||
|                     <span id="siteHeader"> </span> - Result of Weightest Shortest Job First calculation (see @SCALE formula) | ||||
|                 </div> | ||||
|             </div> | ||||
|             <div class="navbar-collapse collapse"> | ||||
|                 <ul class="nav navbar-nav"> | ||||
|                 </ul> | ||||
|                 <p class="navbar-text navbar-right"> | ||||
|                       | ||||
|                 </p> | ||||
|             </div> | ||||
|         </div> | ||||
|     </div> | ||||
|     <div class="container-fluid body-content" style="margin-top: 40px; margin-left: 15px;"> | ||||
|  | ||||
|         <div style="height: 550px;" id="HeaderGridDiv"> | ||||
|             <table id="HeaderGrid" border="1"></table> | ||||
|         </div> | ||||
|  | ||||
|         <br />  | ||||
|  | ||||
|         <div id="AllGridDiv"> | ||||
|             <table id="AllGrid"></table> | ||||
|         </div> | ||||
|     </div> | ||||
|  | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2025-04-14-08-10", "https://eaf-dev.mes.infineon.com/api/v1/ado/"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
| </body> | ||||
|  | ||||
| </html> | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - Result of Weightest Shortest Job First calculation (see @SCALE formula)</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2025-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/wsjf.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/wsjf.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/wsjf.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -55,7 +55,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2024-10-07-18-50", "https://oi-metrology-viewer-prod.mes.infineon.com:4438/api/v1/ado/"); | ||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2025-04-14-08-10", "https://eaf-dev.mes.infineon.com/api/v1/ado/"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| function compareFunction(a, b) { | ||||
|     if (a.CoD === null || b.CoD === null) { | ||||
|     if (a.CoD == undefined || b.CoD == undefined) { | ||||
|         return b.Id - a.Id; | ||||
|     } else { | ||||
|         return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
| @ -7,12 +7,12 @@ function compareFunction(a, b) { | ||||
| } | ||||
|  | ||||
| function showOne(rowData) { | ||||
|     if (rowData == null) | ||||
|     if (rowData == undefined) | ||||
|         return; | ||||
|     var data = []; | ||||
|     data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' }); | ||||
|     for (const property in rowData) { | ||||
|         if (rowData[property] == null) | ||||
|         if (rowData[property] == undefined) | ||||
|             continue; | ||||
|         data.push({ name: property, value: rowData[property].toString() }); | ||||
|     } | ||||
| @ -26,7 +26,7 @@ function showOne(rowData) { | ||||
|  | ||||
| function loadOne() { | ||||
|     var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow(); | ||||
|     if (selectedRow == null) | ||||
|     if (selectedRow == undefined) | ||||
|         return; | ||||
|     var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index]; | ||||
|     showOne(rowData); | ||||
| @ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) { | ||||
|  | ||||
| function getState(state) { | ||||
|     var result; | ||||
|     if (state == null) | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
| @ -62,7 +62,7 @@ function getPriority(workItemType, priority) { | ||||
|     var result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug"; | ||||
|     else if (priority == null || priority === 0) | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High`; | ||||
| @ -78,14 +78,14 @@ function getPriority(workItemType, priority) { | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(workItem) { | ||||
|     if (workItem !== null) { | ||||
|         if (workItem.Effort === null) | ||||
|     if (workItem != undefined) { | ||||
|         if (workItem.Effort == undefined) | ||||
|             workItem.Effort = 10123; | ||||
|         if (workItem.BusinessValue === null) | ||||
|         if (workItem.BusinessValue == undefined) | ||||
|             workItem.BusinessValue = 99999; | ||||
|         if (workItem.TimeCriticality === null) | ||||
|         if (workItem.TimeCriticality == undefined) | ||||
|             workItem.TimeCriticality = 99999; | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement === null) | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement == undefined) | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = 99999; | ||||
|         workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue; | ||||
|     } | ||||
| @ -97,7 +97,7 @@ function updateRecordOther(workItem) { | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent === null) { | ||||
|     if (parent == undefined) { | ||||
|         workItem["ParentId"] = 9999999; | ||||
|         workItem["ParentTitle"] = null; | ||||
|         workItem["ParentState"] = null; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| function compareFunction(a, b) { | ||||
|     if (a.CoD === null || b.CoD === null) { | ||||
|     if (a.CoD == undefined || b.CoD == undefined) { | ||||
|         return b.Id - a.Id; | ||||
|     } else { | ||||
|         return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
| @ -7,12 +7,12 @@ function compareFunction(a, b) { | ||||
| } | ||||
|  | ||||
| function showOne(rowData) { | ||||
|     if (rowData == null) | ||||
|     if (rowData == undefined) | ||||
|         return; | ||||
|     var data = []; | ||||
|     data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' }); | ||||
|     for (const property in rowData) { | ||||
|         if (rowData[property] == null) | ||||
|         if (rowData[property] == undefined) | ||||
|             continue; | ||||
|         data.push({ name: property, value: rowData[property].toString() }); | ||||
|     } | ||||
| @ -26,7 +26,7 @@ function showOne(rowData) { | ||||
|  | ||||
| function loadOne() { | ||||
|     var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow(); | ||||
|     if (selectedRow == null) | ||||
|     if (selectedRow == undefined) | ||||
|         return; | ||||
|     var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index]; | ||||
|     showOne(rowData); | ||||
| @ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) { | ||||
|  | ||||
| function getState(state) { | ||||
|     var result; | ||||
|     if (state == null) | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
| @ -62,7 +62,7 @@ function getPriority(workItemType, priority) { | ||||
|     var result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug"; | ||||
|     else if (priority == null || priority === 0) | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High`; | ||||
| @ -78,14 +78,14 @@ function getPriority(workItemType, priority) { | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(workItem) { | ||||
|     if (workItem !== null) { | ||||
|         if (workItem.Effort === null) | ||||
|     if (workItem != undefined) { | ||||
|         if (workItem.Effort == undefined) | ||||
|             workItem.Effort = 10123; | ||||
|         if (workItem.BusinessValue === null) | ||||
|         if (workItem.BusinessValue == undefined) | ||||
|             workItem.BusinessValue = 99999; | ||||
|         if (workItem.TimeCriticality === null) | ||||
|         if (workItem.TimeCriticality == undefined) | ||||
|             workItem.TimeCriticality = 99999; | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement === null) | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement == undefined) | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = 99999; | ||||
|         workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue; | ||||
|     } | ||||
| @ -97,7 +97,7 @@ function updateRecordOther(workItem) { | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent === null) { | ||||
|     if (parent == undefined) { | ||||
|         workItem["ParentId"] = 9999999; | ||||
|         workItem["ParentTitle"] = null; | ||||
|         workItem["ParentState"] = null; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| function compareFunction(a, b) { | ||||
|     if (a.CoD === null || b.CoD === null) { | ||||
|     if (a.CoD == undefined || b.CoD == undefined) { | ||||
|         return b.Id - a.Id; | ||||
|     } else { | ||||
|         return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
| @ -7,12 +7,12 @@ function compareFunction(a, b) { | ||||
| } | ||||
|  | ||||
| function showOne(rowData) { | ||||
|     if (rowData == null) | ||||
|     if (rowData == undefined) | ||||
|         return; | ||||
|     var data = []; | ||||
|     data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' }); | ||||
|     for (const property in rowData) { | ||||
|         if (rowData[property] == null) | ||||
|         if (rowData[property] == undefined) | ||||
|             continue; | ||||
|         data.push({ name: property, value: rowData[property].toString() }); | ||||
|     } | ||||
| @ -26,7 +26,7 @@ function showOne(rowData) { | ||||
|  | ||||
| function loadOne() { | ||||
|     var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow(); | ||||
|     if (selectedRow == null) | ||||
|     if (selectedRow == undefined) | ||||
|         return; | ||||
|     var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index]; | ||||
|     showOne(rowData); | ||||
| @ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) { | ||||
|  | ||||
| function getState(state) { | ||||
|     var result; | ||||
|     if (state == null) | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
| @ -62,7 +62,7 @@ function getPriority(workItemType, priority) { | ||||
|     var result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug"; | ||||
|     else if (priority == null || priority === 0) | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High`; | ||||
| @ -78,14 +78,14 @@ function getPriority(workItemType, priority) { | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(workItem) { | ||||
|     if (workItem !== null) { | ||||
|         if (workItem.Effort === null) | ||||
|     if (workItem != undefined) { | ||||
|         if (workItem.Effort == undefined) | ||||
|             workItem.Effort = 10123; | ||||
|         if (workItem.BusinessValue === null) | ||||
|         if (workItem.BusinessValue == undefined) | ||||
|             workItem.BusinessValue = 99999; | ||||
|         if (workItem.TimeCriticality === null) | ||||
|         if (workItem.TimeCriticality == undefined) | ||||
|             workItem.TimeCriticality = 99999; | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement === null) | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement == undefined) | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = 99999; | ||||
|         workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue; | ||||
|     } | ||||
| @ -97,7 +97,7 @@ function updateRecordOther(workItem) { | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent === null) { | ||||
|     if (parent == undefined) { | ||||
|         workItem["ParentId"] = 9999999; | ||||
|         workItem["ParentTitle"] = null; | ||||
|         workItem["ParentState"] = null; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| function compareFunction(a, b) { | ||||
|     if (a.CoD === null || b.CoD === null) { | ||||
|     if (a.CoD == undefined || b.CoD == undefined) { | ||||
|         return b.Id - a.Id; | ||||
|     } else { | ||||
|         return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
| @ -7,12 +7,12 @@ function compareFunction(a, b) { | ||||
| } | ||||
|  | ||||
| function showOne(rowData) { | ||||
|     if (rowData == null) | ||||
|     if (rowData == undefined) | ||||
|         return; | ||||
|     var data = []; | ||||
|     data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' }); | ||||
|     for (const property in rowData) { | ||||
|         if (rowData[property] == null) | ||||
|         if (rowData[property] == undefined) | ||||
|             continue; | ||||
|         data.push({ name: property, value: rowData[property].toString() }); | ||||
|     } | ||||
| @ -26,7 +26,7 @@ function showOne(rowData) { | ||||
|  | ||||
| function loadOne() { | ||||
|     var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow(); | ||||
|     if (selectedRow == null) | ||||
|     if (selectedRow == undefined) | ||||
|         return; | ||||
|     var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index]; | ||||
|     showOne(rowData); | ||||
| @ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) { | ||||
|  | ||||
| function getState(state) { | ||||
|     var result; | ||||
|     if (state == null) | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
| @ -62,7 +62,7 @@ function getPriority(workItemType, priority) { | ||||
|     var result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug"; | ||||
|     else if (priority == null || priority === 0) | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High`; | ||||
| @ -78,14 +78,14 @@ function getPriority(workItemType, priority) { | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(workItem) { | ||||
|     if (workItem !== null) { | ||||
|         if (workItem.Effort === null) | ||||
|     if (workItem != undefined) { | ||||
|         if (workItem.Effort == undefined) | ||||
|             workItem.Effort = 10123; | ||||
|         if (workItem.BusinessValue === null) | ||||
|         if (workItem.BusinessValue == undefined) | ||||
|             workItem.BusinessValue = 99999; | ||||
|         if (workItem.TimeCriticality === null) | ||||
|         if (workItem.TimeCriticality == undefined) | ||||
|             workItem.TimeCriticality = 99999; | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement === null) | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement == undefined) | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = 99999; | ||||
|         workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue; | ||||
|     } | ||||
| @ -97,7 +97,7 @@ function updateRecordOther(workItem) { | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent === null) { | ||||
|     if (parent == undefined) { | ||||
|         workItem["ParentId"] = 9999999; | ||||
|         workItem["ParentTitle"] = null; | ||||
|         workItem["ParentState"] = null; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| function compareFunction(a, b) { | ||||
|     if (a.CoD === null || b.CoD === null) { | ||||
|     if (a.CoD == undefined || b.CoD == undefined) { | ||||
|         return b.Id - a.Id; | ||||
|     } else { | ||||
|         return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
| @ -7,12 +7,12 @@ function compareFunction(a, b) { | ||||
| } | ||||
|  | ||||
| function showOne(rowData) { | ||||
|     if (rowData == null) | ||||
|     if (rowData == undefined) | ||||
|         return; | ||||
|     var data = []; | ||||
|     data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' }); | ||||
|     for (const property in rowData) { | ||||
|         if (rowData[property] == null) | ||||
|         if (rowData[property] == undefined) | ||||
|             continue; | ||||
|         data.push({ name: property, value: rowData[property].toString() }); | ||||
|     } | ||||
| @ -26,7 +26,7 @@ function showOne(rowData) { | ||||
|  | ||||
| function loadOne() { | ||||
|     var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow(); | ||||
|     if (selectedRow == null) | ||||
|     if (selectedRow == undefined) | ||||
|         return; | ||||
|     var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index]; | ||||
|     showOne(rowData); | ||||
| @ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) { | ||||
|  | ||||
| function getState(state) { | ||||
|     var result; | ||||
|     if (state == null) | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
| @ -62,7 +62,7 @@ function getPriority(workItemType, priority) { | ||||
|     var result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug"; | ||||
|     else if (priority == null || priority === 0) | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High`; | ||||
| @ -78,14 +78,14 @@ function getPriority(workItemType, priority) { | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(workItem) { | ||||
|     if (workItem !== null) { | ||||
|         if (workItem.Effort === null) | ||||
|     if (workItem != undefined) { | ||||
|         if (workItem.Effort == undefined) | ||||
|             workItem.Effort = 10123; | ||||
|         if (workItem.BusinessValue === null) | ||||
|         if (workItem.BusinessValue == undefined) | ||||
|             workItem.BusinessValue = 99999; | ||||
|         if (workItem.TimeCriticality === null) | ||||
|         if (workItem.TimeCriticality == undefined) | ||||
|             workItem.TimeCriticality = 99999; | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement === null) | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement == undefined) | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = 99999; | ||||
|         workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue; | ||||
|     } | ||||
| @ -97,7 +97,7 @@ function updateRecordOther(workItem) { | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent === null) { | ||||
|     if (parent == undefined) { | ||||
|         workItem["ParentId"] = 9999999; | ||||
|         workItem["ParentTitle"] = null; | ||||
|         workItem["ParentState"] = null; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| function compareFunction(a, b) { | ||||
|     if (a.CoD === null || b.CoD === null) { | ||||
|     if (a.CoD == undefined || b.CoD == undefined) { | ||||
|         return b.Id - a.Id; | ||||
|     } else { | ||||
|         return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
| @ -7,12 +7,12 @@ function compareFunction(a, b) { | ||||
| } | ||||
|  | ||||
| function showOne(rowData) { | ||||
|     if (rowData == null) | ||||
|     if (rowData == undefined) | ||||
|         return; | ||||
|     var data = []; | ||||
|     data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' }); | ||||
|     for (const property in rowData) { | ||||
|         if (rowData[property] == null) | ||||
|         if (rowData[property] == undefined) | ||||
|             continue; | ||||
|         data.push({ name: property, value: rowData[property].toString() }); | ||||
|     } | ||||
| @ -26,7 +26,7 @@ function showOne(rowData) { | ||||
|  | ||||
| function loadOne() { | ||||
|     var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow(); | ||||
|     if (selectedRow == null) | ||||
|     if (selectedRow == undefined) | ||||
|         return; | ||||
|     var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index]; | ||||
|     showOne(rowData); | ||||
| @ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) { | ||||
|  | ||||
| function getState(state) { | ||||
|     var result; | ||||
|     if (state == null) | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
| @ -62,7 +62,7 @@ function getPriority(workItemType, priority) { | ||||
|     var result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug"; | ||||
|     else if (priority == null || priority === 0) | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High`; | ||||
| @ -78,14 +78,14 @@ function getPriority(workItemType, priority) { | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(workItem) { | ||||
|     if (workItem !== null) { | ||||
|         if (workItem.Effort === null) | ||||
|     if (workItem != undefined) { | ||||
|         if (workItem.Effort == undefined) | ||||
|             workItem.Effort = 10123; | ||||
|         if (workItem.BusinessValue === null) | ||||
|         if (workItem.BusinessValue == undefined) | ||||
|             workItem.BusinessValue = 99999; | ||||
|         if (workItem.TimeCriticality === null) | ||||
|         if (workItem.TimeCriticality == undefined) | ||||
|             workItem.TimeCriticality = 99999; | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement === null) | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement == undefined) | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = 99999; | ||||
|         workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue; | ||||
|     } | ||||
| @ -97,7 +97,7 @@ function updateRecordOther(workItem) { | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent === null) { | ||||
|     if (parent == undefined) { | ||||
|         workItem["ParentId"] = 9999999; | ||||
|         workItem["ParentTitle"] = null; | ||||
|         workItem["ParentState"] = null; | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| var _apiUrl = null; | ||||
|  | ||||
| function compareFunction(a, b) { | ||||
|     if (a.BusinessValue === null || b.BusinessValue === null) { | ||||
|     if (a.BusinessValue == undefined || b.BusinessValue == undefined) { | ||||
|         var aPollValue = a.PollValue.split('-'); | ||||
|         var bPollValue = b.PollValue.split('-'); | ||||
|         return bPollValue[0].trim() - aPollValue[0].trim() || b.State[0] - a.State[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
|         return bPollValue[0] - aPollValue[0] || b.State[0] - a.State[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
|     } else { | ||||
|         return b.BusinessValue - a.BusinessValue || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
|     } | ||||
| } | ||||
|  | ||||
| function showOne(rowData) { | ||||
|     if (rowData == null) | ||||
|     if (rowData == undefined) | ||||
|         return; | ||||
|     var data = []; | ||||
|     data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' }); | ||||
|     for (const property in rowData) { | ||||
|         if (rowData[property] == null) | ||||
|         if (rowData[property] == undefined) | ||||
|             continue; | ||||
|         data.push({ name: property, value: rowData[property].toString() }); | ||||
|     } | ||||
| @ -30,7 +30,7 @@ function showOne(rowData) { | ||||
|  | ||||
| function loadOne() { | ||||
|     var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow(); | ||||
|     if (selectedRow == null) | ||||
|     if (selectedRow == undefined) | ||||
|         return; | ||||
|     var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index]; | ||||
|     showOne(rowData); | ||||
| @ -45,7 +45,7 @@ function detailSelectionChangedRunInfo(evt, ui) { | ||||
|  | ||||
| function getState(state) { | ||||
|     var result; | ||||
|     if (state == null) | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
| @ -66,7 +66,7 @@ function getPriority(workItemType, priority) { | ||||
|     var result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug"; | ||||
|     else if (priority == null || priority === 0) | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High`; | ||||
| @ -81,45 +81,34 @@ function getPriority(workItemType, priority) { | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function getInversePriority(priority) { | ||||
| function getPollValue(description, pollValue) { | ||||
|     var result; | ||||
|     if (priority == null || priority === 0) | ||||
|         result = "0.000"; | ||||
|     else if (priority === 1) | ||||
|         result = "3.000"; | ||||
|     else if (priority === 2) | ||||
|         result = "2.000"; | ||||
|     else if (priority === 3) | ||||
|         result = "1.000"; | ||||
|     if (pollValue == undefined || pollValue.BusinessValue == undefined || pollValue.BusinessValue.InverseAverage == undefined) | ||||
|         result = ""; | ||||
|     else if (pollValue.BusinessValue.InverseAverage >= 4) | ||||
|         result = `${pollValue.BusinessValue.InverseAverage} - 1-Highest (Most ${description}) - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.BusinessValue.InverseAverage >= 3) | ||||
|         result = `${pollValue.BusinessValue.InverseAverage} - 2-High - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.BusinessValue.InverseAverage >= 2) | ||||
|         result = `${pollValue.BusinessValue.InverseAverage} - 3-Medium - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.BusinessValue.InverseAverage >= 1) | ||||
|         result = `${pollValue.BusinessValue.InverseAverage} - 4-Low - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.BusinessValue.InverseAverage >= 0) | ||||
|         result = `${pollValue.BusinessValue.InverseAverage} - 5-Lowest - ${pollValue.Count} Vote(s)`; | ||||
|     else | ||||
|         result = "0.000"; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function getPollValue(description, priority, priorityDisplay, pollValue) { | ||||
|     var result; | ||||
|     if (pollValue === undefined || pollValue.Records.length === undefined || pollValue.Records.length === 0 || pollValue.Average === null) | ||||
|         result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority'; | ||||
|     else if (pollValue.Average > 2) | ||||
|         result = `${pollValue.Average} - 1-High (Most ${description}) - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.Average > 1) | ||||
|         result = `${pollValue.Average} - 2-Medium - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.Average > 0) | ||||
|         result = `${pollValue.Average} - 3-Low - ${pollValue.Count} Vote(s)`; | ||||
|     else | ||||
|         result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority'; | ||||
|         result = ""; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(workItem) { | ||||
|     if (workItem !== null) { | ||||
|         if (workItem.Effort === null) | ||||
|     if (workItem != undefined) { | ||||
|         if (workItem.Effort == undefined) | ||||
|             workItem.Effort = 10123; | ||||
|         if (workItem.BusinessValue === null) | ||||
|         if (workItem.BusinessValue == undefined) | ||||
|             workItem.BusinessValue = 99999; | ||||
|         if (workItem.TimeCriticality === null) | ||||
|         if (workItem.TimeCriticality == undefined) | ||||
|             workItem.TimeCriticality = 99999; | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement === null) | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement == undefined) | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = 99999; | ||||
|         workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue; | ||||
|     } | ||||
| @ -128,12 +117,12 @@ function updateRecordCoD(workItem) { | ||||
| function updateRecordOther(workItem, dataB, description) { | ||||
|     workItem["State"] = getState(workItem["State"]); | ||||
|     var priority = getPriority(workItem["WorkItemType"], workItem["Priority"]); | ||||
|     workItem["PollValue"] = getPollValue(description, workItem["Priority"], priority, dataB[workItem.Id]); | ||||
|     workItem["PollValue"] = getPollValue(description, dataB[workItem.Id]); | ||||
|     workItem["Priority"] = priority; | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent === null) { | ||||
|     if (parent == undefined) { | ||||
|         workItem["ParentId"] = 9999999; | ||||
|         workItem["ParentTitle"] = null; | ||||
|         workItem["ParentState"] = null; | ||||
| @ -183,13 +172,46 @@ function sendValue(element, page, id) { | ||||
|         }); | ||||
| } | ||||
|  | ||||
| function getFibonacciValue(average) { | ||||
|     var result; | ||||
|     if (average >= 7) | ||||
|         result = 34; | ||||
|     else if (average >= 6) | ||||
|         result = 21; | ||||
|     else if (average >= 5) | ||||
|         result = 13; | ||||
|     else if (average >= 4) | ||||
|         result = 8; | ||||
|     else if (average >= 3) | ||||
|         result = 5; | ||||
|     else if (average >= 2) | ||||
|         result = 3; | ||||
|     else if (average >= 1) | ||||
|         result = 2; | ||||
|     else if (average >= 0) | ||||
|         result = 1; | ||||
|     else | ||||
|         result = ""; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function setRecords(workItems, page, description, th) { | ||||
|     var record; | ||||
|     var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Up</th><th>Down</th><th>Poll Value</th><th>" + th + "</th></tr>"; | ||||
|     var array = []; | ||||
|     var count = ""; | ||||
|     var select = ""; | ||||
|     var average = ""; | ||||
|     var fibonacciValue = ""; | ||||
|     var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Poll Average</th><th>Fibonacci</th><th>Poll Description</th><th>Vote(s)</th><th>" + th + "</th><th>Up</th><th>Down</th></tr>"; | ||||
|     const element = document.getElementById("HeaderGrid"); | ||||
|     for (var i = 0; i < workItems.length; i++) { | ||||
|         record = workItems[i]; | ||||
|         var length = record.BusinessValue === null ? "" : record.BusinessValue.toString().length; | ||||
|         array = record.PollValue.split('-') | ||||
|         average = array.length > 0 ? array[0] : ""; | ||||
|         fibonacciValue = getFibonacciValue(average); | ||||
|         select = array.length > 2 ? array[1] + '-' + array[2] : ""; | ||||
|         count = array.length > 3 ? array[3].trim().split(' ')[0] : ""; | ||||
|         var length = record.BusinessValue == undefined ? "" : record.BusinessValue.toString().length; | ||||
|         html += "<tr><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" + | ||||
|             "</td><td>" + record.ParentTitle + | ||||
|             "</td><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" + | ||||
| @ -201,14 +223,19 @@ function setRecords(workItems, page, description, th) { | ||||
|             "</td><td>" + | ||||
|             '<select onchange="sendValue(this, \'' + page + '\', ' + record.Id + ')">' + | ||||
|             '<option value="9">Unknown</option>' + | ||||
|             '<option value="1">High (Most ' + description + ')</option>' + | ||||
|             '<option value="2">Medium</option>' + | ||||
|             '<option value="3">Low</option>' + | ||||
|             '<option value="1">Highest (Most ' + description + ')</option>' + | ||||
|             '<option value="2">High</option>' + | ||||
|             '<option value="3">Medium</option>' + | ||||
|             '<option value="4">Low</option>' + | ||||
|             '<option value="5">Lowest</option>' + | ||||
|             "</select>" + | ||||
|             "</td><td>" + average + | ||||
|             "</td><td>" + fibonacciValue + | ||||
|             "</td><td>" + select + | ||||
|             "</td><td>" + count + | ||||
|             "</td><td>" + length + " - " + record.BusinessValue + | ||||
|             "</td><td><a href='#' class='up'>Up</a>" + | ||||
|             "</td><td><a href='#' class='down'>Down</a>" + | ||||
|             "</td><td>" + record.PollValue + | ||||
|             "</td><td>" + length + " - " + record.BusinessValue + | ||||
|             "</td></tr>"; | ||||
|     } | ||||
|     element.innerHTML = html.replaceAll(">null<", "> <"); | ||||
|  | ||||
							
								
								
									
										608
									
								
								Adaptation/FileHandlers/json/StaticSite/js/cod-1-122-0.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										608
									
								
								Adaptation/FileHandlers/json/StaticSite/js/cod-1-122-0.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,608 @@ | ||||
| var _b = {}; | ||||
| var _c = {}; | ||||
| var _e = {}; | ||||
| var _r = {}; | ||||
| var _t = {}; | ||||
| var _w = {}; | ||||
| var _page = ''; | ||||
| var _site = ''; | ||||
| var _apiUrl = ''; | ||||
| var _toggle = true; | ||||
| var _username = ''; | ||||
| var _machineId = ''; | ||||
| var _sessionId = ''; | ||||
| var _windowLocationHRef = ''; | ||||
|  | ||||
| function compareFunctionSortOrder(a, b) { | ||||
|     return a.SortOrder - b.SortOrder; | ||||
| } | ||||
|  | ||||
| function compareFunctionParentId(a, b) { | ||||
|     return a.ParentId - b.ParentId || a.Id - b.Id; | ||||
| } | ||||
|  | ||||
| function compareFunctionWeightedShortestJobFirst(a, b) { | ||||
|     if (b.WeightedShortestJobFirst === ' ') { | ||||
|         return -1; | ||||
|     } | ||||
|     return b.WeightedShortestJobFirst - a.WeightedShortestJobFirst; | ||||
| } | ||||
|  | ||||
| function getState(state) { | ||||
|     let result; | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
|     else if (state === "Active") | ||||
|         result = `2-${state}`; | ||||
|     else if (state === "Resolved") | ||||
|         result = `3-${state}`; | ||||
|     else if (state === "Closed") | ||||
|         result = `4-${state}`; | ||||
|     else if (state === "Removed") | ||||
|         result = `5-${state}`; | ||||
|     else | ||||
|         result = `8-${state}`; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function getPriority(workItemType, priority, sortPriorityGroup) { | ||||
|     let result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug {0}"; | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null {0}"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High {${sortPriorityGroup}}`; | ||||
|     else if (priority === 2) | ||||
|         result = `${priority}-Med {${sortPriorityGroup}}`; | ||||
|     else if (priority === 3) | ||||
|         result = `${priority}-Low {${sortPriorityGroup}}`; | ||||
|     else if (priority === 4) | ||||
|         result = `${priority}-TBD {4}`; | ||||
|     else | ||||
|         result = "8-Not {0}"; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function getNotifications(x, aggregation) { | ||||
|     let result; | ||||
|     if (aggregation == undefined || aggregation.Notifications == undefined || aggregation.Notifications.length === 0) | ||||
|         result = " "; | ||||
|     else { | ||||
|         result = ''; | ||||
|         aggregation.Notifications.forEach(element => { | ||||
|             const username = element.username == null ? 'user' : element.username; | ||||
|             if (element.value === "1") { | ||||
|                 result += 'Highest:' + username + ';|'; | ||||
|             } | ||||
|             else if (element.value === "2") { | ||||
|                 result += 'High:' + username + ';|'; | ||||
|             } | ||||
|             else if (element.value === "3") { | ||||
|                 result += 'Medium:' + username + ';|'; | ||||
|             } | ||||
|             else if (element.value === "4") { | ||||
|                 result += 'Low:' + username + ';|'; | ||||
|             } | ||||
|             else if (element.value === "5") { | ||||
|                 result += 'Lowest:' + username + ';|'; | ||||
|             } | ||||
|             else { | ||||
|                 result += element.value + ':' + username + ';|'; | ||||
|             } | ||||
|         }); | ||||
|         result = result.substring(0, result.length - 1); | ||||
|         result = result.replaceAll('|', '<br />'); | ||||
|     } | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function round(value, factor) { | ||||
|     return (Math.round((value + Number.EPSILON) * factor) / factor).toFixed(2); | ||||
| } | ||||
|  | ||||
| function sum(collection) { | ||||
|     let sum = 0; | ||||
|     if (collection != undefined) { | ||||
|         for (let i = 0; i < collection.length; i++) { | ||||
|             sum += collection[i]; | ||||
|         } | ||||
|     } | ||||
|     return sum; | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(b, r, t, c, e, w, workItem, highestTotalStoryPoints, dataB, totalStoryPoints) { | ||||
|     if (workItem != undefined) { | ||||
|         let data = dataB == undefined ? undefined : dataB[workItem.Id]; | ||||
|         if (data == undefined) { | ||||
|             workItem.CumulativeStoryPoints = " "; | ||||
|             workItem.TotalStoryPoints = " "; | ||||
|             workItem.AbsoluteDelta = " "; | ||||
|             workItem.Effort = " "; | ||||
|             workItem.BusinessValue = " "; | ||||
|             workItem.TimeCriticality = " "; | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = " "; | ||||
|             workItem.CoD = " "; | ||||
|             workItem.WeightedShortestJobFirst = " "; | ||||
|             workItem.Priority = getPriority(workItem.WorkItemType, 4, 0); | ||||
|             workItem.EffortNotifications = " "; | ||||
|             workItem.BusinessValueNotifications = " "; | ||||
|             workItem.TimeCriticalityNotifications = " "; | ||||
|             workItem.RiskReductionMinusOpportunityEnablementNotifications = " "; | ||||
|             workItem.SortOrder = 0; | ||||
|         } | ||||
|         else { | ||||
|             workItem.CumulativeStoryPoints = " "; | ||||
|             workItem.TotalStoryPoints = totalStoryPoints + ' User Story Point(s)'; | ||||
|             workItem.AbsoluteDelta = data.Effort == undefined || data.Effort.FibonacciAverage == undefined || totalStoryPoints == undefined || totalStoryPoints === 0 ? " " : round(Math.abs(data.Effort.FibonacciAverage - ((totalStoryPoints / highestTotalStoryPoints) * 5)), 1); | ||||
|             workItem.Effort = data.Effort == undefined || data.Effort.FibonacciAverage == undefined ? " " : round(data.Effort.FibonacciAverage, 100); | ||||
|             workItem.BusinessValue = data.BusinessValue == undefined || data.BusinessValue.FibonacciAverage == undefined ? " " : round(data.BusinessValue.FibonacciAverage, 100); | ||||
|             workItem.TimeCriticality = data.TimeCriticality == undefined || data.TimeCriticality.FibonacciAverage == undefined ? " " : round(data.TimeCriticality.FibonacciAverage, 100); | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = data.RiskReductionOpportunityEnablement == undefined || data.RiskReductionOpportunityEnablement.FibonacciAverage == undefined ? " " : round(data.RiskReductionOpportunityEnablement.FibonacciAverage, 100); | ||||
|             workItem.CoD = data.CostOfDelay == undefined ? " " : round(data.CostOfDelay, 100); | ||||
|             workItem.WeightedShortestJobFirst = data.WeightedShortestJobFirst == undefined ? " " : round(data.WeightedShortestJobFirst, 100); | ||||
|             workItem.Priority = data.SortPriority == undefined ? getPriority(workItem.WorkItemType, 4, 0) : getPriority(workItem.WorkItemType, data.SortPriority, data.SortPriorityGroup); | ||||
|             workItem.EffortNotifications = data.Effort == undefined ? " " : getNotifications(e, data.Effort); | ||||
|             workItem.BusinessValueNotifications = data.BusinessValue == undefined ? " " : getNotifications(b, data.BusinessValue); | ||||
|             workItem.TimeCriticalityNotifications = data.TimeCriticality == undefined ? " " : getNotifications(t, data.TimeCriticality); | ||||
|             workItem.RiskReductionMinusOpportunityEnablementNotifications = data.RiskReductionOpportunityEnablement == undefined ? " " : getNotifications(r, data.RiskReductionOpportunityEnablement); | ||||
|             workItem.SortOrder = data.SortOrder == undefined ? 0 : data.SortOrder; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent == undefined) { | ||||
|         workItem.ParentId = 9999999; | ||||
|         workItem.ParentTitle = null; | ||||
|         workItem.ParentState = null; | ||||
|         workItem.ParentCoD = 9999999; | ||||
|     } | ||||
|     else { | ||||
|         workItem.ParentId = parent.Id; | ||||
|         workItem.ParentCoD = parent.CoD; | ||||
|         workItem.ParentTitle = parent.Title; | ||||
|         workItem.ParentState = getState(parent.State); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function getRecords(b, r, t, c, e, w, data, dataB, workItems) { | ||||
|     let parent; | ||||
|     let workItem; | ||||
|     let storyPoints; | ||||
|     let records = []; | ||||
|     let totalStoryPoints; | ||||
|     let highestTotalStoryPoints = 0; | ||||
|     for (let i = 0; i < data.length; i++) { | ||||
|         workItem = data[i].WorkItem; | ||||
|         if (workItem.WorkItemType !== 'Feature') | ||||
|             continue; | ||||
|         if (workItem.State !== 'Active' && workItem.State !== 'New') | ||||
|             continue; | ||||
|         if (workItem.Tags != null && workItem.Tags.includes("Ignore")) | ||||
|             continue; | ||||
|         storyPoints = data[i].Tag?.StoryPoints == undefined ? null : JSON.parse(data[i].Tag.StoryPoints); | ||||
|         totalStoryPoints = sum(storyPoints); | ||||
|         if (totalStoryPoints > highestTotalStoryPoints) | ||||
|             highestTotalStoryPoints = totalStoryPoints; | ||||
|     } | ||||
|     for (let i = 0; i < data.length; i++) { | ||||
|         parent = data[i].Parent; | ||||
|         workItem = data[i].WorkItem; | ||||
|         if (workItem.WorkItemType !== 'Feature') | ||||
|             continue; | ||||
|         if (workItem.State !== 'Active' && workItem.State !== 'New') | ||||
|             continue; | ||||
|         if (workItem.Tags != null && workItem.Tags.includes("Ignore")) | ||||
|             continue; | ||||
|         storyPoints = data[i].Tag?.StoryPoints == undefined ? null : JSON.parse(data[i].Tag.StoryPoints); | ||||
|         totalStoryPoints = sum(storyPoints); | ||||
|         if ((_windowLocationHRef.indexOf('=LEO') > -1 && workItem.AreaPath !== 'ART SPS\\LEO') || (_windowLocationHRef.indexOf('=MES') > -1 && workItem.AreaPath !== 'ART SPS\\MES')) | ||||
|             continue; | ||||
|         updateRecordParent(parent, workItem); | ||||
|         updateRecordCoD(b, r, t, c, e, w, parent, highestTotalStoryPoints, null, null); | ||||
|         updateRecordCoD(b, r, t, c, e, w, workItem, highestTotalStoryPoints, dataB, totalStoryPoints); | ||||
|         workItem.State = getState(workItem.State); | ||||
|         records.push(workItem); | ||||
|     } | ||||
|     if (_windowLocationHRef.indexOf('=WSJF') > -1) { | ||||
|         records.sort(compareFunctionWeightedShortestJobFirst); | ||||
|     } | ||||
|     else if (_windowLocationHRef.indexOf('=LIVE') > -1) { | ||||
|         records.sort(compareFunctionSortOrder); | ||||
|     } | ||||
|     else { | ||||
|         records.sort(compareFunctionParentId); | ||||
|     } | ||||
|     return records; | ||||
| } | ||||
|  | ||||
| function warn(message) { | ||||
|     if (typeof acquiredVsCodeApi === 'function') | ||||
|         acquiredVsCodeApi.postMessage(message); | ||||
|     console.warn(message); | ||||
| } | ||||
|  | ||||
| function sendValue(fromHtml, element, page, id) { | ||||
|     let notification = { | ||||
|         id: id, | ||||
|         machineId: _machineId, | ||||
|         page: page, | ||||
|         sessionId: _sessionId, | ||||
|         site: _site, | ||||
|         time: new Date().getTime(), | ||||
|         username: _username, | ||||
|         value: element.value, | ||||
|     }; | ||||
|     if (fromHtml && notification.value !== "9") { | ||||
|         $("#AllTextarea").hide(); | ||||
|         document.getElementById('AllTextarea').value = ''; | ||||
|         $.post(_apiUrl, notification) | ||||
|             .done(function (msg) { | ||||
|                 console.log("Posted value of " + notification.value + " for " + id + " on page " + page + " " + msg); | ||||
|             }) | ||||
|             .fail(function (_, textStatus, _) { | ||||
|                 warn(textStatus); | ||||
|             }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function setRecords(fromHtml, b, r, t, c, e, w, records) { | ||||
|     let record; | ||||
|     let lineA = ""; | ||||
|     let lineB = ""; | ||||
|     let lineC = ""; | ||||
|     let text = 'Id\tRisk Reduction and/or Opportunity Enablement\tTime Criticality\tBusiness Value\tCoD\tEffort\tWSJF\tFeature Total Story Points\tAbsolute Delta\tState\tRequester\tAssigned To\tIteration Path\tSystem\tTitle\r\n'; | ||||
|     let html = '<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Priority</th><th>Risk Reduction and/or Opportunity Enablement</th><th>Time Criticality</th><th>Business Value</th><th>Cost of Delay (CoD)</th><th>Effort</th><th>WSJF</th></tr>'; | ||||
|     for (let i = 0; i < records.length; i++) { | ||||
|         record = records[i]; | ||||
|         text += record.Id + '\t' + | ||||
|             record.RiskReductionMinusOpportunityEnablement + '\t' + | ||||
|             record.TimeCriticality + '\t' + | ||||
|             record.BusinessValue + '\t' + | ||||
|             record.CoD + '\t' + | ||||
|             record.Effort + '\t' + | ||||
|             record.WeightedShortestJobFirst + '\t' + | ||||
|             record.TotalStoryPoints.split(' ')[0] + '\t' + | ||||
|             record.AbsoluteDelta + '\t' + | ||||
|             record.State.split('-')[0] + '\t' + | ||||
|             record.Requester + '\t' + | ||||
|             record.AssignedTo + '\t' + | ||||
|             record.IterationPath + '\t' + | ||||
|             record.Tags + '\t' + | ||||
|             record.Title + '\r\n'; | ||||
|         lineA = '<tr id="tr' + record.Id + '"><td>' + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" + | ||||
|             '</td><td>' + record.ParentTitle + | ||||
|             '</td><td>' + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" + | ||||
|             '</td><td>' + record.Requester + | ||||
|             '</td><td>' + record.Title + | ||||
|             '</td><td>' + record.AssignedTo + | ||||
|             '</td><td>' + record.Tags + | ||||
|             '</td><td>' + record.State + | ||||
|             '</td><td>' + record.Priority + | ||||
|             '</td><td><span id=' + r.page + record.Id + '>' + record.RiskReductionMinusOpportunityEnablementNotifications + '</span><br />' + | ||||
|             '<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + r.page + '\', ' + record.Id + ')">' + | ||||
|             '<option value="9">Unknown</option>' + | ||||
|             '<option value="1">Highest (Most ' + r.description + ')</option>' + | ||||
|             '<option value="2">High</option>' + | ||||
|             '<option value="3">Medium</option>' + | ||||
|             '<option value="4">Low</option>' + | ||||
|             '<option value="5">Lowest</option>' + | ||||
|             '</select>' + | ||||
|             '</td><td><span id=' + t.page + record.Id + '>' + record.TimeCriticalityNotifications + '</span><br />' + | ||||
|             '<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + t.page + '\', ' + record.Id + ')">' + | ||||
|             '<option value="9">Unknown</option>' + | ||||
|             '<option value="1">Highest (Most ' + t.description + ')</option>' + | ||||
|             '<option value="2">High</option>' + | ||||
|             '<option value="3">Medium</option>' + | ||||
|             '<option value="4">Low</option>' + | ||||
|             '<option value="5">Lowest</option>' + | ||||
|             '</select>' + | ||||
|             '</td><td><span id=' + b.page + record.Id + '>' + record.BusinessValueNotifications + '</span><br />' + | ||||
|             '<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + b.page + '\', ' + record.Id + ')">' + | ||||
|             '<option value="9">Unknown</option>' + | ||||
|             '<option value="1">Highest (Most ' + b.description + ')</option>' + | ||||
|             '<option value="2">High</option>' + | ||||
|             '<option value="3">Medium</option>' + | ||||
|             '<option value="4">Low</option>' + | ||||
|             '<option value="5">Lowest</option>' + | ||||
|             '</select>' + | ||||
|             '</td><td><span id=' + c.page + record.Id + '>' + record.CoD + '</span>' + | ||||
|             '</td><td><span id=' + e.page + record.Id + '>' + record.EffortNotifications + '</span><br />'; | ||||
|         if (!fromHtml || _windowLocationHRef.indexOf('=EFFORT') === -1) { | ||||
|             lineB = ''; | ||||
|         } | ||||
|         else { | ||||
|             lineB = '<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + e.page + '\', ' + record.Id + ')">' + | ||||
|                 '<option value="9">Unknown</option>' + | ||||
|                 '<option value="1">Highest (Most ' + e.description + ')</option>' + | ||||
|                 '<option value="2">High</option>' + | ||||
|                 '<option value="3">Medium</option>' + | ||||
|                 '<option value="4">Low</option>' + | ||||
|                 '<option value="5">Lowest</option>' + | ||||
|                 '</select><br />'; | ||||
|         } | ||||
|         lineC = '<span>' + record.TotalStoryPoints + '</span></td>' + | ||||
|             '<td><span id=' + w.page + record.Id + '>' + record.WeightedShortestJobFirst + '<br /><span>' + record.CumulativeStoryPoints + '</span></span>' + | ||||
|             '</td></tr>'; | ||||
|         if (!fromHtml) | ||||
|             console.log(text); | ||||
|         html += lineA + lineB + lineC; | ||||
|     } | ||||
|     if (fromHtml) { | ||||
|         document.getElementById('HeaderGrid').innerHTML = html.replaceAll('>null<', '> <'); | ||||
|         if (_windowLocationHRef.indexOf('=WSJF') === -1) { | ||||
|             document.getElementById('AllTextarea').value = text.replaceAll('null', '').replaceAll(' ', ''); | ||||
|         } | ||||
|         else { | ||||
|             _toggle = !_toggle; | ||||
|             $(".select").hide(); | ||||
|             $("#AllTextarea").hide(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| function updateSite(c, w) { | ||||
|     if (_windowLocationHRef.indexOf('=LEO') > -1) { | ||||
|         _site = 'LEO'; | ||||
|         document.title = document.title.replace('Infineon', 'HiRel (Leominster)'); | ||||
|         document.getElementById('siteHeader').innerText = 'HiRel (Leominster)'; | ||||
|     } | ||||
|     else if (_windowLocationHRef.indexOf('=MES') > -1) { | ||||
|         _site = 'MES'; | ||||
|         document.title = document.title.replace('Infineon', 'Mesa'); | ||||
|         document.getElementById('siteHeader').innerText = 'Mesa'; | ||||
|     } | ||||
|     else { | ||||
|         _site = 'Infineon'; | ||||
|         document.title = document.title.replace('Infineon', 'Infineon'); | ||||
|         document.getElementById('siteHeader').innerText = 'Infineon'; | ||||
|     } | ||||
|     if (_windowLocationHRef.indexOf('=WSJF') > -1) { | ||||
|         document.getElementById('th-span').innerHTML = w.th + ' sorted by WSJF'; | ||||
|     } | ||||
|     else if (_windowLocationHRef.indexOf('=LIVE') > -1) { | ||||
|         document.getElementById('th-span').innerHTML = c.th + ' sorted by CoD'; | ||||
|     } | ||||
|     else if (_windowLocationHRef.indexOf('=EFFORT') > -1) { | ||||
|         document.getElementById('th-span').innerHTML = c.th + ' sorted by Parent Id'; | ||||
|     } | ||||
|     else { | ||||
|         document.getElementById('th-span').innerHTML = c.th + ' sorted by Parent Id'; | ||||
|     } | ||||
| } | ||||
|  | ||||
| function setDocument(fromHtml, b, r, t, c, e, w, dataA, dataB, workItems) { | ||||
|     let records = getRecords(b, r, t, c, e, w, dataA, dataB, workItems); | ||||
|     console.log(dataA.length); | ||||
|     if (dataA.length > 0) | ||||
|         console.log(dataA[0]); | ||||
|     setRecords(fromHtml, b, r, t, c, e, w, records); | ||||
|     $("#toggle").click(function () { | ||||
|         if (_toggle) | ||||
|             $(".select").hide(); | ||||
|         else | ||||
|             $(".select").show(); | ||||
|         _toggle = !_toggle; | ||||
|     }); | ||||
| } | ||||
|  | ||||
| function highlight(el, i) { | ||||
|     el.before("<tr/>") | ||||
|     el.prev() | ||||
|         .width(el.width()) | ||||
|         .height(el.height()) | ||||
|         .css({ | ||||
|             "position": "absolute", | ||||
|             "background-color": "#ffff99", | ||||
|             "opacity": ".9" | ||||
|         }) | ||||
|         .fadeOut(1000 * i); | ||||
| } | ||||
|  | ||||
| function updateWorkItem(b, r, t, c, e, w, page, workItem) { | ||||
|     console.log(workItem); | ||||
|     let x = null; | ||||
|     let aggregation = null; | ||||
|     if (page === b.page) { | ||||
|         x = b; | ||||
|         aggregation = workItem.BusinessValue; | ||||
|     } | ||||
|     else if (page === r.page) { | ||||
|         x = r; | ||||
|         aggregation = workItem.RiskReductionOpportunityEnablement; | ||||
|     } | ||||
|     else if (page === t.page) { | ||||
|         x = t; | ||||
|         aggregation = workItem.TimeCriticality; | ||||
|     } | ||||
|     else if (page === e.page) { | ||||
|         x = e; | ||||
|         aggregation = workItem.Effort; | ||||
|     } | ||||
|     if (x == undefined) | ||||
|         warn("Error with page!"); | ||||
|     else if (aggregation.FibonacciAverage == undefined) | ||||
|         warn("FibonacciAverage not set!"); | ||||
|     else { | ||||
|         $('#' + x.page + workItem.Id).text('!' + round(aggregation.FibonacciAverage, 100)); | ||||
|         if (workItem.WeightedShortestJobFirst != undefined) { | ||||
|             $('#' + w.page + workItem.Id).text('!' + round(workItem.WeightedShortestJobFirst, 100)); | ||||
|         } | ||||
|         if (workItem.CostOfDelay != undefined) { | ||||
|             let element = $('#' + c.page + workItem.Id); | ||||
|             element.text('!' + round(workItem.CostOfDelay, 100)); | ||||
|             if (_windowLocationHRef.indexOf('=LIVE') > -1) { | ||||
|                 if (workItem.SortBeforeId != undefined) { | ||||
|                     let found = 0; | ||||
|                     let row = element.parents("tr:first"); | ||||
|                     let next = row; | ||||
|                     for (let i = 0; i < 150; i++) { | ||||
|                         next = next.next(); | ||||
|                         if (next == undefined) | ||||
|                             break; | ||||
|                         if (next.attr('id') != 'tr' + workItem.SortBeforeId) | ||||
|                             continue; | ||||
|                         console.log("Moved " + i + " down"); | ||||
|                         row.insertAfter(next); | ||||
|                         found = i; | ||||
|                         break; | ||||
|                     } | ||||
|                     if (!found) { | ||||
|                         let prev = row; | ||||
|                         for (let i = 0; i < 150; i++) { | ||||
|                             prev = prev.prev(); | ||||
|                             if (prev == undefined) | ||||
|                                 break; | ||||
|                             if (prev.attr('id') != 'tr' + workItem.SortBeforeId) | ||||
|                                 continue; | ||||
|                             console.log("Moved " + i + " up"); | ||||
|                             row.insertAfter(prev); | ||||
|                             found = i; | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                     if (found != 0) { | ||||
|                         highlight(row, found); | ||||
|                     } | ||||
|                     else { | ||||
|                         console.log("Not found!"); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| }; | ||||
|  | ||||
| function setupPingPong() { | ||||
|     let notification = { | ||||
|         id: null, | ||||
|         machineId: _machineId, | ||||
|         page: _page, | ||||
|         sessionId: _sessionId, | ||||
|         site: _site, | ||||
|         time: new Date().getTime(), | ||||
|         username: _username, | ||||
|         value: null, | ||||
|     }; | ||||
|     $.get(_apiUrl, notification) | ||||
|         .done(function (data) { | ||||
|             if (data != undefined && data.length > 0) { | ||||
|                 keyValuePair = JSON.parse(data); | ||||
|                 if (keyValuePair.Key != undefined && keyValuePair.Value.Id != undefined && keyValuePair.Value != undefined) { | ||||
|                     updateWorkItem(_b, _r, _t, _c, _e, _w, keyValuePair.Key, keyValuePair.Value); | ||||
|                 } | ||||
|             } | ||||
|         }) | ||||
|         .fail(function (_, textStatus, _) { | ||||
|             warn(textStatus); | ||||
|         }); | ||||
| } | ||||
|  | ||||
| function initIndex(fromHtml, username, machineId, windowLocationHRef, workItems, b, r, t, c, e, w, apiUrl, _) { | ||||
|     _b = b; | ||||
|     _r = r; | ||||
|     _t = t; | ||||
|     _c = c; | ||||
|     _e = e; | ||||
|     _w = w; | ||||
|     _page = _b.page; | ||||
|     _apiUrl = apiUrl; | ||||
|     _username = username; | ||||
|     _machineId = machineId; | ||||
|     _windowLocationHRef = windowLocationHRef; | ||||
|     _sessionId = _windowLocationHRef.indexOf('=LIVE') > -1 ? self.crypto.randomUUID() : ''; | ||||
|     if (!fromHtml) { | ||||
|         console.log(b); | ||||
|         console.log(r); | ||||
|         console.log(t); | ||||
|         console.log(c); | ||||
|         console.log("Done :)"); | ||||
|     } | ||||
|     else { | ||||
|         updateSite(c, w); | ||||
|         $.getJSON(workItems.b, { _: new Date().getTime() }, function (dataB) { | ||||
|             $.getJSON(workItems.a, { _: new Date().getTime() }, function (dataA) { | ||||
|                 setDocument(fromHtml, b, r, t, c, e, w, dataA, dataB, workItems); | ||||
|                 if (_windowLocationHRef.indexOf('=LIVE') > -1) { | ||||
|                     _ = setInterval(setupPingPong, workItems.timeout); | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // #region Test | ||||
|  | ||||
| if (typeof document == 'undefined') { | ||||
|     const username = ''; | ||||
|     const machineId = ''; | ||||
|     const fromHtml = false; | ||||
|     const baseUri = 'http://eaf-dev.mes.infineon.com:5054'; | ||||
|     const apiUrl = baseUri + '/api/v1/ado/'; | ||||
|     const windowLocationHRef = baseUri + '/html/cod.html?site=MES'; | ||||
|     const signalRUrl = baseUri + '/signalr'; | ||||
|     const workItems = { | ||||
|         a: baseUri + '/markdown/bugs-features-with-parents.json?v=2025-04-14-08-10', | ||||
|         b: baseUri + '/markdown/{}.json?v=2025-04-14-08-10', | ||||
|         timeout: 3000, | ||||
|     }; | ||||
|     const b = { | ||||
|         page: "business", | ||||
|         description: "Value", | ||||
|         th: "Business Value", | ||||
|         span: "What is the relative value to the Customer or business?<br>• Do our users prefer this over that?<br>• What is the revenue impact on our business?<br>• Is there a potential penalty or other negative effects if we delay?" | ||||
|     }; | ||||
|     const r = { | ||||
|         page: "risk", | ||||
|         description: "Risk", | ||||
|         th: "Risk Reduction and/or Opportunity Enablement", | ||||
|         span: "What else does this do for our business?<br>• Reduce the risk of this or future delivery?<br>• Is there value in the information we will receive?<br>• Enable new business opportunities?" | ||||
|     }; | ||||
|     const t = { | ||||
|         page: "time", | ||||
|         description: "Critical", | ||||
|         th: "Time Criticality", | ||||
|         span: "How does user/business value decay over time?<br>• Is there a fixed deadline?<br>• Will they wait for us or move to another Solution?<br>• What is the current effect on Customer satisfaction?" | ||||
|     }; | ||||
|     const c = { | ||||
|         page: "cod", | ||||
|         description: "CoD", | ||||
|         th: "Cost of Delay (CoD)", | ||||
|         span: "Cost of Delay (CoD) is the money lost by delaying or not doing a job for a specific time. It's a measure of the economic value of a job over time." | ||||
|     }; | ||||
|     const e = { | ||||
|         page: "effort", | ||||
|         description: "Effort", | ||||
|         th: "Effort", | ||||
|         span: "Effort" | ||||
|     }; | ||||
|     const w = { | ||||
|         page: "wsjf", | ||||
|         description: "WSJF", | ||||
|         th: "Weightest Shortest Job First calculation (WSJF)", | ||||
|         span: "Weightest Shortest Job First calculation (see @SCALE formula)" | ||||
|     }; | ||||
|     _windowLocationHRef = windowLocationHRef; | ||||
|     fetch(workItems.b, { _: new Date().getTime() }) | ||||
|         .then((res) => res.text()) | ||||
|         .then((textB) => { | ||||
|             fetch(workItems.a, { _: new Date().getTime() }) | ||||
|                 .then((res) => res.text()) | ||||
|                 .then((textA) => { | ||||
|                     const dataA = JSON.parse(textA); | ||||
|                     const dataB = JSON.parse(textB); | ||||
|                     if (dataA.length > 0) | ||||
|                         console.log(dataA[0]); | ||||
|                     const records = getRecords(b, r, t, c, e, w, dataA, dataB, workItems); | ||||
|                     setRecords(fromHtml, b, r, t, c, e, w, records); | ||||
|                     initIndex(fromHtml, username, machineId, windowLocationHRef, workItems, b, r, t, c, e, w, apiUrl, signalRUrl); | ||||
|                 }) | ||||
|                 .catch((e) => console.error(e)); | ||||
|         }) | ||||
|         .catch((e) => console.error(e)); | ||||
| } | ||||
|  | ||||
| // #endregion Test | ||||
							
								
								
									
										497
									
								
								Adaptation/FileHandlers/json/StaticSite/js/cod-1-123-0-.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										497
									
								
								Adaptation/FileHandlers/json/StaticSite/js/cod-1-123-0-.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,497 @@ | ||||
| var _b = {}; | ||||
| var _c = {}; | ||||
| var _e = {}; | ||||
| var _r = {}; | ||||
| var _t = {}; | ||||
| var _w = {}; | ||||
| var _page = ''; | ||||
| var _site = ''; | ||||
| var _apiUrl = ''; | ||||
| var _toggle = true; | ||||
| var _username = ''; | ||||
| var _machineId = ''; | ||||
| var _sessionId = ''; | ||||
| var _windowLocationHRef = ''; | ||||
|  | ||||
| function compareFunctionEffort(a: any, b: any) { | ||||
|     if (a.Effort == undefined || a.Effort === ' ') { | ||||
|         return -1; | ||||
|     } | ||||
|     if (b.Effort !== a.Effort) { | ||||
|         return b.Effort - a.Effort; | ||||
|     } | ||||
|     return b.WeightedShortestJobFirst - a.WeightedShortestJobFirst; | ||||
| } | ||||
|  | ||||
| function compareFunctionSortOrder(a: any, b: any) { | ||||
|     if (a.SortOrder == undefined || a.SortOrder === ' ') { | ||||
|         return -1; | ||||
|     } | ||||
|     return a.SortOrder - b.SortOrder | ||||
| } | ||||
|  | ||||
| function compareFunctionWeightedShortestJobFirst(a: any, b: any) { | ||||
|     if (b.WeightedShortestJobFirst == undefined || b.WeightedShortestJobFirst === ' ') { | ||||
|         return -1; | ||||
|     } | ||||
|     return b.WeightedShortestJobFirst - a.WeightedShortestJobFirst; | ||||
| } | ||||
|  | ||||
| function compareFunctionWeightedShortestJobFirstNullFirst(a: any, b: any) { | ||||
|     if (a.WeightedShortestJobFirst == undefined || a.WeightedShortestJobFirst === ' ') { | ||||
|         return -1; | ||||
|     } | ||||
|     return b.WeightedShortestJobFirst - a.WeightedShortestJobFirst; | ||||
| } | ||||
|  | ||||
| function getState(state: any) { | ||||
|     let result; | ||||
|     if (state == undefined) | ||||
|         result = '9-Null'; | ||||
|     else if (state === 'New') | ||||
|         result = `1-${state}`; | ||||
|     else if (state === 'Active') | ||||
|         result = `2-${state}`; | ||||
|     else if (state === 'Resolved') | ||||
|         result = `3-${state}`; | ||||
|     else if (state === 'Closed') | ||||
|         result = `4-${state}`; | ||||
|     else if (state === 'Removed') | ||||
|         result = `5-${state}`; | ||||
|     else | ||||
|         result = `8-${state}`; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function getPriority(workItemType: any, priority: any, sortPriorityGroup: any) { | ||||
|     let result; | ||||
|     if (workItemType === 'Bug') | ||||
|         result = '0-Bug {0}'; | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = '9-Null {0}'; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High {${sortPriorityGroup}}`; | ||||
|     else if (priority === 2) | ||||
|         result = `${priority}-Med {${sortPriorityGroup}}`; | ||||
|     else if (priority === 3) | ||||
|         result = `${priority}-Low {${sortPriorityGroup}}`; | ||||
|     else if (priority === 4) | ||||
|         result = `${priority}-TBD {4}`; | ||||
|     else | ||||
|         result = '8-Not {0}'; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function getNotifications(x: any, aggregation: any) { | ||||
|     let result: any; | ||||
|     if (aggregation == undefined || aggregation.Notifications == undefined || aggregation.Notifications.length === 0) | ||||
|         result = ' '; | ||||
|     else { | ||||
|         result = ''; | ||||
|         aggregation.Notifications.forEach((element: any) => { | ||||
|             const username = element.username == null ? 'user' : element.username; | ||||
|             if (element.value === '1') { | ||||
|                 result += 'Highest:' + username + ';|'; | ||||
|             } | ||||
|             else if (element.value === '2') { | ||||
|                 result += 'High:' + username + ';|'; | ||||
|             } | ||||
|             else if (element.value === '3') { | ||||
|                 result += 'Medium:' + username + ';|'; | ||||
|             } | ||||
|             else if (element.value === '4') { | ||||
|                 result += 'Low:' + username + ';|'; | ||||
|             } | ||||
|             else if (element.value === '5') { | ||||
|                 result += 'Lowest:' + username + ';|'; | ||||
|             } | ||||
|             else { | ||||
|                 result += element.value + ':' + username + ';|'; | ||||
|             } | ||||
|         }); | ||||
|         result = result.substring(0, result.length - 1); | ||||
|         result = result.replaceAll('|', '<br />'); | ||||
|     } | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function round(value: any, factor: number) { | ||||
|     return (Math.round((value + Number.EPSILON) * factor) / factor).toFixed(2); | ||||
| } | ||||
|  | ||||
| function roundMultiply(value: any, factor: number, multiply: number) { | ||||
|     return (Math.round((value + Number.EPSILON) * factor) / factor) * multiply; | ||||
| } | ||||
|  | ||||
| function sum(collection: any) { | ||||
|     let sum = 0; | ||||
|     if (collection != undefined) { | ||||
|         for (let i = 0; i < collection.length; i++) { | ||||
|             sum += collection[i]; | ||||
|         } | ||||
|     } | ||||
|     return sum; | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(b: any, r: any, t: any, c: any, e: any, w: any, workItem: any, highestTotalStoryPoints: any, dataB: any, totalStoryPoints: any) { | ||||
|     if (workItem != undefined) { | ||||
|         let data = dataB == undefined ? undefined : dataB[workItem.Id]; | ||||
|         if (data == undefined) { | ||||
|             workItem.api = ''; | ||||
|             workItem.CumulativeStoryPoints = ' '; | ||||
|             workItem.TotalStoryPoints = ' '; | ||||
|             workItem.AbsoluteDelta = ' '; | ||||
|             workItem.Effort = ' '; | ||||
|             workItem.BusinessValue = ' '; | ||||
|             workItem.TimeCriticality = ' '; | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = ' '; | ||||
|             workItem.CoD = ' '; | ||||
|             workItem.WeightedShortestJobFirst = ' '; | ||||
|             workItem.Priority = getPriority(workItem.WorkItemType, 4, 0); | ||||
|             workItem.EffortNotifications = ' '; | ||||
|             workItem.BusinessValueNotifications = ' '; | ||||
|             workItem.TimeCriticalityNotifications = ' '; | ||||
|             workItem.RiskReductionMinusOpportunityEnablementNotifications = ' '; | ||||
|             workItem.SortOrder = 0; | ||||
|         } | ||||
|         else { | ||||
|             let effort = workItem.Effort; | ||||
|             let businessValue = workItem.BusinessValue; | ||||
|             let timeCriticality = workItem.TimeCriticality; | ||||
|             let riskReductionMinusOpportunityEnablement = workItem.RiskReductionMinusOpportunityEnablement; | ||||
|             let weightedShortestJobFirst = workItem.WeightedShortestJobFirst == undefined ? null : workItem.WeightedShortestJobFirst.toFixed(2); | ||||
|             let weightedShortestJobFirstFibonacci = workItem.WeightedShortestJobFirstFibonacci == undefined ? null : workItem.WeightedShortestJobFirstFibonacci.toFixed(2); | ||||
|             if (weightedShortestJobFirst == null || weightedShortestJobFirstFibonacci == null || weightedShortestJobFirst != weightedShortestJobFirstFibonacci) { | ||||
|                 if (weightedShortestJobFirst != weightedShortestJobFirstFibonacci) { | ||||
|  | ||||
|                 } | ||||
|             } | ||||
|             if (workItem.Id === 330178) { | ||||
|                 if (weightedShortestJobFirst != weightedShortestJobFirstFibonacci) { | ||||
|  | ||||
|                 } | ||||
|             } | ||||
|             workItem.CumulativeStoryPoints = ' '; | ||||
|             workItem.TotalStoryPoints = totalStoryPoints + ' User Story Point(s)'; | ||||
|             workItem.AbsoluteDelta = data.Effort == undefined || data.Effort.FibonacciAverage == undefined || totalStoryPoints == undefined || totalStoryPoints === 0 ? ' ' : round(Math.abs(data.Effort.FibonacciAverage - ((totalStoryPoints / highestTotalStoryPoints) * 5)), 1); | ||||
|             workItem.Effort = data.Effort == undefined || data.Effort.FibonacciAverage == undefined ? ' ' : roundMultiply(data.Effort.FibonacciAverage, 100, 100); | ||||
|             workItem.BusinessValue = data.BusinessValue == undefined || data.BusinessValue.FibonacciAverage == undefined ? ' ' : roundMultiply(data.BusinessValue.FibonacciAverage, 100, 100); | ||||
|             workItem.TimeCriticality = data.TimeCriticality == undefined || data.TimeCriticality.FibonacciAverage == undefined ? ' ' : roundMultiply(data.TimeCriticality.FibonacciAverage, 100, 100); | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = data.RiskReductionOpportunityEnablement == undefined || data.RiskReductionOpportunityEnablement.FibonacciAverage == undefined ? ' ' : roundMultiply(data.RiskReductionOpportunityEnablement.FibonacciAverage, 100, 100); | ||||
|             workItem.CoD = data.CostOfDelay == undefined ? ' ' : roundMultiply(data.CostOfDelay, 100, 100); | ||||
|             workItem.WeightedShortestJobFirst = data.WeightedShortestJobFirst == undefined ? ' ' : round(data.WeightedShortestJobFirst, 100); | ||||
|             workItem.Priority = data.SortPriority == undefined ? getPriority(workItem.WorkItemType, 4, 0) : getPriority(workItem.WorkItemType, data.SortPriority, data.SortPriorityGroup); | ||||
|             workItem.EffortNotifications = data.Effort == undefined ? ' ' : getNotifications(e, data.Effort); | ||||
|             workItem.BusinessValueNotifications = data.BusinessValue == undefined ? ' ' : getNotifications(b, data.BusinessValue); | ||||
|             workItem.TimeCriticalityNotifications = data.TimeCriticality == undefined ? ' ' : getNotifications(t, data.TimeCriticality); | ||||
|             workItem.RiskReductionMinusOpportunityEnablementNotifications = data.RiskReductionOpportunityEnablement == undefined ? ' ' : getNotifications(r, data.RiskReductionOpportunityEnablement); | ||||
|             workItem.SortOrder = data.SortOrder == undefined ? 0 : data.SortOrder; | ||||
|             if (workItem.Effort == undefined || | ||||
|                 workItem.BusinessValue == undefined || | ||||
|                 workItem.TimeCriticality == undefined || | ||||
|                 workItem.RiskReductionMinusOpportunityEnablement == undefined || | ||||
|                 workItem.WeightedShortestJobFirst == undefined || | ||||
|                 workItem.Effort == ' ' || | ||||
|                 workItem.BusinessValue == ' ' || | ||||
|                 workItem.TimeCriticality == ' ' || | ||||
|                 workItem.RiskReductionMinusOpportunityEnablement == ' ' || | ||||
|                 workItem.WeightedShortestJobFirst == ' ') { | ||||
|                 workItem.api = ''; | ||||
|             } | ||||
|             else { | ||||
|                 let check = effort === workItem.Effort | ||||
|                     && businessValue === workItem.BusinessValue | ||||
|                     && timeCriticality === workItem.TimeCriticality | ||||
|                     && riskReductionMinusOpportunityEnablement === workItem.RiskReductionMinusOpportunityEnablement; | ||||
|                 if (check && weightedShortestJobFirst == workItem.WeightedShortestJobFirst) { | ||||
|                     workItem.api = ''; | ||||
|                 } else { | ||||
|                     workItem.api = ` | ||||
| ### Work Item Patch ${check} WSJF ${workItem.Id} ${effort}:${workItem.Effort}; ${businessValue}:${workItem.BusinessValue}; ${timeCriticality}:${workItem.TimeCriticality}; ${riskReductionMinusOpportunityEnablement}:${workItem.RiskReductionMinusOpportunityEnablement}; ${weightedShortestJobFirst}:${workItem.WeightedShortestJobFirst}; | ||||
|  | ||||
| PATCH https://tfs.intra.infineon.com/tfs/FactoryIntegration/_apis/wit/workitems/${workItem.Id}?api-version=7.0 | ||||
| Authorization: Basic {{PAT}} | ||||
| Content-Type: application/json-patch+json | ||||
|  | ||||
| [ | ||||
|     { | ||||
|         "op": "replace", | ||||
|         "path": "/fields/Microsoft.VSTS.Common.BusinessValue", | ||||
|         "value": "${workItem.BusinessValue}" | ||||
|     }, | ||||
|     { | ||||
|         "op": "replace", | ||||
|         "path": "/fields/Microsoft.VSTS.Scheduling.Effort", | ||||
|         "value": "${workItem.Effort}" | ||||
|     }, | ||||
|     { | ||||
|         "op": "replace", | ||||
|         "path": "/fields/Custom.RRminusOE", | ||||
|         "value": "${workItem.RiskReductionMinusOpportunityEnablement}" | ||||
|     }, | ||||
|     { | ||||
|         "op": "replace", | ||||
|         "path": "/fields/Microsoft.VSTS.Common.TimeCriticality", | ||||
|         "value": "${workItem.TimeCriticality}" | ||||
|     }, | ||||
|     { | ||||
|         "op": "replace", | ||||
|         "path": "/fields/Custom.WSJF", | ||||
|         "value": "${workItem.WeightedShortestJobFirst}" | ||||
|     }, | ||||
|     { | ||||
|         "op": "replace", | ||||
|         "path": "/fields/Custom.WSJFFib", | ||||
|         "value": "${workItem.WeightedShortestJobFirst}" | ||||
|     } | ||||
| ] | ||||
|  | ||||
| HTTP 200 | ||||
| [Asserts] | ||||
| header "Content-Type" == "application/json; charset=utf-8; api-version=7.0" | ||||
| jsonpath "$.id" == ${workItem.Id} | ||||
| jsonpath "$.fields['Microsoft.VSTS.Common.BusinessValue']" == ${workItem.BusinessValue} | ||||
| jsonpath "$.fields['Microsoft.VSTS.Scheduling.Effort']" == ${workItem.Effort} | ||||
| jsonpath "$.fields['Custom.RRminusOE']" == ${workItem.RiskReductionMinusOpportunityEnablement} | ||||
| jsonpath "$.fields['Microsoft.VSTS.Common.TimeCriticality']" == ${workItem.TimeCriticality} | ||||
| jsonpath "$.fields['Custom.WSJF']" == ${workItem.WeightedShortestJobFirst} | ||||
| jsonpath "$.fields['Custom.WSJFFib']" == ${workItem.WeightedShortestJobFirst}`; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent: any, workItem: any) { | ||||
|     if (parent == undefined) { | ||||
|         workItem.ParentId = 9999999; | ||||
|         workItem.ParentTitle = null; | ||||
|         workItem.ParentState = null; | ||||
|         workItem.ParentCoD = 9999999; | ||||
|     } | ||||
|     else { | ||||
|         workItem.ParentId = parent.Id; | ||||
|         workItem.ParentCoD = parent.CoD; | ||||
|         workItem.ParentTitle = parent.Title; | ||||
|         workItem.ParentState = getState(parent.State); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function getRecords(b: any, r: any, t: any, c: any, e: any, w: any, data: any, dataB: any, workItems: any) { | ||||
|     let parent; | ||||
|     let workItem; | ||||
|     let storyPoints; | ||||
|     let records = []; | ||||
|     let totalStoryPoints; | ||||
|     let highestTotalStoryPoints = 0; | ||||
|     for (let i = 0; i < data.length; i++) { | ||||
|         workItem = data[i].WorkItem; | ||||
|         if (workItem.WorkItemType !== 'Feature') | ||||
|             continue; | ||||
|         if (workItem.State !== 'Active' && workItem.State !== 'New') | ||||
|             continue; | ||||
|         if (workItem.Tags != null && workItem.Tags.includes('Ignore')) | ||||
|             continue; | ||||
|         storyPoints = data[i].Tag?.StoryPoints == undefined ? null : JSON.parse(data[i].Tag.StoryPoints); | ||||
|         totalStoryPoints = sum(storyPoints); | ||||
|         if (totalStoryPoints > highestTotalStoryPoints) | ||||
|             highestTotalStoryPoints = totalStoryPoints; | ||||
|     } | ||||
|     for (let i = 0; i < data.length; i++) { | ||||
|         parent = data[i].Parent; | ||||
|         workItem = data[i].WorkItem; | ||||
|         if (workItem.WorkItemType !== 'Feature') | ||||
|             continue; | ||||
|         if (workItem.State !== 'Active' && workItem.State !== 'New') | ||||
|             continue; | ||||
|         if (workItem.Tags != null && workItem.Tags.includes('Ignore')) | ||||
|             continue; | ||||
|         storyPoints = data[i].Tag?.StoryPoints == undefined ? null : JSON.parse(data[i].Tag.StoryPoints); | ||||
|         totalStoryPoints = sum(storyPoints); | ||||
|         if ((_windowLocationHRef.indexOf('=LEO') > -1 && workItem.AreaPath !== 'ART SPS\\LEO') || (_windowLocationHRef.indexOf('=MES') > -1 && workItem.AreaPath !== 'ART SPS\\MES')) | ||||
|             continue; | ||||
|         updateRecordParent(parent, workItem); | ||||
|         updateRecordCoD(b, r, t, c, e, w, parent, highestTotalStoryPoints, null, null); | ||||
|         updateRecordCoD(b, r, t, c, e, w, workItem, highestTotalStoryPoints, dataB, totalStoryPoints); | ||||
|         workItem.State = getState(workItem.State); | ||||
|         records.push(workItem); | ||||
|     } | ||||
|     if (_windowLocationHRef.indexOf('=EFFORT') > -1) { | ||||
|         records.sort(compareFunctionEffort); | ||||
|     } | ||||
|     else if (_windowLocationHRef.indexOf('=LIVE') > -1) { | ||||
|         records.sort(compareFunctionSortOrder); | ||||
|     } | ||||
|     else if (_windowLocationHRef.indexOf('=WSJF') > -1) { | ||||
|         records.sort(compareFunctionWeightedShortestJobFirst); | ||||
|     } | ||||
|     else { | ||||
|         records.sort(compareFunctionWeightedShortestJobFirstNullFirst); | ||||
|     } | ||||
|     return records; | ||||
| } | ||||
|  | ||||
| function getHtmlTextAndApi(fromHtml: any, b: any, r: any, t: any, c: any, e: any, w: any, records: any) { | ||||
|     let record; | ||||
|     let lineA = ''; | ||||
|     let lineB = ''; | ||||
|     let lineC = ''; | ||||
|     let api = ` | ||||
| ### FactoryIntegration (hurl.exe) | ||||
|  | ||||
| GET https://tfs.intra.infineon.com/tfs/FactoryIntegration | ||||
|  | ||||
| HTTP 401 | ||||
| [Asserts] | ||||
| duration < 12345 | ||||
|  | ||||
| `; | ||||
|     let text = 'Id\tRisk Reduction and/or Opportunity Enablement\tTime Criticality\tBusiness Value\tEffort\tWSJF\tCoD\tFeature Total Story Points\tAbsolute Delta\tState\tRequester\tAssigned To\tIteration Path\tSystem\tTitle-123\r\n'; | ||||
|     let html = '<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Priority</th><th>Risk Reduction and/or Opportunity Enablement</th><th>Time Criticality</th><th>Business Value</th><th>Cost of Delay (CoD)</th><th>Effort</th><th>WSJF</th></tr>'; | ||||
|     for (let i = 0; i < records.length; i++) { | ||||
|         record = records[i]; | ||||
|         if (record.api !== '') { | ||||
|             api += record.api + '\r\n'; | ||||
|         } | ||||
|         text += record.Id + '\t' + | ||||
|             record.RiskReductionMinusOpportunityEnablement + '\t' + | ||||
|             record.TimeCriticality + '\t' + | ||||
|             record.BusinessValue + '\t' + | ||||
|             record.Effort + '\t' + | ||||
|             record.WeightedShortestJobFirst + '\t' + | ||||
|             record.CoD + '\t' + | ||||
|             record.TotalStoryPoints.split(' ')[0] + '\t' + | ||||
|             record.AbsoluteDelta + '\t' + | ||||
|             record.State.split('-')[0] + '\t' + | ||||
|             record.Requester + '\t' + | ||||
|             record.AssignedTo + '\t' + | ||||
|             record.IterationPath + '\t' + | ||||
|             record.Tags + '\t' + | ||||
|             record.Title + '\r\n'; | ||||
|         lineA = '<tr id="tr' + record.Id + '"><td>' + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" + | ||||
|             '</td><td>' + record.ParentTitle + | ||||
|             '</td><td>' + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" + | ||||
|             '</td><td>' + record.Requester + | ||||
|             '</td><td>' + record.Title + | ||||
|             '</td><td>' + record.AssignedTo + | ||||
|             '</td><td>' + record.Tags + | ||||
|             '</td><td>' + record.State + | ||||
|             '</td><td>' + record.Priority + | ||||
|             '</td><td><span id=' + r.page + record.Id + '>' + record.RiskReductionMinusOpportunityEnablementNotifications + '</span><br />' + | ||||
|             '<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + r.page + '\', ' + record.Id + ')">' + | ||||
|             '<option value="9">Unknown</option>' + | ||||
|             '<option value="1">Highest (Most ' + r.description + ')</option>' + | ||||
|             '<option value="2">High</option>' + | ||||
|             '<option value="3">Medium</option>' + | ||||
|             '<option value="4">Low</option>' + | ||||
|             '<option value="5">Lowest</option>' + | ||||
|             '</select>' + | ||||
|             '</td><td><span id=' + t.page + record.Id + '>' + record.TimeCriticalityNotifications + '</span><br />' + | ||||
|             '<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + t.page + '\', ' + record.Id + ')">' + | ||||
|             '<option value="9">Unknown</option>' + | ||||
|             '<option value="1">Highest (Most ' + t.description + ')</option>' + | ||||
|             '<option value="2">High</option>' + | ||||
|             '<option value="3">Medium</option>' + | ||||
|             '<option value="4">Low</option>' + | ||||
|             '<option value="5">Lowest</option>' + | ||||
|             '</select>' + | ||||
|             '</td><td><span id=' + b.page + record.Id + '>' + record.BusinessValueNotifications + '</span><br />' + | ||||
|             '<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + b.page + '\', ' + record.Id + ')">' + | ||||
|             '<option value="9">Unknown</option>' + | ||||
|             '<option value="1">Highest (Most ' + b.description + ')</option>' + | ||||
|             '<option value="2">High</option>' + | ||||
|             '<option value="3">Medium</option>' + | ||||
|             '<option value="4">Low</option>' + | ||||
|             '<option value="5">Lowest</option>' + | ||||
|             '</select>' + | ||||
|             '</td><td><span id=' + c.page + record.Id + '>' + record.CoD + '</span>' + | ||||
|             '</td><td><span id=' + e.page + record.Id + '>' + record.EffortNotifications + '</span><br />'; | ||||
|         if (!fromHtml || _windowLocationHRef.indexOf('=EFFORT') === -1) { | ||||
|             lineB = ''; | ||||
|         } | ||||
|         else { | ||||
|             lineB = '<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + e.page + '\', ' + record.Id + ')">' + | ||||
|                 '<option value="9">Unknown</option>' + | ||||
|                 '<option value="1">Highest (Most ' + e.description + ')</option>' + | ||||
|                 '<option value="2">High</option>' + | ||||
|                 '<option value="3">Medium</option>' + | ||||
|                 '<option value="4">Low</option>' + | ||||
|                 '<option value="5">Lowest</option>' + | ||||
|                 '</select><br />'; | ||||
|         } | ||||
|         lineC = '<span>' + record.TotalStoryPoints + '</span></td>' + | ||||
|             '<td><span id=' + w.page + record.Id + '>' + record.WeightedShortestJobFirst + '<br /><span>' + record.CumulativeStoryPoints + '</span></span>' + | ||||
|             '</td></tr>'; | ||||
|         if (!fromHtml) | ||||
|             console.log(text); | ||||
|         html += lineA + lineB + lineC; | ||||
|     } | ||||
|     return { html, text, api }; | ||||
| } | ||||
|  | ||||
| const username = ''; | ||||
| const machineId = ''; | ||||
| const fromHtml = false; | ||||
| const baseUri = 'http://eaf-dev.mes.infineon.com:5054'; | ||||
| const apiUrl = baseUri + '/api/v1/ado/'; | ||||
| const windowLocationHRef = baseUri + '/html/cod.html?site=MES'; | ||||
| const signalRUrl = baseUri + '/signalr'; | ||||
| const workItems = { | ||||
|     a: baseUri + '/markdown/bugs-features-with-parents.json?v=2025-04-14-08-10', | ||||
|     b: baseUri + '/markdown/{}.json?v=2025-04-14-08-10', | ||||
|     timeout: 3000, | ||||
| }; | ||||
| const b = { | ||||
|     page: 'business', | ||||
|     description: 'Value', | ||||
|     th: 'Business Value', | ||||
|     span: 'What is the relative value to the Customer or business?<br>• Do our users prefer this over that?<br>• What is the revenue impact on our business?<br>• Is there a potential penalty or other negative effects if we delay?' | ||||
| }; | ||||
| const r = { | ||||
|     page: 'risk', | ||||
|     description: 'Risk', | ||||
|     th: 'Risk Reduction and/or Opportunity Enablement', | ||||
|     span: 'What else does this do for our business?<br>• Reduce the risk of this or future delivery?<br>• Is there value in the information we will receive?<br>• Enable new business opportunities?' | ||||
| }; | ||||
| const t = { | ||||
|     page: 'time', | ||||
|     description: 'Critical', | ||||
|     th: 'Time Criticality', | ||||
|     span: 'How does user/business value decay over time?<br>• Is there a fixed deadline?<br>• Will they wait for us or move to another Solution?<br>• What is the current effect on Customer satisfaction?' | ||||
| }; | ||||
| const c = { | ||||
|     page: 'cod', | ||||
|     description: 'CoD', | ||||
|     th: 'Cost of Delay (CoD)', | ||||
|     span: "Cost of Delay (CoD) is the money lost by delaying or not doing a job for a specific time. It's a measure of the economic value of a job over time." | ||||
| }; | ||||
| const e = { | ||||
|     page: 'effort', | ||||
|     description: 'Effort', | ||||
|     th: 'Effort', | ||||
|     span: 'Effort' | ||||
| }; | ||||
| const w = { | ||||
|     page: 'wsjf', | ||||
|     description: 'WSJF', | ||||
|     th: 'Weightest Shortest Job First calculation (WSJF)', | ||||
|     span: 'Weightest Shortest Job First calculation (see @SCALE formula)' | ||||
| }; | ||||
| _windowLocationHRef = windowLocationHRef; | ||||
| fetch(workItems.b) | ||||
|     .then((res) => res.text()) | ||||
|     .then((textB) => { | ||||
|         fetch(workItems.a) | ||||
|             .then((res) => res.text()) | ||||
|             .then((textA) => { | ||||
|                 const dataA = JSON.parse(textA); | ||||
|                 const dataB = JSON.parse(textB); | ||||
|                 if (dataA.length > 0) | ||||
|                     console.log(dataA[0]); | ||||
|                 const records = getRecords(b, r, t, c, e, w, dataA, dataB, workItems); | ||||
|                 let result = getHtmlTextAndApi(fromHtml, b, r, t, c, e, w, records); | ||||
|                 if (result == undefined) { } | ||||
|             }) | ||||
|             .catch((e) => console.error(e)); | ||||
|     }) | ||||
|     .catch((e) => console.error(e)); | ||||
							
								
								
									
										726
									
								
								Adaptation/FileHandlers/json/StaticSite/js/cod-1-123-0.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										726
									
								
								Adaptation/FileHandlers/json/StaticSite/js/cod-1-123-0.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,726 @@ | ||||
| var _b = {}; | ||||
| var _c = {}; | ||||
| var _e = {}; | ||||
| var _r = {}; | ||||
| var _t = {}; | ||||
| var _w = {}; | ||||
| var _page = ''; | ||||
| var _site = ''; | ||||
| var _apiUrl = ''; | ||||
| var _toggle = true; | ||||
| var _username = ''; | ||||
| var _machineId = ''; | ||||
| var _sessionId = ''; | ||||
| var _windowLocationHRef = ''; | ||||
|  | ||||
| function compareFunctionEffort(a, b) { | ||||
|     if (a.Effort == undefined || a.Effort === ' ') { | ||||
|         return -1; | ||||
|     } | ||||
|     if (b.Effort !== a.Effort) { | ||||
|         return b.Effort - a.Effort; | ||||
|     } | ||||
|     return b.WeightedShortestJobFirst - a.WeightedShortestJobFirst; | ||||
| } | ||||
|  | ||||
| function compareFunctionSortOrder(a, b) { | ||||
|     return a.SortOrder - b.SortOrder | ||||
| } | ||||
|  | ||||
| function compareFunctionWeightedShortestJobFirst(a, b) { | ||||
|     if (b.WeightedShortestJobFirst == undefined || b.WeightedShortestJobFirst === ' ') { | ||||
|         return -1; | ||||
|     } | ||||
|     return b.WeightedShortestJobFirst - a.WeightedShortestJobFirst; | ||||
| } | ||||
|  | ||||
| function compareFunctionWeightedShortestJobFirstNullFirst(a, b) { | ||||
|     if (a.WeightedShortestJobFirst == undefined || a.WeightedShortestJobFirst === ' ') { | ||||
|         return -1; | ||||
|     } | ||||
|     return b.WeightedShortestJobFirst - a.WeightedShortestJobFirst; | ||||
| } | ||||
|  | ||||
| function getState(state) { | ||||
|     let result; | ||||
|     if (state == undefined) | ||||
|         result = '9-Null'; | ||||
|     else if (state === 'New') | ||||
|         result = `1-${state}`; | ||||
|     else if (state === 'Active') | ||||
|         result = `2-${state}`; | ||||
|     else if (state === 'Resolved') | ||||
|         result = `3-${state}`; | ||||
|     else if (state === 'Closed') | ||||
|         result = `4-${state}`; | ||||
|     else if (state === 'Removed') | ||||
|         result = `5-${state}`; | ||||
|     else | ||||
|         result = `8-${state}`; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function getPriority(workItemType, priority, sortPriorityGroup) { | ||||
|     let result; | ||||
|     if (workItemType === 'Bug') | ||||
|         result = '0-Bug {0}'; | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = '9-Null {0}'; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High {${sortPriorityGroup}}`; | ||||
|     else if (priority === 2) | ||||
|         result = `${priority}-Med {${sortPriorityGroup}}`; | ||||
|     else if (priority === 3) | ||||
|         result = `${priority}-Low {${sortPriorityGroup}}`; | ||||
|     else if (priority === 4) | ||||
|         result = `${priority}-TBD {4}`; | ||||
|     else | ||||
|         result = '8-Not {0}'; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function getNotifications(x, aggregation) { | ||||
|     let result; | ||||
|     if (aggregation == undefined || aggregation.Notifications == undefined || aggregation.Notifications.length === 0) | ||||
|         result = ' '; | ||||
|     else { | ||||
|         result = ''; | ||||
|         aggregation.Notifications.forEach(element => { | ||||
|             const username = element.username == null ? 'user' : element.username; | ||||
|             if (element.value === '1') { | ||||
|                 result += 'Highest:' + username + ';|'; | ||||
|             } | ||||
|             else if (element.value === '2') { | ||||
|                 result += 'High:' + username + ';|'; | ||||
|             } | ||||
|             else if (element.value === '3') { | ||||
|                 result += 'Medium:' + username + ';|'; | ||||
|             } | ||||
|             else if (element.value === '4') { | ||||
|                 result += 'Low:' + username + ';|'; | ||||
|             } | ||||
|             else if (element.value === '5') { | ||||
|                 result += 'Lowest:' + username + ';|'; | ||||
|             } | ||||
|             else { | ||||
|                 result += element.value + ':' + username + ';|'; | ||||
|             } | ||||
|         }); | ||||
|         result = result.substring(0, result.length - 1); | ||||
|         result = result.replaceAll('|', '<br />'); | ||||
|     } | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function round(value, factor) { | ||||
|     return (Math.round((value + Number.EPSILON) * factor) / factor).toFixed(2); | ||||
| } | ||||
|  | ||||
| function roundMultiply(value, factor, multiply) { | ||||
|     return (Math.round((value + Number.EPSILON) * factor) / factor) * multiply; | ||||
| } | ||||
|  | ||||
| function sum(collection) { | ||||
|     let sum = 0; | ||||
|     if (collection != undefined) { | ||||
|         for (let i = 0; i < collection.length; i++) { | ||||
|             sum += collection[i]; | ||||
|         } | ||||
|     } | ||||
|     return sum; | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(b, r, t, c, e, w, workItem, highestTotalStoryPoints, dataB, totalStoryPoints) { | ||||
|     if (workItem != undefined) { | ||||
|         let data = dataB == undefined ? undefined : dataB[workItem.Id]; | ||||
|         if (data == undefined) { | ||||
|             workItem.api = ''; | ||||
|             workItem.CumulativeStoryPoints = ' '; | ||||
|             workItem.TotalStoryPoints = ' '; | ||||
|             workItem.AbsoluteDelta = ' '; | ||||
|             workItem.Effort = ' '; | ||||
|             workItem.BusinessValue = ' '; | ||||
|             workItem.TimeCriticality = ' '; | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = ' '; | ||||
|             workItem.CoD = ' '; | ||||
|             workItem.WeightedShortestJobFirst = ' '; | ||||
|             workItem.Priority = getPriority(workItem.WorkItemType, 4, 0); | ||||
|             workItem.EffortNotifications = ' '; | ||||
|             workItem.BusinessValueNotifications = ' '; | ||||
|             workItem.TimeCriticalityNotifications = ' '; | ||||
|             workItem.RiskReductionMinusOpportunityEnablementNotifications = ' '; | ||||
|             workItem.SortOrder = 0; | ||||
|         } | ||||
|         else { | ||||
|             let effort = workItem.Effort; | ||||
|             let businessValue = workItem.BusinessValue; | ||||
|             let timeCriticality = workItem.TimeCriticality; | ||||
|             let riskReductionMinusOpportunityEnablement = workItem.RiskReductionMinusOpportunityEnablement; | ||||
|             let weightedShortestJobFirst = workItem.WeightedShortestJobFirst == undefined ? ' ' : workItem.WeightedShortestJobFirst.toFixed(2); | ||||
|             workItem.CumulativeStoryPoints = ' '; | ||||
|             workItem.TotalStoryPoints = totalStoryPoints + ' User Story Point(s)'; | ||||
|             workItem.AbsoluteDelta = data.Effort == undefined || data.Effort.FibonacciAverage == undefined || totalStoryPoints == undefined || totalStoryPoints === 0 ? ' ' : round(Math.abs(data.Effort.FibonacciAverage - ((totalStoryPoints / highestTotalStoryPoints) * 5)), 1); | ||||
|             workItem.Effort = data.Effort == undefined || data.Effort.FibonacciAverage == undefined ? ' ' : roundMultiply(data.Effort.FibonacciAverage, 100, 100); | ||||
|             workItem.BusinessValue = data.BusinessValue == undefined || data.BusinessValue.FibonacciAverage == undefined ? ' ' : roundMultiply(data.BusinessValue.FibonacciAverage, 100, 100); | ||||
|             workItem.TimeCriticality = data.TimeCriticality == undefined || data.TimeCriticality.FibonacciAverage == undefined ? ' ' : roundMultiply(data.TimeCriticality.FibonacciAverage, 100, 100); | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = data.RiskReductionOpportunityEnablement == undefined || data.RiskReductionOpportunityEnablement.FibonacciAverage == undefined ? ' ' : roundMultiply(data.RiskReductionOpportunityEnablement.FibonacciAverage, 100, 100); | ||||
|             workItem.CoD = data.CostOfDelay == undefined ? ' ' : roundMultiply(data.CostOfDelay, 100, 100); | ||||
|             workItem.WeightedShortestJobFirst = data.WeightedShortestJobFirst == undefined ? ' ' : round(data.WeightedShortestJobFirst, 100); | ||||
|             workItem.Priority = data.SortPriority == undefined ? getPriority(workItem.WorkItemType, 4, 0) : getPriority(workItem.WorkItemType, data.SortPriority, data.SortPriorityGroup); | ||||
|             workItem.EffortNotifications = data.Effort == undefined ? ' ' : getNotifications(e, data.Effort); | ||||
|             workItem.BusinessValueNotifications = data.BusinessValue == undefined ? ' ' : getNotifications(b, data.BusinessValue); | ||||
|             workItem.TimeCriticalityNotifications = data.TimeCriticality == undefined ? ' ' : getNotifications(t, data.TimeCriticality); | ||||
|             workItem.RiskReductionMinusOpportunityEnablementNotifications = data.RiskReductionOpportunityEnablement == undefined ? ' ' : getNotifications(r, data.RiskReductionOpportunityEnablement); | ||||
|             workItem.SortOrder = data.SortOrder == undefined ? 0 : data.SortOrder; | ||||
|             if (workItem.Effort == undefined || | ||||
|                 workItem.BusinessValue == undefined || | ||||
|                 workItem.TimeCriticality == undefined || | ||||
|                 workItem.RiskReductionMinusOpportunityEnablement == undefined || | ||||
|                 workItem.WeightedShortestJobFirst == undefined || | ||||
|                 workItem.Effort == ' ' || | ||||
|                 workItem.BusinessValue == ' ' || | ||||
|                 workItem.TimeCriticality == ' ' || | ||||
|                 workItem.RiskReductionMinusOpportunityEnablement == ' ' || | ||||
|                 workItem.WeightedShortestJobFirst == ' ') { | ||||
|                 workItem.api = ''; | ||||
|             } | ||||
|             else { | ||||
|                 let check = effort === workItem.Effort | ||||
|                     && businessValue === workItem.BusinessValue | ||||
|                     && timeCriticality === workItem.TimeCriticality | ||||
|                     && riskReductionMinusOpportunityEnablement === workItem.RiskReductionMinusOpportunityEnablement; | ||||
|                 if (check && weightedShortestJobFirst == workItem.WeightedShortestJobFirst) { | ||||
|                     workItem.api = ''; | ||||
|                 } else { | ||||
|                     workItem.api = ` | ||||
| ### Work Item Patch ${check} WSJF ${workItem.Id} ${effort}:${workItem.Effort}; ${businessValue}:${workItem.BusinessValue}; ${timeCriticality}:${workItem.TimeCriticality}; ${riskReductionMinusOpportunityEnablement}:${workItem.RiskReductionMinusOpportunityEnablement}; ${weightedShortestJobFirst}:${workItem.WeightedShortestJobFirst}; | ||||
|  | ||||
| PATCH https://tfs.intra.infineon.com/tfs/FactoryIntegration/_apis/wit/workitems/${workItem.Id}?api-version=7.0 | ||||
| Authorization: Basic {{PAT}} | ||||
| Content-Type: application/json-patch+json | ||||
|  | ||||
| [ | ||||
|     { | ||||
|         "op": "replace", | ||||
|         "path": "/fields/Microsoft.VSTS.Common.BusinessValue", | ||||
|         "value": "${workItem.BusinessValue}" | ||||
|     }, | ||||
|     { | ||||
|         "op": "replace", | ||||
|         "path": "/fields/Microsoft.VSTS.Scheduling.Effort", | ||||
|         "value": "${workItem.Effort}" | ||||
|     }, | ||||
|     { | ||||
|         "op": "replace", | ||||
|         "path": "/fields/Custom.RRminusOE", | ||||
|         "value": "${workItem.RiskReductionMinusOpportunityEnablement}" | ||||
|     }, | ||||
|     { | ||||
|         "op": "replace", | ||||
|         "path": "/fields/Microsoft.VSTS.Common.TimeCriticality", | ||||
|         "value": "${workItem.TimeCriticality}" | ||||
|     }, | ||||
|     { | ||||
|         "op": "replace", | ||||
|         "path": "/fields/Custom.WSJF", | ||||
|         "value": "${workItem.WeightedShortestJobFirst}" | ||||
|     }, | ||||
|     { | ||||
|         "op": "replace", | ||||
|         "path": "/fields/Custom.WSJFFib", | ||||
|         "value": "${workItem.WeightedShortestJobFirst}" | ||||
|     } | ||||
| ] | ||||
|  | ||||
| HTTP 200 | ||||
| [Asserts] | ||||
| header "Content-Type" == "application/json; charset=utf-8; api-version=7.0" | ||||
| jsonpath "$.id" == ${workItem.Id} | ||||
| jsonpath "$.fields['Microsoft.VSTS.Common.BusinessValue']" == ${workItem.BusinessValue} | ||||
| jsonpath "$.fields['Microsoft.VSTS.Scheduling.Effort']" == ${workItem.Effort} | ||||
| jsonpath "$.fields['Custom.RRminusOE']" == ${workItem.RiskReductionMinusOpportunityEnablement} | ||||
| jsonpath "$.fields['Microsoft.VSTS.Common.TimeCriticality']" == ${workItem.TimeCriticality} | ||||
| jsonpath "$.fields['Custom.WSJF']" == ${workItem.WeightedShortestJobFirst} | ||||
| jsonpath "$.fields['Custom.WSJFFib']" == ${workItem.WeightedShortestJobFirst}`; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent == undefined) { | ||||
|         workItem.ParentId = 9999999; | ||||
|         workItem.ParentTitle = null; | ||||
|         workItem.ParentState = null; | ||||
|         workItem.ParentCoD = 9999999; | ||||
|     } | ||||
|     else { | ||||
|         workItem.ParentId = parent.Id; | ||||
|         workItem.ParentCoD = parent.CoD; | ||||
|         workItem.ParentTitle = parent.Title; | ||||
|         workItem.ParentState = getState(parent.State); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function getRecords(b, r, t, c, e, w, data, dataB, workItems) { | ||||
|     let parent; | ||||
|     let workItem; | ||||
|     let storyPoints; | ||||
|     let records = []; | ||||
|     let totalStoryPoints; | ||||
|     let highestTotalStoryPoints = 0; | ||||
|     for (let i = 0; i < data.length; i++) { | ||||
|         workItem = data[i].WorkItem; | ||||
|         if (workItem.WorkItemType !== 'Feature') | ||||
|             continue; | ||||
|         if (workItem.State !== 'Active' && workItem.State !== 'New') | ||||
|             continue; | ||||
|         if (workItem.Tags != null && workItem.Tags.includes('Ignore')) | ||||
|             continue; | ||||
|         storyPoints = data[i].Tag?.StoryPoints == undefined ? null : JSON.parse(data[i].Tag.StoryPoints); | ||||
|         totalStoryPoints = sum(storyPoints); | ||||
|         if (totalStoryPoints > highestTotalStoryPoints) | ||||
|             highestTotalStoryPoints = totalStoryPoints; | ||||
|     } | ||||
|     for (let i = 0; i < data.length; i++) { | ||||
|         parent = data[i].Parent; | ||||
|         workItem = data[i].WorkItem; | ||||
|         if (workItem.WorkItemType !== 'Feature') | ||||
|             continue; | ||||
|         if (workItem.State !== 'Active' && workItem.State !== 'New') | ||||
|             continue; | ||||
|         if (workItem.Tags != null && workItem.Tags.includes('Ignore')) | ||||
|             continue; | ||||
|         storyPoints = data[i].Tag?.StoryPoints == undefined ? null : JSON.parse(data[i].Tag.StoryPoints); | ||||
|         totalStoryPoints = sum(storyPoints); | ||||
|         if ((_windowLocationHRef.indexOf('=LEO') > -1 && workItem.AreaPath !== 'ART SPS\\LEO') || (_windowLocationHRef.indexOf('=MES') > -1 && workItem.AreaPath !== 'ART SPS\\MES')) | ||||
|             continue; | ||||
|         updateRecordParent(parent, workItem); | ||||
|         updateRecordCoD(b, r, t, c, e, w, parent, highestTotalStoryPoints, null, null); | ||||
|         updateRecordCoD(b, r, t, c, e, w, workItem, highestTotalStoryPoints, dataB, totalStoryPoints); | ||||
|         workItem.State = getState(workItem.State); | ||||
|         records.push(workItem); | ||||
|     } | ||||
|     if (_windowLocationHRef.indexOf('=EFFORT') > -1) { | ||||
|         records.sort(compareFunctionEffort); | ||||
|     } | ||||
|     else if (_windowLocationHRef.indexOf('=LIVE') > -1) { | ||||
|         records.sort(compareFunctionSortOrder); | ||||
|     } | ||||
|     else if (_windowLocationHRef.indexOf('=WSJF') > -1) { | ||||
|         records.sort(compareFunctionWeightedShortestJobFirst); | ||||
|     } | ||||
|     else { | ||||
|         records.sort(compareFunctionWeightedShortestJobFirstNullFirst); | ||||
|     } | ||||
|     return records; | ||||
| } | ||||
|  | ||||
| function warn(message) { | ||||
|     if (typeof acquiredVsCodeApi === 'function') | ||||
|         acquiredVsCodeApi.postMessage(message); | ||||
|     console.warn(message); | ||||
| } | ||||
|  | ||||
| function sendValue(fromHtml, element, page, id) { | ||||
|     let notification = { | ||||
|         id: id, | ||||
|         machineId: _machineId, | ||||
|         page: page, | ||||
|         sessionId: _sessionId, | ||||
|         site: _site, | ||||
|         time: new Date().getTime(), | ||||
|         username: _username, | ||||
|         value: element.value, | ||||
|     }; | ||||
|     if (fromHtml && notification.value !== '9') { | ||||
|         $('#AllTextarea').hide(); | ||||
|         document.getElementById('AllTextarea').value = ''; | ||||
|         $.post(_apiUrl, notification) | ||||
|             .done(function (msg) { | ||||
|                 console.log('Posted value of ' + notification.value + ' for ' + id + ' on page ' + page + ' ' + msg); | ||||
|             }) | ||||
|             .fail(function (_, textStatus, _) { | ||||
|                 warn(textStatus); | ||||
|             }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function getHtmlTextAndApi(fromHtml, b, r, t, c, e, w, records) { | ||||
|     let record; | ||||
|     let lineA = ''; | ||||
|     let lineB = ''; | ||||
|     let lineC = ''; | ||||
|     let api = ` | ||||
| ### FactoryIntegration (hurl.exe) | ||||
|  | ||||
| GET https://tfs.intra.infineon.com/tfs/FactoryIntegration | ||||
|  | ||||
| HTTP 401 | ||||
| [Asserts] | ||||
| duration < 12345 | ||||
|  | ||||
| `; | ||||
|     let text = 'Id\tRisk Reduction and/or Opportunity Enablement\tTime Criticality\tBusiness Value\tEffort\tWSJF\tCoD\tFeature Total Story Points\tAbsolute Delta\tState\tRequester\tAssigned To\tIteration Path\tSystem\tTitle-123\r\n'; | ||||
|     let html = '<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Priority</th><th>Risk Reduction and/or Opportunity Enablement</th><th>Time Criticality</th><th>Business Value</th><th>Cost of Delay (CoD)</th><th>Effort</th><th>WSJF</th></tr>'; | ||||
|     for (let i = 0; i < records.length; i++) { | ||||
|         record = records[i]; | ||||
|         if (record.api !== '') { | ||||
|             api += record.api + '\r\n'; | ||||
|         } | ||||
|         text += record.Id + '\t' + | ||||
|             record.RiskReductionMinusOpportunityEnablement + '\t' + | ||||
|             record.TimeCriticality + '\t' + | ||||
|             record.BusinessValue + '\t' + | ||||
|             record.Effort + '\t' + | ||||
|             record.WeightedShortestJobFirst + '\t' + | ||||
|             record.CoD + '\t' + | ||||
|             record.TotalStoryPoints.split(' ')[0] + '\t' + | ||||
|             record.AbsoluteDelta + '\t' + | ||||
|             record.State.split('-')[0] + '\t' + | ||||
|             record.Requester + '\t' + | ||||
|             record.AssignedTo + '\t' + | ||||
|             record.IterationPath + '\t' + | ||||
|             record.Tags + '\t' + | ||||
|             record.Title + '\r\n'; | ||||
|         lineA = '<tr id="tr' + record.Id + '"><td>' + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" + | ||||
|             '</td><td>' + record.ParentTitle + | ||||
|             '</td><td>' + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" + | ||||
|             '</td><td>' + record.Requester + | ||||
|             '</td><td>' + record.Title + | ||||
|             '</td><td>' + record.AssignedTo + | ||||
|             '</td><td>' + record.Tags + | ||||
|             '</td><td>' + record.State + | ||||
|             '</td><td>' + record.Priority + | ||||
|             '</td><td><span id=' + r.page + record.Id + '>' + record.RiskReductionMinusOpportunityEnablementNotifications + '</span><br />' + | ||||
|             '<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + r.page + '\', ' + record.Id + ')">' + | ||||
|             '<option value="9">Unknown</option>' + | ||||
|             '<option value="1">Highest (Most ' + r.description + ')</option>' + | ||||
|             '<option value="2">High</option>' + | ||||
|             '<option value="3">Medium</option>' + | ||||
|             '<option value="4">Low</option>' + | ||||
|             '<option value="5">Lowest</option>' + | ||||
|             '</select>' + | ||||
|             '</td><td><span id=' + t.page + record.Id + '>' + record.TimeCriticalityNotifications + '</span><br />' + | ||||
|             '<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + t.page + '\', ' + record.Id + ')">' + | ||||
|             '<option value="9">Unknown</option>' + | ||||
|             '<option value="1">Highest (Most ' + t.description + ')</option>' + | ||||
|             '<option value="2">High</option>' + | ||||
|             '<option value="3">Medium</option>' + | ||||
|             '<option value="4">Low</option>' + | ||||
|             '<option value="5">Lowest</option>' + | ||||
|             '</select>' + | ||||
|             '</td><td><span id=' + b.page + record.Id + '>' + record.BusinessValueNotifications + '</span><br />' + | ||||
|             '<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + b.page + '\', ' + record.Id + ')">' + | ||||
|             '<option value="9">Unknown</option>' + | ||||
|             '<option value="1">Highest (Most ' + b.description + ')</option>' + | ||||
|             '<option value="2">High</option>' + | ||||
|             '<option value="3">Medium</option>' + | ||||
|             '<option value="4">Low</option>' + | ||||
|             '<option value="5">Lowest</option>' + | ||||
|             '</select>' + | ||||
|             '</td><td><span id=' + c.page + record.Id + '>' + record.CoD + '</span>' + | ||||
|             '</td><td><span id=' + e.page + record.Id + '>' + record.EffortNotifications + '</span><br />'; | ||||
|         if (!fromHtml || _windowLocationHRef.indexOf('=EFFORT') === -1) { | ||||
|             lineB = ''; | ||||
|         } | ||||
|         else { | ||||
|             lineB = '<select class="select" onchange="sendValue(' + fromHtml + ', this, \'' + e.page + '\', ' + record.Id + ')">' + | ||||
|                 '<option value="9">Unknown</option>' + | ||||
|                 '<option value="1">Highest (Most ' + e.description + ')</option>' + | ||||
|                 '<option value="2">High</option>' + | ||||
|                 '<option value="3">Medium</option>' + | ||||
|                 '<option value="4">Low</option>' + | ||||
|                 '<option value="5">Lowest</option>' + | ||||
|                 '</select><br />'; | ||||
|         } | ||||
|         lineC = '<span>' + record.TotalStoryPoints + '</span></td>' + | ||||
|             '<td><span id=' + w.page + record.Id + '>' + record.WeightedShortestJobFirst + '<br /><span>' + record.CumulativeStoryPoints + '</span></span>' + | ||||
|             '</td></tr>'; | ||||
|         if (!fromHtml) | ||||
|             console.log(text); | ||||
|         html += lineA + lineB + lineC; | ||||
|     } | ||||
|     return { html, text, api }; | ||||
| } | ||||
|  | ||||
| function updateSite(c, w) { | ||||
|     if (_windowLocationHRef.indexOf('=LEO') > -1) { | ||||
|         _site = 'LEO'; | ||||
|         document.title = document.title.replace('Infineon', 'HiRel (Leominster)'); | ||||
|         document.getElementById('siteHeader').innerText = 'HiRel (Leominster)'; | ||||
|     } | ||||
|     else if (_windowLocationHRef.indexOf('=MES') > -1) { | ||||
|         _site = 'MES'; | ||||
|         document.title = document.title.replace('Infineon', 'Mesa'); | ||||
|         document.getElementById('siteHeader').innerText = 'Mesa'; | ||||
|     } | ||||
|     else { | ||||
|         _site = 'Infineon'; | ||||
|         document.title = document.title.replace('Infineon', 'Infineon'); | ||||
|         document.getElementById('siteHeader').innerText = 'Infineon'; | ||||
|     } | ||||
|     if (_windowLocationHRef.indexOf('=EFFORT') > -1) { | ||||
|         document.getElementById('th-span').innerHTML = c.th + ' sorted by Effort (null, highest, ..., lowest)'; | ||||
|     } | ||||
|     else if (_windowLocationHRef.indexOf('=LIVE') > -1) { | ||||
|         document.getElementById('th-span').innerHTML = c.th + ' Live View'; | ||||
|     } | ||||
|     else if (_windowLocationHRef.indexOf('=WSJF') > -1) { | ||||
|         document.getElementById('th-span').innerHTML = w.th + ' sorted by WSJF (highest, ..., lowest, null)'; | ||||
|     } | ||||
|     else { | ||||
|         document.getElementById('th-span').innerHTML = c.th + ' sorted by WSJF (null, highest, ..., lowest)'; | ||||
|     } | ||||
| } | ||||
|  | ||||
| function setDocument(fromHtml, b, r, t, c, e, w, dataA, dataB, workItems) { | ||||
|     let records = getRecords(b, r, t, c, e, w, dataA, dataB, workItems); | ||||
|     console.log(dataA.length); | ||||
|     if (dataA.length > 0) | ||||
|         console.log(dataA[0]); | ||||
|     let result = getHtmlTextAndApi(fromHtml, b, r, t, c, e, w, records); | ||||
|     if (fromHtml) { | ||||
|         document.getElementById('HeaderGrid').innerHTML = result.html.replaceAll('>null<', '> <'); | ||||
|         if (_windowLocationHRef.indexOf('=WSJF') === -1) { | ||||
|             if (_windowLocationHRef.indexOf('=EFFORT') > -1) { | ||||
|                 document.getElementById('AllTextarea').value = result.api; | ||||
|             } | ||||
|             else { | ||||
|                 document.getElementById('AllTextarea').value = result.text.replaceAll('null', '').replaceAll(' ', ''); | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|             _toggle = !_toggle; | ||||
|             $('.select').hide(); | ||||
|             $('#AllTextarea').hide(); | ||||
|         } | ||||
|     } | ||||
|     $('#toggle').click(function () { | ||||
|         if (_toggle) | ||||
|             $('.select').hide(); | ||||
|         else | ||||
|             $('.select').show(); | ||||
|         _toggle = !_toggle; | ||||
|     }); | ||||
| } | ||||
|  | ||||
| function highlight(el, i) { | ||||
|     el.before('<tr/>') | ||||
|     el.prev() | ||||
|         .width(el.width()) | ||||
|         .height(el.height()) | ||||
|         .css({ | ||||
|             'position': 'absolute', | ||||
|             'background-color': '#ffff99', | ||||
|             'opacity': '.9' | ||||
|         }) | ||||
|         .fadeOut(1000 * i); | ||||
| } | ||||
|  | ||||
| function updateWorkItem(b, r, t, c, e, w, page, workItem) { | ||||
|     console.log(workItem); | ||||
|     let x = null; | ||||
|     let aggregation = null; | ||||
|     if (page === b.page) { | ||||
|         x = b; | ||||
|         aggregation = workItem.BusinessValue; | ||||
|     } | ||||
|     else if (page === r.page) { | ||||
|         x = r; | ||||
|         aggregation = workItem.RiskReductionOpportunityEnablement; | ||||
|     } | ||||
|     else if (page === t.page) { | ||||
|         x = t; | ||||
|         aggregation = workItem.TimeCriticality; | ||||
|     } | ||||
|     else if (page === e.page) { | ||||
|         x = e; | ||||
|         aggregation = workItem.Effort; | ||||
|     } | ||||
|     if (x == undefined) | ||||
|         warn('Error with page!'); | ||||
|     else if (aggregation.FibonacciAverage == undefined) | ||||
|         warn('FibonacciAverage not set!'); | ||||
|     else { | ||||
|         $('#' + x.page + workItem.Id).text('!' + round(aggregation.FibonacciAverage, 100)); | ||||
|         if (workItem.WeightedShortestJobFirst != undefined) { | ||||
|             $('#' + w.page + workItem.Id).text('!' + round(workItem.WeightedShortestJobFirst, 100)); | ||||
|         } | ||||
|         if (workItem.CostOfDelay != undefined) { | ||||
|             let element = $('#' + c.page + workItem.Id); | ||||
|             element.text('!' + round(workItem.CostOfDelay, 100)); | ||||
|             if (_windowLocationHRef.indexOf('=LIVE') > -1) { | ||||
|                 if (workItem.SortBeforeId != undefined) { | ||||
|                     let found = 0; | ||||
|                     let row = element.parents('tr:first'); | ||||
|                     let next = row; | ||||
|                     for (let i = 0; i < 150; i++) { | ||||
|                         next = next.next(); | ||||
|                         if (next == undefined) | ||||
|                             break; | ||||
|                         if (next.attr('id') != 'tr' + workItem.SortBeforeId) | ||||
|                             continue; | ||||
|                         console.log('Moved ' + i + ' down'); | ||||
|                         row.insertAfter(next); | ||||
|                         found = i; | ||||
|                         break; | ||||
|                     } | ||||
|                     if (!found) { | ||||
|                         let prev = row; | ||||
|                         for (let i = 0; i < 150; i++) { | ||||
|                             prev = prev.prev(); | ||||
|                             if (prev == undefined) | ||||
|                                 break; | ||||
|                             if (prev.attr('id') != 'tr' + workItem.SortBeforeId) | ||||
|                                 continue; | ||||
|                             console.log('Moved ' + i + ' up'); | ||||
|                             row.insertAfter(prev); | ||||
|                             found = i; | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
|                     if (found != 0) { | ||||
|                         highlight(row, found); | ||||
|                     } | ||||
|                     else { | ||||
|                         console.log('Not found!'); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| }; | ||||
|  | ||||
| function setupPingPong() { | ||||
|     let notification = { | ||||
|         id: null, | ||||
|         machineId: _machineId, | ||||
|         page: _page, | ||||
|         sessionId: _sessionId, | ||||
|         site: _site, | ||||
|         time: new Date().getTime(), | ||||
|         username: _username, | ||||
|         value: null, | ||||
|     }; | ||||
|     $.get(_apiUrl, notification) | ||||
|         .done(function (data) { | ||||
|             if (data != undefined && data.length > 0) { | ||||
|                 keyValuePair = JSON.parse(data); | ||||
|                 if (keyValuePair.Key != undefined && keyValuePair.Value.Id != undefined && keyValuePair.Value != undefined) { | ||||
|                     updateWorkItem(_b, _r, _t, _c, _e, _w, keyValuePair.Key, keyValuePair.Value); | ||||
|                 } | ||||
|             } | ||||
|         }) | ||||
|         .fail(function (_, textStatus, _) { | ||||
|             warn(textStatus); | ||||
|         }); | ||||
| } | ||||
|  | ||||
| function initIndex(fromHtml, username, machineId, windowLocationHRef, workItems, b, r, t, c, e, w, apiUrl, _) { | ||||
|     _b = b; | ||||
|     _r = r; | ||||
|     _t = t; | ||||
|     _c = c; | ||||
|     _e = e; | ||||
|     _w = w; | ||||
|     _page = _b.page; | ||||
|     _apiUrl = apiUrl; | ||||
|     _username = username; | ||||
|     _machineId = machineId; | ||||
|     _windowLocationHRef = windowLocationHRef; | ||||
|     _sessionId = _windowLocationHRef.indexOf('=LIVE') > -1 ? self.crypto.randomUUID() : ''; | ||||
|     if (!fromHtml) { | ||||
|         console.log(b); | ||||
|         console.log(r); | ||||
|         console.log(t); | ||||
|         console.log(c); | ||||
|         console.log('Done :)'); | ||||
|     } | ||||
|     else { | ||||
|         updateSite(c, w); | ||||
|         $.getJSON(workItems.b, { _: new Date().getTime() }, function (dataB) { | ||||
|             $.getJSON(workItems.a, { _: new Date().getTime() }, function (dataA) { | ||||
|                 setDocument(fromHtml, b, r, t, c, e, w, dataA, dataB, workItems); | ||||
|                 if (_windowLocationHRef.indexOf('=LIVE') > -1) { | ||||
|                     _ = setInterval(setupPingPong, workItems.timeout); | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // #region Test | ||||
|  | ||||
| if (typeof document == 'undefined') { | ||||
|     const username = ''; | ||||
|     const machineId = ''; | ||||
|     const fromHtml = false; | ||||
|     const baseUri = 'http://eaf-dev.mes.infineon.com:5054'; | ||||
|     const apiUrl = baseUri + '/api/v1/ado/'; | ||||
|     const windowLocationHRef = baseUri + '/html/cod.html?site=MES'; | ||||
|     const signalRUrl = baseUri + '/signalr'; | ||||
|     const workItems = { | ||||
|         a: baseUri + '/markdown/bugs-features-with-parents.json?v=2025-04-14-08-10', | ||||
|         b: baseUri + '/markdown/{}.json?v=2025-04-14-08-10', | ||||
|         timeout: 3000, | ||||
|     }; | ||||
|     const b = { | ||||
|         page: 'business', | ||||
|         description: 'Value', | ||||
|         th: 'Business Value', | ||||
|         span: 'What is the relative value to the Customer or business?<br>• Do our users prefer this over that?<br>• What is the revenue impact on our business?<br>• Is there a potential penalty or other negative effects if we delay?' | ||||
|     }; | ||||
|     const r = { | ||||
|         page: 'risk', | ||||
|         description: 'Risk', | ||||
|         th: 'Risk Reduction and/or Opportunity Enablement', | ||||
|         span: 'What else does this do for our business?<br>• Reduce the risk of this or future delivery?<br>• Is there value in the information we will receive?<br>• Enable new business opportunities?' | ||||
|     }; | ||||
|     const t = { | ||||
|         page: 'time', | ||||
|         description: 'Critical', | ||||
|         th: 'Time Criticality', | ||||
|         span: 'How does user/business value decay over time?<br>• Is there a fixed deadline?<br>• Will they wait for us or move to another Solution?<br>• What is the current effect on Customer satisfaction?' | ||||
|     }; | ||||
|     const c = { | ||||
|         page: 'cod', | ||||
|         description: 'CoD', | ||||
|         th: 'Cost of Delay (CoD)', | ||||
|         span: "Cost of Delay (CoD) is the money lost by delaying or not doing a job for a specific time. It's a measure of the economic value of a job over time." | ||||
|     }; | ||||
|     const e = { | ||||
|         page: 'effort', | ||||
|         description: 'Effort', | ||||
|         th: 'Effort', | ||||
|         span: 'Effort' | ||||
|     }; | ||||
|     const w = { | ||||
|         page: 'wsjf', | ||||
|         description: 'WSJF', | ||||
|         th: 'Weightest Shortest Job First calculation (WSJF)', | ||||
|         span: 'Weightest Shortest Job First calculation (see @SCALE formula)' | ||||
|     }; | ||||
|     _windowLocationHRef = windowLocationHRef; | ||||
|     fetch(workItems.b, { _: new Date().getTime() }) | ||||
|         .then((res) => res.text()) | ||||
|         .then((textB) => { | ||||
|             fetch(workItems.a, { _: new Date().getTime() }) | ||||
|                 .then((res) => res.text()) | ||||
|                 .then((textA) => { | ||||
|                     const dataA = JSON.parse(textA); | ||||
|                     const dataB = JSON.parse(textB); | ||||
|                     if (dataA.length > 0) | ||||
|                         console.log(dataA[0]); | ||||
|                     const records = getRecords(b, r, t, c, e, w, dataA, dataB, workItems); | ||||
|                     let result = getHtmlTextAndApi(fromHtml, b, r, t, c, e, w, records); | ||||
|                     if (result == undefined) { } | ||||
|                     initIndex(fromHtml, username, machineId, windowLocationHRef, workItems, b, r, t, c, e, w, apiUrl, signalRUrl); | ||||
|                 }) | ||||
|                 .catch((e) => console.error(e)); | ||||
|         }) | ||||
|         .catch((e) => console.error(e)); | ||||
| } | ||||
|  | ||||
| // #endregion Test | ||||
							
								
								
									
										17115
									
								
								Adaptation/FileHandlers/json/StaticSite/js/cod-b.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17115
									
								
								Adaptation/FileHandlers/json/StaticSite/js/cod-b.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -1,22 +1,22 @@ | ||||
| var _apiUrl = null; | ||||
|  | ||||
| function compareFunction(a, b) { | ||||
|     if (a.Effort === null || b.Effort === null) { | ||||
|     if (a.Effort == undefined || b.Effort == undefined) { | ||||
|         var aPollValue = a.PollValue.split('-'); | ||||
|         var bPollValue = b.PollValue.split('-'); | ||||
|         return bPollValue[0].trim() - aPollValue[0].trim() || b.State[0] - a.State[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
|         return bPollValue[0] - aPollValue[0] || b.State[0] - a.State[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
|     } else { | ||||
|         return b.Effort - a.Effort || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
|     } | ||||
| } | ||||
|  | ||||
| function showOne(rowData) { | ||||
|     if (rowData == null) | ||||
|     if (rowData == undefined) | ||||
|         return; | ||||
|     var data = []; | ||||
|     data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' }); | ||||
|     for (const property in rowData) { | ||||
|         if (rowData[property] == null) | ||||
|         if (rowData[property] == undefined) | ||||
|             continue; | ||||
|         data.push({ name: property, value: rowData[property].toString() }); | ||||
|     } | ||||
| @ -30,7 +30,7 @@ function showOne(rowData) { | ||||
|  | ||||
| function loadOne() { | ||||
|     var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow(); | ||||
|     if (selectedRow == null) | ||||
|     if (selectedRow == undefined) | ||||
|         return; | ||||
|     var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index]; | ||||
|     showOne(rowData); | ||||
| @ -45,7 +45,7 @@ function detailSelectionChangedRunInfo(evt, ui) { | ||||
|  | ||||
| function getState(state) { | ||||
|     var result; | ||||
|     if (state == null) | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
| @ -66,7 +66,7 @@ function getPriority(workItemType, priority) { | ||||
|     var result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug"; | ||||
|     else if (priority == null || priority === 0) | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High`; | ||||
| @ -81,45 +81,34 @@ function getPriority(workItemType, priority) { | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function getInversePriority(priority) { | ||||
| function getPollValue(description, pollValue) { | ||||
|     var result; | ||||
|     if (priority == null || priority === 0) | ||||
|         result = "0.000"; | ||||
|     else if (priority === 1) | ||||
|         result = "3.000"; | ||||
|     else if (priority === 2) | ||||
|         result = "2.000"; | ||||
|     else if (priority === 3) | ||||
|         result = "1.000"; | ||||
|     if (pollValue == undefined || pollValue.Effort == undefined || pollValue.Effort.InverseAverage == undefined) | ||||
|         result = ""; | ||||
|     else if (pollValue.Effort.InverseAverage >= 4) | ||||
|         result = `${pollValue.Effort.InverseAverage} - 1-Highest (Most ${description}) - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.Effort.InverseAverage >= 3) | ||||
|         result = `${pollValue.Effort.InverseAverage} - 2-High - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.Effort.InverseAverage >= 2) | ||||
|         result = `${pollValue.Effort.InverseAverage} - 3-Medium - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.Effort.InverseAverage >= 1) | ||||
|         result = `${pollValue.Effort.InverseAverage} - 4-Low - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.Effort.InverseAverage >= 0) | ||||
|         result = `${pollValue.Effort.InverseAverage} - 5-Lowest - ${pollValue.Count} Vote(s)`; | ||||
|     else | ||||
|         result = "0.000"; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function getPollValue(description, priority, priorityDisplay, pollValue) { | ||||
|     var result; | ||||
|     if (pollValue === undefined || pollValue.Records.length === undefined || pollValue.Records.length === 0 || pollValue.Average === null) | ||||
|         result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority'; | ||||
|     else if (pollValue.Average > 2) | ||||
|         result = `${pollValue.Average} - 1-High (Most ${description}) - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.Average > 1) | ||||
|         result = `${pollValue.Average} - 2-Medium - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.Average > 0) | ||||
|         result = `${pollValue.Average} - 3-Low - ${pollValue.Count} Vote(s)`; | ||||
|     else | ||||
|         result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority'; | ||||
|         result = ""; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(workItem) { | ||||
|     if (workItem !== null) { | ||||
|         if (workItem.Effort === null) | ||||
|     if (workItem != undefined) { | ||||
|         if (workItem.Effort == undefined) | ||||
|             workItem.Effort = 10123; | ||||
|         if (workItem.BusinessValue === null) | ||||
|         if (workItem.BusinessValue == undefined) | ||||
|             workItem.BusinessValue = 99999; | ||||
|         if (workItem.TimeCriticality === null) | ||||
|         if (workItem.TimeCriticality == undefined) | ||||
|             workItem.TimeCriticality = 99999; | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement === null) | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement == undefined) | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = 99999; | ||||
|         workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue; | ||||
|     } | ||||
| @ -128,12 +117,12 @@ function updateRecordCoD(workItem) { | ||||
| function updateRecordOther(workItem, dataB, description) { | ||||
|     workItem["State"] = getState(workItem["State"]); | ||||
|     var priority = getPriority(workItem["WorkItemType"], workItem["Priority"]); | ||||
|     workItem["PollValue"] = getPollValue(description, workItem["Priority"], priority, dataB[workItem.Id]); | ||||
|     workItem["PollValue"] = getPollValue(description, dataB[workItem.Id]); | ||||
|     workItem["Priority"] = priority; | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent === null) { | ||||
|     if (parent == undefined) { | ||||
|         workItem["ParentId"] = 9999999; | ||||
|         workItem["ParentTitle"] = null; | ||||
|         workItem["ParentState"] = null; | ||||
| @ -183,13 +172,46 @@ function sendValue(element, page, id) { | ||||
|         }); | ||||
| } | ||||
|  | ||||
| function getFibonacciValue(average) { | ||||
|     var result; | ||||
|     if (average >= 7) | ||||
|         result = 34; | ||||
|     else if (average >= 6) | ||||
|         result = 21; | ||||
|     else if (average >= 5) | ||||
|         result = 13; | ||||
|     else if (average >= 4) | ||||
|         result = 8; | ||||
|     else if (average >= 3) | ||||
|         result = 5; | ||||
|     else if (average >= 2) | ||||
|         result = 3; | ||||
|     else if (average >= 1) | ||||
|         result = 2; | ||||
|     else if (average >= 0) | ||||
|         result = 1; | ||||
|     else | ||||
|         result = ""; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function setRecords(workItems, page, description, th) { | ||||
|     var record; | ||||
|     var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Up</th><th>Down</th><th>Poll Value</th><th>" + th + "</th></tr>"; | ||||
|     var array = []; | ||||
|     var count = ""; | ||||
|     var select = ""; | ||||
|     var average = ""; | ||||
|     var fibonacciValue = ""; | ||||
|     var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Poll Average</th><th>Fibonacci</th><th>Poll Description</th><th>Vote(s)</th><th>" + th + "</th><th>Up</th><th>Down</th></tr>"; | ||||
|     const element = document.getElementById("HeaderGrid"); | ||||
|     for (var i = 0; i < workItems.length; i++) { | ||||
|         record = workItems[i]; | ||||
|         var length = record.Effort === null ? "" : record.Effort.toString().length; | ||||
|         array = record.PollValue.split('-') | ||||
|         average = array.length > 0 ? array[0] : ""; | ||||
|         fibonacciValue = getFibonacciValue(average); | ||||
|         select = array.length > 2 ? array[1] + '-' + array[2] : ""; | ||||
|         count = array.length > 3 ? array[3].trim().split(' ')[0] : ""; | ||||
|         var length = record.Effort == undefined ? "" : record.Effort.toString().length; | ||||
|         html += "<tr><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" + | ||||
|             "</td><td>" + record.ParentTitle + | ||||
|             "</td><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" + | ||||
| @ -201,14 +223,19 @@ function setRecords(workItems, page, description, th) { | ||||
|             "</td><td>" + | ||||
|             '<select onchange="sendValue(this, \'' + page + '\', ' + record.Id + ')">' + | ||||
|             '<option value="9">Unknown</option>' + | ||||
|             '<option value="1">High (Most ' + description + ')</option>' + | ||||
|             '<option value="2">Medium</option>' + | ||||
|             '<option value="3">Low</option>' + | ||||
|             '<option value="1">Highest (Most ' + description + ')</option>' + | ||||
|             '<option value="2">High</option>' + | ||||
|             '<option value="3">Medium</option>' + | ||||
|             '<option value="4">Low</option>' + | ||||
|             '<option value="5">Lowest</option>' + | ||||
|             "</select>" + | ||||
|             "</td><td>" + average + | ||||
|             "</td><td>" + fibonacciValue + | ||||
|             "</td><td>" + select + | ||||
|             "</td><td>" + count + | ||||
|             "</td><td>" + length + " - " + record.Effort + | ||||
|             "</td><td><a href='#' class='up'>Up</a>" + | ||||
|             "</td><td><a href='#' class='down'>Down</a>" + | ||||
|             "</td><td>" + record.PollValue + | ||||
|             "</td><td>" + length + " - " + record.Effort + | ||||
|             "</td></tr>"; | ||||
|     } | ||||
|     element.innerHTML = html.replaceAll(">null<", "> <"); | ||||
|  | ||||
							
								
								
									
										9046
									
								
								Adaptation/FileHandlers/json/StaticSite/js/jquery/v1.6.4/jquery.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9046
									
								
								Adaptation/FileHandlers/json/StaticSite/js/jquery/v1.6.4/jquery.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1,5 +1,5 @@ | ||||
| function compareFunction(a, b) { | ||||
|     if (a.CoD === null || b.CoD === null) { | ||||
|     if (a.CoD == undefined || b.CoD == undefined) { | ||||
|         return b.Id - a.Id; | ||||
|     } else { | ||||
|         return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
| @ -7,12 +7,12 @@ function compareFunction(a, b) { | ||||
| } | ||||
|  | ||||
| function showOne(rowData) { | ||||
|     if (rowData == null) | ||||
|     if (rowData == undefined) | ||||
|         return; | ||||
|     var data = []; | ||||
|     data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' }); | ||||
|     for (const property in rowData) { | ||||
|         if (rowData[property] == null) | ||||
|         if (rowData[property] == undefined) | ||||
|             continue; | ||||
|         data.push({ name: property, value: rowData[property].toString() }); | ||||
|     } | ||||
| @ -26,7 +26,7 @@ function showOne(rowData) { | ||||
|  | ||||
| function loadOne() { | ||||
|     var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow(); | ||||
|     if (selectedRow == null) | ||||
|     if (selectedRow == undefined) | ||||
|         return; | ||||
|     var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index]; | ||||
|     showOne(rowData); | ||||
| @ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) { | ||||
|  | ||||
| function getState(state) { | ||||
|     var result; | ||||
|     if (state == null) | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
| @ -62,7 +62,7 @@ function getPriority(workItemType, priority) { | ||||
|     var result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug"; | ||||
|     else if (priority == null || priority === 0) | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High`; | ||||
| @ -78,14 +78,14 @@ function getPriority(workItemType, priority) { | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(workItem) { | ||||
|     if (workItem !== null) { | ||||
|         if (workItem.Effort === null) | ||||
|     if (workItem != undefined) { | ||||
|         if (workItem.Effort == undefined) | ||||
|             workItem.Effort = 10123; | ||||
|         if (workItem.BusinessValue === null) | ||||
|         if (workItem.BusinessValue == undefined) | ||||
|             workItem.BusinessValue = 99999; | ||||
|         if (workItem.TimeCriticality === null) | ||||
|         if (workItem.TimeCriticality == undefined) | ||||
|             workItem.TimeCriticality = 99999; | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement === null) | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement == undefined) | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = 99999; | ||||
|         workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue; | ||||
|     } | ||||
| @ -97,7 +97,7 @@ function updateRecordOther(workItem) { | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent === null) { | ||||
|     if (parent == undefined) { | ||||
|         workItem["ParentId"] = 9999999; | ||||
|         workItem["ParentTitle"] = null; | ||||
|         workItem["ParentState"] = null; | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| function compareFunction(a, b) { | ||||
|     if (a.CoD === null || b.CoD === null) { | ||||
|     if (a.CoD == undefined || b.CoD == undefined) { | ||||
|         return b.Id - a.Id; | ||||
|     } else { | ||||
|         return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
| @ -7,12 +7,12 @@ function compareFunction(a, b) { | ||||
| } | ||||
|  | ||||
| function showOne(rowData) { | ||||
|     if (rowData == null) | ||||
|     if (rowData == undefined) | ||||
|         return; | ||||
|     var data = []; | ||||
|     data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' }); | ||||
|     for (const property in rowData) { | ||||
|         if (rowData[property] == null) | ||||
|         if (rowData[property] == undefined) | ||||
|             continue; | ||||
|         data.push({ name: property, value: rowData[property].toString() }); | ||||
|     } | ||||
| @ -26,7 +26,7 @@ function showOne(rowData) { | ||||
|  | ||||
| function loadOne() { | ||||
|     var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow(); | ||||
|     if (selectedRow == null) | ||||
|     if (selectedRow == undefined) | ||||
|         return; | ||||
|     var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index]; | ||||
|     showOne(rowData); | ||||
| @ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) { | ||||
|  | ||||
| function getState(state) { | ||||
|     var result; | ||||
|     if (state == null) | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
| @ -62,7 +62,7 @@ function getPriority(workItemType, priority) { | ||||
|     var result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug"; | ||||
|     else if (priority == null || priority === 0) | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High`; | ||||
| @ -78,14 +78,14 @@ function getPriority(workItemType, priority) { | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(workItem) { | ||||
|     if (workItem !== null) { | ||||
|         if (workItem.Effort === null) | ||||
|     if (workItem != undefined) { | ||||
|         if (workItem.Effort == undefined) | ||||
|             workItem.Effort = 10123; | ||||
|         if (workItem.BusinessValue === null) | ||||
|         if (workItem.BusinessValue == undefined) | ||||
|             workItem.BusinessValue = 99999; | ||||
|         if (workItem.TimeCriticality === null) | ||||
|         if (workItem.TimeCriticality == undefined) | ||||
|             workItem.TimeCriticality = 99999; | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement === null) | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement == undefined) | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = 99999; | ||||
|         workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue; | ||||
|     } | ||||
| @ -97,7 +97,7 @@ function updateRecordOther(workItem) { | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent === null) { | ||||
|     if (parent == undefined) { | ||||
|         workItem["ParentId"] = 9999999; | ||||
|         workItem["ParentTitle"] = null; | ||||
|         workItem["ParentState"] = null; | ||||
|  | ||||
| @ -1,22 +1,22 @@ | ||||
| var _apiUrl = null; | ||||
|  | ||||
| function compareFunction(a, b) { | ||||
|     if (a.RiskReductionMinusOpportunityEnablement === null || b.RiskReductionMinusOpportunityEnablement === null) { | ||||
|     if (a.RiskReductionMinusOpportunityEnablement == undefined || b.RiskReductionMinusOpportunityEnablement == undefined) { | ||||
|         var aPollValue = a.PollValue.split('-'); | ||||
|         var bPollValue = b.PollValue.split('-'); | ||||
|         return bPollValue[0].trim() - aPollValue[0].trim() || b.State[0] - a.State[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
|         return bPollValue[0] - aPollValue[0] || b.State[0] - a.State[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
|     } else { | ||||
|         return b.RiskReductionMinusOpportunityEnablement - a.RiskReductionMinusOpportunityEnablement || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
|     } | ||||
| } | ||||
|  | ||||
| function showOne(rowData) { | ||||
|     if (rowData == null) | ||||
|     if (rowData == undefined) | ||||
|         return; | ||||
|     var data = []; | ||||
|     data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' }); | ||||
|     for (const property in rowData) { | ||||
|         if (rowData[property] == null) | ||||
|         if (rowData[property] == undefined) | ||||
|             continue; | ||||
|         data.push({ name: property, value: rowData[property].toString() }); | ||||
|     } | ||||
| @ -30,7 +30,7 @@ function showOne(rowData) { | ||||
|  | ||||
| function loadOne() { | ||||
|     var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow(); | ||||
|     if (selectedRow == null) | ||||
|     if (selectedRow == undefined) | ||||
|         return; | ||||
|     var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index]; | ||||
|     showOne(rowData); | ||||
| @ -45,7 +45,7 @@ function detailSelectionChangedRunInfo(evt, ui) { | ||||
|  | ||||
| function getState(state) { | ||||
|     var result; | ||||
|     if (state == null) | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
| @ -66,7 +66,7 @@ function getPriority(workItemType, priority) { | ||||
|     var result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug"; | ||||
|     else if (priority == null || priority === 0) | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High`; | ||||
| @ -81,45 +81,34 @@ function getPriority(workItemType, priority) { | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function getInversePriority(priority) { | ||||
| function getPollValue(description, pollValue) { | ||||
|     var result; | ||||
|     if (priority == null || priority === 0) | ||||
|         result = "0.000"; | ||||
|     else if (priority === 1) | ||||
|         result = "3.000"; | ||||
|     else if (priority === 2) | ||||
|         result = "2.000"; | ||||
|     else if (priority === 3) | ||||
|         result = "1.000"; | ||||
|     if (pollValue == undefined || pollValue.RiskReductionOpportunityEnablement == undefined || pollValue.RiskReductionOpportunityEnablement.InverseAverage == undefined) | ||||
|         result = ""; | ||||
|     else if (pollValue.RiskReductionOpportunityEnablement.InverseAverage >= 4) | ||||
|         result = `${pollValue.RiskReductionOpportunityEnablement.InverseAverage} - 1-Highest (Most ${description}) - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.RiskReductionOpportunityEnablement.InverseAverage >= 3) | ||||
|         result = `${pollValue.RiskReductionOpportunityEnablement.InverseAverage} - 2-High - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.RiskReductionOpportunityEnablement.InverseAverage >= 2) | ||||
|         result = `${pollValue.RiskReductionOpportunityEnablement.InverseAverage} - 3-Medium - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.RiskReductionOpportunityEnablement.InverseAverage >= 1) | ||||
|         result = `${pollValue.RiskReductionOpportunityEnablement.InverseAverage} - 4-Low - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.RiskReductionOpportunityEnablement.InverseAverage >= 0) | ||||
|         result = `${pollValue.RiskReductionOpportunityEnablement.InverseAverage} - 5-Lowest - ${pollValue.Count} Vote(s)`; | ||||
|     else | ||||
|         result = "0.000"; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function getPollValue(description, priority, priorityDisplay, pollValue) { | ||||
|     var result; | ||||
|     if (pollValue === undefined || pollValue.Records.length === undefined || pollValue.Records.length === 0 || pollValue.Average === null) | ||||
|         result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority'; | ||||
|     else if (pollValue.Average > 2) | ||||
|         result = `${pollValue.Average} - 1-High (Most ${description}) - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.Average > 1) | ||||
|         result = `${pollValue.Average} - 2-Medium - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.Average > 0) | ||||
|         result = `${pollValue.Average} - 3-Low - ${pollValue.Count} Vote(s)`; | ||||
|     else | ||||
|         result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority'; | ||||
|         result = ""; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(workItem) { | ||||
|     if (workItem !== null) { | ||||
|         if (workItem.Effort === null) | ||||
|     if (workItem != undefined) { | ||||
|         if (workItem.Effort == undefined) | ||||
|             workItem.Effort = 10123; | ||||
|         if (workItem.BusinessValue === null) | ||||
|         if (workItem.BusinessValue == undefined) | ||||
|             workItem.BusinessValue = 99999; | ||||
|         if (workItem.TimeCriticality === null) | ||||
|         if (workItem.TimeCriticality == undefined) | ||||
|             workItem.TimeCriticality = 99999; | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement === null) | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement == undefined) | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = 99999; | ||||
|         workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue; | ||||
|     } | ||||
| @ -128,12 +117,12 @@ function updateRecordCoD(workItem) { | ||||
| function updateRecordOther(workItem, dataB, description) { | ||||
|     workItem["State"] = getState(workItem["State"]); | ||||
|     var priority = getPriority(workItem["WorkItemType"], workItem["Priority"]); | ||||
|     workItem["PollValue"] = getPollValue(description, workItem["Priority"], priority, dataB[workItem.Id]); | ||||
|     workItem["PollValue"] = getPollValue(description, dataB[workItem.Id]); | ||||
|     workItem["Priority"] = priority; | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent === null) { | ||||
|     if (parent == undefined) { | ||||
|         workItem["ParentId"] = 9999999; | ||||
|         workItem["ParentTitle"] = null; | ||||
|         workItem["ParentState"] = null; | ||||
| @ -183,13 +172,46 @@ function sendValue(element, page, id) { | ||||
|         }); | ||||
| } | ||||
|  | ||||
| function getFibonacciValue(average) { | ||||
|     var result; | ||||
|     if (average >= 7) | ||||
|         result = 34; | ||||
|     else if (average >= 6) | ||||
|         result = 21; | ||||
|     else if (average >= 5) | ||||
|         result = 13; | ||||
|     else if (average >= 4) | ||||
|         result = 8; | ||||
|     else if (average >= 3) | ||||
|         result = 5; | ||||
|     else if (average >= 2) | ||||
|         result = 3; | ||||
|     else if (average >= 1) | ||||
|         result = 2; | ||||
|     else if (average >= 0) | ||||
|         result = 1; | ||||
|     else | ||||
|         result = ""; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function setRecords(workItems, page, description, th) { | ||||
|     var record; | ||||
|     var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Up</th><th>Down</th><th>Poll Value</th><th>" + th + "</th></tr>"; | ||||
|     var array = []; | ||||
|     var count = ""; | ||||
|     var select = ""; | ||||
|     var average = ""; | ||||
|     var fibonacciValue = ""; | ||||
|     var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Poll Average</th><th>Fibonacci</th><th>Poll Description</th><th>Vote(s)</th><th>" + th + "</th><th>Up</th><th>Down</th></tr>"; | ||||
|     const element = document.getElementById("HeaderGrid"); | ||||
|     for (var i = 0; i < workItems.length; i++) { | ||||
|         record = workItems[i]; | ||||
|         var length = record.RiskReductionMinusOpportunityEnablement === null ? "" : record.RiskReductionMinusOpportunityEnablement.toString().length; | ||||
|         array = record.PollValue.split('-') | ||||
|         average = array.length > 0 ? array[0] : ""; | ||||
|         fibonacciValue = getFibonacciValue(average); | ||||
|         select = array.length > 2 ? array[1] + '-' + array[2] : ""; | ||||
|         count = array.length > 3 ? array[3].trim().split(' ')[0] : ""; | ||||
|         var length = record.RiskReductionMinusOpportunityEnablement == undefined ? "" : record.RiskReductionMinusOpportunityEnablement.toString().length; | ||||
|         html += "<tr><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" + | ||||
|             "</td><td>" + record.ParentTitle + | ||||
|             "</td><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" + | ||||
| @ -201,14 +223,19 @@ function setRecords(workItems, page, description, th) { | ||||
|             "</td><td>" + | ||||
|             '<select onchange="sendValue(this, \'' + page + '\', ' + record.Id + ')">' + | ||||
|             '<option value="9">Unknown</option>' + | ||||
|             '<option value="1">High (Most ' + description + ')</option>' + | ||||
|             '<option value="2">Medium</option>' + | ||||
|             '<option value="3">Low</option>' + | ||||
|             '<option value="1">Highest (Most ' + description + ')</option>' + | ||||
|             '<option value="2">High</option>' + | ||||
|             '<option value="3">Medium</option>' + | ||||
|             '<option value="4">Low</option>' + | ||||
|             '<option value="5">Lowest</option>' + | ||||
|             "</select>" + | ||||
|             "</td><td>" + average + | ||||
|             "</td><td>" + fibonacciValue + | ||||
|             "</td><td>" + select + | ||||
|             "</td><td>" + count + | ||||
|             "</td><td>" + length + " - " + record.RiskReductionMinusOpportunityEnablement + | ||||
|             "</td><td><a href='#' class='up'>Up</a>" + | ||||
|             "</td><td><a href='#' class='down'>Down</a>" + | ||||
|             "</td><td>" + record.PollValue + | ||||
|             "</td><td>" + length + " - " + record.RiskReductionMinusOpportunityEnablement + | ||||
|             "</td></tr>"; | ||||
|     } | ||||
|     element.innerHTML = html.replaceAll(">null<", "> <"); | ||||
|  | ||||
							
								
								
									
										7024
									
								
								Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery-1.6.4-vsdoc.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7024
									
								
								Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery-1.6.4-vsdoc.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										9046
									
								
								Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery-1.6.4.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9046
									
								
								Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery-1.6.4.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										4
									
								
								Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery-1.6.4.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery-1.6.4.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										9
									
								
								Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery.signalR-2.4.3.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery.signalR-2.4.3.min.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										3190
									
								
								Adaptation/FileHandlers/json/StaticSite/js/signalr/dist/browser/signalr.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3190
									
								
								Adaptation/FileHandlers/json/StaticSite/js/signalr/dist/browser/signalr.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										95
									
								
								Adaptation/FileHandlers/json/StaticSite/js/signalr/hubs.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								Adaptation/FileHandlers/json/StaticSite/js/signalr/hubs.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,95 @@ | ||||
| /*! | ||||
|  * ASP.NET SignalR JavaScript Library 2.4.3 | ||||
|  * http://signalr.net/ | ||||
|  * | ||||
|  * Copyright (c) .NET Foundation. All rights reserved. | ||||
|  * Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| /// <reference path="..\..\SignalR.Client.JS\Scripts\jquery-1.6.4.js" /> | ||||
| /// <reference path="jquery.signalR.js" /> | ||||
| (function ($, window, undefined) { | ||||
|     /// <param name="$" type="jQuery" /> | ||||
|     "use strict"; | ||||
|  | ||||
|     if (typeof ($.signalR) !== "function") { | ||||
|         throw new Error("SignalR: SignalR is not loaded. Please ensure jquery.signalR-x.js is referenced before ~/signalr/js."); | ||||
|     } | ||||
|  | ||||
|     var signalR = $.signalR; | ||||
|  | ||||
|     function makeProxyCallback(hub, callback) { | ||||
|         return function () { | ||||
|             // Call the client hub method | ||||
|             callback.apply(hub, $.makeArray(arguments)); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     function registerHubProxies(instance, shouldSubscribe) { | ||||
|         var key, hub, memberKey, memberValue, subscriptionMethod; | ||||
|  | ||||
|         for (key in instance) { | ||||
|             if (instance.hasOwnProperty(key)) { | ||||
|                 hub = instance[key]; | ||||
|  | ||||
|                 if (!(hub.hubName)) { | ||||
|                     // Not a client hub | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 if (shouldSubscribe) { | ||||
|                     // We want to subscribe to the hub events | ||||
|                     subscriptionMethod = hub.on; | ||||
|                 } else { | ||||
|                     // We want to unsubscribe from the hub events | ||||
|                     subscriptionMethod = hub.off; | ||||
|                 } | ||||
|  | ||||
|                 // Loop through all members on the hub and find client hub functions to subscribe/unsubscribe | ||||
|                 for (memberKey in hub.client) { | ||||
|                     if (hub.client.hasOwnProperty(memberKey)) { | ||||
|                         memberValue = hub.client[memberKey]; | ||||
|  | ||||
|                         if (!$.isFunction(memberValue)) { | ||||
|                             // Not a client hub function | ||||
|                             continue; | ||||
|                         } | ||||
|  | ||||
|                         // Use the actual user-provided callback as the "identity" value for the registration. | ||||
|                         subscriptionMethod.call(hub, memberKey, makeProxyCallback(hub, memberValue), memberValue); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     $.hubConnection.prototype.createHubProxies = function () { | ||||
|         var proxies = {}; | ||||
|         this.starting(function () { | ||||
|             // Register the hub proxies as subscribed | ||||
|             // (instance, shouldSubscribe) | ||||
|             registerHubProxies(proxies, true); | ||||
|  | ||||
|             this._registerSubscribedHubs(); | ||||
|         }).disconnected(function () { | ||||
|             // Unsubscribe all hub proxies when we "disconnect".  This is to ensure that we do not re-add functional call backs. | ||||
|             // (instance, shouldSubscribe) | ||||
|             registerHubProxies(proxies, false); | ||||
|         }); | ||||
|  | ||||
|         proxies['weightedShortestJobFirstHub'] = this.createHubProxy('weightedShortestJobFirstHub');  | ||||
|         proxies['weightedShortestJobFirstHub'].client = { }; | ||||
|         proxies['weightedShortestJobFirstHub'].server = { | ||||
|             send: function (name, message) { | ||||
|                 return proxies['weightedShortestJobFirstHub'].invoke.apply(proxies['weightedShortestJobFirstHub'], $.merge(["Send"], $.makeArray(arguments))); | ||||
|              } | ||||
|         }; | ||||
|  | ||||
|         return proxies; | ||||
|     }; | ||||
|  | ||||
|     signalR.hub = $.hubConnection("/signalr", { useDefaultPath: false }); | ||||
|     $.extend(signalR, signalR.hub.createHubProxies()); | ||||
|  | ||||
| }(window.jQuery, window)); | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										45
									
								
								Adaptation/FileHandlers/json/StaticSite/js/simple.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								Adaptation/FileHandlers/json/StaticSite/js/simple.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | ||||
| var _apiUrl = null; | ||||
|  | ||||
| function initIndex(url, apiUrl) { | ||||
|     _apiUrl = apiUrl; | ||||
|      | ||||
|     //Set the hubs URL for the connection | ||||
|     $.connection.hub.url = url; | ||||
|     $.connection.hub.logging = true; | ||||
|  | ||||
|     // Declare a proxy to reference the hub. | ||||
|     // var chat = $.connection.myHub; | ||||
|     var chat = $.connection.weightedShortestJobFirstHub; | ||||
|  | ||||
|     // Create a function that the hub can call to broadcast messages. | ||||
|     chat.client.addNotification = function (name, message) { | ||||
|         // Html encode display name and message. | ||||
|         console.log(message); | ||||
|         var encodedName = $('<div />').text(name).html(); | ||||
|         var encodedMsg = $('<div />').text("hash").html(); | ||||
|         // Add the message to the page. | ||||
|         $('#discussion').append('<li><strong>' + encodedName | ||||
|             + '</strong>:  ' + encodedMsg + '</li>'); | ||||
|     }; | ||||
|     // Get the user name and store it to prepend to messages. | ||||
|     $('#displayname').val(prompt('Enter your name:', '')); | ||||
|     // Set initial focus to message input box. | ||||
|     $('#message').focus(); | ||||
|     // Start the connection. | ||||
|     $.connection.hub.start({ transport: 'longPolling' }).done(function () { | ||||
|         $('#sendmessage').click(function () { | ||||
|             // Call the Send method on the hub. | ||||
|             // chat.server.send($('#displayname').val(), $('#message').val()); | ||||
|             var notification = { | ||||
|                 "id": 110743, | ||||
|                 "page": "effort", | ||||
|                 "username": "user", | ||||
|                 "time": 1737573418926, | ||||
|                 "value": 1 | ||||
|             }; | ||||
|             chat.server.notifyAll(notification); | ||||
|             // Clear text box and reset focus for next comment. | ||||
|             $('#message').val('').focus(); | ||||
|         }); | ||||
|     }); | ||||
| } | ||||
| @ -1,22 +1,22 @@ | ||||
| var _apiUrl = null; | ||||
|  | ||||
| function compareFunction(a, b) { | ||||
|     if (a.TimeCriticality === null || b.TimeCriticality === null) { | ||||
|     if (a.TimeCriticality == undefined || b.TimeCriticality == undefined) { | ||||
|         var aPollValue = a.PollValue.split('-'); | ||||
|         var bPollValue = b.PollValue.split('-'); | ||||
|         return bPollValue[0].trim() - aPollValue[0].trim() || b.State[0] - a.State[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
|         return b.State[0] - a.State[0] || bPollValue[0] - aPollValue[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
|     } else { | ||||
|         return b.TimeCriticality - a.TimeCriticality || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
|     } | ||||
| } | ||||
|  | ||||
| function showOne(rowData) { | ||||
|     if (rowData == null) | ||||
|     if (rowData == undefined) | ||||
|         return; | ||||
|     var data = []; | ||||
|     data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' }); | ||||
|     for (const property in rowData) { | ||||
|         if (rowData[property] == null) | ||||
|         if (rowData[property] == undefined) | ||||
|             continue; | ||||
|         data.push({ name: property, value: rowData[property].toString() }); | ||||
|     } | ||||
| @ -30,7 +30,7 @@ function showOne(rowData) { | ||||
|  | ||||
| function loadOne() { | ||||
|     var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow(); | ||||
|     if (selectedRow == null) | ||||
|     if (selectedRow == undefined) | ||||
|         return; | ||||
|     var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index]; | ||||
|     showOne(rowData); | ||||
| @ -45,7 +45,7 @@ function detailSelectionChangedRunInfo(evt, ui) { | ||||
|  | ||||
| function getState(state) { | ||||
|     var result; | ||||
|     if (state == null) | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
| @ -66,7 +66,7 @@ function getPriority(workItemType, priority) { | ||||
|     var result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug"; | ||||
|     else if (priority == null || priority === 0) | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High`; | ||||
| @ -81,45 +81,34 @@ function getPriority(workItemType, priority) { | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function getInversePriority(priority) { | ||||
| function getPollValue(description, pollValue) { | ||||
|     var result; | ||||
|     if (priority == null || priority === 0) | ||||
|         result = "0.000"; | ||||
|     else if (priority === 1) | ||||
|         result = "3.000"; | ||||
|     else if (priority === 2) | ||||
|         result = "2.000"; | ||||
|     else if (priority === 3) | ||||
|         result = "1.000"; | ||||
|     if (pollValue == undefined || pollValue.TimeCriticality == undefined || pollValue.TimeCriticality.InverseAverage == undefined) | ||||
|         result = ""; | ||||
|     else if (pollValue.TimeCriticality.InverseAverage >= 4) | ||||
|         result = `${pollValue.TimeCriticality.InverseAverage} - 1-Highest (Most ${description}) - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.TimeCriticality.InverseAverage >= 3) | ||||
|         result = `${pollValue.TimeCriticality.InverseAverage} - 2-High - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.TimeCriticality.InverseAverage >= 2) | ||||
|         result = `${pollValue.TimeCriticality.InverseAverage} - 3-Medium - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.TimeCriticality.InverseAverage >= 1) | ||||
|         result = `${pollValue.TimeCriticality.InverseAverage} - 4-Low - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.TimeCriticality.InverseAverage >= 0) | ||||
|         result = `${pollValue.TimeCriticality.InverseAverage} - 5-Lowest - ${pollValue.Count} Vote(s)`; | ||||
|     else | ||||
|         result = "0.000"; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function getPollValue(description, priority, priorityDisplay, pollValue) { | ||||
|     var result; | ||||
|     if (pollValue === undefined || pollValue.Records.length === undefined || pollValue.Records.length === 0 || pollValue.Average === null) | ||||
|         result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority'; | ||||
|     else if (pollValue.Average > 2) | ||||
|         result = `${pollValue.Average} - 1-High (Most ${description}) - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.Average > 1) | ||||
|         result = `${pollValue.Average} - 2-Medium - ${pollValue.Count} Vote(s)`; | ||||
|     else if (pollValue.Average > 0) | ||||
|         result = `${pollValue.Average} - 3-Low - ${pollValue.Count} Vote(s)`; | ||||
|     else | ||||
|         result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority'; | ||||
|         result = ""; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(workItem) { | ||||
|     if (workItem !== null) { | ||||
|         if (workItem.Effort === null) | ||||
|     if (workItem != undefined) { | ||||
|         if (workItem.Effort == undefined) | ||||
|             workItem.Effort = 10123; | ||||
|         if (workItem.BusinessValue === null) | ||||
|         if (workItem.BusinessValue == undefined) | ||||
|             workItem.BusinessValue = 99999; | ||||
|         if (workItem.TimeCriticality === null) | ||||
|         if (workItem.TimeCriticality == undefined) | ||||
|             workItem.TimeCriticality = 99999; | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement === null) | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement == undefined) | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = 99999; | ||||
|         workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue; | ||||
|     } | ||||
| @ -128,12 +117,12 @@ function updateRecordCoD(workItem) { | ||||
| function updateRecordOther(workItem, dataB, description) { | ||||
|     workItem["State"] = getState(workItem["State"]); | ||||
|     var priority = getPriority(workItem["WorkItemType"], workItem["Priority"]); | ||||
|     workItem["PollValue"] = getPollValue(description, workItem["Priority"], priority, dataB[workItem.Id]); | ||||
|     workItem["PollValue"] = getPollValue(description, dataB[workItem.Id]); | ||||
|     workItem["Priority"] = priority; | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent === null) { | ||||
|     if (parent == undefined) { | ||||
|         workItem["ParentId"] = 9999999; | ||||
|         workItem["ParentTitle"] = null; | ||||
|         workItem["ParentState"] = null; | ||||
| @ -183,13 +172,47 @@ function sendValue(element, page, id) { | ||||
|         }); | ||||
| } | ||||
|  | ||||
| function getFibonacciValue(average) { | ||||
|     var result; | ||||
|     if (average >= 7) | ||||
|         result = 34; | ||||
|     else if (average >= 6) | ||||
|         result = 21; | ||||
|     else if (average >= 5) | ||||
|         result = 13; | ||||
|     else if (average >= 4) | ||||
|         result = 8; | ||||
|     else if (average >= 3) | ||||
|         result = 5; | ||||
|     else if (average >= 2) | ||||
|         result = 3; | ||||
|     else if (average >= 1) | ||||
|         result = 2; | ||||
|     else if (average >= 0) | ||||
|         result = 1; | ||||
|     else | ||||
|         result = ""; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
|  | ||||
| function setRecords(workItems, page, description, th) { | ||||
|     var record; | ||||
|     var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Up</th><th>Down</th><th>Poll Value</th><th>" + th + "</th></tr>"; | ||||
|     var array = []; | ||||
|     var count = ""; | ||||
|     var select = ""; | ||||
|     var average = ""; | ||||
|     var fibonacciValue = ""; | ||||
|     var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Poll Average</th><th>Fibonacci</th><th>Poll Description</th><th>Vote(s)</th><th>" + th + "</th><th>Up</th><th>Down</th></tr>"; | ||||
|     const element = document.getElementById("HeaderGrid"); | ||||
|     for (var i = 0; i < workItems.length; i++) { | ||||
|         record = workItems[i]; | ||||
|         var length = record.TimeCriticality === null ? "" : record.TimeCriticality.toString().length; | ||||
|         array = record.PollValue.split('-') | ||||
|         average = array.length > 0 ? array[0] : ""; | ||||
|         fibonacciValue = getFibonacciValue(average); | ||||
|         select = array.length > 2 ? array[1] + '-' + array[2] : ""; | ||||
|         count = array.length > 3 ? array[3].trim().split(' ')[0] : ""; | ||||
|         var length = record.TimeCriticality == undefined ? "" : record.TimeCriticality.toString().length; | ||||
|         html += "<tr><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" + | ||||
|             "</td><td>" + record.ParentTitle + | ||||
|             "</td><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" + | ||||
| @ -201,14 +224,19 @@ function setRecords(workItems, page, description, th) { | ||||
|             "</td><td>" + | ||||
|             '<select onchange="sendValue(this, \'' + page + '\', ' + record.Id + ')">' + | ||||
|             '<option value="9">Unknown</option>' + | ||||
|             '<option value="1">High (Most ' + description + ')</option>' + | ||||
|             '<option value="2">Medium</option>' + | ||||
|             '<option value="3">Low</option>' + | ||||
|             '<option value="1">Highest (Most ' + description + ')</option>' + | ||||
|             '<option value="2">High</option>' + | ||||
|             '<option value="3">Medium</option>' + | ||||
|             '<option value="4">Low</option>' + | ||||
|             '<option value="5">Lowest</option>' + | ||||
|             "</select>" + | ||||
|             "</td><td>" + average + | ||||
|             "</td><td>" + fibonacciValue + | ||||
|             "</td><td>" + select + | ||||
|             "</td><td>" + count + | ||||
|             "</td><td>" + length + " - " + record.TimeCriticality + | ||||
|             "</td><td><a href='#' class='up'>Up</a>" + | ||||
|             "</td><td><a href='#' class='down'>Down</a>" + | ||||
|             "</td><td>" + record.PollValue + | ||||
|             "</td><td>" + length + " - " + record.TimeCriticality + | ||||
|             "</td></tr>"; | ||||
|     } | ||||
|     element.innerHTML = html.replaceAll(">null<", "> <"); | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| function compareFunction(a, b) { | ||||
|     if (a.ParentCoD === null || b.ParentCoD === null) { | ||||
|     if (a.ParentCoD == undefined || b.ParentCoD == undefined) { | ||||
|         return b.ParentCoD - a.ParentCoD || b.Id - a.Id; | ||||
|     } else { | ||||
|         return b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
| @ -7,12 +7,12 @@ function compareFunction(a, b) { | ||||
| } | ||||
|  | ||||
| function showOne(rowData) { | ||||
|     if (rowData == null) | ||||
|     if (rowData == undefined) | ||||
|         return; | ||||
|     var data = []; | ||||
|     data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' }); | ||||
|     for (const property in rowData) { | ||||
|         if (rowData[property] == null) | ||||
|         if (rowData[property] == undefined) | ||||
|             continue; | ||||
|         data.push({ name: property, value: rowData[property].toString() }); | ||||
|     } | ||||
| @ -26,7 +26,7 @@ function showOne(rowData) { | ||||
|  | ||||
| function loadOne() { | ||||
|     var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow(); | ||||
|     if (selectedRow == null) | ||||
|     if (selectedRow == undefined) | ||||
|         return; | ||||
|     var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index]; | ||||
|     showOne(rowData); | ||||
| @ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) { | ||||
|  | ||||
| function getState(state) { | ||||
|     var result; | ||||
|     if (state == null) | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
| @ -62,7 +62,7 @@ function getPriority(workItemType, priority) { | ||||
|     var result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug"; | ||||
|     else if (priority == null || priority === 0) | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High`; | ||||
| @ -78,14 +78,14 @@ function getPriority(workItemType, priority) { | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(workItem) { | ||||
|     if (workItem !== null) { | ||||
|         if (workItem.Effort === null) | ||||
|     if (workItem != undefined) { | ||||
|         if (workItem.Effort == undefined) | ||||
|             workItem.Effort = 10123; | ||||
|         if (workItem.BusinessValue === null) | ||||
|         if (workItem.BusinessValue == undefined) | ||||
|             workItem.BusinessValue = 99999; | ||||
|         if (workItem.TimeCriticality === null) | ||||
|         if (workItem.TimeCriticality == undefined) | ||||
|             workItem.TimeCriticality = 99999; | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement === null) | ||||
|         if (workItem.RiskReductionMinusOpportunityEnablement == undefined) | ||||
|             workItem.RiskReductionMinusOpportunityEnablement = 99999; | ||||
|         workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue; | ||||
|     } | ||||
| @ -97,7 +97,7 @@ function updateRecordOther(workItem) { | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent === null) { | ||||
|     if (parent == undefined) { | ||||
|         workItem["ParentId"] = 9999999; | ||||
|         workItem["ParentTitle"] = null; | ||||
|         workItem["ParentState"] = null; | ||||
|  | ||||
							
								
								
									
										321
									
								
								Adaptation/FileHandlers/json/StaticSite/js/wsjf-b.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										321
									
								
								Adaptation/FileHandlers/json/StaticSite/js/wsjf-b.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,321 @@ | ||||
| var _apiUrl = null; | ||||
|  | ||||
| function compareFunction(a, b) { | ||||
|     return b.WeightedShortestJobFirst - a.WeightedShortestJobFirst || b.CoDRank - b.CoDRank || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
| } | ||||
|  | ||||
| function compareEffortFunction(a, b) { | ||||
|     return a.Effort - b.Effort || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
| } | ||||
|  | ||||
| function compareBusinessValueFunction(a, b) { | ||||
|     return a.BusinessValue - b.BusinessValue || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
| } | ||||
|  | ||||
| function compareTimeCriticalityFunction(a, b) { | ||||
|     return a.TimeCriticality - b.TimeCriticality || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
| } | ||||
|  | ||||
| function compareRiskReductionMinusOpportunityEnablementFunction(a, b) { | ||||
|     return b.RiskReductionMinusOpportunityEnablement - b.RiskReductionMinusOpportunityEnablement || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
| } | ||||
|  | ||||
| function compareCostOfDelay(a, b) { | ||||
|     return b.CoD - b.CoD || b.ParentId - a.ParentId || a.Id - b.Id; | ||||
| } | ||||
|  | ||||
| function showOne(rowData) { | ||||
|     if (rowData == undefined) | ||||
|         return; | ||||
|     var data = []; | ||||
|     data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' }); | ||||
|     for (const property in rowData) { | ||||
|         if (rowData[property] == undefined) | ||||
|             continue; | ||||
|         data.push({ name: property, value: rowData[property].toString() }); | ||||
|     } | ||||
|     $("#AllGrid").igGrid({ | ||||
|         autoGenerateColumns: true, | ||||
|         dataSource: data, | ||||
|         width: "100%", | ||||
|         showHeader: false, | ||||
|     }); | ||||
| } | ||||
|  | ||||
| function loadOne() { | ||||
|     var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow(); | ||||
|     if (selectedRow == undefined) | ||||
|         return; | ||||
|     var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index]; | ||||
|     showOne(rowData); | ||||
| } | ||||
|  | ||||
| function detailSelectionChangedRunInfo(evt, ui) { | ||||
|     if (ui.row.index === 0) | ||||
|         return; | ||||
|     var rowData = ui.owner.grid.dataSource.dataView()[ui.row.index]; | ||||
|     showOne(rowData); | ||||
| } | ||||
|  | ||||
| function getState(state) { | ||||
|     var result; | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
|     else if (state === "Active") | ||||
|         result = `2-${state}`; | ||||
|     else if (state === "Resolved") | ||||
|         result = `3-${state}`; | ||||
|     else if (state === "Closed") | ||||
|         result = `4-${state}`; | ||||
|     else if (state === "Removed") | ||||
|         result = `5-${state}`; | ||||
|     else | ||||
|         result = `8-${state}`; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function getPriority(workItemType, priority) { | ||||
|     var result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug"; | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High`; | ||||
|     else if (priority === 2) | ||||
|         result = `${priority}-Med`; | ||||
|     else if (priority === 3) | ||||
|         result = `${priority}-Low`; | ||||
|     else if (priority === 4) | ||||
|         result = `${priority}-TBD`; | ||||
|     else | ||||
|         result = "8-Not"; | ||||
|     return result; | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(workItem) { | ||||
|     if (workItem != undefined) { | ||||
|         if (workItem["Effort"] == undefined) | ||||
|             workItem["Effort"] = 1; | ||||
|         if (workItem["BusinessValue"] == undefined) | ||||
|             workItem["BusinessValue"] = 99999; | ||||
|         if (workItem["TimeCriticality"] == undefined) | ||||
|             workItem["TimeCriticality"] = 99999; | ||||
|         if (workItem["RiskReductionMinusOpportunityEnablement"] == undefined) | ||||
|             workItem["RiskReductionMinusOpportunityEnablement"] = 99999; | ||||
|     } | ||||
| } | ||||
|  | ||||
| function getFibonacci(length) { | ||||
|     var results = []; | ||||
|     for (var i = 0; i < length; i++) { | ||||
|         results.push(21); | ||||
|     } | ||||
|     var index = 0; | ||||
|     var fibonacci = [3, 5, 8, 13, 20]; | ||||
|     var factor = (length / fibonacci.length).toFixed(); | ||||
|     for (var j = 0; j < fibonacci.length; j++) { | ||||
|         for (var i = 0; i < factor; i++) { | ||||
|             results[index] = fibonacci[j]; | ||||
|             index += 1; | ||||
|         } | ||||
|     } | ||||
|     // for (var i = 0; i < results.length; i++) { | ||||
|     //     console.log(results[i]); | ||||
|     // } | ||||
|     return results; | ||||
| } | ||||
|  | ||||
| function updateCoD(records) { | ||||
|     var workItem; | ||||
|     var collection = []; | ||||
|     for (var i = 0; i < records.length; i++) { | ||||
|         workItem = records[i]; | ||||
|         if (workItem.Priority[0] === '2') { | ||||
|             workItem.EffortFibonacci = 2; | ||||
|             workItem.BusinessValueFibonacci = 2; | ||||
|             workItem.TimeCriticalityFibonacci = 2; | ||||
|             workItem.RiskReductionMinusOpportunityEnablementFibonacci = 2; | ||||
|             continue; | ||||
|         } | ||||
|         else if (workItem.Priority[0] === '3') { | ||||
|             workItem.EffortFibonacci = 1; | ||||
|             workItem.BusinessValueFibonacci = 1; | ||||
|             workItem.TimeCriticalityFibonacci = 1; | ||||
|             workItem.RiskReductionMinusOpportunityEnablementFibonacci = 1; | ||||
|             continue; | ||||
|         } | ||||
|         collection.push(workItem); | ||||
|     } | ||||
|     var fibonacci = getFibonacci(collection.length); | ||||
|     collection.sort(compareEffortFunction); | ||||
|     for (var i = 0; i < collection.length; i++) { | ||||
|         workItem = collection[i]; | ||||
|         workItem.EffortFibonacci = fibonacci[i]; | ||||
|     } | ||||
|     records.sort(compareEffortFunction); | ||||
|     for (var i = 0; i < records.length; i++) { | ||||
|         workItem = records[i]; | ||||
|         workItem.EffortRank = (((i + 1) / records.length) * 100).toFixed(); | ||||
|     } | ||||
|     collection.sort(compareBusinessValueFunction); | ||||
|     for (var i = 0; i < collection.length; i++) { | ||||
|         workItem = collection[i]; | ||||
|         workItem.BusinessValueFibonacci = fibonacci[i]; | ||||
|     } | ||||
|     records.sort(compareBusinessValueFunction); | ||||
|     for (var i = 0; i < records.length; i++) { | ||||
|         workItem = records[i]; | ||||
|         workItem.BusinessValueRank = (((i + 1) / records.length) * 100).toFixed(); | ||||
|     } | ||||
|     collection.sort(compareTimeCriticalityFunction); | ||||
|     for (var i = 0; i < collection.length; i++) { | ||||
|         workItem = collection[i]; | ||||
|         workItem.TimeCriticalityFibonacci = fibonacci[i]; | ||||
|     } | ||||
|     records.sort(compareTimeCriticalityFunction); | ||||
|     for (var i = 0; i < records.length; i++) { | ||||
|         workItem = records[i]; | ||||
|         workItem.TimeCriticalityRank = (((i + 1) / records.length) * 100).toFixed(); | ||||
|     } | ||||
|     collection.sort(compareRiskReductionMinusOpportunityEnablementFunction); | ||||
|     for (var i = 0; i < collection.length; i++) { | ||||
|         workItem = collection[i]; | ||||
|         workItem.RiskReductionMinusOpportunityEnablementFibonacci = fibonacci[i]; | ||||
|     } | ||||
|     records.sort(compareRiskReductionMinusOpportunityEnablementFunction); | ||||
|     for (var i = 0; i < records.length; i++) { | ||||
|         workItem = records[i]; | ||||
|         workItem.RiskReductionMinusOpportunityEnablementRank = (((i + 1) / records.length) * 100).toFixed(); | ||||
|     } | ||||
|     for (var i = 0; i < records.length; i++) { | ||||
|         workItem = records[i]; | ||||
|         workItem.CoD = workItem.RiskReductionMinusOpportunityEnablementFibonacci + workItem.TimeCriticalityFibonacci + workItem.BusinessValueFibonacci; | ||||
|     } | ||||
|     records.sort(compareCostOfDelay); | ||||
|     for (var i = 0; i < records.length; i++) { | ||||
|         workItem = records[i]; | ||||
|         workItem.CoDRank = (((i + 1) / records.length) * 100).toFixed(); | ||||
|     } | ||||
|     for (var i = 0; i < records.length; i++) { | ||||
|         workItem = records[i]; | ||||
|         if (workItem.Priority[0] !== '1' && workItem.Priority[0] !== '4') { | ||||
|             workItem.WeightedShortestJobFirst = 0.000001; | ||||
|             workItem.WeightedShortestJobFirstRank = 0; | ||||
|         } | ||||
|         else { | ||||
|             workItem.WeightedShortestJobFirstRank = (((i + 1) / records.length) * 100).toFixed(); | ||||
|             workItem.WeightedShortestJobFirst = (workItem.CoD / workItem.EffortFibonacci).toFixed(3); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| function updateRecordOther(workItem) { | ||||
|     workItem["State"] = getState(workItem["State"]); | ||||
|     workItem["Priority"] = getPriority(workItem["WorkItemType"], workItem["Priority"]); | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent == undefined) { | ||||
|         workItem["ParentId"] = 9999999; | ||||
|         workItem["ParentTitle"] = null; | ||||
|         workItem["ParentState"] = null; | ||||
|         workItem["ParentCoD"] = 9999999; | ||||
|     } | ||||
|     else { | ||||
|         workItem["ParentId"] = parent["Id"]; | ||||
|         workItem["ParentCoD"] = parent["CoD"]; | ||||
|         workItem["ParentTitle"] = parent["Title"]; | ||||
|         workItem["ParentState"] = getState(parent["State"]); | ||||
|     } | ||||
| } | ||||
|  | ||||
| function getRecords(data) { | ||||
|     var parent; | ||||
|     var workItem; | ||||
|     var records = []; | ||||
|     for (var i = 0; i < data.length; i++) { | ||||
|         parent = data[i].Parent; | ||||
|         workItem = data[i].WorkItem; | ||||
|         if (workItem.WorkItemType !== 'Feature') | ||||
|             continue; | ||||
|         if (workItem.State !== 'Active' && workItem.State !== 'New') | ||||
|             continue; | ||||
|         if (workItem.Tags != null && workItem.Tags.includes("Ignore")) | ||||
|             continue; | ||||
|         if ((window.location.href.indexOf('=LEO') > -1 && workItem.AreaPath !== 'ART SPS\\LEO') || (window.location.href.indexOf('=MES') > -1 && workItem.AreaPath !== 'ART SPS\\MES')) | ||||
|             continue; | ||||
|         updateRecordCoD(parent); | ||||
|         updateRecordCoD(workItem); | ||||
|         updateRecordOther(workItem); | ||||
|         updateRecordParent(parent, workItem); | ||||
|         records.push(workItem); | ||||
|     } | ||||
|     updateCoD(records); | ||||
|     records.sort(compareFunction); | ||||
|     return records; | ||||
| } | ||||
|  | ||||
| function setRecords(workItems) { | ||||
|     var record; | ||||
|     var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Priority</th><th>Risk Reduction and/or Opportunity Enablement</th><th>Time Criticality</th><th>Business Value</th><th>CoD</th><th>Effort</th><th>WSJF</th><th>Up</th><th>Down</th></tr>"; | ||||
|     const element = document.getElementById("HeaderGrid"); | ||||
|     for (var i = 0; i < workItems.length; i++) { | ||||
|         record = workItems[i]; | ||||
|         html += "<tr><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" + | ||||
|             "</td><td>" + record.ParentTitle + | ||||
|             "</td><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" + | ||||
|             "</td><td>" + record.Requester + | ||||
|             "</td><td>" + record.Title + | ||||
|             "</td><td>" + record.AssignedTo + | ||||
|             "</td><td>" + record.Tags + | ||||
|             "</td><td>" + record.State + | ||||
|             "</td><td>" + record.Priority + | ||||
|             "</td><td>" + record.RiskReductionMinusOpportunityEnablementRank + '% - ' + record.RiskReductionMinusOpportunityEnablement + ' - ' + record.RiskReductionMinusOpportunityEnablementFibonacci + | ||||
|             "</td><td>" + record.TimeCriticalityRank + '% - ' +record.TimeCriticality + ' - ' + record.TimeCriticalityFibonacci + | ||||
|             "</td><td>" + record.BusinessValueRank + '% - ' +record.BusinessValue + ' - ' + record.BusinessValueFibonacci + | ||||
|             "</td><td>" + record.CoDRank + '% - ' + record.CoD + | ||||
|             "</td><td>" + record.EffortRank + '% - ' +record.Effort + ' - ' + record.EffortFibonacci + | ||||
|             "</td><td>" + record.WeightedShortestJobFirst + | ||||
|             "</td><td><a href='#' class='up'>Up</a></td><td><a href='#' class='down'>Down</a></td></tr>"; | ||||
|     } | ||||
|     element.innerHTML = html.replaceAll(">null<", "> <"); | ||||
| } | ||||
|  | ||||
| function updateSite() { | ||||
|     if (window.location.href.indexOf('=LEO') > -1) { | ||||
|         document.title = document.title.replace("Infineon", "HiRel (Leominster)"); | ||||
|         document.getElementById("siteHeader").innerText = "HiRel (Leominster)"; | ||||
|     } | ||||
|     else if (window.location.href.indexOf('=MES') > -1) { | ||||
|         document.title = document.title.replace("Infineon", "Mesa"); | ||||
|         document.getElementById("siteHeader").innerText = "Mesa"; | ||||
|     } | ||||
|     else { | ||||
|         document.title = document.title.replace("Infineon", "Infineon"); | ||||
|         document.getElementById("siteHeader").innerText = "Infineon"; | ||||
|     } | ||||
| } | ||||
|  | ||||
| function initIndex(url, apiUrl) { | ||||
|     _apiUrl = apiUrl; | ||||
|     updateSite(); | ||||
|     $.getJSON(url, { _: new Date().getTime() }, function (data) { | ||||
|         var records = getRecords(data); | ||||
|         console.log(data.length); | ||||
|         if (data.length > 0) | ||||
|             console.log(data[0]); | ||||
|         setRecords(records); | ||||
|         $(".up,.down").click(function () { | ||||
|             var row = $(this).parents("tr:first"); | ||||
|             if ($(this).is(".up")) { | ||||
|                 row.insertBefore(row.prev()); | ||||
|             } else { | ||||
|                 row.insertAfter(row.next()); | ||||
|             } | ||||
|         }); | ||||
|     }); | ||||
|     $("#HeaderGrid").on("dblclick", "tr", loadOne); | ||||
| } | ||||
| @ -25,12 +25,12 @@ function compareCostOfDelay(a, b) { | ||||
| } | ||||
|  | ||||
| function showOne(rowData) { | ||||
|     if (rowData == null) | ||||
|     if (rowData == undefined) | ||||
|         return; | ||||
|     var data = []; | ||||
|     data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' }); | ||||
|     for (const property in rowData) { | ||||
|         if (rowData[property] == null) | ||||
|         if (rowData[property] == undefined) | ||||
|             continue; | ||||
|         data.push({ name: property, value: rowData[property].toString() }); | ||||
|     } | ||||
| @ -44,7 +44,7 @@ function showOne(rowData) { | ||||
|  | ||||
| function loadOne() { | ||||
|     var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow(); | ||||
|     if (selectedRow == null) | ||||
|     if (selectedRow == undefined) | ||||
|         return; | ||||
|     var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index]; | ||||
|     showOne(rowData); | ||||
| @ -59,7 +59,7 @@ function detailSelectionChangedRunInfo(evt, ui) { | ||||
|  | ||||
| function getState(state) { | ||||
|     var result; | ||||
|     if (state == null) | ||||
|     if (state == undefined) | ||||
|         result = "9-Null"; | ||||
|     else if (state === "New") | ||||
|         result = `1-${state}`; | ||||
| @ -80,7 +80,7 @@ function getPriority(workItemType, priority) { | ||||
|     var result; | ||||
|     if (workItemType === "Bug") | ||||
|         result = "0-Bug"; | ||||
|     else if (priority == null || priority === 0) | ||||
|     else if (priority == undefined || priority === 0) | ||||
|         result = "9-Null"; | ||||
|     else if (priority === 1) | ||||
|         result = `${priority}-High`; | ||||
| @ -96,14 +96,14 @@ function getPriority(workItemType, priority) { | ||||
| } | ||||
|  | ||||
| function updateRecordCoD(workItem) { | ||||
|     if (workItem !== null) { | ||||
|         if (workItem["Effort"] === null) | ||||
|     if (workItem != undefined) { | ||||
|         if (workItem["Effort"] == undefined) | ||||
|             workItem["Effort"] = 1; | ||||
|         if (workItem["BusinessValue"] === null) | ||||
|         if (workItem["BusinessValue"] == undefined) | ||||
|             workItem["BusinessValue"] = 99999; | ||||
|         if (workItem["TimeCriticality"] === null) | ||||
|         if (workItem["TimeCriticality"] == undefined) | ||||
|             workItem["TimeCriticality"] = 99999; | ||||
|         if (workItem["RiskReductionMinusOpportunityEnablement"] === null) | ||||
|         if (workItem["RiskReductionMinusOpportunityEnablement"] == undefined) | ||||
|             workItem["RiskReductionMinusOpportunityEnablement"] = 99999; | ||||
|     } | ||||
| } | ||||
| @ -218,7 +218,7 @@ function updateRecordOther(workItem) { | ||||
| } | ||||
|  | ||||
| function updateRecordParent(parent, workItem) { | ||||
|     if (parent === null) { | ||||
|     if (parent == undefined) { | ||||
|         workItem["ParentId"] = 9999999; | ||||
|         workItem["ParentTitle"] = null; | ||||
|         workItem["ParentState"] = null; | ||||
| @ -241,7 +241,7 @@ function getRecords(data) { | ||||
|         workItem = data[i].WorkItem; | ||||
|         if (workItem.WorkItemType !== 'Feature') | ||||
|             continue; | ||||
|         if (workItem.State !== 'New' && workItem.State !== 'Active') | ||||
|         if (workItem.State !== 'Active' && workItem.State !== 'New') | ||||
|             continue; | ||||
|         if (workItem.Tags != null && workItem.Tags.includes("Ignore")) | ||||
|             continue; | ||||
| @ -265,7 +265,7 @@ function setRecords(workItems) { | ||||
|     for (var i = 0; i < workItems.length; i++) { | ||||
|         record = workItems[i]; | ||||
|         html += "<tr><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" + | ||||
|             "</td><td>" + record.Title + | ||||
|             "</td><td>" + record.ParentTitle + | ||||
|             "</td><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" + | ||||
|             "</td><td>" + record.Requester + | ||||
|             "</td><td>" + record.Title + | ||||
|  | ||||
							
								
								
									
										37
									
								
								Adaptation/FileHandlers/json/StaticSite/styles/cod.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								Adaptation/FileHandlers/json/StaticSite/styles/cod.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,37 @@ | ||||
| #HeaderGridDiv, | ||||
| #DetailsGridDiv { | ||||
|     font-size: 12px; | ||||
|     min-width: 1200px; | ||||
|     max-width: 1200px; | ||||
| } | ||||
|  | ||||
| #HeaderGrid { | ||||
|     font-family: monospace; | ||||
|     margin-top: 60px; | ||||
| } | ||||
|  | ||||
| #HeaderGrid tr td { | ||||
|     max-width: 200px; | ||||
|     padding: 5px; | ||||
| } | ||||
|  | ||||
| #AllGrid { | ||||
|     font-family: monospace; | ||||
| } | ||||
|  | ||||
| .navbar-brand { | ||||
|     min-width: 1200px; | ||||
|     background-color: whitesmoke; | ||||
| } | ||||
|  | ||||
| tr:nth-of-type(odd) { | ||||
|     background-color: #eee; | ||||
| } | ||||
|  | ||||
| #AllTextarea { | ||||
|     font-family: monospace; | ||||
| } | ||||
|  | ||||
| #th-span { | ||||
|     margin-right: 500px; | ||||
| } | ||||
| @ -9,18 +9,21 @@ internal class Fields | ||||
| #nullable enable | ||||
|  | ||||
|     [JsonConstructor] | ||||
|     public Fields(float? customRRminusOE, | ||||
|     public Fields(decimal? customRRminusOE, | ||||
|                   CustomRequester? customRequester, | ||||
|                   float? customWSJF, | ||||
|                   decimal? customWSJF, | ||||
|                   decimal? customWSJFFib, | ||||
|                   DateTime microsoftVSTSCommonActivatedDate, | ||||
|                   float? microsoftVSTSCommonBusinessValue, | ||||
|                   decimal? microsoftVSTSCommonBusinessValue, | ||||
|                   DateTime microsoftVSTSCommonClosedDate, | ||||
|                   int microsoftVSTSCommonPriority, | ||||
|                   DateTime microsoftVSTSCommonResolvedDate, | ||||
|                   DateTime microsoftVSTSCommonStateChangeDate, | ||||
|                   float? microsoftVSTSCommonTimeCriticality, | ||||
|                   float? microsoftVSTSSchedulingEffort, | ||||
|                   decimal? microsoftVSTSCommonTimeCriticality, | ||||
|                   decimal? microsoftVSTSSchedulingEffort, | ||||
|                   decimal? microsoftVSTSSchedulingRemainingWork, | ||||
|                   DateTime microsoftVSTSSchedulingStartDate, | ||||
|                   decimal? microsoftVSTSSchedulingStoryPoints, | ||||
|                   DateTime microsoftVSTSSchedulingTargetDate, | ||||
|                   string systemAreaPath, | ||||
|                   SystemAssignedTo systemAssignedTo, | ||||
| @ -40,9 +43,10 @@ internal class Fields | ||||
|                   string systemTitle, | ||||
|                   string systemWorkItemType) | ||||
|     { | ||||
|         CustomRequester = customRequester; | ||||
|         CustomRRminusOE = customRRminusOE; | ||||
|         CustomRequester = customRequester; | ||||
|         CustomWSJF = customWSJF; | ||||
|         CustomWSJFFib = customWSJFFib; | ||||
|         MicrosoftVSTSCommonActivatedDate = microsoftVSTSCommonActivatedDate; | ||||
|         MicrosoftVSTSCommonBusinessValue = microsoftVSTSCommonBusinessValue; | ||||
|         MicrosoftVSTSCommonClosedDate = microsoftVSTSCommonClosedDate; | ||||
| @ -51,7 +55,9 @@ internal class Fields | ||||
|         MicrosoftVSTSCommonStateChangeDate = microsoftVSTSCommonStateChangeDate; | ||||
|         MicrosoftVSTSCommonTimeCriticality = microsoftVSTSCommonTimeCriticality; | ||||
|         MicrosoftVSTSSchedulingEffort = microsoftVSTSSchedulingEffort; | ||||
|         MicrosoftVSTSSchedulingRemainingWork = microsoftVSTSSchedulingRemainingWork; | ||||
|         MicrosoftVSTSSchedulingStartDate = microsoftVSTSSchedulingStartDate; | ||||
|         MicrosoftVSTSSchedulingStoryPoints = microsoftVSTSSchedulingStoryPoints; | ||||
|         MicrosoftVSTSSchedulingTargetDate = microsoftVSTSSchedulingTargetDate; | ||||
|         SystemAreaPath = systemAreaPath; | ||||
|         SystemAssignedTo = systemAssignedTo; | ||||
| @ -72,18 +78,21 @@ internal class Fields | ||||
|         SystemWorkItemType = systemWorkItemType; | ||||
|     } | ||||
|  | ||||
|     [JsonPropertyName("Custom.RRminusOE")] public decimal? CustomRRminusOE { get; } | ||||
|     [JsonPropertyName("Custom.Requester")] public CustomRequester? CustomRequester { get; } | ||||
|     [JsonPropertyName("Custom.RRminusOE")] public float? CustomRRminusOE { get; } | ||||
|     [JsonPropertyName("Custom.WSJF")] public float? CustomWSJF { get; } | ||||
|     [JsonPropertyName("Custom.WSJF")] public decimal? CustomWSJF { get; } | ||||
|     [JsonPropertyName("Custom.WSJFFib")] public decimal? CustomWSJFFib { get; } | ||||
|     [JsonPropertyName("Microsoft.VSTS.Common.ActivatedDate")] public DateTime MicrosoftVSTSCommonActivatedDate { get; } | ||||
|     [JsonPropertyName("Microsoft.VSTS.Common.BusinessValue")] public float? MicrosoftVSTSCommonBusinessValue { get; } | ||||
|     [JsonPropertyName("Microsoft.VSTS.Common.BusinessValue")] public decimal? MicrosoftVSTSCommonBusinessValue { get; } | ||||
|     [JsonPropertyName("Microsoft.VSTS.Common.ClosedDate")] public DateTime MicrosoftVSTSCommonClosedDate { get; } | ||||
|     [JsonPropertyName("Microsoft.VSTS.Common.Priority")] public int MicrosoftVSTSCommonPriority { get; } | ||||
|     [JsonPropertyName("Microsoft.VSTS.Common.ResolvedDate")] public DateTime MicrosoftVSTSCommonResolvedDate { get; } | ||||
|     [JsonPropertyName("Microsoft.VSTS.Common.StateChangeDate")] public DateTime MicrosoftVSTSCommonStateChangeDate { get; } | ||||
|     [JsonPropertyName("Microsoft.VSTS.Common.TimeCriticality")] public float? MicrosoftVSTSCommonTimeCriticality { get; } | ||||
|     [JsonPropertyName("Microsoft.VSTS.Scheduling.Effort")] public float? MicrosoftVSTSSchedulingEffort { get; } | ||||
|     [JsonPropertyName("Microsoft.VSTS.Common.TimeCriticality")] public decimal? MicrosoftVSTSCommonTimeCriticality { get; } | ||||
|     [JsonPropertyName("Microsoft.VSTS.Scheduling.Effort")] public decimal? MicrosoftVSTSSchedulingEffort { get; } | ||||
|     [JsonPropertyName("Microsoft.VSTS.Scheduling.RemainingWork")] public decimal? MicrosoftVSTSSchedulingRemainingWork { get; } | ||||
|     [JsonPropertyName("Microsoft.VSTS.Scheduling.StartDate")] public DateTime MicrosoftVSTSSchedulingStartDate { get; } | ||||
|     [JsonPropertyName("Microsoft.VSTS.Scheduling.StoryPoints")] public decimal? MicrosoftVSTSSchedulingStoryPoints { get; } | ||||
|     [JsonPropertyName("Microsoft.VSTS.Scheduling.TargetDate")] public DateTime MicrosoftVSTSSchedulingTargetDate { get; } | ||||
|     [JsonPropertyName("System.AreaPath")] public string SystemAreaPath { get; } | ||||
|     [JsonPropertyName("System.AssignedTo")] public SystemAssignedTo? SystemAssignedTo { get; } | ||||
|  | ||||
| @ -2,6 +2,7 @@ using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.ObjectModel; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
| using System.Text.Json.Serialization; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.json.WorkItems; | ||||
| @ -12,13 +13,14 @@ internal class Record | ||||
| #nullable enable | ||||
|  | ||||
|     [JsonConstructor] | ||||
|     public Record(WorkItem workItem, WorkItem? parent, Record[]? children, Record[]? related, Record[]? successors) | ||||
|     public Record(WorkItem workItem, WorkItem? parent, Record[]? children, Record[]? related, Record[]? successors, Dictionary<string, string>? tag) | ||||
|     { | ||||
|         WorkItem = workItem; | ||||
|         Parent = parent; | ||||
|         Children = children; | ||||
|         Related = related; | ||||
|         Successors = successors; | ||||
|         Tag = tag; | ||||
|     } | ||||
|  | ||||
|     [JsonPropertyName("WorkItem")] public WorkItem WorkItem { get; set; } | ||||
| @ -26,39 +28,43 @@ internal class Record | ||||
|     [JsonPropertyName("Children")] public Record[]? Children { get; set; } | ||||
|     [JsonPropertyName("Related")] public Record[]? Related { get; set; } | ||||
|     [JsonPropertyName("Successors")] public Record[]? Successors { get; set; } | ||||
|     [JsonPropertyName("Tag")] public Dictionary<string, string>? Tag { get; set; } | ||||
|  | ||||
|     internal static Record GetWithoutNesting(Record record, string? violation) | ||||
|     { | ||||
|         Record result; | ||||
|         WorkItem workItem = new(record.WorkItem.ActivatedDate, | ||||
|                                 record.WorkItem.AreaPath, | ||||
|                                 record.WorkItem.AssignedTo, | ||||
|                                 record.WorkItem.BusinessValue, | ||||
|                                 record.WorkItem.ChangedDate, | ||||
|                                 record.WorkItem.ClosedDate, | ||||
|                                 record.WorkItem.CommentCount, | ||||
|                                 record.WorkItem.CreatedDate, | ||||
|                                 record.WorkItem.Description, | ||||
|                                 record.WorkItem.Effort, | ||||
|                                 record.WorkItem.Id, | ||||
|                                 record.WorkItem.IterationPath, | ||||
|                                 record.WorkItem.Parent, | ||||
|                                 record.WorkItem.Priority, | ||||
|                                 record.WorkItem.Relations, | ||||
|                                 record.WorkItem.Requester, | ||||
|                                 record.WorkItem.ResolvedDate, | ||||
|                                 record.WorkItem.Revision, | ||||
|                                 record.WorkItem.RiskReductionMinusOpportunityEnablement, | ||||
|                                 record.WorkItem.StartDate, | ||||
|                                 record.WorkItem.State, | ||||
|                                 record.WorkItem.Tags, | ||||
|                                 record.WorkItem.TargetDate, | ||||
|                                 record.WorkItem.TimeCriticality, | ||||
|                                 record.WorkItem.Title, | ||||
|                                 record.WorkItem.Violation is null ? violation : record.WorkItem.Violation, | ||||
|                                 record.WorkItem.WeightedShortestJobFirst, | ||||
|                                 record.WorkItem.WorkItemType); | ||||
|         result = new(workItem, record.Parent, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>()); | ||||
|         WorkItem workItem = new(activatedDate: record.WorkItem.ActivatedDate, | ||||
|                                 areaPath: record.WorkItem.AreaPath, | ||||
|                                 assignedTo: record.WorkItem.AssignedTo, | ||||
|                                 businessValue: record.WorkItem.BusinessValue, | ||||
|                                 changedDate: record.WorkItem.ChangedDate, | ||||
|                                 closedDate: record.WorkItem.ClosedDate, | ||||
|                                 commentCount: record.WorkItem.CommentCount, | ||||
|                                 createdDate: record.WorkItem.CreatedDate, | ||||
|                                 description: record.WorkItem.Description, | ||||
|                                 effort: record.WorkItem.Effort, | ||||
|                                 id: record.WorkItem.Id, | ||||
|                                 iterationPath: record.WorkItem.IterationPath, | ||||
|                                 parent: record.WorkItem.Parent, | ||||
|                                 priority: record.WorkItem.Priority, | ||||
|                                 relations: record.WorkItem.Relations, | ||||
|                                 remainingWork: record.WorkItem.RemainingWork, | ||||
|                                 requester: record.WorkItem.Requester, | ||||
|                                 resolvedDate: record.WorkItem.ResolvedDate, | ||||
|                                 revision: record.WorkItem.Revision, | ||||
|                                 riskReductionMinusOpportunityEnablement: record.WorkItem.RiskReductionMinusOpportunityEnablement, | ||||
|                                 startDate: record.WorkItem.StartDate, | ||||
|                                 state: record.WorkItem.State, | ||||
|                                 storyPoints: record.WorkItem.StoryPoints, | ||||
|                                 tags: record.WorkItem.Tags, | ||||
|                                 targetDate: record.WorkItem.TargetDate, | ||||
|                                 timeCriticality: record.WorkItem.TimeCriticality, | ||||
|                                 title: record.WorkItem.Title, | ||||
|                                 violation: record.WorkItem.Violation is null ? violation : record.WorkItem.Violation, | ||||
|                                 weightedShortestJobFirst: record.WorkItem.WeightedShortestJobFirst, | ||||
|                                 weightedShortestJobFirstFibonacci: record.WorkItem.WeightedShortestJobFirstFibonacci, | ||||
|                                 workItemType: record.WorkItem.WorkItemType); | ||||
|         result = new(workItem, record.Parent, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>(), record.Tag); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
| @ -98,14 +104,40 @@ internal class Record | ||||
|                 relationRecords.Add(Get(r, keepRelations)); | ||||
|             successorRecords = relationRecords.ToArray(); | ||||
|         } | ||||
|         result = new(workItem, parentWorkItem, childRecords, relatedRecords, successorRecords); | ||||
|         result = new(workItem, parentWorkItem, childRecords, relatedRecords, successorRecords, record.Tag); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     internal static Dictionary<string, string>? GetTag(ReadOnlyCollection<Record>? records) | ||||
|     { | ||||
|         Dictionary<string, string>? result; | ||||
|         if (records is null) | ||||
|             result = null; | ||||
|         else | ||||
|         { | ||||
|             List<long> collection = new(); | ||||
|             foreach (Record record in records) | ||||
|             { | ||||
|                 if (record.WorkItem.State is "Closed" or "Resolved" || record.WorkItem.StoryPoints is null) | ||||
|                     continue; | ||||
|                 collection.Add(record.WorkItem.StoryPoints.Value); | ||||
|             } | ||||
|             if (collection.Count == 0) | ||||
|                 result = null; | ||||
|             else | ||||
|             { | ||||
|                 string json = JsonSerializer.Serialize(collection); | ||||
|                 result = new Dictionary<string, string> { { "StoryPoints", json } }; | ||||
|             } | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     internal static Record Get(WorkItem workItem, WorkItem? parent, ReadOnlyCollection<Record>? children, ReadOnlyCollection<Record>? related, ReadOnlyCollection<Record>? successors, bool keepRelations) | ||||
|     { | ||||
|         Record result; | ||||
|         Record record = new(workItem, parent, children?.ToArray(), related?.ToArray(), successors?.ToArray()); | ||||
|         Dictionary<string, string>? tag = GetTag(children); | ||||
|         Record record = new(workItem, parent, children?.ToArray(), related?.ToArray(), successors?.ToArray(), tag); | ||||
|         result = Get(record, keepRelations); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
| @ -24,18 +24,21 @@ internal class WorkItem | ||||
|                     int? parent, | ||||
|                     int? priority, | ||||
|                     Relation[]? relations, | ||||
|                     long? remainingWork, | ||||
|                     string? requester, | ||||
|                     DateTime? resolvedDate, | ||||
|                     int revision, | ||||
|                     long? riskReductionMinusOpportunityEnablement, | ||||
|                     DateTime? startDate, | ||||
|                     string state, | ||||
|                     long? storyPoints, | ||||
|                     string tags, | ||||
|                     DateTime? targetDate, | ||||
|                     long? timeCriticality, | ||||
|                     string title, | ||||
|                     string? violation, | ||||
|                     long? weightedShortestJobFirst, | ||||
|                     decimal? weightedShortestJobFirst, | ||||
|                     decimal? weightedShortestJobFirstFibonacci, | ||||
|                     string workItemType) | ||||
|     { | ||||
|         ActivatedDate = activatedDate; | ||||
| @ -53,18 +56,21 @@ internal class WorkItem | ||||
|         Parent = parent; | ||||
|         Priority = priority; | ||||
|         Relations = relations; | ||||
|         RemainingWork = remainingWork; | ||||
|         Requester = requester; | ||||
|         ResolvedDate = resolvedDate; | ||||
|         Revision = revision; | ||||
|         RiskReductionMinusOpportunityEnablement = riskReductionMinusOpportunityEnablement; | ||||
|         StartDate = startDate; | ||||
|         State = state; | ||||
|         StoryPoints = storyPoints; | ||||
|         Tags = tags; | ||||
|         TargetDate = targetDate; | ||||
|         TimeCriticality = timeCriticality; | ||||
|         Title = title; | ||||
|         Violation = violation; | ||||
|         WeightedShortestJobFirst = weightedShortestJobFirst; | ||||
|         WeightedShortestJobFirstFibonacci = weightedShortestJobFirstFibonacci; | ||||
|         WorkItemType = workItemType; | ||||
|     } | ||||
|  | ||||
| @ -72,67 +78,73 @@ internal class WorkItem | ||||
|  | ||||
|     public static WorkItem Get(WorkItem workItem, Relation[] relations) | ||||
|     { | ||||
|         WorkItem result = new(workItem.ActivatedDate, | ||||
|                               workItem.AreaPath, | ||||
|                               workItem.AssignedTo, | ||||
|                               workItem.BusinessValue, | ||||
|                               workItem.ChangedDate, | ||||
|                               workItem.ClosedDate, | ||||
|                               workItem.CommentCount, | ||||
|                               workItem.CreatedDate, | ||||
|                               workItem.Description, | ||||
|                               workItem.Effort, | ||||
|                               workItem.Id, | ||||
|                               workItem.IterationPath, | ||||
|                               workItem.Parent, | ||||
|                               workItem.Priority, | ||||
|                               relations, | ||||
|                               workItem.Requester, | ||||
|                               workItem.ResolvedDate, | ||||
|                               workItem.Revision, | ||||
|                               workItem.RiskReductionMinusOpportunityEnablement, | ||||
|                               workItem.StartDate, | ||||
|                               workItem.State, | ||||
|                               workItem.Tags, | ||||
|                               workItem.TargetDate, | ||||
|                               workItem.TimeCriticality, | ||||
|                               workItem.Title, | ||||
|                               workItem.Violation, | ||||
|                               workItem.WeightedShortestJobFirst, | ||||
|                               workItem.WorkItemType); | ||||
|         WorkItem result = new(activatedDate: workItem.ActivatedDate, | ||||
|                               areaPath: workItem.AreaPath, | ||||
|                               assignedTo: workItem.AssignedTo, | ||||
|                               businessValue: workItem.BusinessValue, | ||||
|                               changedDate: workItem.ChangedDate, | ||||
|                               closedDate: workItem.ClosedDate, | ||||
|                               commentCount: workItem.CommentCount, | ||||
|                               createdDate: workItem.CreatedDate, | ||||
|                               description: workItem.Description, | ||||
|                               effort: workItem.Effort, | ||||
|                               id: workItem.Id, | ||||
|                               iterationPath: workItem.IterationPath, | ||||
|                               parent: workItem.Parent, | ||||
|                               priority: workItem.Priority, | ||||
|                               relations: relations, | ||||
|                               remainingWork: workItem.RemainingWork, | ||||
|                               requester: workItem.Requester, | ||||
|                               resolvedDate: workItem.ResolvedDate, | ||||
|                               revision: workItem.Revision, | ||||
|                               riskReductionMinusOpportunityEnablement: workItem.RiskReductionMinusOpportunityEnablement, | ||||
|                               startDate: workItem.StartDate, | ||||
|                               state: workItem.State, | ||||
|                               storyPoints: workItem.StoryPoints, | ||||
|                               tags: workItem.Tags, | ||||
|                               targetDate: workItem.TargetDate, | ||||
|                               timeCriticality: workItem.TimeCriticality, | ||||
|                               title: workItem.Title, | ||||
|                               violation: workItem.Violation, | ||||
|                               weightedShortestJobFirst: workItem.WeightedShortestJobFirst, | ||||
|                               weightedShortestJobFirstFibonacci: workItem.WeightedShortestJobFirstFibonacci, | ||||
|                               workItemType: workItem.WorkItemType); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     public static WorkItem? GetWithOutRelations(WorkItem? workItem) | ||||
|     { | ||||
|         WorkItem? result = workItem is null ? null : new(workItem.ActivatedDate, | ||||
|                                                          workItem.AreaPath, | ||||
|                                                          workItem.AssignedTo, | ||||
|                                                          workItem.BusinessValue, | ||||
|                                                          workItem.ChangedDate, | ||||
|                                                          workItem.ClosedDate, | ||||
|                                                          workItem.CommentCount, | ||||
|                                                          workItem.CreatedDate, | ||||
|                                                          workItem.Description, | ||||
|                                                          workItem.Effort, | ||||
|                                                          workItem.Id, | ||||
|                                                          workItem.IterationPath, | ||||
|                                                          workItem.Parent, | ||||
|                                                          workItem.Priority, | ||||
|                                                          Array.Empty<Relation>(), | ||||
|                                                          workItem.Requester, | ||||
|                                                          workItem.ResolvedDate, | ||||
|                                                          workItem.Revision, | ||||
|                                                          workItem.RiskReductionMinusOpportunityEnablement, | ||||
|                                                          workItem.StartDate, | ||||
|                                                          workItem.State, | ||||
|                                                          workItem.Tags, | ||||
|                                                          workItem.TargetDate, | ||||
|                                                          workItem.TimeCriticality, | ||||
|                                                          workItem.Title, | ||||
|                                                          workItem.Violation, | ||||
|                                                          workItem.WeightedShortestJobFirst, | ||||
|                                                          workItem.WorkItemType); | ||||
|         WorkItem? result = workItem is null ? null : new(activatedDate: workItem.ActivatedDate, | ||||
|                                                          areaPath: workItem.AreaPath, | ||||
|                                                          assignedTo: workItem.AssignedTo, | ||||
|                                                          businessValue: workItem.BusinessValue, | ||||
|                                                          changedDate: workItem.ChangedDate, | ||||
|                                                          closedDate: workItem.ClosedDate, | ||||
|                                                          commentCount: workItem.CommentCount, | ||||
|                                                          createdDate: workItem.CreatedDate, | ||||
|                                                          description: workItem.Description, | ||||
|                                                          effort: workItem.Effort, | ||||
|                                                          id: workItem.Id, | ||||
|                                                          iterationPath: workItem.IterationPath, | ||||
|                                                          parent: workItem.Parent, | ||||
|                                                          priority: workItem.Priority, | ||||
|                                                          relations: Array.Empty<Relation>(), | ||||
|                                                          remainingWork: workItem.RemainingWork, | ||||
|                                                          requester: workItem.Requester, | ||||
|                                                          resolvedDate: workItem.ResolvedDate, | ||||
|                                                          revision: workItem.Revision, | ||||
|                                                          riskReductionMinusOpportunityEnablement: workItem.RiskReductionMinusOpportunityEnablement, | ||||
|                                                          startDate: workItem.StartDate, | ||||
|                                                          state: workItem.State, | ||||
|                                                          storyPoints: workItem.StoryPoints, | ||||
|                                                          tags: workItem.Tags, | ||||
|                                                          targetDate: workItem.TargetDate, | ||||
|                                                          timeCriticality: workItem.TimeCriticality, | ||||
|                                                          title: workItem.Title, | ||||
|                                                          violation: workItem.Violation, | ||||
|                                                          weightedShortestJobFirst: workItem.WeightedShortestJobFirst, | ||||
|                                                          weightedShortestJobFirstFibonacci: workItem.WeightedShortestJobFirstFibonacci, | ||||
|                                                          workItemType: workItem.WorkItemType); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
| @ -151,18 +163,21 @@ internal class WorkItem | ||||
|     [JsonPropertyName("Parent")] public int? Parent { get; } | ||||
|     [JsonPropertyName("Priority")] public int? Priority { get; } | ||||
|     [JsonPropertyName("Relations")] public Relation[]? Relations { get; } | ||||
|     [JsonPropertyName("RemainingWork")] public long? RemainingWork { get; } | ||||
|     [JsonPropertyName("Requester")] public string? Requester { get; } | ||||
|     [JsonPropertyName("ResolvedDate")] public DateTime? ResolvedDate { get; } | ||||
|     [JsonPropertyName("Revision")] public int Revision { get; } | ||||
|     [JsonPropertyName("RiskReductionMinusOpportunityEnablement")] public long? RiskReductionMinusOpportunityEnablement { get; } | ||||
|     [JsonPropertyName("StartDate")] public DateTime? StartDate { get; } | ||||
|     [JsonPropertyName("State")] public string State { get; } | ||||
|     [JsonPropertyName("StoryPoints")] public long? StoryPoints { get; } | ||||
|     [JsonPropertyName("Tags")] public string Tags { get; } | ||||
|     [JsonPropertyName("TargetDate")] public DateTime? TargetDate { get; } | ||||
|     [JsonPropertyName("TimeCriticality")] public long? TimeCriticality { get; } | ||||
|     [JsonPropertyName("Title")] public string Title { get; } | ||||
|     [JsonPropertyName("Violation")] public string? Violation { get; } | ||||
|     [JsonPropertyName("WeightedShortestJobFirst")] public long? WeightedShortestJobFirst { get; } | ||||
|     [JsonPropertyName("WeightedShortestJobFirst")] public decimal? WeightedShortestJobFirst { get; } | ||||
|     [JsonPropertyName("WeightedShortestJobFirstFibonacci")] public decimal? WeightedShortestJobFirstFibonacci { get; } | ||||
|     [JsonPropertyName("WorkItemType")] public string WorkItemType { get; } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -226,9 +226,9 @@ public class MonIn : IMonIn, IDisposable | ||||
|     { | ||||
|         StringBuilder stringBuilder = new(); | ||||
|         if (string.IsNullOrEmpty(subresource)) | ||||
|             _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" {4} \n{5}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), stateName.Trim(), state.Trim(), description.Trim()); | ||||
|             _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" {4} \n{5}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : "now", resource.Trim(), stateName.Trim(), state.Trim(), description.Trim()); | ||||
|         else | ||||
|             _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" \"{4}\" {5} \n{6}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), subresource.Trim(), stateName.Trim(), state.Trim(), description.Trim()); | ||||
|             _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" \"{4}\" {5} \n{6}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : "now", resource.Trim(), subresource.Trim(), stateName.Trim(), state.Trim(), description.Trim()); | ||||
|         return stringBuilder.ToString(); | ||||
|     } | ||||
|  | ||||
| @ -247,14 +247,14 @@ public class MonIn : IMonIn, IDisposable | ||||
|         if (string.IsNullOrEmpty(subresource)) | ||||
|         { | ||||
|             if (unit.Equals(string.Empty) && !interval.HasValue) | ||||
|                 _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" {4} \n{5}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), performanceName.Trim(), value, description.Trim()); | ||||
|                 _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" {4} \n{5}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : "now", resource.Trim(), performanceName.Trim(), value, description.Trim()); | ||||
|             else | ||||
|                 _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" {4} {5} {{interval={6}, unit={7}}}\n", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), performanceName.Trim(), value, description.Trim(), interval.HasValue ? interval.Value.ToString() : (object)string.Empty, unit.Trim()); | ||||
|                 _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" {4} {5} {{interval={6}, unit={7}}}\n", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : "now", resource.Trim(), performanceName.Trim(), value, description.Trim(), interval.HasValue ? interval.Value.ToString() : string.Empty, unit.Trim()); | ||||
|         } | ||||
|         else if (unit.Equals(string.Empty) && !interval.HasValue) | ||||
|             _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" \"{4}\" {5} \n{6}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), subresource.Trim(), performanceName.Trim(), value, description.Trim()); | ||||
|             _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" \"{4}\" {5} \n{6}", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : "now", resource.Trim(), subresource.Trim(), performanceName.Trim(), value, description.Trim()); | ||||
|         else | ||||
|             _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" \"{4}\" {5} {6} {{interval={7}, unit={8}}}\n", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : (object)"now", resource.Trim(), subresource.Trim(), performanceName.Trim(), value, description.Trim(), interval.HasValue ? interval.Value.ToString() : (object)string.Empty, unit.Trim()); | ||||
|             _ = stringBuilder.AppendFormat(_CultureInfo, "> {0} {1} \"{2}\" \"{3}\" \"{4}\" {5} {6} {{interval={7}, unit={8}}}\n", site.Trim(), timeStamp.HasValue ? GetDateTimeNowAsPosix(timeStamp.Value) : "now", resource.Trim(), subresource.Trim(), performanceName.Trim(), value, description.Trim(), interval.HasValue ? interval.Value.ToString() : string.Empty, unit.Trim()); | ||||
|         return stringBuilder.ToString(); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -1,163 +1 @@ | ||||
| trigger: | ||||
|   branches: | ||||
|     include: | ||||
|       - Development | ||||
|   paths: | ||||
|     include: | ||||
|       - "Adaptation/*" | ||||
|  | ||||
| pool: | ||||
|   name: eaf | ||||
|   demands: MESAFIBACKLOG-Development | ||||
|  | ||||
| steps: | ||||
|   - script: | | ||||
|       set coreVersion=net7.0 | ||||
|       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: | | ||||
|       set nugetSource=https://eaf-dev-reporting.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 $(Build.BuildId) | ||||
|       echo $(Build.Reason) | ||||
|       echo $(Build.Repository.Id) | ||||
|       echo $(Build.Repository.Name) | ||||
|       echo $(Build.SourceVersion) | ||||
|       echo $(CoreVersion) | ||||
|       echo $(Configuration) | ||||
|       echo $(NugetSource) | ||||
|       echo $(GitCommitSeven) | ||||
|       REM echo $(pipelinePassword) | ||||
|     displayName: "Echo Check" | ||||
|  | ||||
|   - script: '"C:\program files\dotnet\dotnet.exe" nuget locals all --clear' | ||||
|     displayName: "Nuget Clear" | ||||
|     enabled: false | ||||
|  | ||||
|   - script: | | ||||
|       "C:\program files\dotnet\dotnet.exe" user-secrets init | ||||
|       "C:\program files\dotnet\dotnet.exe" user-secrets set "BuildNumber" "$(Build.BuildId)" | ||||
|       "C:\program files\dotnet\dotnet.exe" user-secrets set "GitCommitSeven" "$(GitCommitSeven)" | ||||
|       "C:\program files\dotnet\dotnet.exe" user-secrets list | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Safe storage of app secrets - Adaptation" | ||||
|  | ||||
|   - script: '"C:\program files\dotnet\dotnet.exe" build --configuration $(Configuration) --source $(NugetSource)' | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Core Build - Adaptation" | ||||
|  | ||||
|   - powershell: Get-ChildItem .\ -include TestResults -Recurse | foreach ($_) { remove-item $_.fullname -Force -Recurse } | ||||
|     workingDirectory: "$(System.DefaultWorkingDirectory)/../../../$(Build.Repository.Name)" | ||||
|     displayName: "PowerShell Script" | ||||
|     continueOnError: true | ||||
|  | ||||
|   - script: "dotnet test --configuration $(Configuration)" | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Core Test" | ||||
|  | ||||
|   - script: 'move /y "$(System.DefaultWorkingDirectory)/../../../$(Build.Repository.Name)/05_TestResults/TestResults" $(System.DefaultWorkingDirectory)' | ||||
|     displayName: "Move Results" | ||||
|  | ||||
|   - script: '"C:\program files\dotnet\dotnet.exe" tool restore' | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Tool Restore" | ||||
|     enabled: false | ||||
|  | ||||
|   - script: '"C:\program files\dotnet\dotnet.exe" ReportGenerator -reports:$(System.DefaultWorkingDirectory)/TestResults/**/coverage.cobertura.xml -targetDir:$(Build.ArtifactStagingDirectory)\Coverage -reportTypes:Html_Dark' | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Report Generator" | ||||
|     enabled: false | ||||
|  | ||||
|   - task: PublishTestResults@2 | ||||
|     displayName: "Publish Test Results **/*.trx" | ||||
|     inputs: | ||||
|       testResultsFormat: VSTest | ||||
|       testResultsFiles: "**/*.trx" | ||||
|       testRunTitle: "$(GitCommitSeven)-$(Build.BuildId)-$(CoreVersion)-$(Configuration)-$(Build.Repository.Name)" | ||||
|       searchFolder: "$(System.DefaultWorkingDirectory)/TestResults" | ||||
|  | ||||
|   - task: PublishTestResults@2 | ||||
|     displayName: "Publish Test Results */coverage.cobertura.xml" | ||||
|     inputs: | ||||
|       testResultsFormat: VSTest | ||||
|       testResultsFiles: "*/coverage.cobertura.xml" | ||||
|       testRunTitle: "$(GitCommitSeven)-$(Build.BuildId)-$(CoreVersion)-$(Configuration)-$(Build.Repository.Name)" | ||||
|       searchFolder: "$(System.DefaultWorkingDirectory)/TestResults" | ||||
|  | ||||
|   - task: mspremier.CreateWorkItem.CreateWorkItem-task.CreateWorkItem@1 | ||||
|     displayName: "Create work item" | ||||
|     inputs: | ||||
|       teamProject: "Mesa_FI" | ||||
|       workItemType: Bug | ||||
|       title: $(GitCommitSeven)-$(Build.BuildId)-$(Build.Repository.Name)-$(Configuration) | ||||
|       assignedTo: "$(Build.RequestedForId)" | ||||
|     enabled: false | ||||
|  | ||||
|   - script: '"C:\program files\dotnet\dotnet.exe" publish --configuration $(Configuration) --runtime win-x64 --self-contained -o $(Build.ArtifactStagingDirectory)\Adaptation --source $(NugetSource)' | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Core Publish" | ||||
|     enabled: false | ||||
|  | ||||
|   - script: '"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" /target:Restore /detailedsummary /consoleloggerparameters:PerformanceSummary;ErrorsOnly; /property:Configuration=$(Configuration);TargetFrameworkVersion=v4.8 /p:RestoreSources=$(NugetSource)' | ||||
|     displayName: "MSBuild Restore" | ||||
|  | ||||
|   - script: '"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" /target:Build /detailedsummary /consoleloggerparameters:PerformanceSummary;ErrorsOnly; /property:Configuration=$(Configuration);TargetFrameworkVersion=v4.8' | ||||
|     displayName: MSBuild | ||||
|  | ||||
|   - script: 'echo $(Build.SourceVersion)-$(Build.BuildId)-$(Build.Repository.Name)>bin\$(Configuration)\$(Build.Repository.Name).txt' | ||||
|     displayName: "Commit Id" | ||||
|  | ||||
|   - task: CopyFiles@2 | ||||
|     displayName: 'Copy Files to: D:\Framework4.8' | ||||
|     inputs: | ||||
|       Contents: "*$(Build.Repository.Name)*" | ||||
|       SourceFolder: 'bin\$(Configuration)' | ||||
|       TargetFolder: 'D:\Framework4.8\$(GitCommitSeven)-$(Build.BuildId)-$(Build.Repository.Name)-$(Configuration)' | ||||
|       OverWrite: true | ||||
|     enabled: false | ||||
|  | ||||
|   - task: CopyFiles@2 | ||||
|     displayName: 'Copy Files to: \\mesfs.infineon.com\EC_EAFRepository' | ||||
|     inputs: | ||||
|       Contents: "*$(Build.Repository.Name)*" | ||||
|       SourceFolder: 'bin\$(Configuration)' | ||||
|       TargetFolder: '\\mesfs.infineon.com\EC_EAFRepository\Staging\DeploymentStorage\Adaptation_$(Build.Repository.Name)' | ||||
|       OverWrite: true | ||||
|     enabled: false | ||||
|  | ||||
|   - script: | | ||||
|       "C:\program files\dotnet\dotnet.exe" clean --configuration $(Configuration) | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Core Clean - Tests" | ||||
|  | ||||
|   - script: | | ||||
|       "C:\program files\dotnet\dotnet.exe" clean --configuration $(Configuration) | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Core Clean - Adaptation" | ||||
|  | ||||
|   - script: 'echo $(Build.SourceVersion)-$(Build.BuildId)>bin_x_x_\$(Configuration)\$(CoreVersion)\win-x64\$(Build.Repository.Name).txt' | ||||
|     displayName: "Force Fail" | ||||
|     enabled: false | ||||
| # dotnet nuget push --source https://tfs.intra.infineon.com/tfs/FactoryIntegration/fccf8303-9cf7-4788-a9e0-4042541503fa/_packaging/EAF-Mesa-Integration/nuget/v3/index.json --api-key az D:\vsts-agent-win-x64-2.210.1-eaf\nuget\infineon.mesa.pdf.text.stripper.4.8.0.1.nupkg | ||||
| @ -35,39 +35,57 @@ | ||||
|         <RuntimeHostConfigurationOption Include="AssemblyName" Value="MESAFIBACKLOG" /> | ||||
|     </ItemGroup> | ||||
|     <ItemGroup> | ||||
|         <PackageReference Include="coverlet.collector" Version="6.0.2" /> | ||||
|         <PackageReference Include="CommonMark.NET" Version="0.15.1" /> | ||||
|         <PackageReference Include="coverlet.collector" Version="6.0.3" /> | ||||
|         <PackageReference Include="FFMpegCore" Version="5.1.0" /> | ||||
|         <PackageReference Include="IKVM.AWT.WinForms" Version="7.2.4630.5"><NoWarn>NU1701</NoWarn></PackageReference> | ||||
|         <PackageReference Include="IKVM.OpenJDK.Core" Version="7.2.4630.5"><NoWarn>NU1701</NoWarn></PackageReference> | ||||
|         <PackageReference Include="IKVM.OpenJDK.Media" Version="7.2.4630.5"><NoWarn>NU1701</NoWarn></PackageReference> | ||||
|         <PackageReference Include="IKVM.OpenJDK.Text" Version="7.2.4630.5"><NoWarn>NU1701</NoWarn></PackageReference> | ||||
|         <PackageReference Include="IKVM.OpenJDK.Util" Version="7.2.4630.5"><NoWarn>NU1701</NoWarn></PackageReference> | ||||
|         <PackageReference Include="IKVM.OpenJDK.XML.API" Version="7.2.4630.5"><NoWarn>NU1701</NoWarn></PackageReference> | ||||
|         <PackageReference Include="IKVM.Runtime" Version="7.2.4630.5"><NoWarn>NU1701</NoWarn></PackageReference> | ||||
|         <PackageReference Include="Instances" Version="3.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="8.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="8.0.1" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Configuration.json" Version="8.0.1" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.1" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" /> | ||||
|         <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" /> | ||||
|         <PackageReference Include="Microsoft.Win32.SystemEvents" Version="8.0.0" /> | ||||
|         <PackageReference Include="MSTest.TestAdapter" Version="3.6.1" /> | ||||
|         <PackageReference Include="MSTest.TestFramework" Version="3.6.1" /> | ||||
|         <PackageReference Include="Pdfbox" Version="1.1.1"><NoWarn>NU1701</NoWarn></PackageReference> | ||||
|         <PackageReference Include="RoboSharp" Version="1.5.3" /> | ||||
|         <PackageReference Include="System.Configuration.ConfigurationManager" Version="8.0.1" /> | ||||
|         <PackageReference Include="System.Data.OleDb" Version="8.0.1" /> | ||||
|         <PackageReference Include="IKVM.AWT.WinForms" Version="7.2.4630.5"> | ||||
|             <NoWarn>NU1701</NoWarn> | ||||
|         </PackageReference> | ||||
|         <PackageReference Include="IKVM.OpenJDK.Core" Version="7.2.4630.5"> | ||||
|             <NoWarn>NU1701</NoWarn> | ||||
|         </PackageReference> | ||||
|         <PackageReference Include="IKVM.OpenJDK.Media" Version="7.2.4630.5"> | ||||
|             <NoWarn>NU1701</NoWarn> | ||||
|         </PackageReference> | ||||
|         <PackageReference Include="IKVM.OpenJDK.Text" Version="7.2.4630.5"> | ||||
|             <NoWarn>NU1701</NoWarn> | ||||
|         </PackageReference> | ||||
|         <PackageReference Include="IKVM.OpenJDK.Util" Version="7.2.4630.5"> | ||||
|             <NoWarn>NU1701</NoWarn> | ||||
|         </PackageReference> | ||||
|         <PackageReference Include="IKVM.OpenJDK.XML.API" Version="7.2.4630.5"> | ||||
|             <NoWarn>NU1701</NoWarn> | ||||
|         </PackageReference> | ||||
|         <PackageReference Include="IKVM.Runtime" Version="7.2.4630.5"> | ||||
|             <NoWarn>NU1701</NoWarn> | ||||
|         </PackageReference> | ||||
|         <PackageReference Include="Instances" Version="3.0.1" /> | ||||
|         <PackageReference Include="log4net" Version="3.0.3"></PackageReference> | ||||
|         <PackageReference Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="9.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="9.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="9.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Configuration.json" Version="9.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.0" /> | ||||
|         <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" /> | ||||
|         <PackageReference Include="Microsoft.Win32.SystemEvents" Version="9.0.0" /> | ||||
|         <PackageReference Include="MSTest.TestAdapter" Version="3.7.0" /> | ||||
|         <PackageReference Include="MSTest.TestFramework" Version="3.7.0" /> | ||||
|         <PackageReference Include="Pdfbox" Version="1.1.1"> | ||||
|             <NoWarn>NU1701</NoWarn> | ||||
|         </PackageReference> | ||||
|         <PackageReference Include="RoboSharp" Version="1.6.0" /> | ||||
|         <PackageReference Include="System.Configuration.ConfigurationManager" Version="9.0.0" /> | ||||
|         <PackageReference Include="System.Data.OleDb" Version="9.0.0" /> | ||||
|         <PackageReference Include="System.Data.SqlClient" Version="4.8.6" /> | ||||
|         <PackageReference Include="System.Drawing.Common" Version="8.0.10" /> | ||||
|         <PackageReference Include="System.Text.Json" Version="8.0.5" /> | ||||
|         <PackageReference Include="Tesseract" Version="5.2.0" /> | ||||
|         <PackageReference Include="System.Drawing.Common" Version="9.0.0" /> | ||||
|         <PackageReference Include="System.Text.Json" Version="9.0.0" /> | ||||
|     </ItemGroup> | ||||
|     <ItemGroup> | ||||
|         <PackageReference Include="CommonMark.NET" Version="0.15.1" /> | ||||
|     </ItemGroup> | ||||
|     <ItemGroup> | ||||
|         <PackageReference Include="Microsoft.AspNet.WebApi.SelfHost" Version="5.2.9" /> | ||||
| @ -76,16 +94,23 @@ | ||||
|         <PackageReference Include="Microsoft.TeamFoundationServer.Client" Version="16.205.1" /> | ||||
|     </ItemGroup> | ||||
|     <ItemGroup> | ||||
|         <PackageReference Include="Infineon.Mesa.PDF.Text.Stripper" Version="4.8.0.2"> | ||||
|             <NoWarn>NU1701</NoWarn> | ||||
|         </PackageReference> | ||||
|     </ItemGroup> | ||||
|     <ItemGroup> | ||||
|         <PackageReference Include="Infineon.Yoda.DotNetCore" Version="5.4.3" /> | ||||
|         <PackageReference Include="Tibco.Rendezvous.DotNetCore" Version="8.5.0" /> | ||||
|         <PackageReference Include="Infineon.Yoda.DotNetCore" Version="5.4.1" /> | ||||
|     </ItemGroup> | ||||
|     <ItemGroup> | ||||
|         <PackageReference Include="Infineon.Mesa.PDF.Text.Stripper" Version="4.8.0.1"><NoWarn>NU1701</NoWarn></PackageReference> | ||||
|         <PackageReference Include="Tesseract" Version="5.2.0" /> | ||||
|     </ItemGroup> | ||||
|     <ItemGroup> | ||||
|         <PackageReference Include="External.Common.Logging.Core" Version="3.3.1"><NoWarn>NU1701</NoWarn></PackageReference> | ||||
|         <PackageReference Include="External.Common.Logging" Version="3.3.1"><NoWarn>NU1701</NoWarn></PackageReference> | ||||
|         <PackageReference Include="External.log4net" Version="2.0.8"><NoWarn>NU1701</NoWarn></PackageReference> | ||||
|         <PackageReference Include="Nancy.Owin" Version="2.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Owin" Version="4.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Owin.Cors" Version="4.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Owin.Hosting" Version="4.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Owin.Host.HttpListener" Version="4.0.0" /> | ||||
|     </ItemGroup> | ||||
|     <ItemGroup> | ||||
|         <None Include="appsettings.json"> | ||||
|  | ||||
| @ -1,3 +1,9 @@ | ||||
| # D: | ||||
| # cd D:\EAF-Mesa-Integration | ||||
| # config --url https://tfs.intra.infineon.com/tfs/FactoryIntegration --pool "EAF Mesa Integration" --agent mestsa003-meseafsvc --work _work --runAsService --auth negotiate --userName infineon\phares | ||||
| # D: | ||||
| # cd D:\EAF-Mesa-Integration | ||||
| # config --url https://tfs.intra.infineon.com/tfs/FactoryIntegration --pool "EAF Mesa Integration" --agent mestsa07ec-ecmeseaf --work _work --runAsService --auth negotiate --userName infineon\phares | ||||
| trigger: | ||||
|   branches: | ||||
|     include: | ||||
| @ -6,159 +12,273 @@ trigger: | ||||
|     include: | ||||
|       - "Adaptation/*" | ||||
|  | ||||
| pool: | ||||
|   name: eaf | ||||
|   demands: MESAFIBACKLOG | ||||
| stages: | ||||
|   - stage: DevServer | ||||
|     displayName: DevServer | ||||
|  | ||||
| steps: | ||||
|   - script: | | ||||
|       set coreVersion=net7.0 | ||||
|       echo %coreVersion% | ||||
|       echo ##vso[task.setvariable variable=CoreVersion;]%coreVersion% | ||||
|       echo $(CoreVersion) | ||||
|     displayName: CoreVersion | ||||
|     pool: | ||||
|       name: EAF Mesa Integration | ||||
|       demands: MESAFIBACKLOG-Development | ||||
|  | ||||
|   - script: | | ||||
|       set configuration=Release | ||||
|       echo %configuration% | ||||
|       echo ##vso[task.setvariable variable=Configuration;]%configuration% | ||||
|       echo $(Configuration) | ||||
|     displayName: Configuration | ||||
|     variables: | ||||
|       coreVersion: "net8.0" | ||||
|       nugetSource: "https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/" | ||||
|  | ||||
|   - script: | | ||||
|       REM set nugetSource=https://eaf-prod.mes.infineon.com/v3/index.json | ||||
|       set nugetSource=https://eaf-dev-reporting.mes.infineon.com/v3/index.json | ||||
|       echo %nugetSource% | ||||
|       echo ##vso[task.setvariable variable=NugetSource;]%nugetSource% | ||||
|       echo $(NugetSource) | ||||
|     displayName: NugetSource | ||||
|     jobs: | ||||
|       - job: SetupEnvironment | ||||
|         steps: | ||||
|           - script: | | ||||
|               echo $(Build.BuildId) | ||||
|               echo $(Build.Reason) | ||||
|               echo $(Build.Repository.Id) | ||||
|               echo $(Build.Repository.Name) | ||||
|               echo $(Build.SourceVersion) | ||||
|               echo $(CoreVersion) | ||||
|               echo $(NugetSource) | ||||
|             displayName: "Echo Check" | ||||
|  | ||||
|   - script: | | ||||
|       set gitCommit=$(Build.SourceVersion) | ||||
|       set gitCommitSeven=%gitCommit:~0,7% | ||||
|       echo %gitCommitSeven% | ||||
|       echo ##vso[task.setvariable variable=GitCommitSeven;]%gitCommitSeven% | ||||
|       echo $(GitCommitSeven) | ||||
|     displayName: GitCommitSeven | ||||
|           - script: '"C:\program files\dotnet\dotnet.exe" nuget locals all --clear' | ||||
|             displayName: "Nuget Clear" | ||||
|             enabled: false | ||||
|  | ||||
|   - script: | | ||||
|       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) | ||||
|       REM echo $(pipelinePassword) | ||||
|     displayName: "Echo Check" | ||||
|           - script: | | ||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets init | ||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets set "BuildNumber" "$(Build.BuildId)" | ||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets set "GitCommit" "$(Build.SourceVersion)" | ||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets list | ||||
|             workingDirectory: Adaptation | ||||
|             displayName: "Safe storage of app secrets - Adaptation" | ||||
|  | ||||
|   - script: '"C:\program files\dotnet\dotnet.exe" nuget locals all --clear' | ||||
|     displayName: "Nuget Clear" | ||||
|     enabled: false | ||||
|       - job: BuildDebug | ||||
|         dependsOn: | ||||
|           - SetupEnvironment | ||||
|         steps: | ||||
|           - script: | | ||||
|               set configuration=Debug | ||||
|               echo %configuration% | ||||
|               echo ##vso[task.setvariable variable=Configuration;]%configuration% | ||||
|               echo $(Configuration) | ||||
|             displayName: Configuration | ||||
|  | ||||
|   - script: | | ||||
|       "C:\program files\dotnet\dotnet.exe" user-secrets init | ||||
|       "C:\program files\dotnet\dotnet.exe" user-secrets set "BuildNumber" "$(Build.BuildId)" | ||||
|       "C:\program files\dotnet\dotnet.exe" user-secrets set "GitCommitSeven" "$(GitCommitSeven)" | ||||
|       "C:\program files\dotnet\dotnet.exe" user-secrets list | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Safe storage of app secrets - Adaptation" | ||||
|           - script: '"C:\program files\dotnet\dotnet.exe" build --configuration $(Configuration) --source $(NugetSource)' | ||||
|             workingDirectory: Adaptation | ||||
|             displayName: "Core Build - Adaptation" | ||||
|  | ||||
|   - script: '"C:\program files\dotnet\dotnet.exe" build --configuration $(Configuration) --source $(NugetSource)' | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Core Build - Adaptation" | ||||
|       - job: BuildRelease | ||||
|         dependsOn: | ||||
|           - SetupEnvironment | ||||
|         steps: | ||||
|           - script: | | ||||
|               set configuration=Release | ||||
|               echo %configuration% | ||||
|               echo ##vso[task.setvariable variable=Configuration;]%configuration% | ||||
|               echo $(Configuration) | ||||
|             displayName: Configuration | ||||
|  | ||||
|   - powershell: Get-ChildItem .\ -include TestResults -Recurse | foreach ($_) { remove-item $_.fullname -Force -Recurse } | ||||
|     workingDirectory: "$(System.DefaultWorkingDirectory)/../../../$(Build.Repository.Name)" | ||||
|     displayName: "PowerShell Script" | ||||
|     continueOnError: true | ||||
|           - script: '"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" /target:Restore /detailedsummary /consoleloggerparameters:PerformanceSummary;ErrorsOnly; /property:Configuration=$(Configuration);TargetFrameworkVersion=v4.8 /p:RestoreSources=$(NugetSource)' | ||||
|             displayName: "MSBuild Restore" | ||||
|  | ||||
|   - script: "dotnet test --configuration $(Configuration) --runtime win-x86" | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Core Test" | ||||
|           - script: '"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" /target:Build /detailedsummary /consoleloggerparameters:PerformanceSummary;ErrorsOnly; /property:Configuration=$(Configuration);TargetFrameworkVersion=v4.8' | ||||
|             displayName: MSBuild | ||||
|  | ||||
|   - script: 'move /y "$(System.DefaultWorkingDirectory)/../../../$(Build.Repository.Name)/05_TestResults/TestResults" $(System.DefaultWorkingDirectory)' | ||||
|     displayName: "Move Results" | ||||
|           - script: '"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" /target:Build /detailedsummary /consoleloggerparameters:PerformanceSummary;ErrorsOnly; /property:Configuration=$(Configuration);TargetFrameworkVersion=v4.8' | ||||
|             displayName: MSBuild | ||||
|  | ||||
|   - script: '"C:\program files\dotnet\dotnet.exe" tool restore' | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Tool Restore" | ||||
|     enabled: false | ||||
|           - script: 'echo $(Build.Repository.Name)-$(Build.BuildId)-$(Build.SourceVersion)>bin\$(Configuration)\$(Build.Repository.Name).txt' | ||||
|             displayName: "Commit Id" | ||||
|  | ||||
|   - script: '"C:\program files\dotnet\dotnet.exe" ReportGenerator -reports:$(System.DefaultWorkingDirectory)/TestResults/**/coverage.cobertura.xml -targetDir:$(Build.ArtifactStagingDirectory)\Coverage -reportTypes:Html_Dark' | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Report Generator" | ||||
|     enabled: false | ||||
|           - task: CopyFiles@2 | ||||
|             displayName: 'Copy Files to: D:\EAF' | ||||
|             inputs: | ||||
|               Contents: "*$(Build.Repository.Name)*" | ||||
|               SourceFolder: 'bin\$(Configuration)' | ||||
|               TargetFolder: 'D:\EAF\EAF Deployment Storage\Adaptation_$(Build.Repository.Name)' | ||||
|               OverWrite: true | ||||
|             enabled: true | ||||
|  | ||||
|   - task: PublishTestResults@2 | ||||
|     displayName: "Publish Test Results **/*.trx" | ||||
|     inputs: | ||||
|       testResultsFormat: VSTest | ||||
|       testResultsFiles: "**/*.trx" | ||||
|       testRunTitle: "$(GitCommitSeven)-$(Build.BuildId)-$(CoreVersion)-$(Configuration)-$(Build.Repository.Name)" | ||||
|       searchFolder: "$(System.DefaultWorkingDirectory)/TestResults" | ||||
|       - job: TestDebug | ||||
|         dependsOn: | ||||
|           - SetupEnvironment | ||||
|           - BuildDebug | ||||
|           - BuildRelease | ||||
|         steps: | ||||
|           - script: | | ||||
|               set configuration=Debug | ||||
|               echo %configuration% | ||||
|               echo ##vso[task.setvariable variable=Configuration;]%configuration% | ||||
|               echo $(Configuration) | ||||
|             displayName: Configuration | ||||
|  | ||||
|   - task: PublishTestResults@2 | ||||
|     displayName: "Publish Test Results */coverage.cobertura.xml" | ||||
|     inputs: | ||||
|       testResultsFormat: VSTest | ||||
|       testResultsFiles: "*/coverage.cobertura.xml" | ||||
|       testRunTitle: "$(GitCommitSeven)-$(Build.BuildId)-$(CoreVersion)-$(Configuration)-$(Build.Repository.Name)" | ||||
|       searchFolder: "$(System.DefaultWorkingDirectory)/TestResults" | ||||
|           - powershell: Get-ChildItem .\ -include TestResults -Recurse | foreach ($_) { remove-item $_.fullname -Force -Recurse } | ||||
|             workingDirectory: "$(System.DefaultWorkingDirectory)/../../../$(Build.Repository.Name)" | ||||
|             displayName: "PowerShell Script" | ||||
|             continueOnError: true | ||||
|  | ||||
|   - task: mspremier.CreateWorkItem.CreateWorkItem-task.CreateWorkItem@1 | ||||
|     displayName: "Create work item" | ||||
|     inputs: | ||||
|       teamProject: "Mesa_FI" | ||||
|       workItemType: Bug | ||||
|       title: $(GitCommitSeven)-$(Build.BuildId)-$(Build.Repository.Name)-$(Configuration) | ||||
|       assignedTo: "$(Build.RequestedForId)" | ||||
|     enabled: false | ||||
|           - script: "dotnet test --configuration $(Configuration)" | ||||
|             workingDirectory: Adaptation | ||||
|             displayName: "Core Test" | ||||
|  | ||||
|   - script: '"C:\program files\dotnet\dotnet.exe" publish --configuration $(Configuration) --runtime win-x64 --self-contained -o $(Build.ArtifactStagingDirectory)\Adaptation --source $(NugetSource)' | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Core Publish" | ||||
|     enabled: false | ||||
|           - script: 'move /y "$(System.DefaultWorkingDirectory)/../../../$(Build.Repository.Name)/05_TestResults/TestResults" $(System.DefaultWorkingDirectory)' | ||||
|             displayName: "Move Results" | ||||
|  | ||||
|   - script: '"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" /target:Restore /detailedsummary /consoleloggerparameters:PerformanceSummary;ErrorsOnly; /property:Configuration=$(Configuration);TargetFrameworkVersion=v4.8 /p:RestoreSources=$(NugetSource)' | ||||
|     displayName: "MSBuild Restore" | ||||
|           - script: '"C:\program files\dotnet\dotnet.exe" tool restore' | ||||
|             workingDirectory: Adaptation | ||||
|             displayName: "Tool Restore" | ||||
|             enabled: false | ||||
|  | ||||
|   - script: '"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" /target:Build /detailedsummary /consoleloggerparameters:PerformanceSummary;ErrorsOnly; /property:Configuration=$(Configuration);TargetFrameworkVersion=v4.8' | ||||
|     displayName: MSBuild | ||||
|           - script: '"C:\program files\dotnet\dotnet.exe" ReportGenerator -reports:$(System.DefaultWorkingDirectory)/TestResults/**/coverage.cobertura.xml -targetDir:$(Build.ArtifactStagingDirectory)\Coverage -reportTypes:Html_Dark' | ||||
|             workingDirectory: Adaptation | ||||
|             displayName: "Report Generator" | ||||
|             enabled: false | ||||
|  | ||||
|   - script: 'echo $(Build.SourceVersion)-$(Build.BuildId)-$(Build.Repository.Name)>bin\$(Configuration)\$(Build.Repository.Name).txt' | ||||
|     displayName: "Commit Id" | ||||
|           - task: PublishTestResults@2 | ||||
|             displayName: "Publish Test Results **/*.trx" | ||||
|             inputs: | ||||
|               testResultsFormat: VSTest | ||||
|               testResultsFiles: "**/*.trx" | ||||
|               testRunTitle: "$(Build.BuildId)-$(Build.SourceVersion)-$(CoreVersion)-$(Configuration)-$(Build.Repository.Name)" | ||||
|               searchFolder: "$(System.DefaultWorkingDirectory)/TestResults" | ||||
|  | ||||
|   - task: CopyFiles@2 | ||||
|     displayName: 'Copy Files to: D:\Framework4.8' | ||||
|     inputs: | ||||
|       Contents: "*$(Build.Repository.Name)*" | ||||
|       SourceFolder: 'bin\$(Configuration)' | ||||
|       TargetFolder: 'D:\Framework4.8\$(GitCommitSeven)-$(Build.BuildId)-$(Build.Repository.Name)-$(Configuration)' | ||||
|       OverWrite: true | ||||
|           - task: PublishTestResults@2 | ||||
|             displayName: "Publish Test Results */coverage.cobertura.xml" | ||||
|             inputs: | ||||
|               testResultsFormat: VSTest | ||||
|               testResultsFiles: "*/coverage.cobertura.xml" | ||||
|               testRunTitle: "$(Build.BuildId)-$(Build.SourceVersion)-$(CoreVersion)-$(Configuration)-$(Build.Repository.Name)" | ||||
|               searchFolder: "$(System.DefaultWorkingDirectory)/TestResults" | ||||
|  | ||||
|   - task: CopyFiles@2 | ||||
|     displayName: 'Copy Files to: \\mesfs.infineon.com\EC_EAFRepository' | ||||
|     inputs: | ||||
|       Contents: "*$(Build.Repository.Name)*" | ||||
|       SourceFolder: 'bin\$(Configuration)' | ||||
|       TargetFolder: 'D:\EAF\EAF Deployment Storage\Adaptation_$(Build.Repository.Name)' | ||||
|       OverWrite: true | ||||
|           - script: | | ||||
|               "C:\program files\dotnet\dotnet.exe" clean --configuration $(Configuration) | ||||
|             workingDirectory: Adaptation | ||||
|             displayName: "Core Clean - Adaptation" | ||||
|  | ||||
|   - script: | | ||||
|       "C:\program files\dotnet\dotnet.exe" clean --configuration $(Configuration) | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Core Clean - Tests" | ||||
|     continueOnError: true | ||||
|           - script: 'echo $(Build.BuildId)-$(Build.SourceVersion)-bin_x_x_\$(Configuration)\$(CoreVersion)\win-x64\$(Build.Repository.Name).txt' | ||||
|             displayName: "Force Fail" | ||||
|             enabled: false | ||||
|  | ||||
|   - script: | | ||||
|       "C:\program files\dotnet\dotnet.exe" clean --configuration $(Configuration) | ||||
|     workingDirectory: Adaptation | ||||
|     displayName: "Core Clean - Adaptation" | ||||
|     continueOnError: true | ||||
|   - stage: ProductionServer | ||||
|     displayName: ProductionServer | ||||
|  | ||||
|   - script: 'echo $(Build.SourceVersion)-$(Build.BuildId)>bin_x_x_\$(Configuration)\$(CoreVersion)\win-x64\$(Build.Repository.Name).txt' | ||||
|     displayName: "Force Fail" | ||||
|     enabled: false | ||||
|     pool: | ||||
|       name: EAF Mesa Integration | ||||
|       demands: MESAFIBACKLOG | ||||
|  | ||||
|     variables: | ||||
|       coreVersion: "net8.0" | ||||
|       nugetSource: "https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/" | ||||
|  | ||||
|     jobs: | ||||
|       - job: SetupEnvironment | ||||
|         steps: | ||||
|           - script: | | ||||
|               echo $(Build.BuildId) | ||||
|               echo $(Build.Reason) | ||||
|               echo $(Build.Repository.Id) | ||||
|               echo $(Build.Repository.Name) | ||||
|               echo $(Build.SourceVersion) | ||||
|               echo $(CoreVersion) | ||||
|               echo $(NugetSource) | ||||
|             displayName: "Echo Check" | ||||
|  | ||||
|           - script: '"C:\program files\dotnet\dotnet.exe" nuget locals all --clear' | ||||
|             displayName: "Nuget Clear" | ||||
|             enabled: false | ||||
|  | ||||
|           - script: | | ||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets init | ||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets set "BuildNumber" "$(Build.BuildId)" | ||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets set "GitCommit" "$(Build.SourceVersion)" | ||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets list | ||||
|             workingDirectory: Adaptation | ||||
|             displayName: "Safe storage of app secrets - Adaptation" | ||||
|  | ||||
|       - job: BuildRelease | ||||
|         dependsOn: | ||||
|           - SetupEnvironment | ||||
|         steps: | ||||
|           - script: | | ||||
|               set configuration=Release | ||||
|               echo %configuration% | ||||
|               echo ##vso[task.setvariable variable=Configuration;]%configuration% | ||||
|               echo $(Configuration) | ||||
|             displayName: Configuration | ||||
|  | ||||
|           - script: '"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" /target:Restore /detailedsummary /consoleloggerparameters:PerformanceSummary;ErrorsOnly; /property:Configuration=$(Configuration);TargetFrameworkVersion=v4.8 /p:RestoreSources=$(NugetSource)' | ||||
|             displayName: "MSBuild Restore" | ||||
|  | ||||
|           - script: '"C:/Program Files (x86)/Microsoft Visual Studio/2022/BuildTools/MSBuild/Current/Bin/MSBuild.exe" /target:Build /detailedsummary /consoleloggerparameters:PerformanceSummary;ErrorsOnly; /property:Configuration=$(Configuration);TargetFrameworkVersion=v4.8' | ||||
|             displayName: MSBuild | ||||
|  | ||||
|           - script: 'echo $(Build.Repository.Name)-$(Build.BuildId)-$(Build.SourceVersion)>bin\$(Configuration)\$(Build.Repository.Name).txt' | ||||
|             displayName: "Commit Id" | ||||
|  | ||||
|           - task: CopyFiles@2 | ||||
|             displayName: 'Copy Files to: D:\EAF' | ||||
|             inputs: | ||||
|               Contents: "*$(Build.Repository.Name)*" | ||||
|               SourceFolder: 'bin\$(Configuration)' | ||||
|               TargetFolder: 'D:\EAF\EAF Deployment Storage\Adaptation_$(Build.Repository.Name)' | ||||
|               OverWrite: true | ||||
|  | ||||
|           - script: '"C:\program files\dotnet\dotnet.exe" build --configuration $(Configuration) --source $(NugetSource)' | ||||
|             workingDirectory: Adaptation | ||||
|             displayName: "Core Build - Adaptation" | ||||
|  | ||||
|       - job: TestRelease | ||||
|         dependsOn: | ||||
|           - SetupEnvironment | ||||
|           - BuildRelease | ||||
|         steps: | ||||
|           - script: | | ||||
|               set configuration=Release | ||||
|               echo %configuration% | ||||
|               echo ##vso[task.setvariable variable=Configuration;]%configuration% | ||||
|               echo $(Configuration) | ||||
|             displayName: Configuration | ||||
|  | ||||
|           - powershell: Get-ChildItem .\ -include TestResults -Recurse | foreach ($_) { remove-item $_.fullname -Force -Recurse } | ||||
|             workingDirectory: "$(System.DefaultWorkingDirectory)/../../../$(Build.Repository.Name)" | ||||
|             displayName: "PowerShell Script" | ||||
|             continueOnError: true | ||||
|  | ||||
|           - script: "dotnet test --configuration $(Configuration)" | ||||
|             workingDirectory: Adaptation | ||||
|             displayName: "Core Test" | ||||
|  | ||||
|           - script: 'move /y "$(System.DefaultWorkingDirectory)/../../../$(Build.Repository.Name)/05_TestResults/TestResults" $(System.DefaultWorkingDirectory)' | ||||
|             displayName: "Move Results" | ||||
|  | ||||
|           - script: '"C:\program files\dotnet\dotnet.exe" tool restore' | ||||
|             workingDirectory: Adaptation | ||||
|             displayName: "Tool Restore" | ||||
|             enabled: false | ||||
|  | ||||
|           - script: '"C:\program files\dotnet\dotnet.exe" ReportGenerator -reports:$(System.DefaultWorkingDirectory)/TestResults/**/coverage.cobertura.xml -targetDir:$(Build.ArtifactStagingDirectory)\Coverage -reportTypes:Html_Dark' | ||||
|             workingDirectory: Adaptation | ||||
|             displayName: "Report Generator" | ||||
|             enabled: false | ||||
|  | ||||
|           - task: PublishTestResults@2 | ||||
|             displayName: "Publish Test Results **/*.trx" | ||||
|             inputs: | ||||
|               testResultsFormat: VSTest | ||||
|               testResultsFiles: "**/*.trx" | ||||
|               testRunTitle: "$(Build.BuildId)-$(Build.SourceVersion)-$(CoreVersion)-$(Configuration)-$(Build.Repository.Name)" | ||||
|               searchFolder: "$(System.DefaultWorkingDirectory)/TestResults" | ||||
|  | ||||
|           - task: PublishTestResults@2 | ||||
|             displayName: "Publish Test Results */coverage.cobertura.xml" | ||||
|             inputs: | ||||
|               testResultsFormat: VSTest | ||||
|               testResultsFiles: "*/coverage.cobertura.xml" | ||||
|               testRunTitle: "$(Build.BuildId)-$(Build.SourceVersion)-$(CoreVersion)-$(Configuration)-$(Build.Repository.Name)" | ||||
|               searchFolder: "$(System.DefaultWorkingDirectory)/TestResults" | ||||
|  | ||||
|           - script: | | ||||
|               "C:\program files\dotnet\dotnet.exe" clean --configuration $(Configuration) | ||||
|             workingDirectory: Adaptation | ||||
|             displayName: "Core Clean - Adaptation" | ||||
|  | ||||
|           - script: 'echo $(Build.BuildId)-$(Build.SourceVersion)-bin_x_x_\$(Configuration)\$(CoreVersion)\win-x64\$(Build.Repository.Name).txt' | ||||
|             displayName: "Force Fail" | ||||
|             enabled: true | ||||
|  | ||||
| @ -3,6 +3,7 @@ using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
| using System.Text.Json.Serialization; | ||||
|  | ||||
| namespace Adaptation.Shared.Duplicator; | ||||
|  | ||||
| @ -142,4 +143,16 @@ public class Description : IDescription, Properties.IDescription | ||||
|  | ||||
|     internal static string GetDateFormat() => "MM/dd/yyyy hh:mm:ss tt"; | ||||
|  | ||||
| } | ||||
|  | ||||
| [JsonSourceGenerationOptions(WriteIndented = true, NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] | ||||
| [JsonSerializable(typeof(Description))] | ||||
| internal partial class SharedDescriptionSourceGenerationContext : JsonSerializerContext | ||||
| { | ||||
| } | ||||
|  | ||||
| [JsonSourceGenerationOptions(WriteIndented = true, NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString)] | ||||
| [JsonSerializable(typeof(Description[]))] | ||||
| internal partial class SharedDescriptionArraySourceGenerationContext : JsonSerializerContext | ||||
| { | ||||
| } | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -35,6 +35,9 @@ public class Logistics : ILogistics | ||||
|     public long Sequence => _Sequence; | ||||
|     public double TotalSecondsSinceLastWriteTimeFromSequence => _TotalSecondsSinceLastWriteTimeFromSequence; | ||||
|  | ||||
|     private static string DefaultMesEntity(DateTime dateTime) => | ||||
|         string.Concat(dateTime.Ticks, "_MES_ENTITY"); | ||||
|  | ||||
|     public Logistics(IFileRead fileRead) | ||||
|     { | ||||
|         DateTime dateTime = DateTime.Now; | ||||
| @ -84,13 +87,13 @@ public class Logistics : ILogistics | ||||
|         _Logistics2 = new List<Logistics2>(); | ||||
|     } | ||||
|  | ||||
|     public Logistics(string reportFullPath, string logistics) | ||||
|     internal Logistics(string reportFullPath, ProcessDataStandardFormat processDataStandardFormat) | ||||
|     { | ||||
|         string key; | ||||
|         DateTime dateTime; | ||||
|         string[] segments; | ||||
|         _FileInfo = new(reportFullPath); | ||||
|         _Logistics1 = logistics.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).ToList(); | ||||
|         _Logistics1 = processDataStandardFormat.Logistics.ToList(); | ||||
|         if (Logistics1.Count == 0 || !Logistics1[0].StartsWith("LOGISTICS_1")) | ||||
|         { | ||||
|             _NullData = null; | ||||
| @ -190,8 +193,6 @@ public class Logistics : ILogistics | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static string DefaultMesEntity(DateTime dateTime) => string.Concat(dateTime.Ticks, "_MES_ENTITY"); | ||||
|  | ||||
|     internal void Update(string mid, string processJobID) | ||||
|     { | ||||
|         _MID = mid; | ||||
|  | ||||
| @ -6,23 +6,25 @@ public partial class WS | ||||
|     public class Attachment | ||||
|     { | ||||
|  | ||||
|         public string SubGroupId { get; set; } | ||||
|         public long HeaderId { get; set; } | ||||
|         public string HeaderIdDirectory { get; set; } | ||||
|         public string UniqueId { get; set; } | ||||
|         public string DestinationFileName { get; set; } | ||||
|         public string SourceFileName { get; set; } | ||||
|         public string AttachmentId { get; set; } | ||||
| #nullable enable | ||||
|  | ||||
|         public Attachment(string subGroupId, long headerId, string headerIdDirectory, string uniqueId, string destinationFileName, string sourceFileName) | ||||
|         public long HeaderId { get; set; } | ||||
|         public string UniqueId { get; set; } | ||||
|         public string SubGroupId { get; set; } | ||||
|         public string AttachmentId { get; set; } | ||||
|         public string SourceFileName { get; set; } | ||||
|         public string HeaderIdDirectory { get; set; } | ||||
|         public string DestinationFileName { get; set; } | ||||
|  | ||||
|         public Attachment(Results? results, string headerIdDirectory, string uniqueId, string destinationFileName, string sourceFileName) | ||||
|         { | ||||
|             SubGroupId = subGroupId; | ||||
|             HeaderId = headerId; | ||||
|             HeaderIdDirectory = headerIdDirectory; | ||||
|             UniqueId = uniqueId; | ||||
|             DestinationFileName = destinationFileName; | ||||
|             SourceFileName = sourceFileName; | ||||
|             HeaderIdDirectory = headerIdDirectory; | ||||
|             DestinationFileName = destinationFileName; | ||||
|             AttachmentId = System.Guid.NewGuid().ToString(); | ||||
|             HeaderId = results?.HeaderId is null ? -1 : results.HeaderId.Value; | ||||
|             SubGroupId = results?.SubgroupId is null ? string.Empty : results.SubgroupId.Value.ToString(); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
| @ -1,27 +1,75 @@ | ||||
| using System.Collections.Generic; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using System.Text.Json; | ||||
| using System.Text.Json.Serialization; | ||||
|  | ||||
| namespace Adaptation.Shared.Metrology; | ||||
|  | ||||
| public partial class WS | ||||
| { | ||||
|     // this class represents the response from the Inbound API endpoint | ||||
|  | ||||
|     public class Results | ||||
|     { | ||||
|         // true or false if data was written to the database | ||||
|         public bool Success { get; set; } | ||||
|  | ||||
|         // if true, contains ID of the Header record in the database | ||||
|         public long HeaderID { get; set; } | ||||
| #nullable enable | ||||
|  | ||||
|         // if false, this collection will contain a list of errors | ||||
|         public List<string> Errors { get; set; } | ||||
|         [JsonConstructor] | ||||
|         public Results(List<string>? errors, | ||||
|                        long? headerId, | ||||
|                        long? subgroupId, | ||||
|                        bool? success, | ||||
|                        List<string>? warnings) | ||||
|         { | ||||
|             Errors = errors; | ||||
|             Success = success; | ||||
|             HeaderId = headerId; | ||||
|             Warnings = warnings; | ||||
|             SubgroupId = subgroupId; | ||||
|         } | ||||
|  | ||||
|         // this collection will contain a list of warnings, they will not prevent data from being saved | ||||
|         public List<string> Warnings { get; set; } | ||||
|         [JsonPropertyName("errors")] public List<string>? Errors { get; set; } | ||||
|         [JsonPropertyName("headerID")] public long? HeaderId { get; set; } | ||||
|         [JsonPropertyName("subgroupId")] public long? SubgroupId { get; set; } | ||||
|         [JsonPropertyName("success")] public bool? Success { get; set; } | ||||
|         [JsonPropertyName("warnings")] public List<string>? Warnings { get; set; } | ||||
|  | ||||
|         public override string ToString() | ||||
|         { | ||||
|             string result = JsonSerializer.Serialize(this, ResultsSourceGenerationContext.Default.Results); | ||||
|             return result; | ||||
|         } | ||||
|  | ||||
|         internal static Results Get(Results results, long? subgroupId) => | ||||
|             new(results.Errors, results.HeaderId, subgroupId, results.Success, results.Warnings); | ||||
|  | ||||
|         internal static Results Get(string resultsJson, Exception e) | ||||
|         { | ||||
|             Results results; | ||||
|             Exception? exception = e; | ||||
|             List<string> errors = new(); | ||||
|             StringBuilder stringBuilder = new(); | ||||
|             while (exception is not null) | ||||
|             { | ||||
|                 _ = stringBuilder.AppendLine(exception.Message); | ||||
|                 exception = exception.InnerException; | ||||
|             } | ||||
|             errors.Add(resultsJson); | ||||
|             errors.Add(stringBuilder.ToString()); | ||||
|             results = new(errors: errors, | ||||
|                           headerId: null, | ||||
|                           subgroupId: null, | ||||
|                           success: false, | ||||
|                           warnings: new()); | ||||
|             return results; | ||||
|         } | ||||
|  | ||||
|         // this is just a helper function to make displaying the results easier | ||||
|         public override string ToString() => JsonSerializer.Serialize(this, GetType()); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| [JsonSourceGenerationOptions(WriteIndented = true)] | ||||
| [JsonSerializable(typeof(WS.Results))] | ||||
| internal partial class ResultsSourceGenerationContext : JsonSerializerContext | ||||
| { | ||||
| } | ||||
| @ -10,9 +10,11 @@ namespace Adaptation.Shared.Metrology; | ||||
| public partial class WS | ||||
| { | ||||
|  | ||||
| #nullable enable | ||||
|  | ||||
|     public static (string, Results) SendData(string url, long sequence, string directory, object payload, int timeoutSeconds = 120) | ||||
|     { | ||||
|         Results results = new(); | ||||
|         Results? wsResults = null; | ||||
|         string resultsJson = string.Empty; | ||||
|         try | ||||
|         { | ||||
| @ -30,29 +32,20 @@ public partial class WS | ||||
|                 }; | ||||
|                 HttpResponseMessage httpResponseMessage = httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead).Result; | ||||
|                 resultsJson = httpResponseMessage.Content.ReadAsStringAsync().Result; | ||||
|                 results = JsonSerializer.Deserialize<Results>(resultsJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); | ||||
|                 string checkDirectory = Path.Combine(directory, $"-{results.HeaderID}"); | ||||
|                 wsResults = JsonSerializer.Deserialize(resultsJson, ResultsSourceGenerationContext.Default.Results); | ||||
|                 if (wsResults is null) | ||||
|                     throw new NullReferenceException(nameof(wsResults)); | ||||
|                 string checkDirectory = Path.Combine(directory, $"-{wsResults.HeaderId}"); | ||||
|                 if (!Directory.Exists(checkDirectory)) | ||||
|                     _ = Directory.CreateDirectory(checkDirectory); | ||||
|                 File.WriteAllText(Path.Combine(checkDirectory, $"{sequence}.json"), json); | ||||
|             } | ||||
|             if (!results.Success) | ||||
|                 results.Errors.Add(results.ToString()); | ||||
|             if (wsResults.Success is null || !wsResults.Success.Value) | ||||
|                 wsResults.Errors?.Add(wsResults.ToString()); | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|             Exception exception = e; | ||||
|             StringBuilder stringBuilder = new(); | ||||
|             while (exception is not null) | ||||
|             { | ||||
|                 _ = stringBuilder.AppendLine(exception.Message); | ||||
|                 exception = exception.InnerException; | ||||
|             } | ||||
|             results.Errors ??= new List<string>(); | ||||
|             results.Errors.Add(resultsJson); | ||||
|             results.Errors.Add(stringBuilder.ToString()); | ||||
|         } | ||||
|         return new(resultsJson, results); | ||||
|         { wsResults ??= Results.Get(resultsJson, e); } | ||||
|         return new(resultsJson, wsResults); | ||||
|     } | ||||
|  | ||||
|     public static void AttachFile(string url, Attachment attachment, int timeoutSeconds = 60) | ||||
| @ -69,16 +62,20 @@ public partial class WS | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static void AttachFiles(string url, List<Attachment> headerAttachments = null, List<Attachment> dataAttachments = null) | ||||
|     public static void AttachFiles(string url, List<Attachment>? headerAttachments = null, List<Attachment>? dataAttachments = null) | ||||
|     { | ||||
|         string directory; | ||||
|         try | ||||
|         { | ||||
|             string? directoryName; | ||||
|             if (headerAttachments is not null) | ||||
|             { | ||||
|                 foreach (Attachment attachment in headerAttachments) | ||||
|                 { | ||||
|                     directory = Path.Combine(Path.GetDirectoryName(attachment.HeaderIdDirectory), attachment.AttachmentId) ?? throw new Exception(); | ||||
|                     directoryName = Path.GetDirectoryName(attachment.HeaderIdDirectory); | ||||
|                     if (string.IsNullOrEmpty(directoryName)) | ||||
|                         continue; | ||||
|                     directory = Path.Combine(directoryName, attachment.AttachmentId) ?? throw new Exception(); | ||||
|                     if (!Directory.Exists(directory)) | ||||
|                         _ = Directory.CreateDirectory(directory); | ||||
|                     File.Copy(attachment.SourceFileName, Path.Combine(directory, attachment.DestinationFileName), overwrite: true); | ||||
| @ -88,7 +85,10 @@ public partial class WS | ||||
|             { | ||||
|                 foreach (Attachment attachment in dataAttachments) | ||||
|                 { | ||||
|                     directory = Path.Combine(Path.GetDirectoryName(attachment.HeaderIdDirectory.Replace("Header", "Data")), attachment.AttachmentId) ?? throw new Exception(); | ||||
|                     directoryName = Path.GetDirectoryName(attachment.HeaderIdDirectory.Replace("Header", "Data")); | ||||
|                     if (string.IsNullOrEmpty(directoryName)) | ||||
|                         continue; | ||||
|                     directory = Path.Combine(directoryName, attachment.AttachmentId) ?? throw new Exception(); | ||||
|                     if (!Directory.Exists(directory)) | ||||
|                         _ = Directory.CreateDirectory(directory); | ||||
|                     File.Copy(attachment.SourceFileName, Path.Combine(directory, attachment.DestinationFileName), overwrite: true); | ||||
| @ -108,7 +108,7 @@ public partial class WS | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|             Exception exception = e; | ||||
|             Exception? exception = e; | ||||
|             StringBuilder stringBuilder = new(); | ||||
|             while (exception is not null) | ||||
|             { | ||||
|  | ||||
							
								
								
									
										1
									
								
								Adaptation/Shared/ProcessData.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								Adaptation/Shared/ProcessData.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										34
									
								
								Adaptation/Shared/ProcessDataStandardFormatMapping.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								Adaptation/Shared/ProcessDataStandardFormatMapping.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| using System.Collections.ObjectModel; | ||||
| using System.Linq; | ||||
|  | ||||
| namespace Adaptation.Shared; | ||||
|  | ||||
| public class ProcessDataStandardFormatMapping | ||||
| { | ||||
|  | ||||
|     public ReadOnlyCollection<int> ColumnIndices { get; private set; } | ||||
|     public ReadOnlyCollection<string> NewColumnNames { get; private set; } | ||||
|     public ReadOnlyCollection<string> OldColumnNames { get; private set; } | ||||
|  | ||||
|     public ProcessDataStandardFormatMapping(ReadOnlyCollection<int> columnIndices, | ||||
|                                             ReadOnlyCollection<string> newColumnNames, | ||||
|                                             ReadOnlyCollection<string> oldColumnNames) | ||||
|     { | ||||
|         ColumnIndices = columnIndices; | ||||
|         NewColumnNames = newColumnNames; | ||||
|         OldColumnNames = oldColumnNames; | ||||
|     } | ||||
|  | ||||
|     internal static ProcessDataStandardFormatMapping Get(string processDataStandardFormatMappingOldColumnNames, string processDataStandardFormatMappingNewColumnNames, string processDataStandardFormatMappingColumnIndices) | ||||
|     { | ||||
|         ProcessDataStandardFormatMapping result; | ||||
|         ReadOnlyCollection<string> newColumnNames = new(processDataStandardFormatMappingNewColumnNames.Split(',')); | ||||
|         ReadOnlyCollection<string> oldColumnNames = new(processDataStandardFormatMappingOldColumnNames.Split(',')); | ||||
|         ReadOnlyCollection<int> columnIndices = new(processDataStandardFormatMappingColumnIndices.Split(',').Select(int.Parse).ToArray()); | ||||
|         result = new(columnIndices: columnIndices, | ||||
|                      newColumnNames: newColumnNames, | ||||
|                      oldColumnNames: oldColumnNames); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user