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.Text; using System.Text.Json; using System.Threading.Tasks; namespace Adaptation.FileHandlers.json; 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, HttpClient httpClient, string basePage, string api, string query, WorkItemTrackingHttpClient workItemTrackingHttpClient, string project, ReadOnlyDictionary<string, string> assignedToNameToUser, ReadOnlyDictionary<string, string> requestorNameToUser, string json) { fileInfoCollection.Clear(); _Details = new List<object>(); Parse(fileRead, logistics, fileInfoCollection, httpClient, basePage, api, query, workItemTrackingHttpClient, project, assignedToNameToUser, requestorNameToUser, json); } 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); internal static List<Description> GetDescriptions(JsonElement[] jsonElements) => throw new NotImplementedException(); #nullable enable 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.Any()) 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(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)); results = JsonSerializer.Deserialize<Value[]>(jsonElement.Value.EnumerateObject().Last().Value); if (results is null || !results.Any()) 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; if (!DateTime.TryParseExact(fiBacklogMesa.CommitDate.Split(' ').First(), "MM/dd/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime dateTime) && dateTime != DateTime.MinValue) result = null; else result = dateTime.AddHours(12).ToUniversalTime(); 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; 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); 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 != $"{valueWithReq.Req} - {fiBacklogMesa.Subject}") { 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) { if (!int.TryParse(fiBacklogMesa.Priority.Substring(0, 1), out int priority)) { Update(workItemTrackingHttpClient, sync, valueWithReq); continue; } 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 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 CORE 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 } 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(); 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} - {fiBacklogMesa.Subject}"); 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 = $"{fiBacklogMesa.Req} - {fiBacklogMesa.Subject}"; if (title.Length > 128) title = title.Substring(0, 127); 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); 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 (int.TryParse(fiBacklogMesa.Priority.Substring(0, 1), out int priority) && priority != 0) AddPatch(result, "/fields/Microsoft.VSTS.Common.Priority", priority); 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> assignedToNameToUser, ReadOnlyDictionary<string, string> requestorNameToUser, string json) { 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? directory = Path.GetDirectoryName(fileRead.ReportFullPath) ?? throw new Exception(); string[] checkFiles = Directory.GetFiles(directory, "*.csv", SearchOption.TopDirectoryOnly); if (checkFiles.Any()) 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(httpClient, basePage, api, ids); int count = keyToFIBacklogMesa.Count; ReadOnlyCollection<ValueWithReq> valueWithReqCollection = GetValueWithReqCollection(workItems); SetSyncTag(workItemTrackingHttpClient, requestorNameToUser, keyToFIBacklogMesa, valueWithReqCollection); 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++; } } } }