Now relying on pipeline to copy files from file shares for ghost-pcl and linc-pdfc

Now using entered-date-time-filter and load-signature-date-time-filter for logistics query
This commit is contained in:
2025-07-22 15:28:05 -07:00
parent 823a31e48a
commit e651c2804c
17 changed files with 431 additions and 187 deletions

View File

@ -41,7 +41,7 @@ public partial class Job
public DateTime DateTime { get; }
public List<Item> Items { get; }
public Job(string lsl2SQLConnectionString, string metrologyFileShare, string barcodeHostFileShare, HttpClient httpClient, string mid)
public Job(string lsl2SQLConnectionString, string metrologyFileShare, string barcodeHostFileShare, HttpClient httpClient, string mid, DateTime enteredDateTimeFilter, DateTime loadSignatureDateTimeFilter)
{
const int zero = 0;
Items = new List<Item>();
@ -52,7 +52,6 @@ public partial class Job
Common common;
CommonB commonB;
int? reactorNumber;
WorkOrder workOrder;
const string hyphen = "-";
const string bioRad2 = "BIORAD2";
const string bioRad3 = "BIORAD3";
@ -65,20 +64,23 @@ public partial class Job
DateTime = new DateTime(sequence);
const string dep08CEPIEPSILON = "DEP08CEPIEPSILON";
if (input.EquipmentType == dep08CEPIEPSILON)
(common, workOrder) = Get(input, httpClient);
{
common = Get(input, httpClient);
}
else if (!string.IsNullOrEmpty(input.MID) && !string.IsNullOrEmpty(input.MesEntity) && Regex.IsMatch(input.MID, reactorNumberPattern) && input.MesEntity is bioRad2 or bioRad3)
(common, workOrder) = Get(input, barcodeHostFileShare);
common = Get(input, barcodeHostFileShare);
else
{
workOrder = GetWorkOrder(input);
reactorNumber = GetReactorNumber(input);
WorkOrder workOrder = GetWorkOrder(input);
if (workOrder.IsWorkOrder || reactorNumber.HasValue)
common = new(layer: null,
psn: null,
rdsNumber: null,
reactor: null,
zone: null,
employee: null);
employee: 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
@ -86,13 +88,14 @@ public partial class Job
}
bool isValid = IsValid(common.RDSNumber);
if (isValid)
commonB = GetWithValidRDS(lsl2SQLConnectionString, common.Layer, common.PSN, common.RDSNumber, common.ReactorNumber, common.Zone);
else if (workOrder.IsWorkOrder || common.RDSNumber.HasValue)
commonB = Get(lsl2SQLConnectionString, common.Layer, common.PSN, common.ReactorNumber, workOrder.SlotNumber, workOrder.WorkOrderNumber, workOrder.WorkOrderCassette, common.Zone);
commonB = GetWithValidRDS(lsl2SQLConnectionString, enteredDateTimeFilter, loadSignatureDateTimeFilter, common.Layer, common.PSN, common.RDSNumber, common.ReactorNumber, common.Zone);
else if (common.WorkOrder is null || common.WorkOrder.IsWorkOrder || common.RDSNumber.HasValue)
commonB = Get(lsl2SQLConnectionString, enteredDateTimeFilter, loadSignatureDateTimeFilter, common);
else
commonB = new(comment: hyphen,
layer: hyphen,
commonB = new(layer: hyphen,
loadLockSide: hyphen,
rdsNumber: common.RDSNumber,
reactorType: hyphen,
psn: common.PSN,
reactorNumber: common.ReactorNumber,
zone: hyphen);
@ -108,17 +111,45 @@ public partial class Job
IsAreaSi = input.Area == "Si"; // N/A
StateModel = input.EquipmentType; // ?
JobName = DateTime.Ticks.ToString(); // ?
BasicType = GetComment(hyphen, httpClient, 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
BasicType = !string.IsNullOrEmpty(commonB.Comment) ? commonB.Comment : hyphen; // BASIC_TYPE
LotName = commonB.RDSNumber is not null ? commonB.RDSNumber.Value.ToString() : input.MID; // MID
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)
{
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
{
string loadLockSideFull = loadLockSide switch
{
"L" => "Left",
"R" => "Right",
_ => loadLockSide,
};
result = $"{loadLockSideFull} - {commonB.ReactorType}";
}
return result;
}
private static int? GetReactorNumber(Input input)
{
int? result;
@ -279,7 +310,8 @@ public partial class Job
rdsNumber: rdsNumber,
reactor: reactorNumber,
zone: zone,
employee: employee);
employee: employee,
workOrder: null);
}
private static string[] GetDirectories(string fileShare)
@ -342,7 +374,8 @@ public partial class Job
rdsNumber: rdsNumber,
reactor: reactor,
zone: zone,
employee: null);
employee: null,
workOrder: null);
}
private static List<string> GetFiles(Input input, string barcodeHostFileShare)
@ -381,12 +414,11 @@ public partial class Job
return result;
}
private static (Common common, WorkOrder workOrder) Get(Input input, HttpClient httpClient)
private static Common Get(Input input, HttpClient httpClient)
{
int? rds;
string psn;
Common common;
WorkOrder workOrder;
string? psn;
Common result;
Task<Stream> streamTask;
Task<HttpResponseMessage> httpResponseMessageTask;
string mid = string.IsNullOrEmpty(input.MID) ? string.Empty : input.MID;
@ -405,60 +437,70 @@ public partial class Job
if (reactorRoot is null || reactor != reactorRoot.Reactor.ReactorNo || reactorRoot.Reactor.LoadedRDS is null || reactorRoot.Reactor.LoadedRDS.Length < 1)
{
rds = null;
psn = string.Empty;
workOrder = new(null, null, null, null, false);
common = new(layer: null,
psn = null;
result = new(layer: null,
psn: psn,
rdsNumber: rds,
reactor: reactor,
zone: null,
employee: null);
employee: null,
workOrder: null);
}
else
{
rds = reactorRoot.Reactor.LoadedRDS[0];
workOrder = new(null, null, null, null, false);
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}>");
streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
streamTask.Wait();
if (!streamTask.Result.CanRead)
throw new NullReferenceException(nameof(streamTask));
RunDataSheetRoot? runDataSheetRoot = JsonSerializer.Deserialize<RunDataSheetRoot>(streamTask.Result, jsonSerializerOptions);
streamTask.Result.Dispose();
RunDataSheetRoot? runDataSheetRoot = GetRunDataSheetRoot(httpClient, rds.Value);
if (runDataSheetRoot is null || reactor != runDataSheetRoot.RunDataSheet.Reactor)
{
psn = string.Empty;
common = new(layer: null,
psn = null;
result = new(layer: null,
psn: psn,
rdsNumber: rds,
reactor: reactor,
zone: null,
employee: null);
employee: null,
workOrder: null);
}
else
{
psn = runDataSheetRoot.RunDataSheet.PSN.ToString();
common = new(layer: null,
result = new(layer: null,
psn: psn,
rdsNumber: rds,
reactor: reactor,
zone: null,
employee: null);
employee: null,
workOrder: null);
}
}
return new(common, workOrder);
return result;
}
private static (Common common, WorkOrder workOrder) Get(Input input, string barcodeHostFileShare)
private static RunDataSheetRoot? GetRunDataSheetRoot(HttpClient httpClient, int rds)
{
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;
}
private static Common Get(Input input, string barcodeHostFileShare)
{
Common result;
if (string.IsNullOrEmpty(barcodeHostFileShare) || !Directory.Exists(barcodeHostFileShare))
throw new Exception($"Unable to access file-share <{barcodeHostFileShare}>");
int? rds;
long sequence = 0;
WorkOrder workOrder;
WorkOrder? workOrder;
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);
@ -471,29 +513,28 @@ public partial class Job
if (text is null || text.Length < 3)
{
rds = null;
workOrder = new(null, null, null, null, false);
workOrder = null;
}
else if (!text.Contains('.'))
{
workOrder = null;
rds = !int.TryParse(text.Substring(2), out int rdsNumber) ? null : rdsNumber;
workOrder = new(null, null, null, null, false);
}
else
{
rds = null;
workOrder = GetWorkOrder(new(input, text.Substring(2)));
}
Common common = new(layer: null,
result = new(layer: null,
psn: null,
rdsNumber: rds,
reactor: reactor,
zone: null,
employee: null);
return new(common, workOrder);
employee: null,
workOrder: workOrder);
return result;
}
#nullable disable
private static string GetRunJson(string lsl2SQLConnectionString, string commandText)
{
StringBuilder result = new();
@ -513,7 +554,7 @@ public partial class Job
return result.ToString();
}
private static string GetCommandText(int? rds, int? workOrderNumber, int? workOrderCassette, int? slot, int? reactor)
private static string GetCommandText(DateTime enteredDateTimeFilter, DateTime loadSignatureDateTimeFilter, int? rds, int? workOrderNumber, int? workOrderCassette, int? slot, int? reactor)
{ // cSpell:disable
List<string> results = new();
int rdsValue = rds is null ? -1 : rds.Value;
@ -540,6 +581,7 @@ public partial class Job
results.Add(" ) zone ");
results.Add(" from lsl2sql.dbo.react_run rr ");
results.Add($" where rr.rds_no = {rdsValue}");
results.Add($" and rr.enter_dtm > '{enteredDateTimeFilter:yyyy-MM-dd} 00:00:00.000' ");
results.Add(" union all ");
results.Add(" select ");
results.Add(" rr.rds_no ");
@ -589,80 +631,87 @@ public partial class Job
results.Add(" select max(qa.rds_no) ");
results.Add(" from lsl2sql.dbo.react_run qa ");
results.Add(" where qa.load_sig != '' ");
results.Add(" and qa.load_sig_dtm > '2023-05-01 00:00:00.000' ");
results.Add($" and qa.load_sig_dtm > '{loadSignatureDateTimeFilter:yyyy-MM-dd} 00:00:00.000' ");
results.Add($" and qa.reactor = {reactorValue}");
results.Add(" ) ");
results.Add(" for json path ");
return string.Join(Environment.NewLine, results);
} // cSpell:restore
private static CommonB Get(string lsl2SQLConnectionString, string layer, string psn, int? reactorNumber, int? slotNumber, int? workOrderNumber, int? workOrderCassette, string zone)
private static CommonB Get(string lsl2SQLConnectionString, DateTime enteredDateTimeFilter, DateTime loadSignatureDateTimeFilter, Common common)
{
int? rdsNumber;
string comment;
string? psn;
string? zone;
string? layer;
const int zero = 0;
const string hyphen = "-";
string commandText = GetCommandText(rds: null,
workOrderNumber: workOrderNumber,
workOrderCassette: workOrderCassette,
slot: slotNumber,
reactor: reactorNumber);
int? reactorNumber;
string? reactorType;
string? loadLockSide;
string commandText = GetCommandText(enteredDateTimeFilter,
loadSignatureDateTimeFilter,
rds: null,
workOrderNumber: common.WorkOrder?.WorkOrderNumber,
workOrderCassette: common.WorkOrder?.WorkOrderCassette,
slot: common.WorkOrder?.SlotNumber,
reactor: common.ReactorNumber);
string json = GetRunJson(lsl2SQLConnectionString, commandText);
if (string.IsNullOrEmpty(json))
{
psn = common.PSN;
rdsNumber = null;
comment = hyphen;
psn = string.Empty;
zone = string.Empty;
reactorType = null;
zone = common.Zone;
loadLockSide = null;
layer = common.Layer;
reactorNumber = common.ReactorNumber;
}
else
{
Run[] runs;
Run[]? runs;
try
{ runs = JsonSerializer.Deserialize<Run[]>(json); }
catch (Exception)
{ runs = Array.Empty<Run>(); }
if (runs.Length == 0)
if (runs is null || runs.Length == 0)
{
psn = common.PSN;
rdsNumber = null;
comment = hyphen;
psn = string.Empty;
zone = string.Empty;
reactorType = null;
zone = common.Zone;
loadLockSide = null;
layer = common.Layer;
reactorNumber = common.ReactorNumber;
}
else
{
rdsNumber = runs[zero].RdsNo;
if (string.IsNullOrEmpty(psn))
psn = runs[zero].PSN;
if (string.IsNullOrEmpty(zone))
zone = runs[zero].Zone;
if (string.IsNullOrEmpty(layer))
layer = runs[zero].EpiLayer;
reactorNumber = runs[zero].Reactor;
string loadLockSide = runs[zero].LoadLockSide;
string loadLockSideFull = loadLockSide switch
{
"L" => "Left",
"R" => "Right",
_ => loadLockSide,
};
comment = $"{loadLockSideFull} - {runs[zero].ReactorType}";
reactorType = null;
Run run = runs[zero];
rdsNumber = run.RdsNo;
reactorNumber = run.Reactor;
loadLockSide = run.LoadLockSide;
psn = string.IsNullOrEmpty(common.PSN) ? run.PSN : common.PSN;
zone = string.IsNullOrEmpty(common.Zone) ? run.Zone : common.Zone;
layer = string.IsNullOrEmpty(common.Layer) ? run.EpiLayer : common.Layer;
}
}
return new(comment: comment,
layer: layer,
return new(layer: layer,
loadLockSide: loadLockSide,
rdsNumber: rdsNumber,
psn: psn,
reactorNumber: reactorNumber,
reactorType: reactorType,
zone: zone);
}
private static CommonB GetWithValidRDS(string lsl2SQLConnectionString, string layer, string psn, int? rdsNumber, int? reactorNumber, string zone)
private static CommonB GetWithValidRDS(string lsl2SQLConnectionString, DateTime enteredDateTimeFilter, DateTime loadSignatureDateTimeFilter, string? layer, string? psn, int? rdsNumber, int? reactorNumber, string? zone)
{
string comment;
const int zero = 0;
const string hyphen = "-";
string commandText = GetCommandText(rds: rdsNumber,
string? reactorType;
string? loadLockSide;
string commandText = GetCommandText(enteredDateTimeFilter,
loadSignatureDateTimeFilter,
rds: rdsNumber,
workOrderNumber: null,
workOrderCassette: null,
slot: null,
@ -670,43 +719,41 @@ public partial class Job
string json = GetRunJson(lsl2SQLConnectionString, commandText);
if (string.IsNullOrEmpty(json))
{
comment = hyphen;
zone = string.Empty;
zone = null;
reactorType = null;
loadLockSide = null;
}
else
{
Run[] runs;
Run[]? runs;
try
{ runs = JsonSerializer.Deserialize<Run[]>(json); }
catch (Exception)
{ runs = Array.Empty<Run>(); }
if (runs.Length == 0)
if (runs is null || runs.Length == 0)
{
comment = hyphen;
zone = string.Empty;
zone = null;
reactorType = null;
loadLockSide = null;
}
else
{
Run run = runs[zero];
if (string.IsNullOrEmpty(psn))
psn = runs[zero].PSN;
psn = run.PSN;
if (string.IsNullOrEmpty(zone))
zone = runs[zero].Zone;
zone = run.Zone;
if (string.IsNullOrEmpty(layer))
layer = runs[zero].EpiLayer;
reactorNumber = runs[zero].Reactor is null ? reactorNumber : runs[zero].Reactor.Value;
string loadLockSide = runs[zero].LoadLockSide;
string loadLockSideFull = loadLockSide switch
{
"L" => "Left",
"R" => "Right",
_ => loadLockSide,
};
comment = $"{loadLockSideFull} - {runs[zero].ReactorType}";
layer = run.EpiLayer;
reactorNumber = run.Reactor is null ? reactorNumber : run.Reactor.Value;
loadLockSide = run.LoadLockSide;
reactorType = run.ReactorType;
}
}
return new(comment: comment,
layer: layer,
return new(layer: layer,
loadLockSide: loadLockSide,
rdsNumber: rdsNumber,
reactorType: reactorType,
psn: psn,
reactorNumber: reactorNumber,
zone: zone);