Export run-data-sheet-root in last-update-user of logistics

Started Bun support but CORS fails

process-data-standard-format code alignment
This commit is contained in:
2025-08-04 16:58:37 -07:00
parent e3910d700f
commit 43024c6c30
13 changed files with 390 additions and 111 deletions

View File

@ -11,6 +11,7 @@ public class Common
public int? ReactorNumber { get; }
public string? Zone { get; }
public string? Employee { get; }
public RunDataSheetRoot? RunDataSheetRoot { get; }
public WorkOrder? WorkOrder { get; }
public Common(string? layer,
@ -19,6 +20,7 @@ public class Common
int? reactor,
string? zone,
string? employee,
RunDataSheetRoot? runDataSheetRoot,
WorkOrder? workOrder)
{
Layer = layer;
@ -27,6 +29,7 @@ public class Common
ReactorNumber = reactor;
Zone = zone;
Employee = employee;
RunDataSheetRoot = runDataSheetRoot;
WorkOrder = workOrder;
}

View File

@ -55,6 +55,7 @@ public partial class Job
const string hyphen = "-";
const string bioRad2 = "BIORAD2";
const string bioRad3 = "BIORAD3";
RunDataSheetRoot? runDataSheetRoot;
const string twoAlphaPattern = "^[a-zA-z]{2,3}";
const string reactorNumberPattern = @"^[0-9]{2}--";
Input input = JsonSerializer.Deserialize<Input>(mid) ?? throw new Exception();
@ -64,11 +65,9 @@ public partial class Job
DateTime = new DateTime(sequence);
const string dep08CEPIEPSILON = "DEP08CEPIEPSILON";
if (input.EquipmentType == dep08CEPIEPSILON)
{
common = Get(input, httpClient);
}
common = ReactorGet(input, httpClient);
else if (!string.IsNullOrEmpty(input.MID) && !string.IsNullOrEmpty(input.MesEntity) && Regex.IsMatch(input.MID, reactorNumberPattern) && input.MesEntity is bioRad2 or bioRad3)
common = Get(input, barcodeHostFileShare);
common = Get(input, barcodeHostFileShare, httpClient);
else
{
reactorNumber = GetReactorNumber(input);
@ -80,11 +79,12 @@ public partial class Job
reactor: null,
zone: null,
employee: null,
runDataSheetRoot: null,
workOrder: workOrder);
else if (!string.IsNullOrEmpty(input.MID) && input.MID.Length is 2 or 3 && Regex.IsMatch(input.MID, twoAlphaPattern))
common = GetTwoAlphaPattern(metrologyFileShare, input);
else
common = Get(input);
common = Get(input, httpClient);
}
bool isValid = IsValid(common.RDSNumber);
if (isValid)
@ -99,11 +99,19 @@ public partial class Job
psn: common.PSN,
reactorNumber: common.ReactorNumber,
zone: hyphen);
if (commonB.RDSNumber is null || common.RunDataSheetRoot is not null)
runDataSheetRoot = common.RunDataSheetRoot;
else
{
try
{ runDataSheetRoot = GetRunDataSheetRoot(httpClient, commonB.RDSNumber.Value); }
catch (Exception)
{ runDataSheetRoot = null; }
}
Qty = "1";
Status = hyphen; // INFO
CreationUser = hyphen; // ?
LotState = hyphen; // LAYER2
LastUpdateUser = hyphen; // ?
Equipment = input.MesEntity; // ?
PackageName = hyphen; // WAFER_ID
Qty2 = input.Sequence; // SEQUENCE
@ -111,30 +119,24 @@ public partial class Job
IsAreaSi = input.Area == "Si"; // N/A
StateModel = input.EquipmentType; // ?
JobName = DateTime.Ticks.ToString(); // ?
BasicType = GetComment(hyphen, httpClient, commonB); // BASIC_TYPE
BasicType = GetComment(hyphen, runDataSheetRoot, commonB); // BASIC_TYPE
AutomationMode = string.Concat(DateTime.Ticks, ".", input.MesEntity); // ?
SpecName = !string.IsNullOrEmpty(commonB.Layer) ? commonB.Layer : hyphen; // LAYER
ProductName = !string.IsNullOrEmpty(commonB.PSN) ? commonB.PSN : hyphen; // PRODUCT
ProcessSpecName = !string.IsNullOrEmpty(commonB.Zone) ? commonB.Zone : hyphen; // WAFER_POS
LotName = commonB.RDSNumber is not null ? commonB.RDSNumber.Value.ToString() : input.MID; // MID
LastUpdateUser = string.IsNullOrEmpty(runDataSheetRoot?.Json) ? "{}" : runDataSheetRoot.Json; // NULL_DATA
ProcessType = commonB.ReactorNumber is not null ? commonB.ReactorNumber.Value.ToString() : hyphen; // PROCESS_JOBID
Items.Add(new Item { Name = "0", Type = "NA", Number = (0 + 1).ToString(), Qty = "1", CarrierName = hyphen });
}
}
private static string GetComment(string hyphen, HttpClient httpClient, CommonB commonB)
private static string GetComment(string hyphen, RunDataSheetRoot? runDataSheetRoot, CommonB commonB)
{
string result;
string? loadLockSide = commonB.LoadLockSide;
if (string.IsNullOrEmpty(loadLockSide) && commonB.RDSNumber is not null)
{
RunDataSheetRoot? runDataSheetRoot;
try
{ runDataSheetRoot = GetRunDataSheetRoot(httpClient, commonB.RDSNumber.Value); }
catch (Exception)
{ runDataSheetRoot = null; }
loadLockSide = runDataSheetRoot?.RunDataSheet?.LoadLockSide;
}
if (string.IsNullOrEmpty(loadLockSide) || string.IsNullOrEmpty(commonB.ReactorType))
result = hyphen;
else
@ -270,8 +272,9 @@ public partial class Job
return result;
}
private static Common Get(Input input)
private static Common Get(Input input, HttpClient httpClient)
{
Common result;
string? psn;
string? rds;
int rdsCheck;
@ -281,6 +284,7 @@ public partial class Job
string? reactor;
string? employee;
int? reactorNumber;
RunDataSheetRoot? runDataSheetRoot;
string mid = string.IsNullOrEmpty(input.MID) ? string.Empty : input.MID;
if (mid.Length > 2 && mid[0] == '1' && (mid[1] == 'T' || mid[1] == 't'))
mid = mid.Substring(2);
@ -290,13 +294,14 @@ public partial class Job
(reactor, rds) = GetReactorAndRDS(input.MID, mid, segments);
rdsNumber = string.IsNullOrEmpty(rds) || !int.TryParse(rds, out rdsCheck) ? null : rdsCheck;
bool isInvalid = IsInvalid(rdsNumber);
if (isInvalid || !int.TryParse(reactor, out int reactorCheck))
if (rdsNumber is null || isInvalid || !int.TryParse(reactor, out int reactorCheck))
{
psn = null;
zone = null;
layer = null;
employee = null;
reactorNumber = null;
runDataSheetRoot = null;
}
else
{
@ -304,14 +309,17 @@ public partial class Job
reactorNumber = reactorCheck;
(layer, psn) = GetLayerAndPSN(segments);
employee = segments.Length <= 4 ? null : segments[4];
runDataSheetRoot = GetRunDataSheetRoot(httpClient, rdsNumber.Value);
}
return new(layer: layer,
psn: psn,
rdsNumber: rdsNumber,
reactor: reactorNumber,
zone: zone,
employee: employee,
workOrder: null);
result = new(layer: layer,
psn: psn,
rdsNumber: rdsNumber,
reactor: reactorNumber,
zone: zone,
employee: employee,
runDataSheetRoot: runDataSheetRoot,
workOrder: null);
return result;
}
private static string[] GetDirectories(string fileShare)
@ -330,6 +338,7 @@ public partial class Job
private static Common GetTwoAlphaPattern(string metrologyFileShare, Input input)
{
Common result;
string lines;
const int zero = 0;
string? psn = null;
@ -369,13 +378,15 @@ public partial class Job
zone = workMaterialOut.Zone;
break;
}
return new(layer: layer,
psn: psn,
rdsNumber: rdsNumber,
reactor: reactor,
zone: zone,
employee: null,
workOrder: null);
result = new(layer: layer,
psn: psn,
rdsNumber: rdsNumber,
reactor: reactor,
zone: zone,
employee: null,
runDataSheetRoot: null,
workOrder: null);
return result;
}
private static List<string> GetFiles(Input input, string barcodeHostFileShare)
@ -414,27 +425,16 @@ public partial class Job
return result;
}
private static Common Get(Input input, HttpClient httpClient)
private static Common ReactorGet(Input input, HttpClient httpClient)
{
int? rds;
string? psn;
Common result;
Task<Stream> streamTask;
Task<HttpResponseMessage> httpResponseMessageTask;
string mid = string.IsNullOrEmpty(input.MID) ? string.Empty : input.MID;
JsonSerializerOptions jsonSerializerOptions = new() { PropertyNameCaseInsensitive = true };
int? reactor = mid.Length < 2 || !int.TryParse(mid.Substring(0, 2), out int reactorNumber) ? null : reactorNumber;
httpResponseMessageTask = httpClient.GetAsync($"{httpClient.BaseAddress}/reactors/{reactor}");
httpResponseMessageTask.Wait();
if (httpResponseMessageTask.Result.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception($"Unable to OI <{httpResponseMessageTask.Result.StatusCode}>");
streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
if (!streamTask.Result.CanRead)
throw new NullReferenceException(nameof(streamTask));
ReactorRoot? reactorRoot = JsonSerializer.Deserialize<ReactorRoot>(streamTask.Result, jsonSerializerOptions);
streamTask.Result.Dispose();
if (reactorRoot is null || reactor != reactorRoot.Reactor.ReactorNo || reactorRoot.Reactor.LoadedRDS is null || reactorRoot.Reactor.LoadedRDS.Length < 1)
ReactorRoot? reactorRoot = reactor is null ? null : GetReactorRoot(httpClient, jsonSerializerOptions, reactor);
if (reactorRoot?.Reactor is null || reactor != reactorRoot.Reactor.ReactorNo || reactorRoot.Reactor.LoadedRDS is null || reactorRoot.Reactor.LoadedRDS.Length < 1)
{
rds = null;
psn = null;
@ -444,13 +444,14 @@ public partial class Job
reactor: reactor,
zone: null,
employee: null,
runDataSheetRoot: null,
workOrder: null);
}
else
{
rds = reactorRoot.Reactor.LoadedRDS[0];
RunDataSheetRoot? runDataSheetRoot = GetRunDataSheetRoot(httpClient, rds.Value);
if (runDataSheetRoot is null || reactor != runDataSheetRoot.RunDataSheet.Reactor)
if (runDataSheetRoot?.RunDataSheet is null || reactor != runDataSheetRoot.RunDataSheet.Reactor)
{
psn = null;
result = new(layer: null,
@ -459,6 +460,7 @@ public partial class Job
reactor: reactor,
zone: null,
employee: null,
runDataSheetRoot: runDataSheetRoot,
workOrder: null);
}
else
@ -470,30 +472,51 @@ public partial class Job
reactor: reactor,
zone: null,
employee: null,
runDataSheetRoot: runDataSheetRoot,
workOrder: null);
}
}
return result;
}
private static RunDataSheetRoot? GetRunDataSheetRoot(HttpClient httpClient, int rds)
private static ReactorRoot? GetReactorRoot(HttpClient httpClient, JsonSerializerOptions jsonSerializerOptions, int? reactor)
{
RunDataSheetRoot? runDataSheetRoot;
JsonSerializerOptions jsonSerializerOptions = new() { PropertyNameCaseInsensitive = true };
using Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync($"{httpClient.BaseAddress}/materials/rds/{rds}");
httpResponseMessageTask.Wait();
if (httpResponseMessageTask.Result.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception($"Unable to OI <{httpResponseMessageTask.Result.StatusCode}>");
using Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
if (!streamTask.Result.CanRead)
throw new NullReferenceException(nameof(streamTask));
runDataSheetRoot = JsonSerializer.Deserialize<RunDataSheetRoot>(streamTask.Result, jsonSerializerOptions);
streamTask.Result.Dispose();
return runDataSheetRoot;
ReactorRoot? result;
try
{
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync($"{httpClient.BaseAddress}/reactors/{reactor}");
httpResponseMessageTask.Wait();
if (httpResponseMessageTask.Result.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception($"Unable to OI <{httpResponseMessageTask.Result.StatusCode}>");
using Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
result = !streamTask.Result.CanRead ? null : JsonSerializer.Deserialize<ReactorRoot>(streamTask.Result, jsonSerializerOptions);
}
catch (Exception) { result = null; }
return result;
}
private static Common Get(Input input, string barcodeHostFileShare)
private static RunDataSheetRoot? GetRunDataSheetRoot(HttpClient httpClient, int rds)
{
RunDataSheetRoot? result;
try
{
JsonSerializerOptions jsonSerializerOptions = new() { PropertyNameCaseInsensitive = true };
using Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync($"{httpClient.BaseAddress}/materials/rds/{rds}");
httpResponseMessageTask.Wait();
if (httpResponseMessageTask.Result.StatusCode != System.Net.HttpStatusCode.OK)
throw new Exception($"Unable to OI <{httpResponseMessageTask.Result.StatusCode}>");
Task<string> json = httpResponseMessageTask.Result.Content.ReadAsStringAsync();
json.Wait();
result = JsonSerializer.Deserialize<RunDataSheetRoot>(json.Result, jsonSerializerOptions);
result ??= new RunDataSheetRoot(null);
result.Json = json.Result;
}
catch (Exception) { result = null; }
return result;
}
private static Common Get(Input input, string barcodeHostFileShare, HttpClient httpClient)
{
Common result;
if (string.IsNullOrEmpty(barcodeHostFileShare) || !Directory.Exists(barcodeHostFileShare))
@ -501,6 +524,7 @@ public partial class Job
int? rds;
long sequence = 0;
WorkOrder? workOrder;
RunDataSheetRoot? runDataSheetRoot;
string mid = string.IsNullOrEmpty(input.MID) ? string.Empty : input.MID;
int? reactor = mid.Length < 2 || !int.TryParse(mid.Substring(0, 2), out int reactorNumber) ? null : reactorNumber;
bool parsed = !string.IsNullOrEmpty(input.Sequence) && long.TryParse(input.Sequence, out sequence);
@ -514,24 +538,28 @@ public partial class Job
{
rds = null;
workOrder = null;
runDataSheetRoot = null;
}
else if (!text.Contains('.'))
{
workOrder = null;
rds = !int.TryParse(text.Substring(2), out int rdsNumber) ? null : rdsNumber;
rds = !int.TryParse(text.Substring(2), out int rdsNumber) || IsInvalid(rdsNumber) ? null : rdsNumber;
runDataSheetRoot = rds is null ? null : GetRunDataSheetRoot(httpClient, rds.Value);
}
else
{
rds = null;
runDataSheetRoot = null;
workOrder = GetWorkOrder(new(input, text.Substring(2)));
}
result = new(layer: null,
psn: null,
rdsNumber: rds,
reactor: reactor,
zone: null,
employee: null,
workOrder: workOrder);
psn: null,
rdsNumber: rds,
reactor: reactor,
zone: null,
employee: null,
runDataSheetRoot: runDataSheetRoot,
workOrder: workOrder);
return result;
}

View File

@ -2,13 +2,15 @@ using System.Text.Json.Serialization;
namespace Adaptation.FileHandlers.TIBCO.Transport;
#nullable enable
public class ReactorRoot
{
[JsonConstructor]
public ReactorRoot(Reactor reactor) =>
public ReactorRoot(Reactor? reactor) =>
Reactor = reactor;
[JsonPropertyName("reactor")] public Reactor Reactor { get; } // { init; get; }
[JsonPropertyName("reactor")] public Reactor? Reactor { get; } // { init; get; }
}

View File

@ -2,13 +2,16 @@ using System.Text.Json.Serialization;
namespace Adaptation.FileHandlers.TIBCO.Transport;
#nullable enable
public class RunDataSheetRoot
{
[JsonConstructor]
public RunDataSheetRoot(RunDataSheet runDataSheet) =>
public RunDataSheetRoot(RunDataSheet? runDataSheet) =>
RunDataSheet = runDataSheet;
[JsonPropertyName("rds")] public RunDataSheet RunDataSheet { get; } // { init; get; }
public string? Json { get; set; }
[JsonPropertyName("rds")] public RunDataSheet? RunDataSheet { get; } // { init; get; }
}