Barcode-Host Job
This commit is contained in:
@ -3,12 +3,42 @@ namespace Adaptation.FileHandlers.TIBCO.Transport;
|
|||||||
public class Input
|
public class Input
|
||||||
{
|
{
|
||||||
|
|
||||||
public string Area { get; set; }
|
public string Area { get; }
|
||||||
public string EquipmentType { get; set; }
|
public string EquipmentType { get; }
|
||||||
public string MID { get; set; }
|
public string MID { get; }
|
||||||
public string Slot { get; set; }
|
public string Slot { get; }
|
||||||
public string MesEntity { get; set; }
|
public string MesEntity { get; }
|
||||||
public string Recipe { get; set; }
|
public string Recipe { get; }
|
||||||
public string Sequence { get; set; }
|
public string Sequence { get; }
|
||||||
|
|
||||||
|
[System.Text.Json.Serialization.JsonConstructor]
|
||||||
|
public Input(string area,
|
||||||
|
string equipmentType,
|
||||||
|
string mid,
|
||||||
|
string slot,
|
||||||
|
string mesEntity,
|
||||||
|
string recipe,
|
||||||
|
string sequence)
|
||||||
|
{
|
||||||
|
|
||||||
|
Area = area;
|
||||||
|
EquipmentType = equipmentType;
|
||||||
|
MID = mid;
|
||||||
|
Slot = slot;
|
||||||
|
MesEntity = mesEntity;
|
||||||
|
Recipe = recipe;
|
||||||
|
Sequence = sequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Input(Input input, string mid)
|
||||||
|
{
|
||||||
|
Area = input.Area;
|
||||||
|
EquipmentType = input.EquipmentType;
|
||||||
|
MID = mid;
|
||||||
|
Slot = input.Slot;
|
||||||
|
MesEntity = input.MesEntity;
|
||||||
|
Recipe = input.Recipe;
|
||||||
|
Sequence = input.Sequence;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -39,6 +39,26 @@ public class Job
|
|||||||
public DateTime DateTime { get; }
|
public DateTime DateTime { get; }
|
||||||
public List<Item> Items { get; }
|
public List<Item> Items { get; }
|
||||||
|
|
||||||
|
private class Common
|
||||||
|
{
|
||||||
|
|
||||||
|
public string Layer { get; }
|
||||||
|
public string PSN { get; }
|
||||||
|
public int? RDSNumber { get; }
|
||||||
|
public int? Reactor { get; }
|
||||||
|
public string Zone { get; }
|
||||||
|
|
||||||
|
public Common(string layer, string psn, int? rdsNumber, int? reactor, string zone)
|
||||||
|
{
|
||||||
|
Layer = layer;
|
||||||
|
PSN = psn;
|
||||||
|
RDSNumber = rdsNumber;
|
||||||
|
Reactor = reactor;
|
||||||
|
Zone = zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public Job(string lsl2SQLConnectionString, string metrologyFileShare, string barcodeHostFileShare, string mid)
|
public Job(string lsl2SQLConnectionString, string metrologyFileShare, string barcodeHostFileShare, string mid)
|
||||||
{
|
{
|
||||||
const int zero = 0;
|
const int zero = 0;
|
||||||
@ -50,30 +70,39 @@ public class Job
|
|||||||
string psn;
|
string psn;
|
||||||
string zone;
|
string zone;
|
||||||
string layer;
|
string layer;
|
||||||
|
Common common;
|
||||||
int? rdsNumber;
|
int? rdsNumber;
|
||||||
string comment;
|
string comment;
|
||||||
|
int? slotNumber;
|
||||||
|
bool isWorkOrder;
|
||||||
|
int? reactorNumber;
|
||||||
|
int? workOrderNumber;
|
||||||
|
int? workOrderCassette;
|
||||||
const string hyphen = "-";
|
const string hyphen = "-";
|
||||||
Input input = JsonSerializer.Deserialize<Input>(mid);
|
Input input = JsonSerializer.Deserialize<Input>(mid);
|
||||||
if (!long.TryParse(input.Sequence, out long sequence))
|
if (!long.TryParse(input.Sequence, out long sequence))
|
||||||
DateTime = DateTime.Now;
|
DateTime = DateTime.Now;
|
||||||
else
|
else
|
||||||
DateTime = new DateTime(sequence);
|
DateTime = new DateTime(sequence);
|
||||||
int? reactorNumber = GetReactorNumber(input);
|
if (!string.IsNullOrEmpty(input.MID) && !string.IsNullOrEmpty(input.MesEntity) && Regex.IsMatch(input.MID, @"^[0-9]{2}--") && input.MesEntity is "BIORAD2" or "BIORAD3")
|
||||||
(int? workOrderNumber, int? _, int? workOrderCassette, int? slotNumber, bool isWorkOrder) = GetWorkOrder(input);
|
(common, workOrderNumber, _, workOrderCassette, slotNumber, isWorkOrder) = Get(input, barcodeHostFileShare);
|
||||||
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
|
else
|
||||||
(layer, psn, rdsNumber, reactorNumber, zone) = Get(input);
|
{
|
||||||
if (IsValid(rdsNumber))
|
reactorNumber = GetReactorNumber(input);
|
||||||
(comment, layer, rdsNumber, psn, reactorNumber, zone) = GetWithValidRDS(lsl2SQLConnectionString, layer, psn, rdsNumber, reactorNumber, zone);
|
(workOrderNumber, _, workOrderCassette, slotNumber, isWorkOrder) = GetWorkOrder(input);
|
||||||
else if (isWorkOrder || reactorNumber.HasValue)
|
if (isWorkOrder || reactorNumber.HasValue)
|
||||||
(comment, layer, rdsNumber, psn, reactorNumber, zone) = Get(lsl2SQLConnectionString, layer, psn, reactorNumber, slotNumber, workOrderNumber, workOrderCassette, zone);
|
common = new(string.Empty, string.Empty, null, 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}"))
|
||||||
|
common = Get(metrologyFileShare, input);
|
||||||
|
else
|
||||||
|
common = Get(input);
|
||||||
|
}
|
||||||
|
if (IsValid(common.RDSNumber))
|
||||||
|
(comment, layer, rdsNumber, psn, reactorNumber, zone) = GetWithValidRDS(lsl2SQLConnectionString, common.Layer, common.PSN, common.RDSNumber, common.Reactor, common.Zone);
|
||||||
|
else if (isWorkOrder || common.RDSNumber.HasValue)
|
||||||
|
(comment, layer, rdsNumber, psn, reactorNumber, zone) = Get(lsl2SQLConnectionString, common.Layer, common.PSN, common.Reactor, slotNumber, workOrderNumber, workOrderCassette, common.Zone);
|
||||||
else
|
else
|
||||||
(comment, layer, zone) = (hyphen, hyphen, hyphen);
|
(comment, layer, rdsNumber, psn, reactorNumber, zone) = (hyphen, hyphen, common.RDSNumber, common.PSN, common.Reactor, hyphen);
|
||||||
Qty = "1";
|
Qty = "1";
|
||||||
Status = hyphen; // INFO
|
Status = hyphen; // INFO
|
||||||
CreationUser = hyphen; // ?
|
CreationUser = hyphen; // ?
|
||||||
@ -211,7 +240,7 @@ public class Job
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static (string, string, int, int?, string) Get(Input input)
|
private static Common Get(Input input)
|
||||||
{
|
{
|
||||||
string psn;
|
string psn;
|
||||||
string rds;
|
string rds;
|
||||||
@ -264,7 +293,7 @@ public class Job
|
|||||||
|
|
||||||
#nullable enable
|
#nullable enable
|
||||||
|
|
||||||
private static (string, string, int?, int?, string) Get(string metrologyFileShare, Input input)
|
private static Common Get(string metrologyFileShare, Input input)
|
||||||
{
|
{
|
||||||
string lines;
|
string lines;
|
||||||
const int zero = 0;
|
const int zero = 0;
|
||||||
@ -308,41 +337,81 @@ public class Job
|
|||||||
return new(layer, psn, rdsNumber, reactor, zone);
|
return new(layer, psn, rdsNumber, reactor, zone);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static (string, string, int?, int?, string) Get(Input input, string barcodeHostFileShare)
|
private static List<string> GetFiles(Input input, string barcodeHostFileShare)
|
||||||
{
|
{
|
||||||
string text;
|
List<string> results = new();
|
||||||
int? rds = null;
|
string[] checkDirectories = GetDirectories(barcodeHostFileShare);
|
||||||
FileInfo fileInfo;
|
foreach (string checkDirectory in checkDirectories)
|
||||||
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);
|
if (!Directory.Exists(checkDirectory))
|
||||||
foreach (string checkDirectory in checkDirectories)
|
_ = Directory.CreateDirectory(checkDirectory);
|
||||||
{
|
results.AddRange(Directory.GetFiles(checkDirectory, $"{input.MesEntity}.csv", SearchOption.TopDirectoryOnly));
|
||||||
if (!Directory.Exists(checkDirectory))
|
|
||||||
_ = Directory.CreateDirectory(checkDirectory);
|
|
||||||
files.AddRange(Directory.GetFiles(checkDirectory, $"{input.MesEntity}.csv", SearchOption.TopDirectoryOnly));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string? GetText(long sequence, List<string> files)
|
||||||
|
{
|
||||||
|
string? result = null;
|
||||||
|
string text;
|
||||||
|
string[] lines;
|
||||||
|
FileInfo fileInfo;
|
||||||
foreach (string file in files.OrderByDescending(l => new FileInfo(l).LastWriteTime))
|
foreach (string file in files.OrderByDescending(l => new FileInfo(l).LastWriteTime))
|
||||||
{
|
{
|
||||||
fileInfo = new FileInfo(file);
|
fileInfo = new FileInfo(file);
|
||||||
if (fileInfo.LastWriteTime.Ticks > sequence)
|
if (fileInfo.LastWriteTime.Ticks > sequence)
|
||||||
continue;
|
continue;
|
||||||
text = File.ReadAllText(file);
|
lines = File.ReadAllLines(file);
|
||||||
rds = !int.TryParse(segments[0], out int rdsNumber) ? null : rdsNumber;
|
if (!lines.Any())
|
||||||
|
continue;
|
||||||
|
text = lines.First();
|
||||||
|
if (string.IsNullOrEmpty(text) || text.Length < 3 || text[0] != '1' || (text[1] != 't' && text[1] != 'T'))
|
||||||
|
continue;
|
||||||
|
result = text;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return new(layer, psn, rds, reactor, zone);
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static (Common common, int?, int?, int?, int?, bool) Get(Input input, string barcodeHostFileShare)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(barcodeHostFileShare) || !Directory.Exists(barcodeHostFileShare))
|
||||||
|
throw new Exception($"Unable to access file-share <{barcodeHostFileShare}>");
|
||||||
|
int? rds;
|
||||||
|
int? slotNumber;
|
||||||
|
bool isWorkOrder;
|
||||||
|
long sequence = 0;
|
||||||
|
int? workOrderStep;
|
||||||
|
int? workOrderNumber;
|
||||||
|
int? workOrderCassette;
|
||||||
|
string psn = string.Empty;
|
||||||
|
string zone = string.Empty;
|
||||||
|
string layer = string.Empty;
|
||||||
|
int? reactor = !int.TryParse(input.MID.Substring(0, 2), out int reactorNumber) ? null : reactorNumber;
|
||||||
|
bool parsed = !string.IsNullOrEmpty(input.Sequence) && long.TryParse(input.Sequence, out sequence);
|
||||||
|
List<string> files;
|
||||||
|
if (!parsed || string.IsNullOrEmpty(input.MID))
|
||||||
|
files = new();
|
||||||
|
else
|
||||||
|
files = GetFiles(input, barcodeHostFileShare);
|
||||||
|
string? text = GetText(sequence, files);
|
||||||
|
if (text is null || text.Length < 3)
|
||||||
|
{
|
||||||
|
rds = null;
|
||||||
|
(workOrderNumber, workOrderStep, workOrderCassette, slotNumber, isWorkOrder) = (null, null, null, null, false);
|
||||||
|
}
|
||||||
|
else if (!text.Contains('.'))
|
||||||
|
{
|
||||||
|
rds = !int.TryParse(text.Substring(2), out int rdsNumber) ? null : rdsNumber;
|
||||||
|
(workOrderNumber, workOrderStep, workOrderCassette, slotNumber, isWorkOrder) = (null, null, null, null, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rds = null;
|
||||||
|
(workOrderNumber, workOrderStep, workOrderCassette, slotNumber, isWorkOrder) = GetWorkOrder(new(input, text.Substring(2)));
|
||||||
|
}
|
||||||
|
Common common = new(layer, psn, rds, reactor, zone);
|
||||||
|
return new(common, workOrderNumber, workOrderStep, workOrderCassette, slotNumber, isWorkOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
@ -43,7 +43,9 @@ public class Job : LoggingUnitTesting, IDisposable
|
|||||||
catch (Exception) { }
|
catch (Exception) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if true
|
||||||
[Ignore]
|
[Ignore]
|
||||||
|
#endif
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void TestJobA()
|
public void TestJobA()
|
||||||
{
|
{
|
||||||
@ -82,7 +84,9 @@ public class Job : LoggingUnitTesting, IDisposable
|
|||||||
NonThrowTryCatch();
|
NonThrowTryCatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if true
|
||||||
[Ignore]
|
[Ignore]
|
||||||
|
#endif
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void TestJobB()
|
public void TestJobB()
|
||||||
{
|
{
|
||||||
@ -100,4 +104,24 @@ public class Job : LoggingUnitTesting, IDisposable
|
|||||||
NonThrowTryCatch();
|
NonThrowTryCatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if true
|
||||||
|
[Ignore]
|
||||||
|
#endif
|
||||||
|
[TestMethod]
|
||||||
|
public void TestJobC()
|
||||||
|
{
|
||||||
|
MethodBase methodBase = new StackFrame().GetMethod();
|
||||||
|
FileHandlers.TIBCO.Transport.Job job;
|
||||||
|
string barcodeHostFileShare = @"\\messv02ecc1.ec.local\EC_Metrology_Si\BarcodeHost\API";
|
||||||
|
string metrologyFileShare = @"\\messv02ecc1.ec.local\EC_Metrology_Si\WorkMaterialOut\API";
|
||||||
|
LoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Getting configuration"));
|
||||||
|
string lsl2SQLConnectionString = "Data Source=10.95.128.28\\PROD1,53959;Initial Catalog=LSL2SQL;Persist Security Info=True;User ID=srpadmin;Password=0okm9ijn;";
|
||||||
|
job = new(lsl2SQLConnectionString, metrologyFileShare, barcodeHostFileShare, "{\"Area\": \"Si\", \"EquipmentType\": \"MET08RESIMAPCDE\", \"MesEntity\": \"BIORAD3\", \"Sequence\": \"638234699589174855\", \"MID\": \"33--\", \"Recipe\": \"Recipe\"}");
|
||||||
|
Assert.IsTrue(!string.IsNullOrEmpty(job.ProcessType));
|
||||||
|
Assert.IsTrue(!string.IsNullOrEmpty(job.LotName));
|
||||||
|
Assert.IsTrue(!string.IsNullOrEmpty(job.ProductName));
|
||||||
|
LoggingUnitTesting.Logger.LogInformation(string.Concat(methodBase.Name, " - Exit"));
|
||||||
|
NonThrowTryCatch();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Reference in New Issue
Block a user