This commit is contained in:
Mike Phares 2024-09-07 10:04:57 -07:00
parent 390090729b
commit 2301a9a9ee
31 changed files with 1121 additions and 1913 deletions

2
.gitignore vendored
View File

@ -343,3 +343,5 @@ ASALocalRun/
.kanbn
Adaptation/.kanbn
Adaptation/FileHandlers/json/StaticSite/json/work-items.json
Adaptation/FileHandlers/json/StaticSite/igniteui/**/*

View File

@ -114,6 +114,7 @@ public class FileRead : Shared.FileRead, IFileRead
}
}
}
#pragma warning disable IDE0060
private void MoveArchive(string reportFullPath, DateTime dateTime)
#pragma warning restore IDE0060

View File

@ -15,9 +15,7 @@ public class CellInstanceConnectionName
{
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(ConvertExcelToJson) => new ConvertExcelToJson.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null),
nameof(CopyToPaths) => new CopyToPaths.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null),
nameof(DownloadExcelFile) => new DownloadExcelFile.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null),
nameof(DownloadWorkItems) => new DownloadWorkItems.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null),
nameof(Dummy) => new Dummy.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null),
nameof(IQSSi) => new IQSSi.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null),
nameof(json) => new json.FileRead(smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null),

View File

@ -1,130 +0,0 @@
using System.Text.Json.Serialization;
namespace Adaptation.FileHandlers.ConvertExcelToJson;
public class FIBacklogMesa
{
[JsonConstructor]
public FIBacklogMesa(string req,
string submitted,
string requestor,
string assignedTo,
string secondResource,
string subject,
string epiLine,
string area,
string systemS,
string priority,
string status,
string definition,
string updates,
string estEffortDays,
string commitDate,
string reCommitDate,
string uATAsOf,
string cmpDate,
string f20,
string f21,
string f22,
string f23,
string f24,
string f25,
string f26,
string f27,
string f28,
string f29,
string f30,
string f31,
string f32,
string f33)
{
Req = req;
Submitted = submitted;
Requestor = requestor;
AssignedTo = assignedTo;
SecondResource = secondResource;
Subject = subject;
EpiLine = epiLine;
Area = area;
SystemS = systemS;
Priority = priority;
Status = status;
Definition = definition;
Updates = updates;
EstEffortDays = estEffortDays;
CommitDate = commitDate;
ReCommitDate = reCommitDate;
UATAsOf = uATAsOf;
CMPDate = cmpDate;
F20 = f20;
F21 = f21;
F22 = f22;
F23 = f23;
F24 = f24;
F25 = f25;
F26 = f26;
F27 = f27;
F28 = f28;
F29 = f29;
F30 = f30;
F31 = f31;
F32 = f32;
F33 = f33;
}
public string Req { get; set; } // { init; get; }
public string Submitted { get; set; } // { init; get; }
public string Requestor { get; set; } // { init; get; }
[JsonPropertyName("Assigned To")]
public string AssignedTo { get; set; } // { init; get; }
[JsonPropertyName("Second Resource")]
public string SecondResource { get; set; } // { init; get; }
[JsonPropertyName("Subject - from Requestor")]
public string Subject { get; set; } // { init; get; }
[JsonPropertyName("Epi Line")]
public string EpiLine { get; set; } // { init; get; }
public string Area { get; set; } // { init; get; }
[JsonPropertyName("System(s)")]
public string SystemS { get; set; } // { init; get; }
public string Priority { get; set; } // { init; get; }
public string Status { get; set; } // { init; get; }
[JsonPropertyName("Definition - from FI")]
public string Definition { get; set; } // { init; get; }
public string Updates { get; set; } // { init; get; }
[JsonPropertyName("Est Effort _(days)")]
public string EstEffortDays { get; set; } // { init; get; }
[JsonPropertyName("Commit Date")]
public string CommitDate { get; set; } // { init; get; }
[JsonPropertyName("Re-Commit Date")]
public string ReCommitDate { get; set; } // { init; get; }
[JsonPropertyName("UAT as of")]
public string UATAsOf { get; set; } // { init; get; }
[JsonPropertyName("CMP _Date")]
public string CMPDate { get; set; } // { init; get; }
public string F20 { get; set; } // { init; get; }
public string F21 { get; set; } // { init; get; }
public string F22 { get; set; } // { init; get; }
public string F23 { get; set; } // { init; get; }
public string F24 { get; set; } // { init; get; }
public string F25 { get; set; } // { init; get; }
public string F26 { get; set; } // { init; get; }
public string F27 { get; set; } // { init; get; }
public string F28 { get; set; } // { init; get; }
public string F29 { get; set; } // { init; get; }
public string F30 { get; set; } // { init; get; }
public string F31 { get; set; } // { init; get; }
public string F32 { get; set; } // { init; get; }
public string F33 { get; set; } // { init; get; }
}

View File

@ -1,128 +0,0 @@
using Adaptation.Eaf.Management.ConfigurationData.CellAutomation;
using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration;
using Adaptation.Shared;
using Adaptation.Shared.Duplicator;
using Adaptation.Shared.Methods;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.Json;
using System.Threading;
namespace Adaptation.FileHandlers.ConvertExcelToJson;
public class FileRead : Shared.FileRead, IFileRead
{
private long? _TickOffset;
private readonly string _SheetName;
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);
_SheetName = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, string.Concat("CellInstance.", cellInstanceName, ".Excel.SheetName"));
}
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 ??= new FileInfo(reportFullPath).LastWriteTime.Ticks - dateTime.Ticks;
_Logistics = new Logistics(this, _TickOffset.Value, reportFullPath, useSplitForMID: true);
SetFileParameterLotIDToLogisticsMID();
if (_Logistics.FileInfo.Length < _MinFileLength)
results.Item4.Add(_Logistics.FileInfo);
else
{
IProcessData iProcessData = new ProcessData(this, _Logistics, results.Item4, _SheetName);
if (iProcessData.Details.Count == 0)
throw new Exception(string.Concat("B) No Data - ", dateTime.Ticks));
string json = iProcessData.Details[0].ToString();
string fileName = Path.Combine(_FileConnectorConfiguration.TargetFileLocation, $"{Path.GetFileNameWithoutExtension(reportFullPath)} - {_SheetName}{_FileConnectorConfiguration.TargetFileName}");
if (File.Exists(fileName))
{
if (_IsEAFHosted)
File.Delete(fileName);
Thread.Sleep(500);
}
if (_IsEAFHosted)
File.WriteAllText(fileName, json);
results = iProcessData.GetResults(this, _Logistics, results.Item4);
}
return results;
}
}

View File

@ -1,177 +0,0 @@
using Adaptation.Shared;
using Adaptation.Shared.Methods;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
namespace Adaptation.FileHandlers.ConvertExcelToJson;
public class ProcessData : IProcessData
{
private readonly List<object> _Details;
List<object> Shared.Properties.IProcessData.Details => _Details;
public ProcessData(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection, string sheetName)
{
fileInfoCollection.Clear();
_Details = new List<object>();
Parse(fileRead, logistics, fileInfoCollection, sheetName);
}
string IProcessData.GetCurrentReactor(IFileRead fileRead, Logistics logistics, Dictionary<string, string> reactors) =>
throw new Exception(string.Concat("See ", nameof(Parse)));
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
/// <summary>
/// https://social.msdn.microsoft.com/Forums/en-US/2e030743-5d66-4e53-bbff-bb2eee0cbc9b/readingwriting-excel-without-excel?forum=Vsexpressvcs
/// </summary>
private static DataTable GetSheet(string file, string selectSql)
{
DataTable results = new();
#if Linux
()("Built on Linux!");
#elif OSX
()("Built on macOS!");
#elif Windows || !NETCORE
#pragma warning disable CA1416
for (int i = 0; i < int.MaxValue; i++)
{
try
{
OleDbConnectionStringBuilder connectionStringBuilder = new()
{
Provider = "Microsoft.ACE.OLEDB.12.0",
DataSource = file
};
connectionStringBuilder.Add("Extended Properties", "Excel 12.0 Xml;HDR=YES;IMEX=1;ReadOnly=1;");
using OleDbConnection connection = new(connectionStringBuilder.ConnectionString);
connection.Open();
using (OleDbDataAdapter adapter = new(selectSql, connection))
adapter.Fill(results);
connection.Close();
break;
}
catch (Exception)
{
if (i > 3) //2019-12-28 - 001
throw;
System.Threading.Thread.Sleep(1000);
}
#pragma warning restore CA1416
}
#else
()("Built in unknown!");
#endif
return results;
}
public static string DataTableToJSON(DataTable table)
{
string name;
string value;
object @object;
StringBuilder jsonString = new();
if (table.Rows.Count > 0)
{
_ = jsonString.Append('[');
for (int i = 0; i < table.Rows.Count; i++)
{
_ = jsonString.Append('{');
for (int j = 0; j < table.Columns.Count; j++)
{
@object = table.Rows[i][j];
if (@object is null)
value = string.Empty;
else
value = JsonSerializer.Serialize(@object.ToString());
if (value.Contains("\\n"))
value = value.Replace("\\n", "<br>");
if (value.Contains("\\t"))
value = value.Replace("\\t", " ");
name = JsonSerializer.Serialize(table.Columns[j].ColumnName.ToString().Trim());
if (name.Contains("\\n"))
name = name.Replace("\\n", "<br>");
if (name.Contains("\\t"))
name = name.Replace("\\t", " ");
_ = jsonString.Append(name).Append(':').Append(value);
if (j < table.Columns.Count - 1)
_ = jsonString.Append(',');
}
if (i == table.Rows.Count - 1)
_ = jsonString.Append('}');
else
_ = jsonString.Append("},");
}
_ = jsonString.Append(']');
}
return jsonString.ToString();
}
private static List<FIBacklogMesa> Parse(IFileRead fileRead, JsonElement[] jsonElements)
{
string key;
string json;
FIBacklogMesa? fiBacklogMesa;
JsonProperty[] jsonProperties;
List<FIBacklogMesa> fiBacklogMesaCollection = new();
foreach (JsonElement jsonElement in jsonElements)
{
if (jsonElement.ValueKind != JsonValueKind.Object)
continue;
jsonProperties = jsonElement.EnumerateObject().ToArray();
if (jsonProperties.Length < 2)
continue;
key = jsonProperties[0].Value.ToString();
if (string.IsNullOrEmpty(key))
continue;
json = jsonElement.ToString();
if (!fileRead.IsEAFHosted)
File.WriteAllText(".json", json);
fiBacklogMesa = JsonSerializer.Deserialize<FIBacklogMesa>(json);
if (fiBacklogMesa is null)
throw new NullReferenceException();
fiBacklogMesaCollection.Add(fiBacklogMesa);
}
return fiBacklogMesaCollection;
}
private void Parse(IFileRead fileRead, Logistics logistics, List<FileInfo> fileInfoCollection, string sheet)
{
if (fileRead is null)
throw new NullReferenceException();
if (fileInfoCollection is null)
throw new NullReferenceException();
string selectSql = string.Concat("SELECT * FROM [", sheet, "$]");
DataTable dataTable = GetSheet(logistics.ReportFullPath, selectSql);
if (dataTable.Rows.Count == 0)
throw new Exception("No rows");
string json = DataTableToJSON(dataTable);
if (!fileRead.IsEAFHosted)
File.WriteAllText(".json", json);
JsonElement[]? jsonElements = JsonSerializer.Deserialize<JsonElement[]>(json, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
if (jsonElements is null || jsonElements.Length == 0)
throw new NullReferenceException();
if (!fileRead.ReportFullPath.Contains("Backlog"))
json = JsonSerializer.Serialize(jsonElements, new JsonSerializerOptions() { WriteIndented = true });
else
{
List<FIBacklogMesa> fiBacklogMesaCollection = Parse(fileRead, jsonElements);
json = JsonSerializer.Serialize(from l in fiBacklogMesaCollection orderby l.Req.Length, l.Req select l, new JsonSerializerOptions() { WriteIndented = true });
}
if (!fileRead.IsEAFHosted)
File.WriteAllText(".json", json);
_Details.Add(json);
}
}

View File

@ -1,135 +0,0 @@
using Adaptation.Eaf.Management.ConfigurationData.CellAutomation;
using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration;
using Adaptation.Shared;
using Adaptation.Shared.Duplicator;
using Adaptation.Shared.Methods;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Text.Json;
using System.Threading;
namespace Adaptation.FileHandlers.CopyToPaths;
public class FileRead : Shared.FileRead, IFileRead
{
private readonly ReadOnlyDictionary<string, string> _CopyToPaths;
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);
Dictionary<string, string> copyToPaths = new();
string cellInstancecellInstanceConnectionNamed = string.Concat("CellInstance.", cellInstanceName, '.', cellInstanceConnectionName, '.');
ModelObjectParameterDefinition[] modelObjectParameterDefinitions = GetProperties(cellInstanceConnectionName, modelObjectParameters, cellInstancecellInstanceConnectionNamed);
foreach (ModelObjectParameterDefinition modelObjectParameterDefinition in modelObjectParameterDefinitions)
copyToPaths.Add(modelObjectParameterDefinition.Name.Split('.')[3], modelObjectParameterDefinition.Value);
_CopyToPaths = new(copyToPaths);
}
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;
string path;
string checkDirectory;
string ticks = dateTime.Ticks.ToString();
string fileExtension = Path.GetExtension(reportFullPath);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(reportFullPath);
_Logistics = new Logistics(reportFullPath, $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};");
foreach (KeyValuePair<string, string> keyValuePair in _CopyToPaths)
{
path = keyValuePair.Value.Replace("%OriginalFileName%", fileNameWithoutExtension).Replace("%OriginalFileExtension%", fileExtension).Replace($".{fileExtension}", fileExtension);
checkDirectory = Path.GetDirectoryName(path);
if (string.IsNullOrEmpty(checkDirectory))
continue;
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(Path.Combine(checkDirectory, ticks));
if (File.Exists(path))
{
if (_IsEAFHosted)
File.Delete(path);
Thread.Sleep(500);
}
if (_IsEAFHosted)
File.Copy(reportFullPath, path);
}
results = new(_Logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), new List<FileInfo>());
return results;
}
}

View File

@ -1,166 +0,0 @@
using Adaptation.Eaf.Management.ConfigurationData.CellAutomation;
using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration;
using Adaptation.Shared;
using Adaptation.Shared.Duplicator;
using Adaptation.Shared.Methods;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
namespace Adaptation.FileHandlers.DownloadExcelFile;
public class FileRead : Shared.FileRead, IFileRead
{
private readonly Timer _Timer;
private readonly string _IShareLink;
private readonly HttpClient _HttpClient;
public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) :
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);
_HttpClient = new(new HttpClientHandler() { UseDefaultCredentials = true });
_IShareLink = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, string.Concat("CellInstance.", cellInstanceName, ".iShare.Link"));
if (!Debugger.IsAttached && fileConnectorConfiguration.PreProcessingMode != FileConnectorConfiguration.PreProcessingModeEnum.Process)
_Timer = new Timer(Callback, null, (int)(fileConnectorConfiguration.FileScanningIntervalInSeconds * 1000), Timeout.Infinite);
else
{
_Timer = new Timer(Callback, null, Timeout.Infinite, Timeout.Infinite);
Callback(null);
}
}
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) => throw new Exception(string.Concat("See ", nameof(Callback)));
private void DownloadExcelFileAsync()
{
if (_HttpClient is null)
throw new Exception();
if (string.IsNullOrEmpty(_IShareLink))
throw new Exception();
string fileName = Path.Combine(_FileConnectorConfiguration.TargetFileLocation, _FileConnectorConfiguration.SourceFileFilter);
if (File.Exists(fileName))
File.Delete(fileName);
Task<HttpResponseMessage> httpResponseMessageTask = _HttpClient.GetAsync(_IShareLink);
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
if (!streamTask.Result.CanRead)
throw new NullReferenceException(nameof(streamTask));
using FileStream fileStream = new(fileName, FileMode.CreateNew);
Task task = streamTask.Result.CopyToAsync(fileStream);
task.Wait();
}
private void Callback(object state)
{
try
{
if (_IsEAFHosted)
DownloadExcelFileAsync();
}
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
{
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) { }
}
}
}

View File

@ -0,0 +1,243 @@
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.Diagnostics;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
namespace Adaptation.FileHandlers.DownloadWorkItems;
public class FileRead : Shared.FileRead, IFileRead
{
internal static string Json { get; private set; }
private readonly string _API;
private readonly Timer _Timer;
private readonly string _Query;
private readonly string _BasePage;
private readonly HttpClient _HttpClient;
public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) :
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);
Dictionary<string, string> requestorNameToUser = new();
Dictionary<string, string> assignedToNameToUser = new();
Dictionary<string, string> assignedToNameToEncodedPAT = new();
string cellInstanceNamed = string.Concat("CellInstance.", _EquipmentType);
MediaTypeWithQualityHeaderValue mediaTypeWithQualityHeaderValue = new("application/json");
_API = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.HttpClient.API");
_Query = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.HttpClient.Query");
string pat = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.HttpClient.PAT");
string basePage = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.HttpClient.BasePage");
string baseAddress = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.HttpClient.BaseAddress");
byte[] bytes = Encoding.ASCII.GetBytes($":{pat}");
string base64 = Convert.ToBase64String(bytes);
_HttpClient = new(new HttpClientHandler() { UseDefaultCredentials = true }) { BaseAddress = new(baseAddress) };
_HttpClient.DefaultRequestHeaders.Authorization = new("Basic", base64);
_HttpClient.DefaultRequestHeaders.Accept.Add(mediaTypeWithQualityHeaderValue);
_BasePage = basePage;
if (!Debugger.IsAttached && fileConnectorConfiguration.PreProcessingMode != FileConnectorConfiguration.PreProcessingModeEnum.Process)
_Timer = new Timer(Callback, null, (int)(fileConnectorConfiguration.FileScanningIntervalInSeconds * 1000), Timeout.Infinite);
else
{
_Timer = new Timer(Callback, null, Timeout.Infinite, Timeout.Infinite);
Callback(null);
}
}
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) => throw new Exception(string.Concat("See ", nameof(Callback)));
#nullable enable
private static string GetIds(HttpClient httpClient, string basePage, string api, string query)
{
List<int> results = new();
StringBuilder result = new();
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync(string.Concat(basePage, api, query));
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
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);
streamTask.Result.Dispose();
if (root is null || root.WorkItems is null)
throw new NullReferenceException(nameof(root));
foreach (json.WIQL.WorkItem workItem in root.WorkItems)
{
results.Add(workItem.Id);
if (results.Count > 199)
break;
}
foreach (int id in results)
_ = result.Append(id).Append(',');
if (result.Length > 0)
_ = result.Remove(result.Length - 1, 1);
return result.ToString();
}
private static void DownloadWorkItemsAsync(HttpClient httpClient, string basePage, string api, string targetFileLocation, string ids, long ticks)
{
string json;
string file;
int i = 100000;
JsonElement[] jsonElements;
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync(string.Concat(basePage, api, $"/workitems?ids={ids}"));
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
if (!streamTask.Result.CanRead)
throw new NullReferenceException(nameof(streamTask));
JsonElement? result = JsonSerializer.Deserialize<JsonElement>(streamTask.Result);
if (result is null || result.Value.ValueKind != JsonValueKind.Object)
throw new NullReferenceException(nameof(result));
JsonProperty[] jsonProperties = result.Value.EnumerateObject().ToArray();
foreach (JsonProperty jsonProperty in jsonProperties)
{
if (jsonProperty.Value.ValueKind != JsonValueKind.Array)
continue;
jsonElements = jsonProperty.Value.EnumerateArray().ToArray();
foreach (JsonElement jsonElement in jsonElements)
{
json = jsonElement.GetRawText();
file = Path.Combine(targetFileLocation, $"{ticks}-{i}.json");
File.WriteAllText(file, json);
i += 1;
}
}
}
private static void DownloadWorkItemsAsync(HttpClient httpClient,
string targetFileLocation,
string basePage,
string api,
string query)
{
long tick = DateTime.Now.Ticks;
string ids = GetIds(httpClient, basePage, api, query);
DownloadWorkItemsAsync(httpClient, basePage, api, targetFileLocation, ids, tick);
}
private void Callback(object state)
{
try
{
if (_IsEAFHosted)
DownloadWorkItemsAsync(_HttpClient, _FileConnectorConfiguration.TargetFileLocation, _BasePage, _API, _Query);
}
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) { }
}
}
}

View File

@ -1,4 +1,5 @@
using Adaptation.Eaf.Management.ConfigurationData.CellAutomation;
using Adaptation.FileHandlers.json.WorkItems;
using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration;
using Adaptation.Shared;
using Adaptation.Shared.Duplicator;
@ -7,9 +8,7 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Text.RegularExpressions;
namespace Adaptation.FileHandlers.Kanban;
@ -110,13 +109,42 @@ public class FileRead : Shared.FileRead, IFileRead
return results;
}
private void Save(string key, string fileNameWithoutExtension, string rootDirectory, JsonElement jsonElement)
#nullable enable
private void Save(string fileNameWithoutExtension, WorkItem[] workItems)
{
string old;
string json;
string checkFile;
string tasksDirectory;
string kanbanDirectory;
string vscodeDirectory;
string singletonDirectory;
List<string> indexLines = new();
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
string rootDirectory = Path.Combine(_FileConnectorConfiguration.TargetFileLocation, fileNameWithoutExtension);
if (string.IsNullOrEmpty(rootDirectory))
throw new NullReferenceException(nameof(rootDirectory));
foreach (WorkItem workItem in workItems)
{
json = JsonSerializer.Serialize(workItem, jsonSerializerOptions);
singletonDirectory = Path.Combine(rootDirectory, workItem.WorkItemType.Replace(" ", "-"), $"{workItem.Id}-{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);
checkFile = Path.Combine(vscodeDirectory, "settings.json");
if (!File.Exists(checkFile))
File.WriteAllText(checkFile, "{ \"[markdown]\": { \"editor.wordWrap\": \"off\" }, \"cSpell.words\": [ \"kanbn\" ] }");
indexLines.Clear();
indexLines.AddRange(_FrontMatterLines);
indexLines.Add(string.Empty);
indexLines.Add($"# {key}");
indexLines.Add($"# {workItem.Id}");
indexLines.Add(string.Empty);
indexLines.Add("## Backlog");
indexLines.Add(string.Empty);
@ -125,68 +153,42 @@ public class FileRead : Shared.FileRead, IFileRead
indexLines.Add("## In Progress");
indexLines.Add(string.Empty);
indexLines.Add("## Done");
string singletonDirectory = Path.Combine(rootDirectory, $"{key}-{fileNameWithoutExtension}");
string vscodeDirectory = Path.Combine(singletonDirectory, ".vscode");
if (!Directory.Exists(vscodeDirectory))
_ = Directory.CreateDirectory(vscodeDirectory);
checkFile = Path.Combine(vscodeDirectory, "settings.json");
if (!File.Exists(checkFile))
File.WriteAllText(checkFile, "{ \"[markdown]\": { \"editor.wordWrap\": \"off\" }, \"cSpell.words\": [ \"kanbn\" ] }");
string kanbanDirectory = Path.Combine(singletonDirectory, ".kanbn");
if (!Directory.Exists(kanbanDirectory))
_ = Directory.CreateDirectory(kanbanDirectory);
checkFile = Path.Combine(kanbanDirectory, ".json");
if (!File.Exists(checkFile))
File.WriteAllText(checkFile, jsonElement.ToString());
else
{
string singletonJson = jsonElement.ToString();
string checkJson = Regex.Replace(File.ReadAllText(checkFile), @"\s+", " ", RegexOptions.Multiline);
if (Regex.Replace(singletonJson, @"\s+", " ", RegexOptions.Multiline) != checkJson)
File.WriteAllText(checkFile, singletonJson);
}
string tasksDirectory = Path.Combine(kanbanDirectory, "tasks");
if (!Directory.Exists(tasksDirectory))
_ = Directory.CreateDirectory(tasksDirectory);
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.WriteAllLines(checkFile, indexLines);
checkFile = Path.Combine(kanbanDirectory, ".json");
if (File.Exists(checkFile))
{
old = File.ReadAllText(checkFile);
if (old == json)
continue;
}
File.WriteAllText(checkFile, json);
}
}
#pragma warning disable IDE0060
private void Save(string reportFullPath, DateTime dateTime)
#pragma warning restore IDE0060
{
string json = File.ReadAllText(reportFullPath);
WorkItem[]? workItems = JsonSerializer.Deserialize<WorkItem[]>(json);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(reportFullPath);
if (workItems is null)
throw new Exception(nameof(workItems));
if (workItems.Length > 0)
Save(fileNameWithoutExtension, workItems);
}
private Tuple<string, Test[], JsonElement[], List<FileInfo>> GetExtractResult(string reportFullPath, DateTime dateTime)
{
Tuple<string, Test[], JsonElement[], List<FileInfo>> results;
string key;
JsonProperty[] jsonProperties;
string ticks = dateTime.Ticks.ToString();
_Logistics = new Logistics(reportFullPath, $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};");
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(reportFullPath).Replace(" ", "-").Replace("---", "-");
string rootDirectory = Path.Combine(_FileConnectorConfiguration.SourceFileLocation, fileNameWithoutExtension);
if (string.IsNullOrEmpty(rootDirectory))
throw new NullReferenceException(nameof(rootDirectory));
if (!Directory.Exists(rootDirectory))
_ = Directory.CreateDirectory(Path.Combine(rootDirectory, ticks));
string json = File.ReadAllText(reportFullPath);
JsonElement[] jsonElements = JsonSerializer.Deserialize<JsonElement[]>(json);
foreach (JsonElement jsonElement in jsonElements)
{
if (jsonElement.ValueKind != JsonValueKind.Object)
continue;
jsonProperties = jsonElement.EnumerateObject().ToArray();
if (jsonProperties.Length < 2)
continue;
key = jsonProperties[0].Value.ToString();
if (string.IsNullOrEmpty(key))
continue;
if (string.IsNullOrEmpty(jsonProperties[1].Value.ToString()))
continue;
Save(key, fileNameWithoutExtension, rootDirectory, jsonElement);
if (!_IsEAFHosted)
break;
}
if (_IsEAFHosted)
Save(reportFullPath, dateTime);
results = new(_Logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), new List<FileInfo>());
return results;
}

View File

@ -1,86 +1,44 @@
using Adaptation.Eaf.Management.ConfigurationData.CellAutomation;
using Adaptation.FileHandlers.json.WorkItems;
using Adaptation.Ifx.Eaf.EquipmentConnector.File.Configuration;
using Adaptation.Shared;
using Adaptation.Shared.Duplicator;
using Adaptation.Shared.Methods;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
using Microsoft.VisualStudio.Services.Common;
using Microsoft.VisualStudio.Services.WebApi;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Linq;
using System.Text.Json;
using System.Threading;
namespace Adaptation.FileHandlers.json;
public class FileRead : Shared.FileRead, IFileRead
{
internal static string Json { get; private set; }
private readonly string _API;
private readonly string _Query;
private readonly string _Project;
private readonly string _BasePage;
private readonly HttpClient _HttpClient;
private string _LastDateForcedUpdatedBy;
private string _LastDateDeleteForcedUpdatedBy;
private readonly WorkItemTrackingHttpClient _WorkItemTrackingHttpClient;
private readonly ReadOnlyDictionary<string, string> _RequestorNameToUser;
private readonly ReadOnlyDictionary<string, string> _AssignedToNameToUser;
private readonly ReadOnlyDictionary<string, string> _AssignedToNameToEncodedPAT;
private readonly Timer _Timer;
public FileRead(ISMTP smtp, Dictionary<string, string> fileParameter, string cellInstanceName, int? connectionCount, string cellInstanceConnectionName, FileConnectorConfiguration fileConnectorConfiguration, string equipmentTypeName, string parameterizedModelObjectDefinitionType, IList<ModelObjectParameterDefinition> modelObjectParameters, string equipmentDictionaryName, Dictionary<string, List<long>> dummyRuns, Dictionary<long, List<string>> staticRuns, bool useCyclicalForDescription, bool isEAFHosted) :
base(new Description(), false, smtp, fileParameter, cellInstanceName, connectionCount, cellInstanceConnectionName, fileConnectorConfiguration, equipmentTypeName, parameterizedModelObjectDefinitionType, modelObjectParameters, equipmentDictionaryName, dummyRuns, staticRuns, useCyclicalForDescription, isEAFHosted: connectionCount is null)
{
_MinFileLength = 10;
Json = string.Empty;
_NullData = string.Empty;
_Logistics = new(this);
if (_FileParameter is null)
throw new Exception(cellInstanceConnectionName);
if (_ModelObjectParameterDefinitions is null)
throw new Exception(cellInstanceConnectionName);
if (!_IsDuplicator)
if (_IsDuplicator)
throw new Exception(cellInstanceConnectionName);
_LastDateForcedUpdatedBy = string.Empty;
_LastDateDeleteForcedUpdatedBy = string.Empty;
Dictionary<string, string> requestorNameToUser = new();
Dictionary<string, string> assignedToNameToUser = new();
Dictionary<string, string> assignedToNameToEncodedPAT = new();
string cellInstanceNamed = string.Concat("CellInstance.", cellInstanceName);
MediaTypeWithQualityHeaderValue mediaTypeWithQualityHeaderValue = new("application/json");
_API = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.HttpClient.API");
_Query = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.HttpClient.Query");
string pat = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.HttpClient.PAT");
_Project = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.HttpClient.Project");
string basePage = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.HttpClient.BasePage");
string baseAddress = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.HttpClient.BaseAddress");
ModelObjectParameterDefinition[] assignedTo = GetProperties(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.Assinged.To.");
foreach (ModelObjectParameterDefinition modelObjectParameterDefinition in assignedTo)
assignedToNameToUser.Add(modelObjectParameterDefinition.Name.Split('.')[4], modelObjectParameterDefinition.Value);
_AssignedToNameToUser = new(assignedToNameToUser);
ModelObjectParameterDefinition[] requestor = GetProperties(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.Requestor.");
foreach (ModelObjectParameterDefinition modelObjectParameterDefinition in requestor)
requestorNameToUser.Add(modelObjectParameterDefinition.Name.Split('.')[3], modelObjectParameterDefinition.Value);
_RequestorNameToUser = new(requestorNameToUser);
ModelObjectParameterDefinition[] encodedPAT = GetProperties(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.Encoded.PAT.");
foreach (ModelObjectParameterDefinition modelObjectParameterDefinition in encodedPAT)
assignedToNameToEncodedPAT.Add(modelObjectParameterDefinition.Name.Split('.')[4], modelObjectParameterDefinition.Value);
_AssignedToNameToEncodedPAT = new(assignedToNameToEncodedPAT);
byte[] bytes = Encoding.ASCII.GetBytes($":{pat}");
string base64 = Convert.ToBase64String(bytes);
_HttpClient = new(new HttpClientHandler() { UseDefaultCredentials = true }) { BaseAddress = new(baseAddress) };
_HttpClient.DefaultRequestHeaders.Authorization = new("Basic", base64);
_HttpClient.DefaultRequestHeaders.Accept.Add(mediaTypeWithQualityHeaderValue);
VssBasicCredential credential = new("", pat);
VssConnection connection = new(new(string.Concat(baseAddress, basePage)), credential);
_WorkItemTrackingHttpClient = connection.GetClient<WorkItemTrackingHttpClient>();
_BasePage = basePage;
if (!Debugger.IsAttached && fileConnectorConfiguration.PreProcessingMode != FileConnectorConfiguration.PreProcessingModeEnum.Process)
_Timer = new Timer(Callback, null, (int)(fileConnectorConfiguration.FileScanningIntervalInSeconds * 1000), Timeout.Infinite);
else
{
_Timer = new Timer(Callback, null, Timeout.Infinite, Timeout.Infinite);
Callback(null);
}
}
void IFileRead.Move(Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResults, Exception exception) => Move(extractResults);
@ -148,44 +106,175 @@ public class FileRead : Shared.FileRead, IFileRead
return results;
}
#nullable enable
private static void ParseWorkItemsAsync(FileConnectorConfiguration fileConnectorConfiguration, string[] alternateTargetFolders, ReadOnlyCollection<WorkItem> workItems)
{
bool writeFile;
string checkFile;
string? pathRoot;
JsonSerializerOptions jsonSerializerOptions = new() { WriteIndented = true };
string json = JsonSerializer.Serialize(workItems, jsonSerializerOptions);
foreach (string alternateTargetFolder in alternateTargetFolders)
{
writeFile = true;
if (alternateTargetFolder == fileConnectorConfiguration.TargetFileLocation)
continue;
pathRoot = Path.GetPathRoot(alternateTargetFolder);
try
{
if (!Directory.Exists(pathRoot))
continue;
}
catch (Exception)
{ continue; }
if (!Directory.Exists(alternateTargetFolder))
_ = Directory.CreateDirectory(alternateTargetFolder);
checkFile = Path.Combine(alternateTargetFolder, fileConnectorConfiguration.TargetFileName);
if (File.Exists(checkFile))
{
string old = File.ReadAllText(checkFile);
if (old == json)
writeFile = false;
}
if (writeFile)
File.WriteAllText(checkFile, json);
}
}
private static ReadOnlyCollection<WorkItem> GetWorkItems(ReadOnlyCollection<Value> valueWithReqCollection)
{
List<WorkItem> results = new();
Fields fields;
WorkItem workItem;
foreach (Value value in valueWithReqCollection)
{
fields = value.Fields;
workItem = new(fields.SystemAreaPath,
fields.SystemAssignedTo?.DisplayName,
fields.MicrosoftVSTSCommonBusinessValue == 0 ? null : fields.MicrosoftVSTSCommonBusinessValue,
fields.SystemChangedDate,
fields.MicrosoftVSTSCommonClosedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonClosedDate,
fields.SystemCommentCount,
fields.SystemCreatedDate,
fields.SystemDescription,
fields.MicrosoftVSTSSchedulingEffort == 0 ? null : fields.MicrosoftVSTSSchedulingEffort,
value.Id,
fields.SystemIterationPath,
fields.MicrosoftVSTSCommonPriority == 0 ? null : fields.MicrosoftVSTSCommonPriority,
fields.CustomRequester?.DisplayName,
fields.MicrosoftVSTSCommonResolvedDate == DateTime.MinValue ? null : fields.MicrosoftVSTSCommonResolvedDate,
value.Rev,
fields.CustomRRminusOE == 0 ? null : fields.CustomRRminusOE,
fields.MicrosoftVSTSSchedulingStartDate == DateTime.MinValue ? null : fields.MicrosoftVSTSSchedulingStartDate,
fields.SystemState,
fields.SystemTags,
fields.MicrosoftVSTSSchedulingTargetDate == DateTime.MinValue ? null : fields.MicrosoftVSTSSchedulingTargetDate,
fields.MicrosoftVSTSCommonTimeCriticality == 0 ? null : fields.MicrosoftVSTSCommonTimeCriticality,
fields.SystemTitle,
fields.SystemWorkItemType,
fields.CustomWSJF == 0 ? null : fields.CustomWSJF);
results.Add(workItem);
}
return new(results);
}
private static ReadOnlyCollection<Value> GetWorkItems(string[] files)
{
List<Value> results = new();
string json;
Value? value;
foreach (string file in from l in files orderby l.Length, l select l)
{
json = File.ReadAllText(file);
value = JsonSerializer.Deserialize<Value>(json);
if (value is null)
continue;
results.Add(value);
}
return new(results);
}
private static void ParseWorkItemsAsync(FileConnectorConfiguration fileConnectorConfiguration, string[] alternateTargetFolders)
{
if (!Directory.Exists(fileConnectorConfiguration.TargetFileLocation))
_ = Directory.CreateDirectory(fileConnectorConfiguration.TargetFileLocation);
string[] files = Directory.GetFiles(fileConnectorConfiguration.TargetFileLocation, fileConnectorConfiguration.SourceFileFilter, SearchOption.TopDirectoryOnly);
ReadOnlyCollection<Value> collection = GetWorkItems(files);
ReadOnlyCollection<WorkItem> workItems = GetWorkItems(collection);
if (workItems.Count > 0)
ParseWorkItemsAsync(fileConnectorConfiguration, alternateTargetFolders, workItems);
}
private static void ParseWorkItemsAsync(FileConnectorConfiguration fileConnectorConfiguration)
{
string[] alternateTargetFolders = fileConnectorConfiguration.AlternateTargetFolder.Split('|');
if (alternateTargetFolders.Length > 0)
ParseWorkItemsAsync(fileConnectorConfiguration, alternateTargetFolders);
}
private void Callback(object state)
{
try
{
if (_IsEAFHosted)
ParseWorkItemsAsync(_FileConnectorConfiguration);
}
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 void MoveJson(string reportFullPath, DateTime dateTime)
#pragma warning restore IDE0060
{
bool moveFile = true;
string json = File.ReadAllText(reportFullPath);
Value? value = JsonSerializer.Deserialize<Value>(json);
if (value is null)
throw new Exception(nameof(value));
string checkFile = Path.Combine(_FileConnectorConfiguration.TargetFileLocation, $"{value.Id}.json");
if (File.Exists(checkFile))
{
string old = File.ReadAllText(checkFile);
if (json == old)
{
moveFile = false;
File.Delete(reportFullPath);
}
}
if (moveFile)
File.Move(reportFullPath, checkFile);
}
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, Test[], JsonElement[], List<FileInfo>> results;
_Logistics = new Logistics(reportFullPath, $"LOGISTICS_1{'\t'}A_JOBID={"BACKLOG"};A_MES_ENTITY={"BACKLOG"};");
string json = File.ReadAllText(reportFullPath);
if (Json == json)
results.Item4.Add(_Logistics.FileInfo);
else
{
string formattedDateTime = dateTime.ToString("yyyy-MM-dd");
bool forceUpdatedBy = false; // !_IsEAFHosted || (dateTime.DayOfWeek == DayOfWeek.Thursday && dateTime.Hour == 12 && _LastDateForcedUpdatedBy != formattedDateTime);
if (forceUpdatedBy)
_LastDateForcedUpdatedBy = formattedDateTime;
bool forceDeleteUpdatedBy = false; // !_IsEAFHosted || (dateTime.DayOfWeek == DayOfWeek.Thursday && dateTime.Hour == 18 && _LastDateDeleteForcedUpdatedBy != formattedDateTime);
if (forceDeleteUpdatedBy)
_LastDateDeleteForcedUpdatedBy = formattedDateTime;
IProcessData iProcessData = new ProcessData(this,
_Logistics,
results.Item4,
_HttpClient,
_BasePage,
_API,
_Query,
_WorkItemTrackingHttpClient,
_Project,
_AssignedToNameToEncodedPAT,
_AssignedToNameToUser,
_RequestorNameToUser,
json,
forceUpdatedBy,
forceDeleteUpdatedBy);
if (iProcessData is not ProcessData _)
throw new Exception(string.Concat("A) No Data - ", dateTime.Ticks));
if (iProcessData.Details.Count == 0)
throw new Exception(string.Concat("B) No Data - ", dateTime.Ticks));
results = iProcessData.GetResults(this, _Logistics, results.Item4);
Json = json;
}
if (_IsEAFHosted && _FileConnectorConfiguration.FileScanningIntervalInSeconds > 0)
MoveJson(reportFullPath, dateTime);
results = new(_Logistics.Logistics1[0], Array.Empty<Test>(), Array.Empty<JsonElement>(), new List<FileInfo>());
return results;
}

View File

@ -1,24 +1,13 @@
using Adaptation.FileHandlers.ConvertExcelToJson;
using Adaptation.FileHandlers.json.WorkItems;
using Adaptation.Shared;
using Adaptation.Shared.Duplicator;
using Adaptation.Shared.Methods;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models;
using Microsoft.VisualStudio.Services.WebApi.Patch;
using Microsoft.VisualStudio.Services.WebApi.Patch.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
namespace Adaptation.FileHandlers.json;
@ -47,21 +36,7 @@ public class ProcessData : IProcessData
{
fileInfoCollection.Clear();
_Details = new List<object>();
Parse(fileRead,
logistics,
fileInfoCollection,
httpClient,
basePage,
api,
query,
workItemTrackingHttpClient,
project,
assignedToNameToEncodedPAT,
assignedToNameToUser,
requestorNameToUser,
json,
forceUpdatedBy,
forceDeleteUpdatedBy);
Parse();
}
string IProcessData.GetCurrentReactor(IFileRead fileRead, Logistics logistics, Dictionary<string, string> reactors) =>
@ -73,724 +48,7 @@ public class ProcessData : IProcessData
internal static List<Description> GetDescriptions(JsonElement[] jsonElements) =>
throw new NotImplementedException();
#nullable enable
private static void KillTime(int loops)
{
for (int i = 1; i < loops; i++)
Thread.Sleep(500);
}
private static void AddPatch(JsonPatchDocument document, string path, object value) =>
document.Add(new JsonPatchOperation { From = null, Operation = Operation.Add, Path = path, Value = value });
private static Dictionary<string, FIBacklogMesa> GetFIBacklogMesaCollection(string json)
{
Dictionary<string, FIBacklogMesa> results = new();
string key;
FIBacklogMesa[]? fiBacklogMesaCollection;
fiBacklogMesaCollection = JsonSerializer.Deserialize<FIBacklogMesa[]>(json, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
if (fiBacklogMesaCollection is null || fiBacklogMesaCollection.Length == 0)
throw new NullReferenceException();
foreach (FIBacklogMesa fiBacklogMesa in fiBacklogMesaCollection)
{
if (string.IsNullOrEmpty(fiBacklogMesa.Req))
continue;
if (string.IsNullOrEmpty(fiBacklogMesa.Submitted))
continue;
if (string.IsNullOrEmpty(fiBacklogMesa.Requestor))
continue;
key = $"{fiBacklogMesa.Req} - ";
if (results.ContainsKey(key))
continue;
results.Add(key, fiBacklogMesa);
}
return results;
}
private static string GetIds(HttpClient httpClient, string basePage, string api, string query)
{
StringBuilder result = new();
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync(string.Concat(basePage, api, query));
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
if (!streamTask.Result.CanRead)
throw new NullReferenceException(nameof(streamTask));
WIQL.Root? root = JsonSerializer.Deserialize<WIQL.Root>(streamTask.Result, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
streamTask.Result.Dispose();
if (root is null || root.WorkItems is null)
throw new NullReferenceException(nameof(root));
foreach (WIQL.WorkItem workItem in root.WorkItems)
_ = result.Append(workItem.Id).Append(',');
if (result.Length > 0)
_ = result.Remove(result.Length - 1, 1);
return result.ToString();
}
private static Value[] GetWorkItems(IFileRead fileRead, HttpClient httpClient, string basePage, string api, string ids)
{
Value[]? results;
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync(string.Concat(basePage, api, $"/workitems?ids={ids}"));
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
if (!streamTask.Result.CanRead)
throw new NullReferenceException(nameof(streamTask));
JsonElement? jsonElement = JsonSerializer.Deserialize<JsonElement>(streamTask.Result);
if (jsonElement is null || jsonElement.Value.ValueKind != JsonValueKind.Object)
throw new NullReferenceException(nameof(jsonElement));
if (!fileRead.IsEAFHosted)
File.WriteAllText("../../example.json", jsonElement.Value.EnumerateObject().Last().Value.ToString());
results = JsonSerializer.Deserialize<Value[]>(jsonElement.Value.EnumerateObject().Last().Value);
if (results is null || results.Length == 0)
throw new NullReferenceException(nameof(results));
return results;
}
private static ReadOnlyCollection<ValueWithReq> GetValueWithReqCollection(IReadOnlyList<Value> workItems)
{
List<ValueWithReq> results = new();
string[] segments;
foreach (Value value in workItems)
{
segments = value.Fields.SystemTitle.Split('-');
if (segments.Length < 2)
continue;
if (!int.TryParse(segments[0], out int req) || req == 0)
continue;
results.Add(new(value, req));
}
return new(results);
}
private static ReadOnlyCollection<ValueWithReq> RemoveFrom(Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa, ReadOnlyCollection<ValueWithReq> valueWithReqCollection)
{
List<ValueWithReq> results = new();
foreach (ValueWithReq valueWithReq in valueWithReqCollection)
{
if (keyToFIBacklogMesa.Remove($"{valueWithReq.Req} - "))
continue;
results.Add(valueWithReq);
}
return new(results);
}
private static void Update(WorkItemTrackingHttpClient workItemTrackingHttpClient, string sync, ValueWithReq valueWithReq)
{
JsonPatchDocument result = new();
AddPatch(result, "/fields/System.Tags", sync);
Task<WorkItem> workItem = workItemTrackingHttpClient.UpdateWorkItemAsync(result, valueWithReq.Value.Id);
workItem.Wait();
}
private static DateTime? GetCommitDate(FIBacklogMesa fiBacklogMesa)
{
DateTime? result;
DateTime dateTime;
DateTime minDateTime = DateTime.MinValue.AddYears(10);
string commitDate = fiBacklogMesa.CommitDate.Split(' ')[0];
if (string.IsNullOrEmpty(commitDate))
result = null;
else
{
if (DateTime.TryParseExact(commitDate, "MM/dd/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime) && dateTime >= minDateTime)
result = dateTime.AddHours(12).ToUniversalTime();
else
{
if (DateTime.TryParseExact(commitDate, "dd-MMM-yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime) && dateTime >= minDateTime)
result = dateTime.AddHours(12).ToUniversalTime();
else
{
if (DateTime.TryParse(commitDate, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime) && dateTime >= minDateTime)
result = dateTime.AddHours(12).ToUniversalTime();
else
result = null;
}
}
}
return result;
}
private static int GetPriority(FIBacklogMesa fiBacklogMesa)
{
int result;
if (!int.TryParse(fiBacklogMesa.Priority.Substring(0, 1), out int priority) || priority == 0 || priority > 3)
result = 4;
else
result = priority;
return result;
}
private static string GetTitle(FIBacklogMesa fiBacklogMesa)
{
string result = $"{fiBacklogMesa.Req} - {fiBacklogMesa.Subject.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)[0]}";
if (result.Length > 128)
result = result.Substring(0, 127);
return result;
}
private static string GetTitle(FIBacklogMesa fiBacklogMesa, ValueWithReq valueWithReq)
{
string result = $"{valueWithReq.Req} - {fiBacklogMesa.Subject.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)[0]}";
if (result.Length > 128)
result = result.Substring(0, 127);
return result;
}
private static string? GetMappedState(FIBacklogMesa fiBacklogMesa) =>
fiBacklogMesa.Status == "CMP" ? "Closed" : fiBacklogMesa.Status == "UAT" ? "Resolved" : fiBacklogMesa.Status == "In process" ? "Active" : null;
private static void SetSyncTag(WorkItemTrackingHttpClient workItemTrackingHttpClient, ReadOnlyDictionary<string, string> requestorNameToUser, Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa, ReadOnlyCollection<ValueWithReq> valueWithReqCollection)
{
string key;
string title;
int priority;
bool isBugFix;
string? state;
List<string> tags;
TimeSpan timeSpan;
DateTime? dateTime;
List<string> compareTags;
const string sync = "Sync";
FIBacklogMesa? fiBacklogMesa;
foreach (ValueWithReq valueWithReq in valueWithReqCollection)
{
key = $"{valueWithReq.Req} - ";
compareTags = GetTags(valueWithReq.Value.Fields);
if (compareTags.Contains(sync))
continue;
if (!keyToFIBacklogMesa.TryGetValue(key, out fiBacklogMesa))
continue;
tags = GetTags(fiBacklogMesa);
title = GetTitle(fiBacklogMesa, valueWithReq);
isBugFix = fiBacklogMesa.Priority == "0 - BugFix";
_ = requestorNameToUser.TryGetValue(fiBacklogMesa.Requestor, out string? requestorUser);
if (!string.IsNullOrEmpty(requestorUser) && (valueWithReq.Value.Fields.SystemAssignedTo is null || !valueWithReq.Value.Fields.SystemAssignedTo.UniqueName.Equals(requestorUser, StringComparison.CurrentCultureIgnoreCase)))
{
Update(workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
if (valueWithReq.Value.Fields.SystemTitle != title)
{
Update(workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
if (!string.IsNullOrEmpty(fiBacklogMesa.Definition) && valueWithReq.Value.Fields.SystemDescription != fiBacklogMesa.Definition.Replace("&", "&amp;").Replace("\"", "&quot;"))
{
Update(workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
foreach (string tag in tags)
{
if (compareTags.Contains(tag))
continue;
_ = tags.Remove(tag);
break;
}
if (tags.Count != compareTags.Count)
{
Update(workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
if ((isBugFix && valueWithReq.Value.Fields.SystemWorkItemType != "Bug") || (!isBugFix && valueWithReq.Value.Fields.SystemWorkItemType == "Bug"))
{
Update(workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
if (!isBugFix)
{
priority = GetPriority(fiBacklogMesa);
if (valueWithReq.Value.Fields.MicrosoftVSTSCommonPriority != priority)
{
Update(workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
}
state = GetMappedState(fiBacklogMesa);
if (!string.IsNullOrEmpty(state) && valueWithReq.Value.Fields.SystemState != state)
{
Update(workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
if (!isBugFix && int.TryParse(fiBacklogMesa.EstEffortDays, out int estEffortDays) && valueWithReq.Value.Fields.Effort != estEffortDays)
{
Update(workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
dateTime = GetCommitDate(fiBacklogMesa);
if (dateTime is not null)
{
timeSpan = new(valueWithReq.Value.Fields.TargetDate.Ticks - dateTime.Value.Ticks);
if (timeSpan.Hours is > 32 or < -32)
{
Update(workItemTrackingHttpClient, sync, valueWithReq);
continue;
}
}
}
}
private static ReadOnlyDictionary<string, List<int>> GetForceUpdatedByCollection(ReadOnlyDictionary<string, string> assignedToNameToEncodedPAT, ReadOnlyDictionary<string, string> assignedToNameToUser, Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa, ReadOnlyCollection<ValueWithReq> valueWithReqCollection)
{
Dictionary<string, List<int>> results = new();
string key;
List<int>? reqCollection;
FIBacklogMesa? fiBacklogMesa;
foreach (ValueWithReq valueWithReq in valueWithReqCollection)
{
key = $"{valueWithReq.Req} - ";
if (!keyToFIBacklogMesa.TryGetValue(key, out fiBacklogMesa))
continue;
if (string.IsNullOrEmpty(fiBacklogMesa.AssignedTo))
continue;
if (!assignedToNameToUser.TryGetValue(fiBacklogMesa.AssignedTo, out string? assignedToUser))
continue;
if (!valueWithReq.Value.Fields.SystemChangedBy.UniqueName.Equals(assignedToUser, StringComparison.CurrentCultureIgnoreCase))
{
if (!assignedToNameToEncodedPAT.TryGetValue(fiBacklogMesa.AssignedTo, out string? assignedToEncodedPAT) || assignedToEncodedPAT.Length < 15)
continue;
if (!results.TryGetValue(assignedToEncodedPAT, out reqCollection))
{
results.Add(assignedToEncodedPAT, new());
if (!results.TryGetValue(assignedToEncodedPAT, out reqCollection))
throw new NotSupportedException();
}
reqCollection.Add(valueWithReq.Value.Id);
}
}
return new(results);
}
private static ReadOnlyDictionary<string, List<int[]>> GetForceUpdatedByCollectionDelete(string forceUpdatedByComment, ReadOnlyDictionary<string, string> assignedToNameToEncodedPAT, ReadOnlyDictionary<string, string> assignedToNameToUser, Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa, ReadOnlyCollection<ValueWithReq> valueWithReqCollection)
{
Dictionary<string, List<int[]>> results = new();
string key;
List<int[]>? reqCollection;
FIBacklogMesa? fiBacklogMesa;
foreach (ValueWithReq valueWithReq in valueWithReqCollection)
{
key = $"{valueWithReq.Req} - ";
if (!keyToFIBacklogMesa.TryGetValue(key, out fiBacklogMesa))
continue;
if (string.IsNullOrEmpty(fiBacklogMesa.AssignedTo))
continue;
if (!assignedToNameToUser.TryGetValue(fiBacklogMesa.AssignedTo, out string? assignedToUser))
continue;
if (valueWithReq.Value.Fields.SystemHistory == forceUpdatedByComment)
{
if (!assignedToNameToEncodedPAT.TryGetValue(fiBacklogMesa.AssignedTo, out string? assignedToEncodedPAT) || assignedToEncodedPAT.Length < 15)
continue;
if (!results.TryGetValue(assignedToEncodedPAT, out reqCollection))
{
results.Add(assignedToEncodedPAT, new());
if (!results.TryGetValue(assignedToEncodedPAT, out reqCollection))
throw new NotSupportedException();
}
reqCollection.Add(new int[] { valueWithReq.Value.Id, valueWithReq.Value.CommentVersionRef.CommentId });
}
}
return new(results);
}
private static void Post(HttpClient httpClient, string basePage, string api, string query, HttpContent httpContent)
{
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.PostAsync(string.Concat(basePage, api, query), httpContent);
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<string> stringTask = httpResponseMessageTask.Result.Content.ReadAsStringAsync();
stringTask.Wait();
KillTime(30);
}
private static void ForceUpdatedBy(HttpClient httpClient, string basePage, string project, string api, string forceUpdatedByComment, ReadOnlyDictionary<string, List<int>> updateCollection)
{
string stringPayload;
HttpContent httpContent;
HttpClient keyHttpClient;
AuthenticationHeaderValue authenticationHeaderValue;
foreach (KeyValuePair<string, List<int>> keyValuePair in updateCollection)
{
keyHttpClient = new() { BaseAddress = httpClient.BaseAddress };
authenticationHeaderValue = keyHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", keyValuePair.Key);
if (authenticationHeaderValue.Parameter != keyValuePair.Key)
throw new NotSupportedException();
foreach (int id in keyValuePair.Value)
{
stringPayload = JsonSerializer.Serialize(new { text = forceUpdatedByComment });
httpContent = new StringContent($"{stringPayload}", Encoding.UTF8, "application/json");
Post(keyHttpClient, $"{basePage}/{project}", api, $"/workitems/{id}/comments?api-version=5.1-preview.3", httpContent);
}
}
}
private static void Delete(HttpClient httpClient, string basePage, string api, string query)
{
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.DeleteAsync(string.Concat(basePage, api, query));
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<string> stringTask = httpResponseMessageTask.Result.Content.ReadAsStringAsync();
stringTask.Wait();
KillTime(30);
}
private static void ForceUpdatedByDelete(HttpClient httpClient, string basePage, string project, string api, ReadOnlyDictionary<string, List<int[]>> deleteCollection)
{
HttpClient keyHttpClient;
AuthenticationHeaderValue authenticationHeaderValue;
foreach (KeyValuePair<string, List<int[]>> keyValuePair in deleteCollection)
{
keyHttpClient = new() { BaseAddress = httpClient.BaseAddress };
authenticationHeaderValue = keyHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", keyValuePair.Key);
if (authenticationHeaderValue.Parameter != keyValuePair.Key)
throw new NotSupportedException();
foreach (int[] idCollection in keyValuePair.Value)
{
if (idCollection.Length != 2)
throw new NotSupportedException();
Delete(keyHttpClient, $"{basePage}/{project}", api, $"/workitems/{idCollection[0]}/comments/{idCollection[1]}?api-version=7.0-preview.3");
}
}
}
private static string GetDescription(FIBacklogMesa fiBacklogMesa, DateTime dateTime) =>
$"Req:{fiBacklogMesa.Req}; Submitted:{(dateTime == DateTime.MinValue ? fiBacklogMesa.Submitted : dateTime.ToString("d-MMM-yy"))}; Requestor:{fiBacklogMesa.Requestor}; AssignedTo:{fiBacklogMesa.AssignedTo}; SecondResource:{fiBacklogMesa.SecondResource}; Systems:{fiBacklogMesa.SystemS}; ";
private static void Update(HttpClient httpClient, string basePage, string api, string query, HttpContent httpContent)
{
#if Windows
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.PatchAsync(string.Concat(basePage, api, query), httpContent);
httpResponseMessageTask.Wait();
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
Task<string> stringTask = httpResponseMessageTask.Result.Content.ReadAsStringAsync();
stringTask.Wait();
#endif
KillTime(30);
}
private static void UpdateIds(HttpClient httpClient, string basePage, string api, string[] checkFiles)
{
int? idIndex;
string[] lines;
string[] segments;
string stringPayload;
HttpContent httpContent;
foreach (string checkFile in checkFiles)
{
idIndex = null;
lines = File.ReadAllLines(checkFile);
if (lines.Length < 1)
continue;
segments = lines.First().Split(',');
for (int i = 0; i < segments.Length; i++)
{
if (segments[i] == "ID")
{
idIndex = i;
break;
}
}
if (idIndex is null)
continue;
for (int i = 1; i < lines.Length; i++)
{
segments = lines[i].Split(',');
if (segments.Length < idIndex.Value)
continue;
var payload = new
{
op = "replace",
path = "/fields/System.IterationPath",
value = "Mesa_FI"
};
stringPayload = JsonSerializer.Serialize(payload);
httpContent = new StringContent($"[{stringPayload}]", Encoding.UTF8, "application/json-patch+json");
Update(httpClient, basePage, api, $"/workitems/{segments[idIndex.Value].Replace("\"", string.Empty)}?api-version=1.0", httpContent);
}
}
}
private static JsonPatchDocument GetUATDocument(string project, ReadOnlyDictionary<string, string> requestorNameToUser, DateTime dateTime, FIBacklogMesa fiBacklogMesa)
{
JsonPatchDocument result = new();
AddPatch(result, "/fields/System.AreaPath", project);
string description = GetDescription(fiBacklogMesa, dateTime);
AddPatch(result, "/fields/System.IterationPath", project);
AddPatch(result, "/fields/System.Title", $"{fiBacklogMesa.Req} - UAT");
AddPatch(result, "/fields/System.Description", description);
if (requestorNameToUser.TryGetValue(fiBacklogMesa.Requestor, out string? requestorUser))
AddPatch(result, "/fields/System.AssignedTo", requestorUser);
return result;
}
private static JsonPatchDocument GetBugDocument(string project, ReadOnlyDictionary<string, string> assignedToNameToUser, Task<WorkItem> uatWorkItemTask, FIBacklogMesa fiBacklogMesa)
{
JsonPatchDocument result = new();
if (uatWorkItemTask.Result.Id is null)
throw new NotSupportedException();
string title = GetTitle(fiBacklogMesa);
AddPatch(result, "/relations/-", new WorkItemRelation() { Rel = "System.LinkTypes.Hierarchy-Forward", Url = uatWorkItemTask.Result.Url });
AddPatch(result, "/fields/System.AreaPath", project);
AddPatch(result, "/fields/System.IterationPath", project);
AddPatch(result, "/fields/System.Title", title);
string? state = GetMappedState(fiBacklogMesa);
if (!string.IsNullOrEmpty(state))
AddPatch(result, "/fields/System.State", state);
if (!string.IsNullOrEmpty(fiBacklogMesa.Definition))
AddPatch(result, "/fields/System.Description", fiBacklogMesa.Definition);
if (assignedToNameToUser.TryGetValue(fiBacklogMesa.Requestor, out string? requestorUser))
AddPatch(result, "/fields/System.AssignedTo", requestorUser);
return result;
}
private static JsonPatchDocument GetDeveloperTaskDocument(string project, ReadOnlyDictionary<string, string> assignedToNameToUser, FIBacklogMesa fiBacklogMesa)
{
JsonPatchDocument result = new();
AddPatch(result, "/fields/System.AreaPath", project);
AddPatch(result, "/fields/System.IterationPath", project);
AddPatch(result, "/fields/System.Title", $"{fiBacklogMesa.Req} - Developer Task");
if (assignedToNameToUser.TryGetValue(fiBacklogMesa.AssignedTo, out string? assignedToUser))
AddPatch(result, "/fields/System.AssignedTo", assignedToUser);
return result;
}
private static JsonPatchDocument GetSecondDeveloperTaskDocument(string project, ReadOnlyDictionary<string, string> assignedToNameToUser, FIBacklogMesa fiBacklogMesa)
{
JsonPatchDocument result = new();
AddPatch(result, "/fields/System.AreaPath", project);
AddPatch(result, "/fields/System.IterationPath", project);
AddPatch(result, "/fields/System.Title", $"{fiBacklogMesa.Req} - Developer Task");
if (assignedToNameToUser.TryGetValue(fiBacklogMesa.SecondResource, out string? secondResourceUser))
AddPatch(result, "/fields/System.AssignedTo", secondResourceUser);
return result;
}
private static JsonPatchDocument GetUserStoryDocument(string project, ReadOnlyDictionary<string, string> requestorNameToUser, Task<WorkItem> uatWorkItemTask, FIBacklogMesa fiBacklogMesa)
{
JsonPatchDocument result = new();
if (uatWorkItemTask?.Result.Id is null)
throw new NotSupportedException();
AddPatch(result, "/relations/-", new WorkItemRelation() { Rel = "System.LinkTypes.Hierarchy-Forward", Url = uatWorkItemTask.Result.Url });
AddPatch(result, "/fields/System.AreaPath", project);
AddPatch(result, "/fields/System.IterationPath", project);
AddPatch(result, "/fields/System.Title", $"{fiBacklogMesa.Req} - User Story");
string? state = GetMappedState(fiBacklogMesa);
if (!string.IsNullOrEmpty(state))
AddPatch(result, "/fields/System.State", state);
if (requestorNameToUser.TryGetValue(fiBacklogMesa.Requestor, out string? requestorUser))
AddPatch(result, "/fields/System.AssignedTo", requestorUser);
return result;
}
private static JsonPatchDocument GetAssignedToRelationDocument(Task<WorkItem> assignedToWorkItemTask)
{
JsonPatchDocument result = new();
if (assignedToWorkItemTask.Result.Id is null)
throw new NotSupportedException();
AddPatch(result, "/relations/-", new WorkItemRelation() { Rel = "System.LinkTypes.Hierarchy-Forward", Url = assignedToWorkItemTask.Result.Url });
return result;
}
private static JsonPatchDocument GetSecondResourceDocument(Task<WorkItem> secondResourceWorkItemTask)
{
JsonPatchDocument result = new();
if (secondResourceWorkItemTask?.Result.Id is null)
throw new NotSupportedException();
AddPatch(result, "/relations/-", new WorkItemRelation() { Rel = "System.LinkTypes.Hierarchy-Forward", Url = secondResourceWorkItemTask.Result.Url });
return result;
}
private static JsonPatchDocument GetFeatureDocument(string project, ReadOnlyDictionary<string, string> requestorNameToUser, List<string> tags, Task<WorkItem>? userStoryWorkItemTask, FIBacklogMesa fiBacklogMesa)
{
JsonPatchDocument result = new();
if (userStoryWorkItemTask?.Result.Id is null)
throw new NotSupportedException();
string title = GetTitle(fiBacklogMesa);
int priority = GetPriority(fiBacklogMesa);
AddPatch(result, "/relations/-", new WorkItemRelation() { Rel = "System.LinkTypes.Hierarchy-Forward", Url = userStoryWorkItemTask.Result.Url });
AddPatch(result, "/fields/System.AreaPath", project);
if (tags.Count > 0)
{
AddPatch(result, "/fields/System.Tags", tags.Last());
tags.RemoveAt(tags.Count - 1);
}
AddPatch(result, "/fields/System.IterationPath", project);
AddPatch(result, "/fields/Microsoft.VSTS.Common.Priority", priority);
if (!string.IsNullOrEmpty(fiBacklogMesa.Definition))
AddPatch(result, "/fields/System.Description", fiBacklogMesa.Definition);
string? state = GetMappedState(fiBacklogMesa);
if (!string.IsNullOrEmpty(state))
AddPatch(result, "/fields/System.State", state);
if (!string.IsNullOrEmpty(fiBacklogMesa.EstEffortDays) && int.TryParse(fiBacklogMesa.EstEffortDays, out int estEffortDays) && estEffortDays != 0)
AddPatch(result, "/fields/Microsoft.VSTS.Scheduling.Effort", estEffortDays);
DateTime? dateTime = GetCommitDate(fiBacklogMesa);
if (dateTime is not null)
AddPatch(result, "/fields/Microsoft.VSTS.Scheduling.TargetDate", dateTime);
if (!string.IsNullOrEmpty(fiBacklogMesa.Updates))
AddPatch(result, "/fields/System.History", fiBacklogMesa.Updates);
AddPatch(result, "/fields/System.Title", title);
if (requestorNameToUser.TryGetValue(fiBacklogMesa.Requestor, out string? requestorUser))
AddPatch(result, "/fields/System.AssignedTo", requestorUser);
// https://tfs.intra.infineon.com/tfs/ManufacturingIT/Mesa_FI/_apis/wit/workitemtypes/feature/fields?api-version=7.0
return result;
}
private static List<string> GetTags(FIBacklogMesa fiBacklogMesa)
{
List<string> results = new();
foreach (string tag in fiBacklogMesa.SystemS.Split('/'))
{
if (string.IsNullOrEmpty(tag.Trim()))
continue;
results.Add(tag.Trim());
}
return results;
}
private static List<string> GetTags(Fields fields)
{
List<string> results = new();
if (!string.IsNullOrEmpty(fields.SystemTags))
{
foreach (string tag in fields.SystemTags.Split(';'))
{
if (string.IsNullOrEmpty(tag.Trim()))
continue;
results.Add(tag.Trim());
}
}
return results;
}
private static void DoWork(WorkItemTrackingHttpClient workItemTrackingHttpClient, string project, ReadOnlyDictionary<string, string> assignedToNameToUser, ReadOnlyDictionary<string, string> requestorNameToUser, FIBacklogMesa fiBacklogMesa)
{
DateTime dateTime;
JsonPatchDocument tagDocument;
List<string> tags = GetTags(fiBacklogMesa);
Task<WorkItem>? secondResourceWorkItemTask = null;
bool isBugFix = fiBacklogMesa.Priority == "0 - BugFix";
if (!DateTime.TryParse(fiBacklogMesa.Submitted, out dateTime))
dateTime = DateTime.MinValue;
JsonPatchDocument uatDocument = GetUATDocument(project, requestorNameToUser, dateTime, fiBacklogMesa);
Task<WorkItem> uatWorkItemTask = workItemTrackingHttpClient.CreateWorkItemAsync(uatDocument, project, "Task");
uatWorkItemTask.Wait();
if (isBugFix)
{
JsonPatchDocument bugDocument = GetBugDocument(project, assignedToNameToUser, uatWorkItemTask, fiBacklogMesa);
Task<WorkItem> bugWorkItemTask = workItemTrackingHttpClient.CreateWorkItemAsync(bugDocument, project, "Bug");
bugWorkItemTask.Wait();
}
if (!isBugFix)
{
JsonPatchDocument developerTaskDocument = GetDeveloperTaskDocument(project, assignedToNameToUser, fiBacklogMesa);
Task<WorkItem> assignedToWorkItemTask = workItemTrackingHttpClient.CreateWorkItemAsync(developerTaskDocument, project, "Task");
assignedToWorkItemTask.Wait();
if (!string.IsNullOrEmpty(fiBacklogMesa.SecondResource))
{
JsonPatchDocument secondDeveloperTaskDocument = GetSecondDeveloperTaskDocument(project, assignedToNameToUser, fiBacklogMesa);
secondResourceWorkItemTask = workItemTrackingHttpClient.CreateWorkItemAsync(secondDeveloperTaskDocument, project, "Task");
secondResourceWorkItemTask.Wait();
}
JsonPatchDocument userStoryDocument = GetUserStoryDocument(project, requestorNameToUser, uatWorkItemTask, fiBacklogMesa);
Task<WorkItem> userStoryWorkItemTask = workItemTrackingHttpClient.CreateWorkItemAsync(userStoryDocument, project, "User Story");
userStoryWorkItemTask.Wait();
if (userStoryWorkItemTask?.Result.Id is null)
throw new NotSupportedException();
JsonPatchDocument assignedToRelationDocument = GetAssignedToRelationDocument(assignedToWorkItemTask);
userStoryWorkItemTask = workItemTrackingHttpClient.UpdateWorkItemAsync(assignedToRelationDocument, userStoryWorkItemTask.Result.Id.Value);
userStoryWorkItemTask.Wait();
if (secondResourceWorkItemTask is not null)
{
if (userStoryWorkItemTask.Result.Id is null)
throw new NotSupportedException();
JsonPatchDocument secondResourceDocument = GetSecondResourceDocument(secondResourceWorkItemTask);
userStoryWorkItemTask = workItemTrackingHttpClient.UpdateWorkItemAsync(secondResourceDocument, userStoryWorkItemTask.Result.Id.Value);
userStoryWorkItemTask.Wait();
}
JsonPatchDocument featureDocument = GetFeatureDocument(project, requestorNameToUser, tags, userStoryWorkItemTask, fiBacklogMesa);
Task<WorkItem> featureWorkItemTask = workItemTrackingHttpClient.CreateWorkItemAsync(featureDocument, project, "Feature");
featureWorkItemTask.Wait();
for (int i = tags.Count - 1; i > -1; i--)
{
if (featureWorkItemTask.Result.Id is null)
throw new NotSupportedException();
tagDocument = new();
AddPatch(tagDocument, "/fields/System.Tags", tags[i]);
tags.RemoveAt(i);
featureWorkItemTask = workItemTrackingHttpClient.UpdateWorkItemAsync(tagDocument, featureWorkItemTask.Result.Id.Value);
featureWorkItemTask.Wait();
}
}
}
private void Parse(IFileRead fileRead,
Logistics logistics,
List<FileInfo> fileInfoCollection,
HttpClient httpClient,
string basePage,
string api,
string query,
WorkItemTrackingHttpClient workItemTrackingHttpClient,
string project,
ReadOnlyDictionary<string, string> assignedToNameToEncodedPAT,
ReadOnlyDictionary<string, string> assignedToNameToUser,
ReadOnlyDictionary<string, string> requestorNameToUser,
string json,
bool forceUpdatedBy,
bool forceDeleteUpdatedBy)
{
if (fileRead is null)
throw new NullReferenceException();
if (logistics is null)
throw new NullReferenceException();
if (fileInfoCollection is null)
throw new NullReferenceException();
int counter = 0;
string forceUpdatedByComment = "Force updated by";
string? directory = Path.GetDirectoryName(fileRead.ReportFullPath) ?? throw new Exception();
string[] checkFiles = Directory.GetFiles(directory, "*.csv", SearchOption.TopDirectoryOnly);
if (checkFiles.Length != 0)
UpdateIds(httpClient, basePage, api, checkFiles);
else
{
string ids = GetIds(httpClient, basePage, api, query);
Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa = GetFIBacklogMesaCollection(json);
Value[] workItems = string.IsNullOrEmpty(ids) ? Array.Empty<Value>() : GetWorkItems(fileRead, httpClient, basePage, api, ids);
int count = keyToFIBacklogMesa.Count;
ReadOnlyCollection<ValueWithReq> valueWithReqCollection = GetValueWithReqCollection(workItems);
SetSyncTag(workItemTrackingHttpClient, requestorNameToUser, keyToFIBacklogMesa, valueWithReqCollection);
ReadOnlyDictionary<string, List<int>> updateCollection = GetForceUpdatedByCollection(assignedToNameToEncodedPAT, assignedToNameToUser, keyToFIBacklogMesa, valueWithReqCollection);
if (updateCollection.Count > 0 && forceUpdatedBy)
ForceUpdatedBy(httpClient, basePage, project, api, forceUpdatedByComment, updateCollection);
if (forceDeleteUpdatedBy)
{
ReadOnlyDictionary<string, List<int[]>> deleteCollection = GetForceUpdatedByCollectionDelete(forceUpdatedByComment, assignedToNameToEncodedPAT, assignedToNameToUser, keyToFIBacklogMesa, valueWithReqCollection);
if (deleteCollection.Count > 0 && forceDeleteUpdatedBy)
ForceUpdatedByDelete(httpClient, basePage, project, api, deleteCollection);
}
ReadOnlyCollection<ValueWithReq> extra = RemoveFrom(keyToFIBacklogMesa, valueWithReqCollection);
if (count != extra.Count)
{ }
if (count != keyToFIBacklogMesa.Count)
{ }
_Details.AddRange(workItems);
foreach (KeyValuePair<string, FIBacklogMesa> keyValuePair in keyToFIBacklogMesa)
{
if (counter > 5)
break;
if (!fileRead.IsEAFHosted)
continue;
DoWork(workItemTrackingHttpClient, project, assignedToNameToUser, requestorNameToUser, keyValuePair.Value);
counter++;
}
}
}
private void Parse() =>
throw new NotImplementedException();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -4,30 +4,11 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>FI Backlog Mesa</title>
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2023-06-09-15-01" rel="stylesheet" />
<link href="/igniteui/css/structure/infragistics.css?v=2023-06-09-15-01" rel="stylesheet" />
<script src="/js/jquery-3.6.0.min.js?v=2023-06-09-15-01" type="text/javascript"></script>
<script src="/js/jquery-ui.min.js?v=2023-06-09-15-01" type="text/javascript"></script>
<script src="/js/site.js?v=2023-06-09-15-01" type="text/javascript"></script>
<script src="/igniteui/js/infragistics.core.js?v=2023-06-09-15-01" type="text/javascript"></script>
<script src="/igniteui/js/infragistics.lob.js?v=2023-06-09-15-01" type="text/javascript"></script>
<script src="/igniteui/js/infragistics.dv.js?v=2023-06-09-15-01" type="text/javascript"></script>
<title>FI Backlog</title>
</head>
<body>
<h2>FI Backlog Mesa</h2>
<div style="height: 550px;" id="HeaderGridDiv">
<table id="HeaderGrid"></table>
</div>
<script>
$(document).ready(function () {
initIndex("/json/data.json");
});
</script>
<h2><a href="mes.html">FI Backlog Mesa</a></h2>
<h2><a href="leo.html">FI Backlog HiRel (Leominster)</a></h2>
</body>
</html>

View File

@ -0,0 +1,159 @@
function compareFunction(a, b) {
return a.Priority[0] - b.Priority[0] || a.TimeCriticality[0] - b.TimeCriticality[0] || b.State[0] - a.State[0] || a.Id - b.Id;
}
function showOne(rowData) {
if (rowData == null)
return;
var data = [];
data.push({ name: "ADO Edit", value: '<a target="_blank" href="https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/' + rowData["Id"] + '">' + rowData["Id"] + '</a>' });
for (const property in rowData) {
if (rowData[property] == null)
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 == null)
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 == null)
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 == null || 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 getTimeCriticality(workItemType, timeCriticality) {
var result;
if (workItemType === "Bug")
result = "0-Bug";
else if (timeCriticality == null || timeCriticality === 0)
result = "9-Null";
else if (timeCriticality === 1)
result = `${timeCriticality}-QSM`;
else if (timeCriticality === 2)
result = `${timeCriticality}-Qual`;
else if (timeCriticality === 3)
result = `${timeCriticality}-Eff`;
else
result = "8-Not";
return result;
}
function getWorkItems(data) {
var workItems = [];
var workItem;
for (var i = data.length - 1; i > -1; i--) {
workItem = data[i];
if (workItem.AreaPath !== 'ART SPS\\LEO')
continue;
if (workItem.WorkItemType !== 'Feature' && workItem.WorkItemType !== 'Bug')
continue;
workItem["State"] = getState(workItem["State"])
workItem["Priority"] = getPriority(workItem["WorkItemType"], workItem["Priority"])
workItem["TimeCriticality"] = getTimeCriticality(workItem["WorkItemType"], workItem["TimeCriticality"])
workItems.push(workItem);
}
workItems.sort(compareFunction);
return workItems;
}
function initIndex(url) {
$.getJSON(url, { _: new Date().getTime() }, function (data) {
var workItems = getWorkItems(data);
console.log(data.length);
if (data.length > 0)
console.log(data[0]);
$("#HeaderGrid").igGrid({
autoGenerateColumns: false,
dataSource: workItems,
height: "100%",
primaryKey: "Id",
width: "100%",
columns: [
{ key: "Id", dataType: "number" },
{ key: "Requester", dataType: "string" },
{ headerText: "Assigned To", key: "AssignedTo", dataType: "string" },
{ key: "Title", dataType: "string", width: "20%" },
{ headerText: "System(s)", key: "Tags", dataType: "string" },
{ key: "Priority", dataType: "string" },
{ headerText: "Qual/Eff", key: "TimeCriticality", dataType: "string" },
{ key: "State", dataType: "string" },
{ headerText: "Effort in Days", key: "Effort", dataType: "number" },
{ headerText: "UAT as of", key: "ResolvedDate", dataType: "date", format: "date" },
{ headerText: "CMP Date", key: "ClosedDate", dataType: "date", format: "date" },
{ headerText: "Target", key: "TargetDate", dataType: "date", format: "date" },
{ key: "AreaPath", dataType: "string", hidden: true },
{ key: "AssignedTo", dataType: "string", hidden: true },
{ key: "BusinessValue", dataType: "number", hidden: true },
{ key: "ChangedDate", dataType: "string", hidden: true },
{ key: "CommentCount", dataType: "number", hidden: true },
{ key: "CreatedDate", dataType: "string", hidden: true },
{ key: "Description", dataType: "string", hidden: true },
{ key: "IterationPath", dataType: "string", hidden: true },
{ key: "Revision", dataType: "number", hidden: true },
{ key: "RiskReductionMinusOpportunityEnablement", dataType: "string", hidden: true },
{ key: "StartDate", dataType: "string", hidden: true },
{ key: "WorkItemType", dataType: "string", hidden: true },
{ key: "WeightedShortestJobFirst", dataType: "number", hidden: true },
],
features: [
{ name: "Sorting", type: "local" },
{ name: "Filtering", type: "local" },
{ name: "Selection", mode: "row", multipleSelection: false, rowSelectionChanging: detailSelectionChangedRunInfo },
{ name: "Paging", type: "local", recordCountKey: "TotalRows", pageSize: 10, pageSizeUrlKey: "pageSize", "pageIndexUrlKey": "page", showPageSizeDropDown: false },
],
});
});
$("#HeaderGrid").on("dblclick", "tr", loadOne);
}

View File

@ -0,0 +1,159 @@
function compareFunction(a, b) {
return a.Priority[0] - b.Priority[0] || a.TimeCriticality[0] - b.TimeCriticality[0] || b.State[0] - a.State[0] || a.Id - b.Id;
}
function showOne(rowData) {
if (rowData == null)
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)
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 == null)
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 == null)
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 == null || 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 getTimeCriticality(workItemType, timeCriticality) {
var result;
if (workItemType === "Bug")
result = "0-Bug";
else if (timeCriticality == null || timeCriticality === 0)
result = "9-Null";
else if (timeCriticality === 1)
result = `${timeCriticality}-QSM`;
else if (timeCriticality === 2)
result = `${timeCriticality}-Qual`;
else if (timeCriticality === 3)
result = `${timeCriticality}-Eff`;
else
result = "8-Not";
return result;
}
function getWorkItems(data) {
var workItems = [];
var workItem;
for (var i = data.length - 1; i > -1; i--) {
workItem = data[i];
if (workItem.AreaPath !== 'ART SPS\\MES')
continue;
if (workItem.WorkItemType !== 'Feature' && workItem.WorkItemType !== 'Bug')
continue;
workItem["State"] = getState(workItem["State"])
workItem["Priority"] = getPriority(workItem["WorkItemType"], workItem["Priority"])
workItem["TimeCriticality"] = getTimeCriticality(workItem["WorkItemType"], workItem["TimeCriticality"])
workItems.push(workItem);
}
workItems.sort(compareFunction);
return workItems;
}
function initIndex(url) {
$.getJSON(url, { _: new Date().getTime() }, function (data) {
var workItems = getWorkItems(data);
console.log(data.length);
if (data.length > 0)
console.log(data[0]);
$("#HeaderGrid").igGrid({
autoGenerateColumns: false,
dataSource: workItems,
height: "100%",
primaryKey: "Id",
width: "100%",
columns: [
{ key: "Id", dataType: "number" },
{ key: "Requester", dataType: "string" },
{ headerText: "Assigned To", key: "AssignedTo", dataType: "string" },
{ key: "Title", dataType: "string", width: "20%" },
{ headerText: "System(s)", key: "Tags", dataType: "string" },
{ key: "Priority", dataType: "string" },
{ headerText: "Qual/Eff", key: "TimeCriticality", dataType: "string" },
{ key: "State", dataType: "string" },
{ headerText: "Effort in Days", key: "Effort", dataType: "number" },
{ headerText: "UAT as of", key: "ResolvedDate", dataType: "date", format: "date" },
{ headerText: "CMP Date", key: "ClosedDate", dataType: "date", format: "date" },
{ headerText: "Target", key: "TargetDate", dataType: "date", format: "date" },
{ key: "AreaPath", dataType: "string", hidden: true },
{ key: "AssignedTo", dataType: "string", hidden: true },
{ key: "BusinessValue", dataType: "number", hidden: true },
{ key: "ChangedDate", dataType: "string", hidden: true },
{ key: "CommentCount", dataType: "number", hidden: true },
{ key: "CreatedDate", dataType: "string", hidden: true },
{ key: "Description", dataType: "string", hidden: true },
{ key: "IterationPath", dataType: "string", hidden: true },
{ key: "Revision", dataType: "number", hidden: true },
{ key: "RiskReductionMinusOpportunityEnablement", dataType: "string", hidden: true },
{ key: "StartDate", dataType: "string", hidden: true },
{ key: "WorkItemType", dataType: "string", hidden: true },
{ key: "WeightedShortestJobFirst", dataType: "number", hidden: true },
],
features: [
{ name: "Sorting", type: "local" },
{ name: "Filtering", type: "local" },
{ name: "Selection", mode: "row", multipleSelection: false, rowSelectionChanging: detailSelectionChangedRunInfo },
{ name: "Paging", type: "local", recordCountKey: "TotalRows", pageSize: 10, pageSizeUrlKey: "pageSize", "pageIndexUrlKey": "page", showPageSizeDropDown: false },
],
});
});
$("#HeaderGrid").on("dblclick", "tr", loadOne);
}

View File

@ -1,36 +0,0 @@
function compareFunction(a, b) {
return a['Priority'][0] - b['Priority'][0] || a['Req '].length - b['Req '].length || a['Req '] - b['Req '];
}
function initIndex(url) {
$.getJSON(url, function (data) {
for (var i = data.length - 1; i > -1; i--) {
if (data[i].Submitted !== '')
continue;
data.splice(i, 1);
}
data.sort(compareFunction);
$("#HeaderGrid").igGrid({
autoGenerateColumns: false,
dataSource: data,
height: "100%",
width: "100%",
columns: [
{ key: "Req", dataType: "number" },
{ key: "Submitted", dataType: "date", format: "date" },
{ key: "Requestor", dataType: "string" },
{ key: "Assigned To", dataType: "string" },
{ key: "Second Resource", dataType: "string" },
{ key: "Subject - from Requestor", dataType: "string" },
{ key: "System(s)", dataType: "string" },
{ key: "Priority", dataType: "string" },
],
features: [
{ name: "Paging", type: "local", recordCountKey: "TotalRows", pageSize: 25, pageSizeUrlKey: "pageSize", "pageIndexUrlKey": "page", showPageSizeDropDown: false },
{ name: "Selection", mode: "row", multipleSelection: false },
{ name: "Filtering", type: "local" },
{ name: "Sorting", type: "local" },
],
});
});
}

View File

@ -1,36 +0,0 @@
[
{
"Req": "",
"Submitted": "",
"Requestor": "",
"Assigned To": "",
"Second Resource": "",
"Subject - from Requestor": null,
"Epi Line": null,
"Area": null,
"System(s)": "",
"Priority": "",
"Status": "",
"Definition": null,
"Updates": "",
"Est Effort _(days)": "",
"Commit Date": "",
"Re-Commit Date": "",
"UAT as of": "",
"CMP Date": null,
"F20": "",
"F21": "",
"F22": "",
"F23": "",
"F24": "",
"F25": "",
"F26": "",
"F27": "",
"F28": "",
"F29": "",
"F30": "",
"F31": "",
"F32": "",
"F33": ""
}
]

View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>FI Backlog HiRel (Leominster)</title>
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-09-07-08-19" rel="stylesheet" />
<link href="/igniteui/css/structure/infragistics.css?v=2024-09-07-08-19" rel="stylesheet" />
<script src="/js/jquery-3.6.0.min.js?v=2024-09-07-08-19" type="text/javascript"></script>
<script src="/js/jquery-ui.min.js?v=2024-09-07-08-19" type="text/javascript"></script>
<script src="/js/leo.js?v=2024-09-07-08-19" type="text/javascript"></script>
<script src="/igniteui/js/infragistics.core.js?v=2024-09-07-08-19" type="text/javascript"></script>
<script src="/igniteui/js/infragistics.lob.js?v=2024-09-07-08-19" type="text/javascript"></script>
<script src="/igniteui/js/infragistics.dv.js?v=2024-09-07-08-19" type="text/javascript"></script>
</head>
<body>
<h2>FI Backlog HiRel (Leominster)</h2>
<div style="height: 550px;" id="HeaderGridDiv">
<table id="HeaderGrid"></table>
</div>
<br />&nbsp;
<div id="AllGridDiv">
<table id="AllGrid"></table>
</div>
<script>
$(document).ready(function () {
initIndex("/json/work-items.json?v=2024-09-07-08-19");
});
</script>
</body>
</html>

View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>FI Backlog Mesa</title>
<link href="/igniteui/css/themes/bootstrap3/default/infragistics.theme.css?v=2024-09-07-08-19" rel="stylesheet" />
<link href="/igniteui/css/structure/infragistics.css?v=2024-09-07-08-19" rel="stylesheet" />
<script src="/js/jquery-3.6.0.min.js?v=2024-09-07-08-19" type="text/javascript"></script>
<script src="/js/jquery-ui.min.js?v=2024-09-07-08-19" type="text/javascript"></script>
<script src="/js/mes.js?v=2024-09-07-08-19" type="text/javascript"></script>
<script src="/igniteui/js/infragistics.core.js?v=2024-09-07-08-19" type="text/javascript"></script>
<script src="/igniteui/js/infragistics.lob.js?v=2024-09-07-08-19" type="text/javascript"></script>
<script src="/igniteui/js/infragistics.dv.js?v=2024-09-07-08-19" type="text/javascript"></script>
</head>
<body>
<h2>FI Backlog Mesa</h2>
<div style="height: 550px;" id="HeaderGridDiv">
<table id="HeaderGrid"></table>
</div>
<br />&nbsp;
<div id="AllGridDiv">
<table id="AllGrid"></table>
</div>
<script>
$(document).ready(function () {
initIndex("/json/work-items.json?v=2024-09-07-08-19");
});
</script>
</body>
</html>

View File

@ -0,0 +1,34 @@
using System.Text.Json.Serialization;
namespace Adaptation.FileHandlers.json.WorkItems;
public class CustomRequester
{
[JsonConstructor]
public CustomRequester(
string descriptor,
string displayName,
string id,
string imageUrl,
Links links,
string uniqueName,
string url
)
{
Descriptor = descriptor;
DisplayName = displayName;
Id = id;
ImageUrl = imageUrl;
Links = links;
UniqueName = uniqueName;
Url = url;
}
[JsonPropertyName("descriptor")] public string Descriptor { get; }
[JsonPropertyName("displayName")] public string DisplayName { get; }
[JsonPropertyName("id")] public string Id { get; }
[JsonPropertyName("imageUrl")] public string ImageUrl { get; }
[JsonPropertyName("_links")] public Links Links { get; }
[JsonPropertyName("uniqueName")] public string UniqueName { get; }
[JsonPropertyName("url")] public string Url { get; }
}

View File

@ -5,109 +5,96 @@ namespace Adaptation.FileHandlers.json.WorkItems;
public class Fields
{
#nullable enable
[JsonConstructor]
public Fields(
string systemAreaPath,
string systemTeamProject,
string systemIterationPath,
string systemWorkItemType,
string systemState,
string systemReason,
SystemAssignedTo systemAssignedTo,
DateTime systemCreatedDate,
SystemCreatedBy systemCreatedBy,
DateTime systemChangedDate,
SystemChangedBy systemChangedBy,
int systemCommentCount,
string systemTitle,
DateTime microsoftVSTSCommonStateChangeDate,
public Fields(int customRRminusOE,
CustomRequester? customRequester,
float customWSJF,
float? microsoftVSTSSchedulingEffort,
int microsoftVSTSCommonBusinessValue,
DateTime microsoftVSTSCommonClosedDate,
int microsoftVSTSCommonPriority,
DateTime microsoftVSTSCommonResolvedDate,
DateTime microsoftVSTSCommonStateChangeDate,
float microsoftVSTSCommonTimeCriticality,
DateTime microsoftVSTSSchedulingStartDate,
string systemAreaPath,
SystemAssignedTo systemAssignedTo,
SystemChangedBy systemChangedBy,
DateTime systemChangedDate,
int systemCommentCount,
SystemCreatedBy systemCreatedBy,
DateTime systemCreatedDate,
string systemDescription,
string systemTags,
string systemHistory,
float? effort,
DateTime targetDate
)
string systemIterationPath,
string systemReason,
string systemState,
string systemTags,
string systemTeamProject,
string systemTitle,
string systemWorkItemType,
DateTime microsoftVSTSSchedulingTargetDate)
{
SystemAreaPath = systemAreaPath;
SystemTeamProject = systemTeamProject;
SystemIterationPath = systemIterationPath;
SystemWorkItemType = systemWorkItemType;
SystemState = systemState;
SystemReason = systemReason;
SystemAssignedTo = systemAssignedTo;
SystemCreatedDate = systemCreatedDate;
SystemCreatedBy = systemCreatedBy;
SystemChangedDate = systemChangedDate;
SystemChangedBy = systemChangedBy;
SystemCommentCount = systemCommentCount;
SystemTitle = systemTitle;
MicrosoftVSTSCommonStateChangeDate = microsoftVSTSCommonStateChangeDate;
CustomRRminusOE = customRRminusOE;
CustomRequester = customRequester;
CustomWSJF = customWSJF;
MicrosoftVSTSSchedulingEffort = microsoftVSTSSchedulingEffort;
MicrosoftVSTSCommonBusinessValue = microsoftVSTSCommonBusinessValue;
MicrosoftVSTSCommonClosedDate = microsoftVSTSCommonClosedDate;
MicrosoftVSTSCommonPriority = microsoftVSTSCommonPriority;
MicrosoftVSTSCommonResolvedDate = microsoftVSTSCommonResolvedDate;
MicrosoftVSTSCommonStateChangeDate = microsoftVSTSCommonStateChangeDate;
MicrosoftVSTSCommonTimeCriticality = microsoftVSTSCommonTimeCriticality;
MicrosoftVSTSSchedulingStartDate = microsoftVSTSSchedulingStartDate;
SystemAreaPath = systemAreaPath;
SystemAssignedTo = systemAssignedTo;
SystemChangedBy = systemChangedBy;
SystemChangedDate = systemChangedDate;
SystemCommentCount = systemCommentCount;
SystemCreatedBy = systemCreatedBy;
SystemCreatedDate = systemCreatedDate;
SystemDescription = systemDescription;
SystemTags = systemTags;
SystemHistory = systemHistory;
Effort = effort;
TargetDate = targetDate;
SystemIterationPath = systemIterationPath;
SystemReason = systemReason;
SystemState = systemState;
SystemTags = systemTags;
SystemTeamProject = systemTeamProject;
SystemTitle = systemTitle;
SystemWorkItemType = systemWorkItemType;
MicrosoftVSTSSchedulingTargetDate = microsoftVSTSSchedulingTargetDate;
}
[JsonPropertyName("System.AreaPath")]
public string SystemAreaPath { get; } // { init; get; }
[JsonPropertyName("Custom.RRminusOE")] public int CustomRRminusOE { get; } // { init; get; }
[JsonPropertyName("Custom.Requester")] public CustomRequester? CustomRequester { get; } // { init; get; }
[JsonPropertyName("Custom.WSJF")] public float CustomWSJF { get; } // { init; get; }
[JsonPropertyName("Microsoft.VSTS.Common.BusinessValue")] public int 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("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.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("Microsoft.VSTS.Scheduling.TargetDate")] public DateTime MicrosoftVSTSSchedulingTargetDate { get; } // { init; get; }
[JsonPropertyName("System.TeamProject")]
public string SystemTeamProject { get; } // { init; get; }
[JsonPropertyName("System.IterationPath")]
public string SystemIterationPath { get; } // { init; get; }
[JsonPropertyName("System.WorkItemType")]
public string SystemWorkItemType { get; } // { init; get; }
[JsonPropertyName("System.State")]
public string SystemState { get; } // { init; get; }
[JsonPropertyName("System.Reason")]
public string SystemReason { get; } // { init; get; }
[JsonPropertyName("System.AssignedTo")]
public SystemAssignedTo SystemAssignedTo { get; } // { init; get; }
[JsonPropertyName("System.CreatedDate")]
public DateTime SystemCreatedDate { get; } // { init; get; }
[JsonPropertyName("System.CreatedBy")]
public SystemCreatedBy SystemCreatedBy { get; } // { init; get; }
[JsonPropertyName("System.ChangedDate")]
public DateTime SystemChangedDate { get; } // { init; get; }
[JsonPropertyName("System.ChangedBy")]
public SystemChangedBy SystemChangedBy { get; } // { init; get; }
[JsonPropertyName("System.CommentCount")]
public int SystemCommentCount { get; } // { init; get; }
[JsonPropertyName("System.Title")]
public string SystemTitle { get; } // { init; get; }
[JsonPropertyName("Microsoft.VSTS.Common.StateChangeDate")]
public DateTime MicrosoftVSTSCommonStateChangeDate { get; } // { init; get; }
[JsonPropertyName("Microsoft.VSTS.Common.Priority")]
public int MicrosoftVSTSCommonPriority { get; } // { init; get; }
[JsonPropertyName("System.Description")]
public string SystemDescription { get; } // { init; get; }
[JsonPropertyName("System.Tags")]
public string SystemTags { get; } // { init; get; }
[JsonPropertyName("System.History")]
public string SystemHistory { get; } // { init; get; }
[JsonPropertyName("Microsoft.VSTS.Scheduling.Effort")]
public float? Effort { get; } // { init; get; }
[JsonPropertyName("Microsoft.VSTS.Scheduling.TargetDate")]
public DateTime TargetDate { get; } // { init; get; }
}

View File

@ -0,0 +1,88 @@
using System;
using System.Text.Json.Serialization;
namespace Adaptation.FileHandlers.json.WorkItems;
public class WorkItem
{
#nullable enable
[JsonConstructor]
public WorkItem(string areaPath,
string? assignedTo,
int? businessValue,
DateTime changedDate,
DateTime? closedDate,
int commentCount,
DateTime createdDate,
string description,
float? effort,
int id,
string iterationPath,
int? priority,
string? requester,
DateTime? resolvedDate,
int revision,
int? riskReductionMinusOpportunityEnablement,
DateTime? startDate,
string state,
string tags,
DateTime? targetDate,
float? timeCriticality,
string title,
string workItemType,
float? weightedShortestJobFirst)
{
AreaPath = areaPath;
AssignedTo = assignedTo;
BusinessValue = businessValue;
ChangedDate = changedDate;
ClosedDate = closedDate;
CommentCount = commentCount;
CreatedDate = createdDate;
Description = description;
Effort = effort;
Id = id;
IterationPath = iterationPath;
Priority = priority;
Requester = requester;
ResolvedDate = resolvedDate;
Revision = revision;
RiskReductionMinusOpportunityEnablement = riskReductionMinusOpportunityEnablement;
StartDate = startDate;
State = state;
Tags = tags;
TargetDate = targetDate;
TimeCriticality = timeCriticality;
Title = title;
WorkItemType = workItemType;
WeightedShortestJobFirst = weightedShortestJobFirst;
}
public string AreaPath { get; set; } // { init; get; }
public string? AssignedTo { get; set; } // { init; get; }
public int? BusinessValue { get; set; } // { init; get; }
public DateTime ChangedDate { get; set; } // { init; get; }
public DateTime? ClosedDate { get; set; } // { init; get; }
public int CommentCount { get; set; } // { init; get; }
public DateTime CreatedDate { get; set; } // { init; get; }
public string Description { get; set; } // { init; get; }
public float? Effort { get; set; } // { init; get; }
public int Id { get; set; } // { init; get; }
public string IterationPath { get; set; } // { init; get; }
public int? Priority { get; set; } // { init; get; }
public string? Requester { get; set; } // { init; get; }
public DateTime? ResolvedDate { get; set; } // { init; get; }
public int Revision { get; set; } // { init; get; }
public int? RiskReductionMinusOpportunityEnablement { get; set; } // { init; get; }
public DateTime? StartDate { get; set; } // { init; get; }
public string State { get; set; } // { init; get; }
public string Tags { get; set; } // { init; get; }
public DateTime? TargetDate { get; set; } // { init; get; }
public float? TimeCriticality { get; set; } // { init; get; }
public string Title { get; set; } // { init; get; }
public string WorkItemType { get; set; } // { init; get; }
public float? WeightedShortestJobFirst { get; set; } // { init; get; }
}

View File

@ -52,7 +52,7 @@ public class BACKLOG_EQPT : EAFLoggingUnitTesting
[Ignore]
#endif
[TestMethod]
public void Development__v2_57_0__BACKLOG_EQPT__DownloadExcelFile()
public void Development__v2_57_0__BACKLOG_EQPT__DownloadWorkItems()
{
string check = ".xlsx";
MethodBase methodBase = new StackFrame().GetMethod();

View File

@ -52,9 +52,9 @@ public class BACKLOG : EAFLoggingUnitTesting
[Ignore]
#endif
[TestMethod]
public void Development__v2_57_0__BACKLOG__ConvertExcelToJson()
public void Development__v2_57_0__BACKLOG__json()
{
string check = "*.xlsx";
string check = "*.json";
MethodBase methodBase = new StackFrame().GetMethod();
EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Getting configuration"));
_ = AdaptationTesting.GetWriteConfigurationGetFileRead(methodBase, check, EAFLoggingUnitTesting.AdaptationTesting);

View File

@ -48,32 +48,6 @@ public class MESAFIBACKLOG : EAFLoggingUnitTesting
EAFLoggingUnitTesting?.Dispose();
}
#if DEBUG
[Ignore]
#endif
[TestMethod]
public void Development__v2_57_0__MESAFIBACKLOG__CopyToPaths()
{
string check = "*.json";
MethodBase methodBase = new StackFrame().GetMethod();
EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Getting configuration"));
_ = AdaptationTesting.GetWriteConfigurationGetFileRead(methodBase, check, EAFLoggingUnitTesting.AdaptationTesting);
EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit"));
}
#if DEBUG
[Ignore]
#endif
[TestMethod]
public void Development__v2_57_0__MESAFIBACKLOG__json()
{
string check = "*.json";
MethodBase methodBase = new StackFrame().GetMethod();
EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Getting configuration"));
_ = AdaptationTesting.GetWriteConfigurationGetFileRead(methodBase, check, EAFLoggingUnitTesting.AdaptationTesting);
EAFLoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit"));
}
#if DEBUG
[Ignore]
#endif

View File

@ -32,16 +32,16 @@ public class BACKLOG_EQPT
[Ignore]
[TestMethod]
public void Development__v2_57_0__BACKLOG_EQPT__DownloadExcelFile() => _BACKLOG_EQPT.Development__v2_57_0__BACKLOG_EQPT__DownloadExcelFile();
public void Development__v2_57_0__BACKLOG_EQPT__DownloadWorkItems() => _BACKLOG_EQPT.Development__v2_57_0__BACKLOG_EQPT__DownloadWorkItems();
[Ignore]
[TestMethod]
public void Development__v2_57_0__BACKLOG_EQPT__DownloadExcelFile637961178824025822__Normal()
public void Development__v2_57_0__BACKLOG_EQPT__DownloadWorkItems638612245609095845__Normal()
{
string check = ".xlsx";
string check = ".json";
bool validatePDSF = false;
MethodBase methodBase = new StackFrame().GetMethod();
_BACKLOG_EQPT.Development__v2_57_0__BACKLOG_EQPT__DownloadExcelFile();
_BACKLOG_EQPT.Development__v2_57_0__BACKLOG_EQPT__DownloadWorkItems();
_ = _BACKLOG_EQPT.AdaptationTesting.GetVariables(methodBase, check, validatePDSF);
for (int i = 0; i < int.MinValue; i++)
Thread.Sleep(500);

View File

@ -38,18 +38,18 @@ public class BACKLOG
[Ignore]
#endif
[TestMethod]
public void Development__v2_57_0__BACKLOG__ConvertExcelToJson() => _BACKLOG.Development__v2_57_0__BACKLOG__ConvertExcelToJson();
public void Development__v2_57_0__BACKLOG__json() => _BACKLOG.Development__v2_57_0__BACKLOG__json();
#if DEBUG
[Ignore]
#endif
[TestMethod]
public void Development__v2_57_0__BACKLOG__ConvertExcelToJson637961178824025822__Normal()
public void Development__v2_57_0__BACKLOG__json638612245609095846__Normal()
{
string check = "*.xlsx";
string check = "*.json";
bool validatePDSF = false;
MethodBase methodBase = new StackFrame().GetMethod();
_BACKLOG.Development__v2_57_0__BACKLOG__ConvertExcelToJson();
_BACKLOG.Development__v2_57_0__BACKLOG__json();
Assert.IsFalse(string.IsNullOrEmpty(_BACKLOG.AdaptationTesting.TestContext.FullyQualifiedTestClassName));
string[] variables = _BACKLOG.AdaptationTesting.GetVariables(methodBase, check, validatePDSF);
IFileRead fileRead = _BACKLOG.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false);

View File

@ -38,47 +38,7 @@ public class MESAFIBACKLOG
[Ignore]
#endif
[TestMethod]
public void Development__v2_57_0__MESAFIBACKLOG__json() => _MESAFIBACKLOG.Development__v2_57_0__MESAFIBACKLOG__json();
#if DEBUG
[Ignore]
#endif
[TestMethod]
public void Development__v2_57_0__MESAFIBACKLOG__json637961251829737445__Normal()
{
string check = "*.json";
bool validatePDSF = false;
_MESAFIBACKLOG.Development__v2_57_0__MESAFIBACKLOG__json();
MethodBase methodBase = new StackFrame().GetMethod();
Assert.IsFalse(string.IsNullOrEmpty(_MESAFIBACKLOG.AdaptationTesting.TestContext.FullyQualifiedTestClassName));
string[] variables = _MESAFIBACKLOG.AdaptationTesting.GetVariables(methodBase, check, validatePDSF);
IFileRead fileRead = _MESAFIBACKLOG.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false);
Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResult = fileRead.ReExtract();
Assert.IsFalse(string.IsNullOrEmpty(extractResult?.Item1));
Assert.IsNotNull(extractResult.Item3);
Assert.IsNotNull(extractResult.Item4);
NonThrowTryCatch();
}
#if DEBUG
[Ignore]
#endif
[TestMethod]
public void Development__v2_57_0__MESAFIBACKLOG__CopyToPaths638323658386612550__Normal()
{
string check = "*.json";
bool validatePDSF = false;
_MESAFIBACKLOG.Development__v2_57_0__MESAFIBACKLOG__CopyToPaths();
MethodBase methodBase = new StackFrame().GetMethod();
Assert.IsFalse(string.IsNullOrEmpty(_MESAFIBACKLOG.AdaptationTesting.TestContext.FullyQualifiedTestClassName));
string[] variables = _MESAFIBACKLOG.AdaptationTesting.GetVariables(methodBase, check, validatePDSF);
IFileRead fileRead = _MESAFIBACKLOG.AdaptationTesting.Get(methodBase, sourceFileLocation: variables[2], sourceFileFilter: variables[3], useCyclicalForDescription: false);
Tuple<string, Test[], JsonElement[], List<FileInfo>> extractResult = fileRead.ReExtract();
Assert.IsFalse(string.IsNullOrEmpty(extractResult?.Item1));
Assert.IsNotNull(extractResult.Item3);
Assert.IsNotNull(extractResult.Item4);
NonThrowTryCatch();
}
public void Development__v2_57_0__MESAFIBACKLOG__Kanban() => _MESAFIBACKLOG.Development__v2_57_0__MESAFIBACKLOG__Kanban();
#if DEBUG
[Ignore]

View File

@ -112,6 +112,7 @@
<Compile Include="Adaptation\FileHandlers\ConvertExcelToJson\ProcessData.cs" />
<Compile Include="Adaptation\FileHandlers\CopyToPaths\FileRead.cs" />
<Compile Include="Adaptation\FileHandlers\DownloadExcelFile\FileRead.cs" />
<Compile Include="Adaptation\FileHandlers\DownloadWorkItems\FileRead.cs" />
<Compile Include="Adaptation\FileHandlers\Dummy\FileRead.cs" />
<Compile Include="Adaptation\FileHandlers\IQSSi\FileRead.cs" />
<Compile Include="Adaptation\FileHandlers\json\FileRead.cs" />
@ -123,6 +124,7 @@
<Compile Include="Adaptation\FileHandlers\json\WIQL\WorkItem.cs" />
<Compile Include="Adaptation\FileHandlers\json\WorkItems\Avatar.cs" />
<Compile Include="Adaptation\FileHandlers\json\WorkItems\CommentVersionRef.cs" />
<Compile Include="Adaptation\FileHandlers\json\WorkItems\CustomRequester.cs" />
<Compile Include="Adaptation\FileHandlers\json\WorkItems\Fields.cs" />
<Compile Include="Adaptation\FileHandlers\json\WorkItems\Html.cs" />
<Compile Include="Adaptation\FileHandlers\json\WorkItems\Links.cs" />
@ -131,6 +133,7 @@
<Compile Include="Adaptation\FileHandlers\json\WorkItems\SystemCreatedBy.cs" />
<Compile Include="Adaptation\FileHandlers\json\WorkItems\Value.cs" />
<Compile Include="Adaptation\FileHandlers\json\WorkItems\ValueWithReq.cs" />
<Compile Include="Adaptation\FileHandlers\json\WorkItems\WorkItem.cs" />
<Compile Include="Adaptation\FileHandlers\Kanban\FileRead.cs" />
<Compile Include="Adaptation\FileHandlers\MoveMatchingFiles\FileRead.cs" />
<Compile Include="Adaptation\FileHandlers\OpenInsight\FileRead.cs" />

View File

@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("2.52.2.0")]
[assembly: AssemblyFileVersion("2.52.2.0")]
[assembly: AssemblyVersion("2.57.0.0")]
[assembly: AssemblyFileVersion("2.57.0.0")]