544 lines
24 KiB
C#
544 lines
24 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data;
|
|
using System.Data.SqlClient;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Text.RegularExpressions;
|
|
|
|
namespace Adaptation.FileHandlers.TIBCO.Transport;
|
|
|
|
public class Job
|
|
{
|
|
|
|
#nullable restore
|
|
|
|
public string AutomationMode { get; }
|
|
public string BasicType { get; }
|
|
public string CreationUser { get; }
|
|
public string Equipment { get; }
|
|
public string JobName { get; }
|
|
public string LastUpdateUser { get; }
|
|
public string LotName { get; }
|
|
public string LotState { get; }
|
|
public string PackageName { get; }
|
|
public string ProcessSpecName { get; }
|
|
public string ProcessType { get; }
|
|
public string ProductName { get; }
|
|
public string Qty { get; }
|
|
public string Qty2 { get; }
|
|
public string RecipeName { get; }
|
|
public string SpecName { get; }
|
|
public string StateModel { get; }
|
|
public string Status { get; }
|
|
//
|
|
public bool IsAreaSi { get; }
|
|
public DateTime DateTime { get; }
|
|
public List<Item> Items { get; }
|
|
|
|
public Job(string lsl2SQLConnectionString, string metrologyFileShare, string barcodeHostFileShare, string mid)
|
|
{
|
|
const int zero = 0;
|
|
Items = new List<Item>();
|
|
if (string.IsNullOrEmpty(mid) || mid[zero] != '{' || mid[mid.Length - 1] != '}' || !mid.Contains("\"Si\""))
|
|
IsAreaSi = false;
|
|
else
|
|
{
|
|
string psn;
|
|
string zone;
|
|
string layer;
|
|
int? rdsNumber;
|
|
string comment;
|
|
const string hyphen = "-";
|
|
Input input = JsonSerializer.Deserialize<Input>(mid);
|
|
if (!long.TryParse(input.Sequence, out long sequence))
|
|
DateTime = DateTime.Now;
|
|
else
|
|
DateTime = new DateTime(sequence);
|
|
int? reactorNumber = GetReactorNumber(input);
|
|
(int? workOrderNumber, int? _, int? workOrderCassette, int? slotNumber, bool isWorkOrder) = GetWorkOrder(input);
|
|
if (isWorkOrder || reactorNumber.HasValue)
|
|
(layer, psn, rdsNumber, zone) = (string.Empty, string.Empty, null, string.Empty);
|
|
else if (!string.IsNullOrEmpty(input.MID) && input.MID.Length is 2 or 3 && Regex.IsMatch(input.MID, "^[a-zA-z]{2,3}"))
|
|
(layer, psn, rdsNumber, reactorNumber, zone) = Get(metrologyFileShare, input);
|
|
else if (!string.IsNullOrEmpty(input.MID) && !string.IsNullOrEmpty(input.MesEntity) && input.MesEntity is "BIORAD2" or "BIORAD3" && Regex.IsMatch(input.MID, @"^[0-9]{2}[.][0-9]{1}[.]?[0-9]{0,1}"))
|
|
(layer, psn, rdsNumber, reactorNumber, zone) = Get(input, barcodeHostFileShare);
|
|
else
|
|
(layer, psn, rdsNumber, reactorNumber, zone) = Get(input);
|
|
if (IsValid(rdsNumber))
|
|
(comment, layer, rdsNumber, psn, reactorNumber, zone) = GetWithValidRDS(lsl2SQLConnectionString, layer, psn, rdsNumber, reactorNumber, zone);
|
|
else if (isWorkOrder || reactorNumber.HasValue)
|
|
(comment, layer, rdsNumber, psn, reactorNumber, zone) = Get(lsl2SQLConnectionString, layer, psn, reactorNumber, slotNumber, workOrderNumber, workOrderCassette, zone);
|
|
else
|
|
(comment, layer, zone) = (hyphen, hyphen, hyphen);
|
|
Qty = "1";
|
|
Status = hyphen; // INFO
|
|
CreationUser = hyphen; // ?
|
|
LotState = hyphen; // LAYER2
|
|
LastUpdateUser = hyphen; // ?
|
|
Equipment = input.MesEntity; // ?
|
|
PackageName = hyphen; // WAFER_ID
|
|
Qty2 = input.Sequence; // SEQUENCE
|
|
RecipeName = input.Recipe; // PPID
|
|
IsAreaSi = input.Area == "Si"; // N/A
|
|
StateModel = input.EquipmentType; // ?
|
|
JobName = DateTime.Ticks.ToString(); // ?
|
|
SpecName = !string.IsNullOrEmpty(layer) ? layer : hyphen; // LAYER
|
|
ProductName = !string.IsNullOrEmpty(psn) ? psn : hyphen; // PRODUCT
|
|
AutomationMode = string.Concat(DateTime.Ticks, ".", input.MesEntity); // ?
|
|
ProcessSpecName = !string.IsNullOrEmpty(zone) ? zone : hyphen; // WAFER_POS
|
|
BasicType = !string.IsNullOrEmpty(comment) ? comment : hyphen; // BASIC_TYPE
|
|
LotName = rdsNumber is not null ? rdsNumber.Value.ToString() : hyphen; // MID
|
|
ProcessType = reactorNumber is not null ? reactorNumber.Value.ToString() : hyphen; // PROCESS_JOBID
|
|
Items.Add(new Item { Name = "0", Type = "NA", Number = (0 + 1).ToString(), Qty = "1", CarrierName = hyphen });
|
|
}
|
|
}
|
|
|
|
private static int? GetReactorNumber(Input input)
|
|
{
|
|
int? result;
|
|
bool isReactor = !string.IsNullOrEmpty(input.MID) && input.MID.Length == 2 && Regex.IsMatch(input.MID, "^[0-9]{2}$");
|
|
if (!isReactor)
|
|
result = null;
|
|
else if (!int.TryParse(input.MID, out int reactor))
|
|
result = null;
|
|
else
|
|
result = reactor;
|
|
return result;
|
|
}
|
|
|
|
private static (int?, int?, int?, int?, bool) GetWorkOrder(Input input)
|
|
{
|
|
int? slotNumber;
|
|
int? workOrderStep = null;
|
|
int? workOrderNumber = null;
|
|
MatchCollection[] collection;
|
|
int? workOrderCassette = null;
|
|
if (string.IsNullOrEmpty(input.MID))
|
|
collection = Array.Empty<MatchCollection>();
|
|
else
|
|
{
|
|
string pattern = @"^([oiOI])?([0-9]{6,7})\.([0-5]{1})\.([0-9]{1,2})$"; // o171308.1.51
|
|
collection = (from l in input.MID.Split('-') select Regex.Matches(l, pattern)).ToArray();
|
|
}
|
|
foreach (MatchCollection matchCollection in collection)
|
|
{
|
|
if (matchCollection.Count == 0)
|
|
continue;
|
|
if (!matchCollection[0].Success || matchCollection[0].Groups.Count != 5)
|
|
continue;
|
|
if (!int.TryParse(matchCollection[0].Groups[3].Value, out int workOrderStepValue))
|
|
continue;
|
|
if (!int.TryParse(matchCollection[0].Groups[2].Value, out int workOrderNumberValue))
|
|
continue;
|
|
if (!int.TryParse(matchCollection[0].Groups[4].Value, out int workOrderCassetteValue))
|
|
continue;
|
|
workOrderStep = workOrderStepValue;
|
|
workOrderNumber = workOrderNumberValue;
|
|
workOrderCassette = workOrderCassetteValue;
|
|
break;
|
|
}
|
|
if (string.IsNullOrEmpty(input.Slot) || !int.TryParse(input.Slot, out int slot))
|
|
slotNumber = null;
|
|
else
|
|
slotNumber = slot;
|
|
return new(workOrderNumber, workOrderStep, workOrderCassette, slotNumber, workOrderStep is not null || workOrderNumber is not null || workOrderCassette is not null);
|
|
}
|
|
|
|
private static bool IsValid(int? rdsNumber) => !IsInvalid(rdsNumber);
|
|
|
|
private static bool IsInvalid(int? rdsNumber) => rdsNumber is null or < 100000 or > 100000000;
|
|
|
|
private static (string, string) GetReactorAndRDS(string defaultReactor, string defaultRDS, string text, string formattedText, string[] segments)
|
|
{
|
|
string rds;
|
|
string reactor;
|
|
if (string.IsNullOrEmpty(text) || segments.Length == 0 || string.IsNullOrEmpty(formattedText))
|
|
reactor = defaultReactor;
|
|
else
|
|
reactor = segments[0];
|
|
if (segments.Length <= 1 || !int.TryParse(segments[1], out int rdsValue) || rdsValue < 99)
|
|
rds = defaultRDS;
|
|
else
|
|
rds = segments[1];
|
|
if (reactor.Length > 3)
|
|
{
|
|
rds = reactor;
|
|
reactor = defaultReactor;
|
|
}
|
|
return new(reactor, rds);
|
|
}
|
|
|
|
private static (string, string) GetLayerAndPSN(string defaultLayer, string defaultPSN, string[] segments)
|
|
{
|
|
string psn;
|
|
string layer;
|
|
if (segments.Length <= 2)
|
|
{
|
|
psn = defaultPSN;
|
|
layer = defaultLayer;
|
|
}
|
|
else
|
|
{
|
|
string[] segmentsB = segments[2].Split('.');
|
|
psn = segmentsB[0];
|
|
if (segmentsB.Length <= 1)
|
|
layer = defaultLayer;
|
|
else
|
|
{
|
|
layer = segmentsB[1];
|
|
if (layer.Length > 1 && layer[0] == '0')
|
|
layer = layer.Substring(1);
|
|
}
|
|
}
|
|
return (layer, psn);
|
|
}
|
|
|
|
private static string GetZone(string[] segments)
|
|
{
|
|
string result;
|
|
if (segments.Length <= 3)
|
|
result = string.Empty;
|
|
else
|
|
{
|
|
result = segments[3];
|
|
if (result.Length > 1 && result[0] == '0')
|
|
result = result.Substring(1);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static (string, string, int, int?, string) Get(Input input)
|
|
{
|
|
string psn;
|
|
string rds;
|
|
string zone;
|
|
string layer;
|
|
int rdsNumber;
|
|
string reactor;
|
|
int? reactorNumber;
|
|
string defaultPSN = string.Empty;
|
|
string defaultRDS = string.Empty;
|
|
string defaultLayer = string.Empty;
|
|
string defaultReactor = string.Empty;
|
|
string[] segments = input.MID.Split(new char[] { '-' });
|
|
// bool hasRDS = Regex.IsMatch(input.MID, "[-]?([QP][0-9]{4,}|[0-9]{5,})[-]?");
|
|
string formattedText = Regex.Replace(input.MID, @"[\\,\/,\:,\*,\?,\"",\<,\>,\|]", "_").Split('\r')[0].Split('\n')[0];
|
|
(reactor, rds) = GetReactorAndRDS(defaultReactor, defaultRDS, input.MID, formattedText, segments);
|
|
if (string.IsNullOrEmpty(rds) || segments.Length < 2)
|
|
rdsNumber = 0;
|
|
else
|
|
_ = int.TryParse(segments[1], out rdsNumber);
|
|
if (IsInvalid(rdsNumber) || !int.TryParse(reactor, out int reactorCheck))
|
|
{
|
|
psn = string.Empty;
|
|
zone = string.Empty;
|
|
layer = string.Empty;
|
|
reactorNumber = null;
|
|
}
|
|
else
|
|
{
|
|
reactorNumber = reactorCheck;
|
|
(layer, psn) = GetLayerAndPSN(defaultLayer, defaultPSN, segments);
|
|
zone = GetZone(segments);
|
|
}
|
|
return new(layer, psn, rdsNumber, reactorNumber, zone);
|
|
}
|
|
|
|
private static string[] GetDirectories(string fileShare)
|
|
{
|
|
DateTime dateTime = DateTime.Now;
|
|
DateTime before = dateTime.AddHours(-1);
|
|
Calendar calendar = new CultureInfo("en-US").Calendar;
|
|
string weekOfYear = $"{dateTime:yyyy}_Week_{calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
|
|
string weekOfYearForBefore = $"{before:yyyy}_Week_{calendar.GetWeekOfYear(before, CalendarWeekRule.FirstDay, DayOfWeek.Sunday):00}";
|
|
return new string[]
|
|
{
|
|
Path.Combine(fileShare, weekOfYear, dateTime.ToString("yyyy-MM-dd_HH")),
|
|
Path.Combine(fileShare, weekOfYearForBefore, before.ToString("yyyy-MM-dd_HH"))
|
|
};
|
|
}
|
|
|
|
#nullable enable
|
|
|
|
private static (string, string, int?, int?, string) Get(string metrologyFileShare, Input input)
|
|
{
|
|
string lines;
|
|
const int zero = 0;
|
|
int? reactor = null;
|
|
int? rdsNumber = null;
|
|
string psn = string.Empty;
|
|
List<string> files = new();
|
|
string zone = string.Empty;
|
|
string layer = string.Empty;
|
|
WorkMaterialOut? workMaterialOut;
|
|
if (string.IsNullOrEmpty(metrologyFileShare) || !Directory.Exists(metrologyFileShare))
|
|
throw new Exception($"Unable to access file-share <{metrologyFileShare}>");
|
|
if (!string.IsNullOrEmpty(input.MID) && input.MID.Length is 3)
|
|
{
|
|
string[] checkDirectories = GetDirectories(metrologyFileShare);
|
|
foreach (string checkDirectory in checkDirectories)
|
|
{
|
|
if (!Directory.Exists(checkDirectory))
|
|
_ = Directory.CreateDirectory(checkDirectory);
|
|
files.AddRange(Directory.GetFiles(checkDirectory, $"WMO-{input.MID}.json", SearchOption.TopDirectoryOnly));
|
|
files.AddRange(Directory.GetFiles(checkDirectory, $"WMO-{input.MID.Substring(1, 2)}{input.MID[zero]}.json", SearchOption.TopDirectoryOnly));
|
|
}
|
|
}
|
|
foreach (string file in files.OrderByDescending(l => new FileInfo(l).LastWriteTime))
|
|
{
|
|
lines = File.ReadAllText(file);
|
|
workMaterialOut = JsonSerializer.Deserialize<WorkMaterialOut>(lines, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
|
|
if (workMaterialOut is null)
|
|
continue;
|
|
if (!string.IsNullOrEmpty(workMaterialOut.Layer))
|
|
layer = workMaterialOut.Layer;
|
|
if (!string.IsNullOrEmpty(workMaterialOut.PSN))
|
|
psn = workMaterialOut.PSN;
|
|
if (!string.IsNullOrEmpty(workMaterialOut.RunDataSheet) && int.TryParse(workMaterialOut.RunDataSheet, out int rds))
|
|
rdsNumber = rds;
|
|
reactor = workMaterialOut.Reactor;
|
|
if (!string.IsNullOrEmpty(workMaterialOut.Zone))
|
|
zone = workMaterialOut.Zone;
|
|
break;
|
|
}
|
|
return new(layer, psn, rdsNumber, reactor, zone);
|
|
}
|
|
|
|
private static (string, string, int?, int?, string) Get(Input input, string barcodeHostFileShare)
|
|
{
|
|
string text;
|
|
int? rds = null;
|
|
FileInfo fileInfo;
|
|
long sequence = 0;
|
|
string psn = string.Empty;
|
|
List<string> files = new();
|
|
string[] segments = input.MID.Split('.');
|
|
string layer = segments[1];
|
|
string zone = segments.Length <= 2 ? string.Empty : segments[2];
|
|
int? reactor = !int.TryParse(segments[0], out int reactorNumber) ? null : reactorNumber;
|
|
bool parsed = !string.IsNullOrEmpty(input.Sequence) && long.TryParse(input.Sequence, out sequence);
|
|
if (string.IsNullOrEmpty(barcodeHostFileShare) || !Directory.Exists(barcodeHostFileShare))
|
|
throw new Exception($"Unable to access file-share <{barcodeHostFileShare}>");
|
|
if (parsed && !string.IsNullOrEmpty(input.MID))
|
|
{
|
|
string[] checkDirectories = GetDirectories(barcodeHostFileShare);
|
|
foreach (string checkDirectory in checkDirectories)
|
|
{
|
|
if (!Directory.Exists(checkDirectory))
|
|
_ = Directory.CreateDirectory(checkDirectory);
|
|
files.AddRange(Directory.GetFiles(checkDirectory, $"{input.MesEntity}.csv", SearchOption.TopDirectoryOnly));
|
|
}
|
|
}
|
|
foreach (string file in files.OrderByDescending(l => new FileInfo(l).LastWriteTime))
|
|
{
|
|
fileInfo = new FileInfo(file);
|
|
if (fileInfo.LastWriteTime.Ticks > sequence)
|
|
continue;
|
|
text = File.ReadAllText(file);
|
|
rds = !int.TryParse(segments[0], out int rdsNumber) ? null : rdsNumber;
|
|
break;
|
|
}
|
|
return new(layer, psn, rds, reactor, zone);
|
|
}
|
|
|
|
#nullable disable
|
|
|
|
private static string GetRunJson(string lsl2SQLConnectionString, int? rds, int? workOrderNumber, int? workOrderCassette, int? slot, int? reactor)
|
|
{
|
|
StringBuilder result = new();
|
|
string commandText = GetCommandText(rds, workOrderNumber, workOrderCassette, slot, reactor);
|
|
try
|
|
{
|
|
using SqlConnection sqlConnection = new(lsl2SQLConnectionString);
|
|
sqlConnection.Open();
|
|
using SqlCommand sqlCommand = new(commandText, sqlConnection);
|
|
SqlDataReader sqlDataReader = sqlCommand.ExecuteReader(CommandBehavior.SequentialAccess);
|
|
while (sqlDataReader.Read())
|
|
_ = result.Append(sqlDataReader.GetString(0));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
_ = result.Clear();
|
|
}
|
|
return result.ToString();
|
|
}
|
|
|
|
private static string GetCommandText(int? rds, int? workOrderNumber, int? workOrderCassette, int? slot, int? reactor)
|
|
{
|
|
StringBuilder result = new();
|
|
_ = result.Append(" select ").
|
|
Append(" rr.rds_no ").
|
|
Append(" , rr.reactor ").
|
|
Append(" , rr.ps_no ").
|
|
Append(" , rr.load_lock_side ").
|
|
Append(" , rr.reactor_type ").
|
|
Append(" , rr.recipe_name ").
|
|
Append(" , rr.recipe_no ").
|
|
Append(" , rr.spec_type ").
|
|
Append(" , ( ").
|
|
Append(" select max(wm.zone) ").
|
|
Append(" from lsl2sql.dbo.wm_out_slot wm ").
|
|
Append(" where wm.wo_no = rr.wo_no ").
|
|
Append(" and wm.rds = rr.rds_no ").
|
|
Append(" and wm.in_cass_no = ").Append(workOrderCassette is null ? -1 : workOrderCassette.Value).Append(' ').
|
|
Append(" and wm.slot_no = ").Append(slot is null ? -1 : slot.Value).Append(' ').
|
|
Append(" ) zone ").
|
|
Append(" from lsl2sql.dbo.react_run rr ").
|
|
Append(" where rr.rds_no = ").Append(rds is null ? -1 : rds.Value).Append(' ').
|
|
Append(" union all ").
|
|
Append(" select ").
|
|
Append(" rr.rds_no ").
|
|
Append(" , rr.reactor ").
|
|
Append(" , rr.ps_no ").
|
|
Append(" , rr.load_lock_side ").
|
|
Append(" , rr.reactor_type ").
|
|
Append(" , rr.recipe_name ").
|
|
Append(" , rr.recipe_no ").
|
|
Append(" , rr.spec_type ").
|
|
Append(" , ( ").
|
|
Append(" select max(wm.zone) ").
|
|
Append(" from lsl2sql.dbo.wm_out_slot wm ").
|
|
Append(" where wm.wo_no = rr.wo_no ").
|
|
Append(" and wm.rds = rr.rds_no ").
|
|
Append(" and wm.in_cass_no = ").Append(workOrderCassette is null ? -1 : workOrderCassette.Value).Append(' ').
|
|
Append(" and wm.slot_no = ").Append(slot is null ? -1 : slot.Value).Append(' ').
|
|
Append(" ) zone ").
|
|
Append(" from lsl2sql.dbo.react_run rr ").
|
|
Append(" where rr.rds_no = ( ").
|
|
Append(" select max(wm.rds) ").
|
|
Append(" from lsl2sql.dbo.wm_out_slot wm ").
|
|
Append(" where wm.wo_no = ").Append(workOrderNumber is null ? -1 : workOrderNumber.Value).Append(' ').
|
|
Append(" and wm.in_cass_no = ").Append(workOrderCassette is null ? -1 : workOrderCassette.Value).Append(' ').
|
|
Append(" and wm.slot_no = ").Append(slot is null ? -1 : slot.Value).Append(' ').
|
|
Append(" ) ").
|
|
Append(" union all ").
|
|
Append(" select ").
|
|
Append(" rr.rds_no ").
|
|
Append(" , rr.reactor ").
|
|
Append(" , rr.ps_no ").
|
|
Append(" , rr.load_lock_side ").
|
|
Append(" , rr.reactor_type ").
|
|
Append(" , rr.recipe_name ").
|
|
Append(" , rr.recipe_no ").
|
|
Append(" , rr.spec_type ").
|
|
Append(" , ( ").
|
|
Append(" select max(wm.zone) ").
|
|
Append(" from lsl2sql.dbo.wm_out_slot wm ").
|
|
Append(" where wm.wo_no = rr.wo_no ").
|
|
Append(" and wm.rds = rr.rds_no ").
|
|
Append(" and wm.in_cass_no = ").Append(workOrderCassette is null ? -1 : workOrderCassette.Value).Append(' ').
|
|
Append(" and wm.slot_no = ").Append(slot is null ? -1 : slot.Value).Append(' ').
|
|
Append(" ) zone ").
|
|
Append(" from lsl2sql.dbo.react_run rr ").
|
|
Append(" where rr.rds_no = ( ").
|
|
Append(" select max(qa.rds_no) ").
|
|
Append(" from lsl2sql.dbo.react_run qa ").
|
|
Append(" where qa.load_sig != '' ").
|
|
Append(" and qa.load_sig_dtm > '2022-07-01 00:00:00.000' ").
|
|
Append(" and qa.reactor = ").Append(reactor is null ? -1 : reactor.Value).Append(' ').
|
|
Append(" ) ").
|
|
Append(" for json path ");
|
|
return result.ToString();
|
|
}
|
|
|
|
private static (string, string, int?, string, int?, string) Get(string lsl2SQLConnectionString, string layer, string psn, int? reactorNumber, int? slotNumber, int? workOrderNumber, int? workOrderCassette, string zone)
|
|
{
|
|
int? rdsNumber;
|
|
string comment;
|
|
const int zero = 0;
|
|
const string hyphen = "-";
|
|
string json = GetRunJson(lsl2SQLConnectionString, rds: null, workOrderNumber, workOrderCassette, slotNumber, reactorNumber);
|
|
if (string.IsNullOrEmpty(json))
|
|
{
|
|
rdsNumber = null;
|
|
comment = hyphen;
|
|
psn = string.Empty;
|
|
zone = string.Empty;
|
|
}
|
|
else
|
|
{
|
|
Run[] runs;
|
|
try
|
|
{ runs = JsonSerializer.Deserialize<Run[]>(json); }
|
|
catch (Exception)
|
|
{ runs = Array.Empty<Run>(); }
|
|
if (!runs.Any())
|
|
{
|
|
rdsNumber = null;
|
|
comment = hyphen;
|
|
psn = string.Empty;
|
|
zone = string.Empty;
|
|
}
|
|
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}";
|
|
}
|
|
}
|
|
return new(comment, layer, rdsNumber, psn, reactorNumber, zone);
|
|
}
|
|
|
|
private static (string, string, int?, string, int?, string) GetWithValidRDS(string lsl2SQLConnectionString, string layer, string psn, int? rdsNumber, int? reactorNumber, string zone)
|
|
{
|
|
string comment;
|
|
const int zero = 0;
|
|
const string hyphen = "-";
|
|
string json = GetRunJson(lsl2SQLConnectionString, rdsNumber, workOrderNumber: null, workOrderCassette: null, slot: null, reactor: null);
|
|
if (string.IsNullOrEmpty(json))
|
|
{
|
|
comment = hyphen;
|
|
zone = string.Empty;
|
|
}
|
|
else
|
|
{
|
|
Run[] runs;
|
|
try
|
|
{ runs = JsonSerializer.Deserialize<Run[]>(json); }
|
|
catch (Exception)
|
|
{ runs = Array.Empty<Run>(); }
|
|
if (!runs.Any())
|
|
{
|
|
comment = hyphen;
|
|
zone = string.Empty;
|
|
}
|
|
else
|
|
{
|
|
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}";
|
|
}
|
|
}
|
|
return new(comment, layer, rdsNumber, psn, reactorNumber, zone);
|
|
}
|
|
|
|
} |