Compare commits
	
		
			10 Commits
		
	
	
		
			2fc83bb54d
			...
			42c264e68f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 42c264e68f | |||
| c5d86f3c43 | |||
| 58ce014b10 | |||
| 6e31dceb4c | |||
| 7df7d5f4d6 | |||
| 736a39245f | |||
| e6a223492c | |||
| 9c5e6fddf2 | |||
| 3e8f5931e2 | |||
| 906868540b | 
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -338,6 +338,10 @@ ASALocalRun/ | |||||||
| !**/.vscode/settings.json | !**/.vscode/settings.json | ||||||
| !**/.vscode/tasks.json | !**/.vscode/tasks.json | ||||||
| !**/.vscode/mklink.md | !**/.vscode/mklink.md | ||||||
|  | !**/.vscode/*.http | ||||||
|  | **/.vscode/2025-*.http | ||||||
|  | **/.vscode/2026-*.http | ||||||
|  |  | ||||||
|  |  | ||||||
| *.lnk | *.lnk | ||||||
|  |  | ||||||
|  | |||||||
							
								
								
									
										30
									
								
								Adaptation/.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								Adaptation/.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							| @ -4,7 +4,33 @@ | |||||||
|       "name": ".NET Core Attach", |       "name": ".NET Core Attach", | ||||||
|       "type": "coreclr", |       "type": "coreclr", | ||||||
|       "request": "attach", |       "request": "attach", | ||||||
|       "processId": 23840 |       "processId": 22868 | ||||||
|     } |     }, | ||||||
|  |     { | ||||||
|  |       "type": "node", | ||||||
|  |       "request": "launch", | ||||||
|  |       "name": "node Launch Current Opened File", | ||||||
|  |       "program": "${file}" | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "type": "bun", | ||||||
|  |       "internalConsoleOptions": "neverOpen", | ||||||
|  |       "request": "launch", | ||||||
|  |       "name": "Debug File", | ||||||
|  |       "program": "${file}", | ||||||
|  |       "cwd": "${workspaceFolder}", | ||||||
|  |       "stopOnEntry": false, | ||||||
|  |       "watchMode": false | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "type": "bun", | ||||||
|  |       "internalConsoleOptions": "neverOpen", | ||||||
|  |       "request": "launch", | ||||||
|  |       "name": "Run File", | ||||||
|  |       "program": "${file}", | ||||||
|  |       "cwd": "${workspaceFolder}", | ||||||
|  |       "noDebug": true, | ||||||
|  |       "watchMode": false | ||||||
|  |     }, | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
							
								
								
									
										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" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | ### | ||||||
							
								
								
									
										7
									
								
								Adaptation/.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								Adaptation/.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @ -8,10 +8,12 @@ | |||||||
|         "EQPT", |         "EQPT", | ||||||
|         "headerid", |         "headerid", | ||||||
|         "Idrv", |         "Idrv", | ||||||
|  |         "Infineon", | ||||||
|         "ipdsf", |         "ipdsf", | ||||||
|         "Irng", |         "Irng", | ||||||
|         "ISMTP", |         "ISMTP", | ||||||
|         "JOBID", |         "JOBID", | ||||||
|  |         "kanbn", | ||||||
|         "messa", |         "messa", | ||||||
|         "messv", |         "messv", | ||||||
|         "pdsf", |         "pdsf", | ||||||
| @ -20,9 +22,12 @@ | |||||||
|         "Rcpe", |         "Rcpe", | ||||||
|         "RESIMAPCDE", |         "RESIMAPCDE", | ||||||
|         "Rsens", |         "Rsens", | ||||||
|  |         "signalr", | ||||||
|         "Smpl", |         "Smpl", | ||||||
|         "Villach", |         "Villach", | ||||||
|         "Vrng" |         "Vrng", | ||||||
|  |         "Weightest", | ||||||
|  |         "WSJF" | ||||||
|     ], |     ], | ||||||
|     "coverage-gutters.coverageBaseDir": "../../../../MESAFIBACKLOG/05_TestResults/TestResults/**", |     "coverage-gutters.coverageBaseDir": "../../../../MESAFIBACKLOG/05_TestResults/TestResults/**", | ||||||
|     "workbench.colorCustomizations": { |     "workbench.colorCustomizations": { | ||||||
|  | |||||||
							
								
								
									
										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 long? _TickOffset; | ||||||
|     private readonly string _URL; |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
|  | |||||||
| @ -7,7 +7,6 @@ using System; | |||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| using System.Collections.ObjectModel; | using System.Collections.ObjectModel; | ||||||
| using System.IO; | using System.IO; | ||||||
| using System.Linq; |  | ||||||
| using System.Text.Json; | using System.Text.Json; | ||||||
| using System.Text.Json.Serialization; | using System.Text.Json.Serialization; | ||||||
|  |  | ||||||
| @ -69,7 +68,6 @@ public class ProcessData : IProcessData | |||||||
|             throw new Exception(nameof(workItems)); |             throw new Exception(nameof(workItems)); | ||||||
|         _Details.Add(workItems); |         _Details.Add(workItems); | ||||||
|         ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations); |         ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations); | ||||||
|         WriteFileStructure(destinationDirectory, keyValuePairs); |  | ||||||
|         WriteFiles(fileRead, destinationDirectory, fileInfoCollection, keyValuePairs); |         WriteFiles(fileRead, destinationDirectory, fileInfoCollection, keyValuePairs); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -83,18 +81,6 @@ public class ProcessData : IProcessData | |||||||
|         return results; |         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) |     private static void WriteFiles(IFileRead fileRead, string destinationDirectory, List<FileInfo> fileInfoCollection, ReadOnlyDictionary<int, Record> keyValuePairs) | ||||||
|     { |     { | ||||||
|         string old; |         string old; | ||||||
| @ -112,10 +98,10 @@ public class ProcessData : IProcessData | |||||||
|             workItem = keyValuePair.Value.WorkItem; |             workItem = keyValuePair.Value.WorkItem; | ||||||
|             workItemType = workItem.WorkItemType.Replace(" ", "-"); |             workItemType = workItem.WorkItemType.Replace(" ", "-"); | ||||||
|             json = JsonSerializer.Serialize(workItem, WorkItemSourceGenerationContext.Default.WorkItem); |             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)) |             if (!Directory.Exists(singletonDirectory)) | ||||||
|                 _ = Directory.CreateDirectory(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; |             old = File.Exists(checkFile) ? File.ReadAllText(checkFile) : string.Empty; | ||||||
|             if (old == json) |             if (old == json) | ||||||
|                 continue; |                 continue; | ||||||
| @ -151,40 +137,14 @@ public class ProcessData : IProcessData | |||||||
|             } |             } | ||||||
|             catch (Exception) |             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); |             results.Add(keyValuePair.Key, record); | ||||||
|         } |         } | ||||||
|         return new(results); |         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) |     private static string GetIndexLines(ReadOnlyCollection<string> frontMatterLines, Record record) | ||||||
|     { |     { | ||||||
|         List<string> results = new(); |         List<string> results = new(); | ||||||
| @ -234,32 +194,4 @@ public class ProcessData : IProcessData | |||||||
|         return string.Join(Environment.NewLine, results); |         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); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } | } | ||||||
| @ -14,7 +14,7 @@ namespace Adaptation.FileHandlers.APC; | |||||||
| public class FileRead : Shared.FileRead, IFileRead | 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) : |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
| @ -128,7 +128,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             FileCopy(reportFullPath, dateTime, descriptions); |             FileCopy(reportFullPath, dateTime, descriptions); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|     private readonly string _JobIdParentDirectory; |     private readonly string _JobIdParentDirectory; | ||||||
|     private readonly string _JobIdArchiveParentDirectory; |     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) : |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
| @ -153,7 +153,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             MoveArchive(reportFullPath, dateTime); |             MoveArchive(reportFullPath, dateTime); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ namespace Adaptation.FileHandlers; | |||||||
| public class CellInstanceConnectionName | 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 |         IFileRead result = cellInstanceConnectionName switch | ||||||
|         { |         { | ||||||
|  | |||||||
| @ -29,7 +29,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|     private readonly string _BasePage; |     private readonly string _BasePage; | ||||||
|     private readonly HttpClient _HttpClient; |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
|  | |||||||
| @ -23,7 +23,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|     private int _LastDummyRunIndex; |     private int _LastDummyRunIndex; | ||||||
|     private readonly string[] _CellNames; |     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) : |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ namespace Adaptation.FileHandlers.IQSSi; | |||||||
| public class FileRead : Shared.FileRead, IFileRead | 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) : |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
| @ -127,7 +127,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             FileCopy(reportFullPath, dateTime, descriptions); |             FileCopy(reportFullPath, dateTime, descriptions); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|     private long? _TickOffset; |     private long? _TickOffset; | ||||||
|     private readonly string _URL; |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
|  | |||||||
| @ -169,7 +169,8 @@ public class ProcessData : IProcessData | |||||||
|             } |             } | ||||||
|             catch (Exception) |             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); |             results.Add(keyValuePair.Key, record); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|     private readonly string _URL; |     private readonly string _URL; | ||||||
|     private readonly ReadOnlyCollection<string> _WorkItemTypes; |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
|  | |||||||
| @ -30,14 +30,14 @@ public class ProcessData : IProcessData | |||||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IProcessData.GetResults(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection) => |     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); |         new(logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), fileInfoCollection); | ||||||
|  |  | ||||||
|  |     private static string GetClosed(WorkItem workItem) => | ||||||
|  |         workItem.State != "Closed" ? "[ ]" : "[x]"; | ||||||
|  |  | ||||||
|     public ProcessData(IFileRead fileRead, Logistics logistics, string targetFileLocation, string url, ReadOnlyCollection<string> workItemTypes, List<FileInfo> fileInfoCollection) |     public ProcessData(IFileRead fileRead, Logistics logistics, string targetFileLocation, string url, ReadOnlyCollection<string> workItemTypes, List<FileInfo> fileInfoCollection) | ||||||
|     { |     { | ||||||
|         if (fileRead.IsEAFHosted) |  | ||||||
|         { |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|         _Details = new List<object>(); |         _Details = new List<object>(); | ||||||
|         _Log = LogManager.GetLogger(typeof(ProcessData)); |         _Log = LogManager.GetLogger(typeof(ProcessData)); | ||||||
|  |         if (fileRead.IsEAFHosted) | ||||||
|             WriteFiles(fileRead, logistics, url, workItemTypes, targetFileLocation, fileInfoCollection); |             WriteFiles(fileRead, logistics, url, workItemTypes, targetFileLocation, fileInfoCollection); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -93,6 +93,7 @@ public class ProcessData : IProcessData | |||||||
|         ReadOnlyCollection<Record> results; |         ReadOnlyCollection<Record> results; | ||||||
|         ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations); |         ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations); | ||||||
|         ReadOnlyCollection<Record> records = new(keyValuePairs.Values.ToArray()); |         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> bugFeatureWorkItemTypes = new(new string[] { "Bug", "Feature" }); | ||||||
|         ReadOnlyCollection<string> bugUserStoryWorkItemTypes = new(new string[] { "Bug", "User Story" }); |         ReadOnlyCollection<string> bugUserStoryWorkItemTypes = new(new string[] { "Bug", "User Story" }); | ||||||
|         messages.AddRange(WriteFile(fileRead, destinationDirectory, fileInfoCollection, records, "records")); |         messages.AddRange(WriteFile(fileRead, destinationDirectory, fileInfoCollection, records, "records")); | ||||||
| @ -108,6 +109,15 @@ public class ProcessData : IProcessData | |||||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, workItemType); |             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, workItemType); | ||||||
|             _Details.Add(results); |             _Details.Add(results); | ||||||
|         } |         } | ||||||
|  |         { | ||||||
|  |             lines.Clear(); | ||||||
|  |             string workItemType = "User Story"; | ||||||
|  |             lines.Add($"# Total User Story Points by Site - Iteration - Assigned To (Initials)"); | ||||||
|  |             lines.Add(string.Empty); | ||||||
|  |             results = UserStoryCheckIterationPath228385(url, lines, userStoryWorkItemTypes, keyValuePairs, workItemType); | ||||||
|  |             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, $"{workItemType} check 228385"); | ||||||
|  |             _Details.Add(results); | ||||||
|  |         } | ||||||
|         if (messages.Count > 0) |         if (messages.Count > 0) | ||||||
|             throw new Exception($"{messages.Count}{Environment.NewLine}{string.Join(Environment.NewLine, messages)}"); |             throw new Exception($"{messages.Count}{Environment.NewLine}{string.Join(Environment.NewLine, messages)}"); | ||||||
|     } |     } | ||||||
| @ -148,7 +158,8 @@ public class ProcessData : IProcessData | |||||||
|             } |             } | ||||||
|             catch (Exception) |             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); |             results.Add(keyValuePair.Key, record); | ||||||
|         } |         } | ||||||
| @ -177,7 +188,7 @@ public class ProcessData : IProcessData | |||||||
|         { |         { | ||||||
|             if (r.WorkItem.State == "Removed" || !workItemTypes.Contains(r.WorkItem.WorkItemType)) |             if (r.WorkItem.State == "Removed" || !workItemTypes.Contains(r.WorkItem.WorkItemType)) | ||||||
|                 continue; |                 continue; | ||||||
|             record = new(r.WorkItem, r.Parent, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>()); |             record = new(r.WorkItem, r.Parent, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>(), r.Tag); | ||||||
|             filtered.Add(record); |             filtered.Add(record); | ||||||
|         } |         } | ||||||
|         string? json = GetJson(filtered, results); |         string? json = GetJson(filtered, results); | ||||||
| @ -285,8 +296,104 @@ public class ProcessData : IProcessData | |||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static string GetClosed(WorkItem workItem) => |     private static ReadOnlyCollection<Record> UserStoryCheckIterationPath228385(string url, List<string> lines, ReadOnlyCollection<string> _, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||||
|         workItem.State != "Closed" ? "[ ]" : "[x]"; |     { | ||||||
|  |         List<Record> results = new(); | ||||||
|  |         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 ReadOnlyDictionary<string, List<Record>> GetWorkItemsMatching228385(ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||||
|  |     { | ||||||
|  |         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) | ||||||
|  |         { | ||||||
|  |             key = $"{record.WorkItem.AreaPath.Split('\\').Last()}-{record.WorkItem.IterationPath.Split('\\').Last().Split(' ').Last()}"; | ||||||
|  |             if (!results.TryGetValue(key, out collection)) | ||||||
|  |             { | ||||||
|  |                 results.Add(key, new()); | ||||||
|  |                 if (!results.TryGetValue(key, out collection)) | ||||||
|  |                     throw new Exception(); | ||||||
|  |             } | ||||||
|  |             collection.Add(record); | ||||||
|  |         } | ||||||
|  |         foreach (Record record in records) | ||||||
|  |         { | ||||||
|  |             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(key, new()); | ||||||
|  |                 if (!results.TryGetValue(key, out collection)) | ||||||
|  |                     throw new Exception(); | ||||||
|  |             } | ||||||
|  |             collection.Add(record); | ||||||
|  |         } | ||||||
|  |         return new(results); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     internal static List<Description> GetDescriptions(JsonElement[] jsonElements) |     internal static List<Description> GetDescriptions(JsonElement[] jsonElements) | ||||||
|     { |     { | ||||||
|  | |||||||
| @ -22,17 +22,21 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|     internal class PreWith |     internal class PreWith | ||||||
|     { |     { | ||||||
|  |  | ||||||
|         internal string MatchingFile { get; private set; } |  | ||||||
|         internal string CheckFile { get; private set; } |  | ||||||
|         internal string ErrFile { get; private set; } |         internal string ErrFile { get; private set; } | ||||||
|  |         internal string CheckFile { get; private set; } | ||||||
|  |         internal string MatchingFile { get; private set; } | ||||||
|         internal string CheckDirectory { get; private set; } |         internal string CheckDirectory { get; private set; } | ||||||
|         internal string NoWaitDirectory { get; private set; } |         internal string NoWaitDirectory { get; private set; } | ||||||
|  |  | ||||||
|         internal PreWith(string matchingFile, string checkFile, string errFile, string checkDirectory, string noWaitDirectory) |         internal PreWith(string checkDirectory, | ||||||
|  |                          string checkFile, | ||||||
|  |                          string errFile, | ||||||
|  |                          string matchingFile, | ||||||
|  |                          string noWaitDirectory) | ||||||
|         { |         { | ||||||
|             MatchingFile = matchingFile; |  | ||||||
|             CheckFile = checkFile; |  | ||||||
|             ErrFile = errFile; |             ErrFile = errFile; | ||||||
|  |             CheckFile = checkFile; | ||||||
|  |             MatchingFile = matchingFile; | ||||||
|             CheckDirectory = checkDirectory; |             CheckDirectory = checkDirectory; | ||||||
|             NoWaitDirectory = noWaitDirectory; |             NoWaitDirectory = noWaitDirectory; | ||||||
|         } |         } | ||||||
| @ -67,7 +71,9 @@ 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 readonly ProcessDataStandardFormatMapping _ProcessDataStandardFormatMapping; | ||||||
|  |  | ||||||
|  |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
| @ -79,6 +85,12 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|             throw new Exception(cellInstanceConnectionName); |             throw new Exception(cellInstanceConnectionName); | ||||||
|         if (!_IsDuplicator) |         if (!_IsDuplicator) | ||||||
|             throw new Exception(cellInstanceConnectionName); |             throw new Exception(cellInstanceConnectionName); | ||||||
|  |         string processDataStandardFormatMappingOldColumnNames = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, "Process.Data.Standard.Format.Mapping.Old.Column.Names"); | ||||||
|  |         string processDataStandardFormatMappingNewColumnNames = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, "Process.Data.Standard.Format.Mapping.New.Column.Names"); | ||||||
|  |         string processDataStandardFormatMappingColumnIndices = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, "Process.Data.Standard.Format.Mapping.Column.Indices"); | ||||||
|  |         _ProcessDataStandardFormatMapping = GetProcessDataStandardFormatMapping(processDataStandardFormatMappingOldColumnNames, | ||||||
|  |                                                                                 processDataStandardFormatMappingNewColumnNames, | ||||||
|  |                                                                                 processDataStandardFormatMappingColumnIndices); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) |     void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) | ||||||
| @ -157,7 +169,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static ProcessDataStandardFormatMapping GetProcessDataStandardFormatMapping() |     private static ProcessDataStandardFormatMapping GetProcessDataStandardFormatMapping(string processDataStandardFormatMappingOldColumnNames, string processDataStandardFormatMappingNewColumnNames, string processDataStandardFormatMappingColumnIndices) | ||||||
|     { |     { | ||||||
|         ProcessDataStandardFormatMapping result; |         ProcessDataStandardFormatMapping result; | ||||||
|         string[] segmentsB; |         string[] segmentsB; | ||||||
| @ -167,16 +179,16 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         string args5 = "Nine10mmEdgeMean,Nine4mmEdgeMean,NineCriticalPointsAverage,NineCriticalPointsPhaseAngleAverage,NineCriticalPointsStdDev,NineEdgeMeanDelta,NineMean,NineResRangePercent,AreaDeltaFromLastRun,Variation,Percentage HgCV 4PP Delta,HGCV1"; |         string args5 = "Nine10mmEdgeMean,Nine4mmEdgeMean,NineCriticalPointsAverage,NineCriticalPointsPhaseAngleAverage,NineCriticalPointsStdDev,NineEdgeMeanDelta,NineMean,NineResRangePercent,AreaDeltaFromLastRun,Variation,Percentage HgCV 4PP Delta,HGCV1"; | ||||||
|         string args6 = "RhoAvg01,RhoAvg02,RhoAvg03,RhoAvg04,RhoAvg05,RhoAvg06,RhoAvg07,RhoAvg08,RhoAvg09,HGCV1"; |         string args6 = "RhoAvg01,RhoAvg02,RhoAvg03,RhoAvg04,RhoAvg05,RhoAvg06,RhoAvg07,RhoAvg08,RhoAvg09,HGCV1"; | ||||||
|         string args7 = "FlatZMean|MeanFlatZ,GradeMean|MeanGrade,NAvgMean|MeanNAvg,NslMean|MeanNsl,PhaseMean|MeanPhase,RhoAvgMean|MeanRhoAvg,RhoslMean|MeanRhosl,RsMean|MeanRs,VdMean|MeanVd,FlatZRadialGradient|RadialGradientFlatZ,GradeRadialGradient|RadialGradientGrade,NAvgRadialGradient|RadialGradientNAvg,NslRadialGradient|RadialGradientNsl,PhaseRadialGradient|RadialGradientPhase,RhoAvgRadialGradient|RadialGradientRhoAvg,RhoslRadialGradient|RadialGradientRhosl,RsRadialGradient|RadialGradientRs,VdRadialGradient|RadialGradientVd,FlatZStdDev|StandardDeviationPercentageFlatZ,GradeStdDev|StandardDeviationPercentageGrade,NAvgStdDev|StandardDeviationPercentageNAvg,NslStdDev|StandardDeviationPercentageNsl,PhaseStdDev|StandardDeviationPercentagePhase,RhoAvgStdDev|StandardDeviationPercentageRhoAvg,RhoslStdDev|StandardDeviationPercentageRhosl,RsStdDev|StandardDeviationPercentageRs,VdStdDev|StandardDeviationPercentageVd,|HGCV1"; |         string args7 = "FlatZMean|MeanFlatZ,GradeMean|MeanGrade,NAvgMean|MeanNAvg,NslMean|MeanNsl,PhaseMean|MeanPhase,RhoAvgMean|MeanRhoAvg,RhoslMean|MeanRhosl,RsMean|MeanRs,VdMean|MeanVd,FlatZRadialGradient|RadialGradientFlatZ,GradeRadialGradient|RadialGradientGrade,NAvgRadialGradient|RadialGradientNAvg,NslRadialGradient|RadialGradientNsl,PhaseRadialGradient|RadialGradientPhase,RhoAvgRadialGradient|RadialGradientRhoAvg,RhoslRadialGradient|RadialGradientRhosl,RsRadialGradient|RadialGradientRs,VdRadialGradient|RadialGradientVd,FlatZStdDev|StandardDeviationPercentageFlatZ,GradeStdDev|StandardDeviationPercentageGrade,NAvgStdDev|StandardDeviationPercentageNAvg,NslStdDev|StandardDeviationPercentageNsl,PhaseStdDev|StandardDeviationPercentagePhase,RhoAvgStdDev|StandardDeviationPercentageRhoAvg,RhoslStdDev|StandardDeviationPercentageRhosl,RsStdDev|StandardDeviationPercentageRs,VdStdDev|StandardDeviationPercentageVd,|HGCV1"; | ||||||
|         string args8 = "Time,A_LOGISTICS,B_LOGISTICS,Test,Count,Index,MesEntity,Date,Employee,Lot,PSN,Reactor,Recipe,Area,Folder,HeaderUniqueId,Id,Layer,Model,Pattern,Phase,Plan,RampRate,RDS,SetupFile,StartVoltage,StopVoltage,UniqueId,Wafer,WaferSize,Zone,Ccomp,CondType,FlatZ,FlatZMean,FlatZRadialGradient,FlatZStdDev,GLimit,Grade,GradeMean,GradeRadialGradient,GradeStdDev,NAvg,NAvgMean,NAvgRadialGradient,NAvgStdDev,Nsl,NslMean,NslRadialGradient,NslStdDev,PhaseMean,PhaseRadialGradient,PhaseStdDev,RhoAvg,RhoAvgMean,RhoAvgRadialGradient,RhoAvgStdDev,RhoMethod,Rhosl,RhoslMean,RhoslRadialGradient,RhoslStdDev,RsMean,RsRadialGradient,RsStdDev,Vd,VdMean,VdRadialGradient,VdStdDev,Variation,AreaDeltaFromLastRun,Nine10mmEdgeMean,Nine4mmEdgeMean,NineCriticalPointsAverage,NineCriticalPointsPhaseAngleAverage,NineCriticalPointsStdDev,NineEdgeMeanDelta,NineMean,NineResRangePercent,RhoAvg01,RhoAvg02,RhoAvg03,RhoAvg04,RhoAvg05,RhoAvg06,RhoAvg07,RhoAvg08,RhoAvg09"; |         // string args8 = "Time,A_LOGISTICS,B_LOGISTICS,Test,Count,Index,MesEntity,Date,Employee,Lot,PSN,Reactor,Recipe,Area,Folder,HeaderUniqueId,Id,Layer,Model,Pattern,Phase,Plan,RampRate,RDS,SetupFile,StartVoltage,StopVoltage,UniqueId,Wafer,WaferSize,Zone,Ccomp,CondType,FlatZ,FlatZMean,FlatZRadialGradient,FlatZStdDev,GLimit,Grade,GradeMean,GradeRadialGradient,GradeStdDev,NAvg,NAvgMean,NAvgRadialGradient,NAvgStdDev,Nsl,NslMean,NslRadialGradient,NslStdDev,PhaseMean,PhaseRadialGradient,PhaseStdDev,RhoAvg,RhoAvgMean,RhoAvgRadialGradient,RhoAvgStdDev,RhoMethod,Rhosl,RhoslMean,RhoslRadialGradient,RhoslStdDev,RsMean,RsRadialGradient,RsStdDev,Vd,VdMean,VdRadialGradient,VdStdDev,Variation,AreaDeltaFromLastRun,Nine10mmEdgeMean,Nine4mmEdgeMean,NineCriticalPointsAverage,NineCriticalPointsPhaseAngleAverage,NineCriticalPointsStdDev,NineEdgeMeanDelta,NineMean,NineResRangePercent,RhoAvg01,RhoAvg02,RhoAvg03,RhoAvg04,RhoAvg05,RhoAvg06,RhoAvg07,RhoAvg08,RhoAvg09"; | ||||||
|         string args9 = "Time,A_LOGISTICS,B_LOGISTICS,Index,Operator,StartVoltage,Wafer,StopVoltage,Lot,RampRate,Plan,GLimit,Date,Time,SetupFile,WaferSize,Folder,Ccomp,Pattern,Area,CondType,RhoMethod,Model,MeanNAvg,MeanNsl,MeanVd,MeanFlatZ,MeanRhoAvg,MeanRhosl,MeanPhase,MeanGrade,MeanRs,StandardDeviationPercentageNAvg,StandardDeviationPercentageNsl,StandardDeviationPercentageVd,StandardDeviationPercentageFlatZ,StandardDeviationPercentageRhoAvg,StandardDeviationPercentageRhosl,StandardDeviationPercentagePhase,StandardDeviationPercentageGrade,StandardDeviationPercentageRs,RadialGradientNAvg,RadialGradientNsl,RadialGradientVd,RadialGradientFlatZ,RadialGradientRhoAvg,RadialGradientRhosl,RadialGradientPhase,RadialGradientGrade,RadialGradientRs,Site,X,Y,NAvg,RhoAvg,Nsl,Rhosl,Vd,Phase,FlatZ,Grade,XLeft,XRight,BottomY,TopY,RDS,PSN,Reactor,Layer,Zone,Employee,InferredLot,Nine10mmEdgeMean,Nine4mmEdgeMean,NineCriticalPointsAverage,NineCriticalPointsPhaseAngleAverage,NineCriticalPointsStdDev,NineEdgeMeanDelta,NineMean,NineResRangePercent,AreaDeltaFromLastRun,Variation,Percentage HgCV 4PP Delta,RhoAvg01,RhoAvg02,RhoAvg03,RhoAvg04,RhoAvg05,RhoAvg06,RhoAvg07,RhoAvg08,RhoAvg09"; |         // string args9 = "Time,A_LOGISTICS,B_LOGISTICS,Index,Operator,StartVoltage,Wafer,StopVoltage,Lot,RampRate,Plan,GLimit,Date,Time,SetupFile,WaferSize,Folder,Ccomp,Pattern,Area,CondType,RhoMethod,Model,MeanNAvg,MeanNsl,MeanVd,MeanFlatZ,MeanRhoAvg,MeanRhosl,MeanPhase,MeanGrade,MeanRs,StandardDeviationPercentageNAvg,StandardDeviationPercentageNsl,StandardDeviationPercentageVd,StandardDeviationPercentageFlatZ,StandardDeviationPercentageRhoAvg,StandardDeviationPercentageRhosl,StandardDeviationPercentagePhase,StandardDeviationPercentageGrade,StandardDeviationPercentageRs,RadialGradientNAvg,RadialGradientNsl,RadialGradientVd,RadialGradientFlatZ,RadialGradientRhoAvg,RadialGradientRhosl,RadialGradientPhase,RadialGradientGrade,RadialGradientRs,Site,X,Y,NAvg,RhoAvg,Nsl,Rhosl,Vd,Phase,FlatZ,Grade,XLeft,XRight,BottomY,TopY,RDS,PSN,Reactor,Layer,Zone,Employee,InferredLot,Nine10mmEdgeMean,Nine4mmEdgeMean,NineCriticalPointsAverage,NineCriticalPointsPhaseAngleAverage,NineCriticalPointsStdDev,NineEdgeMeanDelta,NineMean,NineResRangePercent,AreaDeltaFromLastRun,Variation,Percentage HgCV 4PP Delta,RhoAvg01,RhoAvg02,RhoAvg03,RhoAvg04,RhoAvg05,RhoAvg06,RhoAvg07,RhoAvg08,RhoAvg09"; | ||||||
|         string args10 = "0,1,2,-1,-1,3,-1,12,70,8,66,67,-1,19,16,-1,-1,68,22,18,58,10,9,65,14,5,7,-1,6,15,69,17,20,59,26,44,35,11,60,30,48,39,53,23,41,32,55,24,42,33,29,47,38,54,27,45,36,21,56,28,46,37,31,49,40,57,25,43,34,81,80,72,73,74,75,76,77,78,79,83,84,85,86,87,88,89,90,91"; |         // string args10 = "0,1,2,-1,-1,3,-1,12,70,8,66,67,-1,19,16,-1,-1,68,22,18,58,10,9,65,14,5,7,-1,6,15,69,17,20,59,26,44,35,11,60,30,48,39,53,23,41,32,55,24,42,33,29,47,38,54,27,45,36,21,56,28,46,37,31,49,40,57,25,43,34,81,80,72,73,74,75,76,77,78,79,83,84,85,86,87,88,89,90,91"; | ||||||
|         string[] segments = args7.Split(','); |         string[] segments = args7.Split(','); | ||||||
|         ReadOnlyCollection<string> ignoreColumns = new(args4.Split(',')); |         ReadOnlyCollection<string> ignoreColumns = new(args4.Split(',')); | ||||||
|         ReadOnlyCollection<string> newColumnNames = new(args9.Split(',')); |  | ||||||
|         ReadOnlyCollection<string> oldColumnNames = new(args8.Split(',')); |  | ||||||
|         ReadOnlyCollection<string> backfillColumns = new(args5.Split(',')); |         ReadOnlyCollection<string> backfillColumns = new(args5.Split(',')); | ||||||
|         ReadOnlyCollection<string> indexOnlyColumns = new(args6.Split(',')); |         ReadOnlyCollection<string> indexOnlyColumns = new(args6.Split(',')); | ||||||
|         ReadOnlyCollection<int> columnIndices = new(args10.Split(',').Select(int.Parse).ToArray()); |         ReadOnlyCollection<string> newColumnNames = new(processDataStandardFormatMappingNewColumnNames.Split(',')); | ||||||
|  |         ReadOnlyCollection<string> oldColumnNames = new(processDataStandardFormatMappingOldColumnNames.Split(',')); | ||||||
|  |         ReadOnlyCollection<int> columnIndices = new(processDataStandardFormatMappingColumnIndices.Split(',').Select(int.Parse).ToArray()); | ||||||
|         foreach (string segment in segments) |         foreach (string segment in segments) | ||||||
|         { |         { | ||||||
|             segmentsB = segment.Split('|'); |             segmentsB = segment.Split('|'); | ||||||
| @ -213,7 +225,11 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|             if (!Directory.Exists(checkDirectory)) |             if (!Directory.Exists(checkDirectory)) | ||||||
|                 _ = Directory.CreateDirectory(checkDirectory); |                 _ = Directory.CreateDirectory(checkDirectory); | ||||||
|             noWaitDirectory = Path.Combine(checkDirectory, "NoWaitDirectory"); |             noWaitDirectory = Path.Combine(checkDirectory, "NoWaitDirectory"); | ||||||
|             preWith = new(pre.MatchingFile, pre.CheckFile, errFile, checkDirectory, noWaitDirectory); |             preWith = new(checkDirectory: checkDirectory, | ||||||
|  |                           checkFile: pre.CheckFile, | ||||||
|  |                           errFile: errFile, | ||||||
|  |                           matchingFile: pre.MatchingFile, | ||||||
|  |                           noWaitDirectory: noWaitDirectory); | ||||||
|             results.Add(preWith); |             results.Add(preWith); | ||||||
|         } |         } | ||||||
|         return results.AsReadOnly(); |         return results.AsReadOnly(); | ||||||
| @ -267,7 +283,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         return results.AsReadOnly(); |         return results.AsReadOnly(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void MoveCollection(DateTime dateTime, ProcessDataStandardFormat? processDataStandardFormat, ReadOnlyCollection<PreWith> preWithCollection) |     private void MoveCollection(DateTime dateTime, ProcessDataStandardFormat processDataStandardFormat, ReadOnlyCollection<PreWith> preWithCollection) | ||||||
|     { |     { | ||||||
|         ReadOnlyCollection<Post> postCollection = GetPostCollection(dateTime, processDataStandardFormat, preWithCollection); |         ReadOnlyCollection<Post> postCollection = GetPostCollection(dateTime, processDataStandardFormat, preWithCollection); | ||||||
|         if (postCollection.Count != 0) |         if (postCollection.Count != 0) | ||||||
| @ -286,20 +302,19 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private ReadOnlyCollection<Post> GetPostCollection(DateTime dateTime, ProcessDataStandardFormat? processDataStandardFormat, ReadOnlyCollection<PreWith> preWithCollection) |     private ReadOnlyCollection<Post> GetPostCollection(DateTime dateTime, ProcessDataStandardFormat processDataStandardFormat, ReadOnlyCollection<PreWith> preWithCollection) | ||||||
|     { |     { | ||||||
|         List<Post> results = new(); |         List<Post> results = new(); | ||||||
|         Post post; |         Post post; | ||||||
|         long preWait; |         long preWait; | ||||||
|         foreach (PreWith preWith in preWithCollection) |         foreach (PreWith preWith in preWithCollection) | ||||||
|         { |         { | ||||||
|             if (processDataStandardFormat is null) |             if (!_IsEAFHosted) | ||||||
|                 File.Move(preWith.MatchingFile, preWith.CheckFile); |                 continue; | ||||||
|             else |             if (!_StaticRuns.TryGetValue(_Logistics.Sequence, out List<Shared.Metrology.WS.Results>? wsResults)) | ||||||
|             { |                 wsResults = null; | ||||||
|                 ProcessDataStandardFormat.Write(preWith.CheckFile, processDataStandardFormat); |             ProcessDataStandardFormat.Write(preWith.CheckFile, processDataStandardFormat, wsResults); | ||||||
|             File.Delete(preWith.MatchingFile); |             File.Delete(preWith.MatchingFile); | ||||||
|             } |  | ||||||
|             if (Directory.Exists(preWith.NoWaitDirectory)) |             if (Directory.Exists(preWith.NoWaitDirectory)) | ||||||
|             { |             { | ||||||
|                 post = new(preWith.CheckFile, preWith.ErrFile); |                 post = new(preWith.CheckFile, preWith.ErrFile); | ||||||
| @ -333,16 +348,10 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|     private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime) |     private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime) | ||||||
|     { |     { | ||||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results = new(string.Empty, Array.Empty<Test>(), Array.Empty<JsonElement>(), new List<FileInfo>()); |         Tuple<string, Test[], JsonElement[], List<FileInfo>> results = new(string.Empty, Array.Empty<Test>(), Array.Empty<JsonElement>(), new List<FileInfo>()); | ||||||
|         ProcessDataStandardFormatMapping processDataStandardFormatMapping = GetProcessDataStandardFormatMapping(); |         ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, _ProcessDataStandardFormatMapping); | ||||||
|         ProcessDataStandardFormat? processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, processDataStandardFormatMapping); |  | ||||||
|         if (processDataStandardFormat is not null) |  | ||||||
|         _Logistics = new Logistics(reportFullPath, processDataStandardFormat); |         _Logistics = new Logistics(reportFullPath, processDataStandardFormat); | ||||||
|         else |         if (!_IsEAFHosted) | ||||||
|         { |             ProcessDataStandardFormat.Write("../../.pdsf", processDataStandardFormat, wsResults: null); | ||||||
|             processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath); |  | ||||||
|             _Logistics = new Logistics(reportFullPath, processDataStandardFormat); |  | ||||||
|             processDataStandardFormat = null; |  | ||||||
|         } |  | ||||||
|         SetFileParameterLotIDToLogisticsMID(); |         SetFileParameterLotIDToLogisticsMID(); | ||||||
|         int numberLength = 2; |         int numberLength = 2; | ||||||
|         long ticks = dateTime.Ticks; |         long ticks = dateTime.Ticks; | ||||||
| @ -351,9 +360,12 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         ReadOnlyCollection<string> matchingFiles = GetMatchingFiles(ticks, reportFullPath, searchDirectories); |         ReadOnlyCollection<string> matchingFiles = GetMatchingFiles(ticks, reportFullPath, searchDirectories); | ||||||
|         if (matchingFiles.Count != searchDirectories.Count) |         if (matchingFiles.Count != searchDirectories.Count) | ||||||
|             throw new Exception($"Didn't find all files after {_BreakAfterSeconds} second(s)!"); |             throw new Exception($"Didn't find all files after {_BreakAfterSeconds} second(s)!"); | ||||||
|  |         if (_IsEAFHosted) | ||||||
|  |         { | ||||||
|             try |             try | ||||||
|             { CreatePointerFile(numberLength, parentParentDirectory, matchingFiles); } |             { CreatePointerFile(numberLength, parentParentDirectory, matchingFiles); } | ||||||
|             catch (Exception) { } |             catch (Exception) { } | ||||||
|  |         } | ||||||
|         ReadOnlyCollection<Pre> preCollection = GetPreCollection(numberLength, parentParentDirectory, matchingFiles); |         ReadOnlyCollection<Pre> preCollection = GetPreCollection(numberLength, parentParentDirectory, matchingFiles); | ||||||
|         ReadOnlyCollection<PreWith> preWithCollection = GetPreWithCollection(preCollection); |         ReadOnlyCollection<PreWith> preWithCollection = GetPreWithCollection(preCollection); | ||||||
|         MoveCollection(dateTime, processDataStandardFormat, preWithCollection); |         MoveCollection(dateTime, processDataStandardFormat, preWithCollection); | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ namespace Adaptation.FileHandlers.OpenInsight; | |||||||
| public class FileRead : Shared.FileRead, IFileRead | 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) : |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
| @ -126,7 +126,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             SaveOpenInsightFile(reportFullPath, dateTime, descriptions, tests); |             SaveOpenInsightFile(reportFullPath, dateTime, descriptions, tests); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ namespace Adaptation.FileHandlers.OpenInsightMetrologyViewer; | |||||||
| public class FileRead : Shared.FileRead, IFileRead | 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) : |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
| @ -113,14 +113,14 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         // (string jsonResults, WS.Results wsResults) = WS.SendData(_OpenInsightMetrologyViewerAPI, _Logistics.Sequence, directory, wsRequest); |         // (string jsonResults, WS.Results wsResults) = WS.SendData(_OpenInsightMetrologyViewerAPI, _Logistics.Sequence, directory, wsRequest); | ||||||
|         // if (!wsResults.Success) |         // if (!wsResults.Success) | ||||||
|         //     throw new Exception(wsResults.ToString()); |         //     throw new Exception(wsResults.ToString()); | ||||||
|         // _Log.Debug(wsResults.HeaderID); |         // _Log.Debug(wsResults.HeaderId); | ||||||
|         // lock (_StaticRuns) |         // lock (_StaticRuns) | ||||||
|         // { |         // { | ||||||
|         //     if (!_StaticRuns.ContainsKey(_Logistics.Sequence)) |         //     if (!_StaticRuns.ContainsKey(_Logistics.Sequence)) | ||||||
|         //         _StaticRuns.Add(_Logistics.Sequence, new()); |         //         _StaticRuns.Add(_Logistics.Sequence, new()); | ||||||
|         //     _StaticRuns[_Logistics.Sequence].Add(jsonResults); |         //     _StaticRuns[_Logistics.Sequence].Add(jsonResults); | ||||||
|         // } |         // } | ||||||
|         // string checkDirectory = Path.Combine(directory, wsResults.HeaderID.ToString()); |         // string checkDirectory = Path.Combine(directory, wsResults.HeaderId.ToString()); | ||||||
|         // if (!Directory.Exists(checkDirectory)) |         // if (!Directory.Exists(checkDirectory)) | ||||||
|         //     _ = Directory.CreateDirectory(checkDirectory); |         //     _ = Directory.CreateDirectory(checkDirectory); | ||||||
|         // File.Copy(reportFullPath, Path.Combine(checkDirectory, Path.GetFileName(reportFullPath)), overwrite: true); |         // File.Copy(reportFullPath, Path.Combine(checkDirectory, Path.GetFileName(reportFullPath)), overwrite: true); | ||||||
| @ -137,7 +137,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             SendData(reportFullPath, dateTime, descriptions); |             SendData(reportFullPath, dateTime, descriptions); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|     private readonly string _OpenInsightMetrologyViewerAPI; |     private readonly string _OpenInsightMetrologyViewerAPI; | ||||||
|     private readonly string _OpenInsightMetrologyViewerFileShare; |     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) : |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
| @ -154,7 +154,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             PostOpenInsightMetrologyViewerAttachments(descriptions); |             PostOpenInsightMetrologyViewerAttachments(descriptions); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -45,6 +45,7 @@ public class Aggregation | |||||||
|     private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Dictionary<int, List<Notification>> keyValuePairs) |     private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Dictionary<int, List<Notification>> keyValuePairs) | ||||||
|     { |     { | ||||||
|         Dictionary<int, Aggregation> results = new(); |         Dictionary<int, Aggregation> results = new(); | ||||||
|  |         int value; | ||||||
|         int? inverseValue; |         int? inverseValue; | ||||||
|         double inverseAverage; |         double inverseAverage; | ||||||
|         Aggregation aggregation; |         Aggregation aggregation; | ||||||
| @ -60,7 +61,9 @@ public class Aggregation | |||||||
|             fibonacciCollection.Clear(); |             fibonacciCollection.Clear(); | ||||||
|             foreach (Notification notification in keyValuePair.Value) |             foreach (Notification notification in keyValuePair.Value) | ||||||
|             { |             { | ||||||
|                 collection.Add(notification.Value); |                 if (!int.TryParse(notification.Value, out value)) | ||||||
|  |                     continue; | ||||||
|  |                 collection.Add(value); | ||||||
|                 if (notification.Inverse is null) |                 if (notification.Inverse is null) | ||||||
|                     continue; |                     continue; | ||||||
|                 inverseCollection.Add(notification.Inverse.Value); |                 inverseCollection.Add(notification.Inverse.Value); | ||||||
| @ -72,7 +75,7 @@ public class Aggregation | |||||||
|                 continue; |                 continue; | ||||||
|             inverseAverage = Math.Round(inverseCollection.Average(), settings.Digits); |             inverseAverage = Math.Round(inverseCollection.Average(), settings.Digits); | ||||||
|             averageFromInverseCeiling = (int)Math.Ceiling(inverseAverage); |             averageFromInverseCeiling = (int)Math.Ceiling(inverseAverage); | ||||||
|             inverseValue = Notification.GetInverse(averageFromInverseCeiling); |             inverseValue = Notification.GetInverse(averageFromInverseCeiling.ToString()); | ||||||
|             fibonacciAverage = Math.Round(fibonacciCollection.Average(), settings.Digits); |             fibonacciAverage = Math.Round(fibonacciCollection.Average(), settings.Digits); | ||||||
|             aggregation = new(inverseAverage: inverseAverage, |             aggregation = new(inverseAverage: inverseAverage, | ||||||
|                               valueCount: collection.Count, |                               valueCount: collection.Count, | ||||||
| @ -107,9 +110,9 @@ public class Aggregation | |||||||
|                 if (string.IsNullOrEmpty(text) || text[0] == '[') |                 if (string.IsNullOrEmpty(text) || text[0] == '[') | ||||||
|                     continue; |                     continue; | ||||||
|                 notification = JsonSerializer.Deserialize(text, NotificationSourceGenerationContext.Default.Notification); |                 notification = JsonSerializer.Deserialize(text, NotificationSourceGenerationContext.Default.Notification); | ||||||
|                 if (notification is null || notification.Id == 0) |                 if (notification is null || string.IsNullOrEmpty(notification.Id)) | ||||||
|                     continue; |                     continue; | ||||||
|                 key = !string.IsNullOrEmpty(notification.Username) ? notification.Username : notification.RemoteIpAddress; |                 key = !string.IsNullOrEmpty(notification.Username) ? notification.Username : throw new Exception(); | ||||||
|                 if (string.IsNullOrEmpty(key)) |                 if (string.IsNullOrEmpty(key)) | ||||||
|                     continue; |                     continue; | ||||||
|                 if (!keyValuePairs.TryGetValue(key, out collection)) |                 if (!keyValuePairs.TryGetValue(key, out collection)) | ||||||
| @ -126,7 +129,7 @@ public class Aggregation | |||||||
|                     results.Add(keyValuePair.Value[0]); |                     results.Add(keyValuePair.Value[0]); | ||||||
|                 else |                 else | ||||||
|                 { |                 { | ||||||
|                     notification = keyValuePair.Value.Select(record => new KeyValuePair<long, Notification>(record.Time, record)).OrderBy(pair => pair.Key).Last().Value; |                     notification = keyValuePair.Value.Select(record => new KeyValuePair<string, Notification>(record.Time, record)).OrderBy(pair => pair.Key).Last().Value; | ||||||
|                     results.Add(notification); |                     results.Add(notification); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @ -137,15 +140,18 @@ public class Aggregation | |||||||
|     private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, string directory) |     private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, string directory) | ||||||
|     { |     { | ||||||
|         ReadOnlyDictionary<int, Aggregation> results; |         ReadOnlyDictionary<int, Aggregation> results; | ||||||
|  |         int id; | ||||||
|         List<Notification>? collection; |         List<Notification>? collection; | ||||||
|         Dictionary<int, List<Notification>> keyValuePairs = new(); |         Dictionary<int, List<Notification>> keyValuePairs = new(); | ||||||
|         ReadOnlyCollection<Notification> notifications = GetNotifications(settings, directory); |         ReadOnlyCollection<Notification> notifications = GetNotifications(settings, directory); | ||||||
|         foreach (Notification notification in notifications) |         foreach (Notification notification in notifications) | ||||||
|         { |         { | ||||||
|             if (!keyValuePairs.TryGetValue(notification.Id, out collection)) |             if (!int.TryParse(notification.Id, out id)) | ||||||
|  |                 continue; | ||||||
|  |             if (!keyValuePairs.TryGetValue(id, out collection)) | ||||||
|             { |             { | ||||||
|                 keyValuePairs.Add(notification.Id, new()); |                 keyValuePairs.Add(id, new()); | ||||||
|                 if (!keyValuePairs.TryGetValue(notification.Id, out collection)) |                 if (!keyValuePairs.TryGetValue(id, out collection)) | ||||||
|                     throw new Exception(); |                     throw new Exception(); | ||||||
|             } |             } | ||||||
|             collection.Add(notification); |             collection.Add(notification); | ||||||
| @ -185,8 +191,13 @@ public class Aggregation | |||||||
|     internal static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Notification notification) |     internal static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Notification notification) | ||||||
|     { |     { | ||||||
|         ReadOnlyDictionary<int, Aggregation> results; |         ReadOnlyDictionary<int, Aggregation> results; | ||||||
|         Dictionary<int, List<Notification>> keyValuePairs = new() { { notification.Id, new Notification[] { notification }.ToList() } }; |         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); |             results = GetKeyValuePairs(settings, keyValuePairs); | ||||||
|  |         } | ||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -6,8 +6,10 @@ using Adaptation.Shared.Methods; | |||||||
| using log4net; | using log4net; | ||||||
| using System; | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
|  | using System.Diagnostics; | ||||||
| using System.IO; | using System.IO; | ||||||
| using System.Text.Json; | using System.Text.Json; | ||||||
|  | using System.Threading; | ||||||
|  |  | ||||||
| namespace Adaptation.FileHandlers.Priority; | namespace Adaptation.FileHandlers.Priority; | ||||||
|  |  | ||||||
| @ -16,23 +18,21 @@ namespace Adaptation.FileHandlers.Priority; | |||||||
| public class FileRead : Shared.FileRead, IFileRead | public class FileRead : Shared.FileRead, IFileRead | ||||||
| { | { | ||||||
|  |  | ||||||
|     internal static ILog Log => _Log; |     private readonly Timer _Timer; | ||||||
|     internal static Settings Settings => _Settings; |     internal static ILog? Log { get; private set; } | ||||||
|     internal static Dictionary<int, WorkItem> WorkItems => _WorkItems; |     internal static Settings? Settings { get; private set; } | ||||||
| #pragma warning disable IDE0032, CS8618 |     internal static Dictionary<int, WorkItem>? WorkItems { get; private set; } | ||||||
|     private static new ILog _Log; |     internal static Dictionary<string, Queue<KeyValuePair<string, WorkItem>>>? Queue { get; private set; } | ||||||
|     private static Settings _Settings; |  | ||||||
|     private static Dictionary<int, WorkItem> _WorkItems; |  | ||||||
| #pragma warning restore IDE0032, CS8618 |  | ||||||
|  |  | ||||||
|     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _WorkItems = new(); |         Queue = new(); | ||||||
|  |         WorkItems = new(); | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
|         _Logistics = new(this); |         _Logistics = new(this); | ||||||
|         _NullData = string.Empty; |         _NullData = string.Empty; | ||||||
|         _Log = LogManager.GetLogger(typeof(FileRead)); |         Log = LogManager.GetLogger(typeof(FileRead)); | ||||||
|         if (_FileParameter is null) |         if (_FileParameter is null) | ||||||
|             throw new Exception(cellInstanceConnectionName); |             throw new Exception(cellInstanceConnectionName); | ||||||
|         if (_ModelObjectParameterDefinitions is null) |         if (_ModelObjectParameterDefinitions is null) | ||||||
| @ -42,23 +42,29 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         if (_IsEAFHosted) |         if (_IsEAFHosted) | ||||||
|             NestExistingFiles(_FileConnectorConfiguration); |             NestExistingFiles(_FileConnectorConfiguration); | ||||||
|         string parentDirectory = Path.GetDirectoryName(_FileConnectorConfiguration.TargetFileLocation) ?? throw new Exception(); |         string parentDirectory = Path.GetDirectoryName(_FileConnectorConfiguration.TargetFileLocation) ?? throw new Exception(); | ||||||
|         _Settings = new(digits: 5, |         Settings = new(digits: 5, | ||||||
|                         parentDirectory: parentDirectory, |                         parentDirectory: parentDirectory, | ||||||
|                         priorities: 3, |                         priorities: 3, | ||||||
|                         priorityGroups: 9, |                         priorityGroups: 9, | ||||||
|                         sourceFileFilter: _FileConnectorConfiguration.SourceFileFilter, |                         sourceFileFilter: _FileConnectorConfiguration.SourceFileFilter, | ||||||
|                         sourceFileLocation: _FileConnectorConfiguration.SourceFileLocation, |                         sourceFileLocation: _FileConnectorConfiguration.SourceFileLocation, | ||||||
|                         targetFileLocation: _FileConnectorConfiguration.TargetFileLocation); |                         targetFileLocation: _FileConnectorConfiguration.TargetFileLocation); | ||||||
|         string? json = WeightedShortestJobFirstHub.PopulatedWorkItemsAndGetJson(_Settings); |         _Timer = new Timer(Callback, null, Timeout.Infinite, Timeout.Infinite); | ||||||
|         if (!string.IsNullOrEmpty(json)) |  | ||||||
|             WeightedShortestJobFirstHub.WriteJson(json); |  | ||||||
|         string cellInstanceNamed = string.Concat("CellInstance.", _EquipmentType); |         string cellInstanceNamed = string.Concat("CellInstance.", _EquipmentType); | ||||||
|         string url = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.Microsoft.Owin.Hosting.WebApp.Start.URL"); |         string url = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.Microsoft.Owin.Hosting.WebApp.Start.URL"); | ||||||
|         if (_IsEAFHosted) |         if (_IsEAFHosted) | ||||||
|         { |         { | ||||||
|             _ = Microsoft.Owin.Hosting.WebApp.Start(url); |             _ = Microsoft.Owin.Hosting.WebApp.Start<Startup>(url); | ||||||
|             _Log.Info($"Server running on {url}"); |             _Log.Info($"Server running on {url}"); | ||||||
|         } |         } | ||||||
|  |         if (Debugger.IsAttached || fileConnectorConfiguration.PreProcessingMode == FileConnectorConfiguration.PreProcessingModeEnum.Process) | ||||||
|  |             Callback(null); | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             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); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) => Move(extractResults); |     void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) => Move(extractResults); | ||||||
| @ -134,8 +140,36 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         string[] lines = new string[] { string.Empty, "NUM_DATA_ROWS", $"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); |         ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines); | ||||||
|         _Logistics = new Logistics(reportFullPath, processDataStandardFormat); |         _Logistics = new Logistics(reportFullPath, processDataStandardFormat); | ||||||
|         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; |         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) { } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @ -1,3 +1,5 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
| using System.Text.Json.Serialization; | using System.Text.Json.Serialization; | ||||||
|  |  | ||||||
| namespace Adaptation.FileHandlers.Priority; | namespace Adaptation.FileHandlers.Priority; | ||||||
| @ -9,15 +11,15 @@ public class Notification | |||||||
|  |  | ||||||
|     [JsonConstructor] |     [JsonConstructor] | ||||||
|     public Notification(int? fibonacci, |     public Notification(int? fibonacci, | ||||||
|                         int id, |                         string? id, | ||||||
|                         int? inverse, |                         int? inverse, | ||||||
|                         string? machineId, |                         string? machineId, | ||||||
|                         string page, |                         string page, | ||||||
|                         string? remoteIpAddress, |  | ||||||
|                         string? site, |                         string? site, | ||||||
|                         long time, |                         string? sessionId, | ||||||
|  |                         string time, | ||||||
|                         string? username, |                         string? username, | ||||||
|                         int value) |                         string? value) | ||||||
|     { |     { | ||||||
|         int? i = inverse is not null ? inverse : GetInverse(value); |         int? i = inverse is not null ? inverse : GetInverse(value); | ||||||
|         Fibonacci = fibonacci is not null ? fibonacci : i is null ? null : GetFibonacci(i.Value); |         Fibonacci = fibonacci is not null ? fibonacci : i is null ? null : GetFibonacci(i.Value); | ||||||
| @ -25,32 +27,78 @@ public class Notification | |||||||
|         Inverse = i; |         Inverse = i; | ||||||
|         MachineId = machineId; |         MachineId = machineId; | ||||||
|         Page = page; |         Page = page; | ||||||
|         RemoteIpAddress = remoteIpAddress is not null ? remoteIpAddress : null; |  | ||||||
|         Site = site is not null ? site : "MES"; |         Site = site is not null ? site : "MES"; | ||||||
|  |         SessionId = sessionId; | ||||||
|         Time = time; |         Time = time; | ||||||
|         Username = username; |         Username = username; | ||||||
|         Value = value; |         Value = value; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     [JsonPropertyName("id")] public int Id { get; } |     [JsonPropertyName("id")] public string? Id { get; } | ||||||
|     [JsonPropertyName("fibonacci")] public int? Fibonacci { get; } |     [JsonPropertyName("fibonacci")] public int? Fibonacci { get; } | ||||||
|     [JsonPropertyName("inverse")] public int? Inverse { get; } |     [JsonPropertyName("inverse")] public int? Inverse { get; } | ||||||
|     [JsonPropertyName("machineId")] public string? MachineId { get; } |     [JsonPropertyName("machineId")] public string? MachineId { get; } | ||||||
|     [JsonPropertyName("page")] public string Page { get; } |     [JsonPropertyName("page")] public string Page { get; } | ||||||
|     [JsonPropertyName("RemoteIpAddress")] public string? RemoteIpAddress { get; } |  | ||||||
|     [JsonPropertyName("site")] public string? Site { get; } |     [JsonPropertyName("site")] public string? Site { get; } | ||||||
|     [JsonPropertyName("time")] public long Time { get; } |     [JsonPropertyName("sessionId")] public string? SessionId { get; } | ||||||
|  |     [JsonPropertyName("time")] public string Time { get; } | ||||||
|     [JsonPropertyName("username")] public string? Username { get; } |     [JsonPropertyName("username")] public string? Username { get; } | ||||||
|     [JsonPropertyName("value")] public int Value { get; } |     [JsonPropertyName("value")] public string? Value { get; } | ||||||
|  |  | ||||||
|     internal static int? GetInverse(int value) => |     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 |         value switch | ||||||
|         { |         { | ||||||
|             1 => 5, |             "1" => 5, | ||||||
|             2 => 4, |             "2" => 4, | ||||||
|             3 => 3, |             "3" => 3, | ||||||
|             4 => 2, |             "4" => 2, | ||||||
|             5 => 1, |             "5" => 1, | ||||||
|             _ => null |             _ => null | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
| @ -69,18 +117,6 @@ public class Notification | |||||||
|             _ => null |             _ => null | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|     internal static Notification GetNotification(Notification notification, string? remoteIpAddress, string? connectionId) => |  | ||||||
|         new(notification.Fibonacci, |  | ||||||
|             notification.Id, |  | ||||||
|             notification.Inverse, |  | ||||||
|             notification.MachineId, |  | ||||||
|             notification.Page, |  | ||||||
|             remoteIpAddress ?? connectionId, |  | ||||||
|             notification.Site, |  | ||||||
|             notification.Time, |  | ||||||
|             notification.Username, |  | ||||||
|             notification.Value); |  | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| [JsonSourceGenerationOptions(WriteIndented = true)] | [JsonSourceGenerationOptions(WriteIndented = true)] | ||||||
|  | |||||||
| @ -1,4 +1,5 @@ | |||||||
| using Microsoft.Owin.Cors; | using Microsoft.Owin.Cors; | ||||||
|  | using Nancy.Owin; | ||||||
| using Owin; | using Owin; | ||||||
|  |  | ||||||
| public class Startup | public class Startup | ||||||
| @ -7,7 +8,7 @@ public class Startup | |||||||
|     public void Configuration(IAppBuilder app) |     public void Configuration(IAppBuilder app) | ||||||
|     { |     { | ||||||
|         _ = app.UseCors(CorsOptions.AllowAll); |         _ = app.UseCors(CorsOptions.AllowAll); | ||||||
|         _ = app.MapSignalR(); |         _ = app.UseNancy(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
| @ -1,158 +0,0 @@ | |||||||
| using System; |  | ||||||
| using System.Collections.Generic; |  | ||||||
| using System.Collections.ObjectModel; |  | ||||||
| using System.IO; |  | ||||||
| using System.Linq; |  | ||||||
| using System.Text.Json; |  | ||||||
|  |  | ||||||
| #nullable enable |  | ||||||
|  |  | ||||||
| namespace Adaptation.FileHandlers.Priority; |  | ||||||
|  |  | ||||||
| public class WeightedShortestJobFirstHub : Microsoft.AspNet.SignalR.Hub |  | ||||||
| { |  | ||||||
|  |  | ||||||
|     // public async Task Send(int n) |  | ||||||
|     // { |  | ||||||
|     //     await Clients.All.send(n); |  | ||||||
|     // } |  | ||||||
|  |  | ||||||
|     private string? GetRemoteIpAddress() => |  | ||||||
|         Context?.Headers?.Get("X-Real-IP"); |  | ||||||
|  |  | ||||||
|     public void Send(string name, string message) |  | ||||||
|     { |  | ||||||
|         Console.WriteLine($"{name}:{message};"); |  | ||||||
|         // FileRead.Logger.LogWarning($"{name}:{message};"); |  | ||||||
|         // FileRead.Log?.Info($"{name}:{message};"); |  | ||||||
|         Console.WriteLine(Context?.ConnectionId); |  | ||||||
|         // FileRead.Logger.LogWarning(Context?.ConnectionId); |  | ||||||
|         // FileRead.Log?.Info(Context?.ConnectionId); |  | ||||||
|         string? remoteIpAddress = GetRemoteIpAddress(); |  | ||||||
|         Console.WriteLine(remoteIpAddress); |  | ||||||
|         // FileRead.Logger.LogWarning(remoteIpAddress); |  | ||||||
|         // FileRead.Log?.Info(remoteIpAddress); |  | ||||||
|         Clients.All.addMessage(name, message); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static void FileWriteAllText(Settings settings, Notification n) |  | ||||||
|     { |  | ||||||
|         string json = JsonSerializer.Serialize(n, NotificationSourceGenerationContext.Default.Notification); |  | ||||||
|         string directory = Path.Combine(settings.SourceFileLocation, n.Page, n.Id.ToString()); |  | ||||||
|         if (!Directory.Exists(directory)) |  | ||||||
|             _ = Directory.CreateDirectory(directory); |  | ||||||
|         string checkFile = Path.Combine(directory, $"{n.Time}.json"); |  | ||||||
|         File.WriteAllText(checkFile, json); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     internal static void WriteJson(string json) |  | ||||||
|     { |  | ||||||
|         string jsonFile = Path.Combine(FileRead.Settings.ParentDirectory, "{}.json"); |  | ||||||
|         string jsonFileWith = Path.Combine(FileRead.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); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     internal static string? PopulatedWorkItemsAndGetJson(Settings settings) |  | ||||||
|     { |  | ||||||
|         string? result = null; |  | ||||||
|         ReadOnlyDictionary<int, WorkItem?> workItems = WorkItem.GetKeyValuePairs(settings); |  | ||||||
|         int useCount = (from l in workItems 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 workItems |  | ||||||
|                              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 (FileRead.WorkItems) |  | ||||||
|         { |  | ||||||
|             int j = 0; |  | ||||||
|             WorkItem w; |  | ||||||
|             double value; |  | ||||||
|             int lastId = -1; |  | ||||||
|             int? sortBeforeId; |  | ||||||
|             WorkItem workItem; |  | ||||||
|             int? sortPriority; |  | ||||||
|             int? sortPriorityGroup; |  | ||||||
|             FileRead.WorkItems.Clear(); |  | ||||||
|             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); |  | ||||||
|                 FileRead.WorkItems.Add(workItem.Id, workItem); |  | ||||||
|                 lastId = w.Id; |  | ||||||
|             } |  | ||||||
|             result = JsonSerializer.Serialize(FileRead.WorkItems, WorkItemDictionarySourceGenerationContext.Default.DictionaryInt32WorkItem); |  | ||||||
|         } |  | ||||||
|         return result; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private static WorkItem GetWorkItem(Notification notification) |  | ||||||
|     { |  | ||||||
|         WorkItem? result; |  | ||||||
|         lock (FileRead.WorkItems) |  | ||||||
|         { |  | ||||||
|             if (!FileRead.WorkItems.TryGetValue(notification.Id, out result)) |  | ||||||
|                 throw new Exception(); |  | ||||||
|         } |  | ||||||
|         return result; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void NotifyAll(Notification notification) |  | ||||||
|     { |  | ||||||
|         try |  | ||||||
|         { |  | ||||||
|             string? json = null; |  | ||||||
|             string? remoteIpAddress = GetRemoteIpAddress(); |  | ||||||
|             Notification n = Notification.GetNotification(notification, remoteIpAddress, Context?.ConnectionId); |  | ||||||
|             Console.WriteLine(n.ToString()); |  | ||||||
|             // FileRead.Logger.LogWarning(n.ToString()); |  | ||||||
|             // FileRead.Log?.Info(n.ToString()); |  | ||||||
|             FileWriteAllText(FileRead.Settings, n); |  | ||||||
|             json = PopulatedWorkItemsAndGetJson(FileRead.Settings); |  | ||||||
|             if (!string.IsNullOrEmpty(json)) |  | ||||||
|                 WriteJson(json); |  | ||||||
|             if (!string.IsNullOrEmpty(n.RemoteIpAddress)) |  | ||||||
|             { |  | ||||||
|                 WorkItem workItem = GetWorkItem(n); |  | ||||||
|                 Clients.All.updateWorkItem(n.Page, workItem); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         catch (Exception ex) |  | ||||||
|         { Console.WriteLine($"{ex.Message}{Environment.NewLine}{ex.StackTrace}"); } |  | ||||||
|         // { FileRead.Logger.LogError(ex, "Error!"); } |  | ||||||
|         // { FileRead.Log?.Error("Error!", ex); } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @ -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); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -203,3 +203,9 @@ public class WorkItem | |||||||
| internal partial class WorkItemDictionarySourceGenerationContext : JsonSerializerContext | internal partial class WorkItemDictionarySourceGenerationContext : JsonSerializerContext | ||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | [JsonSourceGenerationOptions(WriteIndented = true)] | ||||||
|  | [JsonSerializable(typeof(KeyValuePair<string, WorkItem>))] | ||||||
|  | internal partial class KeyValuePairStringWorkItemSourceGenerationContext : JsonSerializerContext | ||||||
|  | { | ||||||
|  | } | ||||||
| @ -17,7 +17,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|     private readonly string _JobIdParentDirectory; |     private readonly string _JobIdParentDirectory; | ||||||
|     private readonly string _JobIdProcessParentDirectory; |     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) : |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
| @ -140,6 +140,30 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         // File.WriteAllText(jsonFileName, json); |         // File.WriteAllText(jsonFileName, json); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private static void MoveMatchingFile(string jobIdDirectory, string matchDirectory) | ||||||
|  |     { | ||||||
|  |         string checkFile; | ||||||
|  |         string jobIdDirectoryFileName; | ||||||
|  |         string matchDirectoryFileName; | ||||||
|  |         string[] jobIdDirectoryFiles = Directory.GetFiles(jobIdDirectory, "*", SearchOption.TopDirectoryOnly); | ||||||
|  |         string[] matchDirectoryFiles = Directory.GetFiles(matchDirectory, "*", SearchOption.TopDirectoryOnly); | ||||||
|  |         foreach (string jobIdDirectoryFile in jobIdDirectoryFiles) | ||||||
|  |         { | ||||||
|  |             jobIdDirectoryFileName = Path.GetFileName(jobIdDirectoryFile); | ||||||
|  |             foreach (string matchDirectoryFile in matchDirectoryFiles) | ||||||
|  |             { | ||||||
|  |                 matchDirectoryFileName = Path.GetFileName(matchDirectoryFile); | ||||||
|  |                 if (jobIdDirectoryFileName.StartsWith(matchDirectoryFileName)) | ||||||
|  |                 { | ||||||
|  |                     checkFile = Path.Combine(matchDirectory, jobIdDirectoryFileName); | ||||||
|  |                     if (File.Exists(checkFile)) | ||||||
|  |                         continue; | ||||||
|  |                     File.Move(jobIdDirectoryFile, checkFile); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime) |     private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime) | ||||||
|     { |     { | ||||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; |         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||||
| @ -149,7 +173,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat); |         JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat); | ||||||
|         List<Description> descriptions = json.ProcessData.GetDescriptions(jsonElements); |         List<Description> descriptions = json.ProcessData.GetDescriptions(jsonElements); | ||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             DirectoryMove(reportFullPath, dateTime, descriptions); |             DirectoryMove(reportFullPath, dateTime, descriptions); | ||||||
|         else if (!_IsEAFHosted) |         else if (!_IsEAFHosted) | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ namespace Adaptation.FileHandlers.SPaCe; | |||||||
| public class FileRead : Shared.FileRead, IFileRead | 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) : |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
| @ -125,7 +125,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); |         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             FileCopy(reportFullPath, dateTime, descriptions); |             FileCopy(reportFullPath, dateTime, descriptions); | ||||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>()); |         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics), tests, jsonElements, new List<FileInfo>()); | ||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|     private readonly string _URL; |     private readonly string _URL; | ||||||
|     private readonly ReadOnlyCollection<string> _WorkItemTypes; |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
|  | |||||||
| @ -30,6 +30,17 @@ public class ProcessData : IProcessData | |||||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IProcessData.GetResults(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection) => |     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); |         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) |     public ProcessData(IFileRead fileRead, Logistics logistics, string targetFileLocation, string url, ReadOnlyCollection<string> workItemTypes, List<FileInfo> fileInfoCollection) | ||||||
|     { |     { | ||||||
|         if (fileRead.IsEAFHosted) |         if (fileRead.IsEAFHosted) | ||||||
| @ -66,8 +77,6 @@ public class ProcessData : IProcessData | |||||||
|         ReadOnlyCollection<Record> results; |         ReadOnlyCollection<Record> results; | ||||||
|         ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations); |         ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations); | ||||||
|         ReadOnlyCollection<Record> records = new(keyValuePairs.Values.ToArray()); |         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> bugUserStoryWorkItemTypes = new(new string[] { "Bug", "User Story" }); | ||||||
|         ReadOnlyCollection<string> bugUserStoryTaskWorkItemTypes = new(new string[] { "Bug", "User Story", "Task" }); |         ReadOnlyCollection<string> bugUserStoryTaskWorkItemTypes = new(new string[] { "Bug", "User Story", "Task" }); | ||||||
|         { |         { | ||||||
| @ -124,15 +133,6 @@ public class ProcessData : IProcessData | |||||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-122517"); |             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-122517"); | ||||||
|             _Details.Add(results); |             _Details.Add(results); | ||||||
|         } |         } | ||||||
|         { |  | ||||||
|             lines.Clear(); |  | ||||||
|             string workItemType = "User Story"; |  | ||||||
|             lines.Add($"# {nameof(UserStoryCheckIterationPath228385)}"); |  | ||||||
|             lines.Add(string.Empty); |  | ||||||
|             results = UserStoryCheckIterationPath228385(url, lines, userStoryWorkItemTypes, keyValuePairs, workItemType); |  | ||||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-228385"); |  | ||||||
|             _Details.Add(results); |  | ||||||
|         } |  | ||||||
|         if (messages.Count > 0) |         if (messages.Count > 0) | ||||||
|             throw new Exception($"{messages.Count}{Environment.NewLine}{string.Join(Environment.NewLine, messages)}"); |             throw new Exception($"{messages.Count}{Environment.NewLine}{string.Join(Environment.NewLine, messages)}"); | ||||||
|     } |     } | ||||||
| @ -173,7 +173,8 @@ public class ProcessData : IProcessData | |||||||
|             } |             } | ||||||
|             catch (Exception) |             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); |             results.Add(keyValuePair.Key, record); | ||||||
|         } |         } | ||||||
| @ -474,17 +475,6 @@ public class ProcessData : IProcessData | |||||||
|         return new(results); |         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 ReadOnlyCollection<Record> FeatureCheckState123067(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) |     private static ReadOnlyCollection<Record> FeatureCheckState123067(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||||
|     { |     { | ||||||
|         List<Record> results = new(); |         List<Record> results = new(); | ||||||
| @ -621,71 +611,6 @@ public class ProcessData : IProcessData | |||||||
|         return new(results); |         return new(results); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static ReadOnlyCollection<Record> UserStoryCheckIterationPath228385(string url, List<string> lines, ReadOnlyCollection<string> _, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) |  | ||||||
|     { |  | ||||||
|         List<Record> results = new(); |  | ||||||
|         long totalStoryPoints; |  | ||||||
|         ReadOnlyDictionary<string, List<Record>> records = GetWorkItemsMatching228385(keyValuePairs, workItemType); |  | ||||||
|         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 ReadOnlyDictionary<string, List<Record>> GetWorkItemsMatching228385(ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) |  | ||||||
|     { |  | ||||||
|         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 = records.OrderByDescending(l => l.WorkItem.IterationPath).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; |  | ||||||
|         List<Record>? collection; |  | ||||||
|         foreach (Record record in records) |  | ||||||
|         { |  | ||||||
|             key = $"{record.WorkItem.IterationPath}-{record.WorkItem.AssignedTo}"; |  | ||||||
|             if (!results.TryGetValue(key, out collection)) |  | ||||||
|             { |  | ||||||
|                 results.Add(key, new()); |  | ||||||
|                 if (!results.TryGetValue(key, out collection)) |  | ||||||
|                     throw new Exception(); |  | ||||||
|             } |  | ||||||
|             collection.Add(record); |  | ||||||
|         } |  | ||||||
|         return new(results); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     internal static List<Description> GetDescriptions(JsonElement[] jsonElements) |     internal static List<Description> GetDescriptions(JsonElement[] jsonElements) | ||||||
|     { |     { | ||||||
|         List<Description> results = new(); |         List<Description> results = new(); | ||||||
|  | |||||||
| @ -23,7 +23,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|  |  | ||||||
|     private readonly Timer _Timer; |     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) |         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||||
|     { |     { | ||||||
|         _MinFileLength = 10; |         _MinFileLength = 10; | ||||||
| @ -363,7 +363,7 @@ public class FileRead : Shared.FileRead, IFileRead | |||||||
|         _Logistics = new Logistics(reportFullPath, processDataStandardFormat); |         _Logistics = new Logistics(reportFullPath, processDataStandardFormat); | ||||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) |         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||||
|             MoveJson(reportFullPath, dateTime); |             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; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -6,15 +6,15 @@ | |||||||
|     <meta name="viewport" content="width=device-width" /> |     <meta name="viewport" content="width=device-width" /> | ||||||
|     <title>Infineon - 122508 - Feature iteration should be set to max of children</title> |     <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="/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-01-22-10-49" 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-01-22-10-49" 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" /> |     <link href="/styles/122508.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" type="text/javascript"></script> |     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
| <body> | <body> | ||||||
| @ -56,7 +56,7 @@ | |||||||
|     <script> |     <script> | ||||||
|  |  | ||||||
|         $(document).ready(function () { |         $(document).ready(function () { | ||||||
|             initIndex("/markdown/check-122508.json?v=2025-01-22-10-49"); |             initIndex("/markdown/check-122508.json?v=2025-04-14-08-10"); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|     </script> |     </script> | ||||||
|  | |||||||
| @ -6,15 +6,15 @@ | |||||||
|     <meta name="viewport" content="width=device-width" /> |     <meta name="viewport" content="width=device-width" /> | ||||||
|     <title>Infineon - 122514 - Features and children must have a Tag</title> |     <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="/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-01-22-10-49" 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-01-22-10-49" 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" /> |     <link href="/styles/122514.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" type="text/javascript"></script> |     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
| <body> | <body> | ||||||
| @ -56,7 +56,7 @@ | |||||||
|     <script> |     <script> | ||||||
|  |  | ||||||
|         $(document).ready(function () { |         $(document).ready(function () { | ||||||
|             initIndex("/markdown/check-122514.json?v=2025-01-22-10-49"); |             initIndex("/markdown/check-122514.json?v=2025-04-14-08-10"); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|     </script> |     </script> | ||||||
|  | |||||||
| @ -6,15 +6,15 @@ | |||||||
|     <meta name="viewport" content="width=device-width" /> |     <meta name="viewport" content="width=device-width" /> | ||||||
|     <title>Infineon - 122517 - Feature start date should be min activated date of children</title> |     <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="/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-01-22-10-49" 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-01-22-10-49" 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" /> |     <link href="/styles/122517.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" type="text/javascript"></script> |     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
| <body> | <body> | ||||||
| @ -56,7 +56,7 @@ | |||||||
|     <script> |     <script> | ||||||
|  |  | ||||||
|         $(document).ready(function () { |         $(document).ready(function () { | ||||||
|             initIndex("/markdown/check-122517.json?v=2025-01-22-10-49"); |             initIndex("/markdown/check-122517.json?v=2025-04-14-08-10"); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|     </script> |     </script> | ||||||
|  | |||||||
| @ -6,15 +6,15 @@ | |||||||
|     <meta name="viewport" content="width=device-width" /> |     <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> |     <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="/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-01-22-10-49" 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-01-22-10-49" 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" /> |     <link href="/styles/123066.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" type="text/javascript"></script> |     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
| <body> | <body> | ||||||
| @ -56,7 +56,7 @@ | |||||||
|     <script> |     <script> | ||||||
|  |  | ||||||
|         $(document).ready(function () { |         $(document).ready(function () { | ||||||
|             initIndex("/markdown/check-123066.json?v=2025-01-22-10-49"); |             initIndex("/markdown/check-123066.json?v=2025-04-14-08-10"); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|     </script> |     </script> | ||||||
|  | |||||||
| @ -6,15 +6,15 @@ | |||||||
|     <meta name="viewport" content="width=device-width" /> |     <meta name="viewport" content="width=device-width" /> | ||||||
|     <title>Infineon - 123067 - WIP</title> |     <title>Infineon - 123067 - WIP</title> | ||||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> |     <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-01-22-10-49" 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-01-22-10-49" 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" /> |     <link href="/styles/123067.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" type="text/javascript"></script> |     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
| <body> | <body> | ||||||
| @ -56,7 +56,7 @@ | |||||||
|     <script> |     <script> | ||||||
|  |  | ||||||
|         $(document).ready(function () { |         $(document).ready(function () { | ||||||
|             initIndex("/markdown/check-123067.json?v=2025-01-22-10-49"); |             initIndex("/markdown/check-123067.json?v=2025-04-14-08-10"); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|     </script> |     </script> | ||||||
|  | |||||||
| @ -6,15 +6,15 @@ | |||||||
|     <meta name="viewport" content="width=device-width" /> |     <meta name="viewport" content="width=device-width" /> | ||||||
|     <title>Infineon - 126169 - Children of a Feature should have the same priority</title> |     <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="/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-01-22-10-49" 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-01-22-10-49" 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" /> |     <link href="/styles/126169.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" type="text/javascript"></script> |     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
| <body> | <body> | ||||||
| @ -56,7 +56,7 @@ | |||||||
|     <script> |     <script> | ||||||
|  |  | ||||||
|         $(document).ready(function () { |         $(document).ready(function () { | ||||||
|             initIndex("/markdown/check-126169.json?v=2025-01-22-10-49"); |             initIndex("/markdown/check-126169.json?v=2025-04-14-08-10"); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|     </script> |     </script> | ||||||
|  | |||||||
| @ -6,15 +6,15 @@ | |||||||
|     <meta name="viewport" content="width=device-width" /> |     <meta name="viewport" content="width=device-width" /> | ||||||
|     <title>Infineon - Business Value</title> |     <title>Infineon - Business Value</title> | ||||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> |     <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-01-22-10-49" 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-01-22-10-49" 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" /> |     <link href="/styles/business.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" type="text/javascript"></script> |     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
| <body> | <body> | ||||||
| @ -59,7 +59,7 @@ What is the relative value to the Customer or business? | |||||||
|     <script> |     <script> | ||||||
|  |  | ||||||
|         $(document).ready(function () { |         $(document).ready(function () { | ||||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2025-01-22-10-49", "https://eaf-dev.mes.infineon.com/api/v1/ado/", "business", "Value", "Business Value", "/markdown/PI5-Results/business.json?v=2025-01-22-10-49"); |             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> |     </script> | ||||||
|  | |||||||
| @ -9,8 +9,7 @@ | |||||||
|     <link href="/styles/cod.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-1.6.4.min.js"></script> | ||||||
|     <script src="/js/scripts/jquery.signalR-2.4.3.min.js"></script> |     <script src="/js/scripts/jquery.signalR-2.4.3.min.js"></script> | ||||||
|     <script src="/signalr/hubs"></script> |     <script src="/js/cod-1-122-0.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||||
|     <script src="/js/cod-b.js?v=2025-01-22-10-49" type="text/javascript"></script> |  | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
| <body> | <body> | ||||||
| @ -54,51 +53,53 @@ | |||||||
|     <script> |     <script> | ||||||
|  |  | ||||||
|         $(document).ready(function () { |         $(document).ready(function () { | ||||||
|             const username = ''; |  | ||||||
|             const machineId = ''; |  | ||||||
|             const fromHtml = true; |             const fromHtml = true; | ||||||
|             const signalRUrl = "/signalr"; |             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 windowLocationHRef = window.location.href; | ||||||
|             const apiUrl = "https://eaf-dev.mes.infineon.com/api/v1/ado/"; |             const signalRUrl = baseUri + '/signalr'; | ||||||
|             const workItems = { |             const workItems = { | ||||||
|                 a: "/markdown/bugs-features-with-parents.json?v=2025-01-22-10-49", |                 a: baseUri + '/markdown/bugs-features-with-parents.json?v=2025-04-14-08-10', | ||||||
|                 b: "/markdown/{[]}.json?v=2025-01-22-10-49" |                 b: baseUri + '/markdown/{[]}.json?v=2025-04-14-08-10', | ||||||
|  |                 timeout: 3000, | ||||||
|             }; |             }; | ||||||
|             const b = { |             const b = { | ||||||
|                 page: "business", |                 page: 'business', | ||||||
|                 description: "Value", |                 description: 'Value', | ||||||
|                 th: "Business 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?" |                 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 = { |             const r = { | ||||||
|                 page: "risk", |                 page: 'risk', | ||||||
|                 description: "Risk", |                 description: 'Risk', | ||||||
|                 th: "Risk Reduction and/or Opportunity Enablement", |                 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?" |                 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 = { |             const t = { | ||||||
|                 page: "time", |                 page: 'time', | ||||||
|                 description: "Critical", |                 description: 'Critical', | ||||||
|                 th: "Time Criticality", |                 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?" |                 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 = { |             const c = { | ||||||
|                 page: "cod", |                 page: 'cod', | ||||||
|                 description: "CoD", |                 description: 'CoD', | ||||||
|                 th: "Cost of Delay (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." |                 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 = { |             const e = { | ||||||
|                 page: "effort", |                 page: 'effort', | ||||||
|                 description: "Effort", |                 description: 'Effort', | ||||||
|                 th: "Effort", |                 th: 'Effort', | ||||||
|                 span: "Effort" |                 span: 'Effort' | ||||||
|             }; |             }; | ||||||
|             const w = { |             const w = { | ||||||
|                 page: "wsjf", |                 page: 'wsjf', | ||||||
|                 description: "WSJF", |                 description: 'WSJF', | ||||||
|                 th: "Weightest Shortest Job First calculation (WSJF)", |                 th: 'Weightest Shortest Job First calculation (WSJF)', | ||||||
|                 span: "Weightest Shortest Job First calculation (see @SCALE formula)" |                 span: 'Weightest Shortest Job First calculation (see @SCALE formula)' | ||||||
|             }; |             }; | ||||||
|             initIndex(fromHtml, username, machineId, windowLocationHRef, workItems, b, r, t, c, e, w, apiUrl, signalRUrl); |             initIndex(fromHtml, username, machineId, windowLocationHRef, workItems, b, r, t, c, e, w, apiUrl, signalRUrl); | ||||||
|         }); |         }); | ||||||
|  | |||||||
| @ -1,97 +0,0 @@ | |||||||
| <!DOCTYPE html> |  | ||||||
| <html> |  | ||||||
|  |  | ||||||
| <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="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" /> |  | ||||||
|     <link href="/igniteui/css/structure/infragistics.css?v=2025-01-22-10-49" rel="stylesheet" /> |  | ||||||
|     <link href="/styles/cod.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> |  | ||||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-01-22-10-49" type="text/javascript"></script> |  | ||||||
|     <script src="/js/jquery-ui.min.js?v=2025-01-22-10-49" type="text/javascript"></script> |  | ||||||
|     <script src="/js/scripts/jquery.signalR-2.4.3.min.js"></script> |  | ||||||
|     <script src="/signalr/hubs"></script> |  | ||||||
|     <script src="/js/cod.js?v=2025-01-22-10-49" type="text/javascript"></script> |  | ||||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-01-22-10-49" type="text/javascript"></script> |  | ||||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-01-22-10-49" type="text/javascript"></script> |  | ||||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-01-22-10-49" 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> - Cost of Delay (CoD) (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 id="HeaderGridDiv"> |  | ||||||
|             <table id="HeaderGrid" border="1"></table> |  | ||||||
|         </div> |  | ||||||
|  |  | ||||||
|         <br />  |  | ||||||
|  |  | ||||||
|         <div id="AllGridDiv"> |  | ||||||
|             <table id="AllGrid"></table> |  | ||||||
|         </div> |  | ||||||
|     </div> |  | ||||||
|  |  | ||||||
|     <script> |  | ||||||
|  |  | ||||||
|         $(document).ready(function () { |  | ||||||
|             const fromHtml = true; |  | ||||||
|             const windowLocationHRef = window.location.href; |  | ||||||
|             const headerGrid = document.getElementById("HeaderGrid"); |  | ||||||
|             const workItems = { |  | ||||||
|                 a: "/markdown/bugs-features-with-parents.json?v=2025-01-22-10-49", |  | ||||||
|                 b: "/markdown/{}.json?v=2025-01-22-10-49" |  | ||||||
|             }; |  | ||||||
|             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." |  | ||||||
|             }; |  | ||||||
|             initIndex(fromHtml, windowLocationHRef, headerGrid, workItems, b, r, t, c, "https://eaf-dev.mes.infineon.com/api/v1/ado/"); |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|     </script> |  | ||||||
| </body> |  | ||||||
|  |  | ||||||
| </html> |  | ||||||
| @ -6,15 +6,15 @@ | |||||||
|     <meta name="viewport" content="width=device-width" /> |     <meta name="viewport" content="width=device-width" /> | ||||||
|     <title>Infineon - Effort</title> |     <title>Infineon - Effort</title> | ||||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> |     <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-01-22-10-49" 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-01-22-10-49" 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" /> |     <link href="/styles/effort.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" type="text/javascript"></script> |     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
| <body> | <body> | ||||||
| @ -55,7 +55,7 @@ | |||||||
|     <script> |     <script> | ||||||
|  |  | ||||||
|         $(document).ready(function () { |         $(document).ready(function () { | ||||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2025-01-22-10-49", "https://eaf-dev.mes.infineon.com/api/v1/ado/", "effort", "Effort", "Effort", "/markdown/PI5-Results/effort.json?v=2025-01-22-10-49"); |             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> |     </script> | ||||||
|  | |||||||
| @ -6,15 +6,15 @@ | |||||||
|     <meta name="viewport" content="width=device-width" /> |     <meta name="viewport" content="width=device-width" /> | ||||||
|     <title>Infineon - Risk Reduction and/or Opportunity Enablement</title> |     <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="/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-01-22-10-49" 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-01-22-10-49" 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" /> |     <link href="/styles/risk.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" type="text/javascript"></script> |     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
| <body> | <body> | ||||||
| @ -59,7 +59,7 @@ What else does this do for our business? | |||||||
|     <script> |     <script> | ||||||
|  |  | ||||||
|         $(document).ready(function () { |         $(document).ready(function () { | ||||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2025-01-22-10-49", "https://eaf-dev.mes.infineon.com/api/v1/ado/", "risk", "Risk", "Risk Reduction and/or Opportunity Enablement", "/markdown/PI5-Results/risk.json?v=2025-01-22-10-49"); |             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> |     </script> | ||||||
|  | |||||||
| @ -21,7 +21,7 @@ | |||||||
|     <script src="/js/scripts/jquery-1.6.4.min.js"></script> |     <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/scripts/jquery.signalR-2.4.3.min.js"></script> | ||||||
|     <script src="/signalr/hubs"></script> |     <script src="/signalr/hubs"></script> | ||||||
|     <script src="/js/wsjf-c.js?v=2025-01-22-10-49" type="text/javascript"></script> |     <script src="/js/simple.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||||
| 
 | 
 | ||||||
|     <script> |     <script> | ||||||
| 
 | 
 | ||||||
| @ -6,15 +6,15 @@ | |||||||
|     <meta name="viewport" content="width=device-width" /> |     <meta name="viewport" content="width=device-width" /> | ||||||
|     <title>Infineon - Time Criticality</title> |     <title>Infineon - Time Criticality</title> | ||||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> |     <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-01-22-10-49" 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-01-22-10-49" 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" /> |     <link href="/styles/time.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" type="text/javascript"></script> |     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
| <body> | <body> | ||||||
| @ -59,7 +59,7 @@ How does user/business value decay over time? | |||||||
|     <script> |     <script> | ||||||
|  |  | ||||||
|         $(document).ready(function () { |         $(document).ready(function () { | ||||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2025-01-22-10-49", "https://eaf-dev.mes.infineon.com/api/v1/ado/", "time", "Critical", "Time Criticality", "/markdown/PI5-Results/time.json?v=2025-01-22-10-49"); |             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> |     </script> | ||||||
|  | |||||||
| @ -6,15 +6,15 @@ | |||||||
|     <meta name="viewport" content="width=device-width" /> |     <meta name="viewport" content="width=device-width" /> | ||||||
|     <title>Infineon - User Stor(ies) with parents</title> |     <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="/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-01-22-10-49" 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-01-22-10-49" 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" /> |     <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=2025-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" type="text/javascript"></script> |     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
| <body> | <body> | ||||||
| @ -55,7 +55,7 @@ | |||||||
|     <script> |     <script> | ||||||
|  |  | ||||||
|         $(document).ready(function () { |         $(document).ready(function () { | ||||||
|             initIndex("/markdown/bugs-user-stories-with-parents.json?v=2025-01-22-10-49"); |             initIndex("/markdown/bugs-user-stories-with-parents.json?v=2025-04-14-08-10"); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|     </script> |     </script> | ||||||
|  | |||||||
| @ -6,15 +6,15 @@ | |||||||
|     <meta name="viewport" content="width=device-width" /> |     <meta name="viewport" content="width=device-width" /> | ||||||
|     <title>Infineon - Result of Weightest Shortest Job First calculation (see @SCALE formula)</title> |     <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="/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-01-22-10-49" 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-01-22-10-49" 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" /> |     <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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" type="text/javascript"></script> |     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
| <body> | <body> | ||||||
| @ -55,7 +55,7 @@ | |||||||
|     <script> |     <script> | ||||||
|  |  | ||||||
|         $(document).ready(function () { |         $(document).ready(function () { | ||||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2025-01-22-10-49", "https://eaf-dev.mes.infineon.com/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> |     </script> | ||||||
|  | |||||||
| @ -6,15 +6,15 @@ | |||||||
|     <meta name="viewport" content="width=device-width" /> |     <meta name="viewport" content="width=device-width" /> | ||||||
|     <title>Infineon - Result of Weightest Shortest Job First calculation (see @SCALE formula)</title> |     <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="/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-01-22-10-49" 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-01-22-10-49" 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" /> |     <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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" 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-01-22-10-49" type="text/javascript"></script> |     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||||
| </head> | </head> | ||||||
|  |  | ||||||
| <body> | <body> | ||||||
| @ -55,7 +55,7 @@ | |||||||
|     <script> |     <script> | ||||||
|  |  | ||||||
|         $(document).ready(function () { |         $(document).ready(function () { | ||||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=2025-01-22-10-49", "https://eaf-dev.mes.infineon.com/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> |     </script> | ||||||
|  | |||||||
							
								
								
									
										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 | ||||||
							
								
								
									
										433
									
								
								Adaptation/FileHandlers/json/StaticSite/js/cod-1-123-0-.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										433
									
								
								Adaptation/FileHandlers/json/StaticSite/js/cod-1-123-0-.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,433 @@ | |||||||
|  | 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: any, b: any) { | ||||||
|  |     return a.SortOrder - b.SortOrder; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function compareFunctionParentId(a: any, b: any) { | ||||||
|  |     return a.ParentId - b.ParentId || a.Id - b.Id; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function compareFunctionWeightedShortestJobFirst(a: any, b: any) { | ||||||
|  |     if (b.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 weightedShortestJobFirst = workItem.WeightedShortestJobFirst.toFixed(2); | ||||||
|  |             let riskReductionMinusOpportunityEnablement = workItem.RiskReductionMinusOpportunityEnablement; | ||||||
|  |             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; | ||||||
|  |             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} ${weightedShortestJobFirst} != ${workItem.WeightedShortestJobFirst} | ||||||
|  |  | ||||||
|  |                 patch {{Factory-Integration}}/_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}" | ||||||
|  |                     } | ||||||
|  |                 ]`; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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('=WSJF') > -1) { | ||||||
|  |         records.sort(compareFunctionWeightedShortestJobFirst); | ||||||
|  |     } | ||||||
|  |     else if (_windowLocationHRef.indexOf('=LIVE') > -1) { | ||||||
|  |         records.sort(compareFunctionSortOrder); | ||||||
|  |     } | ||||||
|  |     else { | ||||||
|  |         records.sort(compareFunctionParentId); | ||||||
|  |     } | ||||||
|  |     return records; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function getHtmlTextAndHttp(fromHtml: any, b: any, r: any, t: any, c: any, e: any, w: any, records: any) { | ||||||
|  |     let record; | ||||||
|  |     let http = ''; | ||||||
|  |     let lineA = ''; | ||||||
|  |     let lineB = ''; | ||||||
|  |     let lineC = ''; | ||||||
|  |     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 !== '') { | ||||||
|  |             http += 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, http }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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 = getHtmlTextAndHttp(fromHtml, b, r, t, c, e, w, records); | ||||||
|  |                 if (result == undefined) { } | ||||||
|  |             }) | ||||||
|  |             .catch((e) => console.error(e)); | ||||||
|  |     }) | ||||||
|  |     .catch((e) => console.error(e)); | ||||||
							
								
								
									
										671
									
								
								Adaptation/FileHandlers/json/StaticSite/js/cod-1-123-0.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										671
									
								
								Adaptation/FileHandlers/json/StaticSite/js/cod-1-123-0.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,671 @@ | |||||||
|  | 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 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 weightedShortestJobFirst = workItem.WeightedShortestJobFirst.toFixed(2); | ||||||
|  |             let riskReductionMinusOpportunityEnablement = workItem.RiskReductionMinusOpportunityEnablement; | ||||||
|  |             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; | ||||||
|  |             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} ${weightedShortestJobFirst} != ${workItem.WeightedShortestJobFirst} | ||||||
|  |  | ||||||
|  |                 patch {{Factory-Integration}}/_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}" | ||||||
|  |                     } | ||||||
|  |                 ]`; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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 getHtmlTextAndHttp(fromHtml, b, r, t, c, e, w, records) { | ||||||
|  |     let record; | ||||||
|  |     let http = ''; | ||||||
|  |     let lineA = ''; | ||||||
|  |     let lineB = ''; | ||||||
|  |     let lineC = ''; | ||||||
|  |     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 !== '') { | ||||||
|  |             http += 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, http }; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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]); | ||||||
|  |     let result = getHtmlTextAndHttp(fromHtml, b, r, t, c, e, w, records); | ||||||
|  |     if (fromHtml) { | ||||||
|  |         document.getElementById('HeaderGrid').innerHTML = result.html.replaceAll('>null<', '> <'); | ||||||
|  |         if (_windowLocationHRef.indexOf('=WSJF') === -1) { | ||||||
|  |             document.getElementById('AllTextarea').value = result.text.replaceAll('null', '').replaceAll(' ', '') + result.http; | ||||||
|  |         } | ||||||
|  |         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 = getHtmlTextAndHttp(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 | ||||||
| @ -67,23 +67,24 @@ function getNotifications(x, aggregation) { | |||||||
|     else { |     else { | ||||||
|         result = ''; |         result = ''; | ||||||
|         aggregation.Notifications.forEach(element => { |         aggregation.Notifications.forEach(element => { | ||||||
|  |             const username = element.username == null ? 'user' : element.username; | ||||||
|             if (element.value === 1) { |             if (element.value === 1) { | ||||||
|                 result += 'Highest ' + element.RemoteIpAddress + '|'; |                 result += 'Highest ' + username + '|'; | ||||||
|             } |             } | ||||||
|             else if (element.value === 2) { |             else if (element.value === 2) { | ||||||
|                 result += 'High ' + element.RemoteIpAddress + '|'; |                 result += 'High ' + username + '|'; | ||||||
|             } |             } | ||||||
|             else if (element.value === 3) { |             else if (element.value === 3) { | ||||||
|                 result += 'Medium ' + element.RemoteIpAddress + '|'; |                 result += 'Medium ' + username + '|'; | ||||||
|             } |             } | ||||||
|             else if (element.value === 4) { |             else if (element.value === 4) { | ||||||
|                 result += 'Low ' + element.RemoteIpAddress + '|'; |                 result += 'Low ' + username + '|'; | ||||||
|             } |             } | ||||||
|             else if (element.value === 5) { |             else if (element.value === 5) { | ||||||
|                 result += 'Lowest ' + element.RemoteIpAddress + '|'; |                 result += 'Lowest ' + username + '|'; | ||||||
|             } |             } | ||||||
|             else { |             else { | ||||||
|                 result += element.value + ' ' + element.RemoteIpAddress + '|'; |                 result += element.value + ' ' + username + '|'; | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|         result = result.substring(0, result.length - 1); |         result = result.substring(0, result.length - 1); | ||||||
| @ -191,32 +192,32 @@ function sendValue(fromHtml, element, page, id) { | |||||||
|     if (fromHtml && notification.value !== "9") { |     if (fromHtml && notification.value !== "9") { | ||||||
|         $("#AllTextarea").hide(); |         $("#AllTextarea").hide(); | ||||||
|         document.getElementById('AllTextarea').value = ''; |         document.getElementById('AllTextarea').value = ''; | ||||||
|         // $.post(_apiUrl + "save", notification) |         $.post(_apiUrl, notification) | ||||||
|         //     .done(function (msg) { |             .done(function (msg) { | ||||||
|         //         console.log("Posted value of " + notification.value + " for " + id + " on page " + page + " " + msg); |                 console.log("Posted value of " + notification.value + " for " + id + " on page " + page + " " + msg); | ||||||
|         //     }) |  | ||||||
|         //     .fail(function (_, textStatus, _) { |  | ||||||
|         //         alert(textStatus); |  | ||||||
|         //     }); |  | ||||||
|                 if (!_connectionHubStartDone) { |                 if (!_connectionHubStartDone) { | ||||||
|             alert("Error data not sent!"); |                     console.warn("Error data not sent!"); | ||||||
|                 } |                 } | ||||||
|                 else { |                 else { | ||||||
|                     if (_chat.connection.lastError != undefined) |                     if (_chat.connection.lastError != undefined) | ||||||
|                 alert("Last Error:\r\n\r\n" + _chat.connection.lastError); |                         console.warn("Last Error:\r\n\r\n" + _chat.connection.lastError); | ||||||
|                     _chat.server.notifyAll(notification) |                     _chat.server.notifyAll(notification) | ||||||
|                         .done(function () { |                         .done(function () { | ||||||
|                             console.log("Posted value of " + notification.value + " for " + id + " on page " + page); |                             console.log("Posted value of " + notification.value + " for " + id + " on page " + page); | ||||||
|                         }) |                         }) | ||||||
|                         .fail(function (errorThrown) { |                         .fail(function (errorThrown) { | ||||||
|                             if (errorThrown == undefined || errorThrown.message == undefined || errorThrown.stack == undefined) { |                             if (errorThrown == undefined || errorThrown.message == undefined || errorThrown.stack == undefined) { | ||||||
|                         alert("Error posting!"); |                                 console.warn("Error posting!"); | ||||||
|                             } |                             } | ||||||
|                             else { |                             else { | ||||||
|                         alert(errorThrown.message + "\r\n\r\n" + errorThrown.stack); |                                 console.warn(errorThrown.message + "\r\n\r\n" + errorThrown.stack); | ||||||
|                             } |                             } | ||||||
|                         }); |                         }); | ||||||
|                 } |                 } | ||||||
|  |             }) | ||||||
|  |             .fail(function (_, textStatus, _) { | ||||||
|  |                 console.warn(textStatus); | ||||||
|  |             }); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| @ -391,7 +392,7 @@ function updateWorkItem(b, r, t, c, e, w, page, workItem) { | |||||||
|         aggregation = workItem.Effort; |         aggregation = workItem.Effort; | ||||||
|     } |     } | ||||||
|     if (x == undefined) |     if (x == undefined) | ||||||
|         alert("Error with page!"); |         console.warn("Error with page!"); | ||||||
|     else { |     else { | ||||||
|         $('#' + x.page + workItem.Id).text('!' + myRound(aggregation.FibonacciAverage, 100)); |         $('#' + x.page + workItem.Id).text('!' + myRound(aggregation.FibonacciAverage, 100)); | ||||||
|         if (workItem.WeightedShortestJobFirst != undefined) { |         if (workItem.WeightedShortestJobFirst != undefined) { | ||||||
| @ -447,7 +448,7 @@ function setupSignalR(b, r, t, c, e, w, signalRUrl) { | |||||||
|     $.connection.hub.url = signalRUrl; |     $.connection.hub.url = signalRUrl; | ||||||
|     _chat = $.connection.weightedShortestJobFirstHub; |     _chat = $.connection.weightedShortestJobFirstHub; | ||||||
|     if (_chat == undefined || _chat.server == undefined) { |     if (_chat == undefined || _chat.server == undefined) { | ||||||
|         alert('Error within handshake!'); |         console.warn('Error within handshake!'); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|         _chat.client.updateWorkItem = function (page, workItem) { |         _chat.client.updateWorkItem = function (page, workItem) { | ||||||
| @ -461,10 +462,10 @@ function setupSignalR(b, r, t, c, e, w, signalRUrl) { | |||||||
|             .fail(function (errorThrown) { |             .fail(function (errorThrown) { | ||||||
|                 _connectionHubStartDone = false; |                 _connectionHubStartDone = false; | ||||||
|                 if (errorThrown == undefined || errorThrown.message == undefined || errorThrown.stack == undefined) { |                 if (errorThrown == undefined || errorThrown.message == undefined || errorThrown.stack == undefined) { | ||||||
|                     alert("Error starting conection!"); |                     console.warn("Error starting connection!"); | ||||||
|                 } |                 } | ||||||
|                 else { |                 else { | ||||||
|                     alert(errorThrown.message + "\r\n" + errorThrown.stack); |                     console.warn(errorThrown.message + "\r\n" + errorThrown.stack); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|     } |     } | ||||||
| @ -17061,8 +17062,8 @@ if (typeof document == 'undefined') { | |||||||
|     const apiUrl = "https://eaf-dev.mes.infineon.com/api/v1/ado/"; |     const apiUrl = "https://eaf-dev.mes.infineon.com/api/v1/ado/"; | ||||||
|     const windowLocationHRef = "https://eaf-dev.mes.infineon.com/html/cod.html?site=MES"; |     const windowLocationHRef = "https://eaf-dev.mes.infineon.com/html/cod.html?site=MES"; | ||||||
|     const workItems = { |     const workItems = { | ||||||
|         a: "https://eaf-dev.mes.infineon.com/markdown/bugs-features-with-parents.json?v=2025-01-22-10-49", |         a: "https://eaf-dev.mes.infineon.com/markdown/bugs-features-with-parents.json?v=2025-04-14-08-10", | ||||||
|         b: "https://eaf-dev.mes.infineon.com/markdown/{}.json?v=2025-01-22-10-49" |         b: "https://eaf-dev.mes.infineon.com/markdown/{}.json?v=2025-04-14-08-10" | ||||||
|     }; |     }; | ||||||
|     const b = { |     const b = { | ||||||
|         page: "business", |         page: "business", | ||||||
|  | |||||||
| @ -31,11 +31,9 @@ function initIndex(url, apiUrl) { | |||||||
|             // Call the Send method on the hub.
 |             // Call the Send method on the hub.
 | ||||||
|             // chat.server.send($('#displayname').val(), $('#message').val());
 |             // chat.server.send($('#displayname').val(), $('#message').val());
 | ||||||
|             var notification = { |             var notification = { | ||||||
|                 "Json": null, |  | ||||||
|                 "id": 110743, |                 "id": 110743, | ||||||
|                 "page": "effort", |                 "page": "effort", | ||||||
|                 "QueryString": "time=1737573418926\u0026id=110743\u0026page=effort\u0026value=1", |                 "username": "user", | ||||||
|                 "RemoteIpAddress": "10.95.36.87", |  | ||||||
|                 "time": 1737573418926, |                 "time": 1737573418926, | ||||||
|                 "value": 1 |                 "value": 1 | ||||||
|             }; |             }; | ||||||
| @ -2,6 +2,7 @@ using System; | |||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| using System.Collections.ObjectModel; | using System.Collections.ObjectModel; | ||||||
| using System.Linq; | using System.Linq; | ||||||
|  | using System.Text.Json; | ||||||
| using System.Text.Json.Serialization; | using System.Text.Json.Serialization; | ||||||
|  |  | ||||||
| namespace Adaptation.FileHandlers.json.WorkItems; | namespace Adaptation.FileHandlers.json.WorkItems; | ||||||
| @ -12,13 +13,14 @@ internal class Record | |||||||
| #nullable enable | #nullable enable | ||||||
|  |  | ||||||
|     [JsonConstructor] |     [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; |         WorkItem = workItem; | ||||||
|         Parent = parent; |         Parent = parent; | ||||||
|         Children = children; |         Children = children; | ||||||
|         Related = related; |         Related = related; | ||||||
|         Successors = successors; |         Successors = successors; | ||||||
|  |         Tag = tag; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     [JsonPropertyName("WorkItem")] public WorkItem WorkItem { get; set; } |     [JsonPropertyName("WorkItem")] public WorkItem WorkItem { get; set; } | ||||||
| @ -26,6 +28,7 @@ internal class Record | |||||||
|     [JsonPropertyName("Children")] public Record[]? Children { get; set; } |     [JsonPropertyName("Children")] public Record[]? Children { get; set; } | ||||||
|     [JsonPropertyName("Related")] public Record[]? Related { get; set; } |     [JsonPropertyName("Related")] public Record[]? Related { get; set; } | ||||||
|     [JsonPropertyName("Successors")] public Record[]? Successors { 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) |     internal static Record GetWithoutNesting(Record record, string? violation) | ||||||
|     { |     { | ||||||
| @ -60,7 +63,7 @@ internal class Record | |||||||
|                                 violation: record.WorkItem.Violation is null ? violation : record.WorkItem.Violation, |                                 violation: record.WorkItem.Violation is null ? violation : record.WorkItem.Violation, | ||||||
|                                 weightedShortestJobFirst: record.WorkItem.WeightedShortestJobFirst, |                                 weightedShortestJobFirst: record.WorkItem.WeightedShortestJobFirst, | ||||||
|                                 workItemType: record.WorkItem.WorkItemType); |                                 workItemType: record.WorkItem.WorkItemType); | ||||||
|         result = new(workItem, record.Parent, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>()); |         result = new(workItem, record.Parent, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>(), record.Tag); | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -100,14 +103,40 @@ internal class Record | |||||||
|                 relationRecords.Add(Get(r, keepRelations)); |                 relationRecords.Add(Get(r, keepRelations)); | ||||||
|             successorRecords = relationRecords.ToArray(); |             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; |         return result; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     internal static Record Get(WorkItem workItem, WorkItem? parent, ReadOnlyCollection<Record>? children, ReadOnlyCollection<Record>? related, ReadOnlyCollection<Record>? successors, bool keepRelations) |     internal static Record Get(WorkItem workItem, WorkItem? parent, ReadOnlyCollection<Record>? children, ReadOnlyCollection<Record>? related, ReadOnlyCollection<Record>? successors, bool keepRelations) | ||||||
|     { |     { | ||||||
|         Record result; |         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); |         result = Get(record, keepRelations); | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -106,8 +106,7 @@ | |||||||
|         <PackageReference Include="Tesseract" Version="5.2.0" /> |         <PackageReference Include="Tesseract" Version="5.2.0" /> | ||||||
|     </ItemGroup> |     </ItemGroup> | ||||||
|     <ItemGroup> |     <ItemGroup> | ||||||
|         <PackageReference Include="Microsoft.AspNet.SignalR" Version="2.4.3" /> |         <PackageReference Include="Nancy.Owin" Version="2.0.0" /> | ||||||
|         <PackageReference Include="Microsoft.AspNet.SignalR.Core" Version="2.4.3" /> |  | ||||||
|         <PackageReference Include="Microsoft.Owin" Version="4.0.0" /> |         <PackageReference Include="Microsoft.Owin" Version="4.0.0" /> | ||||||
|         <PackageReference Include="Microsoft.Owin.Cors" 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.Hosting" Version="4.0.0" /> | ||||||
|  | |||||||
| @ -41,6 +41,24 @@ stages: | |||||||
|             displayName: "Nuget Clear" |             displayName: "Nuget Clear" | ||||||
|             enabled: false |             enabled: false | ||||||
|  |  | ||||||
|  |           - task: CopyFiles@2 | ||||||
|  |             displayName: 'Copy GhostPCL Files to: D:\EAF-Mesa-Integration\copy' | ||||||
|  |             inputs: | ||||||
|  |               Contents: "*" | ||||||
|  |               SourceFolder: '\\mesfs.infineon.com\EC_EAFRepository\Staging\DeploymentStorage\GhostPCL' | ||||||
|  |               TargetFolder: 'D:\EAF-Mesa-Integration\copy\GhostPCL' | ||||||
|  |               OverWrite: true | ||||||
|  |             enabled: true | ||||||
|  |  | ||||||
|  |           - task: CopyFiles@2 | ||||||
|  |             displayName: 'Copy LincPDFC Files to: D:\EAF-Mesa-Integration\copy' | ||||||
|  |             inputs: | ||||||
|  |               Contents: "*" | ||||||
|  |               SourceFolder: '\\mesfs.infineon.com\EC_EAFRepository\Staging\DeploymentStorage\LincPDFC' | ||||||
|  |               TargetFolder: 'D:\EAF-Mesa-Integration\copy\LincPDFC' | ||||||
|  |               OverWrite: true | ||||||
|  |             enabled: true | ||||||
|  |  | ||||||
|           - script: | |           - script: | | ||||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets init |               "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 "BuildNumber" "$(Build.BuildId)" | ||||||
| @ -184,6 +202,24 @@ stages: | |||||||
|             displayName: "Nuget Clear" |             displayName: "Nuget Clear" | ||||||
|             enabled: false |             enabled: false | ||||||
|  |  | ||||||
|  |           - task: CopyFiles@2 | ||||||
|  |             displayName: 'Copy GhostPCL Files to: D:\EAF-Mesa-Integration\copy' | ||||||
|  |             inputs: | ||||||
|  |               Contents: "*" | ||||||
|  |               SourceFolder: '\\mestsa003.infineon.com\EC_EAFRepository\Staging\DeploymentStorage\GhostPCL' | ||||||
|  |               TargetFolder: 'D:\EAF-Mesa-Integration\copy\GhostPCL' | ||||||
|  |               OverWrite: true | ||||||
|  |             enabled: true | ||||||
|  |  | ||||||
|  |           - task: CopyFiles@2 | ||||||
|  |             displayName: 'Copy LincPDFC Files to: D:\EAF-Mesa-Integration\copy' | ||||||
|  |             inputs: | ||||||
|  |               Contents: "*" | ||||||
|  |               SourceFolder: '\\mestsa003.infineon.com\EC_EAFRepository\Staging\DeploymentStorage\LincPDFC' | ||||||
|  |               TargetFolder: 'D:\EAF-Mesa-Integration\copy\LincPDFC' | ||||||
|  |               OverWrite: true | ||||||
|  |             enabled: true | ||||||
|  |  | ||||||
|           - script: | |           - script: | | ||||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets init |               "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 "BuildNumber" "$(Build.BuildId)" | ||||||
|  | |||||||
| @ -44,9 +44,9 @@ public class FileRead : Properties.IFileRead | |||||||
|     protected readonly string _CellInstanceConnectionNameBase; |     protected readonly string _CellInstanceConnectionNameBase; | ||||||
|     protected readonly Dictionary<string, List<long>> _DummyRuns; |     protected readonly Dictionary<string, List<long>> _DummyRuns; | ||||||
|     protected readonly Dictionary<string, string> _FileParameter; |     protected readonly Dictionary<string, string> _FileParameter; | ||||||
|     protected readonly Dictionary<long, List<string>> _StaticRuns; |  | ||||||
|     protected readonly string _ParameterizedModelObjectDefinitionType; |     protected readonly string _ParameterizedModelObjectDefinitionType; | ||||||
|     protected readonly FileConnectorConfiguration _FileConnectorConfiguration; |     protected readonly FileConnectorConfiguration _FileConnectorConfiguration; | ||||||
|  |     protected readonly Dictionary<long, List<Metrology.WS.Results>> _StaticRuns; | ||||||
|     protected readonly IList<ModelObjectParameterDefinition> _ModelObjectParameterDefinitions; |     protected readonly IList<ModelObjectParameterDefinition> _ModelObjectParameterDefinitions; | ||||||
|  |  | ||||||
|     bool Properties.IFileRead.IsEvent => _IsEvent; |     bool Properties.IFileRead.IsEvent => _IsEvent; | ||||||
| @ -203,7 +203,7 @@ public class FileRead : Properties.IFileRead | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public FileRead(IDescription description, bool isEvent, 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(IDescription description, bool isEvent, 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<Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) | ||||||
|     { |     { | ||||||
|         _SMTP = smtp; |         _SMTP = smtp; | ||||||
|         _IsEvent = isEvent; |         _IsEvent = isEvent; | ||||||
| @ -377,17 +377,25 @@ public class FileRead : Properties.IFileRead | |||||||
|  |  | ||||||
|     internal string[] GetInProcessDirectory(string jobIdDirectory) |     internal string[] GetInProcessDirectory(string jobIdDirectory) | ||||||
|     { |     { | ||||||
|         string[] results; |         List<string> results = new(); | ||||||
|         if (!_IsEAFHosted) |         if (!_IsEAFHosted) | ||||||
|             results = new string[] { jobIdDirectory }; |             results = new string[] { jobIdDirectory }.ToList(); | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|  |             string[] files; | ||||||
|             string logisticsSequence = _Logistics.Sequence.ToString(); |             string logisticsSequence = _Logistics.Sequence.ToString(); | ||||||
|             results = Directory.GetDirectories(jobIdDirectory, string.Concat(_Logistics.MID, '*', logisticsSequence, '*'), SearchOption.TopDirectoryOnly); |             string[] directories = Directory.GetDirectories(jobIdDirectory, $"*{logisticsSequence}*", SearchOption.TopDirectoryOnly); | ||||||
|  |             foreach (string directory in directories) | ||||||
|  |             { | ||||||
|  |                 files = Directory.GetFiles(directory, "*", SearchOption.TopDirectoryOnly); | ||||||
|  |                 if (files.Length == 0) | ||||||
|  |                     continue; | ||||||
|  |                 results.Add(directory); | ||||||
|             } |             } | ||||||
|         if ((results is null) || results.Length != 1) |         } | ||||||
|  |         if ((results is null) || results.Count != 1) | ||||||
|             throw new Exception("Didn't find directory by logistics sequence"); |             throw new Exception("Didn't find directory by logistics sequence"); | ||||||
|         return results; |         return results.ToArray(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected static string[] GetMatches(FileConnectorConfiguration fileConnectorConfiguration) |     protected static string[] GetMatches(FileConnectorConfiguration fileConnectorConfiguration) | ||||||
| @ -470,27 +478,14 @@ public class FileRead : Properties.IFileRead | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected void WritePDSF(IFileRead fileRead, JsonElement[] jsonElements) |     protected static void WritePDSF(IFileRead fileRead, JsonElement[] jsonElements) | ||||||
|     { |     { | ||||||
|         string directory; | #pragma warning disable CA1510 | ||||||
|         string day = $"{_Logistics.DateTimeFromSequence:yyyy-MM-dd}"; |         if (fileRead is null) | ||||||
|         string weekOfYear = _Calendar.GetWeekOfYear(_Logistics.DateTimeFromSequence, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); |             throw new ArgumentNullException(nameof(fileRead)); | ||||||
|         string weekDirectory = $"{_Logistics.DateTimeFromSequence:yyyy}_Week_{weekOfYear}"; |         if (jsonElements is null) | ||||||
|         if (!_CellInstanceConnectionName.StartsWith(_CellInstanceName) && _CellInstanceConnectionNameBase == _EquipmentType) |             throw new ArgumentNullException(nameof(jsonElements)); | ||||||
|             directory = Path.Combine(_TracePath, _EquipmentType, "Target", weekDirectory, day, _CellInstanceName, _CellInstanceConnectionName); | #pragma warning restore CA1510 | ||||||
|         else |  | ||||||
|             directory = Path.Combine(_TracePath, _EquipmentType, "Source", weekDirectory, day, _CellInstanceName, _CellInstanceConnectionName); |  | ||||||
|         if (!Directory.Exists(directory)) |  | ||||||
|             _ = Directory.CreateDirectory(directory); |  | ||||||
|         string file = Path.Combine(directory, string.Concat(_Logistics.MesEntity, "_", _Logistics.Sequence, ".ipdsf")); |  | ||||||
|         string lines = ProcessDataStandardFormat.GetPDSFText(fileRead, _Logistics, jsonElements, logisticsText: string.Empty); |  | ||||||
|         File.WriteAllText(file, lines); |  | ||||||
|         if (_Logistics.TotalSecondsSinceLastWriteTimeFromSequence > 600) |  | ||||||
|         { |  | ||||||
|             try |  | ||||||
|             { File.SetLastWriteTime(file, _Logistics.DateTimeFromSequence); } |  | ||||||
|             catch (Exception) { } |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected void WaitForThread(Thread thread, List<Exception> threadExceptions) |     protected void WaitForThread(Thread thread, List<Exception> threadExceptions) | ||||||
| @ -616,6 +611,9 @@ public class FileRead : Properties.IFileRead | |||||||
|                 case FileConnectorConfiguration.PostProcessingModeEnum.Delete: |                 case FileConnectorConfiguration.PostProcessingModeEnum.Delete: | ||||||
|                     File.Delete(sourceFile.FullName); |                     File.Delete(sourceFile.FullName); | ||||||
|                     break; |                     break; | ||||||
|  |                 case FileConnectorConfiguration.PostProcessingModeEnum.None: | ||||||
|  |                     File.Move(sourceFile.FullName, itemFile); | ||||||
|  |                     break; | ||||||
|                 default: |                 default: | ||||||
|                     throw new Exception(); |                     throw new Exception(); | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -6,23 +6,25 @@ public partial class WS | |||||||
|     public class Attachment |     public class Attachment | ||||||
|     { |     { | ||||||
|  |  | ||||||
|         public string SubGroupId { get; set; } | #nullable enable | ||||||
|         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; } |  | ||||||
|  |  | ||||||
|         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; |             UniqueId = uniqueId; | ||||||
|             DestinationFileName = destinationFileName; |  | ||||||
|             SourceFileName = sourceFileName; |             SourceFileName = sourceFileName; | ||||||
|  |             HeaderIdDirectory = headerIdDirectory; | ||||||
|  |             DestinationFileName = destinationFileName; | ||||||
|             AttachmentId = System.Guid.NewGuid().ToString(); |             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; | ||||||
|  | using System.Text.Json.Serialization; | ||||||
|  |  | ||||||
| namespace Adaptation.Shared.Metrology; | namespace Adaptation.Shared.Metrology; | ||||||
|  |  | ||||||
| public partial class WS | public partial class WS | ||||||
| { | { | ||||||
|     // this class represents the response from the Inbound API endpoint |  | ||||||
|     public class Results |     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 | #nullable enable | ||||||
|         public long HeaderID { get; set; } |  | ||||||
|  |  | ||||||
|         // if false, this collection will contain a list of errors |         [JsonConstructor] | ||||||
|         public List<string> Errors { get; set; } |         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 |         [JsonPropertyName("errors")] public List<string>? Errors { get; set; } | ||||||
|         public List<string> Warnings { 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 | public partial class WS | ||||||
| { | { | ||||||
|  |  | ||||||
|  | #nullable enable | ||||||
|  |  | ||||||
|     public static (string, Results) SendData(string url, long sequence, string directory, object payload, int timeoutSeconds = 120) |     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; |         string resultsJson = string.Empty; | ||||||
|         try |         try | ||||||
|         { |         { | ||||||
| @ -30,29 +32,20 @@ public partial class WS | |||||||
|                 }; |                 }; | ||||||
|                 HttpResponseMessage httpResponseMessage = httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead).Result; |                 HttpResponseMessage httpResponseMessage = httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead).Result; | ||||||
|                 resultsJson = httpResponseMessage.Content.ReadAsStringAsync().Result; |                 resultsJson = httpResponseMessage.Content.ReadAsStringAsync().Result; | ||||||
|                 results = JsonSerializer.Deserialize<Results>(resultsJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); |                 wsResults = JsonSerializer.Deserialize(resultsJson, ResultsSourceGenerationContext.Default.Results); | ||||||
|                 string checkDirectory = Path.Combine(directory, $"-{results.HeaderID}"); |                 if (wsResults is null) | ||||||
|  |                     throw new NullReferenceException(nameof(wsResults)); | ||||||
|  |                 string checkDirectory = Path.Combine(directory, $"-{wsResults.HeaderId}"); | ||||||
|                 if (!Directory.Exists(checkDirectory)) |                 if (!Directory.Exists(checkDirectory)) | ||||||
|                     _ = Directory.CreateDirectory(checkDirectory); |                     _ = Directory.CreateDirectory(checkDirectory); | ||||||
|                 File.WriteAllText(Path.Combine(checkDirectory, $"{sequence}.json"), json); |                 File.WriteAllText(Path.Combine(checkDirectory, $"{sequence}.json"), json); | ||||||
|             } |             } | ||||||
|             if (!results.Success) |             if (wsResults.Success is null || !wsResults.Success.Value) | ||||||
|                 results.Errors.Add(results.ToString()); |                 wsResults.Errors?.Add(wsResults.ToString()); | ||||||
|         } |         } | ||||||
|         catch (Exception e) |         catch (Exception e) | ||||||
|         { |         { wsResults ??= Results.Get(resultsJson, e); } | ||||||
|             Exception exception = e; |         return new(resultsJson, wsResults); | ||||||
|             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); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void AttachFile(string url, Attachment attachment, int timeoutSeconds = 60) |     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; |         string directory; | ||||||
|         try |         try | ||||||
|         { |         { | ||||||
|  |             string? directoryName; | ||||||
|             if (headerAttachments is not null) |             if (headerAttachments is not null) | ||||||
|             { |             { | ||||||
|                 foreach (Attachment attachment in headerAttachments) |                 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)) |                     if (!Directory.Exists(directory)) | ||||||
|                         _ = Directory.CreateDirectory(directory); |                         _ = Directory.CreateDirectory(directory); | ||||||
|                     File.Copy(attachment.SourceFileName, Path.Combine(directory, attachment.DestinationFileName), overwrite: true); |                     File.Copy(attachment.SourceFileName, Path.Combine(directory, attachment.DestinationFileName), overwrite: true); | ||||||
| @ -88,7 +85,10 @@ public partial class WS | |||||||
|             { |             { | ||||||
|                 foreach (Attachment attachment in dataAttachments) |                 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)) |                     if (!Directory.Exists(directory)) | ||||||
|                         _ = Directory.CreateDirectory(directory); |                         _ = Directory.CreateDirectory(directory); | ||||||
|                     File.Copy(attachment.SourceFileName, Path.Combine(directory, attachment.DestinationFileName), overwrite: true); |                     File.Copy(attachment.SourceFileName, Path.Combine(directory, attachment.DestinationFileName), overwrite: true); | ||||||
| @ -108,7 +108,7 @@ public partial class WS | |||||||
|         } |         } | ||||||
|         catch (Exception e) |         catch (Exception e) | ||||||
|         { |         { | ||||||
|             Exception exception = e; |             Exception? exception = e; | ||||||
|             StringBuilder stringBuilder = new(); |             StringBuilder stringBuilder = new(); | ||||||
|             while (exception is not null) |             while (exception is not null) | ||||||
|             { |             { | ||||||
|  | |||||||
| @ -26,16 +26,25 @@ internal class ProcessDataStandardFormat | |||||||
|  |  | ||||||
|     internal long? Sequence { get; private set; } |     internal long? Sequence { get; private set; } | ||||||
|     internal ReadOnlyCollection<string> Body { get; private set; } |     internal ReadOnlyCollection<string> Body { get; private set; } | ||||||
|  |     internal ReadOnlyCollection<string> Footer { get; private set; } | ||||||
|  |     internal ReadOnlyCollection<string> Header { get; private set; } | ||||||
|     internal ReadOnlyCollection<string> Columns { get; private set; } |     internal ReadOnlyCollection<string> Columns { get; private set; } | ||||||
|  |     internal ProcessDataStandardFormat? InputPDSF { get; private set; } | ||||||
|     internal ReadOnlyCollection<string> Logistics { get; private set; } |     internal ReadOnlyCollection<string> Logistics { get; private set; } | ||||||
|  |  | ||||||
|     internal ProcessDataStandardFormat(ReadOnlyCollection<string> body, |     internal ProcessDataStandardFormat(ReadOnlyCollection<string> body, | ||||||
|                                        ReadOnlyCollection<string> columns, |                                        ReadOnlyCollection<string> columns, | ||||||
|  |                                        ReadOnlyCollection<string> footer, | ||||||
|  |                                        ReadOnlyCollection<string> header, | ||||||
|  |                                        ProcessDataStandardFormat? inputPDSF, | ||||||
|                                        ReadOnlyCollection<string> logistics, |                                        ReadOnlyCollection<string> logistics, | ||||||
|                                        long? sequence) |                                        long? sequence) | ||||||
|     { |     { | ||||||
|         Body = body; |         Body = body; | ||||||
|         Columns = columns; |         Columns = columns; | ||||||
|  |         Footer = footer; | ||||||
|  |         Header = header; | ||||||
|  |         InputPDSF = inputPDSF; | ||||||
|         Logistics = logistics; |         Logistics = logistics; | ||||||
|         Sequence = sequence; |         Sequence = sequence; | ||||||
|     } |     } | ||||||
| @ -52,8 +61,8 @@ internal class ProcessDataStandardFormat | |||||||
|     internal static string Archive(bool addSpaces = true, char separator = ' ') => |     internal static string Archive(bool addSpaces = true, char separator = ' ') => | ||||||
|         GetString(SearchFor.Archive, addSpaces, separator); |         GetString(SearchFor.Archive, addSpaces, separator); | ||||||
|  |  | ||||||
|     internal static ProcessDataStandardFormat GetEmpty() => |     internal static ProcessDataStandardFormat GetEmpty(Logistics logistics) => | ||||||
|         new(new(Array.Empty<string>()), new(Array.Empty<string>()), new(Array.Empty<string>()), null); |         new(new(Array.Empty<string>()), new(Array.Empty<string>()), new(Array.Empty<string>()), new(Array.Empty<string>()), null, new(logistics.Logistics1), null); | ||||||
|  |  | ||||||
|     internal static List<string> PDSFToFixedWidth(string reportFullPath) |     internal static List<string> PDSFToFixedWidth(string reportFullPath) | ||||||
|     { |     { | ||||||
| @ -124,19 +133,27 @@ internal class ProcessDataStandardFormat | |||||||
|         return results; |         return results; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     internal static ProcessDataStandardFormat GetProcessDataStandardFormat(string reportFullPath, string[]? lines = null) |     internal static ProcessDataStandardFormat GetProcessDataStandardFormat(string reportFullPath, string[]? lines = null, int columnsLine = 6) | ||||||
|     { |     { | ||||||
|         ProcessDataStandardFormat result; |         ProcessDataStandardFormat result; | ||||||
|  |         long? sequence; | ||||||
|         string segment; |         string segment; | ||||||
|         List<string> body = new(); |  | ||||||
|         List<string> logistics = new(); |  | ||||||
|         lines ??= File.ReadAllLines(reportFullPath); |  | ||||||
|         string[] segments; |         string[] segments; | ||||||
|         if (lines.Length < 7) |         bool addToFooter = false; | ||||||
|  |         List<string> body = new(); | ||||||
|  |         List<string> header = new(); | ||||||
|  |         List<string> footer = new(); | ||||||
|  |         List<string> columns = new(); | ||||||
|  |         ReadOnlyCollection<string> logistics; | ||||||
|  |         lines ??= File.ReadAllLines(reportFullPath); | ||||||
|  |         if (lines.Length < columnsLine + 1) | ||||||
|             segments = Array.Empty<string>(); |             segments = Array.Empty<string>(); | ||||||
|         else |         else | ||||||
|             segments = lines[6].Trim().Split('\t'); |         { | ||||||
|         List<string> columns = new(); |             segments = lines[columnsLine].Trim().Split('\t'); | ||||||
|  |             for (int i = 0; i < columnsLine; i++) | ||||||
|  |                 header.Add(lines[i]); | ||||||
|  |         } | ||||||
|         for (int c = 0; c < segments.Length; c++) |         for (int c = 0; c < segments.Length; c++) | ||||||
|         { |         { | ||||||
|             segment = segments[c].Substring(1, segments[c].Length - 2); |             segment = segments[c].Substring(1, segments[c].Length - 2); | ||||||
| @ -155,102 +172,133 @@ internal class ProcessDataStandardFormat | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         bool lookForLogistics = false; |         for (int r = columnsLine + 1; r < lines.Length; r++) | ||||||
|         for (int r = 7; r < lines.Length; r++) |  | ||||||
|         { |         { | ||||||
|             if (lines[r].StartsWith("NUM_DATA_ROWS")) |             if (lines[r].StartsWith("NUM_DATA_ROWS")) | ||||||
|                 lookForLogistics = true; |                 addToFooter = true; | ||||||
|             if (!lookForLogistics) |             if (!addToFooter) | ||||||
|             { |  | ||||||
|                 body.Add(lines[r]); |                 body.Add(lines[r]); | ||||||
|                 continue; |             else | ||||||
|             } |  | ||||||
|             if (lines[r].StartsWith("LOGISTICS_1")) |  | ||||||
|             { |  | ||||||
|                 for (int i = r; i < lines.Length; i++) |  | ||||||
|             { |             { | ||||||
|  |                 footer.Add(lines[r]); | ||||||
|                 if (lines[r].StartsWith("END_HEADER")) |                 if (lines[r].StartsWith("END_HEADER")) | ||||||
|                     break; |                     break; | ||||||
|                     logistics.Add(lines[i]); |  | ||||||
|                 } |  | ||||||
|                 break; |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         result = new(logistics.AsReadOnly(), columns.AsReadOnly(), body.AsReadOnly(), null); |         string? linesOne = lines.Length > 0 && body.Count == 0 && columns.Count == 0 ? lines[1] : null; | ||||||
|  |         logistics = GetLogistics(footer, linesOne: linesOne); | ||||||
|  |         if (logistics.Count == 0) | ||||||
|  |             sequence = null; | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             segments = logistics[0].Split(new string[] { "SEQUENCE=" }, StringSplitOptions.None); | ||||||
|  |             sequence = segments.Length < 2 || !long.TryParse(segments[1].Split(';')[0], out long s) ? null : s; | ||||||
|  |         } | ||||||
|  |         if (sequence is null && !string.IsNullOrEmpty(reportFullPath)) | ||||||
|  |         { | ||||||
|  |             FileInfo fileInfo = new(reportFullPath); | ||||||
|  |             sequence = fileInfo.LastWriteTime.Ticks; | ||||||
|  |         } | ||||||
|  |         result = new(body: body.AsReadOnly(), | ||||||
|  |                      columns: columns.AsReadOnly(), | ||||||
|  |                      footer: footer.AsReadOnly(), | ||||||
|  |                      header: header.AsReadOnly(), | ||||||
|  |                      inputPDSF: null, | ||||||
|  |                      logistics: logistics, | ||||||
|  |                      sequence: sequence); | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     internal static ProcessDataStandardFormat? GetProcessDataStandardFormat(string reportFullPath, ProcessDataStandardFormatMapping pdsfMapping) |     private static ReadOnlyCollection<string> GetLogistics(List<string> footer, string? linesOne) | ||||||
|     { |     { | ||||||
|         ProcessDataStandardFormat? result; |         List<string> results = new(); | ||||||
|  |         bool foundLogistics1 = false; | ||||||
|  |         foreach (string line in footer) | ||||||
|  |         { | ||||||
|  |             if (line.StartsWith("END_HEADER")) | ||||||
|  |                 break; | ||||||
|  |             if (line.StartsWith("LOGISTICS_1")) | ||||||
|  |                 foundLogistics1 = true; | ||||||
|  |             if (foundLogistics1 && line.StartsWith("LOGISTICS_")) | ||||||
|  |                 results.Add(line); | ||||||
|  |         } | ||||||
|  |         if (!string.IsNullOrEmpty(linesOne) && results.Count == 0) | ||||||
|  |             results.Add(linesOne); | ||||||
|  |         return results.AsReadOnly(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     internal static ProcessDataStandardFormat GetProcessDataStandardFormat(string reportFullPath, ProcessDataStandardFormatMapping pdsfMapping) | ||||||
|  |     { | ||||||
|  |         ProcessDataStandardFormat result; | ||||||
|         const int columnsLine = 6; |         const int columnsLine = 6; | ||||||
|         FileInfo fileInfo = new(reportFullPath); |         FileInfo fileInfo = new(reportFullPath); | ||||||
|         ProcessDataStandardFormat processDataStandardFormat = GetProcessDataStandardFormat(fileInfo.LastWriteTime, pdsfMapping.NewColumnNames.Count, columnsLine, fileInfo.FullName, lines: null); |         ProcessDataStandardFormat processDataStandardFormat = GetProcessDataStandardFormat(fileInfo.LastWriteTime, columnsLine, fileInfo.FullName, lines: null); | ||||||
|         JsonElement[]? jsonElements = GetArray(pdsfMapping.NewColumnNames.Count, processDataStandardFormat, lookForNumbers: false); |         JsonElement[]? jsonElements = pdsfMapping.OldColumnNames.Count != pdsfMapping.ColumnIndices.Count ? null : GetFullArray(processDataStandardFormat); | ||||||
|         if (jsonElements is null || pdsfMapping.OldColumnNames.Count != pdsfMapping.ColumnIndices.Count) |         JsonProperty[]? jsonProperties = jsonElements is null || jsonElements.Length == 0 ? null : jsonElements[0].EnumerateObject().ToArray(); | ||||||
|             result = null; |         if (jsonElements is null || jsonProperties is null || jsonProperties.Length != pdsfMapping.NewColumnNames.Count) | ||||||
|  |             result = processDataStandardFormat; | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             result = GetProcessDataStandardFormat(pdsfMapping, jsonElements, processDataStandardFormat); |             result = GetProcessDataStandardFormat(pdsfMapping, jsonElements, processDataStandardFormat); | ||||||
|             if (result.Sequence is null || result.Columns.Count == 0 || result.Body.Count == 0 || result.Logistics.Count == 0) |             if (result.Sequence is null || result.Columns.Count == 0 || result.Body.Count == 0 || result.Logistics.Count == 0) | ||||||
|                 result = null; |                 result = processDataStandardFormat; | ||||||
|         } |         } | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static ProcessDataStandardFormat GetProcessDataStandardFormat(DateTime lastWriteTime, int expectedColumns, int columnsLine, string path, string[]? lines) |     private static ProcessDataStandardFormat GetProcessDataStandardFormat(DateTime lastWriteTime, int columnsLine, string path, string[]? lines) | ||||||
|     { |     { | ||||||
|         ProcessDataStandardFormat result; |         ProcessDataStandardFormat result; | ||||||
|         long sequence; |         long? sequence; | ||||||
|         string[] segments; |         string[] segments; | ||||||
|  |         bool addToFooter = false; | ||||||
|         List<string> body = new(); |         List<string> body = new(); | ||||||
|         bool lookForLogistics = false; |         List<string> header = new(); | ||||||
|         List<string> logistics = new(); |         List<string> footer = new(); | ||||||
|  |         ReadOnlyCollection<string> logistics; | ||||||
|         lines ??= File.ReadAllLines(path); |         lines ??= File.ReadAllLines(path); | ||||||
|         if (lines.Length <= columnsLine) |         if (lines.Length <= columnsLine) | ||||||
|             segments = Array.Empty<string>(); |             segments = Array.Empty<string>(); | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             segments = lines[columnsLine].Split('\t'); |             segments = lines[columnsLine].Split('\t'); | ||||||
|             if (segments.Length != expectedColumns) |             for (int i = 0; i < columnsLine; i++) | ||||||
|                 segments = Array.Empty<string>(); |                 header.Add(lines[i]); | ||||||
|         } |         } | ||||||
|         string[] columns = segments.Select(l => l.Trim('"')).ToArray(); |         string[] columns = segments.Select(l => l.Trim('"')).ToArray(); | ||||||
|         for (int r = columnsLine + 1; r < lines.Length; r++) |         for (int r = columnsLine + 1; r < lines.Length; r++) | ||||||
|         { |         { | ||||||
|             if (lines[r].StartsWith("NUM_DATA_ROWS")) |             if (lines[r].StartsWith("NUM_DATA_ROWS")) | ||||||
|                 lookForLogistics = true; |                 addToFooter = true; | ||||||
|             if (!lookForLogistics) |             if (!addToFooter) | ||||||
|             { |  | ||||||
|                 body.Add(lines[r]); |                 body.Add(lines[r]); | ||||||
|                 continue; |             else | ||||||
|             } |  | ||||||
|             if (lines[r].StartsWith("LOGISTICS_1")) |  | ||||||
|             { |  | ||||||
|                 for (int i = r; i < lines.Length; i++) |  | ||||||
|             { |             { | ||||||
|  |                 footer.Add(lines[r]); | ||||||
|                 if (lines[r].StartsWith("END_HEADER")) |                 if (lines[r].StartsWith("END_HEADER")) | ||||||
|                     break; |                     break; | ||||||
|                     logistics.Add(lines[i]); |  | ||||||
|                 } |  | ||||||
|                 break; |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         logistics = GetLogistics(footer, linesOne: null); | ||||||
|         if (logistics.Count == 0) |         if (logistics.Count == 0) | ||||||
|             sequence = lastWriteTime.Ticks; |             sequence = null; | ||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             segments = logistics[0].Split(new string[] { "SEQUENCE=" }, StringSplitOptions.None); |             segments = logistics[0].Split(new string[] { "SEQUENCE=" }, StringSplitOptions.None); | ||||||
|             sequence = segments.Length < 2 || !long.TryParse(segments[1].Split(';')[0], out long s) ? lastWriteTime.Ticks : s; |             sequence = segments.Length < 2 || !long.TryParse(segments[1].Split(';')[0], out long s) ? null : s; | ||||||
|         } |         } | ||||||
|  |         sequence ??= lastWriteTime.Ticks; | ||||||
|         result = new(body: body.AsReadOnly(), |         result = new(body: body.AsReadOnly(), | ||||||
|                      columns: new(columns), |                      columns: new(columns), | ||||||
|                      logistics: logistics.AsReadOnly(), |                      footer: footer.AsReadOnly(), | ||||||
|  |                      header: header.AsReadOnly(), | ||||||
|  |                      inputPDSF: null, | ||||||
|  |                      logistics: logistics, | ||||||
|                      sequence: sequence); |                      sequence: sequence); | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static JsonElement[]? GetArray(int expectedColumns, ProcessDataStandardFormat processDataStandardFormat, bool lookForNumbers) |     private static JsonElement[]? GetFullArray(ProcessDataStandardFormat processDataStandardFormat) | ||||||
|     { |     { | ||||||
|         JsonElement[]? results; |         JsonElement[]? results; | ||||||
|         if (processDataStandardFormat.Body.Count == 0 || !processDataStandardFormat.Body[0].Contains('\t')) |         if (processDataStandardFormat.Body.Count == 0 || !processDataStandardFormat.Body[0].Contains('\t')) | ||||||
| @ -258,37 +306,19 @@ internal class ProcessDataStandardFormat | |||||||
|         else |         else | ||||||
|         { |         { | ||||||
|             string value; |             string value; | ||||||
|             string[] segments; |             List<string> segments; | ||||||
|             List<string> lines = new(); |             List<string> lines = new(); | ||||||
|             StringBuilder stringBuilder = new(); |             StringBuilder stringBuilder = new(); | ||||||
|             foreach (string bodyLine in processDataStandardFormat.Body) |             foreach (string bodyLine in processDataStandardFormat.Body) | ||||||
|             { |             { | ||||||
|                 _ = stringBuilder.Clear(); |                 _ = stringBuilder.Clear(); | ||||||
|                 _ = stringBuilder.Append('{'); |                 _ = stringBuilder.Append('{'); | ||||||
|                 segments = bodyLine.Split('\t'); |                 segments = bodyLine.Split('\t').ToList(); | ||||||
|                 if (segments.Length != expectedColumns) |                 for (int c = 0; c < segments.Count; c++) | ||||||
|                     continue; |  | ||||||
|                 if (!lookForNumbers) |  | ||||||
|                 { |                 { | ||||||
|                     for (int c = 0; c < segments.Length; c++) |                     value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\""); | ||||||
|                     { |  | ||||||
|                         value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\"); |  | ||||||
|                     _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\","); |                     _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\","); | ||||||
|                 } |                 } | ||||||
|                 } |  | ||||||
|                 else |  | ||||||
|                 { |  | ||||||
|                     for (int c = 0; c < segments.Length; c++) |  | ||||||
|                     { |  | ||||||
|                         value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\"); |  | ||||||
|                         if (string.IsNullOrEmpty(value)) |  | ||||||
|                             _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append("null,"); |  | ||||||
|                         else if (value.All(char.IsDigit)) |  | ||||||
|                             _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append(','); |  | ||||||
|                         else |  | ||||||
|                             _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\","); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); |                 _ = stringBuilder.Remove(stringBuilder.Length - 1, 1); | ||||||
|                 _ = stringBuilder.AppendLine("}"); |                 _ = stringBuilder.AppendLine("}"); | ||||||
|                 lines.Add(stringBuilder.ToString()); |                 lines.Add(stringBuilder.ToString()); | ||||||
| @ -335,13 +365,135 @@ internal class ProcessDataStandardFormat | |||||||
|             results.Add(string.Join("\t", values)); |             results.Add(string.Join("\t", values)); | ||||||
|         } |         } | ||||||
|         result = new(body: new(results), |         result = new(body: new(results), | ||||||
|                      columns: processDataStandardFormat.Columns, |                      columns: processDataStandardFormatMapping.OldColumnNames, | ||||||
|  |                      footer: processDataStandardFormat.Footer, | ||||||
|  |                      header: processDataStandardFormat.Header, | ||||||
|  |                      inputPDSF: processDataStandardFormat, | ||||||
|                      logistics: processDataStandardFormat.Logistics, |                      logistics: processDataStandardFormat.Logistics, | ||||||
|                      sequence: processDataStandardFormat.Sequence); |                      sequence: processDataStandardFormat.Sequence); | ||||||
|         return result; |         return result; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     internal static void Write(string path, ProcessDataStandardFormat processDataStandardFormat) |     private static string GetJson(ProcessDataStandardFormat processDataStandardFormat) | ||||||
|  |     { | ||||||
|  |         if (processDataStandardFormat.InputPDSF is null) | ||||||
|  |             throw new NullReferenceException(nameof(processDataStandardFormat.InputPDSF)); | ||||||
|  | #pragma warning disable CA1845, IDE0057 | ||||||
|  |         string result; | ||||||
|  |         string line; | ||||||
|  |         string value; | ||||||
|  |         string[] segments; | ||||||
|  |         List<string> lines = new(); | ||||||
|  |         for (int i = 0; i < processDataStandardFormat.InputPDSF.Body.Count; i++) | ||||||
|  |         { | ||||||
|  |             line = "{"; | ||||||
|  |             segments = processDataStandardFormat.InputPDSF.Body[i].Trim().Split('\t'); | ||||||
|  |             if (segments.Length != processDataStandardFormat.InputPDSF.Columns.Count) | ||||||
|  |                 break; | ||||||
|  |             for (int c = 0; c < segments.Length; c++) | ||||||
|  |             { | ||||||
|  |                 value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\""); | ||||||
|  |                 line += string.Concat('"', processDataStandardFormat.InputPDSF.Columns[c].Trim('"'), '"', ':', '"', value, '"', ','); | ||||||
|  |             } | ||||||
|  |             line = string.Concat(line.Substring(0, line.Length - 1), '}'); | ||||||
|  |             lines.Add(line); | ||||||
|  |         } | ||||||
|  |         string? json = null; | ||||||
|  |         if (processDataStandardFormat.Footer is not null && processDataStandardFormat.Footer.Count > 0) { | ||||||
|  |             Dictionary<string, string> footerKeyValuePairs = GetFooterKeyValuePairs(processDataStandardFormat.Footer); | ||||||
|  |             Dictionary<string, Dictionary<string, string>> logisticKeyValuePairs = GetLogisticKeyValuePairs(processDataStandardFormat.Footer, footerKeyValuePairs); | ||||||
|  |             json = JsonSerializer.Serialize(logisticKeyValuePairs, DictionaryStringDictionaryStringStringSourceGenerationContext.Default.DictionaryStringDictionaryStringString); | ||||||
|  |         } | ||||||
|  |         string footerText = string.IsNullOrEmpty(json) || json == "{}" ? string.Empty : $",{Environment.NewLine}\"PDSF\":{Environment.NewLine}{json}"; | ||||||
|  |         result = string.Concat( | ||||||
|  |             '{', | ||||||
|  |             Environment.NewLine, | ||||||
|  |             '"', | ||||||
|  |             "Count", | ||||||
|  |             '"', | ||||||
|  |             ": ", | ||||||
|  |             processDataStandardFormat.Body.Count, | ||||||
|  |             ',', | ||||||
|  |             Environment.NewLine, | ||||||
|  |             '"', | ||||||
|  |             "Records", | ||||||
|  |             '"', | ||||||
|  |             ": ", | ||||||
|  |             Environment.NewLine, | ||||||
|  |             '[', | ||||||
|  |             Environment.NewLine, | ||||||
|  |             string.Join($",{Environment.NewLine}", lines), | ||||||
|  |             Environment.NewLine, | ||||||
|  |             ']', | ||||||
|  |             ',', | ||||||
|  |             Environment.NewLine, | ||||||
|  |             '"', | ||||||
|  |             "Sequence", | ||||||
|  |             '"', | ||||||
|  |             ": ", | ||||||
|  |             processDataStandardFormat.Sequence, | ||||||
|  |             Environment.NewLine, | ||||||
|  |             footerText, | ||||||
|  |             Environment.NewLine, | ||||||
|  |             '}'); | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static Dictionary<string, string> GetFooterKeyValuePairs(ReadOnlyCollection<string> footerLines) { | ||||||
|  |         Dictionary<string, string> results = new(); | ||||||
|  |         string[] segments; | ||||||
|  |         foreach (string footerLine in footerLines) { | ||||||
|  |             segments = footerLine.Split('\t'); | ||||||
|  |             if (segments.Length != 2 || string.IsNullOrEmpty(segments[1].Trim())) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             if (segments[1].Contains(';')) { | ||||||
|  |                 continue; | ||||||
|  |             } else { | ||||||
|  |                 results.Add(segments[0], segments[1]); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return results; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static Dictionary<string, Dictionary<string, string>> GetLogisticKeyValuePairs(ReadOnlyCollection<string> footerLines, Dictionary<string, string> footerKeyValuePairs) { | ||||||
|  |         Dictionary<string, Dictionary<string, string>> results = new(); | ||||||
|  |         string[] segments; | ||||||
|  |         string[] subSegments; | ||||||
|  |         string[] subSubSegments; | ||||||
|  |         Dictionary<string, string>? keyValue; | ||||||
|  |         results.Add("Footer", footerKeyValuePairs); | ||||||
|  |         foreach (string footerLine in footerLines) { | ||||||
|  |             segments = footerLine.Split('\t'); | ||||||
|  |             if (segments.Length != 2 || string.IsNullOrEmpty(segments[1].Trim())) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             if (!segments[1].Contains(';') || !segments[1].Contains('=')) { | ||||||
|  |                 continue; | ||||||
|  |             } else { | ||||||
|  |                 subSegments = segments[1].Split(';'); | ||||||
|  |                 if (subSegments.Length < 1) { | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
|  |                 if (!results.TryGetValue(segments[0], out keyValue)) { | ||||||
|  |                     results.Add(segments[0], new()); | ||||||
|  |                     if (!results.TryGetValue(segments[0], out keyValue)) { | ||||||
|  |                         throw new Exception(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 foreach (string segment in subSegments) { | ||||||
|  |                     subSubSegments = segment.Split('='); | ||||||
|  |                     if (subSubSegments.Length != 2) { | ||||||
|  |                         continue; | ||||||
|  |                     } | ||||||
|  |                     keyValue.Add(subSubSegments[0], subSubSegments[1]); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return results; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     internal static void Write(string path, ProcessDataStandardFormat processDataStandardFormat, List<Metrology.WS.Results>? wsResults) | ||||||
|     { |     { | ||||||
|         List<string> results = new(); |         List<string> results = new(); | ||||||
|         if (processDataStandardFormat.Sequence is null) |         if (processDataStandardFormat.Sequence is null) | ||||||
| @ -357,7 +509,7 @@ internal class ProcessDataStandardFormat | |||||||
|         results.Add($"HEADER_OFFSET\t{headerOffset}"); |         results.Add($"HEADER_OFFSET\t{headerOffset}"); | ||||||
|         results.Add($"DATA_OFFSET\t{dataOffset}"); |         results.Add($"DATA_OFFSET\t{dataOffset}"); | ||||||
|         results.Add($"END_OFFSET\t{endOffset}"); |         results.Add($"END_OFFSET\t{endOffset}"); | ||||||
|         results.Add($"\"{string.Join("\",\t\"", processDataStandardFormat.Columns)}\""); |         results.Add($"\"{string.Join("\"\t\"", processDataStandardFormat.Columns)}\""); | ||||||
|         results.AddRange(processDataStandardFormat.Body); |         results.AddRange(processDataStandardFormat.Body); | ||||||
|         results.Add($"NUM_DATA_ROWS\t{processDataStandardFormat.Body.Count.ToString().PadLeft(9, '0')}"); |         results.Add($"NUM_DATA_ROWS\t{processDataStandardFormat.Body.Count.ToString().PadLeft(9, '0')}"); | ||||||
|         results.Add($"NUM_DATA_COLUMNS\t{processDataStandardFormat.Columns.Count.ToString().PadLeft(9, '0')}"); |         results.Add($"NUM_DATA_COLUMNS\t{processDataStandardFormat.Columns.Count.ToString().PadLeft(9, '0')}"); | ||||||
| @ -366,7 +518,40 @@ internal class ProcessDataStandardFormat | |||||||
|         results.Add($"START_TIME\t{startTime}"); |         results.Add($"START_TIME\t{startTime}"); | ||||||
|         results.Add("LOGISTICS_COLUMN\tA_LOGISTICS"); |         results.Add("LOGISTICS_COLUMN\tA_LOGISTICS"); | ||||||
|         results.Add("LOGISTICS_COLUMN\tB_LOGISTICS"); |         results.Add("LOGISTICS_COLUMN\tB_LOGISTICS"); | ||||||
|  |         if (wsResults is null || wsResults.Count != 1) | ||||||
|             results.AddRange(processDataStandardFormat.Logistics); |             results.AddRange(processDataStandardFormat.Logistics); | ||||||
|  |         else | ||||||
|  |         { | ||||||
|  |             string[] segments; | ||||||
|  |             foreach (string logistics in processDataStandardFormat.Logistics) | ||||||
|  |             { | ||||||
|  |                 segments = logistics.Split(new string[] { "\t" }, StringSplitOptions.None); | ||||||
|  |                 if (segments.Length != 2 || string.IsNullOrEmpty(segments[1])) | ||||||
|  |                     results.Add(logistics); | ||||||
|  |                 else | ||||||
|  |                     results.Add($"{segments[0]}\t{segments[1][0]}_HeaderId={wsResults[0].HeaderId};{segments[1][0]}_SubgroupId={wsResults[0].SubgroupId};{segments[1]}"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         results.Add("END_HEADER"); | ||||||
|  |         if (processDataStandardFormat.InputPDSF is not null) | ||||||
|  |         { | ||||||
|  |             results.Add(string.Empty); | ||||||
|  |             List<char> hyphens = new(); | ||||||
|  |             results.AddRange(processDataStandardFormat.InputPDSF.Header.Select(l => l.Replace('\t', '|'))); | ||||||
|  |             results.Add(string.Empty); | ||||||
|  |             results.Add($"|{string.Join("|", processDataStandardFormat.InputPDSF.Columns)}|"); | ||||||
|  |             for (int i = 0; i < processDataStandardFormat.InputPDSF.Columns.Count; i++) | ||||||
|  |                 hyphens.Add('-'); | ||||||
|  |             results.Add($"|{string.Join("|", hyphens)}|"); | ||||||
|  |             results.AddRange(processDataStandardFormat.InputPDSF.Body.Select(l => l.Replace('\t', '|'))); | ||||||
|  |             results.Add(string.Empty); | ||||||
|  |             results.AddRange(processDataStandardFormat.InputPDSF.Footer.Select(l => l.Replace('\t', '|'))); | ||||||
|  |             results.Add(string.Empty); | ||||||
|  |             results.Add("EOF"); | ||||||
|  |             results.Add(string.Empty); | ||||||
|  |             string json = GetJson(processDataStandardFormat); | ||||||
|  |             results.Add(json); | ||||||
|  |         } | ||||||
|         File.WriteAllText(path, string.Join(Environment.NewLine, results)); |         File.WriteAllText(path, string.Join(Environment.NewLine, results)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @ -409,7 +594,7 @@ internal class ProcessDataStandardFormat | |||||||
|                 { |                 { | ||||||
|                     for (int c = 1; c < segments.Length; c++) |                     for (int c = 1; c < segments.Length; c++) | ||||||
|                     { |                     { | ||||||
|                         value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\"); |                         value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\""); | ||||||
|                         _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\","); |                         _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":\"").Append(value).Append("\","); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @ -417,7 +602,7 @@ internal class ProcessDataStandardFormat | |||||||
|                 { |                 { | ||||||
|                     for (int c = 1; c < segments.Length; c++) |                     for (int c = 1; c < segments.Length; c++) | ||||||
|                     { |                     { | ||||||
|                         value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\"); |                         value = segments[c].Replace("\\", "\\\\").Replace("\"", "\\\""); | ||||||
|                         if (string.IsNullOrEmpty(value)) |                         if (string.IsNullOrEmpty(value)) | ||||||
|                             _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append("null,"); |                             _ = stringBuilder.Append('"').Append(processDataStandardFormat.Columns[c]).Append("\":").Append(value).Append("null,"); | ||||||
|                         else if (value.All(char.IsDigit)) |                         else if (value.All(char.IsDigit)) | ||||||
| @ -655,3 +840,8 @@ internal class ProcessDataStandardFormat | |||||||
| internal partial class JsonElementCollectionSourceGenerationContext : JsonSerializerContext | internal partial class JsonElementCollectionSourceGenerationContext : JsonSerializerContext | ||||||
| { | { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | [JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] | ||||||
|  | [JsonSerializable(typeof(Dictionary<string, Dictionary<string, string>>))] | ||||||
|  | internal partial class DictionaryStringDictionaryStringStringSourceGenerationContext : JsonSerializerContext { | ||||||
|  | } | ||||||
| @ -1,4 +1,4 @@ | |||||||
| #if true | #if v2_59_0 | ||||||
| using Adaptation._Tests.Shared; | using Adaptation._Tests.Shared; | ||||||
| using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| #if true | #if v2_59_0 | ||||||
| using Adaptation._Tests.Shared; | using Adaptation._Tests.Shared; | ||||||
| using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| #if true | #if v2_59_0 | ||||||
| using Adaptation._Tests.Shared; | using Adaptation._Tests.Shared; | ||||||
| using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||||
|  | |||||||
| @ -0,0 +1,65 @@ | |||||||
|  | #if true | ||||||
|  | using Adaptation._Tests.Shared; | ||||||
|  | using Microsoft.Extensions.Logging; | ||||||
|  | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||||
|  | using System; | ||||||
|  | using System.Diagnostics; | ||||||
|  | using System.IO; | ||||||
|  | using System.Reflection; | ||||||
|  |  | ||||||
|  | namespace Adaptation._Tests.CreateSelfDescription.Development.v2_60_0; | ||||||
|  |  | ||||||
|  | [TestClass] | ||||||
|  | public class BACKLOG_EQPT : EAFLoggingUnitTesting | ||||||
|  | { | ||||||
|  |  | ||||||
|  | #pragma warning disable CA2254 | ||||||
|  | #pragma warning disable IDE0060 | ||||||
|  |  | ||||||
|  |     internal static string DummyRoot { get; private set; } | ||||||
|  |     internal static BACKLOG_EQPT EAFLoggingUnitTesting { get; private set; } | ||||||
|  |  | ||||||
|  |     static BACKLOG_EQPT() => DummyRoot = @"\\mesfs.infineon.com\EC_Characterization_Si\Dummy"; | ||||||
|  |  | ||||||
|  |     public BACKLOG_EQPT() : base(DummyRoot, testContext: null, declaringType: null, skipEquipmentDictionary: false) | ||||||
|  |     { | ||||||
|  |         if (EAFLoggingUnitTesting is null) | ||||||
|  |             throw new Exception(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public BACKLOG_EQPT(TestContext testContext) : base(DummyRoot, testContext, new StackFrame().GetMethod().DeclaringType, skipEquipmentDictionary: false) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [ClassInitialize] | ||||||
|  |     public static void ClassInitialize(TestContext testContext) | ||||||
|  |     { | ||||||
|  |         EAFLoggingUnitTesting ??= new BACKLOG_EQPT(testContext); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(testContext.TestName, " - ClassInitialize")); | ||||||
|  |         string[] fileNameAndText = EAFLoggingUnitTesting.AdaptationTesting.GetCSharpText(testContext.TestName); | ||||||
|  |         File.WriteAllText(fileNameAndText[0], fileNameAndText[1]); | ||||||
|  |         File.WriteAllText(fileNameAndText[2], fileNameAndText[3]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [ClassCleanup()] | ||||||
|  |     public static void ClassCleanup() | ||||||
|  |     { | ||||||
|  |         EAFLoggingUnitTesting.Logger?.LogInformation("Cleanup"); | ||||||
|  |         EAFLoggingUnitTesting?.Dispose(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__BACKLOG_EQPT__DownloadWorkItems() | ||||||
|  |     { | ||||||
|  |         string check = ".xlsx"; | ||||||
|  |         MethodBase methodBase = new StackFrame().GetMethod(); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Getting configuration")); | ||||||
|  |         _ = AdaptationTesting.GetWriteConfigurationGetFileRead(methodBase, check, EAFLoggingUnitTesting.AdaptationTesting); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|  | #endif | ||||||
| @ -0,0 +1,65 @@ | |||||||
|  | #if true | ||||||
|  | using Adaptation._Tests.Shared; | ||||||
|  | using Microsoft.Extensions.Logging; | ||||||
|  | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||||
|  | using System; | ||||||
|  | using System.Diagnostics; | ||||||
|  | using System.IO; | ||||||
|  | using System.Reflection; | ||||||
|  |  | ||||||
|  | namespace Adaptation._Tests.CreateSelfDescription.Development.v2_60_0; | ||||||
|  |  | ||||||
|  | [TestClass] | ||||||
|  | public class BACKLOG : EAFLoggingUnitTesting | ||||||
|  | { | ||||||
|  |  | ||||||
|  | #pragma warning disable CA2254 | ||||||
|  | #pragma warning disable IDE0060 | ||||||
|  |  | ||||||
|  |     internal static string DummyRoot { get; private set; } | ||||||
|  |     internal static BACKLOG EAFLoggingUnitTesting { get; private set; } | ||||||
|  |  | ||||||
|  |     static BACKLOG() => DummyRoot = @"\\mesfs.infineon.com\EC_Characterization_Si\Dummy"; | ||||||
|  |  | ||||||
|  |     public BACKLOG() : base(DummyRoot, testContext: null, declaringType: null, skipEquipmentDictionary: false) | ||||||
|  |     { | ||||||
|  |         if (EAFLoggingUnitTesting is null) | ||||||
|  |             throw new Exception(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public BACKLOG(TestContext testContext) : base(DummyRoot, testContext, new StackFrame().GetMethod().DeclaringType, skipEquipmentDictionary: false) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [ClassInitialize] | ||||||
|  |     public static void ClassInitialize(TestContext testContext) | ||||||
|  |     { | ||||||
|  |         EAFLoggingUnitTesting ??= new BACKLOG(testContext); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(testContext.TestName, " - ClassInitialize")); | ||||||
|  |         string[] fileNameAndText = EAFLoggingUnitTesting.AdaptationTesting.GetCSharpText(testContext.TestName); | ||||||
|  |         File.WriteAllText(fileNameAndText[0], fileNameAndText[1]); | ||||||
|  |         File.WriteAllText(fileNameAndText[2], fileNameAndText[3]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [ClassCleanup()] | ||||||
|  |     public static void ClassCleanup() | ||||||
|  |     { | ||||||
|  |         EAFLoggingUnitTesting.Logger?.LogInformation("Cleanup"); | ||||||
|  |         EAFLoggingUnitTesting?.Dispose(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__BACKLOG__json() | ||||||
|  |     { | ||||||
|  |         string check = "*.json"; | ||||||
|  |         MethodBase methodBase = new StackFrame().GetMethod(); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Getting configuration")); | ||||||
|  |         _ = AdaptationTesting.GetWriteConfigurationGetFileRead(methodBase, check, EAFLoggingUnitTesting.AdaptationTesting); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|  | #endif | ||||||
| @ -0,0 +1,117 @@ | |||||||
|  | #if true | ||||||
|  | using Adaptation._Tests.Shared; | ||||||
|  | using Microsoft.Extensions.Logging; | ||||||
|  | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||||
|  | using System; | ||||||
|  | using System.Diagnostics; | ||||||
|  | using System.IO; | ||||||
|  | using System.Reflection; | ||||||
|  |  | ||||||
|  | namespace Adaptation._Tests.CreateSelfDescription.Development.v2_60_0; | ||||||
|  |  | ||||||
|  | [TestClass] | ||||||
|  | public class MESAFIBACKLOG : EAFLoggingUnitTesting | ||||||
|  | { | ||||||
|  |  | ||||||
|  | #pragma warning disable CA2254 | ||||||
|  | #pragma warning disable IDE0060 | ||||||
|  |  | ||||||
|  |     internal static string DummyRoot { get; private set; } | ||||||
|  |     internal static MESAFIBACKLOG EAFLoggingUnitTesting { get; private set; } | ||||||
|  |  | ||||||
|  |     static MESAFIBACKLOG() => DummyRoot = @"\\mesfs.infineon.com\EC_Characterization_Si\Dummy"; | ||||||
|  |  | ||||||
|  |     public MESAFIBACKLOG() : base(DummyRoot, testContext: null, declaringType: null, skipEquipmentDictionary: false) | ||||||
|  |     { | ||||||
|  |         if (EAFLoggingUnitTesting is null) | ||||||
|  |             throw new Exception(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public MESAFIBACKLOG(TestContext testContext) : base(DummyRoot, testContext, new StackFrame().GetMethod().DeclaringType, skipEquipmentDictionary: false) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [ClassInitialize] | ||||||
|  |     public static void ClassInitialize(TestContext testContext) | ||||||
|  |     { | ||||||
|  |         EAFLoggingUnitTesting ??= new MESAFIBACKLOG(testContext); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(testContext.TestName, " - ClassInitialize")); | ||||||
|  |         string[] fileNameAndText = EAFLoggingUnitTesting.AdaptationTesting.GetCSharpText(testContext.TestName); | ||||||
|  |         File.WriteAllText(fileNameAndText[0], fileNameAndText[1]); | ||||||
|  |         File.WriteAllText(fileNameAndText[2], fileNameAndText[3]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [ClassCleanup()] | ||||||
|  |     public static void ClassCleanup() | ||||||
|  |     { | ||||||
|  |         EAFLoggingUnitTesting.Logger?.LogInformation("Cleanup"); | ||||||
|  |         EAFLoggingUnitTesting?.Dispose(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__MESAFIBACKLOG__Kanban() | ||||||
|  |     { | ||||||
|  |         string check = "*.json"; | ||||||
|  |         MethodBase methodBase = new StackFrame().GetMethod(); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Getting configuration")); | ||||||
|  |         _ = AdaptationTesting.GetWriteConfigurationGetFileRead(methodBase, check, EAFLoggingUnitTesting.AdaptationTesting); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__MESAFIBACKLOG__Markdown() | ||||||
|  |     { | ||||||
|  |         string check = "*.json"; | ||||||
|  |         MethodBase methodBase = new StackFrame().GetMethod(); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Getting configuration")); | ||||||
|  |         _ = AdaptationTesting.GetWriteConfigurationGetFileRead(methodBase, check, EAFLoggingUnitTesting.AdaptationTesting); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__MESAFIBACKLOG__ADO() | ||||||
|  |     { | ||||||
|  |         string check = "*.json"; | ||||||
|  |         MethodBase methodBase = new StackFrame().GetMethod(); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Getting configuration")); | ||||||
|  |         _ = AdaptationTesting.GetWriteConfigurationGetFileRead(methodBase, check, EAFLoggingUnitTesting.AdaptationTesting); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__MESAFIBACKLOG__Priority() | ||||||
|  |     { | ||||||
|  |         string check = "*.json"; | ||||||
|  |         MethodBase methodBase = new StackFrame().GetMethod(); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Getting configuration")); | ||||||
|  |         _ = AdaptationTesting.GetWriteConfigurationGetFileRead(methodBase, check, EAFLoggingUnitTesting.AdaptationTesting); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__MESAFIBACKLOG__Violation() | ||||||
|  |     { | ||||||
|  |         string check = "*.json"; | ||||||
|  |         MethodBase methodBase = new StackFrame().GetMethod(); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Getting configuration")); | ||||||
|  |         _ = AdaptationTesting.GetWriteConfigurationGetFileRead(methodBase, check, EAFLoggingUnitTesting.AdaptationTesting); | ||||||
|  |         EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|  | #endif | ||||||
| @ -1,4 +1,4 @@ | |||||||
| #if true | #if v2_59_0 | ||||||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||||
| using System; | using System; | ||||||
| using System.Diagnostics; | using System.Diagnostics; | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| #if true | #if v2_59_0 | ||||||
| using Adaptation.Shared; | using Adaptation.Shared; | ||||||
| using Adaptation.Shared.Methods; | using Adaptation.Shared.Methods; | ||||||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||||
|  | |||||||
| @ -1,6 +1,5 @@ | |||||||
| #if true | #if v2_59_0 | ||||||
| using Adaptation.FileHandlers.json.WorkItems; | using Adaptation.FileHandlers.json.WorkItems; | ||||||
| using Adaptation.FileHandlers.Priority; |  | ||||||
| using Adaptation.Shared; | using Adaptation.Shared; | ||||||
| using Adaptation.Shared.Methods; | using Adaptation.Shared.Methods; | ||||||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||||
| @ -190,18 +189,6 @@ public class MESAFIBACKLOG | |||||||
|         Assert.IsFalse(string.IsNullOrEmpty(extractResult?.Item1)); |         Assert.IsFalse(string.IsNullOrEmpty(extractResult?.Item1)); | ||||||
|         Assert.IsNotNull(extractResult.Item3); |         Assert.IsNotNull(extractResult.Item3); | ||||||
|         Assert.IsNotNull(extractResult.Item4); |         Assert.IsNotNull(extractResult.Item4); | ||||||
|         WeightedShortestJobFirstHub weightedShortestJobFirstHub = new(); |  | ||||||
|         Notification notification = new(fibonacci: null, |  | ||||||
|                                         id: 1107438888, |  | ||||||
|                                         inverse: null, |  | ||||||
|                                         machineId: Environment.MachineName, |  | ||||||
|                                         page: "effort", |  | ||||||
|                                         remoteIpAddress: "10.95.36.87", |  | ||||||
|                                         site: "MES", |  | ||||||
|                                         time: 1737573418926, |  | ||||||
|                                         username: Environment.UserName, |  | ||||||
|                                         value: 1); |  | ||||||
|         weightedShortestJobFirstHub.NotifyAll(notification); |  | ||||||
|         NonThrowTryCatch(); |         NonThrowTryCatch(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | |||||||
| @ -0,0 +1,52 @@ | |||||||
|  | #if true | ||||||
|  | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||||
|  | using System; | ||||||
|  | using System.Diagnostics; | ||||||
|  | using System.Reflection; | ||||||
|  | using System.Threading; | ||||||
|  |  | ||||||
|  | namespace Adaptation._Tests.Extract.Development.v2_60_0; | ||||||
|  |  | ||||||
|  | [TestClass] | ||||||
|  | public class BACKLOG_EQPT | ||||||
|  | { | ||||||
|  |  | ||||||
|  | #pragma warning disable CA2254 | ||||||
|  | #pragma warning disable IDE0060 | ||||||
|  |  | ||||||
|  |     private static CreateSelfDescription.Development.v2_60_0.BACKLOG_EQPT _BACKLOG_EQPT; | ||||||
|  |  | ||||||
|  |     [ClassInitialize] | ||||||
|  |     public static void ClassInitialize(TestContext testContext) | ||||||
|  |     { | ||||||
|  |         CreateSelfDescription.Development.v2_60_0.BACKLOG_EQPT.ClassInitialize(testContext); | ||||||
|  |         _BACKLOG_EQPT = CreateSelfDescription.Development.v2_60_0.BACKLOG_EQPT.EAFLoggingUnitTesting; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static void NonThrowTryCatch() | ||||||
|  |     { | ||||||
|  |         try | ||||||
|  |         { throw new Exception(); } | ||||||
|  |         catch (Exception) { } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     [Ignore] | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__BACKLOG_EQPT__DownloadWorkItems() => _BACKLOG_EQPT.Development__v2_60_0__BACKLOG_EQPT__DownloadWorkItems(); | ||||||
|  |  | ||||||
|  |     [Ignore] | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__BACKLOG_EQPT__DownloadWorkItems638612245609095845__Normal() | ||||||
|  |     { | ||||||
|  |         string check = ".json"; | ||||||
|  |         bool validatePDSF = false; | ||||||
|  |         MethodBase methodBase = new StackFrame().GetMethod(); | ||||||
|  |         _BACKLOG_EQPT.Development__v2_60_0__BACKLOG_EQPT__DownloadWorkItems(); | ||||||
|  |         _ = _BACKLOG_EQPT.AdaptationTesting.GetVariables(methodBase, check, validatePDSF); | ||||||
|  |         for (int i = 0; i < int.MinValue; i++) | ||||||
|  |             Thread.Sleep(500); | ||||||
|  |         NonThrowTryCatch(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|  | #endif | ||||||
							
								
								
									
										64
									
								
								Adaptation/_Tests/Extract/Development/v2.60.0/BACKLOG.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								Adaptation/_Tests/Extract/Development/v2.60.0/BACKLOG.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,64 @@ | |||||||
|  | #if true | ||||||
|  | using Adaptation.Shared; | ||||||
|  | using Adaptation.Shared.Methods; | ||||||
|  | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Diagnostics; | ||||||
|  | using System.IO; | ||||||
|  | using System.Reflection; | ||||||
|  | using System.Text.Json; | ||||||
|  |  | ||||||
|  | namespace Adaptation._Tests.Extract.Development.v2_60_0; | ||||||
|  |  | ||||||
|  | [TestClass] | ||||||
|  | public class BACKLOG | ||||||
|  | { | ||||||
|  |  | ||||||
|  | #pragma warning disable CA2254 | ||||||
|  | #pragma warning disable IDE0060 | ||||||
|  |  | ||||||
|  |     private static CreateSelfDescription.Development.v2_60_0.BACKLOG _BACKLOG; | ||||||
|  |  | ||||||
|  |     [ClassInitialize] | ||||||
|  |     public static void ClassInitialize(TestContext testContext) | ||||||
|  |     { | ||||||
|  |         CreateSelfDescription.Development.v2_60_0.BACKLOG.ClassInitialize(testContext); | ||||||
|  |         _BACKLOG = CreateSelfDescription.Development.v2_60_0.BACKLOG.EAFLoggingUnitTesting; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static void NonThrowTryCatch() | ||||||
|  |     { | ||||||
|  |         try | ||||||
|  |         { throw new Exception(); } | ||||||
|  |         catch (Exception) { } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__BACKLOG__json() => _BACKLOG.Development__v2_60_0__BACKLOG__json(); | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__BACKLOG__json638612245609095846__Normal() | ||||||
|  |     { | ||||||
|  |         string check = "*.json"; | ||||||
|  |         bool validatePDSF = false; | ||||||
|  |         _BACKLOG.Development__v2_60_0__BACKLOG__json(); | ||||||
|  |         MethodBase methodBase = new StackFrame().GetMethod(); | ||||||
|  |         Assert.IsFalse(string.IsNullOrEmpty(_BACKLOG.AdaptationTesting.TestContext.FullyQualifiedTestClassName)); | ||||||
|  |         string[] variables = _BACKLOG.AdaptationTesting.GetVariables(methodBase, check, validatePDSF); | ||||||
|  |         IFileRead fileRead = _BACKLOG.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false); | ||||||
|  |         Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResult = fileRead.ReExtract(); | ||||||
|  |         Assert.IsFalse(string.IsNullOrEmpty(extractResult?.Item1)); | ||||||
|  |         Assert.IsNotNull(extractResult.Item3); | ||||||
|  |         Assert.IsNotNull(extractResult.Item4); | ||||||
|  |         NonThrowTryCatch(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|  | #endif | ||||||
							
								
								
									
										249
									
								
								Adaptation/_Tests/Extract/Development/v2.60.0/MESAFIBACKLOG.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								Adaptation/_Tests/Extract/Development/v2.60.0/MESAFIBACKLOG.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,249 @@ | |||||||
|  | #if true | ||||||
|  | using Adaptation.FileHandlers.json.WorkItems; | ||||||
|  | using Adaptation.Shared; | ||||||
|  | using Adaptation.Shared.Methods; | ||||||
|  | using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.Collections.ObjectModel; | ||||||
|  | using System.Diagnostics; | ||||||
|  | using System.IO; | ||||||
|  | using System.Reflection; | ||||||
|  | using System.Text.Json; | ||||||
|  |  | ||||||
|  | namespace Adaptation._Tests.Extract.Development.v2_60_0; | ||||||
|  |  | ||||||
|  | [TestClass] | ||||||
|  | public class MESAFIBACKLOG | ||||||
|  | { | ||||||
|  |  | ||||||
|  | #pragma warning disable CA2254 | ||||||
|  | #pragma warning disable IDE0060 | ||||||
|  |  | ||||||
|  |     private static CreateSelfDescription.Development.v2_60_0.MESAFIBACKLOG _MESAFIBACKLOG; | ||||||
|  |  | ||||||
|  |     [ClassInitialize] | ||||||
|  |     public static void ClassInitialize(TestContext testContext) | ||||||
|  |     { | ||||||
|  |         CreateSelfDescription.Development.v2_60_0.MESAFIBACKLOG.ClassInitialize(testContext); | ||||||
|  |         _MESAFIBACKLOG = CreateSelfDescription.Development.v2_60_0.MESAFIBACKLOG.EAFLoggingUnitTesting; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static void NonThrowTryCatch() | ||||||
|  |     { | ||||||
|  |         try | ||||||
|  |         { throw new Exception(); } | ||||||
|  |         catch (Exception) { } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__MESAFIBACKLOG__Kanban() => _MESAFIBACKLOG.Development__v2_60_0__MESAFIBACKLOG__Kanban(); | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__MESAFIBACKLOG__Kanban638323658386612552__Normal() | ||||||
|  |     { | ||||||
|  |         string check = "*.json"; | ||||||
|  |         bool validatePDSF = false; | ||||||
|  |         MethodBase methodBase = new StackFrame().GetMethod(); | ||||||
|  |         _MESAFIBACKLOG.Development__v2_60_0__MESAFIBACKLOG__Kanban(); | ||||||
|  |         Assert.IsFalse(string.IsNullOrEmpty(_MESAFIBACKLOG.AdaptationTesting.TestContext.FullyQualifiedTestClassName)); | ||||||
|  |         string[] variables = _MESAFIBACKLOG.AdaptationTesting.GetVariables(methodBase, check, validatePDSF); | ||||||
|  |         IFileRead fileRead = _MESAFIBACKLOG.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false); | ||||||
|  |         Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResult = fileRead.ReExtract(); | ||||||
|  |         Assert.IsFalse(string.IsNullOrEmpty(extractResult?.Item1)); | ||||||
|  |         Assert.IsNotNull(extractResult.Item3); | ||||||
|  |         Assert.IsNotNull(extractResult.Item4); | ||||||
|  |         NonThrowTryCatch(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__MESAFIBACKLOG__Markdown() => _MESAFIBACKLOG.Development__v2_60_0__MESAFIBACKLOG__Markdown(); | ||||||
|  |  | ||||||
|  |     private static ReadOnlyDictionary<string, FileInfo> GetKeyValuePairs(List<FileInfo> collection) | ||||||
|  |     { | ||||||
|  |         Dictionary<string, FileInfo> results = []; | ||||||
|  |         foreach (FileInfo fileInfo in collection) | ||||||
|  |             results.Add(fileInfo.Name, fileInfo); | ||||||
|  |         return new(results); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static ReadOnlyCollection<Record> GetRecords(FileInfo fileInfo) | ||||||
|  |     { | ||||||
|  |         Record[] results; | ||||||
|  |         string json = File.ReadAllText(fileInfo.FullName); | ||||||
|  |         results = JsonSerializer.Deserialize<Record[]>(json); | ||||||
|  |         return new(results); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static void Verify122508(FileInfo fileInfo) | ||||||
|  |     { | ||||||
|  |         ReadOnlyCollection<Record> records = GetRecords(fileInfo); | ||||||
|  |         Assert.IsNotNull(records); | ||||||
|  |         // Assert.IsTrue(records.Count == 10); | ||||||
|  |         // Assert.IsTrue(records.Count == 6); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static void Verify122514(FileInfo fileInfo) | ||||||
|  |     { | ||||||
|  |         ReadOnlyCollection<Record> records = GetRecords(fileInfo); | ||||||
|  |         Assert.IsNotNull(records); | ||||||
|  |         // Assert.IsTrue(records.Count == 25); | ||||||
|  |         // Assert.IsTrue(records.Count == 6); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static void Verify126169(FileInfo fileInfo) | ||||||
|  |     { | ||||||
|  |         ReadOnlyCollection<Record> records = GetRecords(fileInfo); | ||||||
|  |         Assert.IsNotNull(records); | ||||||
|  |         // Assert.IsTrue(records.Count == 1); | ||||||
|  |         // Assert.IsTrue(records.Count == 1); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static void Verify123066(FileInfo fileInfo) | ||||||
|  |     { | ||||||
|  |         ReadOnlyCollection<Record> records = GetRecords(fileInfo); | ||||||
|  |         Assert.IsNotNull(records); | ||||||
|  |         // Assert.IsTrue(records.Count == 24); | ||||||
|  |         // Assert.IsTrue(records.Count == 5); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static void Verify123067(FileInfo fileInfo) | ||||||
|  |     { | ||||||
|  |         ReadOnlyCollection<Record> records = GetRecords(fileInfo); | ||||||
|  |         Assert.IsNotNull(records); | ||||||
|  |         // Assert.IsTrue(records.Count == 24); | ||||||
|  |         // Assert.IsTrue(records.Count == 5); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private static void Verify122517(FileInfo fileInfo) | ||||||
|  |     { | ||||||
|  |         ReadOnlyCollection<Record> records = GetRecords(fileInfo); | ||||||
|  |         Assert.IsNotNull(records); | ||||||
|  |         // Assert.IsTrue(records.Count == 14); | ||||||
|  |         // Assert.IsTrue(records.Count == 14); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__MESAFIBACKLOG__Markdown638323658386612552__Normal() | ||||||
|  |     { | ||||||
|  |         string check = "*.json"; | ||||||
|  |         bool validatePDSF = false; | ||||||
|  |         MethodBase methodBase = new StackFrame().GetMethod(); | ||||||
|  |         _MESAFIBACKLOG.Development__v2_60_0__MESAFIBACKLOG__Markdown(); | ||||||
|  |         Assert.IsFalse(string.IsNullOrEmpty(_MESAFIBACKLOG.AdaptationTesting.TestContext.FullyQualifiedTestClassName)); | ||||||
|  |         string[] variables = _MESAFIBACKLOG.AdaptationTesting.GetVariables(methodBase, check, validatePDSF); | ||||||
|  |         IFileRead fileRead = _MESAFIBACKLOG.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false); | ||||||
|  |         Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResult = fileRead.ReExtract(); | ||||||
|  |         Assert.IsFalse(string.IsNullOrEmpty(extractResult?.Item1)); | ||||||
|  |         Assert.IsNotNull(extractResult.Item3); | ||||||
|  |         Assert.IsNotNull(extractResult.Item4); | ||||||
|  |         NonThrowTryCatch(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__MESAFIBACKLOG__ADO638323658386612552__Normal() | ||||||
|  |     { | ||||||
|  |         string check = "*.json"; | ||||||
|  |         bool validatePDSF = false; | ||||||
|  |         MethodBase methodBase = new StackFrame().GetMethod(); | ||||||
|  |         _MESAFIBACKLOG.Development__v2_60_0__MESAFIBACKLOG__ADO(); | ||||||
|  |         Assert.IsFalse(string.IsNullOrEmpty(_MESAFIBACKLOG.AdaptationTesting.TestContext.FullyQualifiedTestClassName)); | ||||||
|  |         string[] variables = _MESAFIBACKLOG.AdaptationTesting.GetVariables(methodBase, check, validatePDSF); | ||||||
|  |         IFileRead fileRead = _MESAFIBACKLOG.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false); | ||||||
|  |         Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResult = fileRead.ReExtract(); | ||||||
|  |         Assert.IsFalse(string.IsNullOrEmpty(extractResult?.Item1)); | ||||||
|  |         Assert.IsNotNull(extractResult.Item3); | ||||||
|  |         Assert.IsNotNull(extractResult.Item4); | ||||||
|  |         NonThrowTryCatch(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__MESAFIBACKLOG__Priority638323658386612552__Normal() | ||||||
|  |     { | ||||||
|  |         string check = "*.json"; | ||||||
|  |         bool validatePDSF = false; | ||||||
|  |         MethodBase methodBase = new StackFrame().GetMethod(); | ||||||
|  |         _MESAFIBACKLOG.Development__v2_60_0__MESAFIBACKLOG__Priority(); | ||||||
|  |         Assert.IsFalse(string.IsNullOrEmpty(_MESAFIBACKLOG.AdaptationTesting.TestContext.FullyQualifiedTestClassName)); | ||||||
|  |         string[] variables = _MESAFIBACKLOG.AdaptationTesting.GetVariables(methodBase, check, validatePDSF); | ||||||
|  |         IFileRead fileRead = _MESAFIBACKLOG.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false); | ||||||
|  |         Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResult = fileRead.ReExtract(); | ||||||
|  |         Assert.IsFalse(string.IsNullOrEmpty(extractResult?.Item1)); | ||||||
|  |         Assert.IsNotNull(extractResult.Item3); | ||||||
|  |         Assert.IsNotNull(extractResult.Item4); | ||||||
|  |         NonThrowTryCatch(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__MESAFIBACKLOG__Markdown638779784153157286__Normal() | ||||||
|  |     { | ||||||
|  |         string check = "*.json"; | ||||||
|  |         bool validatePDSF = false; | ||||||
|  |         MethodBase methodBase = new StackFrame().GetMethod(); | ||||||
|  |         _MESAFIBACKLOG.Development__v2_60_0__MESAFIBACKLOG__Markdown(); | ||||||
|  |         Assert.IsFalse(string.IsNullOrEmpty(_MESAFIBACKLOG.AdaptationTesting.TestContext.FullyQualifiedTestClassName)); | ||||||
|  |         string[] variables = _MESAFIBACKLOG.AdaptationTesting.GetVariables(methodBase, check, validatePDSF); | ||||||
|  |         IFileRead fileRead = _MESAFIBACKLOG.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false); | ||||||
|  |         Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResult = fileRead.ReExtract(); | ||||||
|  |         Assert.IsFalse(string.IsNullOrEmpty(extractResult?.Item1)); | ||||||
|  |         Assert.IsNotNull(extractResult.Item3); | ||||||
|  |         Assert.IsNotNull(extractResult.Item4); | ||||||
|  |         NonThrowTryCatch(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | #if DEBUG | ||||||
|  |     [Ignore] | ||||||
|  | #endif | ||||||
|  |     [TestMethod] | ||||||
|  |     public void Development__v2_60_0__MESAFIBACKLOG__Violation638779784153157287__Normal() | ||||||
|  |     { | ||||||
|  |         string check = "*.json"; | ||||||
|  |         bool validatePDSF = false; | ||||||
|  |         MethodBase methodBase = new StackFrame().GetMethod(); | ||||||
|  |         _MESAFIBACKLOG.Development__v2_60_0__MESAFIBACKLOG__Violation(); | ||||||
|  |         Assert.IsFalse(string.IsNullOrEmpty(_MESAFIBACKLOG.AdaptationTesting.TestContext.FullyQualifiedTestClassName)); | ||||||
|  |         string[] variables = _MESAFIBACKLOG.AdaptationTesting.GetVariables(methodBase, check, validatePDSF); | ||||||
|  |         IFileRead fileRead = _MESAFIBACKLOG.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false); | ||||||
|  |         Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResult = fileRead.ReExtract(); | ||||||
|  |         Assert.IsFalse(string.IsNullOrEmpty(extractResult?.Item1)); | ||||||
|  |         Assert.IsNotNull(extractResult.Item3); | ||||||
|  |         Assert.IsNotNull(extractResult.Item4); | ||||||
|  |         ReadOnlyDictionary<string, FileInfo> keyValuePairs = GetKeyValuePairs(extractResult.Item4); | ||||||
|  |         Assert.IsTrue(keyValuePairs.ContainsKey("check-122508.json")); | ||||||
|  |         Assert.IsTrue(keyValuePairs.ContainsKey("check-122514.json")); | ||||||
|  |         Assert.IsTrue(keyValuePairs.ContainsKey("check-126169.json")); | ||||||
|  |         Assert.IsTrue(keyValuePairs.ContainsKey("check-123066.json")); | ||||||
|  |         Assert.IsTrue(keyValuePairs.ContainsKey("check-123067.json")); | ||||||
|  |         Assert.IsTrue(keyValuePairs.ContainsKey("check-122517.json")); | ||||||
|  |         Verify122508(keyValuePairs["check-122508.json"]); | ||||||
|  |         Verify122514(keyValuePairs["check-122514.json"]); | ||||||
|  |         Verify126169(keyValuePairs["check-126169.json"]); | ||||||
|  |         Verify123066(keyValuePairs["check-123066.json"]); | ||||||
|  |         Verify123067(keyValuePairs["check-123067.json"]); | ||||||
|  |         Verify122517(keyValuePairs["check-122517.json"]); | ||||||
|  |         NonThrowTryCatch(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|  | #endif | ||||||
| @ -977,7 +977,7 @@ public class AdaptationTesting : ISMTP | |||||||
|         if (!string.IsNullOrEmpty(mbn.CellInstanceConnectionName) && !Directory.Exists(fileInfo.DirectoryName)) |         if (!string.IsNullOrEmpty(mbn.CellInstanceConnectionName) && !Directory.Exists(fileInfo.DirectoryName)) | ||||||
|             _ = Directory.CreateDirectory(fileInfo.Directory.FullName); |             _ = Directory.CreateDirectory(fileInfo.Directory.FullName); | ||||||
|         Dictionary<string, List<long>> dummyRuns = new(); |         Dictionary<string, List<long>> dummyRuns = new(); | ||||||
|         Dictionary<long, List<string>> staticRuns = new(); |         Dictionary<long, List<Adaptation.Shared.Metrology.WS.Results>> staticRuns = new(); | ||||||
|         Tuple<string, CellInstanceVersion> cellInstanceVersionTuple = GetCellInstanceVersionTuple(mbn.CellInstanceName, mbn.CellInstanceVersionName); |         Tuple<string, CellInstanceVersion> cellInstanceVersionTuple = GetCellInstanceVersionTuple(mbn.CellInstanceName, mbn.CellInstanceVersionName); | ||||||
|         Tuple<string, FileConnectorConfiguration> fileConnectorConfigurationTuple = GetFileConnectorConfigurationTuple(cellInstanceVersionTuple, mbn.CellInstanceConnectionName); |         Tuple<string, FileConnectorConfiguration> fileConnectorConfigurationTuple = GetFileConnectorConfigurationTuple(cellInstanceVersionTuple, mbn.CellInstanceConnectionName); | ||||||
|         Tuple<string, string, string, EquipmentTypeVersion> equipmentTypeVersionTuple = GetEquipmentTypeVersionTuple(cellInstanceVersionTuple.Item2, mbn.CellInstanceConnectionName); |         Tuple<string, string, string, EquipmentTypeVersion> equipmentTypeVersionTuple = GetEquipmentTypeVersionTuple(cellInstanceVersionTuple.Item2, mbn.CellInstanceConnectionName); | ||||||
| @ -1182,7 +1182,7 @@ public class AdaptationTesting : ISMTP | |||||||
|             Assert.IsNotNull(extractResult.Item3); |             Assert.IsNotNull(extractResult.Item3); | ||||||
|             Assert.IsNotNull(extractResult.Item4); |             Assert.IsNotNull(extractResult.Item4); | ||||||
|             if (!validatePDSF) |             if (!validatePDSF) | ||||||
|                 _ = GetProcessDataStandardFormat(fileRead, logistics, extractResult, ProcessDataStandardFormat.GetEmpty()); |                 _ = GetProcessDataStandardFormat(fileRead, logistics, extractResult, ProcessDataStandardFormat.GetEmpty(logistics)); | ||||||
|             else |             else | ||||||
|             { |             { | ||||||
|                 Assert.IsTrue(extractResult.Item3.Length > 0, "extractResult Array Length check!"); |                 Assert.IsTrue(extractResult.Item3.Length > 0, "extractResult Array Length check!"); | ||||||
|  | |||||||
| @ -64,8 +64,8 @@ public class BACKLOG : LoggingUnitTesting, IDisposable | |||||||
|         StringBuilder results = new(); |         StringBuilder results = new(); | ||||||
|         (string cellInstanceName, string cellInstanceVersionName)[] collection = new (string, string)[] |         (string cellInstanceName, string cellInstanceVersionName)[] collection = new (string, string)[] | ||||||
|         { |         { | ||||||
|             new("BACKLOG", "v2.59.0"), |             new("BACKLOG", "v2.60.0"), | ||||||
|             new("BACKLOG-EQPT", "v2.59.0"), |             new("BACKLOG-EQPT", "v2.60.0"), | ||||||
|         }; |         }; | ||||||
|         string development = "http://eaf-dev.mes.infineon.com:9003/CellInstanceServiceV2"; |         string development = "http://eaf-dev.mes.infineon.com:9003/CellInstanceServiceV2"; | ||||||
|         Shared.PasteSpecialXml.EAF.XML.API.CellInstance.CellInstanceVersion cellInstanceVersion; |         Shared.PasteSpecialXml.EAF.XML.API.CellInstance.CellInstanceVersion cellInstanceVersion; | ||||||
|  | |||||||
| @ -64,7 +64,7 @@ public class MESAFIBACKLOG : LoggingUnitTesting, IDisposable | |||||||
|         StringBuilder results = new(); |         StringBuilder results = new(); | ||||||
|         (string cellInstanceName, string cellInstanceVersionName)[] collection = new (string, string)[] |         (string cellInstanceName, string cellInstanceVersionName)[] collection = new (string, string)[] | ||||||
|         { |         { | ||||||
|             new("MESAFIBACKLOG", "v2.59.0"), |             new("MESAFIBACKLOG", "v2.60.0"), | ||||||
|         }; |         }; | ||||||
|         string development = "http://eaf-dev.mes.infineon.com:9003/CellInstanceServiceV2"; |         string development = "http://eaf-dev.mes.infineon.com:9003/CellInstanceServiceV2"; | ||||||
|         Shared.PasteSpecialXml.EAF.XML.API.CellInstance.CellInstanceVersion cellInstanceVersion; |         Shared.PasteSpecialXml.EAF.XML.API.CellInstance.CellInstanceVersion cellInstanceVersion; | ||||||
|  | |||||||
| @ -1,4 +1,14 @@ | |||||||
| { | { | ||||||
|  |     "name": "adaptation", | ||||||
|  |     "module": "index.ts", | ||||||
|  |     "type": "module", | ||||||
|  |     "private": true, | ||||||
|  |     "devDependencies": { | ||||||
|  |         "@types/bun": "latest" | ||||||
|  |     }, | ||||||
|  |     "peerDependencies": { | ||||||
|  |         "typescript": "^5" | ||||||
|  |     }, | ||||||
|     "scripts": { |     "scripts": { | ||||||
|         "AA-CreateSelfDescription.Staging.v2_43_0-BACKLOG_EQPT": "dotnet test --runtime win-x64 --no-build --filter \"FullyQualifiedName~Adaptation._Tests.CreateSelfDescription.Staging.v2_43_0 & ClassName~BACKLOG_EQPT\" -- TestRunParameters.Parameter(name=\\\"WaitFor\\\", value=\\\"Debugger.IsAttached\\\")", |         "AA-CreateSelfDescription.Staging.v2_43_0-BACKLOG_EQPT": "dotnet test --runtime win-x64 --no-build --filter \"FullyQualifiedName~Adaptation._Tests.CreateSelfDescription.Staging.v2_43_0 & ClassName~BACKLOG_EQPT\" -- TestRunParameters.Parameter(name=\\\"WaitFor\\\", value=\\\"Debugger.IsAttached\\\")", | ||||||
|         "BA-CreateSelfDescription.Staging.v2_43_0-BACKLOG": "dotnet test --runtime win-x64 --no-build --filter \"FullyQualifiedName~Adaptation._Tests.CreateSelfDescription.Staging.v2_43_0 & ClassName~BACKLOG\" -- TestRunParameters.Parameter(name=\\\"WaitFor\\\", value=\\\"Debugger.IsAttached\\\")", |         "BA-CreateSelfDescription.Staging.v2_43_0-BACKLOG": "dotnet test --runtime win-x64 --no-build --filter \"FullyQualifiedName~Adaptation._Tests.CreateSelfDescription.Staging.v2_43_0 & ClassName~BACKLOG\" -- TestRunParameters.Parameter(name=\\\"WaitFor\\\", value=\\\"Debugger.IsAttached\\\")", | ||||||
|  | |||||||
							
								
								
									
										29
									
								
								Adaptation/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								Adaptation/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | { | ||||||
|  |   "compilerOptions": { | ||||||
|  |     // Environment setup & latest features | ||||||
|  |     "lib": ["ESNext"], | ||||||
|  |     "target": "ESNext", | ||||||
|  |     "module": "Preserve", | ||||||
|  |     "moduleDetection": "force", | ||||||
|  |     "jsx": "react-jsx", | ||||||
|  |     "allowJs": true, | ||||||
|  |  | ||||||
|  |     // Bundler mode | ||||||
|  |     "moduleResolution": "bundler", | ||||||
|  |     "allowImportingTsExtensions": true, | ||||||
|  |     "verbatimModuleSyntax": true, | ||||||
|  |     "noEmit": true, | ||||||
|  |  | ||||||
|  |     // Best practices | ||||||
|  |     "strict": true, | ||||||
|  |     "skipLibCheck": true, | ||||||
|  |     "noFallthroughCasesInSwitch": true, | ||||||
|  |     "noUncheckedIndexedAccess": true, | ||||||
|  |     "noImplicitOverride": true, | ||||||
|  |  | ||||||
|  |     // Some stricter flags (disabled by default) | ||||||
|  |     "noUnusedLocals": false, | ||||||
|  |     "noUnusedParameters": false, | ||||||
|  |     "noPropertyAccessFromIndexSignature": false | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -37,7 +37,7 @@ public partial class FileRead : FileReaderHandler, ISMTP | |||||||
|     private FilePathGenerator _FilePathGeneratorForTarget; |     private FilePathGenerator _FilePathGeneratorForTarget; | ||||||
|     private readonly List<EquipmentParameter> _EquipmentParameters; |     private readonly List<EquipmentParameter> _EquipmentParameters; | ||||||
|     private static readonly Dictionary<string, List<long>> _DummyRuns; |     private static readonly Dictionary<string, List<long>> _DummyRuns; | ||||||
|     private static readonly Dictionary<long, List<string>> _StaticRuns; |     private static readonly Dictionary<long, List<Adaptation.Shared.Metrology.WS.Results>> _StaticRuns; | ||||||
|  |  | ||||||
|     static FileRead() |     static FileRead() | ||||||
|     { |     { | ||||||
|  | |||||||
| @ -153,7 +153,7 @@ | |||||||
|     <Compile Include="Adaptation\FileHandlers\Priority\Notification.cs" /> |     <Compile Include="Adaptation\FileHandlers\Priority\Notification.cs" /> | ||||||
|     <Compile Include="Adaptation\FileHandlers\Priority\Settings.cs" /> |     <Compile Include="Adaptation\FileHandlers\Priority\Settings.cs" /> | ||||||
|     <Compile Include="Adaptation\FileHandlers\Priority\Startup.cs" /> |     <Compile Include="Adaptation\FileHandlers\Priority\Startup.cs" /> | ||||||
|     <Compile Include="Adaptation\FileHandlers\Priority\WeightedShortestJobFirstHub.cs" /> |     <Compile Include="Adaptation\FileHandlers\Priority\WeightedShortestJobFirstModule.cs" /> | ||||||
|     <Compile Include="Adaptation\FileHandlers\Priority\WorkItem.cs" /> |     <Compile Include="Adaptation\FileHandlers\Priority\WorkItem.cs" /> | ||||||
|     <Compile Include="Adaptation\FileHandlers\Processed\FileRead.cs" /> |     <Compile Include="Adaptation\FileHandlers\Processed\FileRead.cs" /> | ||||||
|     <Compile Include="Adaptation\FileHandlers\SPaCe\FileRead.cs" /> |     <Compile Include="Adaptation\FileHandlers\SPaCe\FileRead.cs" /> | ||||||
| @ -214,34 +214,16 @@ | |||||||
|       <Version>0.15.1</Version> |       <Version>0.15.1</Version> | ||||||
|     </PackageReference> |     </PackageReference> | ||||||
|     <PackageReference Include="Infineon.EAF.Runtime"> |     <PackageReference Include="Infineon.EAF.Runtime"> | ||||||
|       <Version>2.58.0</Version> |       <Version>2.60.0</Version> | ||||||
|     </PackageReference> |     </PackageReference> | ||||||
|     <PackageReference Include="Microsoft.AspNet.SignalR.SelfHost"> |     <PackageReference Include="Nancy.Owin"> | ||||||
|       <Version>2.4.3</Version> |       <Version>2.0.0</Version> | ||||||
|     </PackageReference> |  | ||||||
|     <PackageReference Include="Microsoft.AspNet.SignalR.Core"> |  | ||||||
|       <Version>2.4.3</Version> |  | ||||||
|     </PackageReference> |     </PackageReference> | ||||||
|     <PackageReference Include="Owin"> |     <PackageReference Include="Owin"> | ||||||
|       <Version>1.0.0</Version> |       <Version>1.0.0</Version> | ||||||
|     </PackageReference> |     </PackageReference> | ||||||
|     <PackageReference Include="Microsoft.Owin"> |  | ||||||
|       <Version>2.1.0</Version> |  | ||||||
|     </PackageReference> |  | ||||||
|     <PackageReference Include="Microsoft.Owin.Cors"> |  | ||||||
|       <Version>2.1.0</Version> |  | ||||||
|     </PackageReference> |  | ||||||
|     <PackageReference Include="Microsoft.Owin.Security"> |  | ||||||
|       <Version>2.1.0</Version> |  | ||||||
|     </PackageReference> |  | ||||||
|     <PackageReference Include="Microsoft.Owin.Hosting"> |  | ||||||
|       <Version>2.1.0</Version> |  | ||||||
|     </PackageReference> |  | ||||||
|     <PackageReference Include="Microsoft.TeamFoundationServer.Client"> |  | ||||||
|       <Version>16.205.1</Version> |  | ||||||
|     </PackageReference> |  | ||||||
|     <PackageReference Include="System.Text.Json"> |     <PackageReference Include="System.Text.Json"> | ||||||
|       <Version>8.0.3</Version> |       <Version>8.0.5</Version> | ||||||
|     </PackageReference> |     </PackageReference> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> |   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> | ||||||
|  | |||||||
| @ -32,5 +32,5 @@ using System.Runtime.InteropServices; | |||||||
| // You can specify all the values or you can default the Build and Revision Numbers | // You can specify all the values or you can default the Build and Revision Numbers | ||||||
| // by using the '*' as shown below: | // by using the '*' as shown below: | ||||||
| // [assembly: AssemblyVersion("1.0.*")] | // [assembly: AssemblyVersion("1.0.*")] | ||||||
| [assembly: AssemblyVersion("2.59.0.0")] | [assembly: AssemblyVersion("2.60.0.0")] | ||||||
| [assembly: AssemblyFileVersion("2.59.0.0")] | [assembly: AssemblyFileVersion("2.60.0.0")] | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user