3948 lines
145 KiB
C#
3948 lines
145 KiB
C#
using MongoDB.Driver;
|
|
using Newtonsoft.Json;
|
|
using NKC_SDK;
|
|
using SteamWare;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net.NetworkInformation;
|
|
using System.Threading;
|
|
using System.Web;
|
|
|
|
namespace AppData
|
|
{
|
|
/// <summary>
|
|
/// Classe con metodi di supporto per COMUNICAZIONE
|
|
/// </summary>
|
|
public class ComLib
|
|
{
|
|
#region Public Fields
|
|
|
|
/// <summary>
|
|
/// Classe impiego sstatico ComLib...
|
|
/// </summary>
|
|
public static ComLib man = new ComLib();
|
|
|
|
public static string redBatchDescend = "NKC:SERV:BATCHDESCEND";
|
|
|
|
public static string redKits = "NKC:SERV:KITS";
|
|
|
|
public static string redMachUnloadCount = "NKC:SERV:MACH_UNLOAD:COUNT";
|
|
|
|
public static string redMachUnloadForce = "NKC:SERV:MACH_UNLOAD:FORCERELOAD";
|
|
|
|
public static string redMLCurrBunk = "NKC:SERV:TAKT:CurrBunk";
|
|
|
|
public static string redMsgCount = "NKC:SERV:BREQ:MCount";
|
|
|
|
public static string redMsgList = "NKC:SERV:BREQ:MList";
|
|
|
|
public static string redNestAnsw = "NKC:NEST:BANSW";
|
|
|
|
public static string redOrders = "NKC:SERV:ORDERS";
|
|
|
|
public static string redOutPath = "NKC:SERV:BREQ";
|
|
|
|
public static string redProdAnsw = "NKC:PROD:BUNKS";
|
|
|
|
public static string redProdMachClock = "NKC:PROD:MACH:CLOCK";
|
|
|
|
public static string redProdMachList = "NKC:PROD:MACH:LIST";
|
|
|
|
public static string redProdMachStateData = "NKC:PROD:MACH:STATE";
|
|
|
|
public static string redProdMachStateLive = "NKC:PROD:MACH:LIVE";
|
|
|
|
public static string redProdReq = "NKC:SERV:BUNKS";
|
|
|
|
public static string redProdStatDec = "NKC:PROD:MACH:STATDEC";
|
|
|
|
/// <summary>
|
|
/// chaive redis x cache conteggio coda PJQ
|
|
/// </summary>
|
|
public static string redQueueCount = "NKC:SERV:PJQ";
|
|
|
|
/// <summary>
|
|
/// chaive redis x cache conteggio coda PJQ composta da tante code
|
|
/// </summary>
|
|
public static string redQueueCountSet = "NKC:SERV:PJQCOUNT";
|
|
|
|
/// <summary>
|
|
/// Richiesta sec screen
|
|
/// </summary>
|
|
public static string redSecScreenReq = "NKC:SECSCREEN:REQ";
|
|
|
|
/// <summary>
|
|
/// Vato ricalcolo dati stats giornalieri
|
|
/// </summary>
|
|
public static string redVetoDayStats = "NKC:SERV:DAYSTATS:RECALC";
|
|
|
|
#endregion Public Fields
|
|
|
|
#region Public Constructors
|
|
|
|
/// <summary>
|
|
/// Init classe ComLib
|
|
/// </summary>
|
|
public ComLib()
|
|
{
|
|
database = memLayer.ML.getMongoDatabase("NKC");
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Public Properties
|
|
|
|
/// <summary>
|
|
/// verifica se sia avviabile un nuovo task nesting controllando cache Redis o tabelle batch/offlineOrders
|
|
/// </summary>
|
|
public static bool canStartNew
|
|
{
|
|
get
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
bool answ = false;
|
|
bool valido = false;
|
|
// cerco in redis
|
|
if (memLayer.ML.redKeyPresent(canStartNewKey))
|
|
{
|
|
string rawData = memLayer.ML.getRSV(canStartNewKey);
|
|
valido = bool.TryParse(rawData, out answ);
|
|
}
|
|
if (!valido)
|
|
{
|
|
// in primis controllo SE ci siano task running, nel qual caso è false e basta...
|
|
int numEst = DLMan.taBL.getByStatus((int)BatchStatus.EstimationRequested, "", true, 0).Count;
|
|
int numNest = DLMan.taBL.getByStatus((int)BatchStatus.NestRequested, "", true, 0).Count;
|
|
// ora controllo anche offline orders...
|
|
int numOffOrd = DLMan.taOffOL.getRunning().Count;
|
|
// ora la somma di tutti DEVE essere zero...
|
|
answ = ((numEst + numNest + numOffOrd) == 0);
|
|
// salvo in redis
|
|
memLayer.ML.setRSV(canStartNewKey, answ.ToString(), 2);
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
public static string canStartNewKey
|
|
{
|
|
get
|
|
{
|
|
return $"{redOutPath}:CanStartNew";
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Valore della richiesta corrente di elaborazione batch
|
|
/// </summary>
|
|
public static string currBatchReq
|
|
{
|
|
get
|
|
{
|
|
return memLayer.ML.getRSV(currBatchReqKey);
|
|
}
|
|
set
|
|
{
|
|
// scrivo su REDIS
|
|
memLayer.ML.setRSV(currBatchReqKey, value);
|
|
}
|
|
}
|
|
|
|
public static string currBatchReqKey
|
|
{
|
|
get
|
|
{
|
|
return $"{redOutPath}:CURR";
|
|
}
|
|
}
|
|
|
|
public static DS_App.StatusDecodeDataTable TabStatusDec
|
|
{
|
|
get
|
|
{
|
|
DS_App.StatusDecodeDataTable tabStaDec = new DS_App.StatusDecodeDataTable();
|
|
// cerco in Redis...
|
|
string rawData = memLayer.ML.getRSV(redProdStatDec);
|
|
// provo a deserializzare e cercare...
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
tabStaDec = JsonConvert.DeserializeObject<DS_App.StatusDecodeDataTable>(rawData);
|
|
}
|
|
else
|
|
{ }
|
|
return tabStaDec;
|
|
}
|
|
set
|
|
{
|
|
string rawData = JsonConvert.SerializeObject(value);
|
|
memLayer.ML.setRSV(redProdStatDec, rawData, 600);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// ID del BUNK correntemente in processing per ML (MachineLoad)
|
|
/// </summary>
|
|
public static string taktMLCurrBunk
|
|
{
|
|
get
|
|
{
|
|
return memLayer.ML.getRSV(redMLCurrBunk);
|
|
}
|
|
set
|
|
{
|
|
memLayer.ML.setRSV(redMLCurrBunk, value);
|
|
}
|
|
}
|
|
|
|
#endregion Public Properties
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Aggiorna revisione indice sheet x BUNK (cambio foglio)
|
|
/// </summary>
|
|
/// <param name="BunkID"></param>
|
|
/// <returns></returns>
|
|
public static long advaceSheetRevByBunk(int BunkID)
|
|
{
|
|
long answ = 0;
|
|
if (BunkID > 0)
|
|
{
|
|
// recupero da REDIS!
|
|
string redKeyExp = memLayer.ML.redHash($"DataExp");
|
|
string redKeyRev = $"{ComLib.machineUnloadBunkArea(BunkID)}:Rev";
|
|
// incremento...
|
|
answ = memLayer.ML.setRCntI(redKeyRev);
|
|
// se > 999 --> resetto
|
|
if (answ > 999)
|
|
{
|
|
memLayer.ML.resetRCnt(redKeyRev);
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco dei Batch descendant di un batch ancestor
|
|
/// </summary>
|
|
public static DS_App.BatchListDataTable BatchDescendant(int BatchId)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
string redKey = $"{redBatchDescend}:{BatchId}";
|
|
string rawData = "";
|
|
DS_App.BatchListDataTable answ = new DS_App.BatchListDataTable();
|
|
// cerco in redis
|
|
if (memLayer.ML.redKeyPresent(redKey))
|
|
{
|
|
rawData = memLayer.ML.getRSV(redKey);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
try
|
|
{
|
|
answ = JsonConvert.DeserializeObject<DS_App.BatchListDataTable>(rawData);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
// se vuoto rileggo
|
|
if (answ.Count == 0)
|
|
{
|
|
answ = DLMan.taBL.getDescendByKey(BatchId);
|
|
// salvo in cache
|
|
rawData = JsonConvert.SerializeObject(answ);
|
|
//memLayer.ML.setRSV(redKey, rawData, 5 * 60);
|
|
// memoria brevissima...
|
|
memLayer.ML.setRSV(redKey, rawData, 5);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco dei Batch descendant di un batch a sua volta descendant
|
|
/// </summary>
|
|
public static DS_App.BatchListDataTable BatchOtherDescendant(int BatchDescId)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
string redKey = $"{redBatchDescend}:{BatchDescId}";
|
|
string rawData = "";
|
|
DS_App.BatchListDataTable answ = new DS_App.BatchListDataTable();
|
|
// cerco in redis
|
|
if (memLayer.ML.redKeyPresent(redKey))
|
|
{
|
|
rawData = memLayer.ML.getRSV(redKey);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
try
|
|
{
|
|
answ = JsonConvert.DeserializeObject<DS_App.BatchListDataTable>(rawData);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
// se vuoto rileggo
|
|
if (answ.Count == 0)
|
|
{
|
|
answ = DLMan.taBL.getSplitByKey(BatchDescId);
|
|
// salvo in cache
|
|
rawData = JsonConvert.SerializeObject(answ);
|
|
//memLayer.ML.setRSV(redKey, rawData, 5 * 60);
|
|
// memoria brevissima...
|
|
memLayer.ML.setRSV(redKey, rawData, 5);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
public static string BatchStatusDescr(object value)
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
BatchStatus bStatus = (BatchStatus)Enum.Parse(typeof(BatchStatus), value.ToString());
|
|
switch (bStatus)
|
|
{
|
|
case BatchStatus.Imported:
|
|
answ = traduci("Imported");
|
|
break;
|
|
|
|
case BatchStatus.EstimationRequested:
|
|
answ = traduci("EstimationRequested");
|
|
break;
|
|
|
|
case BatchStatus.EstimationDone:
|
|
answ = traduci("EstimationCompleted");
|
|
break;
|
|
|
|
case BatchStatus.NestRequested:
|
|
answ = traduci("NestingRequested");
|
|
break;
|
|
|
|
case BatchStatus.NestDone:
|
|
answ = traduci("NestingCompleted");
|
|
break;
|
|
|
|
case BatchStatus.Approved:
|
|
answ = traduci("NestingApproved");
|
|
break;
|
|
|
|
case BatchStatus.Discarded:
|
|
answ = traduci("NestingDiscarded");
|
|
break;
|
|
|
|
case BatchStatus.Errors:
|
|
answ = traduci("NestingPrelimErrors");
|
|
break;
|
|
|
|
case BatchStatus.PartEval:
|
|
answ = traduci("NestPartEvaluating");
|
|
break;
|
|
|
|
case BatchStatus.PartOk:
|
|
answ = traduci("NestPartValidated");
|
|
break;
|
|
|
|
case BatchStatus.PartKo:
|
|
answ = traduci("NestPartNotValidated");
|
|
break;
|
|
|
|
case BatchStatus.ErrorsOnEstim:
|
|
answ = traduci("ErrorsOnEstim");
|
|
break;
|
|
|
|
case BatchStatus.ErrorsOnNesting:
|
|
answ = traduci("ErrorsOnNesting");
|
|
break;
|
|
|
|
default:
|
|
answ = traduci("NestStateUnk");
|
|
break;
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stato batch (bozza/stima/nesting...)
|
|
/// </summary>
|
|
/// <param name="BatchId"></param>
|
|
/// <returns></returns>
|
|
public static BatchStatus BStatus(int BatchId)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
BatchStatus answ = BatchStatus.Imported;
|
|
DS_App.BatchListDataTable tabBatch = DLMan.taBL.getByKey(BatchId);
|
|
if (tabBatch != null && tabBatch.Count > 0)
|
|
{
|
|
try
|
|
{
|
|
// mostro split se di tipo 1...
|
|
answ = (BatchStatus)tabBatch[0].STATUS;
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tipo batch tra ancestor/descendant
|
|
/// </summary>
|
|
/// <param name="BatchId"></param>
|
|
/// <returns></returns>
|
|
public static BatchType BType(int BatchId)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
BatchType answ = BatchType.Original;
|
|
DS_App.BatchListDataTable tabBatch = DLMan.taBL.getByKey(BatchId);
|
|
if (tabBatch != null && tabBatch.Count > 0)
|
|
{
|
|
try
|
|
{
|
|
// mostro split se di tipo 1...
|
|
answ = (BatchType)tabBatch[0].BatchType;
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica lo stato di una richiesta di esecuzione BATCH x stima/nesting
|
|
/// </summary>
|
|
/// <param name="OffOrderID">OfflineOrder di cui si chiede processing</param>
|
|
/// <param name="note">note opzionali</param>
|
|
/// <returns></returns>
|
|
public static bool checkBatchReq(int OffOrderID)
|
|
{
|
|
bool answ = false;
|
|
// restituisco ok
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica lo stato di una richiesta di esecuzione
|
|
/// </summary>
|
|
/// <param name="OffOrderID">OfflineOrder di cui si chiede processing</param>
|
|
/// <param name="note">note opzionali</param>
|
|
/// <returns></returns>
|
|
public static bool checkOfflineOrderReq(int OffOrderID)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
bool answ = false;
|
|
string typeSearch = "OffOrdCalculation";
|
|
string keyEnv = "";
|
|
// recupero lista dei vari task APERTI...
|
|
KeyValuePair<string, string>[] comAperte = getEnvList();
|
|
// processo x cercare ordine...
|
|
foreach (var item in comAperte)
|
|
{
|
|
// cerco dove sia quello richiesto
|
|
if (item.Value.Contains(typeSearch))
|
|
{
|
|
// controllo SE sia quello richiesto
|
|
if (item.Value == $"{OffOrderID}|{typeSearch}")
|
|
{
|
|
keyEnv = item.Key;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// controllo e se c'è risposta --> update DB
|
|
string redKey = $"{redNestAnsw}:FULL:{keyEnv}";
|
|
string rawAnsw = memLayer.ML.getRSV(redKey);
|
|
if (rawAnsw != "")
|
|
{
|
|
// cerco risposta come stack --> disegno...
|
|
var offOrder = deserializeOfflineOrder(rawAnsw);
|
|
// se ho in risposta drawing
|
|
if (!string.IsNullOrEmpty(offOrder.DrawingPath))
|
|
{
|
|
DLMan.taOffOL.updateDrawing(OffOrderID, offOrder.DrawingPath, offOrder.CncPath);
|
|
}
|
|
}
|
|
// restituisco ok
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifica esistenza del PDF SE presente negli optParams
|
|
/// - OK SE NON c'è parametro x pdf
|
|
/// - OK SE presente parametro --> cerca il file --> lo trova
|
|
/// </summary>
|
|
/// <param name="reqPart">Part da analizzare</param>
|
|
/// <param name="pdfPath">Path del file PDF analizzato</param>
|
|
/// <returns></returns>
|
|
public static bool checkPdfExistAccessible(Part reqPart, out string pdfPath)
|
|
{
|
|
pdfPath = getPdfFilePath(reqPart.OptParameters);
|
|
bool answ = string.IsNullOrEmpty(pdfPath);
|
|
if (!answ)
|
|
{
|
|
try
|
|
{
|
|
string parentDir = Path.GetDirectoryName(pdfPath);
|
|
bool shareOk = true;
|
|
bool dirOk = true;
|
|
if (IsUnc(parentDir))
|
|
{
|
|
string pathRoot = Path.GetPathRoot(parentDir);
|
|
Uri newUri = new Uri(pathRoot);
|
|
// tento PING
|
|
PingReply pingResult = NKC.testPingDevice(newUri.Host);
|
|
shareOk = (pingResult.Status == IPStatus.Success);
|
|
}
|
|
if (shareOk)
|
|
{
|
|
dirOk = Directory.Exists(parentDir);
|
|
if (dirOk)
|
|
{
|
|
answ = File.Exists(pdfPath);
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Invia una richiesta di esecuzione di Nesting x un Batch ANCESTOR
|
|
/// </summary>
|
|
/// <param name="BatchID">Batch di cui si chiede processing</param>
|
|
/// <returns></returns>
|
|
public static bool checkSendBatchSplit(int BatchID)
|
|
{
|
|
string logIdKey = $"checkSendBatchSplit | BatchID: {BatchID} |";
|
|
int nextIndex = 10;
|
|
bool batchSent = false;
|
|
bool batchProcessed = false;
|
|
DataLayer DLMan = new DataLayer();
|
|
var currType = ComLib.BType(BatchID);
|
|
|
|
// log tipo di batch
|
|
Log.Instance.Info($"{logIdKey} | Batch currType: {currType}");
|
|
// NKC2: controllo SE sia un batch tipo ancestor (1° invio)
|
|
if (currType == BatchType.Ancestor)
|
|
{
|
|
Log.Instance.Info($"{logIdKey} | Batch Ancestor | 01");
|
|
// recupero batch descendant
|
|
var tabDesc = ComLib.BatchDescendant(BatchID);
|
|
if (tabDesc != null && tabDesc.Count > 0)
|
|
{
|
|
batchSent = false;
|
|
// ciclo fino a trovare un batch VALIDO (= contiene ordini)
|
|
foreach (var item in tabDesc)
|
|
{
|
|
batchProcessed = false;
|
|
// 2021.07.19 FIX x caso batch vuoto: se non ho pezzi --> approvo
|
|
// direttamente e passo al successivo...
|
|
var tabItems = DLMan.taIL.getByBatch(item.BatchID);
|
|
if (tabItems != null)
|
|
{
|
|
// calcolo idx da nome macchina...
|
|
string placeCod = item.PlaceCod;
|
|
if (!string.IsNullOrEmpty(placeCod) && placeCod.Contains("NE"))
|
|
{
|
|
int neIdx = 1;
|
|
int.TryParse(placeCod.Replace("NE", ""), out neIdx);
|
|
nextIndex = 10 + 50 * (neIdx - 1);
|
|
}
|
|
// --> invio batch
|
|
if (tabItems.Count > 0)
|
|
{
|
|
// primo parto da indice 10...
|
|
ComLib.sendBatchReq(item.BatchID, "Nesting", 2, false, nextIndex, false);
|
|
// registro su DB nesting iniziato...
|
|
DLMan.taBL.updateStatus(item.BatchID, (int)BatchStatus.NestRequested, "", -1);
|
|
batchProcessed = true;
|
|
batchSent = true;
|
|
}
|
|
}
|
|
|
|
//--> approvo direttamente e passo al successivo... (annullo batch)
|
|
if (!batchProcessed)
|
|
{
|
|
// registro su DB batch DISCARDED (NON HA PEZZI...)
|
|
DLMan.taBL.updateStatus(item.BatchID, (int)BatchStatus.Discarded, "", -1);
|
|
}
|
|
|
|
// se ho fatto --> esco
|
|
if (batchSent)
|
|
break;
|
|
}
|
|
}
|
|
Log.Instance.Info($"{logIdKey} | Batch Ancestor | 02");
|
|
}
|
|
// NKC2: se è un batch ti dipo descendant (invii successivi)
|
|
if (currType == BatchType.Descendant)
|
|
{
|
|
Log.Instance.Info($"{logIdKey} | Batch Descendant | 01");
|
|
// verifico se ce ne siano altri NON validati (ma splitted)
|
|
var tabDesc = ComLib.BatchOtherDescendant(BatchID);
|
|
if (tabDesc != null && tabDesc.Count > 0)
|
|
{
|
|
batchSent = false;
|
|
// ciclo x tutte le righe che NON fossero con nesting effettuato
|
|
foreach (var item in tabDesc)
|
|
{
|
|
batchProcessed = false;
|
|
// se c'è qualcosa da processare lo richiede
|
|
if (item.STATUS == 2)
|
|
{
|
|
nextIndex += 50;
|
|
Log.Instance.Info($"{logIdKey} | Batch Descendant | PlaceCod: {item.PlaceCod} | Takt: {item.Takt} | nextIndex: {nextIndex}");
|
|
// 2021.07.19 FIX x caso batch vuoto: se non ho pezzi --> approvo
|
|
// direttamente e passo al successivo...
|
|
var tabItems = DLMan.taIL.getByBatch(item.BatchID);
|
|
if (tabItems != null)
|
|
{
|
|
// calcolo idx da nome macchina...
|
|
string placeCod = item.PlaceCod;
|
|
if (!string.IsNullOrEmpty(placeCod) && placeCod.Contains("NE"))
|
|
{
|
|
int neIdx = 1;
|
|
int.TryParse(placeCod.Replace("NE", ""), out neIdx);
|
|
nextIndex = 10 + 50 * (neIdx - 1);
|
|
}
|
|
// --> invio batch
|
|
if (tabItems.Count > 0)
|
|
{
|
|
ComLib.sendBatchReq(item.BatchID, "Nesting", 2, false, nextIndex, false);
|
|
// registro su DB nesting iniziato...
|
|
DLMan.taBL.updateStatus(item.BatchID, (int)BatchStatus.NestRequested, "", -1);
|
|
batchProcessed = true;
|
|
batchSent = true;
|
|
}
|
|
}
|
|
|
|
//--> approvo direttamente e passo al successivo... (annullo batch)
|
|
if (!batchProcessed)
|
|
{
|
|
// registro su DB batch DISCARDED (NON HA PEZZI...)
|
|
DLMan.taBL.updateStatus(item.BatchID, (int)BatchStatus.Discarded, "", -1);
|
|
}
|
|
|
|
// se ho fatto --> esco
|
|
if (batchSent)
|
|
break;
|
|
}
|
|
// se non ha trovato nulla --> prova update Batch Ancestor...
|
|
}
|
|
}
|
|
|
|
Log.Instance.Info($"{logIdKey} | Batch Descendant | 02");
|
|
}
|
|
|
|
Log.Instance.Info($"{logIdKey} | Batch test result: {batchSent}");
|
|
return batchSent;
|
|
}
|
|
|
|
/// <summary>
|
|
/// verifica che lo status e la decodifica ci siano...
|
|
/// </summary>
|
|
/// <param name="machine"></param>
|
|
public static DS_App.StatusDecodeRow checkStationDecode(string station, string code)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
var currTab = TabStatusDec;
|
|
|
|
// cerco item
|
|
DS_App.StatusDecodeRow foundItem = currTab.Where(x => x.Station == station && x.Code == code).FirstOrDefault();
|
|
if (foundItem == null)
|
|
{
|
|
// forzo (ri)lettura...
|
|
currTab = DLMan.taStatDec.GetData();
|
|
TabStatusDec = currTab;
|
|
// cerco di nuovo item
|
|
foundItem = currTab.Where(x => x.Station == station && x.Code == code).FirstOrDefault();
|
|
}
|
|
if (foundItem == null)
|
|
{
|
|
// se non ci fosse --> creo
|
|
DLMan.taStatDec.insert(station, code);
|
|
// inserisco empty x 1 sec così rileggerà...
|
|
memLayer.ML.setRSV(redProdStatDec, "", 1);
|
|
// rileggo
|
|
currTab = TabStatusDec;
|
|
foundItem = currTab.Where(x => x.Station == station && x.Code == code).FirstOrDefault();
|
|
}
|
|
|
|
return foundItem;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elimina da MongoDb info envelope fino al valore idx2keep indicato
|
|
/// </summary>
|
|
/// <param name="idx2keep">Valore da lasciare/non eliminare</param>
|
|
/// <returns></returns>
|
|
public static int CleanupMongo(long idx2keep)
|
|
{
|
|
// contatore eliminazioni
|
|
int numDel = 0;
|
|
// inizio recuperando da HashList
|
|
var currList = getEnvList();
|
|
// riordino x chiave x fare prima...
|
|
var ordList = currList.OrderBy(x => x.Key).ToList();
|
|
// ciclo!
|
|
int zIdx = 0;
|
|
foreach (var item in ordList)
|
|
{
|
|
if (int.TryParse(item.Key.Substring(1), out zIdx))
|
|
{
|
|
// per ogni valore controllo se sia < di quello richiesto
|
|
if (zIdx < idx2keep)
|
|
{
|
|
ComLib.man.MongoDeleteEnvData(item.Key);
|
|
// conteggio eliminati
|
|
numDel++;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// ritorno
|
|
return numDel;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elimina da Redis info envelope fino al valore idx2keep indicato
|
|
/// </summary>
|
|
/// <param name="idx2keep">Valore da lasciare/non eliminare</param>
|
|
/// <returns></returns>
|
|
public static int CleanupRedis(long idx2keep)
|
|
{
|
|
// contatore eliminazioni
|
|
int numDel = 0;
|
|
// inizio recuperando da HashList
|
|
var currList = getEnvList();
|
|
// riordino x chiave x fare prima...
|
|
var ordList = currList.OrderBy(x => x.Key).ToList();
|
|
// ciclo!
|
|
int zIdx = 0;
|
|
string redZKey = "";
|
|
foreach (var item in ordList)
|
|
{
|
|
if (int.TryParse(item.Key.Substring(1), out zIdx))
|
|
{
|
|
// per ogni valore controllo se sia < di quello richiesto
|
|
if (zIdx < idx2keep)
|
|
{
|
|
// elimino cache
|
|
redZKey = $"{redOutPath}:{item.Key}";
|
|
memLayer.ML.redDelKey(redZKey);
|
|
// elimino chiave in hashList
|
|
memLayer.ML.redDelHashField(redMsgList, item.Key);
|
|
// conteggio eliminati
|
|
numDel++;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// ritorno conteggio eliminazioni
|
|
return numDel;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Deserializza un ordine offline
|
|
/// </summary>
|
|
/// <param name="rawData"></param>
|
|
/// <returns></returns>
|
|
public static nestReplyOffOrd deserializeOfflineOrder(string rawData)
|
|
{
|
|
nestReplyOffOrd answ = null;
|
|
try
|
|
{
|
|
answ = JsonConvert.DeserializeObject<nestReplyOffOrd>(rawData);
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Helper x deserializzare l'oggetto
|
|
/// </summary>
|
|
/// <param name="rawData"></param>
|
|
/// <returns></returns>
|
|
public static Takt deserializeTakt(string rawData)
|
|
{
|
|
Takt answ = JsonConvert.DeserializeObject<Takt>(rawData);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cache redis del BunkID in lavorazione sulla macchina <param name="machine"></param>
|
|
/// </summary>
|
|
public static int getCurrBatchId(string macchina)
|
|
{
|
|
int answ = -1;
|
|
string rawData = memLayer.ML.getRSV(redCurrBatchId(macchina));
|
|
int.TryParse(rawData, out answ);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// BUNK corrente (x ora copia di first, poi sarà quello SELEZIONATO tra quelli SELEZIONABILI)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static DS_App.StackListRow getCurrBunk(string machine = "WRK001")
|
|
{
|
|
DS_App.StackListRow answ = null;
|
|
DS_App.StackListDataTable tabBunk = null;
|
|
DataLayer DLMan = new DataLayer();
|
|
// cerco in cache....
|
|
if (getCurrBunkTab(machine) != null)
|
|
{
|
|
tabBunk = getCurrBunkTab(machine);
|
|
}
|
|
else
|
|
{
|
|
tabBunk = DLMan.taSTL.getLoaded(machine);
|
|
// salvo in redis
|
|
setCurrBunkTab(machine, tabBunk);
|
|
}
|
|
if (tabBunk != null && tabBunk.Count > 0)
|
|
{
|
|
answ = tabBunk[0];
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cache redis del BunkID in lavorazione sulla macchina <param name="machine"></param>
|
|
/// </summary>
|
|
public static int getCurrBunkId(string macchina)
|
|
{
|
|
int answ = -1;
|
|
string rawData = memLayer.ML.getRSV(redCurrBunkId(macchina));
|
|
int.TryParse(rawData, out answ);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// </summary>
|
|
/// <param name="sheetID"></param>
|
|
/// <returns></returns>
|
|
public static string getCurrentCss(int sheetID)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
// area REDIS!
|
|
string redKeyBase = $"{machineUnloadArea(sheetID)}";
|
|
// TTL standard
|
|
int dataCacheTTL = memLayer.ML.cdvi("cssCacheTTL");
|
|
dataCacheTTL = dataCacheTTL <= 0 ? 60 : dataCacheTTL;
|
|
// files
|
|
string filename = HttpContext.Current.Server.MapPath("~/Content/SheetColor.css");
|
|
string answ = File.ReadAllText(filename);
|
|
// solo se sheet > 0...
|
|
if (sheetID > 0)
|
|
{
|
|
try
|
|
{
|
|
// elenco items da foglio!!!
|
|
var tabItems = DLMan.taIL.getBySheet(sheetID);
|
|
List<string> itemsAll = new List<string>();
|
|
List<string> itemsDepo = new List<string>();
|
|
List<string> itemsCart = new List<string>();
|
|
List<string> itemsBin = new List<string>();
|
|
List<string> itemsSecOp = new List<string>();
|
|
List<string> itemsScrap = new List<string>();
|
|
List<string> itemsSelect = new List<string>();
|
|
|
|
//se ho items...
|
|
if (tabItems.Count > 0)
|
|
{
|
|
// ciclo!
|
|
foreach (var item in tabItems)
|
|
{
|
|
// aggiungoncomunque a lista generale...
|
|
itemsAll.Add(item.ItemDtmx);
|
|
// controllo se sia SCRAP
|
|
if (item.StatusID >= 990)
|
|
{
|
|
itemsScrap.Add(item.ItemDtmx);
|
|
}
|
|
// controllo SE sia stato depositato... check status 3/4
|
|
else if (item.StatusID == 3 || item.StatusID == 4)
|
|
{
|
|
itemsDepo.Add(item.ItemDtmx);
|
|
}
|
|
else if (item.ProcessesReq.Contains("PaintFlag"))
|
|
{
|
|
itemsBin.Add(item.ItemDtmx);
|
|
}
|
|
else
|
|
{
|
|
itemsCart.Add(item.ItemDtmx);
|
|
}
|
|
// controllo ANCHE postprocessing
|
|
if (item.PostProcList != "")
|
|
{
|
|
itemsSecOp.Add(item.ItemDtmx);
|
|
}
|
|
// se selezionato status 2...
|
|
if (item.StatusID == 2)
|
|
{
|
|
itemsSelect.Add(item.ItemDtmx);
|
|
}
|
|
}
|
|
}
|
|
|
|
// FIX BIN
|
|
answ = updateCssByItemList(answ, redKeyBase, "ItemsBin", itemsBin, dataCacheTTL);
|
|
|
|
// FIX CART
|
|
answ = updateCssByItemList(answ, redKeyBase, "ItemsCart", itemsCart, dataCacheTTL);
|
|
|
|
// FIX Scaricati
|
|
answ = updateCssByItemList(answ, redKeyBase, "ItemsDepo", itemsDepo, dataCacheTTL);
|
|
|
|
// FIX SEC-OP
|
|
answ = updateCssByItemList(answ, redKeyBase, "ItemsSecOp", itemsSecOp, dataCacheTTL);
|
|
|
|
// FIX SCRAP
|
|
answ = updateCssByItemList(answ, redKeyBase, "ItemsScrap", itemsScrap, dataCacheTTL);
|
|
|
|
// FIXED SEL da array oggetti selezionati...
|
|
answ = updateCssByItemList(answ, redKeyBase, "ItemsSel", itemsSelect, dataCacheTTL);
|
|
//answ = updateCssByPickedItems(answ, redKeyBase, "ItemsSel", dataCacheTTL);
|
|
|
|
// INFINE serializzo e salvo tutti gli items trovati...
|
|
string serVal = JsonConvert.SerializeObject(itemsAll);
|
|
memLayer.ML.setRSV($"{redKeyBase}:ItemsAll", serVal, dataCacheTTL);
|
|
|
|
// salvo redis css!
|
|
memLayer.ML.setRSV($"{redKeyBase}:Css", answ, dataCacheTTL);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restituisce il codice di envelope ultimo impiegato
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static long GetCurrMCount()
|
|
{
|
|
// incremento counter
|
|
long nextIndex = memLayer.ML.getRCnt(redMsgCount);
|
|
// ritorno
|
|
return nextIndex;
|
|
}
|
|
|
|
/// <summary>
|
|
/// PackList corrente (running in KIT)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static DS_App.PackListRow getCurrPackList()
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
DS_App.PackListRow answ = null;
|
|
var tabPLD = DLMan.taPL.getRunning();
|
|
if (tabPLD.Count > 0)
|
|
{
|
|
answ = tabPLD[0];
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera lo sheet corrente da un BUNK come quello in status 5...
|
|
/// </summary>
|
|
/// <param name="BatchID"></param>
|
|
/// <param name="machine"></param>
|
|
/// <returns></returns>
|
|
public static DS_App.SheetListRow getCurrSheet(int BatchID, string machine)
|
|
{
|
|
DS_App.SheetListRow answ = null;
|
|
if (BatchID > 0 && !string.IsNullOrEmpty(machine))
|
|
{
|
|
try
|
|
{
|
|
DS_App.SheetListDataTable tabSheets = null;
|
|
// cerco in cache....
|
|
if (getCurrSheetTab(machine) != null)
|
|
{
|
|
tabSheets = getCurrSheetTab(machine);
|
|
}
|
|
else
|
|
{
|
|
// 2023.10.27 passaggio versione cached
|
|
#if false
|
|
// recupero sheet corrente da Bunk...
|
|
DataLayer DLMan = new DataLayer();
|
|
tabSheets = DLMan.taSHL.getByMLStatus(BatchID, 5, 5, machine);
|
|
|
|
#endif
|
|
tabSheets = SheetTabGet(machine, BatchID, 5, 5);
|
|
// salvo in redis
|
|
setCurrSheetTab(machine, tabSheets);
|
|
}
|
|
// leggo prima riga --> foglio corrente
|
|
if (tabSheets != null && tabSheets.Count > 0)
|
|
{
|
|
answ = tabSheets[0];
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Cache redis del SheetID in lavorazione sulla macchina <param name="machine"></param>
|
|
/// </summary>
|
|
public static int getCurrSheetId(string macchina)
|
|
{
|
|
int answ = -1;
|
|
string rawData = memLayer.ML.getRSV(redCurrSheetId(macchina));
|
|
int.TryParse(rawData, out answ);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restituisce elenco KVP delle buste ancora "pending" (quando processate le elimina da elenco...)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static KeyValuePair<string, string>[] getEnvList()
|
|
{
|
|
KeyValuePair<string, string>[] answ = memLayer.ML.redGetHash(redMsgList);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// IP del device
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static string GetIPAddress()
|
|
{
|
|
HttpContext context = HttpContext.Current;
|
|
string ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
|
|
|
|
if (!string.IsNullOrEmpty(ipAddress))
|
|
{
|
|
string[] addresses = ipAddress.Split(',');
|
|
if (addresses.Length != 0)
|
|
{
|
|
return addresses[0];
|
|
}
|
|
}
|
|
|
|
return context.Request.ServerVariables["REMOTE_ADDR"];
|
|
}
|
|
|
|
public static bool getMachLiveStatus(string machine)
|
|
{
|
|
bool isLive = false;
|
|
/// cerco in redis...
|
|
string redKey = $"{redProdMachStateLive}:{machine}";
|
|
string redVal = memLayer.ML.getRSV(redKey);
|
|
if (!string.IsNullOrEmpty(redVal))
|
|
{
|
|
bool.TryParse(redVal, out isLive);
|
|
}
|
|
return isLive;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restituisce il prossimo codice di envelope per comunicare con sistemi esterni
|
|
/// </summary>
|
|
/// <param name="BatchID">Batch contenuto nell'envelope</param>
|
|
/// <param name="note">note opzionali (motivo envelope)</param>
|
|
/// <returns></returns>
|
|
public static string getNextEnv(int BatchID, string note)
|
|
{
|
|
// incremento counter
|
|
long nextIndex = memLayer.ML.setRCntI(redMsgCount);
|
|
// salvo contenuto della busta
|
|
string answ = $"Z{nextIndex:000000000000}";
|
|
Dictionary<string, string> lista = new Dictionary<string, string>();
|
|
lista.Add(answ, $"{BatchID}|{note}");
|
|
memLayer.ML.redSaveHashDict(redMsgList, lista);
|
|
// ritorno
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera file pdf
|
|
/// </summary>
|
|
/// <param name="optParameters"></param>
|
|
/// <returns></returns>
|
|
public static string getPdfFilePath(Dictionary<string, string> optParameters)
|
|
{
|
|
string answ = "";
|
|
if (optParameters.ContainsKey("PdfLink"))
|
|
{
|
|
answ = optParameters["PdfLink"];
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera le operazioni di PostProcessing, esempio:
|
|
/// - T-Nut
|
|
/// - Round
|
|
/// - Chop
|
|
/// </summary>
|
|
/// <param name="optParameters"></param>
|
|
/// <returns></returns>
|
|
public static string getPostProcList(Dictionary<string, string> optParameters)
|
|
{
|
|
string answ = "";
|
|
foreach (var currOpt in optParameters)
|
|
{
|
|
switch (currOpt.Key)
|
|
{
|
|
case "ChopAtTab":
|
|
case "RoundEdge":
|
|
case "TNutFlag":
|
|
// se contiene YES aggiungo...
|
|
if (currOpt.Value.ToLower() == "yes")
|
|
{
|
|
answ += $"{currOpt.Key}#";
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
// se finisce per "#" trimmo...
|
|
if (answ.EndsWith("#"))
|
|
{
|
|
answ = answ.Substring(0, answ.Length - 1);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera le operazioni RICHIESTE a valle
|
|
/// - Paint
|
|
/// - Assembly
|
|
/// - SecOp
|
|
/// </summary>
|
|
/// <param name="optParameters"></param>
|
|
/// <returns></returns>
|
|
public static string getProcessesReq(Dictionary<string, string> optParameters)
|
|
{
|
|
string answ = "";
|
|
foreach (var currOpt in optParameters)
|
|
{
|
|
switch (currOpt.Key)
|
|
{
|
|
case "AssemblyCell":
|
|
case "PaintFlag":
|
|
// se contiene YES aggiungo...
|
|
if (currOpt.Value.ToLower() == "yes")
|
|
{
|
|
answ += $"{currOpt.Key}#";
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
// se finisce per "#" trimmo...
|
|
if (answ.EndsWith("#"))
|
|
{
|
|
answ = answ.Substring(0, answ.Length - 1);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
public static int getSecScreenCode()
|
|
{
|
|
int answ = 0;
|
|
Random rnd = new Random();
|
|
answ = rnd.Next(1000000);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restitusice il path del PDF richiesto su una data SecScreen come salvato su REDIS
|
|
/// </summary>
|
|
/// <param name="secScreenCode">cod schermo, formato SSC000000</param>
|
|
/// <returns></returns>
|
|
public static string getSecScreenRequest(string secScreenCode)
|
|
{
|
|
string answ = "";
|
|
// recupero ultima call
|
|
string redKey = $"{redSecScreenReq}:{secScreenCode}";
|
|
answ = memLayer.ML.getRSV(redKey);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera da REDIS info indice revisione x BUNK (cambio foglio)
|
|
/// </summary>
|
|
/// <param name="BunkID"></param>
|
|
/// <returns></returns>
|
|
public static int getSheetRevByBunk(int BunkID)
|
|
{
|
|
int answ = 0;
|
|
if (BunkID > 0)
|
|
{
|
|
// recupero da REDIS!
|
|
string redKeyExp = memLayer.ML.redHash($"DataExp");
|
|
string redKeyRev = $"{ComLib.machineUnloadBunkArea(BunkID)}:Rev";
|
|
// controllo expiry globale... se manca SVUOTO area
|
|
string rawData = memLayer.ML.getRSV(redKeyExp);
|
|
if (string.IsNullOrEmpty(rawData))
|
|
{
|
|
// svuoto e scrivo...
|
|
memLayer.ML.redFlushKey(memLayer.ML.redHash($"MachineUnload"));
|
|
memLayer.ML.redFlushKey(memLayer.ML.redHash($"TabSheets"));
|
|
memLayer.ML.setRSV(redKeyExp, $"Reload Data {DateTime.Now}", 3600);
|
|
}
|
|
answ = memLayer.ML.getRCnt(redKeyRev);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
public static bool IsUnc(string path)
|
|
{
|
|
string root = Path.GetPathRoot(path);
|
|
|
|
// Check if root starts with "\\", clearly an UNC
|
|
if (root.StartsWith(@"\\"))
|
|
return true;
|
|
|
|
// Check if the drive is a network drive
|
|
DriveInfo drive = new DriveInfo(root);
|
|
if (drive.DriveType == DriveType.Network)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco dei kit dato Batch (specifico)
|
|
/// </summary>
|
|
/// <param name="BatchId"></param>
|
|
/// <returns></returns>
|
|
public static DS_App.KitListDataTable KitListByBatch(int BatchId)
|
|
{
|
|
DS_App.KitListDataTable answ = new DS_App.KitListDataTable();
|
|
if (BatchId > 0)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
string redKey = $"{redKits}:ByBatch:{BatchId}";
|
|
string rawData = "";
|
|
|
|
// cerco in redis
|
|
if (memLayer.ML.redKeyPresent(redKey))
|
|
{
|
|
rawData = memLayer.ML.getRSV(redKey);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
try
|
|
{
|
|
answ = JsonConvert.DeserializeObject<DS_App.KitListDataTable>(rawData);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
// se vuoto rileggo
|
|
if (answ.Count == 0)
|
|
{
|
|
// recupero ordini dato il batch MAIN
|
|
answ = DLMan.taKL.getByBatch(BatchId);
|
|
|
|
// salvo in cache
|
|
rawData = JsonConvert.SerializeObject(answ);
|
|
memLayer.ML.setRSV(redKey, rawData, 5);
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// restitusice ultima chiamata REST registrata su REDIS
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static string lastRestAnsw()
|
|
{
|
|
string answ = "";
|
|
// recupero ultima call
|
|
string redKey = $"{redNestAnsw}:LAST_CALL";
|
|
answ = memLayer.ML.getRSV(redKey);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calcola area REDIS per MACCHINA
|
|
/// </summary>
|
|
/// <param name="SheetID"></param>
|
|
/// <returns></returns>
|
|
public static string machineArea(string machineCod)
|
|
{
|
|
string answ = memLayer.ML.redHash($"currMachineData:{machineCod}");
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calcola area REDIS per FOGLIO in fase di scarico
|
|
/// </summary>
|
|
/// <param name="SheetID"></param>
|
|
/// <returns></returns>
|
|
public static string machineUnloadArea(int SheetID)
|
|
{
|
|
// se 0 --> tutto l'albero, sennò solo area corrente...
|
|
string answ = "";
|
|
if (SheetID > 0)
|
|
{
|
|
answ = memLayer.ML.redHash($"MachineUnload:{SheetID}");
|
|
}
|
|
else
|
|
{
|
|
answ = memLayer.ML.redHash($"MachineUnload");
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calcola area REDIS per BUNK in fase di scarico
|
|
/// </summary>
|
|
/// <param name="BunkID"></param>
|
|
/// <returns></returns>
|
|
public static string machineUnloadBunkArea(int BunkID)
|
|
{
|
|
// se 0 --> tutto l'albero, sennò solo area corrente...
|
|
string answ = "";
|
|
if (BunkID > 0)
|
|
{
|
|
answ = memLayer.ML.redHash($"MachineUnload:Bunk:{BunkID}");
|
|
}
|
|
else
|
|
{
|
|
answ = memLayer.ML.redHash($"MachineUnload:Bunk");
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco degli orders dato Batch (specifico)
|
|
/// </summary>
|
|
/// <param name="BatchId"></param>
|
|
/// <returns></returns>
|
|
public static DS_App.OrderListTreeDataTable OrdersExtByBatch(int BatchId)
|
|
{
|
|
DS_App.OrderListTreeDataTable answ = new DS_App.OrderListTreeDataTable();
|
|
if (BatchId > 0)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
string redKey = $"{redOrders}:ByBatch:{BatchId}";
|
|
string rawData = "";
|
|
|
|
// cerco in redis
|
|
if (memLayer.ML.redKeyPresent(redKey))
|
|
{
|
|
rawData = memLayer.ML.getRSV(redKey);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
try
|
|
{
|
|
answ = JsonConvert.DeserializeObject<DS_App.OrderListTreeDataTable>(rawData);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
// se vuoto rileggo
|
|
if (answ.Count == 0)
|
|
{
|
|
// recupero ordini dato il batch MAIN
|
|
answ = DLMan.taOLT.getByBatch(BatchId);
|
|
|
|
// salvo in cache
|
|
rawData = JsonConvert.SerializeObject(answ);
|
|
memLayer.ML.setRSV(redKey, rawData, 5);
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco degli orders dato Batch (Ancestor/Principale)
|
|
/// </summary>
|
|
/// <param name="BatchId"></param>
|
|
/// <returns></returns>
|
|
public static DS_App.OrderListTreeDataTable OrdersExtByBatchTree(int BatchId)
|
|
{
|
|
DS_App.OrderListTreeDataTable answ = new DS_App.OrderListTreeDataTable();
|
|
if (BatchId > 0)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
string redKey = $"{redOrders}:ByBatchTree:{BatchId}";
|
|
string rawData = "";
|
|
// cerco in redis
|
|
if (memLayer.ML.redKeyPresent(redKey))
|
|
{
|
|
rawData = memLayer.ML.getRSV(redKey);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
try
|
|
{
|
|
answ = JsonConvert.DeserializeObject<DS_App.OrderListTreeDataTable>(rawData);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
// se vuoto rileggo
|
|
if (answ.Count == 0)
|
|
{
|
|
// recupero ordini dato il batch MAIN
|
|
answ = DLMan.taOLT.getByBatchTree(BatchId);
|
|
|
|
// salvo in cache
|
|
rawData = JsonConvert.SerializeObject(answ);
|
|
memLayer.ML.setRSV(redKey, rawData, 10);
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset cache ordini EXT
|
|
/// </summary>
|
|
public static void OrdersExtResetCache()
|
|
{
|
|
string redKey = $"{redOrders}:ByBatch:*";
|
|
memLayer.ML.redFlushKey(redKey);
|
|
redKey = $"{redOrders}:ByBatchTree:*";
|
|
memLayer.ML.redFlushKey(redKey);
|
|
redKey = $"{redKits}:ByBatch:*";
|
|
memLayer.ML.redFlushKey(redKey);
|
|
}
|
|
|
|
public static string PositionStatusDescr(object value)
|
|
{
|
|
string answ = "";
|
|
try
|
|
{
|
|
BatchPosition pStatus = (BatchPosition)Enum.Parse(typeof(BatchPosition), value.ToString());
|
|
switch (pStatus)
|
|
{
|
|
case BatchPosition.NotStarted:
|
|
answ = traduci("NotStarted");
|
|
break;
|
|
|
|
case BatchPosition.StackStarted:
|
|
answ = traduci("Stacking");
|
|
break;
|
|
|
|
case BatchPosition.StackDone:
|
|
answ = traduci("StackDone");
|
|
break;
|
|
|
|
case BatchPosition.Current:
|
|
answ = traduci("BatchCurrent");
|
|
break;
|
|
|
|
case BatchPosition.Completed:
|
|
answ = traduci("BatchCompleted");
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue richieste lettura da PROD
|
|
/// </summary>
|
|
public static void procProdReadReq()
|
|
{
|
|
// !!!FIXME!!!
|
|
}
|
|
|
|
/// <summary>
|
|
/// Esegue richieste scrittura da PROD
|
|
/// </summary>
|
|
public static void procProdWriteReq()
|
|
{
|
|
// !!!FIXME!!!
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera e transcodifica DA DB i dati di UN SINGOLO bunk
|
|
/// </summary>
|
|
/// <param name="currBunk"></param>
|
|
/// <param name="machine"></param>
|
|
/// <returns></returns>
|
|
public static ProdBunk prodGetBunk(int StackID, string machine)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
ProdBunk answ = null;
|
|
List<ProdSheet> elSheet = new List<ProdSheet>();
|
|
var tabBunks = DLMan.taSTL.getByKey(StackID);
|
|
if (tabBunks.Count == 1)
|
|
{
|
|
DS_App.StackListRow currBunk = tabBunks[0];
|
|
// calcolo attributi oggetti
|
|
CStatus currSt = CStatus.Programmed;
|
|
if (currBunk.Position == 5)
|
|
{
|
|
currSt = CStatus.Running;
|
|
}
|
|
else
|
|
{
|
|
currSt = CStatus.Done;
|
|
}
|
|
// recupero gli sheets di questo stack...
|
|
DS_App.SheetListDataTable tabSheets = DLMan.taSHL.getByStack(StackID, machine);
|
|
DateTime dataStart = DateTime.Now;
|
|
ProdSheet currPanel;
|
|
string nestBasePath = memLayer.ML.CRS("nestBasePath").ToLower();
|
|
string servBasePath = memLayer.ML.CRS("servBasePath").ToLower();
|
|
string prodBasePath = memLayer.ML.CRS("prodBasePath").ToLower();
|
|
foreach (var item in tabSheets)
|
|
{
|
|
// converto i workData
|
|
WorkData wdPrint = new WorkData()
|
|
{
|
|
DtStart = item.IsPrntStartNull() ? null : (DateTime?)item.PrntStart,
|
|
DtEnd = item.IsPrntEndNull() ? null : (DateTime?)item.PrntEnd,
|
|
ProgramPath = item.PrintFilePath.ToLower().Replace(nestBasePath, prodBasePath).Replace(servBasePath, prodBasePath)
|
|
};
|
|
WorkData wdMachining = new WorkData()
|
|
{
|
|
DtStart = item.IsWrkStartNull() ? null : (DateTime?)item.WrkStart,
|
|
DtEnd = item.IsWrkEndNull() ? null : (DateTime?)item.WrkEnd,
|
|
ProgramPath = item.CncFilePath.ToLower().Replace(nestBasePath, prodBasePath).Replace(servBasePath, prodBasePath)
|
|
};
|
|
WorkData wdUnload = new WorkData()
|
|
{
|
|
DtStart = item.IsUnlStartNull() ? null : (DateTime?)item.UnlStart,
|
|
DtEnd = item.IsUnlEndNull() ? null : (DateTime?)item.UnlEnd
|
|
};
|
|
MaterialData material = new MaterialData()
|
|
{
|
|
MaterialId = item.MatID,
|
|
MaterialDescription = item.MatDesc,
|
|
MaterialPN = item.MatExtCode.ToString()
|
|
};
|
|
PStatus currPnlStatus = PStatus.Programmed;
|
|
Enum.TryParse(item.ShStatus.ToString(), out currPnlStatus);
|
|
currPanel = new ProdSheet()
|
|
{
|
|
Printing = wdPrint,
|
|
Machining = wdMachining,
|
|
Unloading = wdUnload,
|
|
Material = material,
|
|
SheetId = item.StackID,
|
|
Status = currPnlStatus
|
|
};
|
|
elSheet.Add(currPanel);
|
|
if (!item.IsPrntStartNull())
|
|
{
|
|
dataStart = item.PrntStart < dataStart ? item.PrntStart : dataStart;
|
|
}
|
|
}
|
|
// compongo il bunk...
|
|
answ = new ProdBunk()
|
|
{
|
|
BunkId = currBunk.StackID,
|
|
Status = currSt,
|
|
DataMatrix = currBunk.StackDtmx,
|
|
SheetList = elSheet,
|
|
DtStart = dataStart
|
|
};
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restituisce il BUNK che è il primo della lista x la MACCHINA indicata:
|
|
/// - posizione = 3 (ho letto da webApp il BUNK e preso in carico)
|
|
/// - NumSheet > NumSheetUnload
|
|
/// - Ordinato per StackIndex (crescente) x avere il più VECCHIO
|
|
/// </summary>
|
|
/// <param name="machine"></param>
|
|
/// <returns></returns>
|
|
public static ProdBunk prodGetFirstBunk(string machine)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
// cerco prima su REDIS...
|
|
ProdBunk answ = redisFirstBunk;
|
|
if (answ == null)
|
|
{
|
|
// vado sul DB e leggo ...
|
|
DS_App.StackListDataTable tabBunks = DLMan.taSTL.getLoaded(machine);
|
|
// controllo di averne almeno 1...
|
|
if (tabBunks.Count > 0)
|
|
{
|
|
DS_App.StackListRow currBunk = tabBunks[0];
|
|
answ = getBunkFromDb(currBunk, machine);
|
|
// se ho qualcosa salvo su REDIS
|
|
redisFirstBunk = answ;
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restituisce il PROSSIMO bunk x la MACCHINA indicata secondo criterio:
|
|
/// - posizione = 5 (ho letto da webApp il BUNK e preso in carico)
|
|
/// - NumSheet > NumSheetUnload
|
|
/// - Ordinato per StackIndex (crescente) x avere il più VECCHIO
|
|
/// - SUCCESSIVO al BunkID(=StackID) ricevuto
|
|
/// </summary>
|
|
/// <param name="machine"></param>
|
|
/// <returns></returns>
|
|
public static ProdBunk prodGetNextBunk(int BunkID, string machine)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
ProdBunk answ = getRedisNextBunk(BunkID);
|
|
if (answ == null)
|
|
{
|
|
// vado sul DB e leggo ...
|
|
DS_App.StackListDataTable tabBunks = DLMan.taSTL.getLoaded(machine);
|
|
// controllo di averne almeno 1...
|
|
if (tabBunks.Count > 0)
|
|
{
|
|
DS_App.StackListRow currBunk = null;
|
|
bool trovato = false;
|
|
// ciclo
|
|
foreach (var item in tabBunks)
|
|
{
|
|
if (trovato)
|
|
{
|
|
currBunk = item;
|
|
break;
|
|
}
|
|
// controllo se sia quello richiesto
|
|
if (item.StackID == BunkID)
|
|
{
|
|
trovato = true;
|
|
}
|
|
}
|
|
// se c'è un bunk trovato --> carico
|
|
if (currBunk != null)
|
|
{
|
|
answ = getBunkFromDb(currBunk, machine);
|
|
// salvo su redis
|
|
setRedisNextBunk(BunkID, answ);
|
|
}
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco di sheet in lavorazione su una data macchina:
|
|
/// - da macchina recupera il BATCH
|
|
/// - dal batch prende i BUNK CARICATI sulla macchina (posizione 5)
|
|
/// - filtra i fogli già lavorati
|
|
/// </summary>
|
|
/// <param name="codPost"></param>
|
|
/// <returns></returns>
|
|
public static SheetWorkList prodGetSheetWorkList(string codPost)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
// init out
|
|
SheetWorkList answ = null;
|
|
// recupero batch corrente
|
|
DS_App.BatchListDataTable currBatch = DLMan.taBL.getCurrentByMachine(codPost);
|
|
try
|
|
{
|
|
if (currBatch != null)
|
|
{
|
|
// come batch DOVREI averne solo 1 in corso...
|
|
DS_App.BatchListRow batchRow = currBatch[0];
|
|
// recupero i vari SHEETS del batch...
|
|
DS_App.SheetListDataTable sheetTable = DLMan.taSHL.getCurrentByBatch(batchRow.BatchID, codPost);
|
|
List<DS_App.SheetListRow> sheetList = new List<DS_App.SheetListRow>();
|
|
// controllo che SIA NULL la data di unload --> NON ancora scaricato
|
|
foreach (var item in sheetTable)
|
|
{
|
|
// metto in elenco SOLO se NON nulla data fine unload
|
|
if (item.IsUnlEndNull())
|
|
{
|
|
sheetList.Add(item);
|
|
}
|
|
}
|
|
answ = convertSheetWorkList(sheetList);
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Restituisce stato macchina (da Redis)
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static MachineStatData prodMachStateDataGet(string machine)
|
|
{
|
|
MachineStatData answ = new MachineStatData();
|
|
string redVal = memLayer.ML.getRSV($"{redProdMachStateData}:{machine}");
|
|
if (!string.IsNullOrEmpty(redVal))
|
|
{
|
|
answ = JsonConvert.DeserializeObject<MachineStatData>(redVal);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva gli stati macchina ricevuti sul DB e poi salva ultimo su redis Do x scontato tutti
|
|
/// singola macchina
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static bool prodMachStateDataInsert(MachineStatData updateRecords)
|
|
{
|
|
/* ------------------------------------------------------------------
|
|
* Info preliminari
|
|
* Public Const STATION_LINE As String = "LINE"
|
|
* Public Const STATION_PRINTER As String = "PRINTER"
|
|
* Public Const STATION_NC_MACHINE As String = "NC_MACHINE"
|
|
* Public Const STATION_UNLOADER As String = "UNLOADER"
|
|
*
|
|
*
|
|
*
|
|
* Public Const ST_KEEP_ALIVE_START As String = "00"
|
|
* Public Const ST_KEEP_ALIVE As String = "01"
|
|
*
|
|
*
|
|
* Public Const ST_PRINTER_INIT As String = "02"
|
|
* Public Const ST_PRINTER_WARM_START As String = "03"
|
|
* Public Const ST_PRINTER_READY As String = "04"
|
|
* Public Const ST_PRINTER_WAIT_SHEET_LOADED As String = "05"
|
|
* Public Const ST_PRINTER_PRINTING As String = "06"
|
|
* Public Const ST_PRINTER_WAIT_SHEET_UNLOADED As String = "07"
|
|
* Public Const ST_PRINTER_WAIT_PROGRAM As String = "08"
|
|
*
|
|
* ------------------------------------------------------------------ */
|
|
|
|
bool answ = false;
|
|
DataLayer DLMan = new DataLayer();
|
|
|
|
// recupero clockDrift
|
|
string clockDriftKey = $"{redProdMachClock}:{updateRecords.Machine}";
|
|
string rawDrift = memLayer.ML.getRSV(clockDriftKey);
|
|
double driftSec = 0;
|
|
if (!string.IsNullOrEmpty(rawDrift))
|
|
{
|
|
double.TryParse(rawDrift, out driftSec);
|
|
}
|
|
|
|
// salvo in mongo x debug
|
|
ComLib.man.saveProdStat(updateRecords);
|
|
|
|
// verifica preliminare della PLACE
|
|
checkPlace(updateRecords.Machine);
|
|
// salvo sul DB il set di dati...
|
|
foreach (var item in updateRecords.Records)
|
|
{
|
|
// i keep alive NON li scrivo ma processo
|
|
switch (item.Code)
|
|
{
|
|
case "00":
|
|
// è PRIMO keepalive --> uso x sync dell'orologio
|
|
DateTime adesso = DateTime.Now;
|
|
DateTime machClock = item.DtRecord;
|
|
driftSec = adesso.Subtract(machClock).TotalSeconds;
|
|
// salvo
|
|
memLayer.ML.setRSV(clockDriftKey, $"{driftSec}");
|
|
break;
|
|
|
|
case "01":
|
|
// savo status alive
|
|
ComLib.setMachLiveStatus(updateRecords.Machine, true);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
DLMan.taStatLog.insert(item.DtRecord.AddMilliseconds(driftSec), updateRecords.Machine, item.Station, item.Code, item.Payload, 0);
|
|
}
|
|
|
|
// chiamo procedura x fix durate
|
|
DLMan.taStatLog.updateDuration(updateRecords.Machine);
|
|
|
|
// recupero ultimo record ricevuto
|
|
try
|
|
{
|
|
string station = "";
|
|
MachineStatRecord lastRecord = new MachineStatRecord();
|
|
|
|
station = "PRINTER";
|
|
lastRecord = updateRecords.Records.Where(x => x.Station == station).OrderByDescending(x => x.DtRecord).FirstOrDefault();
|
|
if (lastRecord != null)
|
|
saveStatus(updateRecords.Machine, station, lastRecord);
|
|
|
|
station = "NC_MACHINE";
|
|
lastRecord = updateRecords.Records.Where(x => x.Station == station).OrderByDescending(x => x.DtRecord).FirstOrDefault();
|
|
if (lastRecord != null)
|
|
saveStatus(updateRecords.Machine, station, lastRecord);
|
|
|
|
station = "UNLOADER";
|
|
lastRecord = updateRecords.Records.Where(x => x.Station == station).OrderByDescending(x => x.DtRecord).FirstOrDefault();
|
|
if (lastRecord != null)
|
|
saveStatus(updateRecords.Machine, station, lastRecord);
|
|
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset stati macchina registrati
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static bool prodMachStateDataReset()
|
|
{
|
|
bool answ = memLayer.ML.setRSV(redProdMachStateData, "", 1);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua divisione evitando zeri a den...
|
|
/// </summary>
|
|
/// <param name="num"></param>
|
|
/// <param name="den"></param>
|
|
/// <returns></returns>
|
|
public static double ratioProt(double num, double den)
|
|
{
|
|
den = den == 0 ? 1 : den;
|
|
return num / den;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Leggo il Takt inviato
|
|
/// </summary>
|
|
/// <param name="origin">Origine del dato: SERV / PROD / NEST</param>
|
|
/// <param name="currData"></param>
|
|
/// <returns></returns>
|
|
public static Takt readTakt(string origin, string TaktId)
|
|
{
|
|
Takt answ = null;
|
|
try
|
|
{
|
|
string redKey = $"NKC:{origin.ToUpper()}:TAKT:{TaktId}";
|
|
string redVal = memLayer.ML.getRSV(redKey);
|
|
answ = deserializeTakt(redVal);
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset della cache dei BatchDescendant x ID indicato
|
|
/// </summary>
|
|
/// <param name="BatchId"></param>
|
|
public static void ResetBatchDescendant(int BatchId)
|
|
{
|
|
string redKey = $"{redBatchDescend}:{BatchId}";
|
|
memLayer.ML.setRSV(redKey, "", 10);
|
|
}
|
|
|
|
/// <summary>
|
|
/// resetta la richeista corrente in modo che non ce ne siano altre in coda
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static bool resetBatchReq()
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
currBatchReq = "";
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// resetto curr bunk
|
|
/// </summary>
|
|
/// <param name="machine"></param>
|
|
public static void resetCurrBunk(string machine = "WRK001")
|
|
{
|
|
// svuoto"
|
|
memLayer.ML.redFlushKey(redCurrBunkTabKey(machine));
|
|
}
|
|
|
|
/// <summary>
|
|
/// resetto curr sheets
|
|
/// </summary>
|
|
/// <param name="machine"></param>
|
|
public static void resetCurrSheet(string machine = "WRK001")
|
|
{
|
|
// svuoto sheet speciali
|
|
memLayer.ML.redFlushKey(redCurrSheetTabKey(machine));
|
|
// svuoto tutti i fogli in cache x LOAD page
|
|
memLayer.ML.redFlushKey(redCurrSheetTabKey(machine, -1, 0, 0));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Registra che un dato ITEM è stato prelevato in fase di scarico da ID foglio + datamatrix
|
|
/// </summary>
|
|
/// <param name="sheetID">ID foglio</param>
|
|
/// <param name="deviceId">Cod del device di scarico</param>
|
|
/// <returns></returns>
|
|
public static bool resetItemPickup(int sheetID, string deviceId)
|
|
{
|
|
// area REDIS!
|
|
string redKeyBase = $"{machineUnloadArea(sheetID)}";
|
|
bool answ = false;
|
|
string rawData = memLayer.ML.getRSV($"{redKeyBase}:ItemsSel");
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
try
|
|
{
|
|
Dictionary<string, string> dictData = JsonConvert.DeserializeObject<Dictionary<string, string>>(rawData);
|
|
// cerco chiave device...
|
|
if (dictData.ContainsKey(deviceId))
|
|
{
|
|
// sostituisco
|
|
dictData.Remove(deviceId);
|
|
}
|
|
// salvo!
|
|
rawData = JsonConvert.SerializeObject(dictData);
|
|
memLayer.ML.setRSV($"{redKeyBase}:ItemsSel", rawData);
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
// reset memoria redis del CSS x obbligare refresh...
|
|
memLayer.ML.setRSV($"{redKeyBase}:Css", "");
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Reset della cache dei BatchDescendant x ID indicato
|
|
/// </summary>
|
|
/// <param name="BatchId"></param>
|
|
public static void ResetOrderByBatch(int BatchId)
|
|
{
|
|
string redKey = $"{redOrders}:BYBATCH:{BatchId}";
|
|
memLayer.ML.setRSV(redKey, "", 10);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resetto i dati PRIMA di salvare i nuovi dati dal nesting
|
|
/// </summary>
|
|
/// <param name="BatchID"></param>
|
|
/// <param name="BunkList"></param>
|
|
public static void resetPrevDataFromNesting(int BatchID)
|
|
{
|
|
//elimino dati child MA NON il batch...
|
|
DataLayer DLMan = new DataLayer();
|
|
DLMan.taBL.deleteTree(BatchID, 0);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resetto in REDIS i dati di bunk (corrente e successivi)
|
|
/// </summary>
|
|
public static void resetRedisBunkData(string machine)
|
|
{
|
|
resetCurrBunk();
|
|
resetCurrSheet();
|
|
setCurrBatchId(machine, 0);
|
|
setCurrBunkId(machine, 0);
|
|
setCurrSheetId(machine, 0);
|
|
redisFirstBunk = null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Annulla (Svuota) richiesta di esecuzione di CAM
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static bool resetRequestToNest()
|
|
{
|
|
bool answ = false;
|
|
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Registra che un dato ITEM è stato prelevato in fase di scarico da ID foglio + datamatrix
|
|
/// </summary>
|
|
/// <param name="sheetID">ID foglio</param>
|
|
/// <param name="deviceId">Cod del device di scarico</param>
|
|
/// <param name="itemDtmx">Cod datamatrix ITEM</param>
|
|
/// <returns></returns>
|
|
public static bool saveItemPickup(int sheetID, string deviceId, string itemDtmx)
|
|
{
|
|
// area REDIS!
|
|
string redKeyBase = $"{machineUnloadArea(sheetID)}";
|
|
bool answ = false;
|
|
string rawData = memLayer.ML.getRSV($"{redKeyBase}:ItemsSel");
|
|
Dictionary<string, string> dictData = new Dictionary<string, string>();
|
|
try
|
|
{
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
dictData = JsonConvert.DeserializeObject<Dictionary<string, string>>(rawData);
|
|
}
|
|
// cerco chiave device...
|
|
if (dictData.ContainsKey(deviceId))
|
|
{
|
|
// sostituisco
|
|
dictData[deviceId] = itemDtmx;
|
|
}
|
|
else
|
|
{
|
|
dictData.Add(deviceId, itemDtmx);
|
|
}
|
|
// salvo!
|
|
rawData = JsonConvert.SerializeObject(dictData);
|
|
memLayer.ML.setRSV($"{redKeyBase}:ItemsSel", rawData);
|
|
answ = true;
|
|
// reset memoria redis del CSS x obbligare refresh...
|
|
memLayer.ML.setRSV($"{redKeyBase}:Css", "");
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvo il Takt inviato
|
|
/// </summary>
|
|
/// <param name="origin">Origine del dato: SERV / PROD / NEST</param>
|
|
/// <param name="currData"></param>
|
|
/// <returns></returns>
|
|
public static bool saveTakt(string origin, Takt currData)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
// calcolo valori redis
|
|
string redKey = $"NKC:{origin.ToUpper()}:TAKT:{currData.TaktId}";
|
|
string redVal = serializeTakt(currData);
|
|
// scrivo per ora solo su REDIS
|
|
memLayer.ML.setRSV(redKey, redVal);
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Invia una richiesta di esecuzione di Stima/Nesting x un Batch
|
|
/// </summary>
|
|
/// <param name="BatchID">Batch di cui si chiede processing</param>
|
|
/// <param name="note">note opzionali</param>
|
|
/// <param name="pType">Tipo processo: 1 = stima, 2 = nesting, 3 = stima EXTENDED</param>
|
|
/// <param name="isValidation">
|
|
/// Indica se sia validazione (part o disegno) --> in tal caso MaxTime = 1
|
|
/// </param>
|
|
/// <param name="numIndexStart">Numero di indice richiesto con cui partire x creare CART/BIN</param>
|
|
/// <param name="createPng">
|
|
/// Richiesta creazione png delle part valutate, da impiegare x DXF validation
|
|
/// </param>
|
|
/// <returns></returns>
|
|
public static bool sendBatchReq(int BatchID, string note, int pType, bool isValidation, int numIndexStart, bool createPng)
|
|
{
|
|
string logIdKey = $"sendBatchReq | BatchID: {BatchID}";
|
|
// loggo richiesta
|
|
Log.Instance.Info($"{logIdKey} | numIndexStart: {numIndexStart}");
|
|
Log.Instance.Info($"{logIdKey} | note: {note} | pType: {pType} | isValidation: {isValidation} | createPng: {createPng}");
|
|
DataLayer DLMan = new DataLayer();
|
|
bool answ = false;
|
|
// per prima cosa mi serve una "nuova busta" per inviare i messaggi
|
|
string nextEnv = getNextEnv(BatchID, note);
|
|
// preparo il contenuto della busta ed invio i messaggi...
|
|
try
|
|
{
|
|
// preliminare: se è stima EXT --> riporto pezzi su ordine ORIGINALE...
|
|
if (pType == 3)
|
|
{
|
|
DLMan.taOLT.setBatchSplit(BatchID, false);
|
|
}
|
|
// in base allo stato del BATCH corrente determino il tempo e le opzioni da inviare...
|
|
var batch = DLMan.taBL.getByKey(BatchID);
|
|
int mTime = 1;
|
|
// se non è validazione verifico che tempo impostare...
|
|
if (!isValidation)
|
|
{
|
|
if (batch[0].STATUS < (int)BatchStatus.EstimationDone)
|
|
{
|
|
mTime = memLayer.ML.cdvi("estimMaxTime");
|
|
}
|
|
else
|
|
{
|
|
mTime = memLayer.ML.cdvi("nestMaxTime");
|
|
}
|
|
}
|
|
|
|
// init oggetti x fare cicli...
|
|
Order currOrder = null;
|
|
Kit currentKit = null;
|
|
Part currPart = null;
|
|
List<Order> listOrder = new List<Order>();
|
|
List<Kit> listKit = new List<Kit>();
|
|
List<Part> listPart = new List<Part>();
|
|
|
|
// leggo tab ORDINI da DB
|
|
var tblOrd = DLMan.taOL.getByBatch(BatchID);
|
|
// leggo tab KIT da DB
|
|
var tblKit = DLMan.taKL.getByBatch(BatchID);
|
|
// leggo tab ITEMS da DB
|
|
var tblItm = DLMan.taIL.getByBatch(BatchID);
|
|
|
|
// ciclo per comporre oggetto con cicli annidiati ext --> int
|
|
foreach (var rigaOrd in tblOrd)
|
|
{
|
|
listKit = new List<Kit>();
|
|
// compongo kit
|
|
var righeKit = (DS_App.KitListRow[])tblKit.Select($"OrdID = {rigaOrd.OrdID}");
|
|
foreach (var rigaKit in righeKit)
|
|
{
|
|
listPart = new List<Part>();
|
|
// elenco ITEMS
|
|
var righeItems = (DS_App.ItemListRow[])tblItm.Select($"KitID = {rigaKit.KitID}");
|
|
foreach (var rigaItem in righeItems)
|
|
{
|
|
currPart = new Part()
|
|
{
|
|
PartId = rigaItem.ItemID,
|
|
PartExtCode = rigaItem.ItemExtCode,
|
|
PartDtmx = rigaItem.ItemDtmx,
|
|
PartQty = rigaItem.ItemQty,
|
|
MatId = rigaItem.MatID,
|
|
CadFilePath = rigaItem.CadFilePath
|
|
};
|
|
listPart.Add(currPart);
|
|
}
|
|
// compongo KIT
|
|
currentKit = new Kit()
|
|
{
|
|
KitId = rigaKit.KitID,
|
|
KitExtCode = rigaKit.KitExtCode,
|
|
PartList = listPart
|
|
};
|
|
listKit.Add(currentKit);
|
|
}
|
|
// compongo ordine
|
|
currOrder = new Order()
|
|
{
|
|
OrderId = rigaOrd.OrdID,
|
|
OrderCod = rigaOrd.FamilyCode,
|
|
OrderExtCode = rigaOrd.OrderExtCode,
|
|
DestPlant = rigaOrd.DestPlant,
|
|
KitList = listKit
|
|
};
|
|
listOrder.Add(currOrder);
|
|
}
|
|
// oggetto complessivo
|
|
batchRequest newBatchreq = new batchRequest()
|
|
{
|
|
BatchId = BatchID,
|
|
EnvNum = nextEnv,
|
|
MaxTime = mTime,
|
|
ProcType = pType,
|
|
MachineType = mType.Multiax,
|
|
OrderType = oType.BatchRequest,
|
|
OrderList = listOrder,
|
|
NumIndexStart = numIndexStart,
|
|
CreatePng = createPng
|
|
};
|
|
|
|
// serializzo
|
|
string redVal = JsonConvert.SerializeObject(newBatchreq);
|
|
// salvo
|
|
string redKey = $"{redOutPath}:{nextEnv}";
|
|
// scrivo su REDIS
|
|
memLayer.ML.setRSV(redKey, redVal);
|
|
|
|
// invio notifica che c'è una busta da processare
|
|
currBatchReq = nextEnv;
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
Log.Instance.Info($"{logIdKey} | req completed | currBatchReq: {nextEnv}");
|
|
// restituisco ok
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Manda il primo batch di VALIDAZIONE al NESTING...
|
|
/// </summary>
|
|
/// <param name="createPng">indica se creare le PNG delle part validate</param>
|
|
/// <returns></returns>
|
|
public static bool sendFirstValidationBatch(bool createPng)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
bool answ = false;
|
|
// verifico se NON CI SIANO GIA' validazioni in corso...
|
|
var tabBatchRunning = DLMan.taBL.getByStatus(1, "", true, 0);
|
|
if (tabBatchRunning.Count == 0)
|
|
{
|
|
// ora verifico, se ci sono batch per FILE (dxf) VALIDATION in stato 8 (da validare)
|
|
// --> metto in coda!
|
|
DS_App.BatchListDataTable tabBatch = DLMan.taBL.getByStatus(8, "", true, 2);
|
|
// se non ne ho cerco nei PartValidation
|
|
if (tabBatch.Count == 0)
|
|
{
|
|
tabBatch = DLMan.taBL.getByStatus(8, "", true, 1);
|
|
}
|
|
if (tabBatch.Count > 0)
|
|
{
|
|
// invia a redis una richiesta...
|
|
sendMaterials();
|
|
// recupero PRIMO batchID da validare
|
|
int nextBatchId = 0;
|
|
try
|
|
{
|
|
nextBatchId = tabBatch[0].BatchID;
|
|
}
|
|
catch
|
|
{ }
|
|
if (nextBatchId > 0)
|
|
{
|
|
// richiedo!
|
|
sendBatchReq(nextBatchId, "Estimation", 1, true, 1, createPng);
|
|
// registro su DB nesting iniziato... QUANDO MI RISPONDE dovrò verificare
|
|
// che era un batch x VALIDAZIONE
|
|
DLMan.taBL.updateStatus(nextBatchId, (int)BatchStatus.EstimationRequested, "", 0);
|
|
answ = true;
|
|
}
|
|
}
|
|
}
|
|
// resituisco
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva su redis l'oggetto dei materiali serializzato
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public static bool sendMaterials()
|
|
{
|
|
bool answ = false;
|
|
// leggo tab MATERIALS da DB
|
|
DataLayer DLMan = new DataLayer();
|
|
var table = DLMan.taMat.GetData();
|
|
// serializzo
|
|
string redVal = JsonConvert.SerializeObject(table);
|
|
// salvo
|
|
string redKey = $"NKC:SERV:CONF:MATERIALS";
|
|
// scrivo per ora solo su REDIS
|
|
memLayer.ML.setRSV(redKey, redVal);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Invia una richiesta di esecuzione di CAM x un ordine offline
|
|
/// </summary>
|
|
/// <param name="OffOrderID">OfflineOrder di cui si chiede processing</param>
|
|
/// <param name="note">note opzionali</param>
|
|
/// <returns></returns>
|
|
public static bool sendOfflineOrderReq(int OffOrderID, string note)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
bool answ = false;
|
|
// per prima cosa mi serve una "nuova busta" per inviare i messaggi
|
|
string nextEnv = getNextEnv(OffOrderID, note);
|
|
// preparo il contenuto della busta ed invio i messaggi...
|
|
try
|
|
{
|
|
int mTime = 5;
|
|
// FIX pType a ESTIM
|
|
int pType = 1;
|
|
// ora ITEMS
|
|
var tblItm = DLMan.taIL.getByOfflineOrder(OffOrderID);
|
|
|
|
// init oggetti x fare cicli...
|
|
Order currOrder = null;
|
|
Kit currentKit = null;
|
|
Part currPart = null;
|
|
List<Order> listOrder = new List<Order>();
|
|
List<Kit> listKit = new List<Kit>();
|
|
List<Part> listPart = new List<Part>();
|
|
|
|
// elenco ITEMS
|
|
foreach (var rigaItem in tblItm)
|
|
{
|
|
currPart = new Part()
|
|
{
|
|
PartId = rigaItem.ItemID,
|
|
PartExtCode = rigaItem.ItemExtCode,
|
|
PartDtmx = rigaItem.ItemDtmx,
|
|
PartQty = rigaItem.ItemQty,
|
|
MatId = rigaItem.MatID,
|
|
CadFilePath = rigaItem.CadFilePath
|
|
};
|
|
listPart.Add(currPart);
|
|
}
|
|
// compongo KIT
|
|
currentKit = new Kit()
|
|
{
|
|
KitId = OffOrderID,
|
|
KitExtCode = $"OOK{OffOrderID:000000000}",
|
|
PartList = listPart
|
|
};
|
|
listKit.Add(currentKit);
|
|
|
|
// compongo ordine
|
|
currOrder = new Order()
|
|
{
|
|
OrderId = OffOrderID,
|
|
OrderCod = $"OFOR{OffOrderID:000000000}",
|
|
OrderExtCode = $"OFOR{OffOrderID:000000000}",
|
|
DestPlant = "00",
|
|
KitList = listKit
|
|
};
|
|
listOrder.Add(currOrder);
|
|
|
|
// ora versione gerarchica
|
|
batchRequest newBatchreq = new batchRequest()
|
|
{
|
|
BatchId = -OffOrderID,
|
|
EnvNum = nextEnv,
|
|
MaxTime = mTime,
|
|
ProcType = pType,
|
|
MachineType = mType.Offline,
|
|
OrderType = oType.OfflineOrder,
|
|
OrderList = listOrder
|
|
};
|
|
// serializzo
|
|
string redVal = JsonConvert.SerializeObject(newBatchreq);
|
|
// salvo
|
|
string redKey = $"{redOutPath}:{nextEnv}";
|
|
// scrivo su REDIS
|
|
memLayer.ML.setRSV(redKey, redVal);
|
|
|
|
// invio notifica che c'è una busta da processare
|
|
currBatchReq = nextEnv;
|
|
answ = true;
|
|
}
|
|
catch (Exception exc)
|
|
{
|
|
Log.Instance.Error($"Eccezione in sendOfflineOrderReq:{Environment.NewLine}{exc}");
|
|
}
|
|
// restituisco ok
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Helper x serializzare l'oggetto
|
|
/// </summary>
|
|
/// <param name="currData"></param>
|
|
/// <returns></returns>
|
|
public static string serializeTakt(Takt currData)
|
|
{
|
|
string answ = JsonConvert.SerializeObject(currData);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvataggio in redis del BunkID in lavorazione sulla macchina
|
|
/// </summary>
|
|
public static void setCurrBatchId(string macchina, int BatchID)
|
|
{
|
|
memLayer.ML.setRSV(redCurrBatchId(macchina), BatchID.ToString());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvataggio in redis del BunkID in lavorazione sulla macchina
|
|
/// </summary>
|
|
public static void setCurrBunkId(string macchina, int BunkID)
|
|
{
|
|
memLayer.ML.setRSV(redCurrBunkId(macchina), BunkID.ToString());
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvataggio in redis del SheetID in lavorazione sulla macchina
|
|
/// </summary>
|
|
public static void setCurrSheetId(string macchina, int SheetID)
|
|
{
|
|
memLayer.ML.setRSV(redCurrSheetId(macchina), SheetID.ToString());
|
|
}
|
|
|
|
public static bool setMachLiveStatus(string machine, bool isLive)
|
|
{
|
|
string redKey = $"{redProdMachStateLive}:{machine}";
|
|
string redVal = $"{isLive}";
|
|
// salvo x 90 sec
|
|
bool done = memLayer.ML.setRSV(redKey, redVal, 90);
|
|
return done;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva per 5 sec la richiesta di reload delle pagine MachineUnload
|
|
/// </summary>
|
|
public static void setReloadMU()
|
|
{
|
|
memLayer.ML.setRSV(redMachUnloadForce, "true", 5);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva su REDIS richiesta visualizzaizone SecondScreen x
|
|
/// </summary>
|
|
/// <param name="secScreenCode">cod schermo, formato SSC000000</param>
|
|
/// <param name="filePath">Path file richiesto (pdf)</param>
|
|
/// <param name="ttl_sec">durata in redis della richiesta</param>
|
|
/// <returns></returns>
|
|
public static bool setSecScreenRequest(string secScreenCode, string filePath, int ttl_sec)
|
|
{
|
|
bool answ = false;
|
|
// recupero ultima call
|
|
string redKey = $"{redSecScreenReq}:{secScreenCode}";
|
|
answ = memLayer.ML.setRSV(redKey, filePath, ttl_sec);
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupero dati sheet da Redis/DB
|
|
/// </summary>
|
|
public static DS_App.SheetListDataTable SheetTabGet(string Machine, int BatchId, int StMin, int StMax)
|
|
{
|
|
DS_App.SheetListDataTable answ = null;
|
|
string redKey = redCurrSheetTabKey(Machine, BatchId, StMin, StMax);
|
|
string rawData = memLayer.ML.getRSV(redKey);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
try
|
|
{
|
|
// deserializzo...
|
|
answ = JsonConvert.DeserializeObject<DS_App.SheetListDataTable>(rawData);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
else
|
|
{
|
|
// leggo DB
|
|
DataLayer DLMan = new DataLayer();
|
|
answ = DLMan.taSHL.getByMLStatus(BatchId, StMin, StMax, Machine);
|
|
rawData = JsonConvert.SerializeObject(answ);
|
|
// salvo in cache x 30 sec
|
|
memLayer.ML.setRSV(redKey, rawData, 30);
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Wrapper traduzione termini
|
|
/// </summary>
|
|
/// <param name="lemma"></param>
|
|
/// <returns></returns>
|
|
public static string traduci(string lemma)
|
|
{
|
|
return user_std.UtSn.Traduci(lemma);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aggiorna la POSITION del BATCH a aprtire dallo stato DI TUTTI i bunk 0 = not started, 1
|
|
/// = STACKS started, 2 = STACKS done, 3 = Current, 4 = Completed
|
|
/// </summary>
|
|
/// <param name="BatchID"></param>
|
|
/// <returns></returns>
|
|
public static void updateBatchPosition(int BatchID)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
// chiamo stored x checkPosition
|
|
DLMan.taBL.checkPosition(BatchID);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aggiorna la POSITION del BATCH a partire dallo stato dei bunk/stack selezionato 0 = not
|
|
/// started, 1 = STACKS started, 2 = STACKS done, 3 = Current, 4 = Completed
|
|
/// </summary>
|
|
/// <param name="BunkID"></param>
|
|
/// <returns></returns>
|
|
public static void updateBatchPositionByBunk(int BunkID)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
// recupero il BatchID
|
|
DS_App.StackListDataTable tabBunk = DLMan.taSTL.getByKey(BunkID);
|
|
if (tabBunk.Count > 0)
|
|
{
|
|
try
|
|
{
|
|
int BatchID = tabBunk[0].BatchID;
|
|
// chiamo procedura di check sull'intero bunk
|
|
updateBatchPosition(BatchID);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvo dati su PartList ricevuti da Nesting (COMPETATO)
|
|
/// </summary>
|
|
/// <param name="BatchID"></param>
|
|
/// <param name="BinList"></param>
|
|
public static void updateBinsFromNesting(int BatchID, List<NestBin> BinList)
|
|
{
|
|
Dictionary<string, string> part2update = new Dictionary<string, string>();
|
|
DataLayer DLMan = new DataLayer();
|
|
// inizio a processare... bunks!
|
|
if (BinList != null)
|
|
{
|
|
foreach (var item in BinList)
|
|
{
|
|
// creo il BIN!
|
|
object newBin = DLMan.taBN.insertAndReturn(item.BinIndex);
|
|
int BinID = 0;
|
|
bool valOk = int.TryParse(newBin.ToString(), out BinID);
|
|
// se ho un BIN in risposta...
|
|
if (valOk)
|
|
{
|
|
// processo sheets
|
|
if (item.PartList != null)
|
|
{
|
|
foreach (var part in item.PartList)
|
|
{
|
|
// creo lo sheet...
|
|
var newB2I = DLMan.taBNLS.insertAndReturn(BinID, part.PartId);
|
|
}
|
|
}
|
|
}
|
|
// verifico se aggiornare part
|
|
if (!part2update.ContainsKey(item.PartRev))
|
|
{
|
|
part2update.Add(item.PartRev, item.PartExtCode);
|
|
}
|
|
}
|
|
// verifico se ho part da aggiornare
|
|
if (part2update.Count > 0)
|
|
{
|
|
// recupero tabella parts in blocco da batch
|
|
var item4batch = DLMan.taIL.getByBatch(BatchID);
|
|
// chiamo stored x ogni esempio di part
|
|
foreach (var item in part2update)
|
|
{
|
|
var currItemList = item4batch.Where(x => x.ItemExtCode == item.Value).ToList();
|
|
if (currItemList != null && currItemList.Count > 0)
|
|
{
|
|
// processo!
|
|
foreach (var currPart in currItemList)
|
|
{
|
|
DLMan.taIL.updateExtCodeFromBinNesting(BatchID, item.Value, item.Key);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvo dati Bunks/Sheets/Parts ricevuti da Nesting (COMPETATO)
|
|
/// </summary>
|
|
/// <param name="BatchID"></param>
|
|
/// <param name="BunkList"></param>
|
|
public static void updateBunksFromNesting(int BatchID, List<NestBunk> BunkList)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
// inizio a processare... bunks!
|
|
if (BunkList != null)
|
|
{
|
|
foreach (var bunk in BunkList)
|
|
{
|
|
// creo il BUNK!
|
|
var newBunk = DLMan.taSTL.insertAndReturn(bunk.BunkIndex, BatchID);
|
|
// se ho un bunk in risposta...
|
|
if (newBunk.Count == 1)
|
|
{
|
|
var currBunk = newBunk[0];
|
|
// processo sheets
|
|
if (bunk.SheetList != null)
|
|
{
|
|
foreach (var sheet in bunk.SheetList)
|
|
{
|
|
// creo lo sheet...
|
|
var newSheet = DLMan.taSHL.insertAndReturn(sheet.SheetIndex, sheet.MatId, (decimal)sheet.EstimatedWorktime, currBunk.StackID, sheet.PrintProgram, sheet.MachiningProgram, sheet.Drawing);
|
|
// se ho 1 sheet in risposta
|
|
if (newSheet.Count == 1)
|
|
{
|
|
var currSheet = newSheet[0];
|
|
// processo items!
|
|
if (sheet.PartList != null)
|
|
{
|
|
foreach (var part in sheet.PartList)
|
|
{
|
|
// aggiungo part a sheet (in tab nesting)
|
|
DLMan.taNest.insertAndReturn(currSheet.SheetID, part.PartId);
|
|
}
|
|
}
|
|
// ora salvo ANCHE i remnants dello sheet... SE ci sono
|
|
if (sheet.Remnant != null)
|
|
{
|
|
DLMan.taRem.insertAndReturn(BatchID, sheet.MatId, currSheet.SheetID, sheet.Remnant.L_mm, sheet.Remnant.W_mm, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvo dati su PartList ricevuti da Nesting (COMPETATO)
|
|
/// </summary>
|
|
/// <param name="BatchID"></param>
|
|
/// <param name="CartList"></param>
|
|
public static void updateCartsFromNesting(int BatchID, List<NestCart> CartList)
|
|
{
|
|
Dictionary<string, int> part2update = new Dictionary<string, int>();
|
|
DataLayer DLMan = new DataLayer();
|
|
// inizio a processare... bunks!
|
|
if (CartList != null)
|
|
{
|
|
foreach (var item in CartList)
|
|
{
|
|
// creo il CART!
|
|
var newCart = DLMan.taCR.insertAndReturn(item.CartIndex);
|
|
// se ho un CART in risposta...
|
|
if (newCart.Count == 1)
|
|
{
|
|
var currCart = newCart[0];
|
|
// processo sheets
|
|
if (item.KitList != null)
|
|
{
|
|
foreach (var kit in item.KitList)
|
|
{
|
|
// creo lo sheet...
|
|
var updKit = DLMan.taKL.updateCart(kit.KitId, currCart.CartID);
|
|
// verifico x update PartExtCode
|
|
addPart2Upd(ref part2update, kit.PartList);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// verifico se ho part da aggiornare
|
|
if (part2update.Count > 0)
|
|
{
|
|
// recupero tabella parts in blocco da batch
|
|
var item4batch = DLMan.taIL.getByBatch(BatchID);
|
|
// chiamo stored x ogni esempio di part
|
|
foreach (var item in part2update)
|
|
{
|
|
var currItem = item4batch.Where(x => x.ItemID == item.Value).FirstOrDefault();
|
|
// verifico SE sia da processare...
|
|
if (currItem != null && currItem.ItemExtCode != item.Key)
|
|
{
|
|
DLMan.taIL.updateExtCodeFromNesting(BatchID, item.Value, item.Key);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processa elenco items e salva in redis valori x css, elenchi, ...
|
|
/// </summary>
|
|
/// <param name="currCss">CSS corrente</param>
|
|
/// <param name="redKeyBase">HASH abse x area REDIS</param>
|
|
/// <param name="varName">nome variabile x elenco items</param>
|
|
/// <param name="itemList">Elenco items specifici</param>
|
|
/// <param name="dataCacheTTL">TTL della cache x salvataggio valori</param>
|
|
/// <returns></returns>
|
|
public static string updateCssByItemList(string currCss, string redKeyBase, string varName, List<string> itemList, int dataCacheTTL)
|
|
{
|
|
string replaceVal = "";
|
|
if (itemList.Count > 0)
|
|
{
|
|
foreach (var item in itemList)
|
|
{
|
|
replaceVal += $"#{item},";
|
|
}
|
|
if (replaceVal.Length > 1)
|
|
{
|
|
replaceVal = replaceVal.Remove(replaceVal.Length - 1);
|
|
}
|
|
// FIX CSS!
|
|
currCss = currCss.Replace($"#{varName}", replaceVal);
|
|
//serializzo e salvo
|
|
string serVal = JsonConvert.SerializeObject(itemList);
|
|
memLayer.ML.setRSV($"{redKeyBase}:{varName}", serVal, dataCacheTTL);
|
|
}
|
|
return currCss;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Processa elenco items e salva in redis valori x css, elenchi, ...
|
|
/// </summary>
|
|
/// <param name="currCss">CSS corrente</param>
|
|
/// <param name="redKeyBase">HASH abse x area REDIS</param>
|
|
/// <param name="varName">nome variabile x elenco items</param>
|
|
/// <param name="dataCacheTTL">TTL della cache x salvataggio valori</param>
|
|
/// <returns></returns>
|
|
public static string updateCssByPickedItems(string currCss, string redKeyBase, string varName, int dataCacheTTL)
|
|
{
|
|
string replaceVal = "";
|
|
string rawData = memLayer.ML.getRSV($"{redKeyBase}:ItemsSel");
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
try
|
|
{
|
|
Dictionary<string, string> dictData = JsonConvert.DeserializeObject<Dictionary<string, string>>(rawData);
|
|
// ciclo x cercare x ogni chiave (sessione utente)
|
|
foreach (var item in dictData)
|
|
{
|
|
replaceVal += $"#{item.Value},";
|
|
}
|
|
if (replaceVal.Length > 1)
|
|
{
|
|
replaceVal = replaceVal.Remove(replaceVal.Length - 1);
|
|
}
|
|
// FIX CSS!
|
|
currCss = currCss.Replace("#ItemsSel", replaceVal);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return currCss;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvo dati di OrderId ricevuti da Nesting (stima)
|
|
/// </summary>
|
|
/// <param name="PartList"></param>
|
|
public static void updateExtEstimFromNesting(int BatchId, List<OrderPrev> OrdExtList)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
// svuoto x batch...
|
|
DLMan.taOLT.deleteByBatch(BatchId);
|
|
// salvo elenco materiali x ogni item...
|
|
foreach (var currItem in OrdExtList)
|
|
{
|
|
// tempo in sec --> divido 60
|
|
DLMan.taOLT.insert(BatchId, BatchId, currItem.OrderId, currItem.OrderExtCode, currItem.NumBin, currItem.NumCart, currItem.NumPart, (currItem.TotTime / 60));
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvo dati su PartList ricevuti da Nesting (stima)
|
|
/// </summary>
|
|
/// <param name="PartList"></param>
|
|
public static void updatePartsFromNesting(List<Part> PartList)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
string PostProcList = "";
|
|
string ProcessesReq = "";
|
|
string pdfFilePath = "";
|
|
// salvo elenco materiali x ogni item...
|
|
foreach (Part currItem in PartList)
|
|
{
|
|
// calcolo parametri...
|
|
PostProcList = getPostProcList(currItem.OptParameters);
|
|
ProcessesReq = getProcessesReq(currItem.OptParameters);
|
|
pdfFilePath = getPdfFilePath(currItem.OptParameters);
|
|
DLMan.taIL.updateFromNesting(currItem.PartId, currItem.MatId, PostProcList, ProcessesReq, pdfFilePath);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fornisce un dictionary di valori ATTUALI per una specifica macchina
|
|
/// </summary>
|
|
/// <param name="machineCod"></param>
|
|
/// <returns></returns>
|
|
public Dictionary<string, string> getCurrMachineData(string machineCod)
|
|
{
|
|
Dictionary<string, string> answ = new Dictionary<string, string>();
|
|
// cerco in REDIS
|
|
string rawData = memLayer.ML.getRSV(machineArea(machineCod));
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
answ = JsonConvert.DeserializeObject<Dictionary<string, string>>(rawData);
|
|
}
|
|
else
|
|
{
|
|
// recupero batch e sheet...
|
|
int batchId = getNextBatch(machineCod);
|
|
// se non trovo creo un oggetto NUOVO e vuoto x ogni oggetto... e salvo...
|
|
answ.Add("BatchID", batchId.ToString());
|
|
answ.Add("SheetID_load", getSheetIdByBatch(batchId, 0, 1, machineCod).ToString());
|
|
answ.Add("SheetID_print", getSheetIdByBatch(batchId, 1, 2, machineCod).ToString());
|
|
answ.Add("SheetID_work", getSheetIdByBatch(batchId, 2, 3, machineCod).ToString());
|
|
answ.Add("SheetID_unload", getSheetIdByBatch(batchId, 3, 5, machineCod).ToString());
|
|
// serializzo e salvo!
|
|
saveMachineData(machineCod, answ);
|
|
}
|
|
// restituisco!
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupero risposta stima salvata
|
|
/// </summary>
|
|
/// <param name="BatchID"></param>
|
|
/// <returns></returns>
|
|
public nestReplyBatchInitial getEstAnsw(int BatchID)
|
|
{
|
|
nestReplyBatchInitial answ = null;
|
|
try
|
|
{
|
|
// definisco filtro
|
|
var filtBuilder = Builders<nestReplyBatchInitial>.Filter;
|
|
var filter = filtBuilder.Eq<int>("BatchID", BatchID);
|
|
var collRawData = database.GetCollection<nestReplyBatchInitial>("EstimationArchive");
|
|
// recupero
|
|
answ = collRawData.Find(filter).Project<nestReplyBatchInitial>("{_id: 0}").FirstOrDefault<nestReplyBatchInitial>();
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupero risposta stima ESTESA salvata
|
|
/// </summary>
|
|
/// <param name="BatchID"></param>
|
|
/// <returns></returns>
|
|
public nestReplyBatchExtEst getExtEstAnsw(int BatchID)
|
|
{
|
|
nestReplyBatchExtEst answ = null;
|
|
try
|
|
{
|
|
// definisco filtro
|
|
var filtBuilder = Builders<nestReplyBatchExtEst>.Filter;
|
|
var filter = filtBuilder.Eq<int>("BatchID", BatchID);
|
|
var collRawData = database.GetCollection<nestReplyBatchExtEst>("ExtendedEstimationArchive");
|
|
// recupero
|
|
answ = collRawData.Find(filter).Project<nestReplyBatchExtEst>("{_id: 0}").FirstOrDefault<nestReplyBatchExtEst>();
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupero risposta nesting salvata
|
|
/// </summary>
|
|
/// <param name="BatchID"></param>
|
|
/// <returns></returns>
|
|
public nestReplyBatchFinal getNestAnsw(int BatchID)
|
|
{
|
|
nestReplyBatchFinal answ = null;
|
|
try
|
|
{
|
|
// definisco filtro
|
|
var filtBuilder = Builders<nestReplyBatchFinal>.Filter;
|
|
var filter = filtBuilder.Eq<int>("BatchID", BatchID);
|
|
FindOptions opz = new FindOptions { ShowRecordId = false };
|
|
var collRawData = database.GetCollection<nestReplyBatchFinal>("NestingArchive");
|
|
// recupero
|
|
answ = collRawData.Find(filter).Project<nestReplyBatchFinal>("{_id: 0}").FirstOrDefault<nestReplyBatchFinal>();
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elimina da tutti archivi MongoDB i dati relativi ad un dato EnvNum
|
|
/// </summary>
|
|
/// <param name="EnvNum">Stringa EnvNum da eliminare</param>
|
|
/// <returns></returns>
|
|
public bool MongoDeleteEnvData(string EnvNum)
|
|
{
|
|
bool answ = false;
|
|
bool okEstArch = MongoEstArchDeleteEnvData(EnvNum);
|
|
bool okExtEstArch = MongoExtEstArchDeleteEnvData(EnvNum);
|
|
bool okNestArch = MongoNestArchDeleteEnvData(EnvNum);
|
|
bool okOfflArch = MongoOffArchDeleteEnvData(EnvNum);
|
|
answ = okEstArch || okExtEstArch || okNestArch || okOfflArch;
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elimina da EstimationArchive MongoDB i dati relativi ad un dato EnvNum
|
|
/// </summary>
|
|
/// <param name="EnvNum">Stringa EnvNum da eliminare</param>
|
|
/// <returns></returns>
|
|
public bool MongoEstArchDeleteEnvData(string EnvNum)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
// definisco filtro
|
|
var filtBuilder = Builders<nestReplyBatchInitial>.Filter;
|
|
var filter = filtBuilder.Eq<string>("EnvNum", EnvNum);
|
|
var collRawData = database.GetCollection<nestReplyBatchInitial>("EstimationArchive");
|
|
// elimino old
|
|
collRawData.DeleteMany(filter);
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elimina da EstimationArchive MongoDB i dati relativi ad un dato EnvNum
|
|
/// </summary>
|
|
/// <param name="EnvNum">Stringa EnvNum da eliminare</param>
|
|
/// <returns></returns>
|
|
public bool MongoExtEstArchDeleteEnvData(string EnvNum)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
// definisco filtro
|
|
var filtBuilder = Builders<nestReplyBatchExtEst>.Filter;
|
|
var filter = filtBuilder.Eq<string>("EnvNum", EnvNum);
|
|
var collRawData = database.GetCollection<nestReplyBatchExtEst>("ExtendedEstimationArchive");
|
|
// elimino old
|
|
collRawData.DeleteMany(filter);
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elimina da EstimationArchive MongoDB i dati relativi ad un dato EnvNum
|
|
/// </summary>
|
|
/// <param name="EnvNum">Stringa EnvNum da eliminare</param>
|
|
/// <returns></returns>
|
|
public bool MongoNestArchDeleteEnvData(string EnvNum)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
// definisco filtro
|
|
var filtBuilder = Builders<nestReplyBatchFinal>.Filter;
|
|
var filter = filtBuilder.Eq<string>("EnvNum", EnvNum);
|
|
var collRawData = database.GetCollection<nestReplyBatchFinal>("NestingArchive");
|
|
// elimino old
|
|
collRawData.DeleteMany(filter);
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elimina da EstimationArchive MongoDB i dati relativi ad un dato EnvNum
|
|
/// </summary>
|
|
/// <param name="EnvNum">Stringa EnvNum da eliminare</param>
|
|
/// <returns></returns>
|
|
public bool MongoOffArchDeleteEnvData(string EnvNum)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
// definisco filtro
|
|
var filtBuilder = Builders<nestReplyOffOrd>.Filter;
|
|
var filter = filtBuilder.Eq<string>("EnvNum", EnvNum);
|
|
var collRawData = database.GetCollection<nestReplyOffOrd>("OfflineArchive");
|
|
// elimino old
|
|
collRawData.DeleteMany(filter);
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fornisce il prossimo TAKT da elaborare oppure null se non ce ne fossero altri da
|
|
/// elaborare per la data CORRENTE
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public Takt prodGetNextTakt()
|
|
{
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Svuota elenco pezzi nella postazione di unload
|
|
/// </summary>
|
|
/// <param name="SheetID"></param>
|
|
/// <returns></returns>
|
|
public bool resetSheetUnload(int SheetID = 0)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
memLayer.ML.redFlushKey(machineUnloadArea(SheetID));
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva una risposta ricevuta x STIMA
|
|
/// </summary>
|
|
/// <param name="nestAnsw">Stringa della risposta JSON ricevuta dal nesting</param>
|
|
/// <returns></returns>
|
|
public bool saveEstAnsw(nestReplyBatchInitial nestAnsw)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
// definisco filtro
|
|
var filtBuilder = Builders<nestReplyBatchInitial>.Filter;
|
|
var filter = filtBuilder.Eq<int>("BatchID", nestAnsw.BatchID);
|
|
var collRawData = database.GetCollection<nestReplyBatchInitial>("EstimationArchive");
|
|
// elimino old
|
|
collRawData.DeleteMany(filter);
|
|
// aggiungo
|
|
collRawData.InsertOne(nestAnsw);
|
|
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva una risposta ricevuta x STIMA ESTESA
|
|
/// </summary>
|
|
/// <param name="nestAnsw">Stringa della risposta JSON ricevuta dal nesting</param>
|
|
/// <returns></returns>
|
|
public bool saveExtEstAnsw(nestReplyBatchExtEst nestAnsw)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
// definisco filtro
|
|
var filtBuilder = Builders<nestReplyBatchExtEst>.Filter;
|
|
var filter = filtBuilder.Eq<int>("BatchID", nestAnsw.BatchID);
|
|
var collRawData = database.GetCollection<nestReplyBatchExtEst>("ExtendedEstimationArchive");
|
|
// elimino old
|
|
collRawData.DeleteMany(filter);
|
|
// aggiungo
|
|
collRawData.InsertOne(nestAnsw);
|
|
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvataggio array dati di una macchina
|
|
/// </summary>
|
|
/// <param name="machineCod"></param>
|
|
/// <param name="paramsArray"></param>
|
|
/// <returns></returns>
|
|
public bool saveMachineData(string machineCod, Dictionary<string, string> paramsArray)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
// serializzo e salvo!
|
|
string rawData = JsonConvert.SerializeObject(paramsArray);
|
|
memLayer.ML.setRSV(machineArea(machineCod), rawData);
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
// restituisco!
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fornisce un dictionary di valori ATTUALI per una specifica macchina
|
|
/// </summary>
|
|
/// <param name="machineCod"></param>
|
|
/// <param name="Key"></param>
|
|
/// <param name="Val"></param>
|
|
/// <returns></returns>
|
|
public bool saveMachineParam(string machineCod, string Key, string Val)
|
|
{
|
|
bool answ = false;
|
|
// recupero i dati
|
|
try
|
|
{
|
|
var currData = getCurrMachineData(machineCod);
|
|
// aggiorno il record
|
|
if (currData.ContainsKey(Key))
|
|
{
|
|
currData[Key] = Val;
|
|
}
|
|
// oppure aggiungo...
|
|
else
|
|
{
|
|
currData.Add(Key, Val);
|
|
}
|
|
// salvo...
|
|
saveMachineData(machineCod, currData);
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva una risposta ricevuta x NESTING
|
|
/// </summary>
|
|
/// <param name="nestAnsw">Stringa della risposta JSON ricevuta dal nesting</param>
|
|
/// <returns></returns>
|
|
public bool saveNestAnsw(nestReplyBatchFinal nestAnsw)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
// definisco filtro
|
|
var filtBuilder = Builders<nestReplyBatchFinal>.Filter;
|
|
var filter = filtBuilder.Eq<int>("BatchID", nestAnsw.BatchID);
|
|
var collRawData = database.GetCollection<nestReplyBatchFinal>("NestingArchive");
|
|
// elimino old
|
|
collRawData.DeleteMany(filter);
|
|
// aggiungo
|
|
collRawData.InsertOne(nestAnsw);
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva una risposta ricevuta x OfflineOrder
|
|
/// </summary>
|
|
/// <param name="offOrdAnsw">Stringa della risposta JSON ricevuta dal nesting</param>
|
|
/// <returns></returns>
|
|
public bool saveOffOrdAnsw(nestReplyOffOrd offOrdAnsw)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
// definisco filtro
|
|
var filtBuilder = Builders<nestReplyOffOrd>.Filter;
|
|
var filter = filtBuilder.Eq<int>("BatchID", offOrdAnsw.BatchID);
|
|
var collRawData = database.GetCollection<nestReplyOffOrd>("OfflineArchive");
|
|
// elimino old
|
|
collRawData.DeleteMany(filter);
|
|
// aggiungo
|
|
collRawData.InsertOne(offOrdAnsw);
|
|
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva una risposta ricevuta dal PROD
|
|
/// </summary>
|
|
/// <param name="prodAnsw">Stringa della risposta JSON ricevuta dal PROD</param>
|
|
/// <returns></returns>
|
|
public bool saveProdAnsw(SheetWorkList prodAnsw)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
// definisco filtro
|
|
var filtBuilder = Builders<SheetWorkList>.Filter;
|
|
// filtro vuoto x svuotare sempre
|
|
var filter = filtBuilder.Empty;
|
|
var collRawData = database.GetCollection<SheetWorkList>("ProdArchive");
|
|
// elimino old (TUTTI!!!)
|
|
collRawData.DeleteMany(filter);
|
|
// aggiungo
|
|
collRawData.InsertOne(prodAnsw);
|
|
// fatto!
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salva una risposta ricevuta x OfflineOrder
|
|
/// </summary>
|
|
/// <param name="offOrdAnsw">Stringa della risposta JSON ricevuta dal nesting</param>
|
|
/// <returns></returns>
|
|
public bool saveProdStat(MachineStatData offOrdAnsw)
|
|
{
|
|
bool answ = false;
|
|
try
|
|
{
|
|
// definisco filtro
|
|
var filtBuilder = Builders<nestReplyOffOrd>.Filter;
|
|
#if false
|
|
//var filter = filtBuilder.Eq<int>("BatchID", offOrdAnsw.BatchID);
|
|
#endif
|
|
var collRawData = database.GetCollection<MachineStatData>("ProdStat");
|
|
// elimino old
|
|
#if false
|
|
//collRawData.DeleteMany(filter);
|
|
#endif
|
|
// aggiungo
|
|
collRawData.InsertOne(offOrdAnsw);
|
|
|
|
answ = true;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Effettua il ricalcolo delle statistiche x SheetStat --> BatchStat dato un BatchID
|
|
/// recuperando i dati da MongoDB
|
|
/// </summary>
|
|
/// <param name="BatchID"></param>
|
|
/// <returns></returns>
|
|
public bool updateSheetStatsByBatch(int BatchID)
|
|
{
|
|
bool answ = false;
|
|
DataLayer DLMan = new DataLayer();
|
|
List<int> PaintPartList = new List<int>();
|
|
|
|
// cerco da lista salvataggi Estim/Nest...
|
|
var nestAnsw = getNestAnsw(BatchID);
|
|
if (nestAnsw != null)
|
|
{
|
|
// inizio eliminando le vecchie statistiche x foglio
|
|
DLMan.taShStats.resetBatch(BatchID);
|
|
|
|
// recupero i pitturati
|
|
try
|
|
{
|
|
if (nestAnsw.BinList != null)
|
|
{
|
|
foreach (var bin in nestAnsw.BinList)
|
|
{
|
|
// se ho parti le aggiungo
|
|
if (bin.PartList != null)
|
|
{
|
|
foreach (var Part in bin.PartList)
|
|
{
|
|
PaintPartList.Add(Part.PartId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
|
|
// il tot delle part è in bunk > Sheet > part
|
|
try
|
|
{
|
|
if (nestAnsw.BunkList != null)
|
|
{
|
|
int sheetIdx = 0;
|
|
foreach (var bunk in nestAnsw.BunkList)
|
|
{
|
|
foreach (var sheet in bunk.SheetList)
|
|
{
|
|
// incremento contatore sheets
|
|
sheetIdx++;
|
|
// dati resa superfici
|
|
double num = sheet.SurfaceWork > 0 ? sheet.SurfaceWork : 0;
|
|
double den = sheet.SurfaceTotal > 0 ? sheet.SurfaceTotal : 1;
|
|
// parts del foglio
|
|
List<int> PartList = sheet.PartList.Select(x => x.PartId).ToList();
|
|
int numPaint = PartList.Intersect(PaintPartList).Count();
|
|
|
|
// qui salvo le statistiche
|
|
DLMan.taShStats.upsertQuery(BatchID, sheetIdx, sheet.MatId, (decimal)num, (decimal)den, sheet.PartList.Count, numPaint);
|
|
//DLMan.taShStats.upsertQuery(BatchID, sheet.SheetIndex, sheet.MatId, (decimal)num, (decimal)den, sheet.PartList.Count, numPaint);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
// finisco calcolando le statistiche x Batch...
|
|
DLMan.taBStats.refresh(BatchID);
|
|
}
|
|
|
|
return answ;
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Public Classes
|
|
|
|
public class Parte
|
|
{
|
|
#region Public Properties
|
|
|
|
public string CadFilePath { get; set; }
|
|
public string DataMatrix { get; set; }
|
|
public string Description { get; set; }
|
|
public string ExtCode { get; set; }
|
|
public int MatId { get; set; }
|
|
public int PartId { get; set; }
|
|
public string PostProc { get; set; }
|
|
public string ProcessReq { get; set; }
|
|
public int Qty { get; set; }
|
|
|
|
#endregion Public Properties
|
|
}
|
|
|
|
/// <summary>
|
|
/// Oggetto globale TAKT
|
|
/// </summary>
|
|
public class Takt
|
|
{
|
|
#region Public Properties
|
|
|
|
/// <summary>
|
|
/// Numero di Stack da lavorare
|
|
/// </summary>
|
|
public int NumStack
|
|
{
|
|
get
|
|
{
|
|
int answ = 0;
|
|
try
|
|
{
|
|
answ = StackList.Count;
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Elenco degli Stack da lavorare
|
|
/// </summary>
|
|
public List<ProdBunk> StackList { get; set; }
|
|
|
|
/// <summary>
|
|
/// Stato del TAKT
|
|
/// </summary>
|
|
public CStatus Status { get; set; }
|
|
|
|
/// <summary>
|
|
/// Codice univoco oggetto TAKT (data.num)
|
|
/// </summary>
|
|
public string TaktId { get; set; }
|
|
|
|
#endregion Public Properties
|
|
}
|
|
|
|
#endregion Public Classes
|
|
|
|
#region Protected Fields
|
|
|
|
/// <summary>
|
|
/// Chiave primo bunk su redis
|
|
/// </summary>
|
|
protected static string redAllNextBunkKey = $"{redProdReq}:NextBunk";
|
|
|
|
/// <summary>
|
|
/// Chiave primo bunk su redis
|
|
/// </summary>
|
|
protected static string redFirstBunkKey = $"{redProdReq}:FirstBunk";
|
|
|
|
/// <summary>
|
|
/// TTL standard x dati da scambiare con PROD (30 gg)
|
|
/// </summary>
|
|
protected static int ttlProdData = 3600 * 24 * 30;
|
|
|
|
#endregion Protected Fields
|
|
|
|
#region Protected Methods
|
|
|
|
/// <summary>
|
|
/// lettura currBunk table da cache
|
|
/// </summary>
|
|
/// <param name="machine"></param>
|
|
/// <returns></returns>
|
|
protected static DS_App.StackListDataTable getCurrBunkTab(string machine)
|
|
{
|
|
DS_App.StackListDataTable answ = null;
|
|
string rawData = memLayer.ML.getRSV(redCurrBunkTabKey(machine));
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
try
|
|
{
|
|
// deserializzo...
|
|
answ = JsonConvert.DeserializeObject<DS_App.StackListDataTable>(rawData);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupero da redis tab fogli correnti (5:5)
|
|
/// </summary>
|
|
protected static DS_App.SheetListDataTable getCurrSheetTab(string machine)
|
|
{
|
|
DS_App.SheetListDataTable answ = null;
|
|
string rawData = memLayer.ML.getRSV(redCurrSheetTabKey(machine));
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
try
|
|
{
|
|
// deserializzo...
|
|
answ = JsonConvert.DeserializeObject<DS_App.SheetListDataTable>(rawData);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Chiave BATCH corrente su redis
|
|
/// </summary>
|
|
/// <param name="machine"></param>
|
|
/// <returns></returns>
|
|
protected static string redCurrBatchId(string machine)
|
|
{
|
|
string answ = "";
|
|
if (string.IsNullOrEmpty(machine))
|
|
{
|
|
answ = $"{redProdReq}:CurrBatchID";
|
|
}
|
|
else
|
|
{
|
|
answ = $"{redProdReq}:CurrBatchID:{machine}";
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Chiave Bunk corrente su redis
|
|
/// </summary>
|
|
/// <param name="machine"></param>
|
|
/// <returns></returns>
|
|
protected static string redCurrBunkId(string machine)
|
|
{
|
|
string answ = "";
|
|
if (string.IsNullOrEmpty(machine))
|
|
{
|
|
answ = $"{redProdReq}:CurrBunkID";
|
|
}
|
|
else
|
|
{
|
|
answ = $"{redProdReq}:CurrBunkID:{machine}";
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Chiave bunk corrente su redis
|
|
/// </summary>
|
|
/// <param name="machine"></param>
|
|
/// <returns></returns>
|
|
protected static string redCurrBunkTabKey(string machine)
|
|
{
|
|
string answ = "";
|
|
if (string.IsNullOrEmpty(machine))
|
|
{
|
|
answ = $"{redProdReq}:CurrBunks";
|
|
}
|
|
else
|
|
{
|
|
answ = $"{redProdReq}:CurrBunks:{machine}";
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Chiave Sheets corrente su redis
|
|
/// </summary>
|
|
/// <param name="machine"></param>
|
|
/// <returns></returns>
|
|
protected static string redCurrSheetId(string machine)
|
|
{
|
|
string answ = "";
|
|
if (string.IsNullOrEmpty(machine))
|
|
{
|
|
answ = $"{redProdReq}:CurrSheetID";
|
|
}
|
|
else
|
|
{
|
|
answ = $"{redProdReq}:CurrSheetID:{machine}";
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Chiave sheets correnti su redis
|
|
/// </summary>
|
|
/// <param name="machine"></param>
|
|
/// <returns></returns>
|
|
protected static string redCurrSheetTabKey(string machine)
|
|
{
|
|
string answ = "";
|
|
if (string.IsNullOrEmpty(machine))
|
|
{
|
|
answ = $"{redProdReq}:CurrSheets";
|
|
}
|
|
else
|
|
{
|
|
answ = $"{redProdReq}:CurrSheets:{machine}";
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary> Chiave sheets correnti su redis </summary> <param name="Machine"></param>
|
|
/// <param name="BatchId">BatchId, se fosse <= 0 --> chiave parent utile x reset</param>
|
|
/// <param name="StMin"></param> <param name="StMax"></param> <returns></returns>
|
|
protected static string redCurrSheetTabKey(string Machine, int BatchId, int StMin, int StMax)
|
|
{
|
|
string answ = "";
|
|
if (BatchId > 0)
|
|
{
|
|
answ = $"{redProdReq}:SheetByMBS:{Machine}:{BatchId}:{StMin}:{StMax}";
|
|
}
|
|
else
|
|
{
|
|
answ = $"{redProdReq}:SheetByMBS:{Machine}";
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Chiave primo bunk su redis
|
|
/// </summary>
|
|
protected static string redNextBunkKey(int BunkID)
|
|
{
|
|
return $"{redProdReq}:NextBunk:{BunkID}";
|
|
}
|
|
|
|
/// <summary>
|
|
/// salvataggio inc ache currBunk table
|
|
/// </summary>
|
|
/// <param name="machine"></param>
|
|
/// <param name="tabBunks"></param>
|
|
protected static void setCurrBunkTab(string machine, DS_App.StackListDataTable tabBunks)
|
|
{
|
|
string rawData = JsonConvert.SerializeObject(tabBunks);
|
|
// TTL 15 sec
|
|
memLayer.ML.setRSV(redCurrBunkTabKey(machine), rawData, 15);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvataggio in redis tab fogli correnti
|
|
/// </summary>
|
|
/// <param name="machine"></param>
|
|
/// <param name="tabella"></param>
|
|
protected static void setCurrSheetTab(string machine, DS_App.SheetListDataTable tabella)
|
|
{
|
|
string rawData = JsonConvert.SerializeObject(tabella);
|
|
// TTL 1 sec
|
|
memLayer.ML.setRSV(redCurrSheetTabKey(machine), rawData, 1);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera prossimo batch da DB (NEXT... da db x status...)
|
|
/// </summary>
|
|
protected int getNextBatch(string PlaceCod)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
int answ = 0;
|
|
try
|
|
{
|
|
var currData = DLMan.taBL.getNextAvailable(PlaceCod);
|
|
if (currData.Count > 0)
|
|
{
|
|
answ = currData[0].BatchID;
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera PRIMO SHEET da batch e stati permessi...
|
|
/// </summary>
|
|
/// <param name="BatchID"></param>
|
|
/// <param name="minVal"></param>
|
|
/// <param name="maxVal"></param>
|
|
/// <param name="machine"></param>
|
|
/// <returns></returns>
|
|
protected int getSheetIdByBatch(int BatchID, int minVal, int maxVal, string machine)
|
|
{
|
|
int answ = 0;
|
|
if (BatchID > 0 && !string.IsNullOrEmpty(machine))
|
|
{
|
|
try
|
|
{
|
|
// 2023.10.27 passaggio versione cached
|
|
#if false
|
|
DataLayer DLMan = new DataLayer();
|
|
var tabSheet = DLMan.taSHL.getByMLStatus(BatchID, minVal, maxVal, machine);
|
|
#endif
|
|
var tabSheet = SheetTabGet(machine, BatchID, minVal, maxVal);
|
|
if (tabSheet.Count > 0)
|
|
{
|
|
answ = tabSheet[0].SheetID;
|
|
}
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
#endregion Protected Methods
|
|
|
|
#region Private Fields
|
|
|
|
/// <summary>
|
|
/// Database corrente MongoDB
|
|
/// </summary>
|
|
private IMongoDatabase database;
|
|
|
|
#endregion Private Fields
|
|
|
|
#region Private Properties
|
|
|
|
/// <summary>
|
|
/// Cache redis del PRIMO bunk da lavorare
|
|
/// </summary>
|
|
private static ProdBunk redisFirstBunk
|
|
{
|
|
get
|
|
{
|
|
ProdBunk answ = null;
|
|
string rawData = memLayer.ML.getRSV(redFirstBunkKey);
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
// provo a deserializzare
|
|
try
|
|
{
|
|
answ = JsonConvert.DeserializeObject<ProdBunk>(rawData);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return answ;
|
|
}
|
|
set
|
|
{
|
|
if (value != null)
|
|
{
|
|
string redVal = JsonConvert.SerializeObject(value);
|
|
// default lascio x 5 minuti...
|
|
memLayer.ML.setRSV(redFirstBunkKey, redVal, ttlProdData);
|
|
}
|
|
else
|
|
// se null elimino da redis
|
|
{
|
|
memLayer.ML.setRSV(redFirstBunkKey, "");
|
|
// elimino TUTTI i next...
|
|
memLayer.ML.redFlushKey(redAllNextBunkKey);
|
|
// imposto force reload UNLOAD
|
|
setReloadMU();
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion Private Properties
|
|
|
|
#region Private Methods
|
|
|
|
/// <summary>
|
|
/// Verifica ed eventualmente aggiunge part da aggiornare all'elenco
|
|
/// </summary>
|
|
/// <param name="part2update"></param>
|
|
/// <param name="partList"></param>
|
|
private static void addPart2Upd(ref Dictionary<string, int> part2update, List<Part> partList)
|
|
{
|
|
foreach (var item in partList)
|
|
{
|
|
if (!part2update.ContainsKey(item.PartRev))
|
|
{
|
|
part2update.Add(item.PartRev, item.PartId);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// verifica che la macchina dichiarata esiste o la crea...
|
|
/// </summary>
|
|
/// <param name="machine"></param>
|
|
private static void checkPlace(string machine)
|
|
{
|
|
DS_App.PlacesDataTable tabPlace = new DS_App.PlacesDataTable();
|
|
DataLayer DLMan = new DataLayer();
|
|
// cerco in Redis...
|
|
string rawData = memLayer.ML.getRSV(redProdMachList);
|
|
// provo a deserializzare e cercare...
|
|
if (!string.IsNullOrEmpty(rawData))
|
|
{
|
|
tabPlace = JsonConvert.DeserializeObject<DS_App.PlacesDataTable>(rawData);
|
|
}
|
|
// cerco item
|
|
var foundItem = tabPlace.Where(x => x.PlaceCod == machine).ToList();
|
|
if (foundItem.Count == 0)
|
|
{
|
|
// forzo (ri)lettura...
|
|
tabPlace = DLMan.taPlac.GetData();
|
|
rawData = JsonConvert.SerializeObject(tabPlace);
|
|
memLayer.ML.setRSV(redProdMachList, rawData);
|
|
}
|
|
// cerco di nuovoitem
|
|
foundItem = tabPlace.Where(x => x.PlaceCod == machine).ToList();
|
|
if (foundItem.Count == 0)
|
|
{
|
|
// se non ci fosse --> creo
|
|
DLMan.taPlac.insert(machine);
|
|
// inserisco empty x 1 sec così rileggerà...
|
|
memLayer.ML.setRSV(redProdMachList, "", 1);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Transcodifica dati da format DB a formato PROD
|
|
/// </summary>
|
|
/// <param name="sheetList">Elenco fogli da DB</param>
|
|
/// <returns></returns>
|
|
private static SheetWorkList convertSheetWorkList(List<DS_App.SheetListRow> sheetList)
|
|
{
|
|
SheetWorkList answ;
|
|
List<ProdSheetExt> elSheet = new List<ProdSheetExt>();
|
|
string nestBasePath = memLayer.ML.CRS("nestBasePath").ToLower();
|
|
string servBasePath = memLayer.ML.CRS("servBasePath").ToLower();
|
|
string prodBasePath = memLayer.ML.CRS("prodBasePath").ToLower();
|
|
DateTime dataStart = DateTime.Now;
|
|
ProdSheetExt currPanel;
|
|
// ciclo elenco fogli x escludere lavorati...
|
|
foreach (var item in sheetList)
|
|
{
|
|
// converto i workData con check null sul campo data
|
|
WorkData wdPrint = new WorkData()
|
|
{
|
|
DtStart = item.IsPrntStartNull() ? null : (DateTime?)item.PrntStart,
|
|
DtEnd = item.IsPrntEndNull() ? null : (DateTime?)item.PrntEnd,
|
|
ProgramPath = item.PrintFilePath.ToLower().Replace(nestBasePath, prodBasePath).Replace(servBasePath, prodBasePath)
|
|
};
|
|
WorkData wdMachining = new WorkData()
|
|
{
|
|
DtStart = item.IsWrkStartNull() ? null : (DateTime?)item.WrkStart,
|
|
DtEnd = item.IsWrkEndNull() ? null : (DateTime?)item.WrkEnd,
|
|
ProgramPath = item.CncFilePath.ToLower().Replace(nestBasePath, prodBasePath).Replace(servBasePath, prodBasePath)
|
|
};
|
|
WorkData wdUnload = new WorkData()
|
|
{
|
|
DtStart = item.IsUnlStartNull() ? null : (DateTime?)item.UnlStart,
|
|
DtEnd = item.IsUnlEndNull() ? null : (DateTime?)item.UnlEnd
|
|
};
|
|
MaterialData material = new MaterialData()
|
|
{
|
|
MaterialId = item.MatID,
|
|
MaterialDescription = item.MatDesc,
|
|
MaterialPN = item.MatExtCode.ToString()
|
|
};
|
|
PStatus currPnlStatus = PStatus.Programmed;
|
|
Enum.TryParse(item.ShStatus.ToString(), out currPnlStatus);
|
|
currPanel = new ProdSheetExt()
|
|
{
|
|
BunkId = item.StackID,
|
|
Printing = wdPrint,
|
|
Machining = wdMachining,
|
|
Material = material,
|
|
SheetId = item.SheetID,
|
|
SheetIndex = item.SheetIndex,
|
|
Status = currPnlStatus,
|
|
Unloading = wdUnload
|
|
};
|
|
elSheet.Add(currPanel);
|
|
if (!item.IsPrntStartNull())
|
|
{
|
|
dataStart = item.PrntStart < dataStart ? item.PrntStart : dataStart;
|
|
}
|
|
}
|
|
// compongo il bunk...
|
|
answ = new SheetWorkList()
|
|
{
|
|
SheetList = elSheet
|
|
};
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupera e transcodifica DA DB i dati di UN SINGOLO bunk
|
|
/// </summary>
|
|
/// <param name="currBunk"></param>
|
|
/// <returns></returns>
|
|
private static ProdBunk getBunkFromDb(DS_App.StackListRow currBunk, string machine)
|
|
{
|
|
DataLayer DLMan = new DataLayer();
|
|
ProdBunk answ;
|
|
// calcolo attributi oggetti
|
|
CStatus currSt = CStatus.Programmed;
|
|
if (currBunk.Position == 5)
|
|
{
|
|
currSt = CStatus.Running;
|
|
}
|
|
else
|
|
{
|
|
currSt = CStatus.Done;
|
|
}
|
|
List<ProdSheet> elSheet = new List<ProdSheet>();
|
|
// recupero gli sheets di questo stack...
|
|
DS_App.SheetListDataTable tabSheets = DLMan.taSHL.getByStack(currBunk.StackID, machine);
|
|
DateTime dataStart = DateTime.Now;
|
|
ProdSheet currPanel;
|
|
string nestBasePath = memLayer.ML.CRS("nestBasePath").ToLower();
|
|
string servBasePath = memLayer.ML.CRS("servBasePath").ToLower();
|
|
string prodBasePath = memLayer.ML.CRS("prodBasePath").ToLower();
|
|
foreach (var item in tabSheets)
|
|
{
|
|
// converto i workData con check null sul campo data
|
|
WorkData wdPrint = new WorkData()
|
|
{
|
|
DtStart = item.IsPrntStartNull() ? null : (DateTime?)item.PrntStart,
|
|
DtEnd = item.IsPrntEndNull() ? null : (DateTime?)item.PrntEnd,
|
|
ProgramPath = item.PrintFilePath.ToLower().Replace(nestBasePath, prodBasePath).Replace(servBasePath, prodBasePath)
|
|
};
|
|
WorkData wdMachining = new WorkData()
|
|
{
|
|
DtStart = item.IsWrkStartNull() ? null : (DateTime?)item.WrkStart,
|
|
DtEnd = item.IsWrkEndNull() ? null : (DateTime?)item.WrkEnd,
|
|
ProgramPath = item.CncFilePath.ToLower().Replace(nestBasePath, prodBasePath).Replace(servBasePath, prodBasePath)
|
|
};
|
|
WorkData wdUnload = new WorkData()
|
|
{
|
|
DtStart = item.IsUnlStartNull() ? null : (DateTime?)item.UnlStart,
|
|
DtEnd = item.IsUnlEndNull() ? null : (DateTime?)item.UnlEnd
|
|
};
|
|
MaterialData material = new MaterialData()
|
|
{
|
|
MaterialId = item.MatID,
|
|
MaterialDescription = item.MatDesc,
|
|
MaterialPN = item.MatExtCode.ToString()
|
|
};
|
|
PStatus currPnlStatus = PStatus.Programmed;
|
|
Enum.TryParse(item.ShStatus.ToString(), out currPnlStatus);
|
|
currPanel = new ProdSheet()
|
|
{
|
|
Printing = wdPrint,
|
|
Machining = wdMachining,
|
|
Unloading = wdUnload,
|
|
Material = material,
|
|
SheetId = item.SheetID,
|
|
Status = currPnlStatus
|
|
};
|
|
elSheet.Add(currPanel);
|
|
if (!item.IsPrntStartNull())
|
|
{
|
|
dataStart = item.PrntStart < dataStart ? item.PrntStart : dataStart;
|
|
}
|
|
}
|
|
// compongo il bunk...
|
|
answ = new ProdBunk()
|
|
{
|
|
BunkId = currBunk.StackID,
|
|
Status = currSt,
|
|
DataMatrix = currBunk.StackDtmx,
|
|
SheetList = elSheet,
|
|
DtStart = dataStart
|
|
};
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recupero da Redis del SUCCESSIVO bunk da lavorare
|
|
/// </summary>
|
|
/// <param name="currBunkId"></param>
|
|
/// <returns></returns>
|
|
private static ProdBunk getRedisNextBunk(int currBunkId)
|
|
{
|
|
ProdBunk answ = null;
|
|
string rawData = memLayer.ML.getRSV(redNextBunkKey(currBunkId));
|
|
if (rawData != "")
|
|
{
|
|
// provo a deserializzare
|
|
try
|
|
{
|
|
answ = JsonConvert.DeserializeObject<ProdBunk>(rawData);
|
|
}
|
|
catch
|
|
{ }
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Aggiorno il record della station x la machine indicata
|
|
/// </summary>
|
|
/// <param name="machine"></param>
|
|
/// <param name="station"></param>
|
|
/// <param name="lastRecord"></param>
|
|
/// <returns></returns>
|
|
private static MachineStatData saveStatus(string machine, string station, MachineStatRecord lastRecord)
|
|
{
|
|
MachineStatData currData = new MachineStatData() { Machine = machine };
|
|
string redKey = $"{redProdMachStateData}:{machine}";
|
|
// ora processo lo status attuale x salvare MAPPA ULTIMO status in Redis...
|
|
string redVal = memLayer.ML.getRSV(redKey);
|
|
if (!string.IsNullOrEmpty(redVal))
|
|
{
|
|
currData = JsonConvert.DeserializeObject<MachineStatData>(redVal);
|
|
}
|
|
|
|
// recupero ultimo stato x la station corrente
|
|
var stationRecord = currData.Records.Where(x => x.Station == station).FirstOrDefault();
|
|
if (stationRecord != null)
|
|
{
|
|
// lo rimuovo
|
|
currData.Records.Remove(stationRecord);
|
|
|
|
stationRecord = lastRecord;
|
|
}
|
|
// aggiungo...
|
|
currData.Records.Add(lastRecord);
|
|
|
|
// serializzo
|
|
string rawData = JsonConvert.SerializeObject(currData);
|
|
|
|
// salvo!
|
|
memLayer.ML.setRSV(redKey, rawData);
|
|
return currData;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvo in Redis il SUCCESSIVO bunk da lavorare
|
|
/// </summary>
|
|
/// <param name="currBunkId"></param>
|
|
/// <param name="value"></param>
|
|
private static void setRedisNextBunk(int currBunkId, ProdBunk value)
|
|
{
|
|
if (value != null)
|
|
{
|
|
string redVal = JsonConvert.SerializeObject(value);
|
|
// default lascio x 5 minuti...
|
|
memLayer.ML.setRSV(redNextBunkKey(currBunkId), redVal, ttlProdData);
|
|
}
|
|
else
|
|
// se null elimino da redis
|
|
{
|
|
memLayer.ML.setRSV(redNextBunkKey(currBunkId), "");
|
|
}
|
|
}
|
|
|
|
#endregion Private Methods
|
|
}
|
|
} |