Compare commits
17 Commits
5d9b5a4022
...
master
Author | SHA1 | Date | |
---|---|---|---|
2fc83bb54d | |||
40177bfb51 | |||
e02b70e258 | |||
534d0ccc5c | |||
9769e1e106 | |||
c3b309347c | |||
0f23ba19cc | |||
a343243576 | |||
304bf04afe | |||
08a23114c9 | |||
ca4ebff54c | |||
2d82216d25 | |||
7bcb87c5e5 | |||
7e38c565f3 | |||
0505330ac5 | |||
3fa7998ff6 | |||
9c5651a862 |
@ -92,8 +92,8 @@ csharp_using_directive_placement = outside_namespace
|
||||
dotnet_code_quality_unused_parameters = all
|
||||
dotnet_code_quality_unused_parameters = non_public # IDE0060: Remove unused parameter
|
||||
dotnet_code_quality.CAXXXX.api_surface = private, internal
|
||||
dotnet_diagnostic.CA1816.severity = none # CA1816: Call GC.SuppressFinalize correctly
|
||||
dotnet_diagnostic.CA1825.severity = warning # CA1823: Avoid zero-length array allocations
|
||||
dotnet_diagnostic.CA1510.severity = none # CA1510: Use 'ArgumentNullException.ThrowIfNull' instead of explicitly throwing a new exception instance
|
||||
dotnet_diagnostic.CA1816.severity = warning # CA1823: Avoid zero-length array allocations
|
||||
dotnet_diagnostic.CA1829.severity = warning # CA1829: Use Length/Count property instead of Count() when available
|
||||
dotnet_diagnostic.CA1834.severity = warning # CA1834: Consider using 'StringBuilder.Append(char)' when applicable
|
||||
dotnet_diagnostic.CA1846.severity = none # CA1846: Prefer AsSpan over Substring
|
||||
@ -121,6 +121,7 @@ dotnet_diagnostic.IDE0290.severity = none # Use primary constructor [Distance]cs
|
||||
dotnet_diagnostic.IDE0300.severity = none # IDE0300: Collection initialization can be simplified
|
||||
dotnet_diagnostic.IDE0301.severity = none #IDE0301: Collection initialization can be simplified
|
||||
dotnet_diagnostic.IDE0305.severity = none # IDE0305: Collection initialization can be simplified
|
||||
dotnet_diagnostic.MSTEST0037.severity = error # MSTEST0037: Use proper 'Assert' methods
|
||||
dotnet_diagnostic.SYSLIB1045.severity = none # SYSLIB1045: diagnostics for regex source generation
|
||||
dotnet_naming_rule.abstract_method_should_be_pascal_case.severity = warning
|
||||
dotnet_naming_rule.abstract_method_should_be_pascal_case.style = pascal_case
|
||||
|
21
Adaptation/.vscode/format-report.json
vendored
21
Adaptation/.vscode/format-report.json
vendored
@ -1 +1,20 @@
|
||||
[]
|
||||
[
|
||||
{
|
||||
"DocumentId": {
|
||||
"ProjectId": {
|
||||
"Id": "88b6bb05-fef2-487e-bb6c-9ae68922c0bb"
|
||||
},
|
||||
"Id": "63c5cda5-30ee-4e20-9ec8-d45777057452"
|
||||
},
|
||||
"FileName": "MonIn.cs",
|
||||
"FilePath": "L:\\DevOps\\EAF-Mesa-Integration\\mesafibacklog\\Adaptation\\Infineon\\Monitoring\\MonA\\MonIn.cs",
|
||||
"FileChanges": [
|
||||
{
|
||||
"LineNumber": 268,
|
||||
"CharNumber": 17,
|
||||
"DiagnosticId": "CA1816",
|
||||
"FormatDescription": "warning CA1816: Change MonIn.Dispose() to call GC.SuppressFinalize(object). This will prevent derived types that introduce a finalizer from needing to re-implement \u0027IDisposable\u0027 to call it."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
2
Adaptation/.vscode/launch.json
vendored
2
Adaptation/.vscode/launch.json
vendored
@ -4,7 +4,7 @@
|
||||
"name": ".NET Core Attach",
|
||||
"type": "coreclr",
|
||||
"request": "attach",
|
||||
"processId": 25140
|
||||
"processId": 23840
|
||||
}
|
||||
]
|
||||
}
|
||||
|
3
Adaptation/.vscode/settings.json
vendored
3
Adaptation/.vscode/settings.json
vendored
@ -45,6 +45,5 @@
|
||||
"titleBar.inactiveForeground": "#e7e7e799",
|
||||
"commandCenter.border": "#e7e7e799"
|
||||
},
|
||||
"peacock.color": "#4a727e",
|
||||
"cSpell.enabled": false
|
||||
"peacock.color": "#4a727e"
|
||||
}
|
44
Adaptation/.vscode/tasks.json
vendored
44
Adaptation/.vscode/tasks.json
vendored
@ -49,6 +49,16 @@
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "Format-Whitespaces",
|
||||
"command": "dotnet",
|
||||
"type": "process",
|
||||
"args": [
|
||||
"format",
|
||||
"whitespace"
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "Nuget Clear",
|
||||
"command": "dotnet",
|
||||
@ -68,7 +78,7 @@
|
||||
"args": [
|
||||
"/target:Build",
|
||||
"/restore:True",
|
||||
"/p:RestoreSources=https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/%3Bhttps://packagemanagement.eu.infineon.com:4430/api/v2/%3Bhttps://tfs.intra.infineon.com/tfs/ManufacturingIT/_packaging/eaf/nuget/v3/index.json%3Bhttps://tfs.intra.infineon.com/tfs/FactoryIntegration/_packaging/EAF%40Local/nuget/v3/index.json%3Bhttps://api.nuget.org/v3/index.json",
|
||||
"/p:RestoreSources=https://artifactory.intra.infineon.com/artifactory/api/nuget/ngt-fi-package-main-vir/%3Bhttps://tfs.intra.infineon.com/tfs/FactoryIntegration/_packaging/EAF/nuget/v3/index.json%3Bhttps://tfs.intra.infineon.com/tfs/FactoryIntegration/_packaging/EAF%40Local/nuget/v3/index.json%3Bhttps://api.nuget.org/v3/index.json",
|
||||
"/detailedsummary",
|
||||
"/consoleloggerparameters:PerformanceSummary;ErrorsOnly;",
|
||||
"/property:Configuration=Debug;TargetFrameworkVersion=v4.8",
|
||||
@ -76,6 +86,38 @@
|
||||
],
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "Project",
|
||||
"type": "shell",
|
||||
"command": "code ../MESAFIBACKLOG.csproj",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Readme",
|
||||
"type": "shell",
|
||||
"command": "code ../README.md",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "File-Folder-Helper AOT s X Day-Helper-2025-03-20",
|
||||
"type": "shell",
|
||||
"command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe",
|
||||
"args": [
|
||||
"s",
|
||||
"X",
|
||||
"L:/DevOps/EAF-Mesa-Integration/MESAFIBACKLOG",
|
||||
"Day-Helper-2025-03-20",
|
||||
"false",
|
||||
"4"
|
||||
],
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Git Config",
|
||||
"type": "shell",
|
||||
"command": "code ../.git/config",
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Kanbn Console",
|
||||
"type": "npm",
|
||||
|
123
Adaptation/FileHandlers/ADO/FileRead.cs
Normal file
123
Adaptation/FileHandlers/ADO/FileRead.cs
Normal file
@ -0,0 +1,123 @@
|
||||
using Adaptation.Eaf.Management.ConfigurationData.CellAutomation;
|
||||
using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration;
|
||||
using Adaptation.Shared;
|
||||
using Adaptation.Shared.Duplicator;
|
||||
using Adaptation.Shared.Methods;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Adaptation.FileHandlers.ADO;
|
||||
|
||||
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) :
|
||||
base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null)
|
||||
{
|
||||
_MinFileLength = 10;
|
||||
_NullData = string.Empty;
|
||||
_Logistics = new(this);
|
||||
if (_FileParameter is null)
|
||||
throw new Exception(cellInstanceConnectionName);
|
||||
if (_ModelObjectParameterDefinitions is null)
|
||||
throw new Exception(cellInstanceConnectionName);
|
||||
if (!_IsDuplicator)
|
||||
throw new Exception(cellInstanceConnectionName);
|
||||
string cellInstanceNamed = string.Concat("CellInstance.", _EquipmentType);
|
||||
_URL = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.URL");
|
||||
if (_IsEAFHosted)
|
||||
NestExistingFiles(_FileConnectorConfiguration);
|
||||
}
|
||||
|
||||
void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) => Move(extractResults);
|
||||
|
||||
void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null);
|
||||
|
||||
string IFileRead.GetEventDescription()
|
||||
{
|
||||
string result = _Description.GetEventDescription();
|
||||
return result;
|
||||
}
|
||||
|
||||
List<string> IFileRead.GetHeaderNames()
|
||||
{
|
||||
List<string> results = _Description.GetHeaderNames();
|
||||
return results;
|
||||
}
|
||||
|
||||
string[] IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, string to, string from, string resolvedFileLocation, Exception exception)
|
||||
{
|
||||
string[] results = Move(extractResults, to, from, resolvedFileLocation, exception);
|
||||
return results;
|
||||
}
|
||||
|
||||
JsonProperty[] IFileRead.GetDefault()
|
||||
{
|
||||
JsonProperty[] results = _Description.GetDefault(this, _Logistics);
|
||||
return results;
|
||||
}
|
||||
|
||||
Dictionary<string, string> IFileRead.GetDisplayNamesJsonElement()
|
||||
{
|
||||
Dictionary<string, string> results = _Description.GetDisplayNamesJsonElement(this);
|
||||
return results;
|
||||
}
|
||||
|
||||
List<IDescription> IFileRead.GetDescriptions(IFileRead fileRead, List<Test> tests, IProcessData processData)
|
||||
{
|
||||
List<IDescription> results = _Description.GetDescriptions(fileRead, _Logistics, tests, processData);
|
||||
return results;
|
||||
}
|
||||
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.GetExtractResult(string reportFullPath, string eventName)
|
||||
{
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> results;
|
||||
if (string.IsNullOrEmpty(eventName))
|
||||
throw new Exception();
|
||||
_ReportFullPath = reportFullPath;
|
||||
DateTime dateTime = DateTime.Now;
|
||||
results = GetExtractResult(reportFullPath, dateTime);
|
||||
if (results.Item3 is null)
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]"), results.Item4);
|
||||
if (results.Item3.Length > 0 && _IsEAFHosted)
|
||||
WritePDSF(this, results.Item3);
|
||||
UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks);
|
||||
return results;
|
||||
}
|
||||
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.ReExtract()
|
||||
{
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> results;
|
||||
List<string> headerNames = _Description.GetHeaderNames();
|
||||
Dictionary<string, string> keyValuePairs = _Description.GetDisplayNamesJsonElement(this);
|
||||
results = ReExtract(this, headerNames, keyValuePairs);
|
||||
return results;
|
||||
}
|
||||
|
||||
private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime)
|
||||
{
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> results = new(string.Empty, null, null, new List<FileInfo>());
|
||||
_TickOffset ??= 0; // new FileInfo(reportFullPath).LastWriteTime.Ticks - dateTime.Ticks;
|
||||
string[] lines = new string[] { string.Empty, "NUM_DATA_ROWS", $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};" };
|
||||
ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines);
|
||||
_Logistics = new Logistics(reportFullPath, processDataStandardFormat);
|
||||
SetFileParameterLotIDToLogisticsMID();
|
||||
if (_Logistics.FileInfo.Length < _MinFileLength)
|
||||
results.Item4.Add(_Logistics.FileInfo);
|
||||
else
|
||||
{
|
||||
IProcessData iProcessData = new ProcessData(this, _Logistics, _FileConnectorConfiguration.TargetFileLocation, _URL, results.Item4);
|
||||
if (iProcessData.Details.Count == 0)
|
||||
results = new(string.Concat("B) No Data - ", dateTime.Ticks), Array.Empty<Test>(), Array.Empty<JsonElement>(), results.Item4);
|
||||
else
|
||||
results = iProcessData.GetResults(this, _Logistics, results.Item4);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
265
Adaptation/FileHandlers/ADO/ProcessData.cs
Normal file
265
Adaptation/FileHandlers/ADO/ProcessData.cs
Normal file
@ -0,0 +1,265 @@
|
||||
using Adaptation.FileHandlers.json.WorkItems;
|
||||
using Adaptation.Shared;
|
||||
using Adaptation.Shared.Duplicator;
|
||||
using Adaptation.Shared.Methods;
|
||||
using log4net;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.ADO;
|
||||
|
||||
public class ProcessData : IProcessData
|
||||
{
|
||||
|
||||
private readonly List<object> _Details;
|
||||
|
||||
List<object> Shared.Properties.IProcessData.Details => _Details;
|
||||
|
||||
private readonly ILog _Log;
|
||||
|
||||
public ProcessData(IFileRead fileRead, Logistics logistics, string targetFileLocation, string url, List<FileInfo> fileInfoCollection)
|
||||
{
|
||||
if (fileRead.IsEAFHosted)
|
||||
{ }
|
||||
if (url is null)
|
||||
throw new ArgumentNullException(nameof(url));
|
||||
_Details = new List<object>();
|
||||
_Log = LogManager.GetLogger(typeof(ProcessData));
|
||||
WriteFiles(fileRead, logistics, targetFileLocation, fileInfoCollection);
|
||||
}
|
||||
|
||||
string IProcessData.GetCurrentReactor(IFileRead fileRead, Logistics logistics, Dictionary<string, string> reactors) =>
|
||||
throw new Exception(string.Concat("See ", nameof(WriteFiles)));
|
||||
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> IProcessData.GetResults(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection) =>
|
||||
new(logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), fileInfoCollection);
|
||||
|
||||
#nullable enable
|
||||
|
||||
internal static List<Description> GetDescriptions(JsonElement[] jsonElements)
|
||||
{
|
||||
List<Description> results = new();
|
||||
Description? description;
|
||||
JsonSerializerOptions jsonSerializerOptions = new() { NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString };
|
||||
foreach (JsonElement jsonElement in jsonElements)
|
||||
{
|
||||
if (jsonElement.ValueKind != JsonValueKind.Object)
|
||||
throw new Exception();
|
||||
description = JsonSerializer.Deserialize<Description>(jsonElement.ToString(), jsonSerializerOptions);
|
||||
if (description is null)
|
||||
continue;
|
||||
results.Add(description);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private void WriteFiles(IFileRead fileRead, Logistics logistics, string destinationDirectory, List<FileInfo> fileInfoCollection)
|
||||
{
|
||||
bool keepRelations = true;
|
||||
if (!Directory.Exists(destinationDirectory))
|
||||
_ = Directory.CreateDirectory(destinationDirectory);
|
||||
string json = File.ReadAllText(logistics.ReportFullPath);
|
||||
WorkItem[]? workItems = JsonSerializer.Deserialize<WorkItem[]>(json);
|
||||
if (workItems is null)
|
||||
throw new Exception(nameof(workItems));
|
||||
_Details.Add(workItems);
|
||||
ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations);
|
||||
WriteFileStructure(destinationDirectory, keyValuePairs);
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, keyValuePairs);
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, Record> GetWorkItems(WorkItem[] workItems, bool keepRelations)
|
||||
{
|
||||
ReadOnlyDictionary<int, Record> results;
|
||||
Dictionary<int, WorkItem> keyValuePairs = new();
|
||||
foreach (WorkItem workItem in workItems)
|
||||
keyValuePairs.Add(workItem.Id, workItem);
|
||||
results = GetKeyValuePairs(new(keyValuePairs), keepRelations);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static 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;
|
||||
string json;
|
||||
string checkFile;
|
||||
WorkItem workItem;
|
||||
string workItemType;
|
||||
string singletonDirectory;
|
||||
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileRead.ReportFullPath);
|
||||
string rootDirectory = Path.Combine(destinationDirectory, fileNameWithoutExtension);
|
||||
if (string.IsNullOrEmpty(rootDirectory))
|
||||
throw new NullReferenceException(nameof(rootDirectory));
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
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}");
|
||||
if (!Directory.Exists(singletonDirectory))
|
||||
_ = Directory.CreateDirectory(singletonDirectory);
|
||||
checkFile = Path.Combine(singletonDirectory, ".json");
|
||||
old = File.Exists(checkFile) ? File.ReadAllText(checkFile) : string.Empty;
|
||||
if (old == json)
|
||||
continue;
|
||||
File.WriteAllText(checkFile, json);
|
||||
if (!fileRead.IsEAFHosted)
|
||||
fileInfoCollection.Add(new(checkFile));
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, bool keepRelations)
|
||||
{
|
||||
Dictionary<int, Record> results = new();
|
||||
Record record;
|
||||
List<bool> nests = new();
|
||||
WorkItem? parentWorkItem;
|
||||
ReadOnlyCollection<Record> childRecords;
|
||||
ReadOnlyCollection<Record> relatedRecords;
|
||||
ReadOnlyCollection<Record> successorRecords;
|
||||
foreach (KeyValuePair<int, WorkItem> keyValuePair in keyValuePairs)
|
||||
{
|
||||
nests.Clear();
|
||||
if (keyValuePair.Value.Parent is null)
|
||||
parentWorkItem = null;
|
||||
else
|
||||
_ = keyValuePairs.TryGetValue(keyValuePair.Value.Parent.Value, out parentWorkItem);
|
||||
try
|
||||
{
|
||||
childRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Child", nests, keepRelations); // Forward
|
||||
relatedRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Related", nests, keepRelations); // Related
|
||||
successorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Successor", nests, keepRelations); // Forward
|
||||
// predecessorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Predecessor", nests, keepRelations); // Reverse
|
||||
record = Record.Get(keyValuePair.Value, parentWorkItem, childRecords, relatedRecords, successorRecords, keepRelations);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>());
|
||||
}
|
||||
results.Add(keyValuePair.Key, record);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static 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();
|
||||
results.Clear();
|
||||
results.AddRange(frontMatterLines);
|
||||
results.Add(string.Empty);
|
||||
results.Add($"# {record.WorkItem.Id}");
|
||||
results.Add(string.Empty);
|
||||
results.Add("## Backlog");
|
||||
results.Add(string.Empty);
|
||||
results.Add("## Todo");
|
||||
results.Add(string.Empty);
|
||||
results.Add("## In Progress");
|
||||
results.Add(string.Empty);
|
||||
results.Add("## Done");
|
||||
results.Add(string.Empty);
|
||||
return string.Join(Environment.NewLine, results);
|
||||
}
|
||||
|
||||
private static string GetMarkdownLines(string url, Record record, string jsonDirectory, string iterationPathDirectory)
|
||||
{
|
||||
List<string> results = new();
|
||||
string link;
|
||||
string target;
|
||||
results.Add($"# {record.WorkItem.Id}");
|
||||
results.Add(string.Empty);
|
||||
results.Add($"## {record.WorkItem.Title}");
|
||||
results.Add(string.Empty);
|
||||
if (record.Children is not null)
|
||||
{
|
||||
foreach (Record r in record.Children)
|
||||
results.Add($"- [{r.WorkItem.Id}]({url}{r.WorkItem.Id})");
|
||||
}
|
||||
results.Add(string.Empty);
|
||||
results.Add("```bash");
|
||||
if (record.Children is not null)
|
||||
{
|
||||
foreach (Record r in record.Children)
|
||||
{
|
||||
link = Path.Combine(jsonDirectory, $"{r.WorkItem.Id}-{r.WorkItem.WorkItemType}");
|
||||
target = Path.Combine(iterationPathDirectory, r.WorkItem.WorkItemType, $"{r.WorkItem.Id}-{r.WorkItem.WorkItemType}", r.WorkItem.Id.ToString());
|
||||
results.Add($"mklink /J \"{link}\" \"{target}\"");
|
||||
}
|
||||
}
|
||||
results.Add("```");
|
||||
results.Add(string.Empty);
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@ -120,15 +120,15 @@ 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;
|
||||
Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, pdsf.Item1);
|
||||
ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, processDataStandardFormat);
|
||||
SetFileParameterLotIDToLogisticsMID();
|
||||
JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf);
|
||||
JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat);
|
||||
List<Shared.Properties.IDescription> descriptions = GetDuplicatorDescriptions(jsonElements);
|
||||
Test[] tests = (from l in descriptions select (Test)l.Test).ToArray();
|
||||
if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0)
|
||||
FileCopy(reportFullPath, dateTime, descriptions);
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>());
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>());
|
||||
return results;
|
||||
}
|
||||
|
||||
|
@ -115,14 +115,15 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0060
|
||||
private void MoveArchive(string reportFullPath, DateTime dateTime)
|
||||
#pragma warning restore IDE0060
|
||||
{
|
||||
if (dateTime == DateTime.MinValue)
|
||||
throw new ArgumentNullException(nameof(dateTime));
|
||||
string logisticsSequence = _Logistics.Sequence.ToString();
|
||||
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}{@"\"}{_Logistics.DateTimeFromSequence:yyyy-MM-dd}";
|
||||
string destinationArchiveDirectory = Path.Combine(_JobIdArchiveParentDirectory, _Logistics.JobID, weekDirectory);
|
||||
string weekDirectory = $"{_Logistics.DateTimeFromSequence:yyyy}_Week_{weekOfYear}";
|
||||
string destinationArchiveDirectory = Path.Combine(_JobIdArchiveParentDirectory, _Logistics.JobID, weekDirectory, day);
|
||||
if (!Directory.Exists(destinationArchiveDirectory))
|
||||
_ = Directory.CreateDirectory(destinationArchiveDirectory);
|
||||
string jobIdDirectory = Path.Combine(_JobIdParentDirectory, _Logistics.JobID);
|
||||
@ -144,15 +145,15 @@ 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;
|
||||
Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, pdsf.Item1);
|
||||
ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, processDataStandardFormat);
|
||||
SetFileParameterLotIDToLogisticsMID();
|
||||
JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf);
|
||||
JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat);
|
||||
List<Shared.Properties.IDescription> descriptions = GetDuplicatorDescriptions(jsonElements);
|
||||
Test[] tests = (from l in descriptions select (Test)l.Test).ToArray();
|
||||
if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0)
|
||||
MoveArchive(reportFullPath, dateTime);
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>());
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>());
|
||||
return results;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@ public class CellInstanceConnectionName
|
||||
{
|
||||
IFileRead result = cellInstanceConnectionName switch
|
||||
{
|
||||
nameof(ADO) => new ADO.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null),
|
||||
nameof(APC) => new APC.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null),
|
||||
nameof(Archive) => new Archive.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null),
|
||||
nameof(DownloadWorkItems) => new DownloadWorkItems.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null),
|
||||
@ -28,6 +29,7 @@ public class CellInstanceConnectionName
|
||||
nameof(Priority) => new Priority.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null),
|
||||
nameof(Processed) => new Processed.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null),
|
||||
nameof(SPaCe) => new SPaCe.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null),
|
||||
nameof(Violation) => new Violation.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null),
|
||||
_ => throw new Exception($"\"{cellInstanceConnectionName}\" not mapped")
|
||||
};
|
||||
return result;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Adaptation.Eaf.Management.ConfigurationData.CellAutomation;
|
||||
using Adaptation.FileHandlers.json.WIQL;
|
||||
using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration;
|
||||
using Adaptation.Shared;
|
||||
using Adaptation.Shared.Duplicator;
|
||||
@ -148,12 +149,11 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
streamTask.Wait();
|
||||
if (!streamTask.Result.CanRead)
|
||||
throw new NullReferenceException(nameof(streamTask));
|
||||
JsonSerializerOptions jsonSerializerOptions = new() { PropertyNameCaseInsensitive = true };
|
||||
json.WIQL.Root? root = JsonSerializer.Deserialize<json.WIQL.Root>(streamTask.Result, jsonSerializerOptions);
|
||||
Root? root = JsonSerializer.Deserialize(streamTask.Result, RootSourceGenerationContext.Default.Root);
|
||||
streamTask.Result.Dispose();
|
||||
if (root is null || root.WorkItems is null)
|
||||
throw new NullReferenceException(nameof(root));
|
||||
foreach (json.WIQL.WorkItem workItem in root.WorkItems)
|
||||
foreach (WorkItem workItem in root.WorkItems)
|
||||
{
|
||||
results.Add(workItem.Id);
|
||||
if (results.Count > 199)
|
||||
@ -223,7 +223,10 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
string subject = string.Concat("Exception:", _CellInstanceConnectionName);
|
||||
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
|
||||
try
|
||||
{ _SMTP.SendHighPriorityEmailMessage(subject, body); }
|
||||
{
|
||||
_SMTP.SendHighPriorityEmailMessage(subject, body);
|
||||
File.WriteAllText(".email", body);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
try
|
||||
@ -238,7 +241,10 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
string subject = string.Concat("Exception:", _CellInstanceConnectionName);
|
||||
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
|
||||
try
|
||||
{ _SMTP.SendHighPriorityEmailMessage(subject, body); }
|
||||
{
|
||||
_SMTP.SendHighPriorityEmailMessage(subject, body);
|
||||
File.WriteAllText(".email", body);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
|
@ -137,7 +137,10 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
string subject = string.Concat("Exception:", _CellInstanceConnectionName);
|
||||
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
|
||||
try
|
||||
{ _SMTP.SendHighPriorityEmailMessage(subject, body); }
|
||||
{
|
||||
_SMTP.SendHighPriorityEmailMessage(subject, body);
|
||||
File.WriteAllText(".email", body);
|
||||
}
|
||||
catch (Exception) { }
|
||||
File.AppendAllLines(traceDummyFile, new string[] { site, monARessource, stateName, State.Critical.ToString(), exception.Message, exception.StackTrace });
|
||||
_ = monIn.SendStatus(site, monARessource, stateName, State.Critical);
|
||||
@ -265,7 +268,10 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
string subject = string.Concat("Exception:", _CellInstanceConnectionName);
|
||||
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
|
||||
try
|
||||
{ _SMTP.SendHighPriorityEmailMessage(subject, body); }
|
||||
{
|
||||
_SMTP.SendHighPriorityEmailMessage(subject, body);
|
||||
File.WriteAllText(".email", body);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
try
|
||||
@ -278,7 +284,10 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
string subject = string.Concat("Exception:", _CellInstanceConnectionName);
|
||||
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
|
||||
try
|
||||
{ _SMTP.SendHighPriorityEmailMessage(subject, body); }
|
||||
{
|
||||
_SMTP.SendHighPriorityEmailMessage(subject, body);
|
||||
File.WriteAllText(".email", body);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
|
@ -119,15 +119,15 @@ 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;
|
||||
Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, pdsf.Item1);
|
||||
ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, processDataStandardFormat);
|
||||
SetFileParameterLotIDToLogisticsMID();
|
||||
JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf);
|
||||
JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat);
|
||||
List<Shared.Properties.IDescription> descriptions = GetDuplicatorDescriptions(jsonElements);
|
||||
Test[] tests = (from l in descriptions select (Test)l.Test).ToArray();
|
||||
if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0)
|
||||
FileCopy(reportFullPath, dateTime, descriptions);
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>());
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>());
|
||||
return results;
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ using Adaptation.Shared.Duplicator;
|
||||
using Adaptation.Shared.Methods;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
|
||||
@ -16,8 +15,6 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
|
||||
private long? _TickOffset;
|
||||
private readonly string _URL;
|
||||
private readonly ReadOnlyCollection<string> _CSSLines;
|
||||
private readonly ReadOnlyCollection<string> _FrontMatterLines;
|
||||
|
||||
public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) :
|
||||
base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null)
|
||||
@ -31,20 +28,8 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
throw new Exception(cellInstanceConnectionName);
|
||||
if (!_IsDuplicator)
|
||||
throw new Exception(cellInstanceConnectionName);
|
||||
List<string> cssLines = new();
|
||||
string cellInstanceNamed = string.Concat("CellInstance.", _EquipmentType);
|
||||
_URL = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.URL");
|
||||
string cssLinesName = string.Concat("CellInstance.", cellInstanceName, '.', cellInstanceConnectionName, ".CSS.Lines");
|
||||
ModelObjectParameterDefinition[] cssLinesDefinitions = GetProperties(cellInstanceConnectionName, modelObjectParameters, cssLinesName);
|
||||
foreach (ModelObjectParameterDefinition modelObjectParameterDefinition in cssLinesDefinitions)
|
||||
cssLines.Add(modelObjectParameterDefinition.Value);
|
||||
_CSSLines = new(cssLines);
|
||||
List<string> FrontMatterLines = new();
|
||||
string FrontMatterLinesName = string.Concat("CellInstance.", cellInstanceName, '.', cellInstanceConnectionName, ".Front.Matter.Lines");
|
||||
ModelObjectParameterDefinition[] FrontMatterLinesDefinitions = GetProperties(cellInstanceConnectionName, modelObjectParameters, FrontMatterLinesName);
|
||||
foreach (ModelObjectParameterDefinition modelObjectParameterDefinition in FrontMatterLinesDefinitions)
|
||||
FrontMatterLines.Add(modelObjectParameterDefinition.Value);
|
||||
_FrontMatterLines = new(FrontMatterLines);
|
||||
if (_IsEAFHosted)
|
||||
NestExistingFiles(_FileConnectorConfiguration);
|
||||
}
|
||||
@ -118,15 +103,18 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
{
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> results = new(string.Empty, null, null, new List<FileInfo>());
|
||||
_TickOffset ??= 0; // new FileInfo(reportFullPath).LastWriteTime.Ticks - dateTime.Ticks;
|
||||
_Logistics = new Logistics(reportFullPath, $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};");
|
||||
string[] lines = new string[] { string.Empty, "NUM_DATA_ROWS", $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};" };
|
||||
ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines);
|
||||
_Logistics = new Logistics(reportFullPath, processDataStandardFormat);
|
||||
SetFileParameterLotIDToLogisticsMID();
|
||||
if (_Logistics.FileInfo.Length < _MinFileLength)
|
||||
results.Item4.Add(_Logistics.FileInfo);
|
||||
else
|
||||
{
|
||||
IProcessData iProcessData = new ProcessData(this, _Logistics, _FileConnectorConfiguration.TargetFileLocation, _URL, _CSSLines, _FrontMatterLines, results.Item4);
|
||||
IProcessData iProcessData = new ProcessData(this, _Logistics, _Calendar, _FileConnectorConfiguration.TargetFileLocation, _URL, results.Item4);
|
||||
if (iProcessData.Details.Count == 0)
|
||||
throw new Exception(string.Concat("B) No Data - ", dateTime.Ticks));
|
||||
results = new(string.Concat("B) No Data - ", dateTime.Ticks), Array.Empty<Test>(), Array.Empty<JsonElement>(), results.Item4);
|
||||
else
|
||||
results = iProcessData.GetResults(this, _Logistics, results.Item4);
|
||||
}
|
||||
return results;
|
||||
|
@ -6,13 +6,15 @@ using log4net;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.Kanban;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public class ProcessData : IProcessData
|
||||
{
|
||||
|
||||
@ -22,23 +24,197 @@ public class ProcessData : IProcessData
|
||||
|
||||
private readonly ILog _Log;
|
||||
|
||||
public ProcessData(IFileRead fileRead, Logistics logistics, string targetFileLocation, string url, ReadOnlyCollection<string> cssLines, ReadOnlyCollection<string> frontMatterLines, List<FileInfo> fileInfoCollection)
|
||||
{
|
||||
if (fileRead.IsEAFHosted)
|
||||
{ }
|
||||
fileInfoCollection.Clear();
|
||||
_Details = new List<object>();
|
||||
_Log = LogManager.GetLogger(typeof(ProcessData));
|
||||
WriteFiles(fileRead, logistics, url, cssLines, frontMatterLines, targetFileLocation, fileInfoCollection);
|
||||
}
|
||||
|
||||
string IProcessData.GetCurrentReactor(IFileRead fileRead, Logistics logistics, Dictionary<string, string> reactors) =>
|
||||
throw new Exception(string.Concat("See ", nameof(WriteFiles)));
|
||||
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> IProcessData.GetResults(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection) =>
|
||||
new(logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), fileInfoCollection);
|
||||
|
||||
#nullable enable
|
||||
public ProcessData(IFileRead fileRead, Logistics logistics, Calendar calendar, string targetFileLocation, string url, List<FileInfo> fileInfoCollection)
|
||||
{
|
||||
if (fileRead.IsEAFHosted)
|
||||
{
|
||||
|
||||
}
|
||||
if (url is null)
|
||||
throw new ArgumentNullException(nameof(url));
|
||||
_Details = new List<object>();
|
||||
_Log = LogManager.GetLogger(typeof(ProcessData));
|
||||
WriteFiles(fileRead, logistics, calendar, targetFileLocation, fileInfoCollection);
|
||||
}
|
||||
|
||||
private static void WriteFiles(IFileRead fileRead, Calendar calendar, string destinationDirectory, bool keepRelations, WorkItem[] workItems)
|
||||
{
|
||||
string json;
|
||||
string text;
|
||||
string jsonOld;
|
||||
string jsonFile;
|
||||
string textFile;
|
||||
string weekOfYear;
|
||||
WorkItem workItem;
|
||||
DirectoryInfo directory;
|
||||
DirectoryInfo kanbnDirectory;
|
||||
DirectoryInfo tasksDirectory;
|
||||
DirectoryInfo visualStudioCodeDirectory;
|
||||
ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations);
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
workItem = keyValuePair.Value.WorkItem;
|
||||
json = JsonSerializer.Serialize(workItem, WorkItemSourceGenerationContext.Default.WorkItem);
|
||||
weekOfYear = calendar.GetWeekOfYear(workItem.CreatedDate, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
|
||||
directory = new(Path.Combine(destinationDirectory, "{}", $"{workItem.CreatedDate:yyyy}", $"{workItem.CreatedDate:yyyy}_Week_{weekOfYear}", $"{workItem.Id}"));
|
||||
text = GetTaskText(directory.FullName);
|
||||
visualStudioCodeDirectory = new(Path.Combine(directory.FullName, ".vscode"));
|
||||
if (!visualStudioCodeDirectory.Exists)
|
||||
_ = Directory.CreateDirectory(visualStudioCodeDirectory.FullName);
|
||||
textFile = Path.Combine(visualStudioCodeDirectory.FullName, "tasks.json");
|
||||
if (fileRead.IsEAFHosted && !File.Exists(textFile))
|
||||
File.WriteAllText(textFile, text);
|
||||
kanbnDirectory = new(Path.Combine(directory.FullName, ".kanbn"));
|
||||
tasksDirectory = new(Path.Combine(kanbnDirectory.FullName, "tasks"));
|
||||
if (!tasksDirectory.Exists)
|
||||
_ = Directory.CreateDirectory(tasksDirectory.FullName);
|
||||
jsonFile = Path.Combine(kanbnDirectory.FullName, $"{workItem.Id}.json");
|
||||
jsonOld = File.Exists(jsonFile) ? File.ReadAllText(jsonFile) : string.Empty;
|
||||
if (fileRead.IsEAFHosted && jsonOld != json)
|
||||
File.WriteAllText(jsonFile, json);
|
||||
if (keyValuePair.Value.Children is not null && keyValuePair.Value.Children.Length > 0)
|
||||
WriteFiles(fileRead, tasksDirectory, keyValuePair.Value.Children);
|
||||
if (visualStudioCodeDirectory.LastWriteTime != workItem.CreatedDate)
|
||||
Directory.SetLastWriteTime(visualStudioCodeDirectory.FullName, workItem.CreatedDate);
|
||||
if (kanbnDirectory.LastWriteTime != workItem.CreatedDate)
|
||||
Directory.SetLastWriteTime(kanbnDirectory.FullName, workItem.CreatedDate);
|
||||
if (directory.LastWriteTime != workItem.CreatedDate)
|
||||
Directory.SetLastWriteTime(directory.FullName, workItem.CreatedDate);
|
||||
if (visualStudioCodeDirectory.CreationTime != workItem.CreatedDate)
|
||||
Directory.SetCreationTime(visualStudioCodeDirectory.FullName, workItem.CreatedDate);
|
||||
if (kanbnDirectory.CreationTime != workItem.CreatedDate)
|
||||
Directory.SetCreationTime(kanbnDirectory.FullName, workItem.CreatedDate);
|
||||
if (directory.CreationTime != workItem.CreatedDate)
|
||||
Directory.SetCreationTime(directory.FullName, workItem.CreatedDate);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteFiles(IFileRead fileRead, Logistics logistics, Calendar calendar, string destinationDirectory, List<FileInfo> fileInfoCollection)
|
||||
{
|
||||
if (fileInfoCollection is null)
|
||||
throw new ArgumentNullException(nameof(fileInfoCollection));
|
||||
bool keepRelations = true;
|
||||
string json = File.ReadAllText(logistics.ReportFullPath);
|
||||
WorkItem[]? workItems = JsonSerializer.Deserialize<WorkItem[]>(json);
|
||||
if (workItems is null)
|
||||
throw new Exception(nameof(workItems));
|
||||
_Details.Add(workItems);
|
||||
if (!Directory.Exists(destinationDirectory))
|
||||
_ = Directory.CreateDirectory(destinationDirectory);
|
||||
WriteFiles(fileRead, calendar, destinationDirectory, workItems);
|
||||
WriteFiles(fileRead, calendar, destinationDirectory, keepRelations, workItems);
|
||||
}
|
||||
|
||||
private static void WriteFiles(IFileRead fileRead, Calendar calendar, string destinationDirectory, WorkItem[] workItems)
|
||||
{
|
||||
string old;
|
||||
string json;
|
||||
string directory;
|
||||
string checkFile;
|
||||
string weekOfYear;
|
||||
foreach (WorkItem workItem in workItems)
|
||||
{
|
||||
weekOfYear = calendar.GetWeekOfYear(workItem.CreatedDate, CalendarWeekRule.FirstDay, DayOfWeek.Sunday).ToString("00");
|
||||
directory = Path.Combine(destinationDirectory, "[]", $"{workItem.CreatedDate:yyyy}", $"{workItem.CreatedDate:yyyy}_Week_{weekOfYear}", $"{workItem.Id}");
|
||||
if (!Directory.Exists(directory))
|
||||
_ = Directory.CreateDirectory(directory);
|
||||
json = JsonSerializer.Serialize(workItem, WorkItemSourceGenerationContext.Default.WorkItem);
|
||||
checkFile = Path.Combine(directory, $"{workItem.Id}.json");
|
||||
old = File.Exists(checkFile) ? File.ReadAllText(checkFile) : string.Empty;
|
||||
if (!fileRead.IsEAFHosted || old == json)
|
||||
continue;
|
||||
File.WriteAllText(checkFile, json);
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, Record> GetWorkItems(WorkItem[] workItems, bool keepRelations)
|
||||
{
|
||||
ReadOnlyDictionary<int, Record> results;
|
||||
Dictionary<int, WorkItem> keyValuePairs = new();
|
||||
foreach (WorkItem workItem in workItems)
|
||||
keyValuePairs.Add(workItem.Id, workItem);
|
||||
results = GetKeyValuePairs(new(keyValuePairs), keepRelations);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, bool keepRelations)
|
||||
{
|
||||
Dictionary<int, Record> results = new();
|
||||
Record record;
|
||||
List<bool> nests = new();
|
||||
WorkItem? parentWorkItem;
|
||||
ReadOnlyCollection<Record> childRecords;
|
||||
ReadOnlyCollection<Record> relatedRecords;
|
||||
ReadOnlyCollection<Record> successorRecords;
|
||||
foreach (KeyValuePair<int, WorkItem> keyValuePair in keyValuePairs)
|
||||
{
|
||||
nests.Clear();
|
||||
if (keyValuePair.Value.Parent is null)
|
||||
parentWorkItem = null;
|
||||
else
|
||||
_ = keyValuePairs.TryGetValue(keyValuePair.Value.Parent.Value, out parentWorkItem);
|
||||
try
|
||||
{
|
||||
childRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Child", nests, keepRelations); // Forward
|
||||
relatedRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Related", nests, keepRelations); // Related
|
||||
successorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Successor", nests, keepRelations); // Forward
|
||||
// predecessorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Predecessor", nests, keepRelations); // Reverse
|
||||
record = Record.Get(keyValuePair.Value, parentWorkItem, childRecords, relatedRecords, successorRecords, keepRelations);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>());
|
||||
}
|
||||
results.Add(keyValuePair.Key, record);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static string GetTaskText(string directory) =>
|
||||
string.Join(Environment.NewLine, new string[]
|
||||
{
|
||||
"{",
|
||||
"\"version\": \"2.0.0\",",
|
||||
"\"tasks\": [",
|
||||
"{",
|
||||
"\"label\": \"File-Folder-Helper AOT s X Day-Helper-2025-02-04\",",
|
||||
"\"type\": \"shell\",",
|
||||
"\"command\": \"L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe\",",
|
||||
"\"args\": [",
|
||||
"\"s\",",
|
||||
"\"X\",",
|
||||
$"\"{directory.Replace('\\', '/')}\",",
|
||||
"\"Day-Helper-2025-02-04\",",
|
||||
"],",
|
||||
"\"problemMatcher\": []",
|
||||
"}",
|
||||
"]",
|
||||
"}",
|
||||
});
|
||||
|
||||
private static void WriteFiles(IFileRead fileRead, DirectoryInfo tasksDirectory, Record[] records)
|
||||
{
|
||||
string old;
|
||||
string json;
|
||||
string checkFile;
|
||||
WorkItem workItem;
|
||||
foreach (Record record in records)
|
||||
{
|
||||
workItem = record.WorkItem;
|
||||
json = JsonSerializer.Serialize(workItem, WorkItemSourceGenerationContext.Default.WorkItem);
|
||||
checkFile = Path.Combine(tasksDirectory.FullName, $"{workItem.Id}.json");
|
||||
old = File.Exists(checkFile) ? File.ReadAllText(checkFile) : string.Empty;
|
||||
if (!fileRead.IsEAFHosted || old == json)
|
||||
continue;
|
||||
File.WriteAllText(checkFile, json);
|
||||
}
|
||||
}
|
||||
|
||||
internal static List<Description> GetDescriptions(JsonElement[] jsonElements)
|
||||
{
|
||||
@ -57,316 +233,4 @@ public class ProcessData : IProcessData
|
||||
return results;
|
||||
}
|
||||
|
||||
private void WriteFiles(IFileRead fileRead, Logistics logistics, string url, ReadOnlyCollection<string> cssLines, ReadOnlyCollection<string> frontMatterLines, string destinationDirectory, List<FileInfo> fileInfoCollection)
|
||||
{
|
||||
if (!Directory.Exists(destinationDirectory))
|
||||
_ = Directory.CreateDirectory(destinationDirectory);
|
||||
string json = File.ReadAllText(logistics.ReportFullPath);
|
||||
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(logistics.ReportFullPath);
|
||||
WorkItem[]? workItems = JsonSerializer.Deserialize<WorkItem[]>(json);
|
||||
if (workItems is null)
|
||||
throw new Exception(nameof(workItems));
|
||||
_Details.Add(workItems);
|
||||
ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems);
|
||||
WriteFileStructure(destinationDirectory, keyValuePairs);
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, fileNameWithoutExtension, keyValuePairs);
|
||||
WriteKanbanFiles(fileRead, url, cssLines, frontMatterLines, fileInfoCollection, destinationDirectory, keyValuePairs);
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, Record> GetWorkItems(WorkItem[] workItems)
|
||||
{
|
||||
ReadOnlyDictionary<int, Record> results;
|
||||
Dictionary<int, WorkItem> keyValuePairs = new();
|
||||
foreach (WorkItem workItem in workItems)
|
||||
keyValuePairs.Add(workItem.Id, workItem);
|
||||
results = GetKeyValuePairs(new(keyValuePairs));
|
||||
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, string fileNameWithoutExtension, ReadOnlyDictionary<int, Record> keyValuePairs)
|
||||
{
|
||||
string old;
|
||||
string json;
|
||||
string checkFile;
|
||||
WorkItem workItem;
|
||||
string singletonDirectory;
|
||||
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
|
||||
string rootDirectory = Path.Combine(destinationDirectory, fileNameWithoutExtension);
|
||||
if (string.IsNullOrEmpty(rootDirectory))
|
||||
throw new NullReferenceException(nameof(rootDirectory));
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
workItem = keyValuePair.Value.WorkItem;
|
||||
json = JsonSerializer.Serialize(workItem, jsonSerializerOptions);
|
||||
singletonDirectory = Path.Combine(rootDirectory, workItem.WorkItemType.Replace(" ", "-"), $"{workItem.Id}-{workItem.WorkItemType.Replace(" ", "-")}");
|
||||
if (!Directory.Exists(singletonDirectory))
|
||||
_ = Directory.CreateDirectory(singletonDirectory);
|
||||
checkFile = Path.Combine(singletonDirectory, ".json");
|
||||
if (File.Exists(checkFile))
|
||||
{
|
||||
old = File.ReadAllText(checkFile);
|
||||
if (old == json)
|
||||
continue;
|
||||
}
|
||||
File.WriteAllText(checkFile, json);
|
||||
if (!fileRead.IsEAFHosted)
|
||||
fileInfoCollection.Add(new(checkFile));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void WriteKanbanFiles(IFileRead fileRead, string url, ReadOnlyCollection<string> cssLines, ReadOnlyCollection<string> frontMatterLines, List<FileInfo> fileInfoCollection, string destinationDirectory, ReadOnlyDictionary<int, Record> keyValuePairs)
|
||||
{
|
||||
string old;
|
||||
string json;
|
||||
Record record;
|
||||
string markdown;
|
||||
string checkFile;
|
||||
string jsonDirectory;
|
||||
string tasksDirectory;
|
||||
string kanbanDirectory;
|
||||
string vscodeDirectory;
|
||||
string[] iterationPaths;
|
||||
string singletonDirectory;
|
||||
string iterationPathDirectory;
|
||||
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
record = keyValuePair.Value;
|
||||
iterationPathDirectory = destinationDirectory;
|
||||
iterationPaths = record.WorkItem.IterationPath.Split('\\');
|
||||
json = JsonSerializer.Serialize(record, jsonSerializerOptions);
|
||||
foreach (string iterationPath in iterationPaths)
|
||||
{
|
||||
if (iterationPath.Contains("Sprint"))
|
||||
continue;
|
||||
iterationPathDirectory = Path.Combine(iterationPathDirectory, iterationPath);
|
||||
}
|
||||
singletonDirectory = Path.Combine(iterationPathDirectory, record.WorkItem.WorkItemType.Replace(" ", "-"), $"{record.WorkItem.Id}-{record.WorkItem.WorkItemType.Replace(" ", "-")}");
|
||||
kanbanDirectory = Path.Combine(singletonDirectory, ".kanbn");
|
||||
if (!Directory.Exists(kanbanDirectory))
|
||||
_ = Directory.CreateDirectory(kanbanDirectory);
|
||||
tasksDirectory = Path.Combine(kanbanDirectory, "tasks");
|
||||
if (!Directory.Exists(tasksDirectory))
|
||||
_ = Directory.CreateDirectory(tasksDirectory);
|
||||
vscodeDirectory = Path.Combine(singletonDirectory, ".vscode");
|
||||
if (!Directory.Exists(vscodeDirectory))
|
||||
_ = Directory.CreateDirectory(vscodeDirectory);
|
||||
jsonDirectory = Path.Combine(singletonDirectory, record.WorkItem.Id.ToString());
|
||||
if (!Directory.Exists(jsonDirectory))
|
||||
_ = Directory.CreateDirectory(jsonDirectory);
|
||||
checkFile = Path.Combine(vscodeDirectory, "settings.json");
|
||||
if (!File.Exists(checkFile))
|
||||
File.WriteAllText(checkFile, "{ \"[markdown]\": { \"editor.wordWrap\": \"off\" }, \"cSpell.words\": [ \"kanbn\" ] }");
|
||||
markdown = GetIndexLines(frontMatterLines, record);
|
||||
checkFile = Path.Combine(kanbanDirectory, "board.css");
|
||||
if (!File.Exists(checkFile))
|
||||
File.WriteAllLines(checkFile, cssLines);
|
||||
checkFile = Path.Combine(kanbanDirectory, "index.md");
|
||||
if (!File.Exists(checkFile))
|
||||
File.WriteAllText(checkFile, markdown);
|
||||
checkFile = Path.Combine(jsonDirectory, ".json");
|
||||
old = File.Exists(checkFile) ? File.ReadAllText(checkFile) : string.Empty;
|
||||
if (old != json)
|
||||
File.WriteAllText(checkFile, json);
|
||||
markdown = GetMarkdownLines(url, record, jsonDirectory, iterationPathDirectory);
|
||||
checkFile = Path.Combine(vscodeDirectory, "markdown.md");
|
||||
old = File.Exists(checkFile) ? File.ReadAllText(checkFile) : string.Empty;
|
||||
if (old != markdown)
|
||||
File.WriteAllText(checkFile, markdown);
|
||||
if (!fileRead.IsEAFHosted)
|
||||
fileInfoCollection.Add(new(checkFile));
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs)
|
||||
{
|
||||
Dictionary<int, Record> results = new();
|
||||
Record record;
|
||||
List<bool> nests = new();
|
||||
WorkItem? parentWorkItem;
|
||||
ReadOnlyCollection<Record> records;
|
||||
foreach (KeyValuePair<int, WorkItem> keyValuePair in keyValuePairs)
|
||||
{
|
||||
nests.Clear();
|
||||
if (keyValuePair.Value.Parent is null)
|
||||
parentWorkItem = null;
|
||||
else
|
||||
_ = keyValuePairs.TryGetValue(keyValuePair.Value.Parent.Value, out parentWorkItem);
|
||||
try
|
||||
{
|
||||
records = GetKeyValuePairs(keyValuePairs, keyValuePair.Value, nests);
|
||||
record = Record.Get(keyValuePair.Value, parentWorkItem, records);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>());
|
||||
}
|
||||
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();
|
||||
results.Clear();
|
||||
results.AddRange(frontMatterLines);
|
||||
results.Add(string.Empty);
|
||||
results.Add($"# {record.WorkItem.Id}");
|
||||
results.Add(string.Empty);
|
||||
results.Add("## Backlog");
|
||||
results.Add(string.Empty);
|
||||
results.Add("## Todo");
|
||||
results.Add(string.Empty);
|
||||
results.Add("## In Progress");
|
||||
results.Add(string.Empty);
|
||||
results.Add("## Done");
|
||||
results.Add(string.Empty);
|
||||
return string.Join(Environment.NewLine, results);
|
||||
}
|
||||
|
||||
private static string GetMarkdownLines(string url, Record record, string jsonDirectory, string iterationPathDirectory)
|
||||
{
|
||||
List<string> results = new();
|
||||
string link;
|
||||
string target;
|
||||
results.Add($"# {record.WorkItem.Id}");
|
||||
results.Add(string.Empty);
|
||||
results.Add($"## {record.WorkItem.Title}");
|
||||
results.Add(string.Empty);
|
||||
foreach (Record r in record.Children)
|
||||
results.Add($"- [{r.WorkItem.Id}]({url}{r.WorkItem.Id})");
|
||||
results.Add(string.Empty);
|
||||
results.Add("```bash");
|
||||
foreach (Record r in record.Children)
|
||||
{
|
||||
link = Path.Combine(jsonDirectory, $"{r.WorkItem.Id}-{r.WorkItem.WorkItemType}");
|
||||
target = Path.Combine(iterationPathDirectory, r.WorkItem.WorkItemType, $"{r.WorkItem.Id}-{r.WorkItem.WorkItemType}", r.WorkItem.Id.ToString());
|
||||
results.Add($"mklink /J \"{link}\" \"{target}\"");
|
||||
}
|
||||
results.Add("```");
|
||||
results.Add(string.Empty);
|
||||
return string.Join(Environment.NewLine, results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, WorkItem workItem, List<bool> nests)
|
||||
{
|
||||
List<Record> results = new();
|
||||
int? childId;
|
||||
Record record;
|
||||
nests.Add(true);
|
||||
WorkItem? childWorkItem;
|
||||
WorkItem? parentWorkItem;
|
||||
List<WorkItem> collection = new();
|
||||
ReadOnlyCollection<Record> records;
|
||||
if (workItem.Relations is not null && workItem.Relations.Length > 0)
|
||||
{
|
||||
collection.Clear();
|
||||
foreach (Relation relation in workItem.Relations)
|
||||
{
|
||||
childId = GetIdFromUrlIfChild(relation);
|
||||
if (childId is not null && workItem.Parent is not null && relation?.URL is not null && relation.URL.Contains(workItem.Parent.Value.ToString()))
|
||||
continue;
|
||||
if (childId is null || !keyValuePairs.TryGetValue(childId.Value, out childWorkItem))
|
||||
continue;
|
||||
collection.Add(childWorkItem);
|
||||
}
|
||||
collection = (from l in collection orderby l.State != "Closed", l.Id select l).ToList();
|
||||
foreach (WorkItem w in collection)
|
||||
{
|
||||
if (nests.Count > 99)
|
||||
break;
|
||||
if (w.Parent is null)
|
||||
parentWorkItem = null;
|
||||
else
|
||||
_ = keyValuePairs.TryGetValue(w.Parent.Value, out parentWorkItem);
|
||||
records = GetKeyValuePairs(keyValuePairs, w, nests);
|
||||
record = Record.Get(w, parentWorkItem, records);
|
||||
results.Add(record);
|
||||
}
|
||||
}
|
||||
return new(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;
|
||||
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);
|
||||
}
|
||||
|
||||
private static int? GetIdFromUrlIfChild(Relation relation)
|
||||
{
|
||||
int? result;
|
||||
string[] segments = relation?.Attributes is null || relation.Attributes.Name != "Child" ? Array.Empty<string>() : relation.URL.Split('/');
|
||||
if (segments.Length < 2)
|
||||
result = null;
|
||||
else
|
||||
{
|
||||
if (!int.TryParse(segments[segments.Length - 1], out int id))
|
||||
result = null;
|
||||
else
|
||||
result = id;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -107,7 +107,9 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
{
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> results = new(string.Empty, null, null, new List<FileInfo>());
|
||||
_TickOffset ??= 0; // new FileInfo(reportFullPath).LastWriteTime.Ticks - dateTime.Ticks;
|
||||
_Logistics = new Logistics(reportFullPath, $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};");
|
||||
string[] lines = new string[] { string.Empty, "NUM_DATA_ROWS", $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};" };
|
||||
ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines);
|
||||
_Logistics = new Logistics(reportFullPath, processDataStandardFormat);
|
||||
SetFileParameterLotIDToLogisticsMID();
|
||||
if (_Logistics.FileInfo.Length < _MinFileLength)
|
||||
results.Item4.Add(_Logistics.FileInfo);
|
||||
@ -115,7 +117,8 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
{
|
||||
IProcessData iProcessData = new ProcessData(this, _Logistics, _FileConnectorConfiguration.TargetFileLocation, _URL, _WorkItemTypes, results.Item4);
|
||||
if (iProcessData.Details.Count == 0)
|
||||
throw new Exception(string.Concat("B) No Data - ", dateTime.Ticks));
|
||||
results = new(string.Concat("B) No Data - ", dateTime.Ticks), Array.Empty<Test>(), Array.Empty<JsonElement>(), results.Item4);
|
||||
else
|
||||
results = iProcessData.GetResults(this, _Logistics, results.Item4);
|
||||
}
|
||||
return results;
|
||||
|
@ -3,7 +3,6 @@ using Adaptation.Shared;
|
||||
using Adaptation.Shared.Duplicator;
|
||||
using Adaptation.Shared.Methods;
|
||||
using log4net;
|
||||
using Microsoft.VisualStudio.Services.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
@ -14,6 +13,8 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.Markdown;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public class ProcessData : IProcessData
|
||||
{
|
||||
|
||||
@ -23,135 +24,21 @@ public class ProcessData : IProcessData
|
||||
|
||||
private readonly ILog _Log;
|
||||
|
||||
public ProcessData(IFileRead fileRead, Logistics logistics, string targetFileLocation, string url, ReadOnlyCollection<string> workItemTypes, List<FileInfo> fileInfoCollection)
|
||||
{
|
||||
if (fileRead.IsEAFHosted)
|
||||
{ }
|
||||
fileInfoCollection.Clear();
|
||||
_Details = new List<object>();
|
||||
_Log = LogManager.GetLogger(typeof(ProcessData));
|
||||
WriteFiles(fileRead, logistics, url, workItemTypes, targetFileLocation, fileInfoCollection);
|
||||
}
|
||||
|
||||
string IProcessData.GetCurrentReactor(IFileRead fileRead, Logistics logistics, Dictionary<string, string> reactors) =>
|
||||
throw new Exception(string.Concat("See ", nameof(WriteFiles)));
|
||||
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> IProcessData.GetResults(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection) =>
|
||||
new(logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), fileInfoCollection);
|
||||
|
||||
#nullable enable
|
||||
public ProcessData(IFileRead fileRead, Logistics logistics, string targetFileLocation, string url, ReadOnlyCollection<string> workItemTypes, List<FileInfo> fileInfoCollection)
|
||||
{
|
||||
if (fileRead.IsEAFHosted)
|
||||
{
|
||||
|
||||
internal static List<Description> GetDescriptions(JsonElement[] jsonElements)
|
||||
{
|
||||
List<Description> results = new();
|
||||
Description? description;
|
||||
JsonSerializerOptions jsonSerializerOptions = new() { NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString };
|
||||
foreach (JsonElement jsonElement in jsonElements)
|
||||
{
|
||||
if (jsonElement.ValueKind != JsonValueKind.Object)
|
||||
throw new Exception();
|
||||
description = JsonSerializer.Deserialize<Description>(jsonElement.ToString(), jsonSerializerOptions);
|
||||
if (description is null)
|
||||
continue;
|
||||
results.Add(description);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private void WriteFiles(IFileRead fileRead, Logistics logistics, string url, ReadOnlyCollection<string> workItemTypes, string destinationDirectory, List<FileInfo> fileInfoCollection)
|
||||
{
|
||||
if (!Directory.Exists(destinationDirectory))
|
||||
_ = Directory.CreateDirectory(destinationDirectory);
|
||||
string json = File.ReadAllText(logistics.ReportFullPath);
|
||||
// WorkItem[]? workItems = JsonSerializer.Deserialize<WorkItem[]>(json);
|
||||
// if (workItems is null)
|
||||
// throw new Exception(nameof(workItems));
|
||||
JsonElement[]? jsonElements = JsonSerializer.Deserialize<JsonElement[]>(json);
|
||||
if (jsonElements is null)
|
||||
throw new Exception(nameof(jsonElements));
|
||||
WorkItem? workItem;
|
||||
List<WorkItem> workItems = new();
|
||||
foreach (JsonElement jsonElement in jsonElements)
|
||||
{
|
||||
workItem = JsonSerializer.Deserialize<WorkItem>(jsonElement.ToString());
|
||||
if (workItem is null)
|
||||
continue;
|
||||
workItems.Add(workItem);
|
||||
}
|
||||
List<char> spaces = new();
|
||||
List<string> lines = new();
|
||||
ReadOnlyCollection<Record> results;
|
||||
ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems);
|
||||
ReadOnlyCollection<Record> records = new(keyValuePairs.Values.ToArray());
|
||||
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" });
|
||||
WriteWithPartentsFile(fileRead, destinationDirectory, fileInfoCollection, records, bugFeatureWorkItemTypes, "bugs-features-with-parents");
|
||||
WriteWithPartentsFile(fileRead, destinationDirectory, fileInfoCollection, records, bugUserStoryWorkItemTypes, "bugs-user-stories-with-parents");
|
||||
foreach (string workItemType in workItemTypes)
|
||||
{
|
||||
lines.Clear();
|
||||
lines.Add($"# {workItemType}");
|
||||
lines.Add(string.Empty);
|
||||
AppendLines(url, spaces, lines, records, workItemType);
|
||||
results = new(Array.Empty<Record>());
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, workItemType);
|
||||
_Details.Add(results);
|
||||
}
|
||||
{
|
||||
lines.Clear();
|
||||
string workItemType = "Feature";
|
||||
lines.Add($"# {nameof(FeatureCheckIterationPath122508)}");
|
||||
lines.Add(string.Empty);
|
||||
results = FeatureCheckIterationPath122508(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType);
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, "check-122508");
|
||||
_Details.Add(results);
|
||||
}
|
||||
{
|
||||
lines.Clear();
|
||||
string workItemType = "Feature";
|
||||
lines.Add($"# {nameof(FeatureCheckTag122514)}");
|
||||
lines.Add(string.Empty);
|
||||
results = FeatureCheckTag122514(url, lines, bugUserStoryWorkItemTypes, keyValuePairs, workItemType);
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, "check-122514");
|
||||
_Details.Add(results);
|
||||
}
|
||||
{
|
||||
lines.Clear();
|
||||
string workItemType = "Feature";
|
||||
lines.Add($"# {nameof(FeatureCheckPriority126169)}");
|
||||
lines.Add(string.Empty);
|
||||
results = FeatureCheckPriority126169(url, lines, bugUserStoryWorkItemTypes, keyValuePairs, workItemType);
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, "check-126169");
|
||||
_Details.Add(results);
|
||||
}
|
||||
{
|
||||
lines.Clear();
|
||||
string workItemType = "Feature";
|
||||
lines.Add($"# {nameof(FeatureCheckState123066)}");
|
||||
lines.Add(string.Empty);
|
||||
results = FeatureCheckState123066(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType);
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, "check-123066");
|
||||
_Details.Add(results);
|
||||
}
|
||||
{
|
||||
lines.Clear();
|
||||
string workItemType = "Feature";
|
||||
lines.Add($"# {nameof(FeatureCheckState123067)}");
|
||||
lines.Add(string.Empty);
|
||||
results = FeatureCheckState123067(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType);
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, "check-123067");
|
||||
_Details.Add(results);
|
||||
}
|
||||
{
|
||||
lines.Clear();
|
||||
string workItemType = "Feature";
|
||||
lines.Add($"# {nameof(FeatureCheckStart122517)}");
|
||||
lines.Add(string.Empty);
|
||||
results = FeatureCheckStart122517(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType);
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, "check-122517");
|
||||
_Details.Add(results);
|
||||
}
|
||||
_Details = new List<object>();
|
||||
_Log = LogManager.GetLogger(typeof(ProcessData));
|
||||
WriteFiles(fileRead, logistics, url, workItemTypes, targetFileLocation, fileInfoCollection);
|
||||
}
|
||||
|
||||
private static void WriteFiles(IFileRead fileRead, string destinationDirectory, List<FileInfo> fileInfoCollection, ReadOnlyCollection<string> lines, ReadOnlyCollection<Record> records, string fileName)
|
||||
@ -179,34 +66,165 @@ public class ProcessData : IProcessData
|
||||
fileInfoCollection.Add(new(jsonFile));
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, Record> GetWorkItems(IEnumerable<WorkItem> workItems)
|
||||
private void WriteFiles(IFileRead fileRead, Logistics logistics, string url, ReadOnlyCollection<string> workItemTypes, string destinationDirectory, List<FileInfo> fileInfoCollection)
|
||||
{
|
||||
if (!Directory.Exists(destinationDirectory))
|
||||
_ = Directory.CreateDirectory(destinationDirectory);
|
||||
string json = File.ReadAllText(logistics.ReportFullPath);
|
||||
// WorkItem[]? workItems = JsonSerializer.Deserialize<WorkItem[]>(json);
|
||||
// if (workItems is null)
|
||||
// throw new Exception(nameof(workItems));
|
||||
JsonElement[]? jsonElements = JsonSerializer.Deserialize<JsonElement[]>(json);
|
||||
if (jsonElements is null)
|
||||
throw new Exception(nameof(jsonElements));
|
||||
WorkItem? workItem;
|
||||
List<WorkItem> workItems = new();
|
||||
foreach (JsonElement jsonElement in jsonElements)
|
||||
{
|
||||
workItem = JsonSerializer.Deserialize<WorkItem>(jsonElement.ToString());
|
||||
if (workItem is null)
|
||||
continue;
|
||||
workItems.Add(workItem);
|
||||
}
|
||||
List<char> spaces = new();
|
||||
bool keepRelations = false;
|
||||
List<string> lines = new();
|
||||
List<string> messages = new();
|
||||
ReadOnlyCollection<Record> results;
|
||||
ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations);
|
||||
ReadOnlyCollection<Record> records = new(keyValuePairs.Values.ToArray());
|
||||
ReadOnlyCollection<string> bugFeatureWorkItemTypes = new(new string[] { "Bug", "Feature" });
|
||||
ReadOnlyCollection<string> bugUserStoryWorkItemTypes = new(new string[] { "Bug", "User Story" });
|
||||
messages.AddRange(WriteFile(fileRead, destinationDirectory, fileInfoCollection, records, "records"));
|
||||
messages.AddRange(WriteWithParentsFile(fileRead, destinationDirectory, fileInfoCollection, records, bugFeatureWorkItemTypes, "bugs-features-with-parents"));
|
||||
messages.AddRange(WriteWithParentsFile(fileRead, destinationDirectory, fileInfoCollection, records, bugUserStoryWorkItemTypes, "bugs-user-stories-with-parents"));
|
||||
foreach (string workItemType in workItemTypes)
|
||||
{
|
||||
lines.Clear();
|
||||
lines.Add($"# {workItemType}");
|
||||
lines.Add(string.Empty);
|
||||
AppendLines(url, spaces, lines, records, workItemType);
|
||||
results = new(Array.Empty<Record>());
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), results, workItemType);
|
||||
_Details.Add(results);
|
||||
}
|
||||
if (messages.Count > 0)
|
||||
throw new Exception($"{messages.Count}{Environment.NewLine}{string.Join(Environment.NewLine, messages)}");
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, Record> GetWorkItems(IEnumerable<WorkItem> workItems, bool keepRelations)
|
||||
{
|
||||
ReadOnlyDictionary<int, Record> results;
|
||||
Dictionary<int, WorkItem> keyValuePairs = new();
|
||||
foreach (WorkItem workItem in workItems)
|
||||
keyValuePairs.Add(workItem.Id, workItem);
|
||||
results = GetKeyValuePairs(new(keyValuePairs));
|
||||
results = GetKeyValuePairs(new(keyValuePairs), keepRelations);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static void WriteWithPartentsFile(IFileRead fileRead, string destinationDirectory, List<FileInfo> fileInfoCollection, ReadOnlyCollection<Record> records, ReadOnlyCollection<string> workItemTypes, string fileName)
|
||||
private static ReadOnlyDictionary<int, Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, bool keepRelations)
|
||||
{
|
||||
List<Record> filtered = new();
|
||||
Dictionary<int, Record> results = new();
|
||||
Record record;
|
||||
List<bool> nests = new();
|
||||
WorkItem? parentWorkItem;
|
||||
ReadOnlyCollection<Record> childRecords;
|
||||
ReadOnlyCollection<Record> relatedRecords;
|
||||
ReadOnlyCollection<Record> successorRecords;
|
||||
foreach (KeyValuePair<int, WorkItem> keyValuePair in keyValuePairs)
|
||||
{
|
||||
nests.Clear();
|
||||
if (keyValuePair.Value.Parent is null)
|
||||
parentWorkItem = null;
|
||||
else
|
||||
_ = keyValuePairs.TryGetValue(keyValuePair.Value.Parent.Value, out parentWorkItem);
|
||||
try
|
||||
{
|
||||
childRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Child", nests, keepRelations); // Forward
|
||||
relatedRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Related", nests, keepRelations); // Related
|
||||
successorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Successor", nests, keepRelations); // Forward
|
||||
// predecessorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Predecessor", nests, keepRelations); // Reverse
|
||||
record = Record.Get(keyValuePair.Value, parentWorkItem, childRecords, relatedRecords, successorRecords, keepRelations);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>());
|
||||
}
|
||||
results.Add(keyValuePair.Key, record);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<string> WriteFile(IFileRead fileRead, string destinationDirectory, List<FileInfo> fileInfoCollection, ReadOnlyCollection<Record> records, string fileName)
|
||||
{
|
||||
List<string> results = new();
|
||||
string? json = GetJson(records, results);
|
||||
string jsonFile = Path.Combine(destinationDirectory, $"{fileName}.json");
|
||||
string jsonOld = !File.Exists(jsonFile) ? string.Empty : File.ReadAllText(jsonFile);
|
||||
if (!string.IsNullOrEmpty(json) && json != jsonOld)
|
||||
File.WriteAllText(jsonFile, json);
|
||||
if (!fileRead.IsEAFHosted)
|
||||
fileInfoCollection.Add(new(jsonFile));
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<string> WriteWithParentsFile(IFileRead fileRead, string destinationDirectory, List<FileInfo> fileInfoCollection, ReadOnlyCollection<Record> records, ReadOnlyCollection<string> workItemTypes, string fileName)
|
||||
{
|
||||
List<string> results = new();
|
||||
Record record;
|
||||
List<Record> filtered = new();
|
||||
foreach (Record r in records)
|
||||
{
|
||||
if (r.WorkItem.State == "Removed" || !workItemTypes.Contains(r.WorkItem.WorkItemType))
|
||||
continue;
|
||||
record = new(r.WorkItem, r.Parent, Array.Empty<Record>());
|
||||
record = new(r.WorkItem, r.Parent, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>());
|
||||
filtered.Add(record);
|
||||
}
|
||||
string json = JsonSerializer.Serialize(filtered, new JsonSerializerOptions() { WriteIndented = true });
|
||||
string? json = GetJson(filtered, results);
|
||||
string jsonFile = Path.Combine(destinationDirectory, $"{fileName}.json");
|
||||
string jsonOld = !File.Exists(jsonFile) ? string.Empty : File.ReadAllText(jsonFile);
|
||||
if (json != jsonOld)
|
||||
if (!string.IsNullOrEmpty(json) && json != jsonOld)
|
||||
File.WriteAllText(jsonFile, json);
|
||||
if (!fileRead.IsEAFHosted)
|
||||
fileInfoCollection.Add(new(jsonFile));
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static string? GetJson(IEnumerable<Record> records, List<string> results)
|
||||
{
|
||||
string? result;
|
||||
try
|
||||
{ result = JsonSerializer.Serialize(records.ToArray(), RecordCollectionSourceGenerationContext.Default.RecordArray); }
|
||||
catch (Exception)
|
||||
{
|
||||
result = null;
|
||||
foreach (Record record in records)
|
||||
{
|
||||
try
|
||||
{ _ = JsonSerializer.Serialize(record, RecordSourceGenerationContext.Default.Record); }
|
||||
catch (Exception ex)
|
||||
{ results.Add($"Record {record.WorkItem.Id} is not serializable!{Environment.NewLine}{ex.Message}"); }
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void AppendLines(List<char> spaces, List<string> lines, Record record, bool condensed, bool sprintOnly)
|
||||
{
|
||||
string line;
|
||||
spaces.Add('\t');
|
||||
WorkItem workItem;
|
||||
if (record.Children is not null)
|
||||
{
|
||||
foreach (Record child in record.Children)
|
||||
{
|
||||
workItem = child.WorkItem;
|
||||
line = GetLine(spaces, workItem, child, condensed, sprintOnly).TrimEnd();
|
||||
lines.Add(line);
|
||||
AppendLines(spaces, lines, child, condensed, sprintOnly);
|
||||
}
|
||||
}
|
||||
spaces.RemoveAt(0);
|
||||
}
|
||||
|
||||
private static void AppendLines(string url, List<char> spaces, List<string> lines, ReadOnlyCollection<Record> records, string workItemType)
|
||||
@ -223,7 +241,7 @@ public class ProcessData : IProcessData
|
||||
results.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}");
|
||||
results.Add(string.Empty);
|
||||
results.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})");
|
||||
if (record.Children.Length == 0)
|
||||
if (record.Children is null || record.Children.Length == 0)
|
||||
results.Add(string.Empty);
|
||||
else
|
||||
{
|
||||
@ -257,49 +275,6 @@ public class ProcessData : IProcessData
|
||||
}
|
||||
}
|
||||
|
||||
private static void AppendLines(List<char> spaces, List<string> lines, Record record, bool condensed, bool sprintOnly)
|
||||
{
|
||||
string line;
|
||||
spaces.Add('\t');
|
||||
WorkItem workItem;
|
||||
foreach (Record child in record.Children)
|
||||
{
|
||||
workItem = child.WorkItem;
|
||||
line = GetLine(spaces, workItem, child, condensed, sprintOnly).TrimEnd();
|
||||
lines.Add(line);
|
||||
AppendLines(spaces, lines, child, condensed, sprintOnly);
|
||||
}
|
||||
spaces.RemoveAt(0);
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs)
|
||||
{
|
||||
Dictionary<int, Record> results = new();
|
||||
Record record;
|
||||
List<bool> nests = new();
|
||||
WorkItem? parentWorkItem;
|
||||
ReadOnlyCollection<Record> records;
|
||||
foreach (KeyValuePair<int, WorkItem> keyValuePair in keyValuePairs)
|
||||
{
|
||||
nests.Clear();
|
||||
if (keyValuePair.Value.Parent is null)
|
||||
parentWorkItem = null;
|
||||
else
|
||||
_ = keyValuePairs.TryGetValue(keyValuePair.Value.Parent.Value, out parentWorkItem);
|
||||
try
|
||||
{
|
||||
records = GetKeyValuePairs(keyValuePairs, keyValuePair.Value, nests);
|
||||
record = Record.Get(keyValuePair.Value, parentWorkItem, records);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>());
|
||||
}
|
||||
results.Add(keyValuePair.Key, record);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static string GetLine(List<char> spaces, WorkItem workItem, Record record, bool condensed, bool sprintOnly)
|
||||
{
|
||||
string result;
|
||||
@ -310,483 +285,24 @@ public class ProcessData : IProcessData
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, WorkItem workItem, List<bool> nests)
|
||||
{
|
||||
List<Record> results = new();
|
||||
int? childId;
|
||||
Record record;
|
||||
nests.Add(true);
|
||||
WorkItem? childWorkItem;
|
||||
WorkItem? parentWorkItem;
|
||||
List<WorkItem> collection = new();
|
||||
ReadOnlyCollection<Record> records;
|
||||
if (workItem.Relations is not null && workItem.Relations.Length > 0)
|
||||
{
|
||||
collection.Clear();
|
||||
foreach (Relation relation in workItem.Relations)
|
||||
{
|
||||
childId = GetIdFromUrlIfChild(relation);
|
||||
if (childId is not null && workItem.Parent is not null && relation?.URL is not null && relation.URL.Contains(workItem.Parent.Value.ToString()))
|
||||
continue;
|
||||
if (childId is null || !keyValuePairs.TryGetValue(childId.Value, out childWorkItem))
|
||||
continue;
|
||||
collection.Add(childWorkItem);
|
||||
}
|
||||
collection = (from l in collection orderby l.State != "Closed", l.Id select l).ToList();
|
||||
foreach (WorkItem w in collection)
|
||||
{
|
||||
if (nests.Count > 99)
|
||||
break;
|
||||
if (w.Parent is null)
|
||||
parentWorkItem = null;
|
||||
else
|
||||
_ = keyValuePairs.TryGetValue(w.Parent.Value, out parentWorkItem);
|
||||
records = GetKeyValuePairs(keyValuePairs, w, nests);
|
||||
record = Record.Get(w, parentWorkItem, records);
|
||||
results.Add(record);
|
||||
}
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static string GetClosed(WorkItem workItem) =>
|
||||
workItem.State != "Closed" ? "[ ]" : "[x]";
|
||||
|
||||
private static int? GetIdFromUrlIfChild(Relation relation)
|
||||
internal static List<Description> GetDescriptions(JsonElement[] jsonElements)
|
||||
{
|
||||
int? result;
|
||||
string[] segments = relation?.Attributes is null || relation.Attributes.Name != "Child" ? Array.Empty<string>() : relation.URL.Split('/');
|
||||
if (segments.Length < 2)
|
||||
result = null;
|
||||
else
|
||||
List<Description> results = new();
|
||||
Description? description;
|
||||
JsonSerializerOptions jsonSerializerOptions = new() { NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString };
|
||||
foreach (JsonElement jsonElement in jsonElements)
|
||||
{
|
||||
if (!int.TryParse(segments[segments.Length - 1], out int id))
|
||||
result = null;
|
||||
else
|
||||
result = id;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
private static void FilterChildren(ReadOnlyCollection<string> workItemTypes, Record record, List<Record> results)
|
||||
{
|
||||
foreach (Record r in record.Children)
|
||||
{
|
||||
if (!workItemTypes.Contains(r.WorkItem.WorkItemType))
|
||||
continue;
|
||||
results.Add(r);
|
||||
FilterChildren(workItemTypes, r, results);
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> FilterChildren(ReadOnlyCollection<string> workItemTypes, Record record)
|
||||
{
|
||||
List<Record> results = new();
|
||||
FilterChildren(workItemTypes, record, results);
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static int GetState(WorkItem workItem) =>
|
||||
workItem.State switch
|
||||
{
|
||||
"New" => 1,
|
||||
"Active" => 2,
|
||||
"Resolved" => 3,
|
||||
"Closed" => 4,
|
||||
"Removed" => 5,
|
||||
_ => 8
|
||||
};
|
||||
|
||||
private static string? GetMaxIterationPath122508(ReadOnlyCollection<Record> records)
|
||||
{
|
||||
string? result;
|
||||
List<string> results = new();
|
||||
foreach (Record record in records)
|
||||
{
|
||||
if (results.Contains(record.WorkItem.IterationPath))
|
||||
continue;
|
||||
results.Add(record.WorkItem.IterationPath);
|
||||
}
|
||||
result = results.Count == 0 ? null : results.Max();
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> FeatureCheckIterationPath122508(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType)
|
||||
{
|
||||
List<Record> results = new();
|
||||
Record record;
|
||||
string? maxIterationPath;
|
||||
List<string> collection = new();
|
||||
ReadOnlyCollection<Record> records;
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
record = keyValuePair.Value;
|
||||
if (record.WorkItem.State is "Removed")
|
||||
continue;
|
||||
if (record.WorkItem.WorkItemType != workItemType)
|
||||
continue;
|
||||
collection.Clear();
|
||||
if (record.Children.Length == 0)
|
||||
continue;
|
||||
records = FilterChildren(workItemTypes, record);
|
||||
maxIterationPath = GetMaxIterationPath122508(records);
|
||||
if (string.IsNullOrEmpty(maxIterationPath) || record.WorkItem.IterationPath == maxIterationPath)
|
||||
continue;
|
||||
collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}");
|
||||
collection.Add(string.Empty);
|
||||
collection.Add($"- [ ] [{record.WorkItem.Id}]({url}{record.WorkItem.Id}) => {record.WorkItem.IterationPath} != {maxIterationPath}");
|
||||
collection.Add(string.Empty);
|
||||
lines.AddRange(collection);
|
||||
results.Add(WorkItem.Get(record, $"IterationPath:<a target='_blank' href='{url}{record.WorkItem.Id}'>{record.WorkItem.Id}</a>;{record.WorkItem.IterationPath} != {maxIterationPath}"));
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetWorkItemsNotMatching122514(Record record, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Record> results = new();
|
||||
string[] segments;
|
||||
string[] parentTags = record.WorkItem.Tags.Split(';').Select(l => l.Trim()).ToArray();
|
||||
foreach (Record r in records)
|
||||
{
|
||||
segments = string.IsNullOrEmpty(r.WorkItem.Tags) ? Array.Empty<string>() : r.WorkItem.Tags.Split(';').Select(l => l.Trim()).ToArray();
|
||||
if (segments.Length > 0 && parentTags.Any(l => segments.Contains(l)))
|
||||
continue;
|
||||
results.Add(r);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> FeatureCheckTag122514(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType)
|
||||
{
|
||||
List<Record> results = new();
|
||||
Record record;
|
||||
List<string> collection = new();
|
||||
List<string> violations = new();
|
||||
ReadOnlyCollection<Record> records;
|
||||
ReadOnlyCollection<Record> recordsNotMatching;
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
record = keyValuePair.Value;
|
||||
if (record.WorkItem.State is "Removed")
|
||||
continue;
|
||||
if (record.WorkItem.WorkItemType != workItemType)
|
||||
continue;
|
||||
collection.Clear();
|
||||
violations.Clear();
|
||||
if (record.Children.Length == 0)
|
||||
continue;
|
||||
if (string.IsNullOrEmpty(record.WorkItem.Tags))
|
||||
recordsNotMatching = new(new Record[] { record });
|
||||
else
|
||||
{
|
||||
records = FilterChildren(workItemTypes, record);
|
||||
recordsNotMatching = GetWorkItemsNotMatching122514(record, records);
|
||||
if (!string.IsNullOrEmpty(record.WorkItem.Tags) && recordsNotMatching.Count == 0)
|
||||
continue;
|
||||
}
|
||||
collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}");
|
||||
collection.Add(string.Empty);
|
||||
foreach (Record r in recordsNotMatching)
|
||||
collection.Add($"- [ ] [{r.WorkItem}]({url}{r.WorkItem}) {nameof(record.WorkItem.Tags)} != {record.WorkItem.Tags}");
|
||||
collection.Add(string.Empty);
|
||||
lines.AddRange(collection);
|
||||
violations.Add($"Tag:{record.WorkItem.Tags};");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.Tags};");
|
||||
results.Add(WorkItem.Get(record, string.Join(" ", violations)));
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetWorkItemsNotMatching126169(Record record, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Record> results = new();
|
||||
foreach (Record r in records)
|
||||
{
|
||||
if (record.WorkItem.Priority is null)
|
||||
{
|
||||
results.Add(record);
|
||||
break;
|
||||
}
|
||||
if (r.WorkItem.Priority == record.WorkItem.Priority.Value)
|
||||
continue;
|
||||
results.Add(r);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> FeatureCheckPriority126169(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType)
|
||||
{
|
||||
List<Record> results = new();
|
||||
Record record;
|
||||
List<string> collection = new();
|
||||
List<string> violations = new();
|
||||
ReadOnlyCollection<Record> records;
|
||||
ReadOnlyCollection<Record> recordsNotMatching;
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
record = keyValuePair.Value;
|
||||
if (record.WorkItem.State is "Removed")
|
||||
continue;
|
||||
if (record.WorkItem.WorkItemType != workItemType)
|
||||
continue;
|
||||
collection.Clear();
|
||||
violations.Clear();
|
||||
if (record.Children.Length == 0)
|
||||
continue;
|
||||
records = FilterChildren(workItemTypes, record);
|
||||
recordsNotMatching = GetWorkItemsNotMatching126169(record, records);
|
||||
if (recordsNotMatching.Count == 0)
|
||||
continue;
|
||||
collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}");
|
||||
collection.Add(string.Empty);
|
||||
collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.Priority)} != {record.WorkItem.Priority}");
|
||||
collection.Add(string.Empty);
|
||||
lines.AddRange(collection);
|
||||
violations.Add($"Priority:{record.WorkItem.Priority};");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.Priority};");
|
||||
results.Add(WorkItem.Get(record, string.Join(" ", violations)));
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetWorkItemsNotMatching123066(Record record, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Record> results = new();
|
||||
int check;
|
||||
int state = GetState(record.WorkItem);
|
||||
List<KeyValuePair<int, Record>> collection = new();
|
||||
foreach (Record r in records)
|
||||
{
|
||||
if (r.WorkItem.State is "Removed")
|
||||
continue;
|
||||
check = GetState(r.WorkItem);
|
||||
if (check == state)
|
||||
continue;
|
||||
collection.Add(new(check, r));
|
||||
}
|
||||
if (collection.Count > 0)
|
||||
{
|
||||
KeyValuePair<int, Record>[] notNewState = (from l in collection where l.Value.WorkItem.State != "New" select l).ToArray();
|
||||
if (notNewState.Length == 0 && record.WorkItem.State is "New" or "Active")
|
||||
collection.Clear();
|
||||
else if (notNewState.Length > 0)
|
||||
{
|
||||
int minimum = notNewState.Min(l => l.Key);
|
||||
if (minimum == state)
|
||||
collection.Clear();
|
||||
else if (minimum == 1 && record.WorkItem.State == "New")
|
||||
collection.Clear();
|
||||
else if (notNewState.Length > 0 && record.WorkItem.State == "Active")
|
||||
collection.Clear();
|
||||
}
|
||||
}
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in collection.OrderByDescending(l => l.Key))
|
||||
results.Add(keyValuePair.Value);
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetWorkItemsNotMatching123067(Record record, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Record> results = new();
|
||||
int check;
|
||||
int state = GetState(record.WorkItem);
|
||||
List<KeyValuePair<int, Record>> collection = new();
|
||||
foreach (Record r in records)
|
||||
{
|
||||
if (r.WorkItem.State is "Removed")
|
||||
continue;
|
||||
check = GetState(r.WorkItem);
|
||||
if (check == state)
|
||||
continue;
|
||||
collection.Add(new(check, r));
|
||||
}
|
||||
if (collection.Count > 0)
|
||||
{
|
||||
KeyValuePair<int, Record>[] notNewState = (from l in collection where l.Value.WorkItem.State != "New" select l).ToArray();
|
||||
if (notNewState.Length == 0 && record.WorkItem.State is "New" or "Active")
|
||||
collection.Clear();
|
||||
else if (notNewState.Length > 0)
|
||||
{
|
||||
int minimum = notNewState.Min(l => l.Key);
|
||||
if (minimum == state)
|
||||
collection.Clear();
|
||||
else if (minimum == 1 && record.WorkItem.State == "New")
|
||||
collection.Clear();
|
||||
else if (notNewState.Length > 0 && record.WorkItem.State == "Active")
|
||||
collection.Clear();
|
||||
}
|
||||
}
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in collection.OrderByDescending(l => l.Key))
|
||||
results.Add(keyValuePair.Value);
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetWorkItemsNotMatching122517(Record record, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Record> results = new();
|
||||
if (record.WorkItem.StartDate is null)
|
||||
if (jsonElement.ValueKind != JsonValueKind.Object)
|
||||
throw new Exception();
|
||||
DateTime dateTime = record.WorkItem.StartDate.Value;
|
||||
List<KeyValuePair<long, Record>> collection = new();
|
||||
foreach (Record r in records)
|
||||
{
|
||||
if (r.WorkItem.State is "Removed")
|
||||
description = JsonSerializer.Deserialize<Description>(jsonElement.ToString(), jsonSerializerOptions);
|
||||
if (description is null)
|
||||
continue;
|
||||
if (r.WorkItem.ActivatedDate is null)
|
||||
continue;
|
||||
if (dateTime >= r.WorkItem.ActivatedDate.Value)
|
||||
continue;
|
||||
collection.Add(new(r.WorkItem.ActivatedDate.Value.Ticks, r));
|
||||
results.Add(description);
|
||||
}
|
||||
foreach (KeyValuePair<long, Record> keyValuePair in collection.OrderBy(l => l.Key))
|
||||
results.Add(keyValuePair.Value);
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> FeatureCheckState123066(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType)
|
||||
{
|
||||
List<Record> results = new();
|
||||
Record record;
|
||||
List<string> collection = new();
|
||||
List<string> violations = new();
|
||||
ReadOnlyCollection<Record> records;
|
||||
ReadOnlyCollection<Record> recordsNotMatching;
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
record = keyValuePair.Value;
|
||||
if (record.WorkItem.State is "Removed")
|
||||
continue;
|
||||
if (record.WorkItem.WorkItemType != workItemType)
|
||||
continue;
|
||||
collection.Clear();
|
||||
violations.Clear();
|
||||
if (record.Children.Length == 0)
|
||||
continue;
|
||||
records = FilterChildren(workItemTypes, record);
|
||||
recordsNotMatching = GetWorkItemsNotMatching123066(record, records);
|
||||
if (recordsNotMatching.Count == 0)
|
||||
continue;
|
||||
collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}");
|
||||
collection.Add(string.Empty);
|
||||
collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.State)} != {record.WorkItem.State}");
|
||||
collection.Add(string.Empty);
|
||||
lines.AddRange(collection);
|
||||
violations.Add($"State:{record.WorkItem.State};");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.State};");
|
||||
results.Add(WorkItem.Get(record, string.Join(" ", violations)));
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> FeatureCheckState123067(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType)
|
||||
{
|
||||
List<Record> results = new();
|
||||
Record record;
|
||||
List<string> collection = new();
|
||||
List<string> violations = new();
|
||||
ReadOnlyCollection<Record> records;
|
||||
ReadOnlyCollection<Record> recordsNotMatching;
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
record = keyValuePair.Value;
|
||||
if (record.WorkItem.State is "Removed")
|
||||
continue;
|
||||
if (record.WorkItem.WorkItemType != workItemType)
|
||||
continue;
|
||||
collection.Clear();
|
||||
violations.Clear();
|
||||
if (record.Children.Length == 0)
|
||||
continue;
|
||||
records = FilterChildren(workItemTypes, record);
|
||||
recordsNotMatching = GetWorkItemsNotMatching123067(record, records);
|
||||
if (recordsNotMatching.Count == 0)
|
||||
continue;
|
||||
collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}");
|
||||
collection.Add(string.Empty);
|
||||
collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.State)} != {record.WorkItem.State}");
|
||||
collection.Add(string.Empty);
|
||||
lines.AddRange(collection);
|
||||
violations.Add($"State:{record.WorkItem.State};");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.State};");
|
||||
results.Add(WorkItem.Get(record, string.Join(" ", violations)));
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> FeatureCheckStart122517(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType)
|
||||
{
|
||||
List<Record> results = new();
|
||||
Record record;
|
||||
List<string> collection = new();
|
||||
List<string> violations = new();
|
||||
ReadOnlyCollection<Record> records;
|
||||
ReadOnlyCollection<Record> recordsNotMatching;
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
record = keyValuePair.Value;
|
||||
if (record.WorkItem.State is "Removed")
|
||||
continue;
|
||||
if (record.WorkItem.WorkItemType != workItemType)
|
||||
continue;
|
||||
collection.Clear();
|
||||
violations.Clear();
|
||||
if (record.Children.Length == 0)
|
||||
continue;
|
||||
if (record.WorkItem.StartDate is null)
|
||||
continue;
|
||||
records = FilterChildren(workItemTypes, record);
|
||||
recordsNotMatching = GetWorkItemsNotMatching122517(record, records);
|
||||
if (recordsNotMatching.Count == 0)
|
||||
continue;
|
||||
collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}");
|
||||
collection.Add(string.Empty);
|
||||
collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.ActivatedDate)} != {record.WorkItem.ActivatedDate}");
|
||||
collection.Add(string.Empty);
|
||||
lines.AddRange(collection);
|
||||
violations.Add($"StartDate:{record.WorkItem.StartDate};");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.ActivatedDate};");
|
||||
results.Add(WorkItem.Get(record, string.Join(" ", violations)));
|
||||
}
|
||||
return new(results);
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
@ -5,16 +5,68 @@ using Adaptation.Shared.Duplicator;
|
||||
using Adaptation.Shared.Methods;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
|
||||
namespace Adaptation.FileHandlers.MoveMatchingFiles;
|
||||
|
||||
#nullable enable
|
||||
|
||||
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 CheckDirectory { get; private set; }
|
||||
internal string NoWaitDirectory { get; private set; }
|
||||
|
||||
internal PreWith(string matchingFile, string checkFile, string errFile, string checkDirectory, string noWaitDirectory)
|
||||
{
|
||||
MatchingFile = matchingFile;
|
||||
CheckFile = checkFile;
|
||||
ErrFile = errFile;
|
||||
CheckDirectory = checkDirectory;
|
||||
NoWaitDirectory = noWaitDirectory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class Pre
|
||||
{
|
||||
|
||||
internal string MatchingFile { get; private set; }
|
||||
internal string CheckFile { get; private set; }
|
||||
|
||||
internal Pre(string matchingFile, string checkFile)
|
||||
{
|
||||
MatchingFile = matchingFile;
|
||||
CheckFile = checkFile;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class Post
|
||||
{
|
||||
|
||||
internal string ErrFile { get; private set; }
|
||||
internal string CheckFile { get; private set; }
|
||||
|
||||
internal Post(string checkFile, string errFile)
|
||||
{
|
||||
ErrFile = errFile;
|
||||
CheckFile = checkFile;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) :
|
||||
base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null)
|
||||
{
|
||||
@ -41,7 +93,8 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
Move(extractResults);
|
||||
}
|
||||
|
||||
void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null);
|
||||
void IFileRead.WaitForThread() =>
|
||||
WaitForThread(thread: null, threadExceptions: null);
|
||||
|
||||
string IFileRead.GetEventDescription()
|
||||
{
|
||||
@ -88,7 +141,7 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
DateTime dateTime = DateTime.Now;
|
||||
results = GetExtractResult(reportFullPath, dateTime);
|
||||
if (results.Item3 is null)
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]"), results.Item4);
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]") ?? throw new Exception(), results.Item4);
|
||||
if (results.Item3.Length > 0 && _IsEAFHosted)
|
||||
WritePDSF(this, results.Item3);
|
||||
UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks);
|
||||
@ -104,7 +157,69 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<string> GetSearchDirectories(int numberLength, string parentDirectory)
|
||||
private static ProcessDataStandardFormatMapping GetProcessDataStandardFormatMapping()
|
||||
{
|
||||
ProcessDataStandardFormatMapping result;
|
||||
string[] segmentsB;
|
||||
List<string> distinct = new();
|
||||
Dictionary<string, string> keyValuePairs = new();
|
||||
string args4 = "Time,Test,Count,MesEntity,HeaderUniqueId,UniqueId,Id,Recipe,Date,AreaDeltaFromLastRun,GLimit,HGCV1";
|
||||
string args5 = "Nine10mmEdgeMean,Nine4mmEdgeMean,NineCriticalPointsAverage,NineCriticalPointsPhaseAngleAverage,NineCriticalPointsStdDev,NineEdgeMeanDelta,NineMean,NineResRangePercent,AreaDeltaFromLastRun,Variation,Percentage HgCV 4PP Delta,HGCV1";
|
||||
string args6 = "RhoAvg01,RhoAvg02,RhoAvg03,RhoAvg04,RhoAvg05,RhoAvg06,RhoAvg07,RhoAvg08,RhoAvg09,HGCV1";
|
||||
string 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[] 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());
|
||||
foreach (string segment in segments)
|
||||
{
|
||||
segmentsB = segment.Split('|');
|
||||
if (segmentsB.Length != 2)
|
||||
continue;
|
||||
if (distinct.Contains(segmentsB[0]))
|
||||
continue;
|
||||
distinct.Add(segmentsB[0]);
|
||||
keyValuePairs.Add(segmentsB[0], segmentsB[1]);
|
||||
}
|
||||
result = new(backfillColumns: backfillColumns,
|
||||
columnIndices: columnIndices,
|
||||
newColumnNames: newColumnNames,
|
||||
ignoreColumns: ignoreColumns,
|
||||
indexOnlyColumns: indexOnlyColumns,
|
||||
keyValuePairs: new(keyValuePairs),
|
||||
oldColumnNames: oldColumnNames);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<PreWith> GetPreWithCollection(ReadOnlyCollection<Pre> preCollection)
|
||||
{
|
||||
List<PreWith> results = new();
|
||||
string errFile;
|
||||
PreWith preWith;
|
||||
string? checkDirectory;
|
||||
string noWaitDirectory;
|
||||
foreach (Pre pre in preCollection)
|
||||
{
|
||||
errFile = string.Concat(pre.CheckFile, ".err");
|
||||
checkDirectory = Path.GetDirectoryName(pre.CheckFile);
|
||||
if (string.IsNullOrEmpty(checkDirectory))
|
||||
continue;
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
noWaitDirectory = Path.Combine(checkDirectory, "NoWaitDirectory");
|
||||
preWith = new(pre.MatchingFile, pre.CheckFile, errFile, checkDirectory, noWaitDirectory);
|
||||
results.Add(preWith);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<string> GetSearchDirectories(int numberLength, string parentDirectory)
|
||||
{
|
||||
List<string> results = new();
|
||||
string[] directories = Directory.GetDirectories(parentDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
@ -115,10 +230,137 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
results.Add(directory);
|
||||
}
|
||||
results.Sort();
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void CreatePointerFile(int numberLength, string parentDirectory, ReadOnlyCollection<string> matchingFiles)
|
||||
{
|
||||
string checkFile;
|
||||
string writeFile;
|
||||
string? directoryName;
|
||||
int parentDirectoryLength = parentDirectory.Length;
|
||||
foreach (string matchingFile in matchingFiles)
|
||||
{
|
||||
directoryName = Path.GetDirectoryName(matchingFile);
|
||||
if (directoryName is null)
|
||||
continue;
|
||||
checkFile = $"{matchingFile[0]}{directoryName.Substring(parentDirectoryLength + numberLength + 1)}";
|
||||
writeFile = Path.Combine(parentDirectory, $"{directoryName.Substring(parentDirectory.Length + 1, numberLength)}.txt");
|
||||
if (File.Exists(writeFile))
|
||||
continue;
|
||||
File.AppendAllLines(writeFile, new string[] { parentDirectory, matchingFile, directoryName, checkFile });
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Pre> GetPreCollection(int numberLength, string parentDirectory, ReadOnlyCollection<string> matchingFiles)
|
||||
{
|
||||
List<Pre> results = new();
|
||||
Pre pre;
|
||||
string checkFile;
|
||||
int parentDirectoryLength = parentDirectory.Length;
|
||||
foreach (string matchingFile in matchingFiles)
|
||||
{
|
||||
checkFile = $"{matchingFile[0]}{matchingFile.Substring(parentDirectoryLength + numberLength + 1)}";
|
||||
pre = new(matchingFile, checkFile);
|
||||
results.Add(pre);
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private void MoveCollection(DateTime dateTime, ProcessDataStandardFormat? processDataStandardFormat, ReadOnlyCollection<PreWith> preWithCollection)
|
||||
{
|
||||
ReadOnlyCollection<Post> postCollection = GetPostCollection(dateTime, processDataStandardFormat, preWithCollection);
|
||||
if (postCollection.Count != 0)
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
StringBuilder stringBuilder = new();
|
||||
foreach (Post post in postCollection)
|
||||
{
|
||||
if (File.Exists(post.ErrFile))
|
||||
_ = stringBuilder.AppendLine(File.ReadAllText(post.ErrFile));
|
||||
if (File.Exists(post.CheckFile))
|
||||
_ = stringBuilder.AppendLine($"<{post.CheckFile}> was not consumed by the end!");
|
||||
}
|
||||
if (stringBuilder.Length > 0)
|
||||
throw new Exception(stringBuilder.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
File.Delete(preWith.MatchingFile);
|
||||
}
|
||||
if (Directory.Exists(preWith.NoWaitDirectory))
|
||||
{
|
||||
post = new(preWith.CheckFile, preWith.ErrFile);
|
||||
results.Add(post);
|
||||
continue;
|
||||
}
|
||||
if (_FileConnectorConfiguration?.FileHandleWaitTime is null)
|
||||
preWait = DateTime.Now.AddMilliseconds(1234).Ticks;
|
||||
else
|
||||
preWait = DateTime.Now.AddMilliseconds(_FileConnectorConfiguration.FileHandleWaitTime.Value).Ticks;
|
||||
for (short i = 0; i < short.MaxValue; i++)
|
||||
{
|
||||
if (DateTime.Now.Ticks > preWait)
|
||||
break;
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
for (int i = 0; i < int.MaxValue; i++)
|
||||
{
|
||||
if (File.Exists(preWith.ErrFile))
|
||||
throw new Exception(File.ReadAllText(preWith.ErrFile));
|
||||
if (!File.Exists(preWith.CheckFile))
|
||||
break;
|
||||
if (new TimeSpan(DateTime.Now.Ticks - dateTime.Ticks).TotalSeconds > _BreakAfterSeconds)
|
||||
throw new Exception($"Not all files were consumed after {_BreakAfterSeconds} second(s)!");
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
}
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
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)
|
||||
_Logistics = new Logistics(reportFullPath, processDataStandardFormat);
|
||||
else
|
||||
{
|
||||
processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, processDataStandardFormat);
|
||||
processDataStandardFormat = null;
|
||||
}
|
||||
SetFileParameterLotIDToLogisticsMID();
|
||||
int numberLength = 2;
|
||||
long ticks = dateTime.Ticks;
|
||||
string parentParentDirectory = GetParentParent(reportFullPath);
|
||||
ReadOnlyCollection<string> searchDirectories = GetSearchDirectories(numberLength, parentParentDirectory);
|
||||
ReadOnlyCollection<string> matchingFiles = GetMatchingFiles(ticks, reportFullPath, searchDirectories);
|
||||
if (matchingFiles.Count != searchDirectories.Count)
|
||||
throw new Exception($"Didn't find all files after {_BreakAfterSeconds} second(s)!");
|
||||
try
|
||||
{ CreatePointerFile(numberLength, parentParentDirectory, matchingFiles); }
|
||||
catch (Exception) { }
|
||||
ReadOnlyCollection<Pre> preCollection = GetPreCollection(numberLength, parentParentDirectory, matchingFiles);
|
||||
ReadOnlyCollection<PreWith> preWithCollection = GetPreWithCollection(preCollection);
|
||||
MoveCollection(dateTime, processDataStandardFormat, preWithCollection);
|
||||
return results;
|
||||
}
|
||||
|
||||
private List<string> GetMatchingFiles(long ticks, string reportFullPath, List<string> searchDirectories)
|
||||
private ReadOnlyCollection<string> GetMatchingFiles(long ticks, string reportFullPath, ReadOnlyCollection<string> searchDirectories)
|
||||
{
|
||||
List<string> results = new();
|
||||
string[] found;
|
||||
@ -137,129 +379,7 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
break;
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<(string matchingFile, string checkFile)> GetCollection(int numberLength, string parentDirectory, List<string> matchingFiles)
|
||||
{
|
||||
List<(string matchingFile, string checkFile)> results = new();
|
||||
string checkFile;
|
||||
int parentDirectoryLength = parentDirectory.Length;
|
||||
foreach (string matchingFile in matchingFiles)
|
||||
{
|
||||
checkFile = $"{matchingFile[0]}{matchingFile.Substring(parentDirectoryLength + numberLength + 1)}";
|
||||
results.Add(new(matchingFile, checkFile));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private static List<(string, string, string, string, string)> GetCollection(List<(string matchingFile, string checkFile)> collection)
|
||||
{
|
||||
List<(string, string, string, string, string)> results = new();
|
||||
string errFile;
|
||||
string checkDirectory;
|
||||
string noWaitDirectory;
|
||||
foreach ((string matchingFile, string checkFile) in collection)
|
||||
{
|
||||
errFile = string.Concat(checkFile, ".err");
|
||||
checkDirectory = Path.GetDirectoryName(checkFile);
|
||||
if (!Directory.Exists(checkDirectory))
|
||||
_ = Directory.CreateDirectory(checkDirectory);
|
||||
noWaitDirectory = Path.Combine(checkDirectory, "NoWaitDirectory");
|
||||
results.Add(new(matchingFile, checkFile, errFile, checkDirectory, noWaitDirectory));
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private void MoveCollection(DateTime dateTime, List<(string matchingFile, string checkFile)> collection)
|
||||
{
|
||||
long preWait;
|
||||
List<(string checkFile, string errFile)> postCollection = new();
|
||||
foreach ((string matchingFile, string checkFile, string errFile, string checkDirectory, string noWaitDirectory) in GetCollection(collection))
|
||||
{
|
||||
File.Move(matchingFile, checkFile);
|
||||
if (Directory.Exists(noWaitDirectory))
|
||||
{
|
||||
postCollection.Add(new(checkFile, errFile));
|
||||
continue;
|
||||
}
|
||||
if (_FileConnectorConfiguration?.FileHandleWaitTime is null)
|
||||
preWait = DateTime.Now.AddMilliseconds(1234).Ticks;
|
||||
else
|
||||
preWait = DateTime.Now.AddMilliseconds(_FileConnectorConfiguration.FileHandleWaitTime.Value).Ticks;
|
||||
for (short i = 0; i < short.MaxValue; i++)
|
||||
{
|
||||
if (DateTime.Now.Ticks > preWait)
|
||||
break;
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
for (int i = 0; i < int.MaxValue; i++)
|
||||
{
|
||||
if (File.Exists(errFile))
|
||||
throw new Exception(File.ReadAllText(errFile));
|
||||
if (!File.Exists(checkFile))
|
||||
break;
|
||||
if (new TimeSpan(DateTime.Now.Ticks - dateTime.Ticks).TotalSeconds > _BreakAfterSeconds)
|
||||
throw new Exception($"Not all files were consumed after {_BreakAfterSeconds} second(s)!");
|
||||
Thread.Sleep(500);
|
||||
}
|
||||
}
|
||||
if (postCollection.Count != 0)
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
StringBuilder stringBuilder = new();
|
||||
foreach ((string checkFile, string errFile) in postCollection)
|
||||
{
|
||||
if (File.Exists(errFile))
|
||||
_ = stringBuilder.AppendLine(File.ReadAllText(errFile));
|
||||
if (File.Exists(checkFile))
|
||||
_ = stringBuilder.AppendLine($"<{checkFile}> was not consumed by the end!");
|
||||
}
|
||||
if (stringBuilder.Length > 0)
|
||||
throw new Exception(stringBuilder.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreatePointerFile(int numberLength, string parentDirectory, List<string> matchingFiles)
|
||||
{
|
||||
#nullable enable
|
||||
string checkFile;
|
||||
string writeFile;
|
||||
string? directoryName;
|
||||
int parentDirectoryLength = parentDirectory.Length;
|
||||
foreach (string matchingFile in matchingFiles)
|
||||
{
|
||||
directoryName = Path.GetDirectoryName(matchingFile);
|
||||
if (directoryName is null)
|
||||
continue;
|
||||
checkFile = $"{matchingFile[0]}{directoryName.Substring(parentDirectoryLength + numberLength + 1)}";
|
||||
writeFile = Path.Combine(parentDirectory, $"{directoryName.Substring(parentDirectory.Length + 1, numberLength)}.txt");
|
||||
if (File.Exists(writeFile))
|
||||
continue;
|
||||
File.AppendAllLines(writeFile, new string[] { parentDirectory, matchingFile, directoryName, checkFile });
|
||||
}
|
||||
#nullable disable
|
||||
}
|
||||
|
||||
private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime)
|
||||
{
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> results = new(string.Empty, null, null, new List<FileInfo>());
|
||||
Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, pdsf.Item1);
|
||||
SetFileParameterLotIDToLogisticsMID();
|
||||
int numberLength = 2;
|
||||
long ticks = dateTime.Ticks;
|
||||
string parentParentDirectory = GetParentParent(reportFullPath);
|
||||
List<string> searchDirectories = GetSearchDirectories(numberLength, parentParentDirectory);
|
||||
List<string> matchingFiles = GetMatchingFiles(ticks, reportFullPath, searchDirectories);
|
||||
if (matchingFiles.Count != searchDirectories.Count)
|
||||
throw new Exception($"Didn't find all files after {_BreakAfterSeconds} second(s)!");
|
||||
try
|
||||
{ CreatePointerFile(numberLength, parentParentDirectory, matchingFiles); }
|
||||
catch (Exception) { }
|
||||
List<(string matchingFile, string checkFile)> collection = GetCollection(numberLength, parentParentDirectory, matchingFiles);
|
||||
MoveCollection(dateTime, collection);
|
||||
return results;
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
}
|
@ -103,24 +103,30 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
return results;
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0060
|
||||
private static void SaveOpenInsightFile(string reportFullPath, DateTime dateTime, List<Description> descriptions, Test[] tests)
|
||||
#pragma warning restore IDE0060
|
||||
{
|
||||
if (string.IsNullOrEmpty(reportFullPath))
|
||||
throw new ArgumentException($"'{nameof(reportFullPath)}' cannot be null or empty.", nameof(reportFullPath));
|
||||
if (dateTime == DateTime.MinValue)
|
||||
throw new ArgumentNullException(nameof(dateTime));
|
||||
if (descriptions is null)
|
||||
throw new ArgumentNullException(nameof(descriptions));
|
||||
if (tests is null)
|
||||
throw new ArgumentNullException(nameof(tests));
|
||||
}
|
||||
|
||||
private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime)
|
||||
{
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> results;
|
||||
Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, pdsf.Item1);
|
||||
ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, processDataStandardFormat);
|
||||
SetFileParameterLotIDToLogisticsMID();
|
||||
JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf);
|
||||
JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat);
|
||||
List<Description> descriptions = json.ProcessData.GetDescriptions(jsonElements);
|
||||
Test[] tests = (from l in descriptions select (Test)l.Test).ToArray();
|
||||
if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0)
|
||||
SaveOpenInsightFile(reportFullPath, dateTime, descriptions, tests);
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>());
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>());
|
||||
return results;
|
||||
}
|
||||
|
||||
|
@ -129,15 +129,15 @@ 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;
|
||||
Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, pdsf.Item1);
|
||||
ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, processDataStandardFormat);
|
||||
SetFileParameterLotIDToLogisticsMID();
|
||||
JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf);
|
||||
JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat);
|
||||
List<Description> descriptions = json.ProcessData.GetDescriptions(jsonElements);
|
||||
Test[] tests = (from l in descriptions select (Test)l.Test).ToArray();
|
||||
if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0)
|
||||
SendData(reportFullPath, dateTime, descriptions);
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>());
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>());
|
||||
return results;
|
||||
}
|
||||
|
||||
|
@ -135,26 +135,26 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0060
|
||||
private static void PostOpenInsightMetrologyViewerAttachments(List<Description> descriptions)
|
||||
#pragma warning restore IDE0060
|
||||
{
|
||||
if (descriptions is null)
|
||||
throw new ArgumentNullException(nameof(descriptions));
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0060
|
||||
private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime)
|
||||
#pragma warning restore IDE0060
|
||||
{
|
||||
if (dateTime == DateTime.MinValue)
|
||||
throw new ArgumentNullException(nameof(dateTime));
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> results;
|
||||
Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, pdsf.Item1);
|
||||
ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, processDataStandardFormat);
|
||||
SetFileParameterLotIDToLogisticsMID();
|
||||
JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf);
|
||||
JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat);
|
||||
List<Description> descriptions = json.ProcessData.GetDescriptions(jsonElements);
|
||||
Test[] tests = (from l in descriptions select (Test)l.Test).ToArray();
|
||||
if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0)
|
||||
PostOpenInsightMetrologyViewerAttachments(descriptions);
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>());
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>());
|
||||
return results;
|
||||
}
|
||||
|
||||
|
@ -1,37 +1,211 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.Priority;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public class Aggregation
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public Aggregation(
|
||||
string average,
|
||||
int count,
|
||||
int? inverse,
|
||||
int maximum,
|
||||
int minimum,
|
||||
ReadOnlyCollection<Record> records,
|
||||
int sum
|
||||
)
|
||||
public Aggregation(double inverseAverage,
|
||||
int valueCount,
|
||||
double fibonacciAverage,
|
||||
int? inverseValue,
|
||||
int valueMaximum,
|
||||
int valueMinimum,
|
||||
Notification[] notifications,
|
||||
int valueSum)
|
||||
{
|
||||
Average = average;
|
||||
Count = count;
|
||||
Inverse = inverse;
|
||||
Maximum = maximum;
|
||||
Minimum = minimum;
|
||||
Records = records;
|
||||
Sum = sum;
|
||||
InverseAverage = inverseAverage;
|
||||
ValueCount = valueCount;
|
||||
FibonacciAverage = fibonacciAverage;
|
||||
InverseValue = inverseValue;
|
||||
ValueMaximum = valueMaximum;
|
||||
ValueMinimum = valueMinimum;
|
||||
Notifications = notifications;
|
||||
ValueSum = valueSum;
|
||||
}
|
||||
|
||||
[JsonPropertyName("Average")] public string Average { get; }
|
||||
[JsonPropertyName("Count")] public int Count { get; }
|
||||
[JsonPropertyName("Inverse")] public int? Inverse { get; }
|
||||
[JsonPropertyName("Maximum")] public int Maximum { get; }
|
||||
[JsonPropertyName("Minimum")] public int Minimum { get; }
|
||||
[JsonPropertyName("Records")] public ReadOnlyCollection<Record> Records { get; }
|
||||
[JsonPropertyName("Sum")] public int Sum { get; }
|
||||
public double InverseAverage { get; } // [JsonPropertyName("InverseAverage")]
|
||||
public int ValueCount { get; } // [JsonPropertyName("ValueCount")]
|
||||
public double FibonacciAverage { get; } // [JsonPropertyName("Fibonacci")]
|
||||
public int? InverseValue { get; } // [JsonPropertyName("InverseValue")]
|
||||
public int ValueMaximum { get; } // [JsonPropertyName("ValueMaximum")]
|
||||
public int ValueMinimum { get; } // [JsonPropertyName("ValueMinimum")]
|
||||
public Notification[] Notifications { get; } // [JsonPropertyName("Notifications")]
|
||||
public int ValueSum { get; } // [JsonPropertyName("ValueSum")]
|
||||
|
||||
private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Dictionary<int, List<Notification>> keyValuePairs)
|
||||
{
|
||||
Dictionary<int, Aggregation> results = new();
|
||||
int? inverseValue;
|
||||
double inverseAverage;
|
||||
Aggregation aggregation;
|
||||
double fibonacciAverage;
|
||||
List<int> collection = new();
|
||||
int averageFromInverseCeiling;
|
||||
List<int> inverseCollection = new();
|
||||
List<int> fibonacciCollection = new();
|
||||
foreach (KeyValuePair<int, List<Notification>> keyValuePair in keyValuePairs)
|
||||
{
|
||||
collection.Clear();
|
||||
inverseCollection.Clear();
|
||||
fibonacciCollection.Clear();
|
||||
foreach (Notification notification in keyValuePair.Value)
|
||||
{
|
||||
collection.Add(notification.Value);
|
||||
if (notification.Inverse is null)
|
||||
continue;
|
||||
inverseCollection.Add(notification.Inverse.Value);
|
||||
if (notification.Fibonacci is null)
|
||||
continue;
|
||||
fibonacciCollection.Add(notification.Fibonacci.Value);
|
||||
}
|
||||
if (inverseCollection.Count == 0 || fibonacciCollection.Count == 0)
|
||||
continue;
|
||||
inverseAverage = Math.Round(inverseCollection.Average(), settings.Digits);
|
||||
averageFromInverseCeiling = (int)Math.Ceiling(inverseAverage);
|
||||
inverseValue = Notification.GetInverse(averageFromInverseCeiling);
|
||||
fibonacciAverage = Math.Round(fibonacciCollection.Average(), settings.Digits);
|
||||
aggregation = new(inverseAverage: inverseAverage,
|
||||
valueCount: collection.Count,
|
||||
fibonacciAverage: fibonacciAverage,
|
||||
inverseValue: inverseValue,
|
||||
valueMaximum: collection.Max(),
|
||||
valueMinimum: collection.Min(),
|
||||
notifications: keyValuePair.Value.ToArray(),
|
||||
valueSum: collection.Sum());
|
||||
results.Add(keyValuePair.Key, aggregation);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Notification> GetNotifications(Settings settings, string directory)
|
||||
{
|
||||
List<Notification> results = new();
|
||||
string? key;
|
||||
string text;
|
||||
string[] files;
|
||||
Notification? notification;
|
||||
List<Notification>? collection;
|
||||
Dictionary<string, List<Notification>> keyValuePairs = new();
|
||||
string[] directories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly);
|
||||
foreach (string subDirectory in directories)
|
||||
{
|
||||
keyValuePairs.Clear();
|
||||
files = Directory.GetFiles(subDirectory, settings.SourceFileFilter, SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
{
|
||||
text = File.ReadAllText(file);
|
||||
if (string.IsNullOrEmpty(text) || text[0] == '[')
|
||||
continue;
|
||||
notification = JsonSerializer.Deserialize(text, NotificationSourceGenerationContext.Default.Notification);
|
||||
if (notification is null || notification.Id == 0)
|
||||
continue;
|
||||
key = !string.IsNullOrEmpty(notification.Username) ? notification.Username : notification.RemoteIpAddress;
|
||||
if (string.IsNullOrEmpty(key))
|
||||
continue;
|
||||
if (!keyValuePairs.TryGetValue(key, out collection))
|
||||
{
|
||||
keyValuePairs.Add(key, new());
|
||||
if (!keyValuePairs.TryGetValue(key, out collection))
|
||||
throw new Exception();
|
||||
}
|
||||
collection.Add(notification);
|
||||
}
|
||||
foreach (KeyValuePair<string, List<Notification>> keyValuePair in keyValuePairs)
|
||||
{
|
||||
if (keyValuePair.Value.Count == 1)
|
||||
results.Add(keyValuePair.Value[0]);
|
||||
else
|
||||
{
|
||||
notification = keyValuePair.Value.Select(record => new KeyValuePair<long, Notification>(record.Time, record)).OrderBy(pair => pair.Key).Last().Value;
|
||||
results.Add(notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, string directory)
|
||||
{
|
||||
ReadOnlyDictionary<int, Aggregation> results;
|
||||
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))
|
||||
{
|
||||
keyValuePairs.Add(notification.Id, new());
|
||||
if (!keyValuePairs.TryGetValue(notification.Id, out collection))
|
||||
throw new Exception();
|
||||
}
|
||||
collection.Add(notification);
|
||||
}
|
||||
results = GetKeyValuePairs(settings, keyValuePairs);
|
||||
return results;
|
||||
}
|
||||
|
||||
internal static ReadOnlyDictionary<string, ReadOnlyDictionary<int, Aggregation>> GetKeyValuePairsAndWriteFiles(Settings settings)
|
||||
{
|
||||
Dictionary<string, ReadOnlyDictionary<int, Aggregation>> results = new();
|
||||
string json;
|
||||
string jsonOld;
|
||||
string jsonFile;
|
||||
string directoryName;
|
||||
ReadOnlyDictionary<int, Aggregation> keyValuePairs;
|
||||
if (!Directory.Exists(settings.SourceFileLocation))
|
||||
_ = Directory.CreateDirectory(settings.SourceFileLocation);
|
||||
if (!Directory.Exists(settings.TargetFileLocation))
|
||||
_ = Directory.CreateDirectory(settings.TargetFileLocation);
|
||||
string[] directories = Directory.GetDirectories(settings.SourceFileLocation, "*", SearchOption.TopDirectoryOnly);
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
directoryName = Path.GetFileName(directory);
|
||||
keyValuePairs = GetKeyValuePairs(settings, directory);
|
||||
jsonFile = Path.Combine(settings.TargetFileLocation, $"{directoryName}.json");
|
||||
json = JsonSerializer.Serialize(keyValuePairs, AggregationReadOnlyDictionarySourceGenerationContext.Default.ReadOnlyDictionaryInt32Aggregation);
|
||||
// keyValuePairs = JsonSerializer.Deserialize(json, AggregationReadOnlyDictionarySourceGenerationContext.Default.ReadOnlyDictionaryInt32Aggregation);
|
||||
jsonOld = File.Exists(jsonFile) ? File.ReadAllText(jsonFile) : string.Empty;
|
||||
if (json != jsonOld)
|
||||
File.WriteAllText(jsonFile, json);
|
||||
results.Add(directoryName, keyValuePairs);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
internal static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Settings settings, Notification notification)
|
||||
{
|
||||
ReadOnlyDictionary<int, Aggregation> results;
|
||||
Dictionary<int, List<Notification>> keyValuePairs = new() { { notification.Id, new Notification[] { notification }.ToList() } };
|
||||
results = GetKeyValuePairs(settings, keyValuePairs);
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Aggregation))]
|
||||
internal partial class AggregationSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Aggregation[]))]
|
||||
internal partial class AggregationCollectionSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(ReadOnlyDictionary<int, Aggregation>))]
|
||||
internal partial class AggregationReadOnlyDictionarySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -3,28 +3,36 @@ using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration;
|
||||
using Adaptation.Shared;
|
||||
using Adaptation.Shared.Duplicator;
|
||||
using Adaptation.Shared.Methods;
|
||||
using log4net;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
|
||||
namespace Adaptation.FileHandlers.Priority;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public class FileRead : Shared.FileRead, IFileRead
|
||||
{
|
||||
|
||||
private readonly Timer _Timer;
|
||||
internal static ILog Log => _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
|
||||
|
||||
public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) :
|
||||
base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null)
|
||||
{
|
||||
_WorkItems = new();
|
||||
_MinFileLength = 10;
|
||||
_NullData = string.Empty;
|
||||
_Logistics = new(this);
|
||||
_NullData = string.Empty;
|
||||
_Log = LogManager.GetLogger(typeof(FileRead));
|
||||
if (_FileParameter is null)
|
||||
throw new Exception(cellInstanceConnectionName);
|
||||
if (_ModelObjectParameterDefinitions is null)
|
||||
@ -33,12 +41,23 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
throw new Exception(cellInstanceConnectionName);
|
||||
if (_IsEAFHosted)
|
||||
NestExistingFiles(_FileConnectorConfiguration);
|
||||
if (!Debugger.IsAttached && fileConnectorConfiguration.PreProcessingMode != FileConnectorConfiguration.PreProcessingModeEnum.Process)
|
||||
_Timer = new Timer(Callback, null, (int)(fileConnectorConfiguration.FileScanningIntervalInSeconds * 1000), Timeout.Infinite);
|
||||
else
|
||||
string parentDirectory = Path.GetDirectoryName(_FileConnectorConfiguration.TargetFileLocation) ?? throw new Exception();
|
||||
_Settings = new(digits: 5,
|
||||
parentDirectory: parentDirectory,
|
||||
priorities: 3,
|
||||
priorityGroups: 9,
|
||||
sourceFileFilter: _FileConnectorConfiguration.SourceFileFilter,
|
||||
sourceFileLocation: _FileConnectorConfiguration.SourceFileLocation,
|
||||
targetFileLocation: _FileConnectorConfiguration.TargetFileLocation);
|
||||
string? json = WeightedShortestJobFirstHub.PopulatedWorkItemsAndGetJson(_Settings);
|
||||
if (!string.IsNullOrEmpty(json))
|
||||
WeightedShortestJobFirstHub.WriteJson(json);
|
||||
string cellInstanceNamed = string.Concat("CellInstance.", _EquipmentType);
|
||||
string url = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.Microsoft.Owin.Hosting.WebApp.Start.URL");
|
||||
if (_IsEAFHosted)
|
||||
{
|
||||
_Timer = new Timer(Callback, null, Timeout.Infinite, Timeout.Infinite);
|
||||
Callback(null);
|
||||
_ = Microsoft.Owin.Hosting.WebApp.Start(url);
|
||||
_Log.Info($"Server running on {url}");
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,7 +110,7 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
DateTime dateTime = DateTime.Now;
|
||||
results = GetExtractResult(reportFullPath, dateTime);
|
||||
if (results.Item3 is null)
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]"), results.Item4);
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]") ?? throw new Exception(), results.Item4);
|
||||
if (results.Item3.Length > 0 && _IsEAFHosted)
|
||||
WritePDSF(this, results.Item3);
|
||||
UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks);
|
||||
@ -107,187 +126,14 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
return results;
|
||||
}
|
||||
|
||||
#nullable enable
|
||||
|
||||
private static ReadOnlyCollection<Record> GetRecords(string directory, string searchPattern)
|
||||
{
|
||||
List<Record> results = new();
|
||||
string text;
|
||||
Record? record;
|
||||
string[] files;
|
||||
List<Record>? collection;
|
||||
Dictionary<string, List<Record>> keyValuePairs = new();
|
||||
string[] directories = Directory.GetDirectories(directory, "*", SearchOption.TopDirectoryOnly);
|
||||
foreach (string subDirectory in directories)
|
||||
{
|
||||
keyValuePairs.Clear();
|
||||
files = Directory.GetFiles(subDirectory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||
foreach (string file in files)
|
||||
{
|
||||
text = File.ReadAllText(file);
|
||||
if (string.IsNullOrEmpty(text) || text[0] == '[')
|
||||
continue;
|
||||
record = JsonSerializer.Deserialize<Record>(text);
|
||||
if (record is null || record.Id == 0)
|
||||
continue;
|
||||
if (!keyValuePairs.TryGetValue(record.RemoteIpAddress, out collection))
|
||||
{
|
||||
keyValuePairs.Add(record.RemoteIpAddress, new());
|
||||
if (!keyValuePairs.TryGetValue(record.RemoteIpAddress, out collection))
|
||||
throw new Exception();
|
||||
}
|
||||
collection.Add(record);
|
||||
}
|
||||
foreach (KeyValuePair<string, List<Record>> keyValuePair in keyValuePairs)
|
||||
{
|
||||
if (keyValuePair.Value.Count == 1)
|
||||
results.Add(keyValuePair.Value[0]);
|
||||
else
|
||||
{
|
||||
record = keyValuePair.Value.Select(record => new KeyValuePair<long, Record>(record.Time, record)).OrderBy(pair => pair.Key).Last().Value;
|
||||
results.Add(record);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static int? GetInverse(int value) =>
|
||||
value switch
|
||||
{
|
||||
1 => 3,
|
||||
2 => 2,
|
||||
3 => 1,
|
||||
_ => null
|
||||
};
|
||||
|
||||
private static int? GetInverse(double value)
|
||||
{
|
||||
int? result;
|
||||
if (value > 3)
|
||||
result = null;
|
||||
else if (value > 2)
|
||||
result = 1;
|
||||
else if (value > 1)
|
||||
result = 2;
|
||||
else if (value > 0)
|
||||
result = 3;
|
||||
else
|
||||
result = null;
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(Dictionary<int, List<Record>> keyValuePairs)
|
||||
{
|
||||
Dictionary<int, Aggregation> results = new();
|
||||
Aggregation aggregation;
|
||||
int? inverse;
|
||||
double average;
|
||||
List<int> collection = new();
|
||||
foreach (KeyValuePair<int, List<Record>> keyValuePair in keyValuePairs)
|
||||
{
|
||||
collection.Clear();
|
||||
foreach (Record record in keyValuePair.Value)
|
||||
{
|
||||
inverse = GetInverse(record.Value);
|
||||
if (inverse is null)
|
||||
continue;
|
||||
collection.Add(inverse.Value);
|
||||
}
|
||||
average = collection.Average();
|
||||
inverse = GetInverse(average);
|
||||
aggregation = new(average.ToString("0.000"),
|
||||
keyValuePair.Value.Count,
|
||||
inverse,
|
||||
keyValuePair.Value.Max(record => record.Value),
|
||||
keyValuePair.Value.Min(record => record.Value),
|
||||
new(keyValuePair.Value),
|
||||
keyValuePair.Value.Sum(record => record.Value));
|
||||
results.Add(keyValuePair.Key, aggregation);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, Aggregation> GetKeyValuePairs(string directory, string searchPattern)
|
||||
{
|
||||
ReadOnlyDictionary<int, Aggregation> results;
|
||||
List<Record>? collection;
|
||||
Dictionary<int, List<Record>> keyValuePairs = new();
|
||||
ReadOnlyCollection<Record> records = GetRecords(directory, searchPattern);
|
||||
foreach (Record record in records)
|
||||
{
|
||||
if (!keyValuePairs.TryGetValue(record.Id, out collection))
|
||||
{
|
||||
keyValuePairs.Add(record.Id, new());
|
||||
if (!keyValuePairs.TryGetValue(record.Id, out collection))
|
||||
throw new Exception();
|
||||
}
|
||||
collection.Add(record);
|
||||
}
|
||||
results = GetKeyValuePairs(keyValuePairs);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static void WriteFiles(string sourceFileLocation, string sourceFileFilter, string targetFileLocation)
|
||||
{
|
||||
string json;
|
||||
string jsonFile;
|
||||
string directoryName;
|
||||
if (!Directory.Exists(sourceFileLocation))
|
||||
_ = Directory.CreateDirectory(sourceFileLocation);
|
||||
if (!Directory.Exists(targetFileLocation))
|
||||
_ = Directory.CreateDirectory(targetFileLocation);
|
||||
ReadOnlyDictionary<int, Aggregation> keyValuePairs;
|
||||
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
|
||||
string[] directories = Directory.GetDirectories(sourceFileLocation, "*", SearchOption.TopDirectoryOnly);
|
||||
foreach (string directory in directories)
|
||||
{
|
||||
directoryName = Path.GetFileName(directory);
|
||||
keyValuePairs = GetKeyValuePairs(directory, sourceFileFilter);
|
||||
jsonFile = Path.Combine(targetFileLocation, $"{directoryName}.json");
|
||||
json = JsonSerializer.Serialize(keyValuePairs, jsonSerializerOptions);
|
||||
File.WriteAllText(jsonFile, json);
|
||||
}
|
||||
}
|
||||
|
||||
private void Callback(object state)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_IsEAFHosted)
|
||||
WriteFiles(_FileConnectorConfiguration.SourceFileLocation, _FileConnectorConfiguration.SourceFileFilter, _FileConnectorConfiguration.TargetFileLocation);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
string subject = string.Concat("Exception:", _CellInstanceConnectionName);
|
||||
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
|
||||
try
|
||||
{ _SMTP.SendHighPriorityEmailMessage(subject, body); }
|
||||
catch (Exception) { }
|
||||
}
|
||||
try
|
||||
{
|
||||
if (_FileConnectorConfiguration?.FileScanningIntervalInSeconds is null)
|
||||
throw new Exception();
|
||||
TimeSpan timeSpan = new(DateTime.Now.AddSeconds(_FileConnectorConfiguration.FileScanningIntervalInSeconds.Value).Ticks - DateTime.Now.Ticks);
|
||||
_ = _Timer.Change((long)timeSpan.TotalMilliseconds, Timeout.Infinite);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
string subject = string.Concat("Exception:", _CellInstanceConnectionName);
|
||||
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
|
||||
try
|
||||
{ _SMTP.SendHighPriorityEmailMessage(subject, body); }
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0060
|
||||
private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime)
|
||||
#pragma warning restore IDE0060
|
||||
{
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> results;
|
||||
_Logistics = new Logistics(reportFullPath, $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};");
|
||||
if (dateTime == DateTime.MinValue)
|
||||
throw new ArgumentNullException(nameof(dateTime));
|
||||
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>());
|
||||
return results;
|
||||
}
|
||||
|
90
Adaptation/FileHandlers/Priority/Notification.cs
Normal file
90
Adaptation/FileHandlers/Priority/Notification.cs
Normal file
@ -0,0 +1,90 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.Priority;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public class Notification
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public Notification(int? fibonacci,
|
||||
int id,
|
||||
int? inverse,
|
||||
string? machineId,
|
||||
string page,
|
||||
string? remoteIpAddress,
|
||||
string? site,
|
||||
long time,
|
||||
string? username,
|
||||
int value)
|
||||
{
|
||||
int? i = inverse is not null ? inverse : GetInverse(value);
|
||||
Fibonacci = fibonacci is not null ? fibonacci : i is null ? null : GetFibonacci(i.Value);
|
||||
Id = id;
|
||||
Inverse = i;
|
||||
MachineId = machineId;
|
||||
Page = page;
|
||||
RemoteIpAddress = remoteIpAddress is not null ? remoteIpAddress : null;
|
||||
Site = site is not null ? site : "MES";
|
||||
Time = time;
|
||||
Username = username;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
[JsonPropertyName("id")] public int 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("username")] public string? Username { get; }
|
||||
[JsonPropertyName("value")] public int Value { get; }
|
||||
|
||||
internal static int? GetInverse(int value) =>
|
||||
value switch
|
||||
{
|
||||
1 => 5,
|
||||
2 => 4,
|
||||
3 => 3,
|
||||
4 => 2,
|
||||
5 => 1,
|
||||
_ => null
|
||||
};
|
||||
|
||||
private static int? GetFibonacci(int value) =>
|
||||
value switch
|
||||
{
|
||||
9 => 55,
|
||||
8 => 34,
|
||||
7 => 21,
|
||||
6 => 13,
|
||||
5 => 8,
|
||||
4 => 5,
|
||||
3 => 3,
|
||||
2 => 2,
|
||||
1 => 1,
|
||||
_ => null
|
||||
};
|
||||
|
||||
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)]
|
||||
[JsonSerializable(typeof(Notification))]
|
||||
public partial class NotificationSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.Priority;
|
||||
|
||||
public class Record
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public Record(
|
||||
string json,
|
||||
int id,
|
||||
string page,
|
||||
string queryString,
|
||||
string remoteIpAddress,
|
||||
long time,
|
||||
int value
|
||||
)
|
||||
{
|
||||
Json = json;
|
||||
Id = id;
|
||||
Page = page;
|
||||
QueryString = queryString;
|
||||
RemoteIpAddress = remoteIpAddress;
|
||||
Time = time;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
[JsonPropertyName("Json")] public string Json { get; }
|
||||
[JsonPropertyName("id")] public int Id { get; }
|
||||
[JsonPropertyName("page")] public string Page { get; }
|
||||
[JsonPropertyName("QueryString")] public string QueryString { get; }
|
||||
[JsonPropertyName("RemoteIpAddress")] public string RemoteIpAddress { get; }
|
||||
[JsonPropertyName("time")] public long Time { get; }
|
||||
[JsonPropertyName("value")] public int Value { get; }
|
||||
|
||||
}
|
43
Adaptation/FileHandlers/Priority/Settings.cs
Normal file
43
Adaptation/FileHandlers/Priority/Settings.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.Priority;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public class Settings
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public Settings(int digits,
|
||||
string parentDirectory,
|
||||
int priorities,
|
||||
int priorityGroups,
|
||||
string sourceFileFilter,
|
||||
string sourceFileLocation,
|
||||
string targetFileLocation)
|
||||
{
|
||||
Digits = digits;
|
||||
ParentDirectory = parentDirectory;
|
||||
Priorities = priorities;
|
||||
PriorityGroups = priorityGroups;
|
||||
SourceFileFilter = sourceFileFilter;
|
||||
SourceFileLocation = sourceFileLocation;
|
||||
TargetFileLocation = targetFileLocation;
|
||||
}
|
||||
|
||||
public int Digits { get; } // [JsonPropertyName("Digits")]
|
||||
public string ParentDirectory { get; } // [JsonPropertyName("ParentDirectory")]
|
||||
public int Priorities { get; } // [JsonPropertyName("Priorities")]
|
||||
public int PriorityGroups { get; } // [JsonPropertyName("PriorityGroups")]
|
||||
public string SourceFileFilter { get; } // [JsonPropertyName("SourceFileFilter")]
|
||||
public string SourceFileLocation { get; } // [JsonPropertyName("SourceFileLocation")]
|
||||
public string TargetFileLocation { get; } // [JsonPropertyName("TargetFileLocation")]
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Dictionary<int, Settings>))]
|
||||
internal partial class SettingsDictionarySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
13
Adaptation/FileHandlers/Priority/Startup.cs
Normal file
13
Adaptation/FileHandlers/Priority/Startup.cs
Normal file
@ -0,0 +1,13 @@
|
||||
using Microsoft.Owin.Cors;
|
||||
using Owin;
|
||||
|
||||
public class Startup
|
||||
{
|
||||
|
||||
public void Configuration(IAppBuilder app)
|
||||
{
|
||||
_ = app.UseCors(CorsOptions.AllowAll);
|
||||
_ = app.MapSignalR();
|
||||
}
|
||||
|
||||
}
|
158
Adaptation/FileHandlers/Priority/WeightedShortestJobFirstHub.cs
Normal file
158
Adaptation/FileHandlers/Priority/WeightedShortestJobFirstHub.cs
Normal file
@ -0,0 +1,158 @@
|
||||
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); }
|
||||
}
|
||||
|
||||
}
|
205
Adaptation/FileHandlers/Priority/WorkItem.cs
Normal file
205
Adaptation/FileHandlers/Priority/WorkItem.cs
Normal file
@ -0,0 +1,205 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.Priority;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public class WorkItem
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public WorkItem(double? costOfDelay,
|
||||
Aggregation? businessValue,
|
||||
Aggregation? effort,
|
||||
int id,
|
||||
int? sortBeforeId,
|
||||
int? sortPriority,
|
||||
int? sortPriorityGroup,
|
||||
Aggregation? riskReductionOpportunityEnablement,
|
||||
string? site,
|
||||
int? sortOrder,
|
||||
Aggregation? timeCriticality,
|
||||
double? weightedShortestJobFirst)
|
||||
{
|
||||
CostOfDelay = costOfDelay;
|
||||
BusinessValue = businessValue;
|
||||
Effort = effort;
|
||||
Id = id;
|
||||
Site = site;
|
||||
SortBeforeId = sortBeforeId;
|
||||
SortPriority = sortPriority;
|
||||
SortPriorityGroup = sortPriorityGroup;
|
||||
RiskReductionOpportunityEnablement = riskReductionOpportunityEnablement;
|
||||
SortOrder = sortOrder;
|
||||
TimeCriticality = timeCriticality;
|
||||
WeightedShortestJobFirst = weightedShortestJobFirst;
|
||||
}
|
||||
|
||||
const string _PageEffort = "effort";
|
||||
const string _PageTimeCriticality = "time";
|
||||
const string _PageBusinessValue = "business";
|
||||
const string _PageRiskReductionOpportunityEnablement = "risk";
|
||||
|
||||
public double? CostOfDelay { get; } // [JsonPropertyName("CostOfDelay")]
|
||||
public Aggregation? BusinessValue { get; } // [JsonPropertyName("BusinessValue")]
|
||||
public Aggregation? Effort { get; } // [JsonPropertyName("Effort")]
|
||||
public int Id { get; } // [JsonPropertyName("Id")]
|
||||
public string? Site { get; } // [JsonPropertyName("Site")]
|
||||
public int? SortBeforeId { get; } // [JsonPropertyName("SortBeforeId")]
|
||||
public int? SortPriority { get; } // [JsonPropertyName("SortPriority")]
|
||||
public int? SortPriorityGroup { get; } // [JsonPropertyName("SortPriorityGroup")]
|
||||
public Aggregation? RiskReductionOpportunityEnablement { get; } // [JsonPropertyName("RiskReductionOpportunityEnablement")]
|
||||
public int? SortOrder { get; } // [JsonPropertyName("SortOrder")]
|
||||
public Aggregation? TimeCriticality { get; } // [JsonPropertyName("TimeCriticality")]
|
||||
public double? WeightedShortestJobFirst { get; } // [JsonPropertyName("WeightedShortestJobFirst")]
|
||||
|
||||
internal static WorkItem GetWorkItem(WorkItem workItem, int i, int? sortBeforeId, int? sortPriority, int? sortPriorityGroup) =>
|
||||
new(workItem.CostOfDelay,
|
||||
workItem.BusinessValue,
|
||||
workItem.Effort,
|
||||
workItem.Id,
|
||||
sortBeforeId,
|
||||
sortPriority,
|
||||
sortPriorityGroup,
|
||||
workItem.RiskReductionOpportunityEnablement,
|
||||
workItem.Site,
|
||||
i,
|
||||
workItem.TimeCriticality,
|
||||
workItem.WeightedShortestJobFirst);
|
||||
|
||||
private static string? GetSite(Aggregation? effort, Aggregation? businessValue, Aggregation? timeCriticality, Aggregation? riskReductionOpportunityEnablement)
|
||||
{
|
||||
string? result = null;
|
||||
if (result is null && effort is not null)
|
||||
{
|
||||
foreach (Notification notification in effort.Notifications)
|
||||
{
|
||||
if (notification.Site is not null)
|
||||
{
|
||||
result = notification.Site;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result is null && businessValue is not null)
|
||||
{
|
||||
foreach (Notification notification in businessValue.Notifications)
|
||||
{
|
||||
if (notification.Site is not null)
|
||||
{
|
||||
result = notification.Site;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result is null && timeCriticality is not null)
|
||||
{
|
||||
foreach (Notification notification in timeCriticality.Notifications)
|
||||
{
|
||||
if (notification.Site is not null)
|
||||
{
|
||||
result = notification.Site;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (result is null && riskReductionOpportunityEnablement is not null)
|
||||
{
|
||||
foreach (Notification notification in riskReductionOpportunityEnablement.Notifications)
|
||||
{
|
||||
if (notification.Site is not null)
|
||||
{
|
||||
result = notification.Site;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static ReadOnlyDictionary<int, WorkItem?> GetWorkItems(Settings settings, ReadOnlyDictionary<string, ReadOnlyDictionary<int, Aggregation>> keyValuePairs)
|
||||
{
|
||||
Dictionary<int, WorkItem?> results = new();
|
||||
string? site;
|
||||
WorkItem? workItem;
|
||||
double? costOfDelay;
|
||||
Aggregation? effort;
|
||||
List<int> ids = new();
|
||||
Aggregation? businessValue;
|
||||
Aggregation? timeCriticality;
|
||||
double? weightedShortestJobFirst;
|
||||
Aggregation? riskReductionOpportunityEnablement;
|
||||
Dictionary<int, Aggregation?> effortCollection = new();
|
||||
Dictionary<int, Aggregation?> businessValueCollection = new();
|
||||
Dictionary<int, Aggregation?> timeCriticalityCollection = new();
|
||||
Dictionary<int, Aggregation?> riskReductionOpportunityEnablementCollection = new();
|
||||
foreach (KeyValuePair<string, ReadOnlyDictionary<int, Aggregation>> keyValuePair in keyValuePairs)
|
||||
{
|
||||
foreach (KeyValuePair<int, Aggregation> keyValue in keyValuePair.Value)
|
||||
{
|
||||
if (!ids.Contains(keyValue.Key))
|
||||
ids.Add(keyValue.Key);
|
||||
if (keyValuePair.Key == _PageEffort)
|
||||
effortCollection.Add(keyValue.Key, keyValue.Value);
|
||||
else if (keyValuePair.Key == _PageTimeCriticality)
|
||||
timeCriticalityCollection.Add(keyValue.Key, keyValue.Value);
|
||||
else if (keyValuePair.Key == _PageBusinessValue)
|
||||
businessValueCollection.Add(keyValue.Key, keyValue.Value);
|
||||
else if (keyValuePair.Key == _PageRiskReductionOpportunityEnablement)
|
||||
riskReductionOpportunityEnablementCollection.Add(keyValue.Key, keyValue.Value);
|
||||
else
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
foreach (int id in ids)
|
||||
{
|
||||
if (!effortCollection.TryGetValue(id, out effort))
|
||||
effort = null;
|
||||
if (!businessValueCollection.TryGetValue(id, out businessValue))
|
||||
businessValue = null;
|
||||
if (!timeCriticalityCollection.TryGetValue(id, out timeCriticality))
|
||||
timeCriticality = null;
|
||||
if (!riskReductionOpportunityEnablementCollection.TryGetValue(id, out riskReductionOpportunityEnablement))
|
||||
riskReductionOpportunityEnablement = null;
|
||||
site = GetSite(effort, businessValue, timeCriticality, riskReductionOpportunityEnablement);
|
||||
costOfDelay = businessValue is null
|
||||
|| timeCriticality is null
|
||||
|| riskReductionOpportunityEnablement is null ? null : businessValue.FibonacciAverage
|
||||
+ timeCriticality.FibonacciAverage
|
||||
+ riskReductionOpportunityEnablement.FibonacciAverage;
|
||||
weightedShortestJobFirst = costOfDelay is null || effort is null ? null : Math.Round(costOfDelay.Value / effort.FibonacciAverage, settings.Digits);
|
||||
workItem = new(costOfDelay: costOfDelay,
|
||||
businessValue: businessValue,
|
||||
effort: effort,
|
||||
id: id,
|
||||
sortBeforeId: null,
|
||||
sortPriority: null,
|
||||
sortPriorityGroup: null,
|
||||
riskReductionOpportunityEnablement: riskReductionOpportunityEnablement,
|
||||
site: site,
|
||||
sortOrder: null,
|
||||
timeCriticality: timeCriticality,
|
||||
weightedShortestJobFirst: weightedShortestJobFirst);
|
||||
results.Add(id, workItem);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
internal static ReadOnlyDictionary<int, WorkItem?> GetKeyValuePairs(Settings settings)
|
||||
{
|
||||
ReadOnlyDictionary<int, WorkItem?> results;
|
||||
ReadOnlyDictionary<string, ReadOnlyDictionary<int, Aggregation>> keyValuePairs = Aggregation.GetKeyValuePairsAndWriteFiles(settings);
|
||||
results = GetWorkItems(settings, keyValuePairs);
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Dictionary<int, WorkItem>))]
|
||||
internal partial class WorkItemDictionarySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -108,10 +108,12 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
return results;
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0060
|
||||
private void DirectoryMove(string reportFullPath, DateTime dateTime, List<Description> descriptions)
|
||||
#pragma warning restore IDE0060
|
||||
{
|
||||
if (dateTime == DateTime.MinValue)
|
||||
throw new ArgumentNullException(nameof(dateTime));
|
||||
if (descriptions is null)
|
||||
throw new ArgumentNullException(nameof(descriptions));
|
||||
FileInfo fileInfo = new(reportFullPath);
|
||||
_ = _Logistics.Sequence.ToString();
|
||||
string jobIdDirectory = Path.Combine(_JobIdParentDirectory, _Logistics.JobID);
|
||||
@ -141,13 +143,13 @@ 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;
|
||||
Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, pdsf.Item1);
|
||||
ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, processDataStandardFormat);
|
||||
SetFileParameterLotIDToLogisticsMID();
|
||||
JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf);
|
||||
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>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>());
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>());
|
||||
if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0)
|
||||
DirectoryMove(reportFullPath, dateTime, descriptions);
|
||||
else if (!_IsEAFHosted)
|
||||
|
@ -117,15 +117,15 @@ 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;
|
||||
Tuple<string, string[], string[]> pdsf = ProcessDataStandardFormat.GetLogisticsColumnsAndBody(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, pdsf.Item1);
|
||||
ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath);
|
||||
_Logistics = new Logistics(reportFullPath, processDataStandardFormat);
|
||||
SetFileParameterLotIDToLogisticsMID();
|
||||
JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(pdsf);
|
||||
JsonElement[] jsonElements = ProcessDataStandardFormat.GetArray(processDataStandardFormat);
|
||||
List<Shared.Properties.IDescription> descriptions = GetDuplicatorDescriptions(jsonElements);
|
||||
Test[] tests = (from l in descriptions select (Test)l.Test).ToArray();
|
||||
if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0)
|
||||
FileCopy(reportFullPath, dateTime, descriptions);
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(pdsf.Item1, tests, jsonElements, new List<FileInfo>());
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(string.Join(Environment.NewLine, processDataStandardFormat.Logistics[0]), tests, jsonElements, new List<FileInfo>());
|
||||
return results;
|
||||
}
|
||||
|
||||
|
127
Adaptation/FileHandlers/Violation/FileRead.cs
Normal file
127
Adaptation/FileHandlers/Violation/FileRead.cs
Normal file
@ -0,0 +1,127 @@
|
||||
using Adaptation.Eaf.Management.ConfigurationData.CellAutomation;
|
||||
using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration;
|
||||
using Adaptation.Shared;
|
||||
using Adaptation.Shared.Duplicator;
|
||||
using Adaptation.Shared.Methods;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Adaptation.FileHandlers.Violation;
|
||||
|
||||
public class FileRead : Shared.FileRead, IFileRead
|
||||
{
|
||||
|
||||
private long? _TickOffset;
|
||||
private readonly string _URL;
|
||||
private readonly ReadOnlyCollection<string> _WorkItemTypes;
|
||||
|
||||
public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) :
|
||||
base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null)
|
||||
{
|
||||
_MinFileLength = 10;
|
||||
_NullData = string.Empty;
|
||||
_Logistics = new(this);
|
||||
if (_FileParameter is null)
|
||||
throw new Exception(cellInstanceConnectionName);
|
||||
if (_ModelObjectParameterDefinitions is null)
|
||||
throw new Exception(cellInstanceConnectionName);
|
||||
if (!_IsDuplicator)
|
||||
throw new Exception(cellInstanceConnectionName);
|
||||
string cellInstanceNamed = string.Concat("CellInstance.", _EquipmentType);
|
||||
_URL = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.URL");
|
||||
string workItemTypes = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.WorkItemTypes");
|
||||
_WorkItemTypes = new(workItemTypes.Split('|'));
|
||||
if (_IsEAFHosted)
|
||||
NestExistingFiles(_FileConnectorConfiguration);
|
||||
}
|
||||
|
||||
void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) => Move(extractResults);
|
||||
|
||||
void IFileRead.WaitForThread() => WaitForThread(thread: null, threadExceptions: null);
|
||||
|
||||
string IFileRead.GetEventDescription()
|
||||
{
|
||||
string result = _Description.GetEventDescription();
|
||||
return result;
|
||||
}
|
||||
|
||||
List<string> IFileRead.GetHeaderNames()
|
||||
{
|
||||
List<string> results = _Description.GetHeaderNames();
|
||||
return results;
|
||||
}
|
||||
|
||||
string[] IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, string to, string from, string resolvedFileLocation, Exception exception)
|
||||
{
|
||||
string[] results = Move(extractResults, to, from, resolvedFileLocation, exception);
|
||||
return results;
|
||||
}
|
||||
|
||||
JsonProperty[] IFileRead.GetDefault()
|
||||
{
|
||||
JsonProperty[] results = _Description.GetDefault(this, _Logistics);
|
||||
return results;
|
||||
}
|
||||
|
||||
Dictionary<string, string> IFileRead.GetDisplayNamesJsonElement()
|
||||
{
|
||||
Dictionary<string, string> results = _Description.GetDisplayNamesJsonElement(this);
|
||||
return results;
|
||||
}
|
||||
|
||||
List<IDescription> IFileRead.GetDescriptions(IFileRead fileRead, List<Test> tests, IProcessData processData)
|
||||
{
|
||||
List<IDescription> results = _Description.GetDescriptions(fileRead, _Logistics, tests, processData);
|
||||
return results;
|
||||
}
|
||||
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.GetExtractResult(string reportFullPath, string eventName)
|
||||
{
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> results;
|
||||
if (string.IsNullOrEmpty(eventName))
|
||||
throw new Exception();
|
||||
_ReportFullPath = reportFullPath;
|
||||
DateTime dateTime = DateTime.Now;
|
||||
results = GetExtractResult(reportFullPath, dateTime);
|
||||
if (results.Item3 is null)
|
||||
results = new Tuple<string, Test[], JsonElement[], List<FileInfo>>(results.Item1, Array.Empty<Test>(), JsonSerializer.Deserialize<JsonElement[]>("[]"), results.Item4);
|
||||
if (results.Item3.Length > 0 && _IsEAFHosted)
|
||||
WritePDSF(this, results.Item3);
|
||||
UpdateLastTicksDuration(DateTime.Now.Ticks - dateTime.Ticks);
|
||||
return results;
|
||||
}
|
||||
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> IFileRead.ReExtract()
|
||||
{
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> results;
|
||||
List<string> headerNames = _Description.GetHeaderNames();
|
||||
Dictionary<string, string> keyValuePairs = _Description.GetDisplayNamesJsonElement(this);
|
||||
results = ReExtract(this, headerNames, keyValuePairs);
|
||||
return results;
|
||||
}
|
||||
|
||||
private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime)
|
||||
{
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> results = new(string.Empty, null, null, new List<FileInfo>());
|
||||
_TickOffset ??= 0; // new FileInfo(reportFullPath).LastWriteTime.Ticks - dateTime.Ticks;
|
||||
string[] lines = new string[] { string.Empty, "NUM_DATA_ROWS", $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};" };
|
||||
ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines);
|
||||
_Logistics = new Logistics(reportFullPath, processDataStandardFormat);
|
||||
SetFileParameterLotIDToLogisticsMID();
|
||||
if (_Logistics.FileInfo.Length < _MinFileLength)
|
||||
results.Item4.Add(_Logistics.FileInfo);
|
||||
else
|
||||
{
|
||||
IProcessData iProcessData = new ProcessData(this, _Logistics, _FileConnectorConfiguration.TargetFileLocation, _URL, _WorkItemTypes, results.Item4);
|
||||
if (iProcessData.Details.Count == 0)
|
||||
results = new(string.Concat("B) No Data - ", dateTime.Ticks), Array.Empty<Test>(), Array.Empty<JsonElement>(), results.Item4);
|
||||
else
|
||||
results = iProcessData.GetResults(this, _Logistics, results.Item4);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
706
Adaptation/FileHandlers/Violation/ProcessData.cs
Normal file
706
Adaptation/FileHandlers/Violation/ProcessData.cs
Normal file
@ -0,0 +1,706 @@
|
||||
using Adaptation.FileHandlers.json.WorkItems;
|
||||
using Adaptation.Shared;
|
||||
using Adaptation.Shared.Duplicator;
|
||||
using Adaptation.Shared.Methods;
|
||||
using log4net;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.Violation;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public class ProcessData : IProcessData
|
||||
{
|
||||
|
||||
private readonly List<object> _Details;
|
||||
|
||||
List<object> Shared.Properties.IProcessData.Details => _Details;
|
||||
|
||||
private readonly ILog _Log;
|
||||
|
||||
string IProcessData.GetCurrentReactor(IFileRead fileRead, Logistics logistics, Dictionary<string, string> reactors) =>
|
||||
throw new Exception(string.Concat("See ", nameof(WriteFiles)));
|
||||
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> IProcessData.GetResults(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection) =>
|
||||
new(logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), fileInfoCollection);
|
||||
|
||||
public ProcessData(IFileRead fileRead, Logistics logistics, string targetFileLocation, string url, ReadOnlyCollection<string> workItemTypes, List<FileInfo> fileInfoCollection)
|
||||
{
|
||||
if (fileRead.IsEAFHosted)
|
||||
{ }
|
||||
_Details = new List<object>();
|
||||
_Log = LogManager.GetLogger(typeof(ProcessData));
|
||||
WriteFiles(fileRead, logistics, targetFileLocation, url, fileInfoCollection, workItemTypes);
|
||||
}
|
||||
|
||||
private void WriteFiles(IFileRead fileRead, Logistics logistics, string destinationDirectory, string url, List<FileInfo> fileInfoCollection, ReadOnlyCollection<string> __)
|
||||
{
|
||||
if (!Directory.Exists(destinationDirectory))
|
||||
_ = Directory.CreateDirectory(destinationDirectory);
|
||||
string json = File.ReadAllText(logistics.ReportFullPath);
|
||||
// WorkItem[]? workItems = JsonSerializer.Deserialize<WorkItem[]>(json);
|
||||
// if (workItems is null)
|
||||
// throw new Exception(nameof(workItems));
|
||||
JsonElement[]? jsonElements = JsonSerializer.Deserialize<JsonElement[]>(json);
|
||||
if (jsonElements is null)
|
||||
throw new Exception(nameof(jsonElements));
|
||||
WorkItem? workItem;
|
||||
List<WorkItem> workItems = new();
|
||||
foreach (JsonElement jsonElement in jsonElements)
|
||||
{
|
||||
workItem = JsonSerializer.Deserialize<WorkItem>(jsonElement.ToString());
|
||||
if (workItem is null)
|
||||
continue;
|
||||
workItems.Add(workItem);
|
||||
}
|
||||
List<char> spaces = new();
|
||||
bool keepRelations = false;
|
||||
List<string> lines = new();
|
||||
List<string> messages = new();
|
||||
ReadOnlyCollection<Record> results;
|
||||
ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations);
|
||||
ReadOnlyCollection<Record> records = new(keyValuePairs.Values.ToArray());
|
||||
ReadOnlyCollection<string> 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" });
|
||||
{
|
||||
lines.Clear();
|
||||
string workItemType = "Feature";
|
||||
lines.Add($"# {nameof(FeatureCheckIterationPath122508)}");
|
||||
lines.Add(string.Empty);
|
||||
results = FeatureCheckIterationPath122508(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType);
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-122508");
|
||||
_Details.Add(results);
|
||||
}
|
||||
{
|
||||
lines.Clear();
|
||||
string workItemType = "Feature";
|
||||
lines.Add($"# {nameof(FeatureCheckTag122514)}");
|
||||
lines.Add(string.Empty);
|
||||
results = FeatureCheckTag122514(url, lines, bugUserStoryWorkItemTypes, keyValuePairs, workItemType);
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-122514");
|
||||
_Details.Add(results);
|
||||
}
|
||||
{
|
||||
lines.Clear();
|
||||
string workItemType = "Feature";
|
||||
lines.Add($"# {nameof(FeatureCheckPriority126169)}");
|
||||
lines.Add(string.Empty);
|
||||
results = FeatureCheckPriority126169(url, lines, bugUserStoryWorkItemTypes, keyValuePairs, workItemType);
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-126169");
|
||||
_Details.Add(results);
|
||||
}
|
||||
{
|
||||
lines.Clear();
|
||||
string workItemType = "Feature";
|
||||
lines.Add($"# {nameof(FeatureCheckState123066)}");
|
||||
lines.Add(string.Empty);
|
||||
results = FeatureCheckState123066(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType);
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-123066");
|
||||
_Details.Add(results);
|
||||
}
|
||||
{
|
||||
lines.Clear();
|
||||
string workItemType = "Feature";
|
||||
lines.Add($"# {nameof(FeatureCheckState123067)}");
|
||||
lines.Add(string.Empty);
|
||||
results = FeatureCheckState123067(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType);
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-123067");
|
||||
_Details.Add(results);
|
||||
}
|
||||
{
|
||||
lines.Clear();
|
||||
string workItemType = "Feature";
|
||||
lines.Add($"# {nameof(FeatureCheckStart122517)}");
|
||||
lines.Add(string.Empty);
|
||||
results = FeatureCheckStart122517(url, lines, bugUserStoryTaskWorkItemTypes, keyValuePairs, workItemType);
|
||||
WriteFiles(fileRead, destinationDirectory, fileInfoCollection, new(lines), workItemType, results, "check-122517");
|
||||
_Details.Add(results);
|
||||
}
|
||||
{
|
||||
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)}");
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, Record> GetWorkItems(IEnumerable<WorkItem> workItems, bool keepRelations)
|
||||
{
|
||||
ReadOnlyDictionary<int, Record> results;
|
||||
Dictionary<int, WorkItem> keyValuePairs = new();
|
||||
foreach (WorkItem workItem in workItems)
|
||||
keyValuePairs.Add(workItem.Id, workItem);
|
||||
results = GetKeyValuePairs(new(keyValuePairs), keepRelations);
|
||||
return results;
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, bool keepRelations)
|
||||
{
|
||||
Dictionary<int, Record> results = new();
|
||||
Record record;
|
||||
List<bool> nests = new();
|
||||
WorkItem? parentWorkItem;
|
||||
ReadOnlyCollection<Record> childRecords;
|
||||
ReadOnlyCollection<Record> relatedRecords;
|
||||
ReadOnlyCollection<Record> successorRecords;
|
||||
foreach (KeyValuePair<int, WorkItem> keyValuePair in keyValuePairs)
|
||||
{
|
||||
nests.Clear();
|
||||
if (keyValuePair.Value.Parent is null)
|
||||
parentWorkItem = null;
|
||||
else
|
||||
_ = keyValuePairs.TryGetValue(keyValuePair.Value.Parent.Value, out parentWorkItem);
|
||||
try
|
||||
{
|
||||
childRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Child", nests, keepRelations); // Forward
|
||||
relatedRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Related", nests, keepRelations); // Related
|
||||
successorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Successor", nests, keepRelations); // Forward
|
||||
// predecessorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Predecessor", nests, keepRelations); // Reverse
|
||||
record = Record.Get(keyValuePair.Value, parentWorkItem, childRecords, relatedRecords, successorRecords, keepRelations);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
record = new(keyValuePair.Value, parentWorkItem, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>());
|
||||
}
|
||||
results.Add(keyValuePair.Key, record);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> FeatureCheckIterationPath122508(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType)
|
||||
{
|
||||
List<Record> results = new();
|
||||
Record record;
|
||||
List<string> violations = new();
|
||||
List<string> collection = new();
|
||||
ReadOnlyCollection<Record> records;
|
||||
ReadOnlyCollection<Record> maxIterationPaths;
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
record = keyValuePair.Value;
|
||||
if (record.WorkItem.State is "Removed")
|
||||
continue;
|
||||
if (!record.WorkItem.IterationPath.Contains('\\'))
|
||||
continue;
|
||||
if (record.WorkItem.WorkItemType != workItemType)
|
||||
continue;
|
||||
collection.Clear();
|
||||
violations.Clear();
|
||||
if (record.Children is null || record.Children.Length == 0)
|
||||
continue;
|
||||
records = FilterChildren(workItemTypes, record);
|
||||
maxIterationPaths = GetMaxIterationPaths122508(records);
|
||||
foreach (Record r in maxIterationPaths)
|
||||
{
|
||||
if (string.IsNullOrEmpty(r.WorkItem.IterationPath) || record.WorkItem.IterationPath == r.WorkItem.IterationPath)
|
||||
continue;
|
||||
violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.IterationPath};");
|
||||
}
|
||||
if (violations.Count > 0)
|
||||
{
|
||||
collection.Insert(0, string.Empty);
|
||||
collection.Insert(0, $"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}");
|
||||
lines.AddRange(collection);
|
||||
violations.Insert(0, $"<a target='_blank' href='{url}{record.WorkItem.Id}'>IterationPath</a>:{record.WorkItem.IterationPath};");
|
||||
results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations)));
|
||||
}
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetMaxIterationPaths122508(ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Record> results;
|
||||
List<Record>? collection;
|
||||
Dictionary<string, List<Record>> keyValuePairs = new();
|
||||
foreach (Record record in records)
|
||||
{
|
||||
if (!keyValuePairs.TryGetValue(record.WorkItem.IterationPath, out collection))
|
||||
{
|
||||
keyValuePairs.Add(record.WorkItem.IterationPath, new());
|
||||
if (!keyValuePairs.TryGetValue(record.WorkItem.IterationPath, out collection))
|
||||
throw new Exception();
|
||||
|
||||
}
|
||||
collection.Add(record);
|
||||
}
|
||||
string? max = keyValuePairs.Keys.Max();
|
||||
results = string.IsNullOrEmpty(max) ? new() : keyValuePairs[max];
|
||||
return results.AsReadOnly();
|
||||
}
|
||||
|
||||
private static void WriteFiles(IFileRead fileRead, string destinationDirectory, List<FileInfo> fileInfoCollection, ReadOnlyCollection<string> lines, string _, ReadOnlyCollection<Record> records, string fileName)
|
||||
{
|
||||
string markdown = string.Join(Environment.NewLine, lines);
|
||||
string markdownFile = Path.Combine(destinationDirectory, $"{fileName}.md");
|
||||
string markdownOld = !File.Exists(markdownFile) ? string.Empty : File.ReadAllText(markdownFile);
|
||||
if (markdown != markdownOld)
|
||||
File.WriteAllText(markdownFile, markdown);
|
||||
if (!fileRead.IsEAFHosted)
|
||||
fileInfoCollection.Add(new(markdownFile));
|
||||
string html = CommonMark.CommonMarkConverter.Convert(markdown).Replace("<a href", "<a target='_blank' href");
|
||||
string htmlFile = Path.Combine(destinationDirectory, $"{fileName}.html");
|
||||
string htmlOld = !File.Exists(htmlFile) ? string.Empty : File.ReadAllText(htmlFile);
|
||||
if (html != htmlOld)
|
||||
File.WriteAllText(htmlFile, html);
|
||||
if (!fileRead.IsEAFHosted)
|
||||
fileInfoCollection.Add(new(htmlFile));
|
||||
string json = JsonSerializer.Serialize(records, new JsonSerializerOptions() { WriteIndented = true });
|
||||
string jsonFile = Path.Combine(destinationDirectory, $"{fileName}.json");
|
||||
string jsonOld = !File.Exists(jsonFile) ? string.Empty : File.ReadAllText(jsonFile);
|
||||
if (json != jsonOld)
|
||||
File.WriteAllText(jsonFile, json);
|
||||
if (!fileRead.IsEAFHosted)
|
||||
fileInfoCollection.Add(new(jsonFile));
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> FeatureCheckTag122514(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType)
|
||||
{
|
||||
List<Record> results = new();
|
||||
Record record;
|
||||
List<string> collection = new();
|
||||
List<string> violations = new();
|
||||
ReadOnlyCollection<Record> records;
|
||||
ReadOnlyCollection<Record> recordsNotMatching;
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
record = keyValuePair.Value;
|
||||
if (record.WorkItem.State is "Removed")
|
||||
continue;
|
||||
if (record.WorkItem.WorkItemType != workItemType)
|
||||
continue;
|
||||
collection.Clear();
|
||||
violations.Clear();
|
||||
if (record.Children is null || record.Children.Length == 0)
|
||||
continue;
|
||||
if (string.IsNullOrEmpty(record.WorkItem.Tags))
|
||||
recordsNotMatching = new(new Record[] { record });
|
||||
else
|
||||
{
|
||||
records = FilterChildren(workItemTypes, record);
|
||||
recordsNotMatching = GetWorkItemsNotMatching122514(record, records);
|
||||
if (!string.IsNullOrEmpty(record.WorkItem.Tags) && recordsNotMatching.Count == 0)
|
||||
continue;
|
||||
}
|
||||
collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}");
|
||||
collection.Add(string.Empty);
|
||||
foreach (Record r in recordsNotMatching)
|
||||
collection.Add($"- [ ] [{r.WorkItem}]({url}{r.WorkItem}) {nameof(record.WorkItem.Tags)} != {record.WorkItem.Tags}");
|
||||
collection.Add(string.Empty);
|
||||
lines.AddRange(collection);
|
||||
violations.Add($"<a target='_blank' href='{url}{record.WorkItem.Id}'>Tag</a>:{record.WorkItem.Tags};");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.Tags};");
|
||||
results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations)));
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> FilterChildren(ReadOnlyCollection<string> workItemTypes, Record record)
|
||||
{
|
||||
List<Record> results = new();
|
||||
FilterChildren(workItemTypes, record, results);
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static void FilterChildren(ReadOnlyCollection<string> workItemTypes, Record record, List<Record> results)
|
||||
{
|
||||
if (record.Children is not null)
|
||||
{
|
||||
foreach (Record r in record.Children)
|
||||
{
|
||||
if (!workItemTypes.Contains(r.WorkItem.WorkItemType))
|
||||
continue;
|
||||
results.Add(r);
|
||||
FilterChildren(workItemTypes, r, results);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetWorkItemsNotMatching122514(Record record, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Record> results = new();
|
||||
string[] segments;
|
||||
string[] parentTags = record.WorkItem.Tags.Split(';').Select(l => l.Trim()).ToArray();
|
||||
foreach (Record r in records)
|
||||
{
|
||||
segments = string.IsNullOrEmpty(r.WorkItem.Tags) ? Array.Empty<string>() : r.WorkItem.Tags.Split(';').Select(l => l.Trim()).ToArray();
|
||||
if (segments.Length > 0 && parentTags.Any(l => segments.Contains(l)))
|
||||
continue;
|
||||
results.Add(r);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> FeatureCheckPriority126169(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType)
|
||||
{
|
||||
List<Record> results = new();
|
||||
Record record;
|
||||
List<string> collection = new();
|
||||
List<string> violations = new();
|
||||
ReadOnlyCollection<Record> records;
|
||||
ReadOnlyCollection<Record> recordsNotMatching;
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
record = keyValuePair.Value;
|
||||
if (record.WorkItem.State is "Removed")
|
||||
continue;
|
||||
if (record.WorkItem.WorkItemType != workItemType)
|
||||
continue;
|
||||
collection.Clear();
|
||||
violations.Clear();
|
||||
if (record.Children is null || record.Children.Length == 0)
|
||||
continue;
|
||||
records = FilterChildren(workItemTypes, record);
|
||||
recordsNotMatching = GetWorkItemsNotMatching126169(record, records);
|
||||
if (recordsNotMatching.Count == 0)
|
||||
continue;
|
||||
collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}");
|
||||
collection.Add(string.Empty);
|
||||
collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.Priority)} != {record.WorkItem.Priority}");
|
||||
collection.Add(string.Empty);
|
||||
lines.AddRange(collection);
|
||||
violations.Add($"<a target='_blank' href='{url}{record.WorkItem.Id}'>Priority</a>:{record.WorkItem.Priority};");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.Priority};");
|
||||
results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations)));
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetWorkItemsNotMatching126169(Record record, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Record> results = new();
|
||||
foreach (Record r in records)
|
||||
{
|
||||
if (record.WorkItem.Priority is null)
|
||||
{
|
||||
results.Add(record);
|
||||
break;
|
||||
}
|
||||
if (r.WorkItem.Priority == record.WorkItem.Priority.Value)
|
||||
continue;
|
||||
results.Add(r);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> FeatureCheckState123066(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType)
|
||||
{
|
||||
List<Record> results = new();
|
||||
Record record;
|
||||
List<string> collection = new();
|
||||
List<string> violations = new();
|
||||
ReadOnlyCollection<Record> records;
|
||||
ReadOnlyCollection<Record> recordsNotMatching;
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
record = keyValuePair.Value;
|
||||
if (record.WorkItem.State is "Removed")
|
||||
continue;
|
||||
if (record.WorkItem.WorkItemType != workItemType)
|
||||
continue;
|
||||
collection.Clear();
|
||||
violations.Clear();
|
||||
if (record.Children is null || record.Children.Length == 0)
|
||||
continue;
|
||||
records = FilterChildren(workItemTypes, record);
|
||||
recordsNotMatching = GetWorkItemsNotMatching123066(record, records);
|
||||
if (recordsNotMatching.Count == 0)
|
||||
continue;
|
||||
collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}");
|
||||
collection.Add(string.Empty);
|
||||
collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.State)} != {record.WorkItem.State}");
|
||||
collection.Add(string.Empty);
|
||||
lines.AddRange(collection);
|
||||
violations.Add($"<a target='_blank' href='{url}{record.WorkItem.Id}'>State</a>:{record.WorkItem.State};");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.State};");
|
||||
results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations)));
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetWorkItemsNotMatching123066(Record record, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Record> results = new();
|
||||
int check;
|
||||
int state = GetState(record.WorkItem);
|
||||
List<KeyValuePair<int, Record>> collection = new();
|
||||
foreach (Record r in records)
|
||||
{
|
||||
if (r.WorkItem.State is "Removed")
|
||||
continue;
|
||||
check = GetState(r.WorkItem);
|
||||
if (check == state)
|
||||
continue;
|
||||
collection.Add(new(check, r));
|
||||
}
|
||||
if (collection.Count > 0)
|
||||
{
|
||||
KeyValuePair<int, Record>[] notNewState = (from l in collection where l.Value.WorkItem.State != "New" select l).ToArray();
|
||||
if (notNewState.Length == 0 && record.WorkItem.State is "New" or "Active")
|
||||
collection.Clear();
|
||||
else if (notNewState.Length > 0)
|
||||
{
|
||||
int minimum = notNewState.Min(l => l.Key);
|
||||
if (minimum == state)
|
||||
collection.Clear();
|
||||
else if (minimum == 1 && record.WorkItem.State == "New")
|
||||
collection.Clear();
|
||||
else if (notNewState.Length > 0 && record.WorkItem.State == "Active")
|
||||
collection.Clear();
|
||||
}
|
||||
}
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in collection.OrderByDescending(l => l.Key))
|
||||
results.Add(keyValuePair.Value);
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static 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();
|
||||
Record record;
|
||||
List<string> collection = new();
|
||||
List<string> violations = new();
|
||||
ReadOnlyCollection<Record> records;
|
||||
ReadOnlyCollection<Record> recordsNotMatching;
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
record = keyValuePair.Value;
|
||||
if (record.WorkItem.State is "Removed")
|
||||
continue;
|
||||
if (record.WorkItem.WorkItemType != workItemType)
|
||||
continue;
|
||||
collection.Clear();
|
||||
violations.Clear();
|
||||
if (record.Children is null || record.Children.Length == 0)
|
||||
continue;
|
||||
records = FilterChildren(workItemTypes, record);
|
||||
recordsNotMatching = GetWorkItemsNotMatching123067(record, records);
|
||||
if (recordsNotMatching.Count == 0)
|
||||
continue;
|
||||
collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}");
|
||||
collection.Add(string.Empty);
|
||||
collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.State)} != {record.WorkItem.State}");
|
||||
collection.Add(string.Empty);
|
||||
lines.AddRange(collection);
|
||||
violations.Add($"<a target='_blank' href='{url}{record.WorkItem.Id}'>State</a>:{record.WorkItem.State};");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.State};");
|
||||
results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations)));
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetWorkItemsNotMatching123067(Record record, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Record> results = new();
|
||||
int check;
|
||||
int state = GetState(record.WorkItem);
|
||||
List<KeyValuePair<int, Record>> collection = new();
|
||||
foreach (Record r in records)
|
||||
{
|
||||
if (r.WorkItem.State is "Removed")
|
||||
continue;
|
||||
check = GetState(r.WorkItem);
|
||||
if (check == state)
|
||||
continue;
|
||||
collection.Add(new(check, r));
|
||||
}
|
||||
if (collection.Count > 0)
|
||||
{
|
||||
KeyValuePair<int, Record>[] notNewState = (from l in collection where l.Value.WorkItem.State != "New" select l).ToArray();
|
||||
if (notNewState.Length == 0 && record.WorkItem.State is "New" or "Active")
|
||||
collection.Clear();
|
||||
else if (notNewState.Length > 0)
|
||||
{
|
||||
int minimum = notNewState.Min(l => l.Key);
|
||||
if (minimum == state)
|
||||
collection.Clear();
|
||||
else if (minimum == 1 && record.WorkItem.State == "New")
|
||||
collection.Clear();
|
||||
else if (notNewState.Length > 0 && record.WorkItem.State == "Active")
|
||||
collection.Clear();
|
||||
}
|
||||
}
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in collection.OrderByDescending(l => l.Key))
|
||||
results.Add(keyValuePair.Value);
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> FeatureCheckStart122517(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> keyValuePairs, string workItemType)
|
||||
{
|
||||
List<Record> results = new();
|
||||
Record record;
|
||||
List<string> collection = new();
|
||||
List<string> violations = new();
|
||||
ReadOnlyCollection<Record> records;
|
||||
ReadOnlyCollection<Record> recordsNotMatching;
|
||||
foreach (KeyValuePair<int, Record> keyValuePair in keyValuePairs)
|
||||
{
|
||||
record = keyValuePair.Value;
|
||||
if (record.WorkItem.State is "Removed")
|
||||
continue;
|
||||
if (record.WorkItem.WorkItemType != workItemType)
|
||||
continue;
|
||||
collection.Clear();
|
||||
violations.Clear();
|
||||
if (record.Children is null || record.Children.Length == 0)
|
||||
continue;
|
||||
if (record.WorkItem.StartDate is null)
|
||||
continue;
|
||||
records = FilterChildren(workItemTypes, record);
|
||||
recordsNotMatching = GetWorkItemsNotMatching122517(record, records);
|
||||
if (recordsNotMatching.Count == 0)
|
||||
continue;
|
||||
collection.Add($"## {record.WorkItem.AssignedTo} - {record.WorkItem.Id} - {record.WorkItem.Title}");
|
||||
collection.Add(string.Empty);
|
||||
collection.Add($"- [{record.WorkItem.Id}]({url}{record.WorkItem.Id})");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
collection.Add($"- [ ] [{r.WorkItem.Id}]({url}{r.WorkItem.Id}) {nameof(record.WorkItem.ActivatedDate)} != {record.WorkItem.ActivatedDate}");
|
||||
collection.Add(string.Empty);
|
||||
lines.AddRange(collection);
|
||||
violations.Add($"<a target='_blank' href='{url}{record.WorkItem.Id}'>StartDate</a>:{record.WorkItem.StartDate};");
|
||||
foreach (Record r in recordsNotMatching)
|
||||
violations.Add($"<a target='_blank' href='{url}{r.WorkItem.Id}'>{r.WorkItem.Id}</a>:{r.WorkItem.ActivatedDate};");
|
||||
results.Add(Record.GetWithoutNesting(record, string.Join(" ", violations)));
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<Record> GetWorkItemsNotMatching122517(Record record, ReadOnlyCollection<Record> records)
|
||||
{
|
||||
List<Record> results = new();
|
||||
if (record.WorkItem.StartDate is null)
|
||||
throw new Exception();
|
||||
DateTime dateTime = record.WorkItem.StartDate.Value;
|
||||
List<KeyValuePair<long, Record>> collection = new();
|
||||
foreach (Record r in records)
|
||||
{
|
||||
if (r.WorkItem.State is "Removed")
|
||||
continue;
|
||||
if (r.WorkItem.ActivatedDate is null)
|
||||
continue;
|
||||
if (dateTime >= r.WorkItem.ActivatedDate.Value)
|
||||
continue;
|
||||
collection.Add(new(r.WorkItem.ActivatedDate.Value.Ticks, r));
|
||||
}
|
||||
foreach (KeyValuePair<long, Record> keyValuePair in collection.OrderBy(l => l.Key))
|
||||
results.Add(keyValuePair.Value);
|
||||
return new(results);
|
||||
}
|
||||
|
||||
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();
|
||||
Description? description;
|
||||
JsonSerializerOptions jsonSerializerOptions = new() { NumberHandling = JsonNumberHandling.AllowReadingFromString | JsonNumberHandling.WriteAsString };
|
||||
foreach (JsonElement jsonElement in jsonElements)
|
||||
{
|
||||
if (jsonElement.ValueKind != JsonValueKind.Object)
|
||||
throw new Exception();
|
||||
description = JsonSerializer.Deserialize<Description>(jsonElement.ToString(), jsonSerializerOptions);
|
||||
if (description is null)
|
||||
continue;
|
||||
results.Add(description);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
}
|
@ -11,7 +11,9 @@ using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
|
||||
namespace Adaptation.FileHandlers.json;
|
||||
@ -111,42 +113,115 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
|
||||
#nullable enable
|
||||
|
||||
private static string GetParamCase(string value)
|
||||
{
|
||||
string result;
|
||||
StringBuilder stringBuilder = new(value);
|
||||
List<Match> matches = new();
|
||||
MatchCollection matchCollection = Regex.Matches(value, "([A-Z]+(.))");
|
||||
foreach (object? item in matchCollection)
|
||||
{
|
||||
if (item is not Match match)
|
||||
continue;
|
||||
matches.Add(match);
|
||||
}
|
||||
for (int i = matches.Count - 1; i > -1; i--)
|
||||
_ = stringBuilder.Insert(matches[i].Index, '-');
|
||||
string[] segments = Regex.Split(stringBuilder.ToString().ToLower(), "[\\s!?.,@:;|\\\\/\"'`£$%\\^&*{}[\\]()<>~#+\\-=_¬]+");
|
||||
result = string.Join("-", segments).Trim('-');
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ReadOnlyDictionary<int, WorkItem> GetKeyValuePairs(ReadOnlyCollection<Value> valueWithReqCollection)
|
||||
{
|
||||
Dictionary<int, WorkItem> results = new();
|
||||
Fields fields;
|
||||
WorkItem workItem;
|
||||
Relation relation;
|
||||
string[] segments;
|
||||
List<Relation> relations;
|
||||
WorkItems.Attribute attributes;
|
||||
foreach (Value value in valueWithReqCollection)
|
||||
{
|
||||
relations = new();
|
||||
fields = value.Fields;
|
||||
if (value.Relations is not null)
|
||||
{
|
||||
foreach (WIQL.Relation r in value.Relations)
|
||||
{
|
||||
segments = r?.Attributes is null ? Array.Empty<string>() : r.URL.Split('/');
|
||||
if (segments.Length < 2)
|
||||
continue;
|
||||
if (r?.Attributes is null)
|
||||
continue;
|
||||
if (!int.TryParse(segments[segments.Length - 1], out int id))
|
||||
continue;
|
||||
attributes = new(r.Attributes.IsLocked, r.Attributes.Name, null, null, null);
|
||||
relation = new(attributes, id, r.Rel);
|
||||
relations.Add(relation);
|
||||
}
|
||||
}
|
||||
workItem = new(activatedDate: fields.MicrosoftVSTSCommonActivatedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonActivatedDate,
|
||||
areaPath: fields.SystemAreaPath,
|
||||
assignedTo: fields.SystemAssignedTo?.DisplayName,
|
||||
businessValue: fields.MicrosoftVSTSCommonBusinessValue is null or 0 ? null : (long)fields.MicrosoftVSTSCommonBusinessValue,
|
||||
changedDate: fields.SystemChangedDate,
|
||||
closedDate: fields.MicrosoftVSTSCommonClosedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonClosedDate,
|
||||
commentCount: fields.SystemCommentCount,
|
||||
createdDate: fields.SystemCreatedDate,
|
||||
description: fields.SystemDescription,
|
||||
effort: fields.MicrosoftVSTSSchedulingEffort is null or 0 ? null : (long)fields.MicrosoftVSTSSchedulingEffort,
|
||||
id: value.Id,
|
||||
iterationPath: fields.SystemIterationPath,
|
||||
parent: fields.SystemParent == 0 ? null : fields.SystemParent,
|
||||
priority: fields.MicrosoftVSTSCommonPriority == 0 ? null : fields.MicrosoftVSTSCommonPriority,
|
||||
relations: relations.ToArray(),
|
||||
remainingWork: fields.MicrosoftVSTSSchedulingRemainingWork is null ? null : (long)fields.MicrosoftVSTSSchedulingRemainingWork,
|
||||
requester: fields.CustomRequester?.DisplayName,
|
||||
resolvedDate: fields.MicrosoftVSTSCommonResolvedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonResolvedDate,
|
||||
revision: value.Rev,
|
||||
riskReductionMinusOpportunityEnablement: fields.CustomRRminusOE is null or 0 ? null : (long)fields.CustomRRminusOE,
|
||||
startDate: fields.MicrosoftVSTSSchedulingStartDate == DateTime.MinValue ? null : fields.MicrosoftVSTSSchedulingStartDate,
|
||||
state: fields.SystemState,
|
||||
storyPoints: fields.MicrosoftVSTSSchedulingStoryPoints is null ? null : (long)fields.MicrosoftVSTSSchedulingStoryPoints,
|
||||
tags: fields.SystemTags,
|
||||
targetDate: fields.MicrosoftVSTSSchedulingTargetDate == DateTime.MinValue ? null : fields.MicrosoftVSTSSchedulingTargetDate,
|
||||
timeCriticality: fields.MicrosoftVSTSCommonTimeCriticality is null or 0 ? null : (long)fields.MicrosoftVSTSCommonTimeCriticality,
|
||||
title: fields.SystemTitle.Trim(),
|
||||
violation: null,
|
||||
weightedShortestJobFirst: fields.CustomWSJF is null or 0 ? null : (long)fields.CustomWSJF,
|
||||
workItemType: fields.SystemWorkItemType);
|
||||
results.Add(workItem.Id, workItem);
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
private static ReadOnlyCollection<WorkItem> GetWorkItems(ReadOnlyCollection<Value> valueWithReqCollection)
|
||||
{
|
||||
List<WorkItem> results = new();
|
||||
Fields fields;
|
||||
WorkItem workItem;
|
||||
foreach (Value value in valueWithReqCollection)
|
||||
Relation relation;
|
||||
string parameterTitle;
|
||||
List<Relation> relations;
|
||||
WorkItem? relationWorkItem;
|
||||
WorkItems.Attribute attributes;
|
||||
ReadOnlyDictionary<int, WorkItem> keyValuePairs = GetKeyValuePairs(valueWithReqCollection);
|
||||
foreach (KeyValuePair<int, WorkItem> keyValuePair in keyValuePairs)
|
||||
{
|
||||
fields = value.Fields;
|
||||
workItem = new(fields.MicrosoftVSTSCommonActivatedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonActivatedDate,
|
||||
fields.SystemAreaPath,
|
||||
fields.SystemAssignedTo?.DisplayName,
|
||||
fields.MicrosoftVSTSCommonBusinessValue is null or 0 ? null : (long)fields.MicrosoftVSTSCommonBusinessValue,
|
||||
fields.SystemChangedDate,
|
||||
fields.MicrosoftVSTSCommonClosedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonClosedDate,
|
||||
fields.SystemCommentCount,
|
||||
fields.SystemCreatedDate,
|
||||
fields.SystemDescription,
|
||||
fields.MicrosoftVSTSSchedulingEffort is null or 0 ? null : (long)fields.MicrosoftVSTSSchedulingEffort,
|
||||
value.Id,
|
||||
fields.SystemIterationPath,
|
||||
fields.SystemParent == 0 ? null : fields.SystemParent,
|
||||
fields.MicrosoftVSTSCommonPriority == 0 ? null : fields.MicrosoftVSTSCommonPriority,
|
||||
value.Relations,
|
||||
fields.CustomRequester?.DisplayName,
|
||||
fields.MicrosoftVSTSCommonResolvedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonResolvedDate,
|
||||
value.Rev,
|
||||
fields.CustomRRminusOE is null or 0 ? null : (long)fields.CustomRRminusOE,
|
||||
fields.MicrosoftVSTSSchedulingStartDate == DateTime.MinValue ? null : fields.MicrosoftVSTSSchedulingStartDate,
|
||||
fields.SystemState,
|
||||
fields.SystemTags,
|
||||
fields.MicrosoftVSTSSchedulingTargetDate == DateTime.MinValue ? null : fields.MicrosoftVSTSSchedulingTargetDate,
|
||||
fields.MicrosoftVSTSCommonTimeCriticality is null or 0 ? null : (long)fields.MicrosoftVSTSCommonTimeCriticality,
|
||||
fields.SystemTitle,
|
||||
null,
|
||||
fields.CustomWSJF is null or 0 ? null : (long)fields.CustomWSJF,
|
||||
fields.SystemWorkItemType);
|
||||
relations = new();
|
||||
if (keyValuePair.Value.Relations is not null)
|
||||
{
|
||||
foreach (Relation r in keyValuePair.Value.Relations)
|
||||
{
|
||||
if (!keyValuePairs.TryGetValue(r.Id, out relationWorkItem))
|
||||
continue;
|
||||
parameterTitle = GetParamCase(relationWorkItem.Title);
|
||||
attributes = new(r.Attributes.IsLocked, r.Attributes.Name, parameterTitle, relationWorkItem.State, relationWorkItem.WorkItemType);
|
||||
relation = new(attributes, r.Id, r.Rel);
|
||||
relations.Add(relation);
|
||||
}
|
||||
}
|
||||
workItem = WorkItem.Get(keyValuePair.Value, relations.ToArray());
|
||||
results.Add(workItem);
|
||||
}
|
||||
return new(results);
|
||||
@ -173,8 +248,7 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
string old;
|
||||
string checkFile;
|
||||
string? pathRoot;
|
||||
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
|
||||
string json = JsonSerializer.Serialize(workItems, jsonSerializerOptions);
|
||||
string json = JsonSerializer.Serialize(workItems.ToArray(), WorkItemCollectionSourceGenerationContext.Default.WorkItemArray);
|
||||
foreach (string alternateTargetFolder in alternateTargetFolders)
|
||||
{
|
||||
if (alternateTargetFolder == fileConnectorConfiguration.TargetFileLocation)
|
||||
@ -238,7 +312,10 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
string subject = string.Concat("Exception:", _CellInstanceConnectionName);
|
||||
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
|
||||
try
|
||||
{ _SMTP.SendHighPriorityEmailMessage(subject, body); }
|
||||
{
|
||||
_SMTP.SendHighPriorityEmailMessage(subject, body);
|
||||
File.WriteAllText(".email", body);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
try
|
||||
@ -253,15 +330,18 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
string subject = string.Concat("Exception:", _CellInstanceConnectionName);
|
||||
string body = string.Concat(exception.Message, Environment.NewLine, Environment.NewLine, exception.StackTrace);
|
||||
try
|
||||
{ _SMTP.SendHighPriorityEmailMessage(subject, body); }
|
||||
{
|
||||
_SMTP.SendHighPriorityEmailMessage(subject, body);
|
||||
File.WriteAllText(".email", body);
|
||||
}
|
||||
catch (Exception) { }
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0060
|
||||
private void MoveJson(string reportFullPath, DateTime dateTime)
|
||||
#pragma warning restore IDE0060
|
||||
{
|
||||
if (dateTime == DateTime.MinValue)
|
||||
throw new ArgumentNullException(nameof(dateTime));
|
||||
string json = File.ReadAllText(reportFullPath);
|
||||
Value? value = JsonSerializer.Deserialize<Value>(json);
|
||||
if (value is null)
|
||||
@ -278,7 +358,9 @@ public class FileRead : Shared.FileRead, IFileRead
|
||||
private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime)
|
||||
{
|
||||
Tuple<string, Test[], JsonElement[], List<FileInfo>> results;
|
||||
_Logistics = new Logistics(reportFullPath, $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};");
|
||||
string[] lines = new string[] { string.Empty, "NUM_DATA_ROWS", $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};" };
|
||||
ProcessDataStandardFormat processDataStandardFormat = ProcessDataStandardFormat.GetProcessDataStandardFormat(reportFullPath, lines);
|
||||
_Logistics = new Logistics(reportFullPath, processDataStandardFormat);
|
||||
if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0)
|
||||
MoveJson(reportFullPath, dateTime);
|
||||
results = new(_Logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), new List<FileInfo>());
|
||||
|
@ -19,7 +19,6 @@ public class ProcessData : IProcessData
|
||||
Logistics logistics,
|
||||
List<FileInfo> fileInfoCollection)
|
||||
{
|
||||
fileInfoCollection.Clear();
|
||||
_Details = new List<object>();
|
||||
Parse();
|
||||
}
|
||||
|
@ -6,15 +6,15 @@
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Infineon - 122508 - Feature iteration should be set to max of children</title>
|
||||
<link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/styles/122508.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/122508.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2025-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>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -56,7 +56,7 @@
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
initIndex("/markdown/check-122508.json?v=2024-10-07-18-50");
|
||||
initIndex("/markdown/check-122508.json?v=2025-01-22-10-49");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
@ -6,15 +6,15 @@
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Infineon - 122514 - Features and children must have a Tag</title>
|
||||
<link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/styles/122514.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/122514.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2025-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>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -56,7 +56,7 @@
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
initIndex("/markdown/check-122514.json?v=2024-10-07-18-50");
|
||||
initIndex("/markdown/check-122514.json?v=2025-01-22-10-49");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
@ -6,15 +6,15 @@
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Infineon - 122517 - Feature start date should be min activated date of children</title>
|
||||
<link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/styles/122517.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/122517.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2025-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>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -56,7 +56,7 @@
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
initIndex("/markdown/check-122517.json?v=2024-10-07-18-50");
|
||||
initIndex("/markdown/check-122517.json?v=2025-01-22-10-49");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
@ -6,15 +6,15 @@
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Infineon - 123066 - When children of a Feature are not New Feature must also not be New</title>
|
||||
<link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/styles/123066.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/123066.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2025-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>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -56,7 +56,7 @@
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
initIndex("/markdown/check-123066.json?v=2024-10-07-18-50");
|
||||
initIndex("/markdown/check-123066.json?v=2025-01-22-10-49");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
@ -6,15 +6,15 @@
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Infineon - 123067 - WIP</title>
|
||||
<link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/styles/123067.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/123067.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2025-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>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -56,7 +56,7 @@
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
initIndex("/markdown/check-123067.json?v=2024-10-07-18-50");
|
||||
initIndex("/markdown/check-123067.json?v=2025-01-22-10-49");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
@ -6,15 +6,15 @@
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Infineon - 126169 - Children of a Feature should have the same priority</title>
|
||||
<link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/styles/126169.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/126169.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2025-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>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -56,7 +56,7 @@
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
initIndex("/markdown/check-126169.json?v=2024-10-07-18-50");
|
||||
initIndex("/markdown/check-126169.json?v=2025-01-22-10-49");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
@ -6,15 +6,15 @@
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Infineon - Business Value</title>
|
||||
<link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/styles/business.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/business.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2025-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>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -59,7 +59,7 @@ What is the relative value to the Customer or business?
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
initIndex("/markdown/bugs-features-with-parents.json?v=2024-10-07-18-50", "https://oi-metrology-viewer-prod.mes.infineon.com:4438/api/v1/ado/", "business", "Value", "Business Value", "/markdown/PI4-Results/business.json?v=2024-10-07-18-50");
|
||||
initIndex("/markdown/bugs-features-with-parents.json?v=2025-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");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
109
Adaptation/FileHandlers/json/StaticSite/html/cod-b.html
Normal file
109
Adaptation/FileHandlers/json/StaticSite/html/cod-b.html
Normal file
@ -0,0 +1,109 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Infineon - Cost of Delay (CoD) (see @SCALE formula)</title>
|
||||
<link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<link href="/styles/cod.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<script src="/js/scripts/jquery-1.6.4.min.js"></script>
|
||||
<script src="/js/scripts/jquery.signalR-2.4.3.min.js"></script>
|
||||
<script src="/signalr/hubs"></script>
|
||||
<script src="/js/cod-b.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> -
|
||||
<span id="th-span"> </span>
|
||||
<button id="toggle">Toggle</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
</ul>
|
||||
<p class="navbar-text navbar-right">
|
||||
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid body-content" style="margin-top: 40px; margin-left: 15px;">
|
||||
<div id="HeaderGridDiv">
|
||||
<table id="HeaderGrid" border="1"></table>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div id="AllGridDiv">
|
||||
<table id="AllGrid"></table>
|
||||
</div>
|
||||
|
||||
<textarea id="AllTextarea" rows="20" cols="147"></textarea>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
const username = '';
|
||||
const machineId = '';
|
||||
const fromHtml = true;
|
||||
const signalRUrl = "/signalr";
|
||||
const windowLocationHRef = window.location.href;
|
||||
const apiUrl = "https://eaf-dev.mes.infineon.com/api/v1/ado/";
|
||||
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."
|
||||
};
|
||||
const e = {
|
||||
page: "effort",
|
||||
description: "Effort",
|
||||
th: "Effort",
|
||||
span: "Effort"
|
||||
};
|
||||
const w = {
|
||||
page: "wsjf",
|
||||
description: "WSJF",
|
||||
th: "Weightest Shortest Job First calculation (WSJF)",
|
||||
span: "Weightest Shortest Job First calculation (see @SCALE formula)"
|
||||
};
|
||||
initIndex(fromHtml, username, machineId, windowLocationHRef, workItems, b, r, t, c, e, w, apiUrl, signalRUrl);
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
97
Adaptation/FileHandlers/json/StaticSite/html/cod.html
Normal file
97
Adaptation/FileHandlers/json/StaticSite/html/cod.html
Normal file
@ -0,0 +1,97 @@
|
||||
<!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=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/styles/effort.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/effort.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2025-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>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -55,7 +55,7 @@
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
initIndex("/markdown/bugs-features-with-parents.json?v=2024-10-07-18-50", "https://oi-metrology-viewer-prod.mes.infineon.com:4438/api/v1/ado/", "effort", "Effort", "Effort", "/markdown/PI4-Results/effort.json?v=2024-10-07-18-50");
|
||||
initIndex("/markdown/bugs-features-with-parents.json?v=2025-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");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
@ -6,15 +6,15 @@
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Infineon - Risk Reduction and/or Opportunity Enablement</title>
|
||||
<link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/styles/risk.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/risk.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2025-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>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -59,7 +59,7 @@ What else does this do for our business?
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
initIndex("/markdown/bugs-features-with-parents.json?v=2024-10-07-18-50", "https://oi-metrology-viewer-prod.mes.infineon.com:4438/api/v1/ado/", "risk", "Risk", "Risk Reduction and/or Opportunity Enablement", "/markdown/PI4-Results/risk.json?v=2024-10-07-18-50");
|
||||
initIndex("/markdown/bugs-features-with-parents.json?v=2025-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");
|
||||
});
|
||||
|
||||
</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=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/styles/time.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/time.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2025-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>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -32,7 +32,6 @@ How does user/business value decay over time?
|
||||
• Is there a fixed deadline?
|
||||
• Will they wait for us or move to another Solution?
|
||||
• What is the current effect on Customer satisfaction?
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
@ -60,7 +59,7 @@ How does user/business value decay over time?
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
initIndex("/markdown/bugs-features-with-parents.json?v=2024-10-07-18-50", "https://oi-metrology-viewer-prod.mes.infineon.com:4438/api/v1/ado/", "time", "Critical", "Time Criticality", "/markdown/PI4-Results/time.json?v=2024-10-07-18-50");
|
||||
initIndex("/markdown/bugs-features-with-parents.json?v=2025-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");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
@ -6,15 +6,15 @@
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Infineon - User Stor(ies) with parents</title>
|
||||
<link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/styles/with-parents.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/with-parents.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2025-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>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -55,7 +55,7 @@
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
initIndex("/markdown/bugs-user-stories-with-parents.json?v=2024-10-07-18-50");
|
||||
initIndex("/markdown/bugs-user-stories-with-parents.json?v=2025-01-22-10-49");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
64
Adaptation/FileHandlers/json/StaticSite/html/wsjf-b.html
Normal file
64
Adaptation/FileHandlers/json/StaticSite/html/wsjf-b.html
Normal file
@ -0,0 +1,64 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Infineon - Result of Weightest Shortest Job First calculation (see @SCALE formula)</title>
|
||||
<link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2025-01-22-10-49" 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>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<div class="navbar-brand">
|
||||
<span id="siteHeader"> </span> - Result of Weightest Shortest Job First calculation (see @SCALE formula)
|
||||
</div>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
</ul>
|
||||
<p class="navbar-text navbar-right">
|
||||
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container-fluid body-content" style="margin-top: 40px; margin-left: 15px;">
|
||||
|
||||
<div style="height: 550px;" id="HeaderGridDiv">
|
||||
<table id="HeaderGrid" border="1"></table>
|
||||
</div>
|
||||
|
||||
<br />
|
||||
|
||||
<div id="AllGridDiv">
|
||||
<table id="AllGrid"></table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
initIndex("/markdown/bugs-features-with-parents.json?v=2025-01-22-10-49", "https://eaf-dev.mes.infineon.com/api/v1/ado/");
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
34
Adaptation/FileHandlers/json/StaticSite/html/wsjf-c.html
Normal file
34
Adaptation/FileHandlers/json/StaticSite/html/wsjf-c.html
Normal file
@ -0,0 +1,34 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>SignalR Simple Chat</title>
|
||||
<style type="text/css">
|
||||
.container {
|
||||
background-color: #99CCFF;
|
||||
border: thick solid #808080;
|
||||
padding: 20px;
|
||||
margin: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<input type="text" id="message" />
|
||||
<input type="button" id="sendmessage" value="Send" />
|
||||
<input type="hidden" id="displayname" />
|
||||
<ul id="discussion"></ul>
|
||||
</div>
|
||||
<script src="/js/scripts/jquery-1.6.4.min.js"></script>
|
||||
<script src="/js/scripts/jquery.signalR-2.4.3.min.js"></script>
|
||||
<script src="/signalr/hubs"></script>
|
||||
<script src="/js/wsjf-c.js?v=2025-01-22-10-49" type="text/javascript"></script>
|
||||
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
initIndex("/signalr", "https://eaf-dev.mes.infineon.com/api/v1/ado/");
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -6,15 +6,15 @@
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Infineon - Result of Weightest Shortest Job First calculation (see @SCALE formula)</title>
|
||||
<link href="/styles/bootstrap.min.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2024-10-07-18-50" rel="stylesheet" />
|
||||
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/igniteui/css/structure/infragistics.css?v=2025-01-22-10-49" rel="stylesheet" />
|
||||
<link href="/styles/wsjf.css?no-cache=2024-10-04-08-34" rel="stylesheet" />
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-ui.min.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/wsjf.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.core.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.lob.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/igniteui/js/infragistics.dv.js?v=2024-10-07-18-50" type="text/javascript"></script>
|
||||
<script src="/js/jquery-3.6.0.min.js?v=2025-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>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -55,7 +55,7 @@
|
||||
<script>
|
||||
|
||||
$(document).ready(function () {
|
||||
initIndex("/markdown/bugs-features-with-parents.json?v=2024-10-07-18-50", "https://oi-metrology-viewer-prod.mes.infineon.com:4438/api/v1/ado/");
|
||||
initIndex("/markdown/bugs-features-with-parents.json?v=2025-01-22-10-49", "https://eaf-dev.mes.infineon.com/api/v1/ado/");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
@ -1,5 +1,5 @@
|
||||
function compareFunction(a, b) {
|
||||
if (a.CoD === null || b.CoD === null) {
|
||||
if (a.CoD == undefined || b.CoD == undefined) {
|
||||
return b.Id - a.Id;
|
||||
} else {
|
||||
return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
@ -7,12 +7,12 @@ function compareFunction(a, b) {
|
||||
}
|
||||
|
||||
function showOne(rowData) {
|
||||
if (rowData == null)
|
||||
if (rowData == undefined)
|
||||
return;
|
||||
var data = [];
|
||||
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||
for (const property in rowData) {
|
||||
if (rowData[property] == null)
|
||||
if (rowData[property] == undefined)
|
||||
continue;
|
||||
data.push({ name: property, value: rowData[property].toString() });
|
||||
}
|
||||
@ -26,7 +26,7 @@ function showOne(rowData) {
|
||||
|
||||
function loadOne() {
|
||||
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||
if (selectedRow == null)
|
||||
if (selectedRow == undefined)
|
||||
return;
|
||||
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||
showOne(rowData);
|
||||
@ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) {
|
||||
|
||||
function getState(state) {
|
||||
var result;
|
||||
if (state == null)
|
||||
if (state == undefined)
|
||||
result = "9-Null";
|
||||
else if (state === "New")
|
||||
result = `1-${state}`;
|
||||
@ -62,7 +62,7 @@ function getPriority(workItemType, priority) {
|
||||
var result;
|
||||
if (workItemType === "Bug")
|
||||
result = "0-Bug";
|
||||
else if (priority == null || priority === 0)
|
||||
else if (priority == undefined || priority === 0)
|
||||
result = "9-Null";
|
||||
else if (priority === 1)
|
||||
result = `${priority}-High`;
|
||||
@ -78,14 +78,14 @@ function getPriority(workItemType, priority) {
|
||||
}
|
||||
|
||||
function updateRecordCoD(workItem) {
|
||||
if (workItem !== null) {
|
||||
if (workItem.Effort === null)
|
||||
if (workItem != undefined) {
|
||||
if (workItem.Effort == undefined)
|
||||
workItem.Effort = 10123;
|
||||
if (workItem.BusinessValue === null)
|
||||
if (workItem.BusinessValue == undefined)
|
||||
workItem.BusinessValue = 99999;
|
||||
if (workItem.TimeCriticality === null)
|
||||
if (workItem.TimeCriticality == undefined)
|
||||
workItem.TimeCriticality = 99999;
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement === null)
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement == undefined)
|
||||
workItem.RiskReductionMinusOpportunityEnablement = 99999;
|
||||
workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue;
|
||||
}
|
||||
@ -97,7 +97,7 @@ function updateRecordOther(workItem) {
|
||||
}
|
||||
|
||||
function updateRecordParent(parent, workItem) {
|
||||
if (parent === null) {
|
||||
if (parent == undefined) {
|
||||
workItem["ParentId"] = 9999999;
|
||||
workItem["ParentTitle"] = null;
|
||||
workItem["ParentState"] = null;
|
||||
|
@ -1,5 +1,5 @@
|
||||
function compareFunction(a, b) {
|
||||
if (a.CoD === null || b.CoD === null) {
|
||||
if (a.CoD == undefined || b.CoD == undefined) {
|
||||
return b.Id - a.Id;
|
||||
} else {
|
||||
return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
@ -7,12 +7,12 @@ function compareFunction(a, b) {
|
||||
}
|
||||
|
||||
function showOne(rowData) {
|
||||
if (rowData == null)
|
||||
if (rowData == undefined)
|
||||
return;
|
||||
var data = [];
|
||||
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||
for (const property in rowData) {
|
||||
if (rowData[property] == null)
|
||||
if (rowData[property] == undefined)
|
||||
continue;
|
||||
data.push({ name: property, value: rowData[property].toString() });
|
||||
}
|
||||
@ -26,7 +26,7 @@ function showOne(rowData) {
|
||||
|
||||
function loadOne() {
|
||||
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||
if (selectedRow == null)
|
||||
if (selectedRow == undefined)
|
||||
return;
|
||||
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||
showOne(rowData);
|
||||
@ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) {
|
||||
|
||||
function getState(state) {
|
||||
var result;
|
||||
if (state == null)
|
||||
if (state == undefined)
|
||||
result = "9-Null";
|
||||
else if (state === "New")
|
||||
result = `1-${state}`;
|
||||
@ -62,7 +62,7 @@ function getPriority(workItemType, priority) {
|
||||
var result;
|
||||
if (workItemType === "Bug")
|
||||
result = "0-Bug";
|
||||
else if (priority == null || priority === 0)
|
||||
else if (priority == undefined || priority === 0)
|
||||
result = "9-Null";
|
||||
else if (priority === 1)
|
||||
result = `${priority}-High`;
|
||||
@ -78,14 +78,14 @@ function getPriority(workItemType, priority) {
|
||||
}
|
||||
|
||||
function updateRecordCoD(workItem) {
|
||||
if (workItem !== null) {
|
||||
if (workItem.Effort === null)
|
||||
if (workItem != undefined) {
|
||||
if (workItem.Effort == undefined)
|
||||
workItem.Effort = 10123;
|
||||
if (workItem.BusinessValue === null)
|
||||
if (workItem.BusinessValue == undefined)
|
||||
workItem.BusinessValue = 99999;
|
||||
if (workItem.TimeCriticality === null)
|
||||
if (workItem.TimeCriticality == undefined)
|
||||
workItem.TimeCriticality = 99999;
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement === null)
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement == undefined)
|
||||
workItem.RiskReductionMinusOpportunityEnablement = 99999;
|
||||
workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue;
|
||||
}
|
||||
@ -97,7 +97,7 @@ function updateRecordOther(workItem) {
|
||||
}
|
||||
|
||||
function updateRecordParent(parent, workItem) {
|
||||
if (parent === null) {
|
||||
if (parent == undefined) {
|
||||
workItem["ParentId"] = 9999999;
|
||||
workItem["ParentTitle"] = null;
|
||||
workItem["ParentState"] = null;
|
||||
|
@ -1,5 +1,5 @@
|
||||
function compareFunction(a, b) {
|
||||
if (a.CoD === null || b.CoD === null) {
|
||||
if (a.CoD == undefined || b.CoD == undefined) {
|
||||
return b.Id - a.Id;
|
||||
} else {
|
||||
return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
@ -7,12 +7,12 @@ function compareFunction(a, b) {
|
||||
}
|
||||
|
||||
function showOne(rowData) {
|
||||
if (rowData == null)
|
||||
if (rowData == undefined)
|
||||
return;
|
||||
var data = [];
|
||||
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||
for (const property in rowData) {
|
||||
if (rowData[property] == null)
|
||||
if (rowData[property] == undefined)
|
||||
continue;
|
||||
data.push({ name: property, value: rowData[property].toString() });
|
||||
}
|
||||
@ -26,7 +26,7 @@ function showOne(rowData) {
|
||||
|
||||
function loadOne() {
|
||||
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||
if (selectedRow == null)
|
||||
if (selectedRow == undefined)
|
||||
return;
|
||||
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||
showOne(rowData);
|
||||
@ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) {
|
||||
|
||||
function getState(state) {
|
||||
var result;
|
||||
if (state == null)
|
||||
if (state == undefined)
|
||||
result = "9-Null";
|
||||
else if (state === "New")
|
||||
result = `1-${state}`;
|
||||
@ -62,7 +62,7 @@ function getPriority(workItemType, priority) {
|
||||
var result;
|
||||
if (workItemType === "Bug")
|
||||
result = "0-Bug";
|
||||
else if (priority == null || priority === 0)
|
||||
else if (priority == undefined || priority === 0)
|
||||
result = "9-Null";
|
||||
else if (priority === 1)
|
||||
result = `${priority}-High`;
|
||||
@ -78,14 +78,14 @@ function getPriority(workItemType, priority) {
|
||||
}
|
||||
|
||||
function updateRecordCoD(workItem) {
|
||||
if (workItem !== null) {
|
||||
if (workItem.Effort === null)
|
||||
if (workItem != undefined) {
|
||||
if (workItem.Effort == undefined)
|
||||
workItem.Effort = 10123;
|
||||
if (workItem.BusinessValue === null)
|
||||
if (workItem.BusinessValue == undefined)
|
||||
workItem.BusinessValue = 99999;
|
||||
if (workItem.TimeCriticality === null)
|
||||
if (workItem.TimeCriticality == undefined)
|
||||
workItem.TimeCriticality = 99999;
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement === null)
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement == undefined)
|
||||
workItem.RiskReductionMinusOpportunityEnablement = 99999;
|
||||
workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue;
|
||||
}
|
||||
@ -97,7 +97,7 @@ function updateRecordOther(workItem) {
|
||||
}
|
||||
|
||||
function updateRecordParent(parent, workItem) {
|
||||
if (parent === null) {
|
||||
if (parent == undefined) {
|
||||
workItem["ParentId"] = 9999999;
|
||||
workItem["ParentTitle"] = null;
|
||||
workItem["ParentState"] = null;
|
||||
|
@ -1,5 +1,5 @@
|
||||
function compareFunction(a, b) {
|
||||
if (a.CoD === null || b.CoD === null) {
|
||||
if (a.CoD == undefined || b.CoD == undefined) {
|
||||
return b.Id - a.Id;
|
||||
} else {
|
||||
return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
@ -7,12 +7,12 @@ function compareFunction(a, b) {
|
||||
}
|
||||
|
||||
function showOne(rowData) {
|
||||
if (rowData == null)
|
||||
if (rowData == undefined)
|
||||
return;
|
||||
var data = [];
|
||||
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||
for (const property in rowData) {
|
||||
if (rowData[property] == null)
|
||||
if (rowData[property] == undefined)
|
||||
continue;
|
||||
data.push({ name: property, value: rowData[property].toString() });
|
||||
}
|
||||
@ -26,7 +26,7 @@ function showOne(rowData) {
|
||||
|
||||
function loadOne() {
|
||||
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||
if (selectedRow == null)
|
||||
if (selectedRow == undefined)
|
||||
return;
|
||||
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||
showOne(rowData);
|
||||
@ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) {
|
||||
|
||||
function getState(state) {
|
||||
var result;
|
||||
if (state == null)
|
||||
if (state == undefined)
|
||||
result = "9-Null";
|
||||
else if (state === "New")
|
||||
result = `1-${state}`;
|
||||
@ -62,7 +62,7 @@ function getPriority(workItemType, priority) {
|
||||
var result;
|
||||
if (workItemType === "Bug")
|
||||
result = "0-Bug";
|
||||
else if (priority == null || priority === 0)
|
||||
else if (priority == undefined || priority === 0)
|
||||
result = "9-Null";
|
||||
else if (priority === 1)
|
||||
result = `${priority}-High`;
|
||||
@ -78,14 +78,14 @@ function getPriority(workItemType, priority) {
|
||||
}
|
||||
|
||||
function updateRecordCoD(workItem) {
|
||||
if (workItem !== null) {
|
||||
if (workItem.Effort === null)
|
||||
if (workItem != undefined) {
|
||||
if (workItem.Effort == undefined)
|
||||
workItem.Effort = 10123;
|
||||
if (workItem.BusinessValue === null)
|
||||
if (workItem.BusinessValue == undefined)
|
||||
workItem.BusinessValue = 99999;
|
||||
if (workItem.TimeCriticality === null)
|
||||
if (workItem.TimeCriticality == undefined)
|
||||
workItem.TimeCriticality = 99999;
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement === null)
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement == undefined)
|
||||
workItem.RiskReductionMinusOpportunityEnablement = 99999;
|
||||
workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue;
|
||||
}
|
||||
@ -97,7 +97,7 @@ function updateRecordOther(workItem) {
|
||||
}
|
||||
|
||||
function updateRecordParent(parent, workItem) {
|
||||
if (parent === null) {
|
||||
if (parent == undefined) {
|
||||
workItem["ParentId"] = 9999999;
|
||||
workItem["ParentTitle"] = null;
|
||||
workItem["ParentState"] = null;
|
||||
|
@ -1,5 +1,5 @@
|
||||
function compareFunction(a, b) {
|
||||
if (a.CoD === null || b.CoD === null) {
|
||||
if (a.CoD == undefined || b.CoD == undefined) {
|
||||
return b.Id - a.Id;
|
||||
} else {
|
||||
return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
@ -7,12 +7,12 @@ function compareFunction(a, b) {
|
||||
}
|
||||
|
||||
function showOne(rowData) {
|
||||
if (rowData == null)
|
||||
if (rowData == undefined)
|
||||
return;
|
||||
var data = [];
|
||||
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||
for (const property in rowData) {
|
||||
if (rowData[property] == null)
|
||||
if (rowData[property] == undefined)
|
||||
continue;
|
||||
data.push({ name: property, value: rowData[property].toString() });
|
||||
}
|
||||
@ -26,7 +26,7 @@ function showOne(rowData) {
|
||||
|
||||
function loadOne() {
|
||||
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||
if (selectedRow == null)
|
||||
if (selectedRow == undefined)
|
||||
return;
|
||||
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||
showOne(rowData);
|
||||
@ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) {
|
||||
|
||||
function getState(state) {
|
||||
var result;
|
||||
if (state == null)
|
||||
if (state == undefined)
|
||||
result = "9-Null";
|
||||
else if (state === "New")
|
||||
result = `1-${state}`;
|
||||
@ -62,7 +62,7 @@ function getPriority(workItemType, priority) {
|
||||
var result;
|
||||
if (workItemType === "Bug")
|
||||
result = "0-Bug";
|
||||
else if (priority == null || priority === 0)
|
||||
else if (priority == undefined || priority === 0)
|
||||
result = "9-Null";
|
||||
else if (priority === 1)
|
||||
result = `${priority}-High`;
|
||||
@ -78,14 +78,14 @@ function getPriority(workItemType, priority) {
|
||||
}
|
||||
|
||||
function updateRecordCoD(workItem) {
|
||||
if (workItem !== null) {
|
||||
if (workItem.Effort === null)
|
||||
if (workItem != undefined) {
|
||||
if (workItem.Effort == undefined)
|
||||
workItem.Effort = 10123;
|
||||
if (workItem.BusinessValue === null)
|
||||
if (workItem.BusinessValue == undefined)
|
||||
workItem.BusinessValue = 99999;
|
||||
if (workItem.TimeCriticality === null)
|
||||
if (workItem.TimeCriticality == undefined)
|
||||
workItem.TimeCriticality = 99999;
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement === null)
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement == undefined)
|
||||
workItem.RiskReductionMinusOpportunityEnablement = 99999;
|
||||
workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue;
|
||||
}
|
||||
@ -97,7 +97,7 @@ function updateRecordOther(workItem) {
|
||||
}
|
||||
|
||||
function updateRecordParent(parent, workItem) {
|
||||
if (parent === null) {
|
||||
if (parent == undefined) {
|
||||
workItem["ParentId"] = 9999999;
|
||||
workItem["ParentTitle"] = null;
|
||||
workItem["ParentState"] = null;
|
||||
|
@ -1,5 +1,5 @@
|
||||
function compareFunction(a, b) {
|
||||
if (a.CoD === null || b.CoD === null) {
|
||||
if (a.CoD == undefined || b.CoD == undefined) {
|
||||
return b.Id - a.Id;
|
||||
} else {
|
||||
return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
@ -7,12 +7,12 @@ function compareFunction(a, b) {
|
||||
}
|
||||
|
||||
function showOne(rowData) {
|
||||
if (rowData == null)
|
||||
if (rowData == undefined)
|
||||
return;
|
||||
var data = [];
|
||||
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||
for (const property in rowData) {
|
||||
if (rowData[property] == null)
|
||||
if (rowData[property] == undefined)
|
||||
continue;
|
||||
data.push({ name: property, value: rowData[property].toString() });
|
||||
}
|
||||
@ -26,7 +26,7 @@ function showOne(rowData) {
|
||||
|
||||
function loadOne() {
|
||||
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||
if (selectedRow == null)
|
||||
if (selectedRow == undefined)
|
||||
return;
|
||||
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||
showOne(rowData);
|
||||
@ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) {
|
||||
|
||||
function getState(state) {
|
||||
var result;
|
||||
if (state == null)
|
||||
if (state == undefined)
|
||||
result = "9-Null";
|
||||
else if (state === "New")
|
||||
result = `1-${state}`;
|
||||
@ -62,7 +62,7 @@ function getPriority(workItemType, priority) {
|
||||
var result;
|
||||
if (workItemType === "Bug")
|
||||
result = "0-Bug";
|
||||
else if (priority == null || priority === 0)
|
||||
else if (priority == undefined || priority === 0)
|
||||
result = "9-Null";
|
||||
else if (priority === 1)
|
||||
result = `${priority}-High`;
|
||||
@ -78,14 +78,14 @@ function getPriority(workItemType, priority) {
|
||||
}
|
||||
|
||||
function updateRecordCoD(workItem) {
|
||||
if (workItem !== null) {
|
||||
if (workItem.Effort === null)
|
||||
if (workItem != undefined) {
|
||||
if (workItem.Effort == undefined)
|
||||
workItem.Effort = 10123;
|
||||
if (workItem.BusinessValue === null)
|
||||
if (workItem.BusinessValue == undefined)
|
||||
workItem.BusinessValue = 99999;
|
||||
if (workItem.TimeCriticality === null)
|
||||
if (workItem.TimeCriticality == undefined)
|
||||
workItem.TimeCriticality = 99999;
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement === null)
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement == undefined)
|
||||
workItem.RiskReductionMinusOpportunityEnablement = 99999;
|
||||
workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue;
|
||||
}
|
||||
@ -97,7 +97,7 @@ function updateRecordOther(workItem) {
|
||||
}
|
||||
|
||||
function updateRecordParent(parent, workItem) {
|
||||
if (parent === null) {
|
||||
if (parent == undefined) {
|
||||
workItem["ParentId"] = 9999999;
|
||||
workItem["ParentTitle"] = null;
|
||||
workItem["ParentState"] = null;
|
||||
|
@ -1,22 +1,22 @@
|
||||
var _apiUrl = null;
|
||||
|
||||
function compareFunction(a, b) {
|
||||
if (a.BusinessValue === null || b.BusinessValue === null) {
|
||||
if (a.BusinessValue == undefined || b.BusinessValue == undefined) {
|
||||
var aPollValue = a.PollValue.split('-');
|
||||
var bPollValue = b.PollValue.split('-');
|
||||
return bPollValue[0].trim() - aPollValue[0].trim() || b.State[0] - a.State[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
return bPollValue[0] - aPollValue[0] || b.State[0] - a.State[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
} else {
|
||||
return b.BusinessValue - a.BusinessValue || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
}
|
||||
}
|
||||
|
||||
function showOne(rowData) {
|
||||
if (rowData == null)
|
||||
if (rowData == undefined)
|
||||
return;
|
||||
var data = [];
|
||||
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||
for (const property in rowData) {
|
||||
if (rowData[property] == null)
|
||||
if (rowData[property] == undefined)
|
||||
continue;
|
||||
data.push({ name: property, value: rowData[property].toString() });
|
||||
}
|
||||
@ -30,7 +30,7 @@ function showOne(rowData) {
|
||||
|
||||
function loadOne() {
|
||||
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||
if (selectedRow == null)
|
||||
if (selectedRow == undefined)
|
||||
return;
|
||||
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||
showOne(rowData);
|
||||
@ -45,7 +45,7 @@ function detailSelectionChangedRunInfo(evt, ui) {
|
||||
|
||||
function getState(state) {
|
||||
var result;
|
||||
if (state == null)
|
||||
if (state == undefined)
|
||||
result = "9-Null";
|
||||
else if (state === "New")
|
||||
result = `1-${state}`;
|
||||
@ -66,7 +66,7 @@ function getPriority(workItemType, priority) {
|
||||
var result;
|
||||
if (workItemType === "Bug")
|
||||
result = "0-Bug";
|
||||
else if (priority == null || priority === 0)
|
||||
else if (priority == undefined || priority === 0)
|
||||
result = "9-Null";
|
||||
else if (priority === 1)
|
||||
result = `${priority}-High`;
|
||||
@ -81,45 +81,34 @@ function getPriority(workItemType, priority) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function getInversePriority(priority) {
|
||||
function getPollValue(description, pollValue) {
|
||||
var result;
|
||||
if (priority == null || priority === 0)
|
||||
result = "0.000";
|
||||
else if (priority === 1)
|
||||
result = "3.000";
|
||||
else if (priority === 2)
|
||||
result = "2.000";
|
||||
else if (priority === 3)
|
||||
result = "1.000";
|
||||
if (pollValue == undefined || pollValue.BusinessValue == undefined || pollValue.BusinessValue.InverseAverage == undefined)
|
||||
result = "";
|
||||
else if (pollValue.BusinessValue.InverseAverage >= 4)
|
||||
result = `${pollValue.BusinessValue.InverseAverage} - 1-Highest (Most ${description}) - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.BusinessValue.InverseAverage >= 3)
|
||||
result = `${pollValue.BusinessValue.InverseAverage} - 2-High - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.BusinessValue.InverseAverage >= 2)
|
||||
result = `${pollValue.BusinessValue.InverseAverage} - 3-Medium - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.BusinessValue.InverseAverage >= 1)
|
||||
result = `${pollValue.BusinessValue.InverseAverage} - 4-Low - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.BusinessValue.InverseAverage >= 0)
|
||||
result = `${pollValue.BusinessValue.InverseAverage} - 5-Lowest - ${pollValue.Count} Vote(s)`;
|
||||
else
|
||||
result = "0.000";
|
||||
return result;
|
||||
}
|
||||
|
||||
function getPollValue(description, priority, priorityDisplay, pollValue) {
|
||||
var result;
|
||||
if (pollValue === undefined || pollValue.Records.length === undefined || pollValue.Records.length === 0 || pollValue.Average === null)
|
||||
result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority';
|
||||
else if (pollValue.Average > 2)
|
||||
result = `${pollValue.Average} - 1-High (Most ${description}) - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.Average > 1)
|
||||
result = `${pollValue.Average} - 2-Medium - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.Average > 0)
|
||||
result = `${pollValue.Average} - 3-Low - ${pollValue.Count} Vote(s)`;
|
||||
else
|
||||
result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority';
|
||||
result = "";
|
||||
return result;
|
||||
}
|
||||
|
||||
function updateRecordCoD(workItem) {
|
||||
if (workItem !== null) {
|
||||
if (workItem.Effort === null)
|
||||
if (workItem != undefined) {
|
||||
if (workItem.Effort == undefined)
|
||||
workItem.Effort = 10123;
|
||||
if (workItem.BusinessValue === null)
|
||||
if (workItem.BusinessValue == undefined)
|
||||
workItem.BusinessValue = 99999;
|
||||
if (workItem.TimeCriticality === null)
|
||||
if (workItem.TimeCriticality == undefined)
|
||||
workItem.TimeCriticality = 99999;
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement === null)
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement == undefined)
|
||||
workItem.RiskReductionMinusOpportunityEnablement = 99999;
|
||||
workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue;
|
||||
}
|
||||
@ -128,12 +117,12 @@ function updateRecordCoD(workItem) {
|
||||
function updateRecordOther(workItem, dataB, description) {
|
||||
workItem["State"] = getState(workItem["State"]);
|
||||
var priority = getPriority(workItem["WorkItemType"], workItem["Priority"]);
|
||||
workItem["PollValue"] = getPollValue(description, workItem["Priority"], priority, dataB[workItem.Id]);
|
||||
workItem["PollValue"] = getPollValue(description, dataB[workItem.Id]);
|
||||
workItem["Priority"] = priority;
|
||||
}
|
||||
|
||||
function updateRecordParent(parent, workItem) {
|
||||
if (parent === null) {
|
||||
if (parent == undefined) {
|
||||
workItem["ParentId"] = 9999999;
|
||||
workItem["ParentTitle"] = null;
|
||||
workItem["ParentState"] = null;
|
||||
@ -183,13 +172,46 @@ function sendValue(element, page, id) {
|
||||
});
|
||||
}
|
||||
|
||||
function getFibonacciValue(average) {
|
||||
var result;
|
||||
if (average >= 7)
|
||||
result = 34;
|
||||
else if (average >= 6)
|
||||
result = 21;
|
||||
else if (average >= 5)
|
||||
result = 13;
|
||||
else if (average >= 4)
|
||||
result = 8;
|
||||
else if (average >= 3)
|
||||
result = 5;
|
||||
else if (average >= 2)
|
||||
result = 3;
|
||||
else if (average >= 1)
|
||||
result = 2;
|
||||
else if (average >= 0)
|
||||
result = 1;
|
||||
else
|
||||
result = "";
|
||||
return result;
|
||||
}
|
||||
|
||||
function setRecords(workItems, page, description, th) {
|
||||
var record;
|
||||
var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Up</th><th>Down</th><th>Poll Value</th><th>" + th + "</th></tr>";
|
||||
var array = [];
|
||||
var count = "";
|
||||
var select = "";
|
||||
var average = "";
|
||||
var fibonacciValue = "";
|
||||
var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Poll Average</th><th>Fibonacci</th><th>Poll Description</th><th>Vote(s)</th><th>" + th + "</th><th>Up</th><th>Down</th></tr>";
|
||||
const element = document.getElementById("HeaderGrid");
|
||||
for (var i = 0; i < workItems.length; i++) {
|
||||
record = workItems[i];
|
||||
var length = record.BusinessValue === null ? "" : record.BusinessValue.toString().length;
|
||||
array = record.PollValue.split('-')
|
||||
average = array.length > 0 ? array[0] : "";
|
||||
fibonacciValue = getFibonacciValue(average);
|
||||
select = array.length > 2 ? array[1] + '-' + array[2] : "";
|
||||
count = array.length > 3 ? array[3].trim().split(' ')[0] : "";
|
||||
var length = record.BusinessValue == undefined ? "" : record.BusinessValue.toString().length;
|
||||
html += "<tr><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" +
|
||||
"</td><td>" + record.ParentTitle +
|
||||
"</td><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" +
|
||||
@ -201,14 +223,19 @@ function setRecords(workItems, page, description, th) {
|
||||
"</td><td>" +
|
||||
'<select onchange="sendValue(this, \'' + page + '\', ' + record.Id + ')">' +
|
||||
'<option value="9">Unknown</option>' +
|
||||
'<option value="1">High (Most ' + description + ')</option>' +
|
||||
'<option value="2">Medium</option>' +
|
||||
'<option value="3">Low</option>' +
|
||||
'<option value="1">Highest (Most ' + description + ')</option>' +
|
||||
'<option value="2">High</option>' +
|
||||
'<option value="3">Medium</option>' +
|
||||
'<option value="4">Low</option>' +
|
||||
'<option value="5">Lowest</option>' +
|
||||
"</select>" +
|
||||
"</td><td>" + average +
|
||||
"</td><td>" + fibonacciValue +
|
||||
"</td><td>" + select +
|
||||
"</td><td>" + count +
|
||||
"</td><td>" + length + " - " + record.BusinessValue +
|
||||
"</td><td><a href='#' class='up'>Up</a>" +
|
||||
"</td><td><a href='#' class='down'>Down</a>" +
|
||||
"</td><td>" + record.PollValue +
|
||||
"</td><td>" + length + " - " + record.BusinessValue +
|
||||
"</td></tr>";
|
||||
}
|
||||
element.innerHTML = html.replaceAll(">null<", "> <");
|
||||
|
17114
Adaptation/FileHandlers/json/StaticSite/js/cod-b.js
Normal file
17114
Adaptation/FileHandlers/json/StaticSite/js/cod-b.js
Normal file
File diff suppressed because one or more lines are too long
@ -1,22 +1,22 @@
|
||||
var _apiUrl = null;
|
||||
|
||||
function compareFunction(a, b) {
|
||||
if (a.Effort === null || b.Effort === null) {
|
||||
if (a.Effort == undefined || b.Effort == undefined) {
|
||||
var aPollValue = a.PollValue.split('-');
|
||||
var bPollValue = b.PollValue.split('-');
|
||||
return bPollValue[0].trim() - aPollValue[0].trim() || b.State[0] - a.State[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
return bPollValue[0] - aPollValue[0] || b.State[0] - a.State[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
} else {
|
||||
return b.Effort - a.Effort || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
}
|
||||
}
|
||||
|
||||
function showOne(rowData) {
|
||||
if (rowData == null)
|
||||
if (rowData == undefined)
|
||||
return;
|
||||
var data = [];
|
||||
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||
for (const property in rowData) {
|
||||
if (rowData[property] == null)
|
||||
if (rowData[property] == undefined)
|
||||
continue;
|
||||
data.push({ name: property, value: rowData[property].toString() });
|
||||
}
|
||||
@ -30,7 +30,7 @@ function showOne(rowData) {
|
||||
|
||||
function loadOne() {
|
||||
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||
if (selectedRow == null)
|
||||
if (selectedRow == undefined)
|
||||
return;
|
||||
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||
showOne(rowData);
|
||||
@ -45,7 +45,7 @@ function detailSelectionChangedRunInfo(evt, ui) {
|
||||
|
||||
function getState(state) {
|
||||
var result;
|
||||
if (state == null)
|
||||
if (state == undefined)
|
||||
result = "9-Null";
|
||||
else if (state === "New")
|
||||
result = `1-${state}`;
|
||||
@ -66,7 +66,7 @@ function getPriority(workItemType, priority) {
|
||||
var result;
|
||||
if (workItemType === "Bug")
|
||||
result = "0-Bug";
|
||||
else if (priority == null || priority === 0)
|
||||
else if (priority == undefined || priority === 0)
|
||||
result = "9-Null";
|
||||
else if (priority === 1)
|
||||
result = `${priority}-High`;
|
||||
@ -81,45 +81,34 @@ function getPriority(workItemType, priority) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function getInversePriority(priority) {
|
||||
function getPollValue(description, pollValue) {
|
||||
var result;
|
||||
if (priority == null || priority === 0)
|
||||
result = "0.000";
|
||||
else if (priority === 1)
|
||||
result = "3.000";
|
||||
else if (priority === 2)
|
||||
result = "2.000";
|
||||
else if (priority === 3)
|
||||
result = "1.000";
|
||||
if (pollValue == undefined || pollValue.Effort == undefined || pollValue.Effort.InverseAverage == undefined)
|
||||
result = "";
|
||||
else if (pollValue.Effort.InverseAverage >= 4)
|
||||
result = `${pollValue.Effort.InverseAverage} - 1-Highest (Most ${description}) - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.Effort.InverseAverage >= 3)
|
||||
result = `${pollValue.Effort.InverseAverage} - 2-High - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.Effort.InverseAverage >= 2)
|
||||
result = `${pollValue.Effort.InverseAverage} - 3-Medium - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.Effort.InverseAverage >= 1)
|
||||
result = `${pollValue.Effort.InverseAverage} - 4-Low - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.Effort.InverseAverage >= 0)
|
||||
result = `${pollValue.Effort.InverseAverage} - 5-Lowest - ${pollValue.Count} Vote(s)`;
|
||||
else
|
||||
result = "0.000";
|
||||
return result;
|
||||
}
|
||||
|
||||
function getPollValue(description, priority, priorityDisplay, pollValue) {
|
||||
var result;
|
||||
if (pollValue === undefined || pollValue.Records.length === undefined || pollValue.Records.length === 0 || pollValue.Average === null)
|
||||
result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority';
|
||||
else if (pollValue.Average > 2)
|
||||
result = `${pollValue.Average} - 1-High (Most ${description}) - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.Average > 1)
|
||||
result = `${pollValue.Average} - 2-Medium - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.Average > 0)
|
||||
result = `${pollValue.Average} - 3-Low - ${pollValue.Count} Vote(s)`;
|
||||
else
|
||||
result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority';
|
||||
result = "";
|
||||
return result;
|
||||
}
|
||||
|
||||
function updateRecordCoD(workItem) {
|
||||
if (workItem !== null) {
|
||||
if (workItem.Effort === null)
|
||||
if (workItem != undefined) {
|
||||
if (workItem.Effort == undefined)
|
||||
workItem.Effort = 10123;
|
||||
if (workItem.BusinessValue === null)
|
||||
if (workItem.BusinessValue == undefined)
|
||||
workItem.BusinessValue = 99999;
|
||||
if (workItem.TimeCriticality === null)
|
||||
if (workItem.TimeCriticality == undefined)
|
||||
workItem.TimeCriticality = 99999;
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement === null)
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement == undefined)
|
||||
workItem.RiskReductionMinusOpportunityEnablement = 99999;
|
||||
workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue;
|
||||
}
|
||||
@ -128,12 +117,12 @@ function updateRecordCoD(workItem) {
|
||||
function updateRecordOther(workItem, dataB, description) {
|
||||
workItem["State"] = getState(workItem["State"]);
|
||||
var priority = getPriority(workItem["WorkItemType"], workItem["Priority"]);
|
||||
workItem["PollValue"] = getPollValue(description, workItem["Priority"], priority, dataB[workItem.Id]);
|
||||
workItem["PollValue"] = getPollValue(description, dataB[workItem.Id]);
|
||||
workItem["Priority"] = priority;
|
||||
}
|
||||
|
||||
function updateRecordParent(parent, workItem) {
|
||||
if (parent === null) {
|
||||
if (parent == undefined) {
|
||||
workItem["ParentId"] = 9999999;
|
||||
workItem["ParentTitle"] = null;
|
||||
workItem["ParentState"] = null;
|
||||
@ -183,13 +172,46 @@ function sendValue(element, page, id) {
|
||||
});
|
||||
}
|
||||
|
||||
function getFibonacciValue(average) {
|
||||
var result;
|
||||
if (average >= 7)
|
||||
result = 34;
|
||||
else if (average >= 6)
|
||||
result = 21;
|
||||
else if (average >= 5)
|
||||
result = 13;
|
||||
else if (average >= 4)
|
||||
result = 8;
|
||||
else if (average >= 3)
|
||||
result = 5;
|
||||
else if (average >= 2)
|
||||
result = 3;
|
||||
else if (average >= 1)
|
||||
result = 2;
|
||||
else if (average >= 0)
|
||||
result = 1;
|
||||
else
|
||||
result = "";
|
||||
return result;
|
||||
}
|
||||
|
||||
function setRecords(workItems, page, description, th) {
|
||||
var record;
|
||||
var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Up</th><th>Down</th><th>Poll Value</th><th>" + th + "</th></tr>";
|
||||
var array = [];
|
||||
var count = "";
|
||||
var select = "";
|
||||
var average = "";
|
||||
var fibonacciValue = "";
|
||||
var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Poll Average</th><th>Fibonacci</th><th>Poll Description</th><th>Vote(s)</th><th>" + th + "</th><th>Up</th><th>Down</th></tr>";
|
||||
const element = document.getElementById("HeaderGrid");
|
||||
for (var i = 0; i < workItems.length; i++) {
|
||||
record = workItems[i];
|
||||
var length = record.Effort === null ? "" : record.Effort.toString().length;
|
||||
array = record.PollValue.split('-')
|
||||
average = array.length > 0 ? array[0] : "";
|
||||
fibonacciValue = getFibonacciValue(average);
|
||||
select = array.length > 2 ? array[1] + '-' + array[2] : "";
|
||||
count = array.length > 3 ? array[3].trim().split(' ')[0] : "";
|
||||
var length = record.Effort == undefined ? "" : record.Effort.toString().length;
|
||||
html += "<tr><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" +
|
||||
"</td><td>" + record.ParentTitle +
|
||||
"</td><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" +
|
||||
@ -201,14 +223,19 @@ function setRecords(workItems, page, description, th) {
|
||||
"</td><td>" +
|
||||
'<select onchange="sendValue(this, \'' + page + '\', ' + record.Id + ')">' +
|
||||
'<option value="9">Unknown</option>' +
|
||||
'<option value="1">High (Most ' + description + ')</option>' +
|
||||
'<option value="2">Medium</option>' +
|
||||
'<option value="3">Low</option>' +
|
||||
'<option value="1">Highest (Most ' + description + ')</option>' +
|
||||
'<option value="2">High</option>' +
|
||||
'<option value="3">Medium</option>' +
|
||||
'<option value="4">Low</option>' +
|
||||
'<option value="5">Lowest</option>' +
|
||||
"</select>" +
|
||||
"</td><td>" + average +
|
||||
"</td><td>" + fibonacciValue +
|
||||
"</td><td>" + select +
|
||||
"</td><td>" + count +
|
||||
"</td><td>" + length + " - " + record.Effort +
|
||||
"</td><td><a href='#' class='up'>Up</a>" +
|
||||
"</td><td><a href='#' class='down'>Down</a>" +
|
||||
"</td><td>" + record.PollValue +
|
||||
"</td><td>" + length + " - " + record.Effort +
|
||||
"</td></tr>";
|
||||
}
|
||||
element.innerHTML = html.replaceAll(">null<", "> <");
|
||||
|
9046
Adaptation/FileHandlers/json/StaticSite/js/jquery/v1.6.4/jquery.js
vendored
Normal file
9046
Adaptation/FileHandlers/json/StaticSite/js/jquery/v1.6.4/jquery.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
function compareFunction(a, b) {
|
||||
if (a.CoD === null || b.CoD === null) {
|
||||
if (a.CoD == undefined || b.CoD == undefined) {
|
||||
return b.Id - a.Id;
|
||||
} else {
|
||||
return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
@ -7,12 +7,12 @@ function compareFunction(a, b) {
|
||||
}
|
||||
|
||||
function showOne(rowData) {
|
||||
if (rowData == null)
|
||||
if (rowData == undefined)
|
||||
return;
|
||||
var data = [];
|
||||
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||
for (const property in rowData) {
|
||||
if (rowData[property] == null)
|
||||
if (rowData[property] == undefined)
|
||||
continue;
|
||||
data.push({ name: property, value: rowData[property].toString() });
|
||||
}
|
||||
@ -26,7 +26,7 @@ function showOne(rowData) {
|
||||
|
||||
function loadOne() {
|
||||
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||
if (selectedRow == null)
|
||||
if (selectedRow == undefined)
|
||||
return;
|
||||
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||
showOne(rowData);
|
||||
@ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) {
|
||||
|
||||
function getState(state) {
|
||||
var result;
|
||||
if (state == null)
|
||||
if (state == undefined)
|
||||
result = "9-Null";
|
||||
else if (state === "New")
|
||||
result = `1-${state}`;
|
||||
@ -62,7 +62,7 @@ function getPriority(workItemType, priority) {
|
||||
var result;
|
||||
if (workItemType === "Bug")
|
||||
result = "0-Bug";
|
||||
else if (priority == null || priority === 0)
|
||||
else if (priority == undefined || priority === 0)
|
||||
result = "9-Null";
|
||||
else if (priority === 1)
|
||||
result = `${priority}-High`;
|
||||
@ -78,14 +78,14 @@ function getPriority(workItemType, priority) {
|
||||
}
|
||||
|
||||
function updateRecordCoD(workItem) {
|
||||
if (workItem !== null) {
|
||||
if (workItem.Effort === null)
|
||||
if (workItem != undefined) {
|
||||
if (workItem.Effort == undefined)
|
||||
workItem.Effort = 10123;
|
||||
if (workItem.BusinessValue === null)
|
||||
if (workItem.BusinessValue == undefined)
|
||||
workItem.BusinessValue = 99999;
|
||||
if (workItem.TimeCriticality === null)
|
||||
if (workItem.TimeCriticality == undefined)
|
||||
workItem.TimeCriticality = 99999;
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement === null)
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement == undefined)
|
||||
workItem.RiskReductionMinusOpportunityEnablement = 99999;
|
||||
workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue;
|
||||
}
|
||||
@ -97,7 +97,7 @@ function updateRecordOther(workItem) {
|
||||
}
|
||||
|
||||
function updateRecordParent(parent, workItem) {
|
||||
if (parent === null) {
|
||||
if (parent == undefined) {
|
||||
workItem["ParentId"] = 9999999;
|
||||
workItem["ParentTitle"] = null;
|
||||
workItem["ParentState"] = null;
|
||||
|
@ -1,5 +1,5 @@
|
||||
function compareFunction(a, b) {
|
||||
if (a.CoD === null || b.CoD === null) {
|
||||
if (a.CoD == undefined || b.CoD == undefined) {
|
||||
return b.Id - a.Id;
|
||||
} else {
|
||||
return b.CoD - a.CoD || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
@ -7,12 +7,12 @@ function compareFunction(a, b) {
|
||||
}
|
||||
|
||||
function showOne(rowData) {
|
||||
if (rowData == null)
|
||||
if (rowData == undefined)
|
||||
return;
|
||||
var data = [];
|
||||
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||
for (const property in rowData) {
|
||||
if (rowData[property] == null)
|
||||
if (rowData[property] == undefined)
|
||||
continue;
|
||||
data.push({ name: property, value: rowData[property].toString() });
|
||||
}
|
||||
@ -26,7 +26,7 @@ function showOne(rowData) {
|
||||
|
||||
function loadOne() {
|
||||
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||
if (selectedRow == null)
|
||||
if (selectedRow == undefined)
|
||||
return;
|
||||
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||
showOne(rowData);
|
||||
@ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) {
|
||||
|
||||
function getState(state) {
|
||||
var result;
|
||||
if (state == null)
|
||||
if (state == undefined)
|
||||
result = "9-Null";
|
||||
else if (state === "New")
|
||||
result = `1-${state}`;
|
||||
@ -62,7 +62,7 @@ function getPriority(workItemType, priority) {
|
||||
var result;
|
||||
if (workItemType === "Bug")
|
||||
result = "0-Bug";
|
||||
else if (priority == null || priority === 0)
|
||||
else if (priority == undefined || priority === 0)
|
||||
result = "9-Null";
|
||||
else if (priority === 1)
|
||||
result = `${priority}-High`;
|
||||
@ -78,14 +78,14 @@ function getPriority(workItemType, priority) {
|
||||
}
|
||||
|
||||
function updateRecordCoD(workItem) {
|
||||
if (workItem !== null) {
|
||||
if (workItem.Effort === null)
|
||||
if (workItem != undefined) {
|
||||
if (workItem.Effort == undefined)
|
||||
workItem.Effort = 10123;
|
||||
if (workItem.BusinessValue === null)
|
||||
if (workItem.BusinessValue == undefined)
|
||||
workItem.BusinessValue = 99999;
|
||||
if (workItem.TimeCriticality === null)
|
||||
if (workItem.TimeCriticality == undefined)
|
||||
workItem.TimeCriticality = 99999;
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement === null)
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement == undefined)
|
||||
workItem.RiskReductionMinusOpportunityEnablement = 99999;
|
||||
workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue;
|
||||
}
|
||||
@ -97,7 +97,7 @@ function updateRecordOther(workItem) {
|
||||
}
|
||||
|
||||
function updateRecordParent(parent, workItem) {
|
||||
if (parent === null) {
|
||||
if (parent == undefined) {
|
||||
workItem["ParentId"] = 9999999;
|
||||
workItem["ParentTitle"] = null;
|
||||
workItem["ParentState"] = null;
|
||||
|
@ -1,22 +1,22 @@
|
||||
var _apiUrl = null;
|
||||
|
||||
function compareFunction(a, b) {
|
||||
if (a.RiskReductionMinusOpportunityEnablement === null || b.RiskReductionMinusOpportunityEnablement === null) {
|
||||
if (a.RiskReductionMinusOpportunityEnablement == undefined || b.RiskReductionMinusOpportunityEnablement == undefined) {
|
||||
var aPollValue = a.PollValue.split('-');
|
||||
var bPollValue = b.PollValue.split('-');
|
||||
return bPollValue[0].trim() - aPollValue[0].trim() || b.State[0] - a.State[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
return bPollValue[0] - aPollValue[0] || b.State[0] - a.State[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
} else {
|
||||
return b.RiskReductionMinusOpportunityEnablement - a.RiskReductionMinusOpportunityEnablement || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
}
|
||||
}
|
||||
|
||||
function showOne(rowData) {
|
||||
if (rowData == null)
|
||||
if (rowData == undefined)
|
||||
return;
|
||||
var data = [];
|
||||
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||
for (const property in rowData) {
|
||||
if (rowData[property] == null)
|
||||
if (rowData[property] == undefined)
|
||||
continue;
|
||||
data.push({ name: property, value: rowData[property].toString() });
|
||||
}
|
||||
@ -30,7 +30,7 @@ function showOne(rowData) {
|
||||
|
||||
function loadOne() {
|
||||
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||
if (selectedRow == null)
|
||||
if (selectedRow == undefined)
|
||||
return;
|
||||
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||
showOne(rowData);
|
||||
@ -45,7 +45,7 @@ function detailSelectionChangedRunInfo(evt, ui) {
|
||||
|
||||
function getState(state) {
|
||||
var result;
|
||||
if (state == null)
|
||||
if (state == undefined)
|
||||
result = "9-Null";
|
||||
else if (state === "New")
|
||||
result = `1-${state}`;
|
||||
@ -66,7 +66,7 @@ function getPriority(workItemType, priority) {
|
||||
var result;
|
||||
if (workItemType === "Bug")
|
||||
result = "0-Bug";
|
||||
else if (priority == null || priority === 0)
|
||||
else if (priority == undefined || priority === 0)
|
||||
result = "9-Null";
|
||||
else if (priority === 1)
|
||||
result = `${priority}-High`;
|
||||
@ -81,45 +81,34 @@ function getPriority(workItemType, priority) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function getInversePriority(priority) {
|
||||
function getPollValue(description, pollValue) {
|
||||
var result;
|
||||
if (priority == null || priority === 0)
|
||||
result = "0.000";
|
||||
else if (priority === 1)
|
||||
result = "3.000";
|
||||
else if (priority === 2)
|
||||
result = "2.000";
|
||||
else if (priority === 3)
|
||||
result = "1.000";
|
||||
if (pollValue == undefined || pollValue.RiskReductionOpportunityEnablement == undefined || pollValue.RiskReductionOpportunityEnablement.InverseAverage == undefined)
|
||||
result = "";
|
||||
else if (pollValue.RiskReductionOpportunityEnablement.InverseAverage >= 4)
|
||||
result = `${pollValue.RiskReductionOpportunityEnablement.InverseAverage} - 1-Highest (Most ${description}) - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.RiskReductionOpportunityEnablement.InverseAverage >= 3)
|
||||
result = `${pollValue.RiskReductionOpportunityEnablement.InverseAverage} - 2-High - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.RiskReductionOpportunityEnablement.InverseAverage >= 2)
|
||||
result = `${pollValue.RiskReductionOpportunityEnablement.InverseAverage} - 3-Medium - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.RiskReductionOpportunityEnablement.InverseAverage >= 1)
|
||||
result = `${pollValue.RiskReductionOpportunityEnablement.InverseAverage} - 4-Low - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.RiskReductionOpportunityEnablement.InverseAverage >= 0)
|
||||
result = `${pollValue.RiskReductionOpportunityEnablement.InverseAverage} - 5-Lowest - ${pollValue.Count} Vote(s)`;
|
||||
else
|
||||
result = "0.000";
|
||||
return result;
|
||||
}
|
||||
|
||||
function getPollValue(description, priority, priorityDisplay, pollValue) {
|
||||
var result;
|
||||
if (pollValue === undefined || pollValue.Records.length === undefined || pollValue.Records.length === 0 || pollValue.Average === null)
|
||||
result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority';
|
||||
else if (pollValue.Average > 2)
|
||||
result = `${pollValue.Average} - 1-High (Most ${description}) - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.Average > 1)
|
||||
result = `${pollValue.Average} - 2-Medium - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.Average > 0)
|
||||
result = `${pollValue.Average} - 3-Low - ${pollValue.Count} Vote(s)`;
|
||||
else
|
||||
result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority';
|
||||
result = "";
|
||||
return result;
|
||||
}
|
||||
|
||||
function updateRecordCoD(workItem) {
|
||||
if (workItem !== null) {
|
||||
if (workItem.Effort === null)
|
||||
if (workItem != undefined) {
|
||||
if (workItem.Effort == undefined)
|
||||
workItem.Effort = 10123;
|
||||
if (workItem.BusinessValue === null)
|
||||
if (workItem.BusinessValue == undefined)
|
||||
workItem.BusinessValue = 99999;
|
||||
if (workItem.TimeCriticality === null)
|
||||
if (workItem.TimeCriticality == undefined)
|
||||
workItem.TimeCriticality = 99999;
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement === null)
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement == undefined)
|
||||
workItem.RiskReductionMinusOpportunityEnablement = 99999;
|
||||
workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue;
|
||||
}
|
||||
@ -128,12 +117,12 @@ function updateRecordCoD(workItem) {
|
||||
function updateRecordOther(workItem, dataB, description) {
|
||||
workItem["State"] = getState(workItem["State"]);
|
||||
var priority = getPriority(workItem["WorkItemType"], workItem["Priority"]);
|
||||
workItem["PollValue"] = getPollValue(description, workItem["Priority"], priority, dataB[workItem.Id]);
|
||||
workItem["PollValue"] = getPollValue(description, dataB[workItem.Id]);
|
||||
workItem["Priority"] = priority;
|
||||
}
|
||||
|
||||
function updateRecordParent(parent, workItem) {
|
||||
if (parent === null) {
|
||||
if (parent == undefined) {
|
||||
workItem["ParentId"] = 9999999;
|
||||
workItem["ParentTitle"] = null;
|
||||
workItem["ParentState"] = null;
|
||||
@ -183,13 +172,46 @@ function sendValue(element, page, id) {
|
||||
});
|
||||
}
|
||||
|
||||
function getFibonacciValue(average) {
|
||||
var result;
|
||||
if (average >= 7)
|
||||
result = 34;
|
||||
else if (average >= 6)
|
||||
result = 21;
|
||||
else if (average >= 5)
|
||||
result = 13;
|
||||
else if (average >= 4)
|
||||
result = 8;
|
||||
else if (average >= 3)
|
||||
result = 5;
|
||||
else if (average >= 2)
|
||||
result = 3;
|
||||
else if (average >= 1)
|
||||
result = 2;
|
||||
else if (average >= 0)
|
||||
result = 1;
|
||||
else
|
||||
result = "";
|
||||
return result;
|
||||
}
|
||||
|
||||
function setRecords(workItems, page, description, th) {
|
||||
var record;
|
||||
var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Up</th><th>Down</th><th>Poll Value</th><th>" + th + "</th></tr>";
|
||||
var array = [];
|
||||
var count = "";
|
||||
var select = "";
|
||||
var average = "";
|
||||
var fibonacciValue = "";
|
||||
var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Poll Average</th><th>Fibonacci</th><th>Poll Description</th><th>Vote(s)</th><th>" + th + "</th><th>Up</th><th>Down</th></tr>";
|
||||
const element = document.getElementById("HeaderGrid");
|
||||
for (var i = 0; i < workItems.length; i++) {
|
||||
record = workItems[i];
|
||||
var length = record.RiskReductionMinusOpportunityEnablement === null ? "" : record.RiskReductionMinusOpportunityEnablement.toString().length;
|
||||
array = record.PollValue.split('-')
|
||||
average = array.length > 0 ? array[0] : "";
|
||||
fibonacciValue = getFibonacciValue(average);
|
||||
select = array.length > 2 ? array[1] + '-' + array[2] : "";
|
||||
count = array.length > 3 ? array[3].trim().split(' ')[0] : "";
|
||||
var length = record.RiskReductionMinusOpportunityEnablement == undefined ? "" : record.RiskReductionMinusOpportunityEnablement.toString().length;
|
||||
html += "<tr><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" +
|
||||
"</td><td>" + record.ParentTitle +
|
||||
"</td><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" +
|
||||
@ -201,14 +223,19 @@ function setRecords(workItems, page, description, th) {
|
||||
"</td><td>" +
|
||||
'<select onchange="sendValue(this, \'' + page + '\', ' + record.Id + ')">' +
|
||||
'<option value="9">Unknown</option>' +
|
||||
'<option value="1">High (Most ' + description + ')</option>' +
|
||||
'<option value="2">Medium</option>' +
|
||||
'<option value="3">Low</option>' +
|
||||
'<option value="1">Highest (Most ' + description + ')</option>' +
|
||||
'<option value="2">High</option>' +
|
||||
'<option value="3">Medium</option>' +
|
||||
'<option value="4">Low</option>' +
|
||||
'<option value="5">Lowest</option>' +
|
||||
"</select>" +
|
||||
"</td><td>" + average +
|
||||
"</td><td>" + fibonacciValue +
|
||||
"</td><td>" + select +
|
||||
"</td><td>" + count +
|
||||
"</td><td>" + length + " - " + record.RiskReductionMinusOpportunityEnablement +
|
||||
"</td><td><a href='#' class='up'>Up</a>" +
|
||||
"</td><td><a href='#' class='down'>Down</a>" +
|
||||
"</td><td>" + record.PollValue +
|
||||
"</td><td>" + length + " - " + record.RiskReductionMinusOpportunityEnablement +
|
||||
"</td></tr>";
|
||||
}
|
||||
element.innerHTML = html.replaceAll(">null<", "> <");
|
||||
|
7024
Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery-1.6.4-vsdoc.js
vendored
Normal file
7024
Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery-1.6.4-vsdoc.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9046
Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery-1.6.4.js
vendored
Normal file
9046
Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery-1.6.4.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4
Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery-1.6.4.min.js
vendored
Normal file
4
Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery-1.6.4.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
9
Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery.signalR-2.4.3.min.js
vendored
Normal file
9
Adaptation/FileHandlers/json/StaticSite/js/scripts/jquery.signalR-2.4.3.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
3190
Adaptation/FileHandlers/json/StaticSite/js/signalr/dist/browser/signalr.js
vendored
Normal file
3190
Adaptation/FileHandlers/json/StaticSite/js/signalr/dist/browser/signalr.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
95
Adaptation/FileHandlers/json/StaticSite/js/signalr/hubs.js
Normal file
95
Adaptation/FileHandlers/json/StaticSite/js/signalr/hubs.js
Normal file
@ -0,0 +1,95 @@
|
||||
/*!
|
||||
* ASP.NET SignalR JavaScript Library 2.4.3
|
||||
* http://signalr.net/
|
||||
*
|
||||
* Copyright (c) .NET Foundation. All rights reserved.
|
||||
* Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
*
|
||||
*/
|
||||
|
||||
/// <reference path="..\..\SignalR.Client.JS\Scripts\jquery-1.6.4.js" />
|
||||
/// <reference path="jquery.signalR.js" />
|
||||
(function ($, window, undefined) {
|
||||
/// <param name="$" type="jQuery" />
|
||||
"use strict";
|
||||
|
||||
if (typeof ($.signalR) !== "function") {
|
||||
throw new Error("SignalR: SignalR is not loaded. Please ensure jquery.signalR-x.js is referenced before ~/signalr/js.");
|
||||
}
|
||||
|
||||
var signalR = $.signalR;
|
||||
|
||||
function makeProxyCallback(hub, callback) {
|
||||
return function () {
|
||||
// Call the client hub method
|
||||
callback.apply(hub, $.makeArray(arguments));
|
||||
};
|
||||
}
|
||||
|
||||
function registerHubProxies(instance, shouldSubscribe) {
|
||||
var key, hub, memberKey, memberValue, subscriptionMethod;
|
||||
|
||||
for (key in instance) {
|
||||
if (instance.hasOwnProperty(key)) {
|
||||
hub = instance[key];
|
||||
|
||||
if (!(hub.hubName)) {
|
||||
// Not a client hub
|
||||
continue;
|
||||
}
|
||||
|
||||
if (shouldSubscribe) {
|
||||
// We want to subscribe to the hub events
|
||||
subscriptionMethod = hub.on;
|
||||
} else {
|
||||
// We want to unsubscribe from the hub events
|
||||
subscriptionMethod = hub.off;
|
||||
}
|
||||
|
||||
// Loop through all members on the hub and find client hub functions to subscribe/unsubscribe
|
||||
for (memberKey in hub.client) {
|
||||
if (hub.client.hasOwnProperty(memberKey)) {
|
||||
memberValue = hub.client[memberKey];
|
||||
|
||||
if (!$.isFunction(memberValue)) {
|
||||
// Not a client hub function
|
||||
continue;
|
||||
}
|
||||
|
||||
// Use the actual user-provided callback as the "identity" value for the registration.
|
||||
subscriptionMethod.call(hub, memberKey, makeProxyCallback(hub, memberValue), memberValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$.hubConnection.prototype.createHubProxies = function () {
|
||||
var proxies = {};
|
||||
this.starting(function () {
|
||||
// Register the hub proxies as subscribed
|
||||
// (instance, shouldSubscribe)
|
||||
registerHubProxies(proxies, true);
|
||||
|
||||
this._registerSubscribedHubs();
|
||||
}).disconnected(function () {
|
||||
// Unsubscribe all hub proxies when we "disconnect". This is to ensure that we do not re-add functional call backs.
|
||||
// (instance, shouldSubscribe)
|
||||
registerHubProxies(proxies, false);
|
||||
});
|
||||
|
||||
proxies['weightedShortestJobFirstHub'] = this.createHubProxy('weightedShortestJobFirstHub');
|
||||
proxies['weightedShortestJobFirstHub'].client = { };
|
||||
proxies['weightedShortestJobFirstHub'].server = {
|
||||
send: function (name, message) {
|
||||
return proxies['weightedShortestJobFirstHub'].invoke.apply(proxies['weightedShortestJobFirstHub'], $.merge(["Send"], $.makeArray(arguments)));
|
||||
}
|
||||
};
|
||||
|
||||
return proxies;
|
||||
};
|
||||
|
||||
signalR.hub = $.hubConnection("/signalr", { useDefaultPath: false });
|
||||
$.extend(signalR, signalR.hub.createHubProxies());
|
||||
|
||||
}(window.jQuery, window));
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,22 +1,22 @@
|
||||
var _apiUrl = null;
|
||||
|
||||
function compareFunction(a, b) {
|
||||
if (a.TimeCriticality === null || b.TimeCriticality === null) {
|
||||
if (a.TimeCriticality == undefined || b.TimeCriticality == undefined) {
|
||||
var aPollValue = a.PollValue.split('-');
|
||||
var bPollValue = b.PollValue.split('-');
|
||||
return bPollValue[0].trim() - aPollValue[0].trim() || b.State[0] - a.State[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
return b.State[0] - a.State[0] || bPollValue[0] - aPollValue[0] || bPollValue[bPollValue.length - 1].trim()[0] - aPollValue[aPollValue.length - 1].trim()[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
} else {
|
||||
return b.TimeCriticality - a.TimeCriticality || b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
}
|
||||
}
|
||||
|
||||
function showOne(rowData) {
|
||||
if (rowData == null)
|
||||
if (rowData == undefined)
|
||||
return;
|
||||
var data = [];
|
||||
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||
for (const property in rowData) {
|
||||
if (rowData[property] == null)
|
||||
if (rowData[property] == undefined)
|
||||
continue;
|
||||
data.push({ name: property, value: rowData[property].toString() });
|
||||
}
|
||||
@ -30,7 +30,7 @@ function showOne(rowData) {
|
||||
|
||||
function loadOne() {
|
||||
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||
if (selectedRow == null)
|
||||
if (selectedRow == undefined)
|
||||
return;
|
||||
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||
showOne(rowData);
|
||||
@ -45,7 +45,7 @@ function detailSelectionChangedRunInfo(evt, ui) {
|
||||
|
||||
function getState(state) {
|
||||
var result;
|
||||
if (state == null)
|
||||
if (state == undefined)
|
||||
result = "9-Null";
|
||||
else if (state === "New")
|
||||
result = `1-${state}`;
|
||||
@ -66,7 +66,7 @@ function getPriority(workItemType, priority) {
|
||||
var result;
|
||||
if (workItemType === "Bug")
|
||||
result = "0-Bug";
|
||||
else if (priority == null || priority === 0)
|
||||
else if (priority == undefined || priority === 0)
|
||||
result = "9-Null";
|
||||
else if (priority === 1)
|
||||
result = `${priority}-High`;
|
||||
@ -81,45 +81,34 @@ function getPriority(workItemType, priority) {
|
||||
return result;
|
||||
}
|
||||
|
||||
function getInversePriority(priority) {
|
||||
function getPollValue(description, pollValue) {
|
||||
var result;
|
||||
if (priority == null || priority === 0)
|
||||
result = "0.000";
|
||||
else if (priority === 1)
|
||||
result = "3.000";
|
||||
else if (priority === 2)
|
||||
result = "2.000";
|
||||
else if (priority === 3)
|
||||
result = "1.000";
|
||||
if (pollValue == undefined || pollValue.TimeCriticality == undefined || pollValue.TimeCriticality.InverseAverage == undefined)
|
||||
result = "";
|
||||
else if (pollValue.TimeCriticality.InverseAverage >= 4)
|
||||
result = `${pollValue.TimeCriticality.InverseAverage} - 1-Highest (Most ${description}) - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.TimeCriticality.InverseAverage >= 3)
|
||||
result = `${pollValue.TimeCriticality.InverseAverage} - 2-High - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.TimeCriticality.InverseAverage >= 2)
|
||||
result = `${pollValue.TimeCriticality.InverseAverage} - 3-Medium - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.TimeCriticality.InverseAverage >= 1)
|
||||
result = `${pollValue.TimeCriticality.InverseAverage} - 4-Low - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.TimeCriticality.InverseAverage >= 0)
|
||||
result = `${pollValue.TimeCriticality.InverseAverage} - 5-Lowest - ${pollValue.Count} Vote(s)`;
|
||||
else
|
||||
result = "0.000";
|
||||
return result;
|
||||
}
|
||||
|
||||
function getPollValue(description, priority, priorityDisplay, pollValue) {
|
||||
var result;
|
||||
if (pollValue === undefined || pollValue.Records.length === undefined || pollValue.Records.length === 0 || pollValue.Average === null)
|
||||
result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority';
|
||||
else if (pollValue.Average > 2)
|
||||
result = `${pollValue.Average} - 1-High (Most ${description}) - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.Average > 1)
|
||||
result = `${pollValue.Average} - 2-Medium - ${pollValue.Count} Vote(s)`;
|
||||
else if (pollValue.Average > 0)
|
||||
result = `${pollValue.Average} - 3-Low - ${pollValue.Count} Vote(s)`;
|
||||
else
|
||||
result = getInversePriority(priority) + ' - ' + priorityDisplay + ' - *Priority';
|
||||
result = "";
|
||||
return result;
|
||||
}
|
||||
|
||||
function updateRecordCoD(workItem) {
|
||||
if (workItem !== null) {
|
||||
if (workItem.Effort === null)
|
||||
if (workItem != undefined) {
|
||||
if (workItem.Effort == undefined)
|
||||
workItem.Effort = 10123;
|
||||
if (workItem.BusinessValue === null)
|
||||
if (workItem.BusinessValue == undefined)
|
||||
workItem.BusinessValue = 99999;
|
||||
if (workItem.TimeCriticality === null)
|
||||
if (workItem.TimeCriticality == undefined)
|
||||
workItem.TimeCriticality = 99999;
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement === null)
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement == undefined)
|
||||
workItem.RiskReductionMinusOpportunityEnablement = 99999;
|
||||
workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue;
|
||||
}
|
||||
@ -128,12 +117,12 @@ function updateRecordCoD(workItem) {
|
||||
function updateRecordOther(workItem, dataB, description) {
|
||||
workItem["State"] = getState(workItem["State"]);
|
||||
var priority = getPriority(workItem["WorkItemType"], workItem["Priority"]);
|
||||
workItem["PollValue"] = getPollValue(description, workItem["Priority"], priority, dataB[workItem.Id]);
|
||||
workItem["PollValue"] = getPollValue(description, dataB[workItem.Id]);
|
||||
workItem["Priority"] = priority;
|
||||
}
|
||||
|
||||
function updateRecordParent(parent, workItem) {
|
||||
if (parent === null) {
|
||||
if (parent == undefined) {
|
||||
workItem["ParentId"] = 9999999;
|
||||
workItem["ParentTitle"] = null;
|
||||
workItem["ParentState"] = null;
|
||||
@ -183,13 +172,47 @@ function sendValue(element, page, id) {
|
||||
});
|
||||
}
|
||||
|
||||
function getFibonacciValue(average) {
|
||||
var result;
|
||||
if (average >= 7)
|
||||
result = 34;
|
||||
else if (average >= 6)
|
||||
result = 21;
|
||||
else if (average >= 5)
|
||||
result = 13;
|
||||
else if (average >= 4)
|
||||
result = 8;
|
||||
else if (average >= 3)
|
||||
result = 5;
|
||||
else if (average >= 2)
|
||||
result = 3;
|
||||
else if (average >= 1)
|
||||
result = 2;
|
||||
else if (average >= 0)
|
||||
result = 1;
|
||||
else
|
||||
result = "";
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
function setRecords(workItems, page, description, th) {
|
||||
var record;
|
||||
var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Up</th><th>Down</th><th>Poll Value</th><th>" + th + "</th></tr>";
|
||||
var array = [];
|
||||
var count = "";
|
||||
var select = "";
|
||||
var average = "";
|
||||
var fibonacciValue = "";
|
||||
var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Value</th><th>Poll Average</th><th>Fibonacci</th><th>Poll Description</th><th>Vote(s)</th><th>" + th + "</th><th>Up</th><th>Down</th></tr>";
|
||||
const element = document.getElementById("HeaderGrid");
|
||||
for (var i = 0; i < workItems.length; i++) {
|
||||
record = workItems[i];
|
||||
var length = record.TimeCriticality === null ? "" : record.TimeCriticality.toString().length;
|
||||
array = record.PollValue.split('-')
|
||||
average = array.length > 0 ? array[0] : "";
|
||||
fibonacciValue = getFibonacciValue(average);
|
||||
select = array.length > 2 ? array[1] + '-' + array[2] : "";
|
||||
count = array.length > 3 ? array[3].trim().split(' ')[0] : "";
|
||||
var length = record.TimeCriticality == undefined ? "" : record.TimeCriticality.toString().length;
|
||||
html += "<tr><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" +
|
||||
"</td><td>" + record.ParentTitle +
|
||||
"</td><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" +
|
||||
@ -201,14 +224,19 @@ function setRecords(workItems, page, description, th) {
|
||||
"</td><td>" +
|
||||
'<select onchange="sendValue(this, \'' + page + '\', ' + record.Id + ')">' +
|
||||
'<option value="9">Unknown</option>' +
|
||||
'<option value="1">High (Most ' + description + ')</option>' +
|
||||
'<option value="2">Medium</option>' +
|
||||
'<option value="3">Low</option>' +
|
||||
'<option value="1">Highest (Most ' + description + ')</option>' +
|
||||
'<option value="2">High</option>' +
|
||||
'<option value="3">Medium</option>' +
|
||||
'<option value="4">Low</option>' +
|
||||
'<option value="5">Lowest</option>' +
|
||||
"</select>" +
|
||||
"</td><td>" + average +
|
||||
"</td><td>" + fibonacciValue +
|
||||
"</td><td>" + select +
|
||||
"</td><td>" + count +
|
||||
"</td><td>" + length + " - " + record.TimeCriticality +
|
||||
"</td><td><a href='#' class='up'>Up</a>" +
|
||||
"</td><td><a href='#' class='down'>Down</a>" +
|
||||
"</td><td>" + record.PollValue +
|
||||
"</td><td>" + length + " - " + record.TimeCriticality +
|
||||
"</td></tr>";
|
||||
}
|
||||
element.innerHTML = html.replaceAll(">null<", "> <");
|
||||
|
@ -1,5 +1,5 @@
|
||||
function compareFunction(a, b) {
|
||||
if (a.ParentCoD === null || b.ParentCoD === null) {
|
||||
if (a.ParentCoD == undefined || b.ParentCoD == undefined) {
|
||||
return b.ParentCoD - a.ParentCoD || b.Id - a.Id;
|
||||
} else {
|
||||
return b.State[0] - a.State[0] || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
@ -7,12 +7,12 @@ function compareFunction(a, b) {
|
||||
}
|
||||
|
||||
function showOne(rowData) {
|
||||
if (rowData == null)
|
||||
if (rowData == undefined)
|
||||
return;
|
||||
var data = [];
|
||||
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||
for (const property in rowData) {
|
||||
if (rowData[property] == null)
|
||||
if (rowData[property] == undefined)
|
||||
continue;
|
||||
data.push({ name: property, value: rowData[property].toString() });
|
||||
}
|
||||
@ -26,7 +26,7 @@ function showOne(rowData) {
|
||||
|
||||
function loadOne() {
|
||||
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||
if (selectedRow == null)
|
||||
if (selectedRow == undefined)
|
||||
return;
|
||||
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||
showOne(rowData);
|
||||
@ -41,7 +41,7 @@ function detailSelectionChangedRunInfo(evt, ui) {
|
||||
|
||||
function getState(state) {
|
||||
var result;
|
||||
if (state == null)
|
||||
if (state == undefined)
|
||||
result = "9-Null";
|
||||
else if (state === "New")
|
||||
result = `1-${state}`;
|
||||
@ -62,7 +62,7 @@ function getPriority(workItemType, priority) {
|
||||
var result;
|
||||
if (workItemType === "Bug")
|
||||
result = "0-Bug";
|
||||
else if (priority == null || priority === 0)
|
||||
else if (priority == undefined || priority === 0)
|
||||
result = "9-Null";
|
||||
else if (priority === 1)
|
||||
result = `${priority}-High`;
|
||||
@ -78,14 +78,14 @@ function getPriority(workItemType, priority) {
|
||||
}
|
||||
|
||||
function updateRecordCoD(workItem) {
|
||||
if (workItem !== null) {
|
||||
if (workItem.Effort === null)
|
||||
if (workItem != undefined) {
|
||||
if (workItem.Effort == undefined)
|
||||
workItem.Effort = 10123;
|
||||
if (workItem.BusinessValue === null)
|
||||
if (workItem.BusinessValue == undefined)
|
||||
workItem.BusinessValue = 99999;
|
||||
if (workItem.TimeCriticality === null)
|
||||
if (workItem.TimeCriticality == undefined)
|
||||
workItem.TimeCriticality = 99999;
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement === null)
|
||||
if (workItem.RiskReductionMinusOpportunityEnablement == undefined)
|
||||
workItem.RiskReductionMinusOpportunityEnablement = 99999;
|
||||
workItem.CoD = workItem.RiskReductionMinusOpportunityEnablement + workItem.TimeCriticality + workItem.BusinessValue;
|
||||
}
|
||||
@ -97,7 +97,7 @@ function updateRecordOther(workItem) {
|
||||
}
|
||||
|
||||
function updateRecordParent(parent, workItem) {
|
||||
if (parent === null) {
|
||||
if (parent == undefined) {
|
||||
workItem["ParentId"] = 9999999;
|
||||
workItem["ParentTitle"] = null;
|
||||
workItem["ParentState"] = null;
|
||||
|
321
Adaptation/FileHandlers/json/StaticSite/js/wsjf-b.js
Normal file
321
Adaptation/FileHandlers/json/StaticSite/js/wsjf-b.js
Normal file
@ -0,0 +1,321 @@
|
||||
var _apiUrl = null;
|
||||
|
||||
function compareFunction(a, b) {
|
||||
return b.WeightedShortestJobFirst - a.WeightedShortestJobFirst || b.CoDRank - b.CoDRank || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
}
|
||||
|
||||
function compareEffortFunction(a, b) {
|
||||
return a.Effort - b.Effort || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
}
|
||||
|
||||
function compareBusinessValueFunction(a, b) {
|
||||
return a.BusinessValue - b.BusinessValue || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
}
|
||||
|
||||
function compareTimeCriticalityFunction(a, b) {
|
||||
return a.TimeCriticality - b.TimeCriticality || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
}
|
||||
|
||||
function compareRiskReductionMinusOpportunityEnablementFunction(a, b) {
|
||||
return b.RiskReductionMinusOpportunityEnablement - b.RiskReductionMinusOpportunityEnablement || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
}
|
||||
|
||||
function compareCostOfDelay(a, b) {
|
||||
return b.CoD - b.CoD || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
}
|
||||
|
||||
function showOne(rowData) {
|
||||
if (rowData == undefined)
|
||||
return;
|
||||
var data = [];
|
||||
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||
for (const property in rowData) {
|
||||
if (rowData[property] == undefined)
|
||||
continue;
|
||||
data.push({ name: property, value: rowData[property].toString() });
|
||||
}
|
||||
$("#AllGrid").igGrid({
|
||||
autoGenerateColumns: true,
|
||||
dataSource: data,
|
||||
width: "100%",
|
||||
showHeader: false,
|
||||
});
|
||||
}
|
||||
|
||||
function loadOne() {
|
||||
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||
if (selectedRow == undefined)
|
||||
return;
|
||||
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||
showOne(rowData);
|
||||
}
|
||||
|
||||
function detailSelectionChangedRunInfo(evt, ui) {
|
||||
if (ui.row.index === 0)
|
||||
return;
|
||||
var rowData = ui.owner.grid.dataSource.dataView()[ui.row.index];
|
||||
showOne(rowData);
|
||||
}
|
||||
|
||||
function getState(state) {
|
||||
var result;
|
||||
if (state == undefined)
|
||||
result = "9-Null";
|
||||
else if (state === "New")
|
||||
result = `1-${state}`;
|
||||
else if (state === "Active")
|
||||
result = `2-${state}`;
|
||||
else if (state === "Resolved")
|
||||
result = `3-${state}`;
|
||||
else if (state === "Closed")
|
||||
result = `4-${state}`;
|
||||
else if (state === "Removed")
|
||||
result = `5-${state}`;
|
||||
else
|
||||
result = `8-${state}`;
|
||||
return result;
|
||||
}
|
||||
|
||||
function getPriority(workItemType, priority) {
|
||||
var result;
|
||||
if (workItemType === "Bug")
|
||||
result = "0-Bug";
|
||||
else if (priority == undefined || priority === 0)
|
||||
result = "9-Null";
|
||||
else if (priority === 1)
|
||||
result = `${priority}-High`;
|
||||
else if (priority === 2)
|
||||
result = `${priority}-Med`;
|
||||
else if (priority === 3)
|
||||
result = `${priority}-Low`;
|
||||
else if (priority === 4)
|
||||
result = `${priority}-TBD`;
|
||||
else
|
||||
result = "8-Not";
|
||||
return result;
|
||||
}
|
||||
|
||||
function updateRecordCoD(workItem) {
|
||||
if (workItem != undefined) {
|
||||
if (workItem["Effort"] == undefined)
|
||||
workItem["Effort"] = 1;
|
||||
if (workItem["BusinessValue"] == undefined)
|
||||
workItem["BusinessValue"] = 99999;
|
||||
if (workItem["TimeCriticality"] == undefined)
|
||||
workItem["TimeCriticality"] = 99999;
|
||||
if (workItem["RiskReductionMinusOpportunityEnablement"] == undefined)
|
||||
workItem["RiskReductionMinusOpportunityEnablement"] = 99999;
|
||||
}
|
||||
}
|
||||
|
||||
function getFibonacci(length) {
|
||||
var results = [];
|
||||
for (var i = 0; i < length; i++) {
|
||||
results.push(21);
|
||||
}
|
||||
var index = 0;
|
||||
var fibonacci = [3, 5, 8, 13, 20];
|
||||
var factor = (length / fibonacci.length).toFixed();
|
||||
for (var j = 0; j < fibonacci.length; j++) {
|
||||
for (var i = 0; i < factor; i++) {
|
||||
results[index] = fibonacci[j];
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
// for (var i = 0; i < results.length; i++) {
|
||||
// console.log(results[i]);
|
||||
// }
|
||||
return results;
|
||||
}
|
||||
|
||||
function updateCoD(records) {
|
||||
var workItem;
|
||||
var collection = [];
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
if (workItem.Priority[0] === '2') {
|
||||
workItem.EffortFibonacci = 2;
|
||||
workItem.BusinessValueFibonacci = 2;
|
||||
workItem.TimeCriticalityFibonacci = 2;
|
||||
workItem.RiskReductionMinusOpportunityEnablementFibonacci = 2;
|
||||
continue;
|
||||
}
|
||||
else if (workItem.Priority[0] === '3') {
|
||||
workItem.EffortFibonacci = 1;
|
||||
workItem.BusinessValueFibonacci = 1;
|
||||
workItem.TimeCriticalityFibonacci = 1;
|
||||
workItem.RiskReductionMinusOpportunityEnablementFibonacci = 1;
|
||||
continue;
|
||||
}
|
||||
collection.push(workItem);
|
||||
}
|
||||
var fibonacci = getFibonacci(collection.length);
|
||||
collection.sort(compareEffortFunction);
|
||||
for (var i = 0; i < collection.length; i++) {
|
||||
workItem = collection[i];
|
||||
workItem.EffortFibonacci = fibonacci[i];
|
||||
}
|
||||
records.sort(compareEffortFunction);
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
workItem.EffortRank = (((i + 1) / records.length) * 100).toFixed();
|
||||
}
|
||||
collection.sort(compareBusinessValueFunction);
|
||||
for (var i = 0; i < collection.length; i++) {
|
||||
workItem = collection[i];
|
||||
workItem.BusinessValueFibonacci = fibonacci[i];
|
||||
}
|
||||
records.sort(compareBusinessValueFunction);
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
workItem.BusinessValueRank = (((i + 1) / records.length) * 100).toFixed();
|
||||
}
|
||||
collection.sort(compareTimeCriticalityFunction);
|
||||
for (var i = 0; i < collection.length; i++) {
|
||||
workItem = collection[i];
|
||||
workItem.TimeCriticalityFibonacci = fibonacci[i];
|
||||
}
|
||||
records.sort(compareTimeCriticalityFunction);
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
workItem.TimeCriticalityRank = (((i + 1) / records.length) * 100).toFixed();
|
||||
}
|
||||
collection.sort(compareRiskReductionMinusOpportunityEnablementFunction);
|
||||
for (var i = 0; i < collection.length; i++) {
|
||||
workItem = collection[i];
|
||||
workItem.RiskReductionMinusOpportunityEnablementFibonacci = fibonacci[i];
|
||||
}
|
||||
records.sort(compareRiskReductionMinusOpportunityEnablementFunction);
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
workItem.RiskReductionMinusOpportunityEnablementRank = (((i + 1) / records.length) * 100).toFixed();
|
||||
}
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
workItem.CoD = workItem.RiskReductionMinusOpportunityEnablementFibonacci + workItem.TimeCriticalityFibonacci + workItem.BusinessValueFibonacci;
|
||||
}
|
||||
records.sort(compareCostOfDelay);
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
workItem.CoDRank = (((i + 1) / records.length) * 100).toFixed();
|
||||
}
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
if (workItem.Priority[0] !== '1' && workItem.Priority[0] !== '4') {
|
||||
workItem.WeightedShortestJobFirst = 0.000001;
|
||||
workItem.WeightedShortestJobFirstRank = 0;
|
||||
}
|
||||
else {
|
||||
workItem.WeightedShortestJobFirstRank = (((i + 1) / records.length) * 100).toFixed();
|
||||
workItem.WeightedShortestJobFirst = (workItem.CoD / workItem.EffortFibonacci).toFixed(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateRecordOther(workItem) {
|
||||
workItem["State"] = getState(workItem["State"]);
|
||||
workItem["Priority"] = getPriority(workItem["WorkItemType"], workItem["Priority"]);
|
||||
}
|
||||
|
||||
function updateRecordParent(parent, workItem) {
|
||||
if (parent == undefined) {
|
||||
workItem["ParentId"] = 9999999;
|
||||
workItem["ParentTitle"] = null;
|
||||
workItem["ParentState"] = null;
|
||||
workItem["ParentCoD"] = 9999999;
|
||||
}
|
||||
else {
|
||||
workItem["ParentId"] = parent["Id"];
|
||||
workItem["ParentCoD"] = parent["CoD"];
|
||||
workItem["ParentTitle"] = parent["Title"];
|
||||
workItem["ParentState"] = getState(parent["State"]);
|
||||
}
|
||||
}
|
||||
|
||||
function getRecords(data) {
|
||||
var parent;
|
||||
var workItem;
|
||||
var records = [];
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
parent = data[i].Parent;
|
||||
workItem = data[i].WorkItem;
|
||||
if (workItem.WorkItemType !== 'Feature')
|
||||
continue;
|
||||
if (workItem.State !== 'Active' && workItem.State !== 'New')
|
||||
continue;
|
||||
if (workItem.Tags != null && workItem.Tags.includes("Ignore"))
|
||||
continue;
|
||||
if ((window.location.href.indexOf('=LEO') > -1 && workItem.AreaPath !== 'ART SPS\\LEO') || (window.location.href.indexOf('=MES') > -1 && workItem.AreaPath !== 'ART SPS\\MES'))
|
||||
continue;
|
||||
updateRecordCoD(parent);
|
||||
updateRecordCoD(workItem);
|
||||
updateRecordOther(workItem);
|
||||
updateRecordParent(parent, workItem);
|
||||
records.push(workItem);
|
||||
}
|
||||
updateCoD(records);
|
||||
records.sort(compareFunction);
|
||||
return records;
|
||||
}
|
||||
|
||||
function setRecords(workItems) {
|
||||
var record;
|
||||
var html = "<tr><th>Parent Id</th><th>Parent Title</th><th>Id</th><th>Requester</th><th>Title</th><th>Assigned To</th><th>System(s)</th><th>State</th><th>Priority</th><th>Risk Reduction and/or Opportunity Enablement</th><th>Time Criticality</th><th>Business Value</th><th>CoD</th><th>Effort</th><th>WSJF</th><th>Up</th><th>Down</th></tr>";
|
||||
const element = document.getElementById("HeaderGrid");
|
||||
for (var i = 0; i < workItems.length; i++) {
|
||||
record = workItems[i];
|
||||
html += "<tr><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" +
|
||||
"</td><td>" + record.ParentTitle +
|
||||
"</td><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" +
|
||||
"</td><td>" + record.Requester +
|
||||
"</td><td>" + record.Title +
|
||||
"</td><td>" + record.AssignedTo +
|
||||
"</td><td>" + record.Tags +
|
||||
"</td><td>" + record.State +
|
||||
"</td><td>" + record.Priority +
|
||||
"</td><td>" + record.RiskReductionMinusOpportunityEnablementRank + '% - ' + record.RiskReductionMinusOpportunityEnablement + ' - ' + record.RiskReductionMinusOpportunityEnablementFibonacci +
|
||||
"</td><td>" + record.TimeCriticalityRank + '% - ' +record.TimeCriticality + ' - ' + record.TimeCriticalityFibonacci +
|
||||
"</td><td>" + record.BusinessValueRank + '% - ' +record.BusinessValue + ' - ' + record.BusinessValueFibonacci +
|
||||
"</td><td>" + record.CoDRank + '% - ' + record.CoD +
|
||||
"</td><td>" + record.EffortRank + '% - ' +record.Effort + ' - ' + record.EffortFibonacci +
|
||||
"</td><td>" + record.WeightedShortestJobFirst +
|
||||
"</td><td><a href='#' class='up'>Up</a></td><td><a href='#' class='down'>Down</a></td></tr>";
|
||||
}
|
||||
element.innerHTML = html.replaceAll(">null<", "> <");
|
||||
}
|
||||
|
||||
function updateSite() {
|
||||
if (window.location.href.indexOf('=LEO') > -1) {
|
||||
document.title = document.title.replace("Infineon", "HiRel (Leominster)");
|
||||
document.getElementById("siteHeader").innerText = "HiRel (Leominster)";
|
||||
}
|
||||
else if (window.location.href.indexOf('=MES') > -1) {
|
||||
document.title = document.title.replace("Infineon", "Mesa");
|
||||
document.getElementById("siteHeader").innerText = "Mesa";
|
||||
}
|
||||
else {
|
||||
document.title = document.title.replace("Infineon", "Infineon");
|
||||
document.getElementById("siteHeader").innerText = "Infineon";
|
||||
}
|
||||
}
|
||||
|
||||
function initIndex(url, apiUrl) {
|
||||
_apiUrl = apiUrl;
|
||||
updateSite();
|
||||
$.getJSON(url, { _: new Date().getTime() }, function (data) {
|
||||
var records = getRecords(data);
|
||||
console.log(data.length);
|
||||
if (data.length > 0)
|
||||
console.log(data[0]);
|
||||
setRecords(records);
|
||||
$(".up,.down").click(function () {
|
||||
var row = $(this).parents("tr:first");
|
||||
if ($(this).is(".up")) {
|
||||
row.insertBefore(row.prev());
|
||||
} else {
|
||||
row.insertAfter(row.next());
|
||||
}
|
||||
});
|
||||
});
|
||||
$("#HeaderGrid").on("dblclick", "tr", loadOne);
|
||||
}
|
47
Adaptation/FileHandlers/json/StaticSite/js/wsjf-c.js
Normal file
47
Adaptation/FileHandlers/json/StaticSite/js/wsjf-c.js
Normal file
@ -0,0 +1,47 @@
|
||||
var _apiUrl = null;
|
||||
|
||||
function initIndex(url, apiUrl) {
|
||||
_apiUrl = apiUrl;
|
||||
|
||||
//Set the hubs URL for the connection
|
||||
$.connection.hub.url = url;
|
||||
$.connection.hub.logging = true;
|
||||
|
||||
// Declare a proxy to reference the hub.
|
||||
// var chat = $.connection.myHub;
|
||||
var chat = $.connection.weightedShortestJobFirstHub;
|
||||
|
||||
// Create a function that the hub can call to broadcast messages.
|
||||
chat.client.addNotification = function (name, message) {
|
||||
// Html encode display name and message.
|
||||
console.log(message);
|
||||
var encodedName = $('<div />').text(name).html();
|
||||
var encodedMsg = $('<div />').text("hash").html();
|
||||
// Add the message to the page.
|
||||
$('#discussion').append('<li><strong>' + encodedName
|
||||
+ '</strong>: ' + encodedMsg + '</li>');
|
||||
};
|
||||
// Get the user name and store it to prepend to messages.
|
||||
$('#displayname').val(prompt('Enter your name:', ''));
|
||||
// Set initial focus to message input box.
|
||||
$('#message').focus();
|
||||
// Start the connection.
|
||||
$.connection.hub.start({ transport: 'longPolling' }).done(function () {
|
||||
$('#sendmessage').click(function () {
|
||||
// Call the Send method on the hub.
|
||||
// chat.server.send($('#displayname').val(), $('#message').val());
|
||||
var notification = {
|
||||
"Json": null,
|
||||
"id": 110743,
|
||||
"page": "effort",
|
||||
"QueryString": "time=1737573418926\u0026id=110743\u0026page=effort\u0026value=1",
|
||||
"RemoteIpAddress": "10.95.36.87",
|
||||
"time": 1737573418926,
|
||||
"value": 1
|
||||
};
|
||||
chat.server.notifyAll(notification);
|
||||
// Clear text box and reset focus for next comment.
|
||||
$('#message').val('').focus();
|
||||
});
|
||||
});
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
var _apiUrl = null;
|
||||
|
||||
function compareFunction(a, b) {
|
||||
return b.WeightedShortestJobFirst - a.WeightedShortestJobFirst || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
return b.WeightedShortestJobFirst - a.WeightedShortestJobFirst || b.CoDRank - b.CoDRank || b.ParentId - a.ParentId || a.Id - b.Id;
|
||||
}
|
||||
|
||||
function compareEffortFunction(a, b) {
|
||||
@ -25,12 +25,12 @@ function compareCostOfDelay(a, b) {
|
||||
}
|
||||
|
||||
function showOne(rowData) {
|
||||
if (rowData == null)
|
||||
if (rowData == undefined)
|
||||
return;
|
||||
var data = [];
|
||||
data.push({ name: "Edit in ADO", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">Edit in ADO ' + rowData["Id"] + '</a>' });
|
||||
for (const property in rowData) {
|
||||
if (rowData[property] == null)
|
||||
if (rowData[property] == undefined)
|
||||
continue;
|
||||
data.push({ name: property, value: rowData[property].toString() });
|
||||
}
|
||||
@ -44,7 +44,7 @@ function showOne(rowData) {
|
||||
|
||||
function loadOne() {
|
||||
var selectedRow = $("#HeaderGrid").data("igGridSelection").selectedRow();
|
||||
if (selectedRow == null)
|
||||
if (selectedRow == undefined)
|
||||
return;
|
||||
var rowData = $("#HeaderGrid").data("igGrid").dataSource.dataView()[selectedRow.index];
|
||||
showOne(rowData);
|
||||
@ -59,7 +59,7 @@ function detailSelectionChangedRunInfo(evt, ui) {
|
||||
|
||||
function getState(state) {
|
||||
var result;
|
||||
if (state == null)
|
||||
if (state == undefined)
|
||||
result = "9-Null";
|
||||
else if (state === "New")
|
||||
result = `1-${state}`;
|
||||
@ -80,7 +80,7 @@ function getPriority(workItemType, priority) {
|
||||
var result;
|
||||
if (workItemType === "Bug")
|
||||
result = "0-Bug";
|
||||
else if (priority == null || priority === 0)
|
||||
else if (priority == undefined || priority === 0)
|
||||
result = "9-Null";
|
||||
else if (priority === 1)
|
||||
result = `${priority}-High`;
|
||||
@ -96,90 +96,100 @@ function getPriority(workItemType, priority) {
|
||||
}
|
||||
|
||||
function updateRecordCoD(workItem) {
|
||||
if (workItem !== null) {
|
||||
if (workItem["Effort"] === null)
|
||||
if (workItem != undefined) {
|
||||
if (workItem["Effort"] == undefined)
|
||||
workItem["Effort"] = 1;
|
||||
if (workItem["BusinessValue"] === null)
|
||||
if (workItem["BusinessValue"] == undefined)
|
||||
workItem["BusinessValue"] = 99999;
|
||||
if (workItem["TimeCriticality"] === null)
|
||||
if (workItem["TimeCriticality"] == undefined)
|
||||
workItem["TimeCriticality"] = 99999;
|
||||
if (workItem["RiskReductionMinusOpportunityEnablement"] === null)
|
||||
if (workItem["RiskReductionMinusOpportunityEnablement"] == undefined)
|
||||
workItem["RiskReductionMinusOpportunityEnablement"] = 99999;
|
||||
}
|
||||
}
|
||||
|
||||
function getFibonacci(length) {
|
||||
var results = [];
|
||||
var i;
|
||||
var fib = [0, 1];
|
||||
for (i = 2; i <= length + 1; i++) {
|
||||
fib[i] = fib[i - 2] + fib[i - 1];
|
||||
results.push(fib[i]);
|
||||
for (var i = 0; i < length; i++) {
|
||||
results.push(21);
|
||||
}
|
||||
var index = 0;
|
||||
var fibonacci = [3, 5, 8, 13, 20];
|
||||
var factor = (length / fibonacci.length).toFixed();
|
||||
for (var j = 0; j < fibonacci.length; j++) {
|
||||
for (var i = 0; i < factor; i++) {
|
||||
results[index] = fibonacci[j];
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
// for (var i = 0; i < results.length; i++) {
|
||||
// console.log(results[i]);
|
||||
// }
|
||||
return results;
|
||||
}
|
||||
|
||||
function updateCoD(records) {
|
||||
var iHigh;
|
||||
var workItem;
|
||||
var fibonacci = getFibonacci(records.length);
|
||||
records.sort(compareEffortFunction);
|
||||
iHigh = 0;
|
||||
var collection = [];
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
if (workItem.Priority[0] !== '1' && workItem.Priority[0] !== '4') {
|
||||
workItem.EffortRank = 0;
|
||||
if (workItem.Priority[0] === '2') {
|
||||
workItem.EffortFibonacci = 2;
|
||||
workItem.BusinessValueFibonacci = 2;
|
||||
workItem.TimeCriticalityFibonacci = 2;
|
||||
workItem.RiskReductionMinusOpportunityEnablementFibonacci = 2;
|
||||
continue;
|
||||
}
|
||||
else if (workItem.Priority[0] === '3') {
|
||||
workItem.EffortFibonacci = 1;
|
||||
workItem.BusinessValueFibonacci = 1;
|
||||
workItem.TimeCriticalityFibonacci = 1;
|
||||
workItem.RiskReductionMinusOpportunityEnablementFibonacci = 1;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
collection.push(workItem);
|
||||
}
|
||||
var fibonacci = getFibonacci(collection.length);
|
||||
collection.sort(compareEffortFunction);
|
||||
for (var i = 0; i < collection.length; i++) {
|
||||
workItem = collection[i];
|
||||
workItem.EffortFibonacci = fibonacci[i];
|
||||
}
|
||||
records.sort(compareEffortFunction);
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
workItem.EffortRank = (((i + 1) / records.length) * 100).toFixed();
|
||||
workItem.EffortFibonacci = fibonacci[iHigh];
|
||||
iHigh += 1;
|
||||
}
|
||||
collection.sort(compareBusinessValueFunction);
|
||||
for (var i = 0; i < collection.length; i++) {
|
||||
workItem = collection[i];
|
||||
workItem.BusinessValueFibonacci = fibonacci[i];
|
||||
}
|
||||
records.sort(compareBusinessValueFunction);
|
||||
iHigh = 0;
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
if (workItem.Priority[0] !== '1' && workItem.Priority[0] !== '4') {
|
||||
workItem.BusinessValueRank = 0;
|
||||
workItem.BusinessValueFibonacci = 1;
|
||||
}
|
||||
else {
|
||||
workItem.BusinessValueRank = (((i + 1) / records.length) * 100).toFixed();
|
||||
workItem.BusinessValueFibonacci = fibonacci[iHigh];
|
||||
iHigh += 1;
|
||||
}
|
||||
collection.sort(compareTimeCriticalityFunction);
|
||||
for (var i = 0; i < collection.length; i++) {
|
||||
workItem = collection[i];
|
||||
workItem.TimeCriticalityFibonacci = fibonacci[i];
|
||||
}
|
||||
records.sort(compareTimeCriticalityFunction);
|
||||
iHigh = 0;
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
if (workItem.Priority[0] !== '1' && workItem.Priority[0] !== '4') {
|
||||
workItem.TimeCriticalityRank = 0;
|
||||
workItem.TimeCriticalityFibonacci = 1;
|
||||
}
|
||||
else {
|
||||
workItem.TimeCriticalityRank = (((i + 1) / records.length) * 100).toFixed();
|
||||
workItem.TimeCriticalityFibonacci = fibonacci[iHigh];
|
||||
iHigh += 1;
|
||||
}
|
||||
collection.sort(compareRiskReductionMinusOpportunityEnablementFunction);
|
||||
for (var i = 0; i < collection.length; i++) {
|
||||
workItem = collection[i];
|
||||
workItem.RiskReductionMinusOpportunityEnablementFibonacci = fibonacci[i];
|
||||
}
|
||||
records.sort(compareRiskReductionMinusOpportunityEnablementFunction);
|
||||
iHigh = 0;
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
if (workItem.Priority[0] !== '1' && workItem.Priority[0] !== '4') {
|
||||
workItem.RiskReductionMinusOpportunityEnablementRank = 0;
|
||||
workItem.RiskReductionMinusOpportunityEnablementFibonacci = 1;
|
||||
}
|
||||
else {
|
||||
workItem.RiskReductionMinusOpportunityEnablementRank = (((i + 1) / records.length) * 100).toFixed();
|
||||
workItem.RiskReductionMinusOpportunityEnablementFibonacci = fibonacci[iHigh];
|
||||
iHigh += 1;
|
||||
}
|
||||
}
|
||||
records.sort(compareCostOfDelay);
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
workItem.CoD = workItem.RiskReductionMinusOpportunityEnablementFibonacci + workItem.TimeCriticalityFibonacci + workItem.BusinessValueFibonacci;
|
||||
@ -187,14 +197,7 @@ function updateCoD(records) {
|
||||
records.sort(compareCostOfDelay);
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
if (workItem.Priority[0] !== '1' && workItem.Priority[0] !== '4') {
|
||||
workItem.CoD = 0.000001;
|
||||
workItem.CoDRank = 0;
|
||||
}
|
||||
else {
|
||||
workItem.CoDRank = (((i + 1) / records.length) * 100).toFixed();
|
||||
// workItem.CoD = (workItem.CoD / workItem.CoDFibonacci).toFixed(6);
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < records.length; i++) {
|
||||
workItem = records[i];
|
||||
@ -204,7 +207,7 @@ function updateCoD(records) {
|
||||
}
|
||||
else {
|
||||
workItem.WeightedShortestJobFirstRank = (((i + 1) / records.length) * 100).toFixed();
|
||||
workItem.WeightedShortestJobFirst = (workItem.CoD / workItem.EffortFibonacci).toFixed(6);
|
||||
workItem.WeightedShortestJobFirst = (workItem.CoD / workItem.EffortFibonacci).toFixed(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -215,7 +218,7 @@ function updateRecordOther(workItem) {
|
||||
}
|
||||
|
||||
function updateRecordParent(parent, workItem) {
|
||||
if (parent === null) {
|
||||
if (parent == undefined) {
|
||||
workItem["ParentId"] = 9999999;
|
||||
workItem["ParentTitle"] = null;
|
||||
workItem["ParentState"] = null;
|
||||
@ -238,7 +241,7 @@ function getRecords(data) {
|
||||
workItem = data[i].WorkItem;
|
||||
if (workItem.WorkItemType !== 'Feature')
|
||||
continue;
|
||||
if (workItem.State !== 'New' && workItem.State !== 'Active')
|
||||
if (workItem.State !== 'Active' && workItem.State !== 'New')
|
||||
continue;
|
||||
if (workItem.Tags != null && workItem.Tags.includes("Ignore"))
|
||||
continue;
|
||||
@ -262,7 +265,7 @@ function setRecords(workItems) {
|
||||
for (var i = 0; i < workItems.length; i++) {
|
||||
record = workItems[i];
|
||||
html += "<tr><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.ParentId + '">' + record.ParentId + "</a>" +
|
||||
"</td><td>" + record.Title +
|
||||
"</td><td>" + record.ParentTitle +
|
||||
"</td><td>" + '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + record.Id + '">' + record.Id + "</a>" +
|
||||
"</td><td>" + record.Requester +
|
||||
"</td><td>" + record.Title +
|
||||
@ -270,11 +273,11 @@ function setRecords(workItems) {
|
||||
"</td><td>" + record.Tags +
|
||||
"</td><td>" + record.State +
|
||||
"</td><td>" + record.Priority +
|
||||
"</td><td>" + record.RiskReductionMinusOpportunityEnablement + '-' + record.RiskReductionMinusOpportunityEnablementRank + '% -' + record.RiskReductionMinusOpportunityEnablementFibonacci +
|
||||
"</td><td>" + record.TimeCriticality + '-' + record.TimeCriticalityRank + '% -' + record.TimeCriticalityFibonacci +
|
||||
"</td><td>" + record.BusinessValue + '-' + record.BusinessValueRank + '% -' + record.BusinessValueFibonacci +
|
||||
"</td><td>" + record.CoD + '-' + record.CoDRank + '% -' +
|
||||
"</td><td>" + record.Effort + '-' + record.EffortRank + '% -' + record.EffortFibonacci +
|
||||
"</td><td>" + record.RiskReductionMinusOpportunityEnablementRank + '% - ' + record.RiskReductionMinusOpportunityEnablement + ' - ' + record.RiskReductionMinusOpportunityEnablementFibonacci +
|
||||
"</td><td>" + record.TimeCriticalityRank + '% - ' +record.TimeCriticality + ' - ' + record.TimeCriticalityFibonacci +
|
||||
"</td><td>" + record.BusinessValueRank + '% - ' +record.BusinessValue + ' - ' + record.BusinessValueFibonacci +
|
||||
"</td><td>" + record.CoDRank + '% - ' + record.CoD +
|
||||
"</td><td>" + record.EffortRank + '% - ' +record.Effort + ' - ' + record.EffortFibonacci +
|
||||
"</td><td>" + record.WeightedShortestJobFirst +
|
||||
"</td><td><a href='#' class='up'>Up</a></td><td><a href='#' class='down'>Down</a></td></tr>";
|
||||
}
|
||||
|
37
Adaptation/FileHandlers/json/StaticSite/styles/cod.css
Normal file
37
Adaptation/FileHandlers/json/StaticSite/styles/cod.css
Normal file
@ -0,0 +1,37 @@
|
||||
#HeaderGridDiv,
|
||||
#DetailsGridDiv {
|
||||
font-size: 12px;
|
||||
min-width: 1200px;
|
||||
max-width: 1200px;
|
||||
}
|
||||
|
||||
#HeaderGrid {
|
||||
font-family: monospace;
|
||||
margin-top: 60px;
|
||||
}
|
||||
|
||||
#HeaderGrid tr td {
|
||||
max-width: 200px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#AllGrid {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
min-width: 1200px;
|
||||
background-color: whitesmoke;
|
||||
}
|
||||
|
||||
tr:nth-of-type(odd) {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
#AllTextarea {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
#th-span {
|
||||
margin-right: 500px;
|
||||
}
|
25
Adaptation/FileHandlers/json/WIQL/Attribute.cs
Normal file
25
Adaptation/FileHandlers/json/WIQL/Attribute.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WIQL;
|
||||
|
||||
internal class Attribute
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public Attribute(bool isLocked,
|
||||
string name)
|
||||
{
|
||||
IsLocked = isLocked;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
[JsonPropertyName("isLocked")] public bool IsLocked { get; }
|
||||
[JsonPropertyName("name")] public string Name { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Attribute))]
|
||||
internal partial class WIQLAttributeSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -2,8 +2,9 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WIQL;
|
||||
|
||||
public class Column
|
||||
internal class Column
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public Column(
|
||||
string referenceName,
|
||||
@ -16,7 +17,14 @@ public class Column
|
||||
Url = url;
|
||||
}
|
||||
|
||||
public string ReferenceName { get; set; } // { init; get; }
|
||||
public string Name { get; set; } // { init; get; }
|
||||
public string Url { get; set; } // { init; get; }
|
||||
[JsonPropertyName("referenceName")] public string ReferenceName { get; }
|
||||
[JsonPropertyName("name")] public string Name { get; }
|
||||
[JsonPropertyName("url")] public string Url { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Column))]
|
||||
internal partial class ColumnSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -2,8 +2,9 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WIQL;
|
||||
|
||||
public class Field
|
||||
internal class Field
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public Field(
|
||||
string referenceName,
|
||||
@ -16,7 +17,14 @@ public class Field
|
||||
Url = url;
|
||||
}
|
||||
|
||||
public string ReferenceName { get; set; } // { init; get; }
|
||||
public string Name { get; set; } // { init; get; }
|
||||
public string Url { get; set; } // { init; get; }
|
||||
[JsonPropertyName("referenceName")] public string ReferenceName { get; }
|
||||
[JsonPropertyName("name")] public string Name { get; }
|
||||
[JsonPropertyName("url")] public string Url { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Field))]
|
||||
internal partial class FieldSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
35
Adaptation/FileHandlers/json/WIQL/Relation.cs
Normal file
35
Adaptation/FileHandlers/json/WIQL/Relation.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WIQL;
|
||||
|
||||
internal class Relation
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public Relation(string rel,
|
||||
string url,
|
||||
Attribute attributes)
|
||||
{
|
||||
Rel = rel;
|
||||
Rel = rel;
|
||||
URL = url;
|
||||
Attributes = attributes;
|
||||
}
|
||||
|
||||
[JsonPropertyName("attributes")] public Attribute Attributes { get; set; }
|
||||
[JsonPropertyName("rel")] public string Rel { get; set; }
|
||||
[JsonPropertyName("url")] public string URL { get; set; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Relation))]
|
||||
internal partial class WIQLRelationSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Relation[]))]
|
||||
internal partial class WIQLRelationCollectionSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -3,8 +3,9 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WIQL;
|
||||
|
||||
public class Root
|
||||
internal class Root
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public Root(
|
||||
string queryType,
|
||||
@ -23,10 +24,17 @@ public class Root
|
||||
WorkItems = workItems;
|
||||
}
|
||||
|
||||
public string QueryType { get; set; } // { init; get; }
|
||||
public string QueryResultType { get; set; } // { init; get; }
|
||||
public DateTime AsOf { get; set; } // { init; get; }
|
||||
public Column[] Columns { get; set; } // { init; get; }
|
||||
public SortColumn[] SortColumns { get; set; } // { init; get; }
|
||||
public WorkItem[] WorkItems { get; set; } // { init; get; }
|
||||
[JsonPropertyName("queryType")] public string QueryType { get; }
|
||||
[JsonPropertyName("queryResultType")] public string QueryResultType { get; }
|
||||
[JsonPropertyName("asOf")] public DateTime AsOf { get; }
|
||||
[JsonPropertyName("columns")] public Column[] Columns { get; }
|
||||
[JsonPropertyName("sortColumns")] public SortColumn[] SortColumns { get; }
|
||||
[JsonPropertyName("workItems")] public WorkItem[] WorkItems { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)] // PropertyNameCaseInsensitive = true
|
||||
[JsonSerializable(typeof(Root))]
|
||||
internal partial class RootSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -2,8 +2,9 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WIQL;
|
||||
|
||||
public class SortColumn
|
||||
internal class SortColumn
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public SortColumn(
|
||||
Field field,
|
||||
@ -14,6 +15,13 @@ public class SortColumn
|
||||
Descending = descending;
|
||||
}
|
||||
|
||||
public Field Field { get; set; } // { init; get; }
|
||||
public bool Descending { get; set; } // { init; get; }
|
||||
[JsonPropertyName("field")] public Field Field { get; }
|
||||
[JsonPropertyName("descending")] public bool Descending { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(SortColumn))]
|
||||
internal partial class SortColumnSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -2,8 +2,9 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WIQL;
|
||||
|
||||
public class WorkItem
|
||||
internal class WorkItem
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public WorkItem(
|
||||
int id,
|
||||
@ -14,6 +15,13 @@ public class WorkItem
|
||||
Url = url;
|
||||
}
|
||||
|
||||
public int Id { get; set; } // { init; get; }
|
||||
public string Url { get; set; } // { init; get; }
|
||||
[JsonPropertyName("id")] public int Id { get; }
|
||||
[JsonPropertyName("url")] public string Url { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(WorkItem))]
|
||||
internal partial class WIQLWorkItemSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -2,20 +2,35 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WorkItems;
|
||||
|
||||
public class Attribute
|
||||
internal class Attribute
|
||||
{
|
||||
|
||||
#nullable enable
|
||||
|
||||
[JsonConstructor]
|
||||
public Attribute(bool isLocked,
|
||||
string name)
|
||||
string name,
|
||||
string? parameterTitle,
|
||||
string? state,
|
||||
string? workItemType)
|
||||
{
|
||||
IsLocked = isLocked;
|
||||
Name = name;
|
||||
ParameterTitle = parameterTitle;
|
||||
State = state;
|
||||
WorkItemType = workItemType;
|
||||
}
|
||||
|
||||
[JsonPropertyName("isLocked")] public bool IsLocked { get; set; }
|
||||
[JsonPropertyName("name")] public string Name { get; set; }
|
||||
[JsonPropertyName("isLocked")] public bool IsLocked { get; }
|
||||
[JsonPropertyName("name")] public string Name { get; }
|
||||
[JsonPropertyName("parameterTitle")] public string? ParameterTitle { get; set; }
|
||||
[JsonPropertyName("state")] public string? State { get; set; }
|
||||
[JsonPropertyName("workItemType")] public string? WorkItemType { get; set; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Attribute))]
|
||||
internal partial class AttributeSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -2,12 +2,20 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WorkItems;
|
||||
|
||||
public class Avatar
|
||||
internal class Avatar
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public Avatar(
|
||||
string href
|
||||
) => Href = href;
|
||||
|
||||
public string Href { get; } // { init; get; }
|
||||
[JsonPropertyName("href")] public string Href { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Avatar))]
|
||||
internal partial class AvatarSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -2,8 +2,9 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WorkItems;
|
||||
|
||||
public class CommentVersionRef
|
||||
internal class CommentVersionRef
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public CommentVersionRef(
|
||||
int commentId,
|
||||
@ -16,8 +17,14 @@ public class CommentVersionRef
|
||||
URL = url;
|
||||
}
|
||||
|
||||
[JsonPropertyName("commentId")] public int CommentId { get; } // { init; get; }
|
||||
[JsonPropertyName("url")] public string URL { get; } // { init; get; }
|
||||
[JsonPropertyName("version")] public int Version { get; } // { init; get; }
|
||||
[JsonPropertyName("commentId")] public int CommentId { get; }
|
||||
[JsonPropertyName("url")] public string URL { get; }
|
||||
[JsonPropertyName("version")] public int Version { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(CommentVersionRef))]
|
||||
internal partial class CommentVersionRefSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -2,8 +2,9 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WorkItems;
|
||||
|
||||
public class CustomRequester
|
||||
internal class CustomRequester
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public CustomRequester(
|
||||
string descriptor,
|
||||
@ -31,4 +32,11 @@ public class CustomRequester
|
||||
[JsonPropertyName("_links")] public Links Links { get; }
|
||||
[JsonPropertyName("uniqueName")] public string UniqueName { get; }
|
||||
[JsonPropertyName("url")] public string Url { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(CustomRequester))]
|
||||
internal partial class CustomRequesterSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -3,7 +3,7 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WorkItems;
|
||||
|
||||
public class Fields
|
||||
internal class Fields
|
||||
{
|
||||
|
||||
#nullable enable
|
||||
@ -20,7 +20,9 @@ public class Fields
|
||||
DateTime microsoftVSTSCommonStateChangeDate,
|
||||
float? microsoftVSTSCommonTimeCriticality,
|
||||
float? microsoftVSTSSchedulingEffort,
|
||||
float? microsoftVSTSSchedulingRemainingWork,
|
||||
DateTime microsoftVSTSSchedulingStartDate,
|
||||
float? microsoftVSTSSchedulingStoryPoints,
|
||||
DateTime microsoftVSTSSchedulingTargetDate,
|
||||
string systemAreaPath,
|
||||
SystemAssignedTo systemAssignedTo,
|
||||
@ -40,8 +42,8 @@ public class Fields
|
||||
string systemTitle,
|
||||
string systemWorkItemType)
|
||||
{
|
||||
CustomRequester = customRequester;
|
||||
CustomRRminusOE = customRRminusOE;
|
||||
CustomRequester = customRequester;
|
||||
CustomWSJF = customWSJF;
|
||||
MicrosoftVSTSCommonActivatedDate = microsoftVSTSCommonActivatedDate;
|
||||
MicrosoftVSTSCommonBusinessValue = microsoftVSTSCommonBusinessValue;
|
||||
@ -51,7 +53,9 @@ public class Fields
|
||||
MicrosoftVSTSCommonStateChangeDate = microsoftVSTSCommonStateChangeDate;
|
||||
MicrosoftVSTSCommonTimeCriticality = microsoftVSTSCommonTimeCriticality;
|
||||
MicrosoftVSTSSchedulingEffort = microsoftVSTSSchedulingEffort;
|
||||
MicrosoftVSTSSchedulingRemainingWork = microsoftVSTSSchedulingRemainingWork;
|
||||
MicrosoftVSTSSchedulingStartDate = microsoftVSTSSchedulingStartDate;
|
||||
MicrosoftVSTSSchedulingStoryPoints = microsoftVSTSSchedulingStoryPoints;
|
||||
MicrosoftVSTSSchedulingTargetDate = microsoftVSTSSchedulingTargetDate;
|
||||
SystemAreaPath = systemAreaPath;
|
||||
SystemAssignedTo = systemAssignedTo;
|
||||
@ -72,35 +76,43 @@ public class Fields
|
||||
SystemWorkItemType = systemWorkItemType;
|
||||
}
|
||||
|
||||
[JsonPropertyName("Custom.Requester")] public CustomRequester? CustomRequester { get; } // { init; get; }
|
||||
[JsonPropertyName("Custom.RRminusOE")] public float? CustomRRminusOE { get; } // { init; get; }
|
||||
[JsonPropertyName("Custom.WSJF")] public float? CustomWSJF { get; } // { init; get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Common.ActivatedDate")] public DateTime MicrosoftVSTSCommonActivatedDate { get; } // { init; get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Common.BusinessValue")] public float? MicrosoftVSTSCommonBusinessValue { get; } // { init; get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Common.ClosedDate")] public DateTime MicrosoftVSTSCommonClosedDate { get; } // { init; get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Common.Priority")] public int MicrosoftVSTSCommonPriority { get; } // { init; get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Common.ResolvedDate")] public DateTime MicrosoftVSTSCommonResolvedDate { get; } // { init; get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Common.StateChangeDate")] public DateTime MicrosoftVSTSCommonStateChangeDate { get; } // { init; get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Common.TimeCriticality")] public float? MicrosoftVSTSCommonTimeCriticality { get; } // { init; get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Scheduling.Effort")] public float? MicrosoftVSTSSchedulingEffort { get; } // { init; get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Scheduling.StartDate")] public DateTime MicrosoftVSTSSchedulingStartDate { get; } // { init; get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Scheduling.TargetDate")] public DateTime MicrosoftVSTSSchedulingTargetDate { get; } // { init; get; }
|
||||
[JsonPropertyName("System.AreaPath")] public string SystemAreaPath { get; } // { init; get; }
|
||||
[JsonPropertyName("System.AssignedTo")] public SystemAssignedTo? SystemAssignedTo { get; } // { init; get; }
|
||||
[JsonPropertyName("System.ChangedBy")] public SystemChangedBy SystemChangedBy { get; } // { init; get; }
|
||||
[JsonPropertyName("System.ChangedDate")] public DateTime SystemChangedDate { get; } // { init; get; }
|
||||
[JsonPropertyName("System.CommentCount")] public int SystemCommentCount { get; } // { init; get; }
|
||||
[JsonPropertyName("System.CreatedBy")] public SystemCreatedBy SystemCreatedBy { get; } // { init; get; }
|
||||
[JsonPropertyName("System.CreatedDate")] public DateTime SystemCreatedDate { get; } // { init; get; }
|
||||
[JsonPropertyName("System.Description")] public string SystemDescription { get; } // { init; get; }
|
||||
[JsonPropertyName("System.History")] public string SystemHistory { get; } // { init; get; }
|
||||
[JsonPropertyName("System.IterationPath")] public string SystemIterationPath { get; } // { init; get; }
|
||||
[JsonPropertyName("System.Parent")] public int SystemParent { get; } // { init; get; }
|
||||
[JsonPropertyName("System.Reason")] public string SystemReason { get; } // { init; get; }
|
||||
[JsonPropertyName("System.State")] public string SystemState { get; } // { init; get; }
|
||||
[JsonPropertyName("System.Tags")] public string SystemTags { get; } // { init; get; }
|
||||
[JsonPropertyName("System.TeamProject")] public string SystemTeamProject { get; } // { init; get; }
|
||||
[JsonPropertyName("System.Title")] public string SystemTitle { get; } // { init; get; }
|
||||
[JsonPropertyName("System.WorkItemType")] public string SystemWorkItemType { get; } // { init; get; }
|
||||
[JsonPropertyName("Custom.RRminusOE")] public float? CustomRRminusOE { get; }
|
||||
[JsonPropertyName("Custom.Requester")] public CustomRequester? CustomRequester { get; }
|
||||
[JsonPropertyName("Custom.WSJF")] public float? CustomWSJF { get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Common.ActivatedDate")] public DateTime MicrosoftVSTSCommonActivatedDate { get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Common.BusinessValue")] public float? MicrosoftVSTSCommonBusinessValue { get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Common.ClosedDate")] public DateTime MicrosoftVSTSCommonClosedDate { get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Common.Priority")] public int MicrosoftVSTSCommonPriority { get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Common.ResolvedDate")] public DateTime MicrosoftVSTSCommonResolvedDate { get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Common.StateChangeDate")] public DateTime MicrosoftVSTSCommonStateChangeDate { get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Common.TimeCriticality")] public float? MicrosoftVSTSCommonTimeCriticality { get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Scheduling.Effort")] public float? MicrosoftVSTSSchedulingEffort { get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Scheduling.RemainingWork")] public float? MicrosoftVSTSSchedulingRemainingWork { get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Scheduling.StartDate")] public DateTime MicrosoftVSTSSchedulingStartDate { get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Scheduling.StoryPoints")] public float? MicrosoftVSTSSchedulingStoryPoints { get; }
|
||||
[JsonPropertyName("Microsoft.VSTS.Scheduling.TargetDate")] public DateTime MicrosoftVSTSSchedulingTargetDate { get; }
|
||||
[JsonPropertyName("System.AreaPath")] public string SystemAreaPath { get; }
|
||||
[JsonPropertyName("System.AssignedTo")] public SystemAssignedTo? SystemAssignedTo { get; }
|
||||
[JsonPropertyName("System.ChangedBy")] public SystemChangedBy SystemChangedBy { get; }
|
||||
[JsonPropertyName("System.ChangedDate")] public DateTime SystemChangedDate { get; }
|
||||
[JsonPropertyName("System.CommentCount")] public int SystemCommentCount { get; }
|
||||
[JsonPropertyName("System.CreatedBy")] public SystemCreatedBy SystemCreatedBy { get; }
|
||||
[JsonPropertyName("System.CreatedDate")] public DateTime SystemCreatedDate { get; }
|
||||
[JsonPropertyName("System.Description")] public string SystemDescription { get; }
|
||||
[JsonPropertyName("System.History")] public string SystemHistory { get; }
|
||||
[JsonPropertyName("System.IterationPath")] public string SystemIterationPath { get; }
|
||||
[JsonPropertyName("System.Parent")] public int SystemParent { get; }
|
||||
[JsonPropertyName("System.Reason")] public string SystemReason { get; }
|
||||
[JsonPropertyName("System.State")] public string SystemState { get; }
|
||||
[JsonPropertyName("System.Tags")] public string SystemTags { get; }
|
||||
[JsonPropertyName("System.TeamProject")] public string SystemTeamProject { get; }
|
||||
[JsonPropertyName("System.Title")] public string SystemTitle { get; }
|
||||
[JsonPropertyName("System.WorkItemType")] public string SystemWorkItemType { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Fields))]
|
||||
internal partial class FieldsSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -2,12 +2,20 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WorkItems;
|
||||
|
||||
public class Html
|
||||
internal class Html
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public Html(
|
||||
string href
|
||||
) => Href = href;
|
||||
|
||||
public string Href { get; } // { init; get; }
|
||||
[JsonPropertyName("href")] public string Href { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Html))]
|
||||
internal partial class HtmlSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -2,12 +2,20 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WorkItems;
|
||||
|
||||
public class Links
|
||||
internal class Links
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public Links(
|
||||
Avatar avatar
|
||||
) => Avatar = avatar;
|
||||
|
||||
[JsonPropertyName("avatar")] public Avatar Avatar { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Links))]
|
||||
internal partial class LinksSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -1,27 +1,171 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WorkItems;
|
||||
|
||||
public class Record
|
||||
internal class Record
|
||||
{
|
||||
|
||||
#nullable enable
|
||||
|
||||
[JsonConstructor]
|
||||
public Record(WorkItem workItem, WorkItem? parent, Record[] children)
|
||||
public Record(WorkItem workItem, WorkItem? parent, Record[]? children, Record[]? related, Record[]? successors)
|
||||
{
|
||||
WorkItem = workItem;
|
||||
Parent = parent;
|
||||
Children = children;
|
||||
Related = related;
|
||||
Successors = successors;
|
||||
}
|
||||
|
||||
public WorkItem WorkItem { get; set; }
|
||||
public WorkItem? Parent { get; set; }
|
||||
public Record[] Children { get; set; }
|
||||
[JsonPropertyName("WorkItem")] public WorkItem WorkItem { get; set; }
|
||||
[JsonPropertyName("Parent")] public WorkItem? Parent { get; set; }
|
||||
[JsonPropertyName("Children")] public Record[]? Children { get; set; }
|
||||
[JsonPropertyName("Related")] public Record[]? Related { get; set; }
|
||||
[JsonPropertyName("Successors")] public Record[]? Successors { get; set; }
|
||||
|
||||
public static Record Get(WorkItem workItem, WorkItem? parent, ReadOnlyCollection<Record> children) =>
|
||||
new(workItem, parent, children.ToArray());
|
||||
internal static Record GetWithoutNesting(Record record, string? violation)
|
||||
{
|
||||
Record result;
|
||||
WorkItem workItem = new(activatedDate: record.WorkItem.ActivatedDate,
|
||||
areaPath: record.WorkItem.AreaPath,
|
||||
assignedTo: record.WorkItem.AssignedTo,
|
||||
businessValue: record.WorkItem.BusinessValue,
|
||||
changedDate: record.WorkItem.ChangedDate,
|
||||
closedDate: record.WorkItem.ClosedDate,
|
||||
commentCount: record.WorkItem.CommentCount,
|
||||
createdDate: record.WorkItem.CreatedDate,
|
||||
description: record.WorkItem.Description,
|
||||
effort: record.WorkItem.Effort,
|
||||
id: record.WorkItem.Id,
|
||||
iterationPath: record.WorkItem.IterationPath,
|
||||
parent: record.WorkItem.Parent,
|
||||
priority: record.WorkItem.Priority,
|
||||
relations: record.WorkItem.Relations,
|
||||
remainingWork: record.WorkItem.RemainingWork,
|
||||
requester: record.WorkItem.Requester,
|
||||
resolvedDate: record.WorkItem.ResolvedDate,
|
||||
revision: record.WorkItem.Revision,
|
||||
riskReductionMinusOpportunityEnablement: record.WorkItem.RiskReductionMinusOpportunityEnablement,
|
||||
startDate: record.WorkItem.StartDate,
|
||||
state: record.WorkItem.State,
|
||||
storyPoints: record.WorkItem.StoryPoints,
|
||||
tags: record.WorkItem.Tags,
|
||||
targetDate: record.WorkItem.TargetDate,
|
||||
timeCriticality: record.WorkItem.TimeCriticality,
|
||||
title: record.WorkItem.Title,
|
||||
violation: record.WorkItem.Violation is null ? violation : record.WorkItem.Violation,
|
||||
weightedShortestJobFirst: record.WorkItem.WeightedShortestJobFirst,
|
||||
workItemType: record.WorkItem.WorkItemType);
|
||||
result = new(workItem, record.Parent, Array.Empty<Record>(), Array.Empty<Record>(), Array.Empty<Record>());
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Record Get(Record record, bool keepRelations)
|
||||
{
|
||||
Record result;
|
||||
Record[]? childRecords;
|
||||
Record[]? relatedRecords;
|
||||
Record[]? successorRecords;
|
||||
List<Record> relationRecords;
|
||||
WorkItem? parentWorkItem = keepRelations ? record.Parent : WorkItem.GetWithOutRelations(record.Parent);
|
||||
WorkItem? workItem = keepRelations ? record.WorkItem : WorkItem.GetWithOutRelations(record.WorkItem) ?? throw new Exception();
|
||||
if (record.Children is null)
|
||||
childRecords = null;
|
||||
else
|
||||
{
|
||||
relationRecords = new();
|
||||
foreach (Record r in record.Children)
|
||||
relationRecords.Add(Get(r, keepRelations));
|
||||
childRecords = relationRecords.ToArray();
|
||||
}
|
||||
if (record.Related is null)
|
||||
relatedRecords = null;
|
||||
else
|
||||
{
|
||||
relationRecords = new();
|
||||
foreach (Record r in record.Related)
|
||||
relationRecords.Add(Get(r, keepRelations));
|
||||
relatedRecords = relationRecords.ToArray();
|
||||
}
|
||||
if (record.Successors is null)
|
||||
successorRecords = null;
|
||||
else
|
||||
{
|
||||
relationRecords = new();
|
||||
foreach (Record r in record.Successors)
|
||||
relationRecords.Add(Get(r, keepRelations));
|
||||
successorRecords = relationRecords.ToArray();
|
||||
}
|
||||
result = new(workItem, parentWorkItem, childRecords, relatedRecords, successorRecords);
|
||||
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());
|
||||
result = Get(record, keepRelations);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal static ReadOnlyCollection<Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, WorkItem workItem, string relationName, List<bool> nests, bool keepRelations)
|
||||
{
|
||||
List<Record> results = new();
|
||||
Record record;
|
||||
nests.Add(true);
|
||||
WorkItem? parentWorkItem;
|
||||
WorkItem? relationWorkItem;
|
||||
List<WorkItem> collection = new();
|
||||
ReadOnlyCollection<Record>? childRecords;
|
||||
ReadOnlyCollection<Record>? relatedRecords;
|
||||
ReadOnlyCollection<Record>? successorRecords;
|
||||
if (workItem.Relations is not null && workItem.Relations.Length > 0)
|
||||
{
|
||||
collection.Clear();
|
||||
foreach (Relation relation in workItem.Relations)
|
||||
{
|
||||
if (relation.Attributes.Name != relationName)
|
||||
continue;
|
||||
if (workItem.Parent is not null && relation.Id == workItem.Parent.Value)
|
||||
continue;
|
||||
if (!keyValuePairs.TryGetValue(relation.Id, out relationWorkItem))
|
||||
continue;
|
||||
collection.Add(relationWorkItem);
|
||||
}
|
||||
collection = (from l in collection orderby l.State != "Closed", l.Id select l).ToList();
|
||||
foreach (WorkItem w in collection)
|
||||
{
|
||||
if (nests.Count > 500)
|
||||
break;
|
||||
if (w.Parent is null)
|
||||
parentWorkItem = null;
|
||||
else
|
||||
_ = keyValuePairs.TryGetValue(w.Parent.Value, out parentWorkItem);
|
||||
childRecords = GetKeyValuePairs(keyValuePairs, w, "Child", nests, keepRelations); // Forward
|
||||
relatedRecords = null; // GetKeyValuePairs(keyValuePairs, w, "Related", nests, keepRelations); // Related
|
||||
successorRecords = null; // GetKeyValuePairs(keyValuePairs, w, "Successor", nests, keepRelations); // Forward
|
||||
// predecessorRecords = GetKeyValuePairs(keyValuePairs, w, "Predecessor", nests, keepRelations); // Reverse
|
||||
record = Get(w, parentWorkItem, childRecords, relatedRecords, successorRecords, keepRelations);
|
||||
results.Add(record);
|
||||
}
|
||||
}
|
||||
return new(results);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Record))]
|
||||
internal partial class RecordSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Record[]))]
|
||||
internal partial class RecordCollectionSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -2,23 +2,33 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WorkItems;
|
||||
|
||||
public class Relation
|
||||
internal class Relation
|
||||
{
|
||||
|
||||
#nullable enable
|
||||
|
||||
[JsonConstructor]
|
||||
public Relation(string rel,
|
||||
string url,
|
||||
Attribute attributes)
|
||||
public Relation(Attribute attributes,
|
||||
int id,
|
||||
string rel)
|
||||
{
|
||||
Rel = rel;
|
||||
URL = url;
|
||||
Attributes = attributes;
|
||||
Id = id;
|
||||
Rel = rel;
|
||||
}
|
||||
|
||||
[JsonPropertyName("attributes")] public Attribute Attributes { get; set; }
|
||||
[JsonPropertyName("id")] public int Id { get; set; }
|
||||
[JsonPropertyName("rel")] public string Rel { get; set; }
|
||||
[JsonPropertyName("url")] public string URL { get; set; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Relation))]
|
||||
internal partial class RelationSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Relation[]))]
|
||||
internal partial class RelationCollectionSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -2,8 +2,9 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WorkItems;
|
||||
|
||||
public class SystemAssignedTo
|
||||
internal class SystemAssignedTo
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public SystemAssignedTo(
|
||||
string displayName,
|
||||
@ -33,3 +34,9 @@ public class SystemAssignedTo
|
||||
[JsonPropertyName("url")] public string Url { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(SystemAssignedTo))]
|
||||
internal partial class SystemAssignedToSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -2,8 +2,9 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WorkItems;
|
||||
|
||||
public class SystemChangedBy
|
||||
internal class SystemChangedBy
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public SystemChangedBy(
|
||||
string displayName,
|
||||
@ -33,3 +34,9 @@ public class SystemChangedBy
|
||||
[JsonPropertyName("url")] public string Url { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(SystemChangedBy))]
|
||||
internal partial class SystemChangedBySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -2,8 +2,9 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WorkItems;
|
||||
|
||||
public class SystemCreatedBy
|
||||
internal class SystemCreatedBy
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public SystemCreatedBy(
|
||||
string displayName,
|
||||
@ -33,3 +34,9 @@ public class SystemCreatedBy
|
||||
[JsonPropertyName("url")] public string Url { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(SystemCreatedBy))]
|
||||
internal partial class SystemCreatedBySourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -2,14 +2,15 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WorkItems;
|
||||
|
||||
public class Value
|
||||
internal class Value
|
||||
{
|
||||
|
||||
[JsonConstructor]
|
||||
public Value(
|
||||
int id,
|
||||
int rev,
|
||||
Fields fields,
|
||||
Relation[] relations,
|
||||
WIQL.Relation[] relations,
|
||||
CommentVersionRef commentVersionRef,
|
||||
string url
|
||||
)
|
||||
@ -25,7 +26,14 @@ public class Value
|
||||
[JsonPropertyName("commentVersionRef")] public CommentVersionRef CommentVersionRef { get; }
|
||||
[JsonPropertyName("fields")] public Fields Fields { get; }
|
||||
[JsonPropertyName("id")] public int Id { get; }
|
||||
[JsonPropertyName("relations")] public Relation[] Relations { get; }
|
||||
[JsonPropertyName("relations")] public WIQL.Relation[] Relations { get; }
|
||||
[JsonPropertyName("rev")] public int Rev { get; }
|
||||
[JsonPropertyName("url")] public string Url { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(Value))]
|
||||
internal partial class ValueSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
@ -3,7 +3,7 @@ using System.Text.Json.Serialization;
|
||||
|
||||
namespace Adaptation.FileHandlers.json.WorkItems;
|
||||
|
||||
public class WorkItem
|
||||
internal class WorkItem
|
||||
{
|
||||
|
||||
#nullable enable
|
||||
@ -24,12 +24,14 @@ public class WorkItem
|
||||
int? parent,
|
||||
int? priority,
|
||||
Relation[]? relations,
|
||||
long? remainingWork,
|
||||
string? requester,
|
||||
DateTime? resolvedDate,
|
||||
int revision,
|
||||
long? riskReductionMinusOpportunityEnablement,
|
||||
DateTime? startDate,
|
||||
string state,
|
||||
long? storyPoints,
|
||||
string tags,
|
||||
DateTime? targetDate,
|
||||
long? timeCriticality,
|
||||
@ -53,12 +55,14 @@ public class WorkItem
|
||||
Parent = parent;
|
||||
Priority = priority;
|
||||
Relations = relations;
|
||||
RemainingWork = remainingWork;
|
||||
Requester = requester;
|
||||
ResolvedDate = resolvedDate;
|
||||
Revision = revision;
|
||||
RiskReductionMinusOpportunityEnablement = riskReductionMinusOpportunityEnablement;
|
||||
StartDate = startDate;
|
||||
State = state;
|
||||
StoryPoints = storyPoints;
|
||||
Tags = tags;
|
||||
TargetDate = targetDate;
|
||||
TimeCriticality = timeCriticality;
|
||||
@ -70,68 +74,117 @@ public class WorkItem
|
||||
|
||||
public override string ToString() => $"{Id} - {WorkItemType} - {Title}";
|
||||
|
||||
public static Record Get(Record record, string? violation)
|
||||
public static WorkItem Get(WorkItem workItem, Relation[] relations)
|
||||
{
|
||||
Record result;
|
||||
WorkItem workItem = new(record.WorkItem.ActivatedDate,
|
||||
record.WorkItem.AreaPath,
|
||||
record.WorkItem.AssignedTo,
|
||||
record.WorkItem.BusinessValue,
|
||||
record.WorkItem.ChangedDate,
|
||||
record.WorkItem.ClosedDate,
|
||||
record.WorkItem.CommentCount,
|
||||
record.WorkItem.CreatedDate,
|
||||
record.WorkItem.Description,
|
||||
record.WorkItem.Effort,
|
||||
record.WorkItem.Id,
|
||||
record.WorkItem.IterationPath,
|
||||
record.WorkItem.Parent,
|
||||
record.WorkItem.Priority,
|
||||
record.WorkItem.Relations,
|
||||
record.WorkItem.Requester,
|
||||
record.WorkItem.ResolvedDate,
|
||||
record.WorkItem.Revision,
|
||||
record.WorkItem.RiskReductionMinusOpportunityEnablement,
|
||||
record.WorkItem.StartDate,
|
||||
record.WorkItem.State,
|
||||
record.WorkItem.Tags,
|
||||
record.WorkItem.TargetDate,
|
||||
record.WorkItem.TimeCriticality,
|
||||
record.WorkItem.Title,
|
||||
record.WorkItem.Violation is null ? violation : record.WorkItem.Violation,
|
||||
record.WorkItem.WeightedShortestJobFirst,
|
||||
record.WorkItem.WorkItemType);
|
||||
result = new(workItem, record.Parent, Array.Empty<Record>());
|
||||
WorkItem result = new(activatedDate: workItem.ActivatedDate,
|
||||
areaPath: workItem.AreaPath,
|
||||
assignedTo: workItem.AssignedTo,
|
||||
businessValue: workItem.BusinessValue,
|
||||
changedDate: workItem.ChangedDate,
|
||||
closedDate: workItem.ClosedDate,
|
||||
commentCount: workItem.CommentCount,
|
||||
createdDate: workItem.CreatedDate,
|
||||
description: workItem.Description,
|
||||
effort: workItem.Effort,
|
||||
id: workItem.Id,
|
||||
iterationPath: workItem.IterationPath,
|
||||
parent: workItem.Parent,
|
||||
priority: workItem.Priority,
|
||||
relations: relations,
|
||||
remainingWork: workItem.RemainingWork,
|
||||
requester: workItem.Requester,
|
||||
resolvedDate: workItem.ResolvedDate,
|
||||
revision: workItem.Revision,
|
||||
riskReductionMinusOpportunityEnablement: workItem.RiskReductionMinusOpportunityEnablement,
|
||||
startDate: workItem.StartDate,
|
||||
state: workItem.State,
|
||||
storyPoints: workItem.StoryPoints,
|
||||
tags: workItem.Tags,
|
||||
targetDate: workItem.TargetDate,
|
||||
timeCriticality: workItem.TimeCriticality,
|
||||
title: workItem.Title,
|
||||
violation: workItem.Violation,
|
||||
weightedShortestJobFirst: workItem.WeightedShortestJobFirst,
|
||||
workItemType: workItem.WorkItemType);
|
||||
return result;
|
||||
}
|
||||
|
||||
public DateTime? ActivatedDate { get; set; }
|
||||
public string AreaPath { get; set; }
|
||||
public string? AssignedTo { get; set; }
|
||||
public long? BusinessValue { get; set; }
|
||||
public DateTime ChangedDate { get; set; }
|
||||
public DateTime? ClosedDate { get; set; }
|
||||
public int CommentCount { get; set; }
|
||||
public DateTime CreatedDate { get; set; }
|
||||
public string Description { get; set; }
|
||||
public long? Effort { get; set; }
|
||||
public int Id { get; set; }
|
||||
public string IterationPath { get; set; }
|
||||
public int? Parent { get; set; }
|
||||
public int? Priority { get; set; }
|
||||
public Relation[]? Relations { get; set; }
|
||||
public string? Requester { get; set; }
|
||||
public DateTime? ResolvedDate { get; set; }
|
||||
public int Revision { get; set; }
|
||||
public long? RiskReductionMinusOpportunityEnablement { get; set; }
|
||||
public DateTime? StartDate { get; set; }
|
||||
public string State { get; set; }
|
||||
public string Tags { get; set; }
|
||||
public DateTime? TargetDate { get; set; }
|
||||
public long? TimeCriticality { get; set; }
|
||||
public string Title { get; set; }
|
||||
public string? Violation { get; set; }
|
||||
public string WorkItemType { get; set; }
|
||||
public long? WeightedShortestJobFirst { get; set; }
|
||||
public static WorkItem? GetWithOutRelations(WorkItem? workItem)
|
||||
{
|
||||
WorkItem? result = workItem is null ? null : new(activatedDate: workItem.ActivatedDate,
|
||||
areaPath: workItem.AreaPath,
|
||||
assignedTo: workItem.AssignedTo,
|
||||
businessValue: workItem.BusinessValue,
|
||||
changedDate: workItem.ChangedDate,
|
||||
closedDate: workItem.ClosedDate,
|
||||
commentCount: workItem.CommentCount,
|
||||
createdDate: workItem.CreatedDate,
|
||||
description: workItem.Description,
|
||||
effort: workItem.Effort,
|
||||
id: workItem.Id,
|
||||
iterationPath: workItem.IterationPath,
|
||||
parent: workItem.Parent,
|
||||
priority: workItem.Priority,
|
||||
relations: Array.Empty<Relation>(),
|
||||
remainingWork: workItem.RemainingWork,
|
||||
requester: workItem.Requester,
|
||||
resolvedDate: workItem.ResolvedDate,
|
||||
revision: workItem.Revision,
|
||||
riskReductionMinusOpportunityEnablement: workItem.RiskReductionMinusOpportunityEnablement,
|
||||
startDate: workItem.StartDate,
|
||||
state: workItem.State,
|
||||
storyPoints: workItem.StoryPoints,
|
||||
tags: workItem.Tags,
|
||||
targetDate: workItem.TargetDate,
|
||||
timeCriticality: workItem.TimeCriticality,
|
||||
title: workItem.Title,
|
||||
violation: workItem.Violation,
|
||||
weightedShortestJobFirst: workItem.WeightedShortestJobFirst,
|
||||
workItemType: workItem.WorkItemType);
|
||||
return result;
|
||||
}
|
||||
|
||||
[JsonPropertyName("ActivatedDate")] public DateTime? ActivatedDate { get; }
|
||||
[JsonPropertyName("AreaPath")] public string AreaPath { get; }
|
||||
[JsonPropertyName("AssignedTo")] public string? AssignedTo { get; }
|
||||
[JsonPropertyName("BusinessValue")] public long? BusinessValue { get; }
|
||||
[JsonPropertyName("ChangedDate")] public DateTime ChangedDate { get; }
|
||||
[JsonPropertyName("ClosedDate")] public DateTime? ClosedDate { get; }
|
||||
[JsonPropertyName("CommentCount")] public int CommentCount { get; }
|
||||
[JsonPropertyName("CreatedDate")] public DateTime CreatedDate { get; }
|
||||
[JsonPropertyName("Description")] public string Description { get; }
|
||||
[JsonPropertyName("Effort")] public long? Effort { get; }
|
||||
[JsonPropertyName("Id")] public int Id { get; }
|
||||
[JsonPropertyName("IterationPath")] public string IterationPath { get; }
|
||||
[JsonPropertyName("Parent")] public int? Parent { get; }
|
||||
[JsonPropertyName("Priority")] public int? Priority { get; }
|
||||
[JsonPropertyName("Relations")] public Relation[]? Relations { get; }
|
||||
[JsonPropertyName("RemainingWork")] public long? RemainingWork { get; }
|
||||
[JsonPropertyName("Requester")] public string? Requester { get; }
|
||||
[JsonPropertyName("ResolvedDate")] public DateTime? ResolvedDate { get; }
|
||||
[JsonPropertyName("Revision")] public int Revision { get; }
|
||||
[JsonPropertyName("RiskReductionMinusOpportunityEnablement")] public long? RiskReductionMinusOpportunityEnablement { get; }
|
||||
[JsonPropertyName("StartDate")] public DateTime? StartDate { get; }
|
||||
[JsonPropertyName("State")] public string State { get; }
|
||||
[JsonPropertyName("StoryPoints")] public long? StoryPoints { get; }
|
||||
[JsonPropertyName("Tags")] public string Tags { get; }
|
||||
[JsonPropertyName("TargetDate")] public DateTime? TargetDate { get; }
|
||||
[JsonPropertyName("TimeCriticality")] public long? TimeCriticality { get; }
|
||||
[JsonPropertyName("Title")] public string Title { get; }
|
||||
[JsonPropertyName("Violation")] public string? Violation { get; }
|
||||
[JsonPropertyName("WeightedShortestJobFirst")] public long? WeightedShortestJobFirst { get; }
|
||||
[JsonPropertyName("WorkItemType")] public string WorkItemType { get; }
|
||||
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(WorkItem))]
|
||||
internal partial class WorkItemSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
||||
|
||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||
[JsonSerializable(typeof(WorkItem[]))]
|
||||
internal partial class WorkItemCollectionSourceGenerationContext : JsonSerializerContext
|
||||
{
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user