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/tasks.json | ||||
| !**/.vscode/mklink.md | ||||
| !**/.vscode/*.http | ||||
| **/.vscode/2025-*.http | ||||
| **/.vscode/2026-*.http | ||||
|  | ||||
|  | ||||
| *.lnk | ||||
|  | ||||
|  | ||||
							
								
								
									
										30
									
								
								Adaptation/.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								Adaptation/.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							| @ -4,7 +4,33 @@ | ||||
|       "name": ".NET Core Attach", | ||||
|       "type": "coreclr", | ||||
|       "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", | ||||
|         "headerid", | ||||
|         "Idrv", | ||||
|         "Infineon", | ||||
|         "ipdsf", | ||||
|         "Irng", | ||||
|         "ISMTP", | ||||
|         "JOBID", | ||||
|         "kanbn", | ||||
|         "messa", | ||||
|         "messv", | ||||
|         "pdsf", | ||||
| @ -20,9 +22,12 @@ | ||||
|         "Rcpe", | ||||
|         "RESIMAPCDE", | ||||
|         "Rsens", | ||||
|         "signalr", | ||||
|         "Smpl", | ||||
|         "Villach", | ||||
|         "Vrng" | ||||
|         "Vrng", | ||||
|         "Weightest", | ||||
|         "WSJF" | ||||
|     ], | ||||
|     "coverage-gutters.coverageBaseDir": "../../../../MESAFIBACKLOG/05_TestResults/TestResults/**", | ||||
|     "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 readonly string _URL; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
|  | ||||
| @ -7,7 +7,6 @@ using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.ObjectModel; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
| using System.Text.Json.Serialization; | ||||
|  | ||||
| @ -69,7 +68,6 @@ public class ProcessData : IProcessData | ||||
|             throw new Exception(nameof(workItems)); | ||||
|         _Details.Add(workItems); | ||||
|         ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations); | ||||
|         WriteFileStructure(destinationDirectory, keyValuePairs); | ||||
|         WriteFiles(fileRead, destinationDirectory, fileInfoCollection, keyValuePairs); | ||||
|     } | ||||
|  | ||||
| @ -83,18 +81,6 @@ public class ProcessData : IProcessData | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private static void WriteFileStructure(string destinationDirectory, ReadOnlyDictionary<int, Record> keyValuePairs) | ||||
|     { | ||||
|         ReadOnlyCollection<string> collection = GetDirectories(destinationDirectory, keyValuePairs); | ||||
|         foreach (string directory in collection) | ||||
|         { | ||||
|             if (directory.Length > 222) | ||||
|                 continue; | ||||
|             if (!Directory.Exists(directory)) | ||||
|                 _ = Directory.CreateDirectory(directory); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static void WriteFiles(IFileRead fileRead, string destinationDirectory, List<FileInfo> fileInfoCollection, ReadOnlyDictionary<int, Record> keyValuePairs) | ||||
|     { | ||||
|         string old; | ||||
| @ -112,10 +98,10 @@ public class ProcessData : IProcessData | ||||
|             workItem = keyValuePair.Value.WorkItem; | ||||
|             workItemType = workItem.WorkItemType.Replace(" ", "-"); | ||||
|             json = JsonSerializer.Serialize(workItem, WorkItemSourceGenerationContext.Default.WorkItem); | ||||
|             singletonDirectory = Path.Combine(rootDirectory, workItemType, $"{workItem.Id}-{workItemType}", $"{workItem.Id}"); | ||||
|             singletonDirectory = Path.Combine(rootDirectory, workItemType, $"{workItem.Id}"); | ||||
|             if (!Directory.Exists(singletonDirectory)) | ||||
|                 _ = Directory.CreateDirectory(singletonDirectory); | ||||
|             checkFile = Path.Combine(singletonDirectory, ".json"); | ||||
|             checkFile = Path.Combine(singletonDirectory, $"{workItem.Id}-{workItemType.ToLower()}.json"); | ||||
|             old = File.Exists(checkFile) ? File.ReadAllText(checkFile) : string.Empty; | ||||
|             if (old == json) | ||||
|                 continue; | ||||
| @ -151,40 +137,14 @@ public class ProcessData : IProcessData | ||||
|             } | ||||
|             catch (Exception) | ||||
|             { | ||||
|                 record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>()); | ||||
|                 Dictionary<string, string>? tag = null; | ||||
|                 record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>(), tag); | ||||
|             } | ||||
|             results.Add(keyValuePair.Key, record); | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<string> GetDirectories(string destinationDirectory, ReadOnlyDictionary<int, Record> keyValuePairs) | ||||
|     { | ||||
|         List<string> results = new(); | ||||
|         Record record; | ||||
|         string directory; | ||||
|         List<bool> nests = new(); | ||||
|         ReadOnlyCollection<string> childrenDirectories; | ||||
|         string dateDirectory = Path.Combine(destinationDirectory, "_", DateTime.Now.ToString("yyyy-MM-dd")); | ||||
|         foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs) | ||||
|         { | ||||
|             record = keyValuePair.Value; | ||||
|             if (record.Parent is not null && (record.WorkItem.Parent is null || record.Parent.Id != record.WorkItem.Parent.Value)) | ||||
|                 continue; | ||||
|             if (record.Parent is not null) | ||||
|                 continue; | ||||
|             // if (record.WorkItem.Id == 110730) | ||||
|             //     continue; | ||||
|             // if (record.WorkItem.Id == 110732) | ||||
|             //     continue; | ||||
|             nests.Clear(); | ||||
|             directory = Path.Combine(dateDirectory, $"{record.WorkItem.WorkItemType.Substring(0, 1)}-{record.WorkItem.Id}-{record.WorkItem.Title.Trim().Substring(0, 1)}"); | ||||
|             childrenDirectories = GetChildrenDirectories(keyValuePairs, nests, directory, record); | ||||
|             results.AddRange(childrenDirectories); | ||||
|         } | ||||
|         return new(results.Distinct().ToArray()); | ||||
|     } | ||||
|  | ||||
|     private static string GetIndexLines(ReadOnlyCollection<string> frontMatterLines, Record record) | ||||
|     { | ||||
|         List<string> results = new(); | ||||
| @ -234,32 +194,4 @@ public class ProcessData : IProcessData | ||||
|         return string.Join(Environment.NewLine, results); | ||||
|     } | ||||
|  | ||||
|     private static ReadOnlyCollection<string> GetChildrenDirectories(ReadOnlyDictionary<int, Record> keyValuePairs, List<bool> nests, string parentDirectory, Record record) | ||||
|     { | ||||
|         List<string> results = new(); | ||||
|         nests.Add(true); | ||||
|         string directory; | ||||
|         Record? childRecord; | ||||
|         ReadOnlyCollection<string> childrenDirectories; | ||||
|         if (record.Children is not null) | ||||
|         { | ||||
|             foreach (Record r in record.Children) | ||||
|             { | ||||
|                 // if (record.WorkItem.Id == 110730) | ||||
|                 //     continue; | ||||
|                 // if (record.WorkItem.Id == 110732) | ||||
|                 //     continue; | ||||
|                 directory = Path.Combine(parentDirectory, $"{r.WorkItem.WorkItemType.Substring(0, 1)}-{r.WorkItem.Id}-{r.WorkItem.Title.Trim().Substring(0, 1)}"); | ||||
|                 results.Add(directory); | ||||
|                 if (!keyValuePairs.TryGetValue(r.WorkItem.Id, out childRecord)) | ||||
|                     continue; | ||||
|                 if (nests.Count > 99) | ||||
|                     break; | ||||
|                 childrenDirectories = GetChildrenDirectories(keyValuePairs, nests, directory, childRecord); | ||||
|                 results.AddRange(childrenDirectories); | ||||
|             } | ||||
|         } | ||||
|         return new(results); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -14,7 +14,7 @@ namespace Adaptation.FileHandlers.APC; | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -128,7 +128,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             FileCopy(reportFullPath, dateTime, descriptions); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(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; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -18,7 +18,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     private readonly string _JobIdParentDirectory; | ||||
|     private readonly string _JobIdArchiveParentDirectory; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -153,7 +153,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             MoveArchive(reportFullPath, dateTime); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(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; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -9,7 +9,7 @@ namespace Adaptation.FileHandlers; | ||||
| public class CellInstanceConnectionName | ||||
| { | ||||
|  | ||||
|     internal static IFileRead Get(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, int? connectionCount) | ||||
|     internal static IFileRead Get(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, int? connectionCount) | ||||
|     { | ||||
|         IFileRead result = cellInstanceConnectionName switch | ||||
|         { | ||||
|  | ||||
| @ -29,7 +29,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     private readonly string _BasePage; | ||||
|     private readonly HttpClient _HttpClient; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
|  | ||||
| @ -23,7 +23,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     private int _LastDummyRunIndex; | ||||
|     private readonly string[] _CellNames; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
|  | ||||
| @ -14,7 +14,7 @@ namespace Adaptation.FileHandlers.IQSSi; | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -127,7 +127,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             FileCopy(reportFullPath, dateTime, descriptions); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(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; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -16,7 +16,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     private long? _TickOffset; | ||||
|     private readonly string _URL; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
|  | ||||
| @ -169,7 +169,8 @@ public class ProcessData : IProcessData | ||||
|             } | ||||
|             catch (Exception) | ||||
|             { | ||||
|                 record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>()); | ||||
|                 Dictionary<string, string>? tag = null; | ||||
|                 record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>(), tag); | ||||
|             } | ||||
|             results.Add(keyValuePair.Key, record); | ||||
|         } | ||||
|  | ||||
| @ -18,7 +18,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     private readonly string _URL; | ||||
|     private readonly ReadOnlyCollection<string> _WorkItemTypes; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
|  | ||||
| @ -30,14 +30,14 @@ public class ProcessData : IProcessData | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IProcessData.GetResults(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection) => | ||||
|         new(logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), fileInfoCollection); | ||||
|  | ||||
|     private static string GetClosed(WorkItem workItem) => | ||||
|         workItem.State != "Closed" ? "[ ]" : "[x]"; | ||||
|  | ||||
|     public ProcessData(IFileRead fileRead, Logistics logistics, string targetFileLocation, string url, ReadOnlyCollection<string> workItemTypes, List<FileInfo> fileInfoCollection) | ||||
|     { | ||||
|         if (fileRead.IsEAFHosted) | ||||
|         { | ||||
|  | ||||
|         } | ||||
|         _Details = new List<object>(); | ||||
|         _Log = LogManager.GetLogger(typeof(ProcessData)); | ||||
|         if (fileRead.IsEAFHosted) | ||||
|             WriteFiles(fileRead, logistics, url, workItemTypes, targetFileLocation, fileInfoCollection); | ||||
|     } | ||||
|  | ||||
| @ -93,6 +93,7 @@ public class ProcessData : IProcessData | ||||
|         ReadOnlyCollection<Record> results; | ||||
|         ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations); | ||||
|         ReadOnlyCollection<Record> records = new(keyValuePairs.Values.ToArray()); | ||||
|         ReadOnlyCollection<string> userStoryWorkItemTypes = new(new string[] { "User Story" }); | ||||
|         ReadOnlyCollection<string> bugFeatureWorkItemTypes = new(new string[] { "Bug", "Feature" }); | ||||
|         ReadOnlyCollection<string> bugUserStoryWorkItemTypes = new(new string[] { "Bug", "User Story" }); | ||||
|         messages.AddRange(WriteFile(fileRead, destinationDirectory, fileInfoCollection, records, "records")); | ||||
| @ -108,6 +109,15 @@ public class ProcessData : IProcessData | ||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, workItemType); | ||||
|             _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) | ||||
|             throw new Exception($"{messages.Count}{Environment.NewLine}{string.Join(Environment.NewLine, messages)}"); | ||||
|     } | ||||
| @ -148,7 +158,8 @@ public class ProcessData : IProcessData | ||||
|             } | ||||
|             catch (Exception) | ||||
|             { | ||||
|                 record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>()); | ||||
|                 Dictionary<string, string>? tag = null; | ||||
|                 record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>(), tag); | ||||
|             } | ||||
|             results.Add(keyValuePair.Key, record); | ||||
|         } | ||||
| @ -177,7 +188,7 @@ public class ProcessData : IProcessData | ||||
|         { | ||||
|             if (r.WorkItem.State == "Removed" || !workItemTypes.Contains(r.WorkItem.WorkItemType)) | ||||
|                 continue; | ||||
|             record = new(r.WorkItem, r.Parent, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>()); | ||||
|             record = new(r.WorkItem, r.Parent, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>(), r.Tag); | ||||
|             filtered.Add(record); | ||||
|         } | ||||
|         string? json = GetJson(filtered, results); | ||||
| @ -285,8 +296,104 @@ public class ProcessData : IProcessData | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     private static string GetClosed(WorkItem workItem) => | ||||
|         workItem.State != "Closed" ? "[ ]" : "[x]"; | ||||
|     private static ReadOnlyCollection<Record> UserStoryCheckIterationPath228385(string url, List<string> lines, ReadOnlyCollection<string> _, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType) | ||||
|     { | ||||
|         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) | ||||
|     { | ||||
|  | ||||
| @ -22,17 +22,21 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     internal class PreWith | ||||
|     { | ||||
|  | ||||
|         internal string MatchingFile { get; private set; } | ||||
|         internal string CheckFile { 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 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; | ||||
|             CheckFile = checkFile; | ||||
|             MatchingFile = matchingFile; | ||||
|             CheckDirectory = checkDirectory; | ||||
|             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) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -79,6 +85,12 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (!_IsDuplicator) | ||||
|             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) | ||||
| @ -157,7 +169,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|     private static ProcessDataStandardFormatMapping GetProcessDataStandardFormatMapping() | ||||
|     private static ProcessDataStandardFormatMapping GetProcessDataStandardFormatMapping(string processDataStandardFormatMappingOldColumnNames, string processDataStandardFormatMappingNewColumnNames, string processDataStandardFormatMappingColumnIndices) | ||||
|     { | ||||
|         ProcessDataStandardFormatMapping result; | ||||
|         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 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 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 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 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 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(','); | ||||
|         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> 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) | ||||
|         { | ||||
|             segmentsB = segment.Split('|'); | ||||
| @ -213,7 +225,11 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|             if (!Directory.Exists(checkDirectory)) | ||||
|                 _ = Directory.CreateDirectory(checkDirectory); | ||||
|             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); | ||||
|         } | ||||
|         return results.AsReadOnly(); | ||||
| @ -267,7 +283,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         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); | ||||
|         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(); | ||||
|         Post post; | ||||
|         long preWait; | ||||
|         foreach (PreWith preWith in preWithCollection) | ||||
|         { | ||||
|             if (processDataStandardFormat is null) | ||||
|                 File.Move(preWith.MatchingFile, preWith.CheckFile); | ||||
|             else | ||||
|             { | ||||
|                 ProcessDataStandardFormat.Write(preWith.CheckFile, processDataStandardFormat); | ||||
|             if (!_IsEAFHosted) | ||||
|                 continue; | ||||
|             if (!_StaticRuns.TryGetValue(_Logistics.Sequence, out List<Shared.Metrology.WS.Results>? wsResults)) | ||||
|                 wsResults = null; | ||||
|             ProcessDataStandardFormat.Write(preWith.CheckFile, processDataStandardFormat, wsResults); | ||||
|             File.Delete(preWith.MatchingFile); | ||||
|             } | ||||
|             if (Directory.Exists(preWith.NoWaitDirectory)) | ||||
|             { | ||||
|                 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) | ||||
|     { | ||||
|         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); | ||||
|         if (processDataStandardFormat is not null) | ||||
|         ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, _ProcessDataStandardFormatMapping); | ||||
|         _Logistics = new Logistics(reportFullPath, processDataStandardFormat); | ||||
|         else | ||||
|         { | ||||
|             processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath); | ||||
|             _Logistics = new Logistics(reportFullPath, processDataStandardFormat); | ||||
|             processDataStandardFormat = null; | ||||
|         } | ||||
|         if (!_IsEAFHosted) | ||||
|             ProcessDataStandardFormat.Write("../../.pdsf", processDataStandardFormat, wsResults: null); | ||||
|         SetFileParameterLotIDToLogisticsMID(); | ||||
|         int numberLength = 2; | ||||
|         long ticks = dateTime.Ticks; | ||||
| @ -351,9 +360,12 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         ReadOnlyCollection<string> matchingFiles = GetMatchingFiles(ticks, reportFullPath, searchDirectories); | ||||
|         if (matchingFiles.Count != searchDirectories.Count) | ||||
|             throw new Exception($"Didn't find all files after {_BreakAfterSeconds} second(s)!"); | ||||
|         if (_IsEAFHosted) | ||||
|         { | ||||
|             try | ||||
|             { CreatePointerFile(numberLength, parentParentDirectory, matchingFiles); } | ||||
|             catch (Exception) { } | ||||
|         } | ||||
|         ReadOnlyCollection<Pre> preCollection = GetPreCollection(numberLength, parentParentDirectory, matchingFiles); | ||||
|         ReadOnlyCollection<PreWith> preWithCollection = GetPreWithCollection(preCollection); | ||||
|         MoveCollection(dateTime, processDataStandardFormat, preWithCollection); | ||||
|  | ||||
| @ -14,7 +14,7 @@ namespace Adaptation.FileHandlers.OpenInsight; | ||||
| 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) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -126,7 +126,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             SaveOpenInsightFile(reportFullPath, dateTime, descriptions, tests); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(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; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -14,7 +14,7 @@ namespace Adaptation.FileHandlers.OpenInsightMetrologyViewer; | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -113,14 +113,14 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         // (string jsonResults, WS.Results wsResults) = WS.SendData(_OpenInsightMetrologyViewerAPI, _Logistics.Sequence, directory, wsRequest); | ||||
|         // if (!wsResults.Success) | ||||
|         //     throw new Exception(wsResults.ToString()); | ||||
|         // _Log.Debug(wsResults.HeaderID); | ||||
|         // _Log.Debug(wsResults.HeaderId); | ||||
|         // lock (_StaticRuns) | ||||
|         // { | ||||
|         //     if (!_StaticRuns.ContainsKey(_Logistics.Sequence)) | ||||
|         //         _StaticRuns.Add(_Logistics.Sequence, new()); | ||||
|         //     _StaticRuns[_Logistics.Sequence].Add(jsonResults); | ||||
|         // } | ||||
|         // string checkDirectory = Path.Combine(directory, wsResults.HeaderID.ToString()); | ||||
|         // string checkDirectory = Path.Combine(directory, wsResults.HeaderId.ToString()); | ||||
|         // if (!Directory.Exists(checkDirectory)) | ||||
|         //     _ = Directory.CreateDirectory(checkDirectory); | ||||
|         // File.Copy(reportFullPath, Path.Combine(checkDirectory, Path.GetFileName(reportFullPath)), overwrite: true); | ||||
| @ -137,7 +137,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             SendData(reportFullPath, dateTime, descriptions); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(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; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -18,7 +18,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     private readonly string _OpenInsightMetrologyViewerAPI; | ||||
|     private readonly string _OpenInsightMetrologyViewerFileShare; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -154,7 +154,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             PostOpenInsightMetrologyViewerAttachments(descriptions); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(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; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -45,6 +45,7 @@ public class Aggregation | ||||
|     private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Dictionary<int, List<Notification>> keyValuePairs) | ||||
|     { | ||||
|         Dictionary<int, Aggregation> results = new(); | ||||
|         int value; | ||||
|         int? inverseValue; | ||||
|         double inverseAverage; | ||||
|         Aggregation aggregation; | ||||
| @ -60,7 +61,9 @@ public class Aggregation | ||||
|             fibonacciCollection.Clear(); | ||||
|             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) | ||||
|                     continue; | ||||
|                 inverseCollection.Add(notification.Inverse.Value); | ||||
| @ -72,7 +75,7 @@ public class Aggregation | ||||
|                 continue; | ||||
|             inverseAverage = Math.Round(inverseCollection.Average(), settings.Digits); | ||||
|             averageFromInverseCeiling = (int)Math.Ceiling(inverseAverage); | ||||
|             inverseValue = Notification.GetInverse(averageFromInverseCeiling); | ||||
|             inverseValue = Notification.GetInverse(averageFromInverseCeiling.ToString()); | ||||
|             fibonacciAverage = Math.Round(fibonacciCollection.Average(), settings.Digits); | ||||
|             aggregation = new(inverseAverage: inverseAverage, | ||||
|                               valueCount: collection.Count, | ||||
| @ -107,9 +110,9 @@ public class Aggregation | ||||
|                 if (string.IsNullOrEmpty(text) || text[0] == '[') | ||||
|                     continue; | ||||
|                 notification = JsonSerializer.Deserialize(text, NotificationSourceGenerationContext.Default.Notification); | ||||
|                 if (notification is null || notification.Id == 0) | ||||
|                 if (notification is null || string.IsNullOrEmpty(notification.Id)) | ||||
|                     continue; | ||||
|                 key = !string.IsNullOrEmpty(notification.Username) ? notification.Username : notification.RemoteIpAddress; | ||||
|                 key = !string.IsNullOrEmpty(notification.Username) ? notification.Username : throw new Exception(); | ||||
|                 if (string.IsNullOrEmpty(key)) | ||||
|                     continue; | ||||
|                 if (!keyValuePairs.TryGetValue(key, out collection)) | ||||
| @ -126,7 +129,7 @@ public class Aggregation | ||||
|                     results.Add(keyValuePair.Value[0]); | ||||
|                 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); | ||||
|                 } | ||||
|             } | ||||
| @ -137,15 +140,18 @@ public class Aggregation | ||||
|     private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, string directory) | ||||
|     { | ||||
|         ReadOnlyDictionary<int, Aggregation> results; | ||||
|         int id; | ||||
|         List<Notification>? collection; | ||||
|         Dictionary<int, List<Notification>> keyValuePairs = new(); | ||||
|         ReadOnlyCollection<Notification> notifications = GetNotifications(settings, directory); | ||||
|         foreach (Notification notification in notifications) | ||||
|         { | ||||
|             if (!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()); | ||||
|                 if (!keyValuePairs.TryGetValue(notification.Id, out collection)) | ||||
|                 keyValuePairs.Add(id, new()); | ||||
|                 if (!keyValuePairs.TryGetValue(id, out collection)) | ||||
|                     throw new Exception(); | ||||
|             } | ||||
|             collection.Add(notification); | ||||
| @ -185,8 +191,13 @@ public class Aggregation | ||||
|     internal static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Notification notification) | ||||
|     { | ||||
|         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); | ||||
|         } | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -6,8 +6,10 @@ using Adaptation.Shared.Methods; | ||||
| using log4net; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Diagnostics; | ||||
| using System.IO; | ||||
| using System.Text.Json; | ||||
| using System.Threading; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.Priority; | ||||
|  | ||||
| @ -16,23 +18,21 @@ namespace Adaptation.FileHandlers.Priority; | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
|  | ||||
|     internal static ILog Log => _Log; | ||||
|     internal static Settings Settings => _Settings; | ||||
|     internal static Dictionary<int, WorkItem> WorkItems => _WorkItems; | ||||
| #pragma warning disable IDE0032, CS8618 | ||||
|     private static new ILog _Log; | ||||
|     private static Settings _Settings; | ||||
|     private static Dictionary<int, WorkItem> _WorkItems; | ||||
| #pragma warning restore IDE0032, CS8618 | ||||
|     private readonly Timer _Timer; | ||||
|     internal static ILog? Log { get; private set; } | ||||
|     internal static Settings? Settings { get; private set; } | ||||
|     internal static Dictionary<int, WorkItem>? WorkItems { get; private set; } | ||||
|     internal static Dictionary<string, Queue<KeyValuePair<string, WorkItem>>>? Queue { get; private set; } | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _WorkItems = new(); | ||||
|         Queue = new(); | ||||
|         WorkItems = new(); | ||||
|         _MinFileLength = 10; | ||||
|         _Logistics = new(this); | ||||
|         _NullData = string.Empty; | ||||
|         _Log = LogManager.GetLogger(typeof(FileRead)); | ||||
|         Log = LogManager.GetLogger(typeof(FileRead)); | ||||
|         if (_FileParameter is null) | ||||
|             throw new Exception(cellInstanceConnectionName); | ||||
|         if (_ModelObjectParameterDefinitions is null) | ||||
| @ -42,23 +42,29 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         if (_IsEAFHosted) | ||||
|             NestExistingFiles(_FileConnectorConfiguration); | ||||
|         string parentDirectory = Path.GetDirectoryName(_FileConnectorConfiguration.TargetFileLocation) ?? throw new Exception(); | ||||
|         _Settings = new(digits: 5, | ||||
|         Settings = new(digits: 5, | ||||
|                         parentDirectory: parentDirectory, | ||||
|                         priorities: 3, | ||||
|                         priorityGroups: 9, | ||||
|                         sourceFileFilter: _FileConnectorConfiguration.SourceFileFilter, | ||||
|                         sourceFileLocation: _FileConnectorConfiguration.SourceFileLocation, | ||||
|                         targetFileLocation: _FileConnectorConfiguration.TargetFileLocation); | ||||
|         string? json = WeightedShortestJobFirstHub.PopulatedWorkItemsAndGetJson(_Settings); | ||||
|         if (!string.IsNullOrEmpty(json)) | ||||
|             WeightedShortestJobFirstHub.WriteJson(json); | ||||
|         _Timer = new Timer(Callback, null, Timeout.Infinite, Timeout.Infinite); | ||||
|         string cellInstanceNamed = string.Concat("CellInstance.", _EquipmentType); | ||||
|         string url = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.Microsoft.Owin.Hosting.WebApp.Start.URL"); | ||||
|         if (_IsEAFHosted) | ||||
|         { | ||||
|             _ = Microsoft.Owin.Hosting.WebApp.Start(url); | ||||
|             _ = Microsoft.Owin.Hosting.WebApp.Start<Startup>(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); | ||||
| @ -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"};" }; | ||||
|         ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines); | ||||
|         _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; | ||||
|     } | ||||
|  | ||||
|     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; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.Priority; | ||||
| @ -9,15 +11,15 @@ public class Notification | ||||
|  | ||||
|     [JsonConstructor] | ||||
|     public Notification(int? fibonacci, | ||||
|                         int id, | ||||
|                         string? id, | ||||
|                         int? inverse, | ||||
|                         string? machineId, | ||||
|                         string page, | ||||
|                         string? remoteIpAddress, | ||||
|                         string? site, | ||||
|                         long time, | ||||
|                         string? sessionId, | ||||
|                         string time, | ||||
|                         string? username, | ||||
|                         int value) | ||||
|                         string? value) | ||||
|     { | ||||
|         int? i = inverse is not null ? inverse : GetInverse(value); | ||||
|         Fibonacci = fibonacci is not null ? fibonacci : i is null ? null : GetFibonacci(i.Value); | ||||
| @ -25,32 +27,78 @@ public class Notification | ||||
|         Inverse = i; | ||||
|         MachineId = machineId; | ||||
|         Page = page; | ||||
|         RemoteIpAddress = remoteIpAddress is not null ? remoteIpAddress : null; | ||||
|         Site = site is not null ? site : "MES"; | ||||
|         SessionId = sessionId; | ||||
|         Time = time; | ||||
|         Username = username; | ||||
|         Value = value; | ||||
|     } | ||||
|  | ||||
|     [JsonPropertyName("id")] public int Id { get; } | ||||
|     [JsonPropertyName("id")] public string? Id { get; } | ||||
|     [JsonPropertyName("fibonacci")] public int? Fibonacci { get; } | ||||
|     [JsonPropertyName("inverse")] public int? Inverse { get; } | ||||
|     [JsonPropertyName("machineId")] public string? MachineId { get; } | ||||
|     [JsonPropertyName("page")] public string Page { get; } | ||||
|     [JsonPropertyName("RemoteIpAddress")] public string? RemoteIpAddress { 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("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 | ||||
|         { | ||||
|             1 => 5, | ||||
|             2 => 4, | ||||
|             3 => 3, | ||||
|             4 => 2, | ||||
|             5 => 1, | ||||
|             "1" => 5, | ||||
|             "2" => 4, | ||||
|             "3" => 3, | ||||
|             "4" => 2, | ||||
|             "5" => 1, | ||||
|             _ => null | ||||
|         }; | ||||
|  | ||||
| @ -69,18 +117,6 @@ public class Notification | ||||
|             _ => 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)] | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| using Microsoft.Owin.Cors; | ||||
| using Nancy.Owin; | ||||
| using Owin; | ||||
|  | ||||
| public class Startup | ||||
| @ -7,7 +8,7 @@ public class Startup | ||||
|     public void Configuration(IAppBuilder app) | ||||
|     { | ||||
|         _ = 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 | ||||
| { | ||||
| } | ||||
|  | ||||
| [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 _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) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -140,6 +140,30 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         // 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) | ||||
|     { | ||||
|         Tuple<string, Test[], JsonElement[], List<FileInfo>> results; | ||||
| @ -149,7 +173,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat); | ||||
|         List<Description> descriptions = json.ProcessData.GetDescriptions(jsonElements); | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(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) | ||||
|             DirectoryMove(reportFullPath, dateTime, descriptions); | ||||
|         else if (!_IsEAFHosted) | ||||
|  | ||||
| @ -14,7 +14,7 @@ namespace Adaptation.FileHandlers.SPaCe; | ||||
| public class FileRead : Shared.FileRead, IFileRead | ||||
| { | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -125,7 +125,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         Test[] tests = (from l in descriptions select (Test)l.Test).ToArray(); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             FileCopy(reportFullPath, dateTime, descriptions); | ||||
|         results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(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; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -18,7 +18,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|     private readonly string _URL; | ||||
|     private readonly ReadOnlyCollection<string> _WorkItemTypes; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
|  | ||||
| @ -30,6 +30,17 @@ public class ProcessData : IProcessData | ||||
|     Tuple<string, Test[], JsonElement[], List<FileInfo>> IProcessData.GetResults(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection) => | ||||
|         new(logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), fileInfoCollection); | ||||
|  | ||||
|     private static int GetState(WorkItem workItem) => | ||||
|         workItem.State switch | ||||
|         { | ||||
|             "New" => 1, | ||||
|             "Active" => 2, | ||||
|             "Resolved" => 3, | ||||
|             "Closed" => 4, | ||||
|             "Removed" => 5, | ||||
|             _ => 8 | ||||
|         }; | ||||
|  | ||||
|     public ProcessData(IFileRead fileRead, Logistics logistics, string targetFileLocation, string url, ReadOnlyCollection<string> workItemTypes, List<FileInfo> fileInfoCollection) | ||||
|     { | ||||
|         if (fileRead.IsEAFHosted) | ||||
| @ -66,8 +77,6 @@ public class ProcessData : IProcessData | ||||
|         ReadOnlyCollection<Record> results; | ||||
|         ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations); | ||||
|         ReadOnlyCollection<Record> records = new(keyValuePairs.Values.ToArray()); | ||||
|         ReadOnlyCollection<string> userStoryWorkItemTypes = new(new string[] { "User Story" }); | ||||
|         ReadOnlyCollection<string> bugFeatureWorkItemTypes = new(new string[] { "Bug", "Feature" }); | ||||
|         ReadOnlyCollection<string> bugUserStoryWorkItemTypes = new(new string[] { "Bug", "User Story" }); | ||||
|         ReadOnlyCollection<string> bugUserStoryTaskWorkItemTypes = new(new string[] { "Bug", "User Story", "Task" }); | ||||
|         { | ||||
| @ -124,15 +133,6 @@ public class ProcessData : IProcessData | ||||
|             WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-122517"); | ||||
|             _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) | ||||
|             throw new Exception($"{messages.Count}{Environment.NewLine}{string.Join(Environment.NewLine, messages)}"); | ||||
|     } | ||||
| @ -173,7 +173,8 @@ public class ProcessData : IProcessData | ||||
|             } | ||||
|             catch (Exception) | ||||
|             { | ||||
|                 record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>()); | ||||
|                 Dictionary<string, string>? tag = null; | ||||
|                 record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>(), tag); | ||||
|             } | ||||
|             results.Add(keyValuePair.Key, record); | ||||
|         } | ||||
| @ -474,17 +475,6 @@ public class ProcessData : IProcessData | ||||
|         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) | ||||
|     { | ||||
|         List<Record> results = new(); | ||||
| @ -621,71 +611,6 @@ public class ProcessData : IProcessData | ||||
|         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) | ||||
|     { | ||||
|         List<Description> results = new(); | ||||
|  | ||||
| @ -23,7 +23,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|  | ||||
|     private readonly Timer _Timer; | ||||
|  | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|     public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<Shared.Metrology.WS.Results>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) : | ||||
|         base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null) | ||||
|     { | ||||
|         _MinFileLength = 10; | ||||
| @ -363,7 +363,7 @@ public class FileRead : Shared.FileRead, IFileRead | ||||
|         _Logistics = new Logistics(reportFullPath, processDataStandardFormat); | ||||
|         if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0) | ||||
|             MoveJson(reportFullPath, dateTime); | ||||
|         results = new(_Logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), new List<FileInfo>()); | ||||
|         results = new(string.Join(Environment.NewLine, _Logistics.Logistics1), Array.Empty<Test>(), Array.Empty<JsonElement>(), new List<FileInfo>()); | ||||
|         return results; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - 122508 - Feature iteration should be set to max of children</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.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-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/122508.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=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/122508.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> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/122508.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -56,7 +56,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/check-122508.json?v=2025-01-22-10-49"); | ||||
|             initIndex("/markdown/check-122508.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - 122514 - Features and children must have a Tag</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.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-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/122514.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=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/122514.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> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/122514.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -56,7 +56,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/check-122514.json?v=2025-01-22-10-49"); | ||||
|             initIndex("/markdown/check-122514.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - 122517 - Feature start date should be min activated date of children</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.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-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/122517.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=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/122517.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> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/122517.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -56,7 +56,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/check-122517.json?v=2025-01-22-10-49"); | ||||
|             initIndex("/markdown/check-122517.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - 123066 - When children of a Feature are not New Feature must also not be New</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.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-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/123066.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=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/123066.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> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/123066.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -56,7 +56,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/check-123066.json?v=2025-01-22-10-49"); | ||||
|             initIndex("/markdown/check-123066.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - 123067 - WIP</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.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-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/123067.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=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/123067.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> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/123067.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -56,7 +56,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/check-123067.json?v=2025-01-22-10-49"); | ||||
|             initIndex("/markdown/check-123067.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - 126169 - Children of a Feature should have the same priority</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.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-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/126169.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=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/126169.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> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/126169.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -56,7 +56,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/check-126169.json?v=2025-01-22-10-49"); | ||||
|             initIndex("/markdown/check-126169.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - Business Value</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.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-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/business.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=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/business.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> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/business.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -59,7 +59,7 @@ What is the relative value to the Customer or business? | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=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> | ||||
|  | ||||
| @ -9,8 +9,7 @@ | ||||
|     <link href="/styles/cod.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/scripts/jquery-1.6.4.min.js"></script> | ||||
|     <script src="/js/scripts/jquery.signalR-2.4.3.min.js"></script> | ||||
|     <script src="/signalr/hubs"></script> | ||||
|     <script src="/js/cod-b.js?v=2025-01-22-10-49" type="text/javascript"></script> | ||||
|     <script src="/js/cod-1-122-0.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -54,51 +53,53 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             const username = ''; | ||||
|             const machineId = ''; | ||||
|             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 apiUrl = "https://eaf-dev.mes.infineon.com/api/v1/ado/"; | ||||
|             const signalRUrl = baseUri + '/signalr'; | ||||
|             const workItems = { | ||||
|                 a: "/markdown/bugs-features-with-parents.json?v=2025-01-22-10-49", | ||||
|                 b: "/markdown/{[]}.json?v=2025-01-22-10-49" | ||||
|                 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?" | ||||
|                 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?" | ||||
|                 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?" | ||||
|                 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)", | ||||
|                 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" | ||||
|                 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)" | ||||
|                 page: 'wsjf', | ||||
|                 description: 'WSJF', | ||||
|                 th: 'Weightest Shortest Job First calculation (WSJF)', | ||||
|                 span: 'Weightest Shortest Job First calculation (see @SCALE formula)' | ||||
|             }; | ||||
|             initIndex(fromHtml, username, machineId, windowLocationHRef, workItems, b, r, t, c, e, w, apiUrl, signalRUrl); | ||||
|         }); | ||||
|  | ||||
| @ -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" /> | ||||
|     <title>Infineon - Effort</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.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-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/effort.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=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/effort.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> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/effort.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -55,7 +55,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=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> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - Risk Reduction and/or Opportunity Enablement</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.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-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/risk.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=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/risk.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> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/risk.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -59,7 +59,7 @@ What else does this do for our business? | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=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> | ||||
|  | ||||
| @ -21,7 +21,7 @@ | ||||
|     <script src="/js/scripts/jquery-1.6.4.min.js"></script> | ||||
|     <script src="/js/scripts/jquery.signalR-2.4.3.min.js"></script> | ||||
|     <script src="/signalr/hubs"></script> | ||||
|     <script src="/js/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> | ||||
| 
 | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - Time Criticality</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.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-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/time.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=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/time.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> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/time.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -59,7 +59,7 @@ How does user/business value decay over time? | ||||
|     <script> | ||||
|  | ||||
|         $(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> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - User Stor(ies) with parents</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.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-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/with-parents.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=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/with-parents.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> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/with-parents.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -55,7 +55,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/bugs-user-stories-with-parents.json?v=2025-01-22-10-49"); | ||||
|             initIndex("/markdown/bugs-user-stories-with-parents.json?v=2025-04-14-08-10"); | ||||
|         }); | ||||
|  | ||||
|     </script> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - Result of Weightest Shortest Job First calculation (see @SCALE formula)</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.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-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/wsjf.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-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/wsjf-b.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> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/wsjf-b.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -55,7 +55,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(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> | ||||
|  | ||||
| @ -6,15 +6,15 @@ | ||||
|     <meta name="viewport" content="width=device-width" /> | ||||
|     <title>Infineon - Result of Weightest Shortest Job First calculation (see @SCALE formula)</title> | ||||
|     <link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" /> | ||||
|     <link href="/igniteui/css/structure/infragistics.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-04-14-08-10" rel="stylesheet" /> | ||||
|     <link href="/styles/wsjf.css?no-cache=2024-10-04-08-34" rel="stylesheet" /> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-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/wsjf.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> | ||||
|     <script src="/js/jquery-3.6.0.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/jquery-ui.min.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/js/wsjf.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.core.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.lob.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
|     <script src="/igniteui/js/infragistics.dv.js?v=2025-04-14-08-10" type="text/javascript"></script> | ||||
| </head> | ||||
|  | ||||
| <body> | ||||
| @ -55,7 +55,7 @@ | ||||
|     <script> | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             initIndex("/markdown/bugs-features-with-parents.json?v=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> | ||||
|  | ||||
							
								
								
									
										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 { | ||||
|         result = ''; | ||||
|         aggregation.Notifications.forEach(element => { | ||||
|             const username = element.username == null ? 'user' : element.username; | ||||
|             if (element.value === 1) { | ||||
|                 result += 'Highest ' + element.RemoteIpAddress + '|'; | ||||
|                 result += 'Highest ' + username + '|'; | ||||
|             } | ||||
|             else if (element.value === 2) { | ||||
|                 result += 'High ' + element.RemoteIpAddress + '|'; | ||||
|                 result += 'High ' + username + '|'; | ||||
|             } | ||||
|             else if (element.value === 3) { | ||||
|                 result += 'Medium ' + element.RemoteIpAddress + '|'; | ||||
|                 result += 'Medium ' + username + '|'; | ||||
|             } | ||||
|             else if (element.value === 4) { | ||||
|                 result += 'Low ' + element.RemoteIpAddress + '|'; | ||||
|                 result += 'Low ' + username + '|'; | ||||
|             } | ||||
|             else if (element.value === 5) { | ||||
|                 result += 'Lowest ' + element.RemoteIpAddress + '|'; | ||||
|                 result += 'Lowest ' + username + '|'; | ||||
|             } | ||||
|             else { | ||||
|                 result += element.value + ' ' + element.RemoteIpAddress + '|'; | ||||
|                 result += element.value + ' ' + username + '|'; | ||||
|             } | ||||
|         }); | ||||
|         result = result.substring(0, result.length - 1); | ||||
| @ -191,32 +192,32 @@ function sendValue(fromHtml, element, page, id) { | ||||
|     if (fromHtml && notification.value !== "9") { | ||||
|         $("#AllTextarea").hide(); | ||||
|         document.getElementById('AllTextarea').value = ''; | ||||
|         // $.post(_apiUrl + "save", notification) | ||||
|         //     .done(function (msg) { | ||||
|         //         console.log("Posted value of " + notification.value + " for " + id + " on page " + page + " " + msg); | ||||
|         //     }) | ||||
|         //     .fail(function (_, textStatus, _) { | ||||
|         //         alert(textStatus); | ||||
|         //     }); | ||||
|         $.post(_apiUrl, notification) | ||||
|             .done(function (msg) { | ||||
|                 console.log("Posted value of " + notification.value + " for " + id + " on page " + page + " " + msg); | ||||
|                 if (!_connectionHubStartDone) { | ||||
|             alert("Error data not sent!"); | ||||
|                     console.warn("Error data not sent!"); | ||||
|                 } | ||||
|                 else { | ||||
|                     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) | ||||
|                         .done(function () { | ||||
|                             console.log("Posted value of " + notification.value + " for " + id + " on page " + page); | ||||
|                         }) | ||||
|                         .fail(function (errorThrown) { | ||||
|                             if (errorThrown == undefined || errorThrown.message == undefined || errorThrown.stack == undefined) { | ||||
|                         alert("Error posting!"); | ||||
|                                 console.warn("Error posting!"); | ||||
|                             } | ||||
|                             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; | ||||
|     } | ||||
|     if (x == undefined) | ||||
|         alert("Error with page!"); | ||||
|         console.warn("Error with page!"); | ||||
|     else { | ||||
|         $('#' + x.page + workItem.Id).text('!' + myRound(aggregation.FibonacciAverage, 100)); | ||||
|         if (workItem.WeightedShortestJobFirst != undefined) { | ||||
| @ -447,7 +448,7 @@ function setupSignalR(b, r, t, c, e, w, signalRUrl) { | ||||
|     $.connection.hub.url = signalRUrl; | ||||
|     _chat = $.connection.weightedShortestJobFirstHub; | ||||
|     if (_chat == undefined || _chat.server == undefined) { | ||||
|         alert('Error within handshake!'); | ||||
|         console.warn('Error within handshake!'); | ||||
|     } | ||||
|     else { | ||||
|         _chat.client.updateWorkItem = function (page, workItem) { | ||||
| @ -461,10 +462,10 @@ function setupSignalR(b, r, t, c, e, w, signalRUrl) { | ||||
|             .fail(function (errorThrown) { | ||||
|                 _connectionHubStartDone = false; | ||||
|                 if (errorThrown == undefined || errorThrown.message == undefined || errorThrown.stack == undefined) { | ||||
|                     alert("Error starting conection!"); | ||||
|                     console.warn("Error starting connection!"); | ||||
|                 } | ||||
|                 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 windowLocationHRef = "https://eaf-dev.mes.infineon.com/html/cod.html?site=MES"; | ||||
|     const workItems = { | ||||
|         a: "https://eaf-dev.mes.infineon.com/markdown/bugs-features-with-parents.json?v=2025-01-22-10-49", | ||||
|         b: "https://eaf-dev.mes.infineon.com/markdown/{}.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-04-14-08-10" | ||||
|     }; | ||||
|     const b = { | ||||
|         page: "business", | ||||
|  | ||||
| @ -31,11 +31,9 @@ function initIndex(url, apiUrl) { | ||||
|             // Call the Send method on the hub.
 | ||||
|             // chat.server.send($('#displayname').val(), $('#message').val());
 | ||||
|             var notification = { | ||||
|                 "Json": null, | ||||
|                 "id": 110743, | ||||
|                 "page": "effort", | ||||
|                 "QueryString": "time=1737573418926\u0026id=110743\u0026page=effort\u0026value=1", | ||||
|                 "RemoteIpAddress": "10.95.36.87", | ||||
|                 "username": "user", | ||||
|                 "time": 1737573418926, | ||||
|                 "value": 1 | ||||
|             }; | ||||
| @ -2,6 +2,7 @@ using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Collections.ObjectModel; | ||||
| using System.Linq; | ||||
| using System.Text.Json; | ||||
| using System.Text.Json.Serialization; | ||||
|  | ||||
| namespace Adaptation.FileHandlers.json.WorkItems; | ||||
| @ -12,13 +13,14 @@ internal class Record | ||||
| #nullable enable | ||||
|  | ||||
|     [JsonConstructor] | ||||
|     public Record(WorkItem workItem, WorkItem? parent, Record[]? children, Record[]? related, Record[]? successors) | ||||
|     public Record(WorkItem workItem, WorkItem? parent, Record[]? children, Record[]? related, Record[]? successors, Dictionary<string, string>? tag) | ||||
|     { | ||||
|         WorkItem = workItem; | ||||
|         Parent = parent; | ||||
|         Children = children; | ||||
|         Related = related; | ||||
|         Successors = successors; | ||||
|         Tag = tag; | ||||
|     } | ||||
|  | ||||
|     [JsonPropertyName("WorkItem")] public WorkItem WorkItem { get; set; } | ||||
| @ -26,6 +28,7 @@ internal class Record | ||||
|     [JsonPropertyName("Children")] public Record[]? Children { get; set; } | ||||
|     [JsonPropertyName("Related")] public Record[]? Related { get; set; } | ||||
|     [JsonPropertyName("Successors")] public Record[]? Successors { get; set; } | ||||
|     [JsonPropertyName("Tag")] public Dictionary<string, string>? Tag { get; set; } | ||||
|  | ||||
|     internal static Record GetWithoutNesting(Record record, string? violation) | ||||
|     { | ||||
| @ -60,7 +63,7 @@ internal class Record | ||||
|                                 violation: record.WorkItem.Violation is null ? violation : record.WorkItem.Violation, | ||||
|                                 weightedShortestJobFirst: record.WorkItem.WeightedShortestJobFirst, | ||||
|                                 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; | ||||
|     } | ||||
|  | ||||
| @ -100,14 +103,40 @@ internal class Record | ||||
|                 relationRecords.Add(Get(r, keepRelations)); | ||||
|             successorRecords = relationRecords.ToArray(); | ||||
|         } | ||||
|         result = new(workItem, parentWorkItem, childRecords, relatedRecords, successorRecords); | ||||
|         result = new(workItem, parentWorkItem, childRecords, relatedRecords, successorRecords, record.Tag); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     internal static Dictionary<string, string>? GetTag(ReadOnlyCollection<Record>? records) | ||||
|     { | ||||
|         Dictionary<string, string>? result; | ||||
|         if (records is null) | ||||
|             result = null; | ||||
|         else | ||||
|         { | ||||
|             List<long> collection = new(); | ||||
|             foreach (Record record in records) | ||||
|             { | ||||
|                 if (record.WorkItem.State is "Closed" or "Resolved" || record.WorkItem.StoryPoints is null) | ||||
|                     continue; | ||||
|                 collection.Add(record.WorkItem.StoryPoints.Value); | ||||
|             } | ||||
|             if (collection.Count == 0) | ||||
|                 result = null; | ||||
|             else | ||||
|             { | ||||
|                 string json = JsonSerializer.Serialize(collection); | ||||
|                 result = new Dictionary<string, string> { { "StoryPoints", json } }; | ||||
|             } | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     internal static Record Get(WorkItem workItem, WorkItem? parent, ReadOnlyCollection<Record>? children, ReadOnlyCollection<Record>? related, ReadOnlyCollection<Record>? successors, bool keepRelations) | ||||
|     { | ||||
|         Record result; | ||||
|         Record record = new(workItem, parent, children?.ToArray(), related?.ToArray(), successors?.ToArray()); | ||||
|         Dictionary<string, string>? tag = GetTag(children); | ||||
|         Record record = new(workItem, parent, children?.ToArray(), related?.ToArray(), successors?.ToArray(), tag); | ||||
|         result = Get(record, keepRelations); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
| @ -106,8 +106,7 @@ | ||||
|         <PackageReference Include="Tesseract" Version="5.2.0" /> | ||||
|     </ItemGroup> | ||||
|     <ItemGroup> | ||||
|         <PackageReference Include="Microsoft.AspNet.SignalR" Version="2.4.3" /> | ||||
|         <PackageReference Include="Microsoft.AspNet.SignalR.Core" Version="2.4.3" /> | ||||
|         <PackageReference Include="Nancy.Owin" Version="2.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Owin" Version="4.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Owin.Cors" Version="4.0.0" /> | ||||
|         <PackageReference Include="Microsoft.Owin.Hosting" Version="4.0.0" /> | ||||
|  | ||||
| @ -41,6 +41,24 @@ stages: | ||||
|             displayName: "Nuget Clear" | ||||
|             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: | | ||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets init | ||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets set "BuildNumber" "$(Build.BuildId)" | ||||
| @ -184,6 +202,24 @@ stages: | ||||
|             displayName: "Nuget Clear" | ||||
|             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: | | ||||
|               "C:\program files\dotnet\dotnet.exe" user-secrets init | ||||
|               "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 Dictionary<string, List<long>> _DummyRuns; | ||||
|     protected readonly Dictionary<string, string> _FileParameter; | ||||
|     protected readonly Dictionary<long, List<string>> _StaticRuns; | ||||
|     protected readonly string _ParameterizedModelObjectDefinitionType; | ||||
|     protected readonly FileConnectorConfiguration _FileConnectorConfiguration; | ||||
|     protected readonly Dictionary<long, List<Metrology.WS.Results>> _StaticRuns; | ||||
|     protected readonly IList<ModelObjectParameterDefinition> _ModelObjectParameterDefinitions; | ||||
|  | ||||
|     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; | ||||
|         _IsEvent = isEvent; | ||||
| @ -377,17 +377,25 @@ public class FileRead : Properties.IFileRead | ||||
|  | ||||
|     internal string[] GetInProcessDirectory(string jobIdDirectory) | ||||
|     { | ||||
|         string[] results; | ||||
|         List<string> results = new(); | ||||
|         if (!_IsEAFHosted) | ||||
|             results = new string[] { jobIdDirectory }; | ||||
|             results = new string[] { jobIdDirectory }.ToList(); | ||||
|         else | ||||
|         { | ||||
|             string[] files; | ||||
|             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"); | ||||
|         return results; | ||||
|         return results.ToArray(); | ||||
|     } | ||||
|  | ||||
|     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; | ||||
|         string day = $"{_Logistics.DateTimeFromSequence:yyyy-MM-dd}"; | ||||
|         string weekOfYear = _Calendar.GetWeekOfYear(_Logistics.DateTimeFromSequence, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00"); | ||||
|         string weekDirectory = $"{_Logistics.DateTimeFromSequence:yyyy}_Week_{weekOfYear}"; | ||||
|         if (!_CellInstanceConnectionName.StartsWith(_CellInstanceName) && _CellInstanceConnectionNameBase == _EquipmentType) | ||||
|             directory = Path.Combine(_TracePath, _EquipmentType, "Target", weekDirectory, day, _CellInstanceName, _CellInstanceConnectionName); | ||||
|         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) { } | ||||
|         } | ||||
| #pragma warning disable CA1510 | ||||
|         if (fileRead is null) | ||||
|             throw new ArgumentNullException(nameof(fileRead)); | ||||
|         if (jsonElements is null) | ||||
|             throw new ArgumentNullException(nameof(jsonElements)); | ||||
| #pragma warning restore CA1510 | ||||
|     } | ||||
|  | ||||
|     protected void WaitForThread(Thread thread, List<Exception> threadExceptions) | ||||
| @ -616,6 +611,9 @@ public class FileRead : Properties.IFileRead | ||||
|                 case FileConnectorConfiguration.PostProcessingModeEnum.Delete: | ||||
|                     File.Delete(sourceFile.FullName); | ||||
|                     break; | ||||
|                 case FileConnectorConfiguration.PostProcessingModeEnum.None: | ||||
|                     File.Move(sourceFile.FullName, itemFile); | ||||
|                     break; | ||||
|                 default: | ||||
|                     throw new Exception(); | ||||
|             } | ||||
|  | ||||
| @ -6,23 +6,25 @@ public partial class WS | ||||
|     public class Attachment | ||||
|     { | ||||
|  | ||||
|         public string SubGroupId { get; set; } | ||||
|         public long HeaderId { get; set; } | ||||
|         public string HeaderIdDirectory { get; set; } | ||||
|         public string UniqueId { get; set; } | ||||
|         public string DestinationFileName { get; set; } | ||||
|         public string SourceFileName { get; set; } | ||||
|         public string AttachmentId { get; set; } | ||||
| #nullable enable | ||||
|  | ||||
|         public Attachment(string subGroupId, long headerId, string headerIdDirectory, string uniqueId, string destinationFileName, string sourceFileName) | ||||
|         public long HeaderId { get; set; } | ||||
|         public string UniqueId { get; set; } | ||||
|         public string SubGroupId { get; set; } | ||||
|         public string AttachmentId { get; set; } | ||||
|         public string SourceFileName { get; set; } | ||||
|         public string HeaderIdDirectory { get; set; } | ||||
|         public string DestinationFileName { get; set; } | ||||
|  | ||||
|         public Attachment(Results? results, string headerIdDirectory, string uniqueId, string destinationFileName, string sourceFileName) | ||||
|         { | ||||
|             SubGroupId = subGroupId; | ||||
|             HeaderId = headerId; | ||||
|             HeaderIdDirectory = headerIdDirectory; | ||||
|             UniqueId = uniqueId; | ||||
|             DestinationFileName = destinationFileName; | ||||
|             SourceFileName = sourceFileName; | ||||
|             HeaderIdDirectory = headerIdDirectory; | ||||
|             DestinationFileName = destinationFileName; | ||||
|             AttachmentId = System.Guid.NewGuid().ToString(); | ||||
|             HeaderId = results?.HeaderId is null ? -1 : results.HeaderId.Value; | ||||
|             SubGroupId = results?.SubgroupId is null ? string.Empty : results.SubgroupId.Value.ToString(); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
| @ -1,27 +1,75 @@ | ||||
| using System.Collections.Generic; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Text; | ||||
| using System.Text.Json; | ||||
| using System.Text.Json.Serialization; | ||||
|  | ||||
| namespace Adaptation.Shared.Metrology; | ||||
|  | ||||
| public partial class WS | ||||
| { | ||||
|     // this class represents the response from the Inbound API endpoint | ||||
|  | ||||
|     public class Results | ||||
|     { | ||||
|         // true or false if data was written to the database | ||||
|         public bool Success { get; set; } | ||||
|  | ||||
|         // if true, contains ID of the Header record in the database | ||||
|         public long HeaderID { get; set; } | ||||
| #nullable enable | ||||
|  | ||||
|         // if false, this collection will contain a list of errors | ||||
|         public List<string> Errors { get; set; } | ||||
|         [JsonConstructor] | ||||
|         public Results(List<string>? errors, | ||||
|                        long? headerId, | ||||
|                        long? subgroupId, | ||||
|                        bool? success, | ||||
|                        List<string>? warnings) | ||||
|         { | ||||
|             Errors = errors; | ||||
|             Success = success; | ||||
|             HeaderId = headerId; | ||||
|             Warnings = warnings; | ||||
|             SubgroupId = subgroupId; | ||||
|         } | ||||
|  | ||||
|         // this collection will contain a list of warnings, they will not prevent data from being saved | ||||
|         public List<string> Warnings { get; set; } | ||||
|         [JsonPropertyName("errors")] public List<string>? Errors { get; set; } | ||||
|         [JsonPropertyName("headerID")] public long? HeaderId { get; set; } | ||||
|         [JsonPropertyName("subgroupId")] public long? SubgroupId { get; set; } | ||||
|         [JsonPropertyName("success")] public bool? Success { get; set; } | ||||
|         [JsonPropertyName("warnings")] public List<string>? Warnings { get; set; } | ||||
|  | ||||
|         public override string ToString() | ||||
|         { | ||||
|             string result = JsonSerializer.Serialize(this, ResultsSourceGenerationContext.Default.Results); | ||||
|             return result; | ||||
|         } | ||||
|  | ||||
|         internal static Results Get(Results results, long? subgroupId) => | ||||
|             new(results.Errors, results.HeaderId, subgroupId, results.Success, results.Warnings); | ||||
|  | ||||
|         internal static Results Get(string resultsJson, Exception e) | ||||
|         { | ||||
|             Results results; | ||||
|             Exception? exception = e; | ||||
|             List<string> errors = new(); | ||||
|             StringBuilder stringBuilder = new(); | ||||
|             while (exception is not null) | ||||
|             { | ||||
|                 _ = stringBuilder.AppendLine(exception.Message); | ||||
|                 exception = exception.InnerException; | ||||
|             } | ||||
|             errors.Add(resultsJson); | ||||
|             errors.Add(stringBuilder.ToString()); | ||||
|             results = new(errors: errors, | ||||
|                           headerId: null, | ||||
|                           subgroupId: null, | ||||
|                           success: false, | ||||
|                           warnings: new()); | ||||
|             return results; | ||||
|         } | ||||
|  | ||||
|         // this is just a helper function to make displaying the results easier | ||||
|         public override string ToString() => JsonSerializer.Serialize(this, GetType()); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| [JsonSourceGenerationOptions(WriteIndented = true)] | ||||
| [JsonSerializable(typeof(WS.Results))] | ||||
| internal partial class ResultsSourceGenerationContext : JsonSerializerContext | ||||
| { | ||||
| } | ||||
| @ -10,9 +10,11 @@ namespace Adaptation.Shared.Metrology; | ||||
| public partial class WS | ||||
| { | ||||
|  | ||||
| #nullable enable | ||||
|  | ||||
|     public static (string, Results) SendData(string url, long sequence, string directory, object payload, int timeoutSeconds = 120) | ||||
|     { | ||||
|         Results results = new(); | ||||
|         Results? wsResults = null; | ||||
|         string resultsJson = string.Empty; | ||||
|         try | ||||
|         { | ||||
| @ -30,29 +32,20 @@ public partial class WS | ||||
|                 }; | ||||
|                 HttpResponseMessage httpResponseMessage = httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead).Result; | ||||
|                 resultsJson = httpResponseMessage.Content.ReadAsStringAsync().Result; | ||||
|                 results = JsonSerializer.Deserialize<Results>(resultsJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); | ||||
|                 string checkDirectory = Path.Combine(directory, $"-{results.HeaderID}"); | ||||
|                 wsResults = JsonSerializer.Deserialize(resultsJson, ResultsSourceGenerationContext.Default.Results); | ||||
|                 if (wsResults is null) | ||||
|                     throw new NullReferenceException(nameof(wsResults)); | ||||
|                 string checkDirectory = Path.Combine(directory, $"-{wsResults.HeaderId}"); | ||||
|                 if (!Directory.Exists(checkDirectory)) | ||||
|                     _ = Directory.CreateDirectory(checkDirectory); | ||||
|                 File.WriteAllText(Path.Combine(checkDirectory, $"{sequence}.json"), json); | ||||
|             } | ||||
|             if (!results.Success) | ||||
|                 results.Errors.Add(results.ToString()); | ||||
|             if (wsResults.Success is null || !wsResults.Success.Value) | ||||
|                 wsResults.Errors?.Add(wsResults.ToString()); | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|             Exception exception = e; | ||||
|             StringBuilder stringBuilder = new(); | ||||
|             while (exception is not null) | ||||
|             { | ||||
|                 _ = stringBuilder.AppendLine(exception.Message); | ||||
|                 exception = exception.InnerException; | ||||
|             } | ||||
|             results.Errors ??= new List<string>(); | ||||
|             results.Errors.Add(resultsJson); | ||||
|             results.Errors.Add(stringBuilder.ToString()); | ||||
|         } | ||||
|         return new(resultsJson, results); | ||||
|         { wsResults ??= Results.Get(resultsJson, e); } | ||||
|         return new(resultsJson, wsResults); | ||||
|     } | ||||
|  | ||||
|     public static void AttachFile(string url, Attachment attachment, int timeoutSeconds = 60) | ||||
| @ -69,16 +62,20 @@ public partial class WS | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static void AttachFiles(string url, List<Attachment> headerAttachments = null, List<Attachment> dataAttachments = null) | ||||
|     public static void AttachFiles(string url, List<Attachment>? headerAttachments = null, List<Attachment>? dataAttachments = null) | ||||
|     { | ||||
|         string directory; | ||||
|         try | ||||
|         { | ||||
|             string? directoryName; | ||||
|             if (headerAttachments is not null) | ||||
|             { | ||||
|                 foreach (Attachment attachment in headerAttachments) | ||||
|                 { | ||||
|                     directory = Path.Combine(Path.GetDirectoryName(attachment.HeaderIdDirectory), attachment.AttachmentId) ?? throw new Exception(); | ||||
|                     directoryName = Path.GetDirectoryName(attachment.HeaderIdDirectory); | ||||
|                     if (string.IsNullOrEmpty(directoryName)) | ||||
|                         continue; | ||||
|                     directory = Path.Combine(directoryName, attachment.AttachmentId) ?? throw new Exception(); | ||||
|                     if (!Directory.Exists(directory)) | ||||
|                         _ = Directory.CreateDirectory(directory); | ||||
|                     File.Copy(attachment.SourceFileName, Path.Combine(directory, attachment.DestinationFileName), overwrite: true); | ||||
| @ -88,7 +85,10 @@ public partial class WS | ||||
|             { | ||||
|                 foreach (Attachment attachment in dataAttachments) | ||||
|                 { | ||||
|                     directory = Path.Combine(Path.GetDirectoryName(attachment.HeaderIdDirectory.Replace("Header", "Data")), attachment.AttachmentId) ?? throw new Exception(); | ||||
|                     directoryName = Path.GetDirectoryName(attachment.HeaderIdDirectory.Replace("Header", "Data")); | ||||
|                     if (string.IsNullOrEmpty(directoryName)) | ||||
|                         continue; | ||||
|                     directory = Path.Combine(directoryName, attachment.AttachmentId) ?? throw new Exception(); | ||||
|                     if (!Directory.Exists(directory)) | ||||
|                         _ = Directory.CreateDirectory(directory); | ||||
|                     File.Copy(attachment.SourceFileName, Path.Combine(directory, attachment.DestinationFileName), overwrite: true); | ||||
| @ -108,7 +108,7 @@ public partial class WS | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|             Exception exception = e; | ||||
|             Exception? exception = e; | ||||
|             StringBuilder stringBuilder = new(); | ||||
|             while (exception is not null) | ||||
|             { | ||||
|  | ||||
| @ -26,16 +26,25 @@ internal class ProcessDataStandardFormat | ||||
|  | ||||
|     internal long? Sequence { 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 ProcessDataStandardFormat? InputPDSF { get; private set; } | ||||
|     internal ReadOnlyCollection<string> Logistics { get; private set; } | ||||
|  | ||||
|     internal ProcessDataStandardFormat(ReadOnlyCollection<string> body, | ||||
|                                        ReadOnlyCollection<string> columns, | ||||
|                                        ReadOnlyCollection<string> footer, | ||||
|                                        ReadOnlyCollection<string> header, | ||||
|                                        ProcessDataStandardFormat? inputPDSF, | ||||
|                                        ReadOnlyCollection<string> logistics, | ||||
|                                        long? sequence) | ||||
|     { | ||||
|         Body = body; | ||||
|         Columns = columns; | ||||
|         Footer = footer; | ||||
|         Header = header; | ||||
|         InputPDSF = inputPDSF; | ||||
|         Logistics = logistics; | ||||
|         Sequence = sequence; | ||||
|     } | ||||
| @ -52,8 +61,8 @@ internal class ProcessDataStandardFormat | ||||
|     internal static string Archive(bool addSpaces = true, char separator = ' ') => | ||||
|         GetString(SearchFor.Archive, addSpaces, separator); | ||||
|  | ||||
|     internal static ProcessDataStandardFormat GetEmpty() => | ||||
|         new(new(Array.Empty<string>()), new(Array.Empty<string>()), new(Array.Empty<string>()), null); | ||||
|     internal static ProcessDataStandardFormat GetEmpty(Logistics logistics) => | ||||
|         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) | ||||
|     { | ||||
| @ -124,19 +133,27 @@ internal class ProcessDataStandardFormat | ||||
|         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; | ||||
|         long? sequence; | ||||
|         string segment; | ||||
|         List<string> body = new(); | ||||
|         List<string> logistics = new(); | ||||
|         lines ??= File.ReadAllLines(reportFullPath); | ||||
|         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>(); | ||||
|         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++) | ||||
|         { | ||||
|             segment = segments[c].Substring(1, segments[c].Length - 2); | ||||
| @ -155,102 +172,133 @@ internal class ProcessDataStandardFormat | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         bool lookForLogistics = false; | ||||
|         for (int r = 7; r < lines.Length; r++) | ||||
|         for (int r = columnsLine + 1; r < lines.Length; r++) | ||||
|         { | ||||
|             if (lines[r].StartsWith("NUM_DATA_ROWS")) | ||||
|                 lookForLogistics = true; | ||||
|             if (!lookForLogistics) | ||||
|             { | ||||
|                 addToFooter = true; | ||||
|             if (!addToFooter) | ||||
|                 body.Add(lines[r]); | ||||
|                 continue; | ||||
|             } | ||||
|             if (lines[r].StartsWith("LOGISTICS_1")) | ||||
|             { | ||||
|                 for (int i = r; i < lines.Length; i++) | ||||
|             else | ||||
|             { | ||||
|                 footer.Add(lines[r]); | ||||
|                 if (lines[r].StartsWith("END_HEADER")) | ||||
|                     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; | ||||
|     } | ||||
|  | ||||
|     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; | ||||
|         FileInfo fileInfo = new(reportFullPath); | ||||
|         ProcessDataStandardFormat processDataStandardFormat = GetProcessDataStandardFormat(fileInfo.LastWriteTime, pdsfMapping.NewColumnNames.Count, columnsLine, fileInfo.FullName, lines: null); | ||||
|         JsonElement[]? jsonElements = GetArray(pdsfMapping.NewColumnNames.Count, processDataStandardFormat, lookForNumbers: false); | ||||
|         if (jsonElements is null || pdsfMapping.OldColumnNames.Count != pdsfMapping.ColumnIndices.Count) | ||||
|             result = null; | ||||
|         ProcessDataStandardFormat processDataStandardFormat = GetProcessDataStandardFormat(fileInfo.LastWriteTime, columnsLine, fileInfo.FullName, lines: null); | ||||
|         JsonElement[]? jsonElements = pdsfMapping.OldColumnNames.Count != pdsfMapping.ColumnIndices.Count ? null : GetFullArray(processDataStandardFormat); | ||||
|         JsonProperty[]? jsonProperties = jsonElements is null || jsonElements.Length == 0 ? null : jsonElements[0].EnumerateObject().ToArray(); | ||||
|         if (jsonElements is null || jsonProperties is null || jsonProperties.Length != pdsfMapping.NewColumnNames.Count) | ||||
|             result = processDataStandardFormat; | ||||
|         else | ||||
|         { | ||||
|             result = GetProcessDataStandardFormat(pdsfMapping, jsonElements, processDataStandardFormat); | ||||
|             if (result.Sequence is null || result.Columns.Count == 0 || result.Body.Count == 0 || result.Logistics.Count == 0) | ||||
|                 result = null; | ||||
|                 result = processDataStandardFormat; | ||||
|         } | ||||
|         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; | ||||
|         long sequence; | ||||
|         long? sequence; | ||||
|         string[] segments; | ||||
|         bool addToFooter = false; | ||||
|         List<string> body = new(); | ||||
|         bool lookForLogistics = false; | ||||
|         List<string> logistics = new(); | ||||
|         List<string> header = new(); | ||||
|         List<string> footer = new(); | ||||
|         ReadOnlyCollection<string> logistics; | ||||
|         lines ??= File.ReadAllLines(path); | ||||
|         if (lines.Length <= columnsLine) | ||||
|             segments = Array.Empty<string>(); | ||||
|         else | ||||
|         { | ||||
|             segments = lines[columnsLine].Split('\t'); | ||||
|             if (segments.Length != expectedColumns) | ||||
|                 segments = Array.Empty<string>(); | ||||
|             for (int i = 0; i < columnsLine; i++) | ||||
|                 header.Add(lines[i]); | ||||
|         } | ||||
|         string[] columns = segments.Select(l => l.Trim('"')).ToArray(); | ||||
|         for (int r = columnsLine + 1; r < lines.Length; r++) | ||||
|         { | ||||
|             if (lines[r].StartsWith("NUM_DATA_ROWS")) | ||||
|                 lookForLogistics = true; | ||||
|             if (!lookForLogistics) | ||||
|             { | ||||
|                 addToFooter = true; | ||||
|             if (!addToFooter) | ||||
|                 body.Add(lines[r]); | ||||
|                 continue; | ||||
|             } | ||||
|             if (lines[r].StartsWith("LOGISTICS_1")) | ||||
|             { | ||||
|                 for (int i = r; i < lines.Length; i++) | ||||
|             else | ||||
|             { | ||||
|                 footer.Add(lines[r]); | ||||
|                 if (lines[r].StartsWith("END_HEADER")) | ||||
|                     break; | ||||
|                     logistics.Add(lines[i]); | ||||
|                 } | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         logistics = GetLogistics(footer, linesOne: null); | ||||
|         if (logistics.Count == 0) | ||||
|             sequence = lastWriteTime.Ticks; | ||||
|             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) ? 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(), | ||||
|                      columns: new(columns), | ||||
|                      logistics: logistics.AsReadOnly(), | ||||
|                      footer: footer.AsReadOnly(), | ||||
|                      header: header.AsReadOnly(), | ||||
|                      inputPDSF: null, | ||||
|                      logistics: logistics, | ||||
|                      sequence: sequence); | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     private static JsonElement[]? GetArray(int expectedColumns, ProcessDataStandardFormat processDataStandardFormat, bool lookForNumbers) | ||||
|     private static JsonElement[]? GetFullArray(ProcessDataStandardFormat processDataStandardFormat) | ||||
|     { | ||||
|         JsonElement[]? results; | ||||
|         if (processDataStandardFormat.Body.Count == 0 || !processDataStandardFormat.Body[0].Contains('\t')) | ||||
| @ -258,37 +306,19 @@ internal class ProcessDataStandardFormat | ||||
|         else | ||||
|         { | ||||
|             string value; | ||||
|             string[] segments; | ||||
|             List<string> segments; | ||||
|             List<string> lines = new(); | ||||
|             StringBuilder stringBuilder = new(); | ||||
|             foreach (string bodyLine in processDataStandardFormat.Body) | ||||
|             { | ||||
|                 _ = stringBuilder.Clear(); | ||||
|                 _ = stringBuilder.Append('{'); | ||||
|                 segments = bodyLine.Split('\t'); | ||||
|                 if (segments.Length != expectedColumns) | ||||
|                     continue; | ||||
|                 if (!lookForNumbers) | ||||
|                 segments = bodyLine.Split('\t').ToList(); | ||||
|                 for (int c = 0; c < segments.Count; c++) | ||||
|                 { | ||||
|                     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("\","); | ||||
|                 } | ||||
|                 } | ||||
|                 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.AppendLine("}"); | ||||
|                 lines.Add(stringBuilder.ToString()); | ||||
| @ -335,13 +365,135 @@ internal class ProcessDataStandardFormat | ||||
|             results.Add(string.Join("\t", values)); | ||||
|         } | ||||
|         result = new(body: new(results), | ||||
|                      columns: processDataStandardFormat.Columns, | ||||
|                      columns: processDataStandardFormatMapping.OldColumnNames, | ||||
|                      footer: processDataStandardFormat.Footer, | ||||
|                      header: processDataStandardFormat.Header, | ||||
|                      inputPDSF: processDataStandardFormat, | ||||
|                      logistics: processDataStandardFormat.Logistics, | ||||
|                      sequence: processDataStandardFormat.Sequence); | ||||
|         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(); | ||||
|         if (processDataStandardFormat.Sequence is null) | ||||
| @ -357,7 +509,7 @@ internal class ProcessDataStandardFormat | ||||
|         results.Add($"HEADER_OFFSET\t{headerOffset}"); | ||||
|         results.Add($"DATA_OFFSET\t{dataOffset}"); | ||||
|         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.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')}"); | ||||
| @ -366,7 +518,40 @@ internal class ProcessDataStandardFormat | ||||
|         results.Add($"START_TIME\t{startTime}"); | ||||
|         results.Add("LOGISTICS_COLUMN\tA_LOGISTICS"); | ||||
|         results.Add("LOGISTICS_COLUMN\tB_LOGISTICS"); | ||||
|         if (wsResults is null || wsResults.Count != 1) | ||||
|             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)); | ||||
|     } | ||||
|  | ||||
| @ -409,7 +594,7 @@ internal class ProcessDataStandardFormat | ||||
|                 { | ||||
|                     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("\","); | ||||
|                     } | ||||
|                 } | ||||
| @ -417,7 +602,7 @@ internal class ProcessDataStandardFormat | ||||
|                 { | ||||
|                     for (int c = 1; c < segments.Length; c++) | ||||
|                     { | ||||
|                         value = segments[c].Replace("\"", "\\\"").Replace("\\", "\\\\"); | ||||
|                         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)) | ||||
| @ -655,3 +840,8 @@ internal class ProcessDataStandardFormat | ||||
| 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 Microsoft.Extensions.Logging; | ||||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| #if true | ||||
| #if v2_59_0 | ||||
| using Adaptation._Tests.Shared; | ||||
| using Microsoft.Extensions.Logging; | ||||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| #if true | ||||
| #if v2_59_0 | ||||
| using Adaptation._Tests.Shared; | ||||
| using Microsoft.Extensions.Logging; | ||||
| 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 System; | ||||
| using System.Diagnostics; | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| #if true | ||||
| #if v2_59_0 | ||||
| using Adaptation.Shared; | ||||
| using Adaptation.Shared.Methods; | ||||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| #if true | ||||
| #if v2_59_0 | ||||
| using Adaptation.FileHandlers.json.WorkItems; | ||||
| using Adaptation.FileHandlers.Priority; | ||||
| using Adaptation.Shared; | ||||
| using Adaptation.Shared.Methods; | ||||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||
| @ -190,18 +189,6 @@ public class MESAFIBACKLOG | ||||
|         Assert.IsFalse(string.IsNullOrEmpty(extractResult?.Item1)); | ||||
|         Assert.IsNotNull(extractResult.Item3); | ||||
|         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(); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -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)) | ||||
|             _ = Directory.CreateDirectory(fileInfo.Directory.FullName); | ||||
|         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, FileConnectorConfiguration> fileConnectorConfigurationTuple = GetFileConnectorConfigurationTuple(cellInstanceVersionTuple, 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.Item4); | ||||
|             if (!validatePDSF) | ||||
|                 _ = GetProcessDataStandardFormat(fileRead, logistics, extractResult, ProcessDataStandardFormat.GetEmpty()); | ||||
|                 _ = GetProcessDataStandardFormat(fileRead, logistics, extractResult, ProcessDataStandardFormat.GetEmpty(logistics)); | ||||
|             else | ||||
|             { | ||||
|                 Assert.IsTrue(extractResult.Item3.Length > 0, "extractResult Array Length check!"); | ||||
|  | ||||
| @ -64,8 +64,8 @@ public class BACKLOG : LoggingUnitTesting, IDisposable | ||||
|         StringBuilder results = new(); | ||||
|         (string cellInstanceName, string cellInstanceVersionName)[] collection = new (string, string)[] | ||||
|         { | ||||
|             new("BACKLOG", "v2.59.0"), | ||||
|             new("BACKLOG-EQPT", "v2.59.0"), | ||||
|             new("BACKLOG", "v2.60.0"), | ||||
|             new("BACKLOG-EQPT", "v2.60.0"), | ||||
|         }; | ||||
|         string development = "http://eaf-dev.mes.infineon.com:9003/CellInstanceServiceV2"; | ||||
|         Shared.PasteSpecialXml.EAF.XML.API.CellInstance.CellInstanceVersion cellInstanceVersion; | ||||
|  | ||||
| @ -64,7 +64,7 @@ public class MESAFIBACKLOG : LoggingUnitTesting, IDisposable | ||||
|         StringBuilder results = new(); | ||||
|         (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"; | ||||
|         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": { | ||||
|         "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\\\")", | ||||
|  | ||||
							
								
								
									
										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 readonly List<EquipmentParameter> _EquipmentParameters; | ||||
|     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() | ||||
|     { | ||||
|  | ||||
| @ -153,7 +153,7 @@ | ||||
|     <Compile Include="Adaptation\FileHandlers\Priority\Notification.cs" /> | ||||
|     <Compile Include="Adaptation\FileHandlers\Priority\Settings.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\Processed\FileRead.cs" /> | ||||
|     <Compile Include="Adaptation\FileHandlers\SPaCe\FileRead.cs" /> | ||||
| @ -214,34 +214,16 @@ | ||||
|       <Version>0.15.1</Version> | ||||
|     </PackageReference> | ||||
|     <PackageReference Include="Infineon.EAF.Runtime"> | ||||
|       <Version>2.58.0</Version> | ||||
|       <Version>2.60.0</Version> | ||||
|     </PackageReference> | ||||
|     <PackageReference Include="Microsoft.AspNet.SignalR.SelfHost"> | ||||
|       <Version>2.4.3</Version> | ||||
|     </PackageReference> | ||||
|     <PackageReference Include="Microsoft.AspNet.SignalR.Core"> | ||||
|       <Version>2.4.3</Version> | ||||
|     <PackageReference Include="Nancy.Owin"> | ||||
|       <Version>2.0.0</Version> | ||||
|     </PackageReference> | ||||
|     <PackageReference Include="Owin"> | ||||
|       <Version>1.0.0</Version> | ||||
|     </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"> | ||||
|       <Version>8.0.3</Version> | ||||
|       <Version>8.0.5</Version> | ||||
|     </PackageReference> | ||||
|   </ItemGroup> | ||||
|   <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 | ||||
| // by using the '*' as shown below: | ||||
| // [assembly: AssemblyVersion("1.0.*")] | ||||
| [assembly: AssemblyVersion("2.59.0.0")] | ||||
| [assembly: AssemblyFileVersion("2.59.0.0")] | ||||
| [assembly: AssemblyVersion("2.60.0.0")] | ||||
| [assembly: AssemblyFileVersion("2.60.0.0")] | ||||
|  | ||||
		Reference in New Issue
	
	Block a user