From d731091076f72cbd737b85f420ef4e98121ff6fd Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 26 Apr 2023 19:42:04 +0200 Subject: [PATCH] update comlib x gestione png creation --- AppData/ComLib.cs | 1243 +++++++++++++++++++++++---------------------- 1 file changed, 632 insertions(+), 611 deletions(-) diff --git a/AppData/ComLib.cs b/AppData/ComLib.cs index 12f2150..47d340e 100644 --- a/AppData/ComLib.cs +++ b/AppData/ComLib.cs @@ -1,15 +1,13 @@ -using System.Linq; -using MongoDB.Driver; +using MongoDB.Driver; using Newtonsoft.Json; -using Newtonsoft.Json.Converters; using NKC_SDK; using SteamWare; using System; using System.Collections.Generic; using System.IO; -using System.Web; -using System.Net; +using System.Linq; using System.Net.NetworkInformation; +using System.Web; namespace AppData { @@ -18,34 +16,6 @@ namespace AppData /// public class ComLib { - #region Private Fields - - /// - /// Database corrente MongoDB - /// - private IMongoDatabase database; - - #endregion Private Fields - - #region Protected Fields - - /// - /// Chiave primo bunk su redis - /// - protected static string redAllNextBunkKey = $"{redProdReq}:NextBunk"; - - /// - /// Chiave primo bunk su redis - /// - protected static string redFirstBunkKey = $"{redProdReq}:FirstBunk"; - - /// - /// TTL standard x dati da scambiare con PROD (30 gg) - /// - protected static int ttlProdData = 3600 * 24 * 30; - - #endregion Protected Fields - #region Public Fields /// @@ -54,20 +24,35 @@ namespace AppData public static ComLib man = new ComLib(); public static string redBatchDescend = "NKC:SERV:BATCHDESCEND"; + 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"; /// @@ -104,55 +89,10 @@ namespace AppData #endregion Public Constructors - #region Private Properties - - /// - /// Cache redis del PRIMO bunk da lavorare - /// - 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(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 Public Properties /// - /// verifica se sia avviabile un nuovo task nesting controllando cache Redis o tabelle batch/offlineOrders + /// verifica se sia avviabile un nuovo task nesting controllando cache Redis o tabelle batch/offlineOrders /// public static bool canStartNew { @@ -255,509 +195,6 @@ namespace AppData #endregion Public Properties - #region Private Methods - - /// - /// Verifica ed eventualmente aggiunge part da aggiornare all'elenco - /// - /// - /// - private static void addPart2Upd(ref Dictionary part2update, List partList) - { - foreach (var item in partList) - { - if (!part2update.ContainsKey(item.PartRev)) - { - part2update.Add(item.PartRev, item.PartId); - } - } - } - - /// - /// verifica che la macchina dichiarata esiste o la crea... - /// - /// - 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(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); - } - } - - /// - /// Transcodifica dati da format DB a formato PROD - /// - /// Elenco fogli da DB - /// - private static SheetWorkList convertSheetWorkList(List sheetList) - { - SheetWorkList answ; - List elSheet = new List(); - 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; - } - - /// - /// Recupera e transcodifica DA DB i dati di UN SINGOLO bunk - /// - /// - /// - 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 elSheet = new List(); - // 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; - } - - /// - /// Recupero da Redis del SUCCESSIVO bunk da lavorare - /// - /// - /// - 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(rawData); - } - catch - { } - } - return answ; - } - - /// - /// Aggiorno il record della station x la machine indicata - /// - /// - /// - /// - /// - 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(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; - } - - /// - /// Salvo in Redis il SUCCESSIVO bunk da lavorare - /// - /// - /// - 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 - - #region Protected Methods - - /// - /// lettura currBunk table da cache - /// - /// - /// - 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(rawData); - } - catch - { } - } - return answ; - } - - /// - /// Recupero da redis tab fogli correnti - /// - 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(rawData); - } - catch - { } - } - return answ; - } - - /// - /// Chiave BATCH corrente su redis - /// - /// - /// - protected static string redCurrBatchId(string machine) - { - string answ = ""; - if (string.IsNullOrEmpty(machine)) - { - answ = $"{redProdReq}:CurrBatchID"; - } - else - { - answ = $"{redProdReq}:CurrBatchID:{machine}"; - } - return answ; - } - - /// - /// Chiave Bunk corrente su redis - /// - /// - /// - protected static string redCurrBunkId(string machine) - { - string answ = ""; - if (string.IsNullOrEmpty(machine)) - { - answ = $"{redProdReq}:CurrBunkID"; - } - else - { - answ = $"{redProdReq}:CurrBunkID:{machine}"; - } - return answ; - } - - /// - /// Chiave bunk corrente su redis - /// - /// - /// - protected static string redCurrBunkTabKey(string machine) - { - string answ = ""; - if (string.IsNullOrEmpty(machine)) - { - answ = $"{redProdReq}:CurrBunks"; - } - else - { - answ = $"{redProdReq}:CurrBunks:{machine}"; - } - return answ; - } - - /// - /// Chiave Sheets corrente su redis - /// - /// - /// - protected static string redCurrSheetId(string machine) - { - string answ = ""; - if (string.IsNullOrEmpty(machine)) - { - answ = $"{redProdReq}:CurrSheetID"; - } - else - { - answ = $"{redProdReq}:CurrSheetID:{machine}"; - } - return answ; - } - - /// - /// Chiave sheets correnti su redis - /// - /// - /// - protected static string redCurrSheetTabKey(string machine) - { - string answ = ""; - if (string.IsNullOrEmpty(machine)) - { - answ = $"{redProdReq}:CurrSheets"; - } - else - { - answ = $"{redProdReq}:CurrSheets:{machine}"; - } - return answ; - } - - /// - /// Chiave primo bunk su redis - /// - protected static string redNextBunkKey(int BunkID) - { - return $"{redProdReq}:NextBunk:{BunkID}"; - } - - /// - /// salvataggio inc ache currBunk table - /// - /// - /// - 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); - } - - /// - /// Salvataggio in redis tab fogli correnti - /// - /// - /// - protected static void setCurrSheetTab(string machine, DS_App.SheetListDataTable tabella) - { - string rawData = JsonConvert.SerializeObject(tabella); - // TTL 5 sec - memLayer.ML.setRSV(redCurrSheetTabKey(machine), rawData, 2); - } - - /// - /// Recupera prossimo batch da DB (NEXT... da db x status...) - /// - 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; - } - - /// - /// Recupera SHEET da batch e sstati permessi... - /// - /// - /// - /// - /// - /// - protected int getSheetIdByBatch(int BatchID, int minVal, int maxVal, string machine) - { - int answ = 0; - try - { - DataLayer DLMan = new DataLayer(); - var tabSheet = DLMan.taSHL.getByMLStatus(BatchID, minVal, maxVal, machine); - if (tabSheet.Count > 0) - { - answ = tabSheet[0].SheetID; - } - } - catch - { } - return answ; - } - - #endregion Protected Methods - #region Public Methods /// @@ -961,7 +398,7 @@ namespace AppData } /// - /// Verifica lo stato di una richiesta di esecuzione BATCH x stima/nesting + /// Verifica lo stato di una richiesta di esecuzione BATCH x stima/nesting /// /// OfflineOrder di cui si chiede processing /// note opzionali @@ -1021,7 +458,7 @@ namespace AppData /// /// Verifica esistenza del PDF SE presente negli optParams /// - OK SE NON c'è parametro x pdf - /// - OK SE presente parametro --> cerca il file --> lo trova + /// - OK SE presente parametro --> cerca il file --> lo trova /// /// Part da analizzare /// Path del file PDF analizzato @@ -1085,7 +522,8 @@ namespace AppData 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... + // 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) { @@ -1093,7 +531,7 @@ namespace AppData if (tabItems.Count > 0) { // primo parto da indice 10... - ComLib.sendBatchReq(item.BatchID, "Nesting", 2, false, nextIndex); + 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; @@ -1130,14 +568,15 @@ namespace AppData if (item.STATUS == 2) { nextIndex += 50; - // 2021.07.19 FIX x caso batch vuoto: se non ho pezzi --> approvo direttamente e passo al successivo... + // 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) { // --> invio batch if (tabItems.Count > 0) { - ComLib.sendBatchReq(item.BatchID, "Nesting", 2, false, nextIndex); + 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; @@ -1225,8 +664,7 @@ namespace AppData } /// - /// Cache redis del BunkID in lavorazione sulla macchina - /// + /// Cache redis del BunkID in lavorazione sulla macchina /// public static int getCurrBatchId(string macchina) { @@ -1264,8 +702,7 @@ namespace AppData } /// - /// Cache redis del BunkID in lavorazione sulla macchina - /// + /// Cache redis del BunkID in lavorazione sulla macchina /// public static int getCurrBunkId(string macchina) { @@ -1276,7 +713,6 @@ namespace AppData } /// - /// /// /// /// @@ -1434,8 +870,7 @@ namespace AppData } /// - /// Cache redis del SheetID in lavorazione sulla macchina - /// + /// Cache redis del SheetID in lavorazione sulla macchina /// public static int getCurrSheetId(string macchina) { @@ -1905,7 +1340,7 @@ namespace AppData /// /// 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 + /// - NumSheet > NumSheetUnload /// - Ordinato per StackIndex (crescente) x avere il più VECCHIO /// /// @@ -1934,7 +1369,7 @@ namespace AppData /// /// Restituisce il PROSSIMO bunk x la MACCHINA indicata secondo criterio: /// - posizione = 5 (ho letto da webApp il BUNK e preso in carico) - /// - NumSheet > NumSheetUnload + /// - NumSheet > NumSheetUnload /// - Ordinato per StackIndex (crescente) x avere il più VECCHIO /// - SUCCESSIVO al BunkID(=StackID) ricevuto /// @@ -2036,8 +1471,8 @@ namespace AppData } /// - /// Salva gli stati macchina ricevuti sul DB e poi salva ultimo su redis - /// Do x scontato tutti singola macchina + /// Salva gli stati macchina ricevuti sul DB e poi salva ultimo su redis Do x scontato tutti + /// singola macchina /// /// public static bool prodMachStateDataInsert(MachineStatData updateRecords) @@ -2381,10 +1816,15 @@ namespace AppData /// Batch di cui si chiede processing /// note opzionali /// Tipo processo: 1 = stima, 2 = nesting, 3 = stima EXTENDED - /// Indica se sia validaizone (part o disegno) --> in tal caso MaxTime = 1 + /// + /// Indica se sia validaizone (part o disegno) --> in tal caso MaxTime = 1 + /// /// Numero di indice richiesto con cui partire x creare CART/BIN + /// + /// Richiesta creazione png delle part valutate, da impiegare x DXF validation + /// /// - public static bool sendBatchReq(int BatchID, string note, int pType, bool isValidation, int numIndexStart) + public static bool sendBatchReq(int BatchID, string note, int pType, bool isValidation, int numIndexStart, bool createPng) { DataLayer DLMan = new DataLayer(); bool answ = false; @@ -2506,8 +1946,9 @@ namespace AppData /// /// Manda il primo batch di VALIDAZIONE al NESTING... /// + /// indica se creare le PNG delle part validate /// - public static bool sendFirstValidationBatch() + public static bool sendFirstValidationBatch(bool createPng) { DataLayer DLMan = new DataLayer(); bool answ = false; @@ -2515,7 +1956,8 @@ namespace AppData 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! + // 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) @@ -2537,8 +1979,9 @@ namespace AppData if (nextBatchId > 0) { // richiedo! - sendBatchReq(nextBatchId, "Estimation", 1, true, 1); - // registro su DB nesting iniziato... QUANDO MI RISPONDE dovrò verificare che era un batch x VALIDAZIONE + 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; } @@ -2739,8 +2182,8 @@ namespace AppData } /// - /// 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 + /// 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 /// /// /// @@ -2752,8 +2195,8 @@ namespace AppData } /// - /// 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 + /// 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 /// /// /// @@ -3141,7 +2584,8 @@ namespace AppData } /// - /// Fornisce il prossimo TAKT da elaborare oppure null se non ce ne fossero altri da elaborare per la data CORRENTE + /// Fornisce il prossimo TAKT da elaborare oppure null se non ce ne fossero altri da + /// elaborare per la data CORRENTE /// /// public Takt prodGetNextTakt() @@ -3383,7 +2827,8 @@ namespace AppData } /// - /// Effettua il ricalcolo delle statistiche x SheetStat --> BatchStat dato un BatchID recuperando i dati da MongoDB + /// Effettua il ricalcolo delle statistiche x SheetStat --> BatchStat dato un BatchID + /// recuperando i dati da MongoDB /// /// /// @@ -3521,5 +2966,581 @@ namespace AppData } #endregion Public Classes + + #region Protected Fields + + /// + /// Chiave primo bunk su redis + /// + protected static string redAllNextBunkKey = $"{redProdReq}:NextBunk"; + + /// + /// Chiave primo bunk su redis + /// + protected static string redFirstBunkKey = $"{redProdReq}:FirstBunk"; + + /// + /// TTL standard x dati da scambiare con PROD (30 gg) + /// + protected static int ttlProdData = 3600 * 24 * 30; + + #endregion Protected Fields + + #region Protected Methods + + /// + /// lettura currBunk table da cache + /// + /// + /// + 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(rawData); + } + catch + { } + } + return answ; + } + + /// + /// Recupero da redis tab fogli correnti + /// + 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(rawData); + } + catch + { } + } + return answ; + } + + /// + /// Chiave BATCH corrente su redis + /// + /// + /// + protected static string redCurrBatchId(string machine) + { + string answ = ""; + if (string.IsNullOrEmpty(machine)) + { + answ = $"{redProdReq}:CurrBatchID"; + } + else + { + answ = $"{redProdReq}:CurrBatchID:{machine}"; + } + return answ; + } + + /// + /// Chiave Bunk corrente su redis + /// + /// + /// + protected static string redCurrBunkId(string machine) + { + string answ = ""; + if (string.IsNullOrEmpty(machine)) + { + answ = $"{redProdReq}:CurrBunkID"; + } + else + { + answ = $"{redProdReq}:CurrBunkID:{machine}"; + } + return answ; + } + + /// + /// Chiave bunk corrente su redis + /// + /// + /// + protected static string redCurrBunkTabKey(string machine) + { + string answ = ""; + if (string.IsNullOrEmpty(machine)) + { + answ = $"{redProdReq}:CurrBunks"; + } + else + { + answ = $"{redProdReq}:CurrBunks:{machine}"; + } + return answ; + } + + /// + /// Chiave Sheets corrente su redis + /// + /// + /// + protected static string redCurrSheetId(string machine) + { + string answ = ""; + if (string.IsNullOrEmpty(machine)) + { + answ = $"{redProdReq}:CurrSheetID"; + } + else + { + answ = $"{redProdReq}:CurrSheetID:{machine}"; + } + return answ; + } + + /// + /// Chiave sheets correnti su redis + /// + /// + /// + protected static string redCurrSheetTabKey(string machine) + { + string answ = ""; + if (string.IsNullOrEmpty(machine)) + { + answ = $"{redProdReq}:CurrSheets"; + } + else + { + answ = $"{redProdReq}:CurrSheets:{machine}"; + } + return answ; + } + + /// + /// Chiave primo bunk su redis + /// + protected static string redNextBunkKey(int BunkID) + { + return $"{redProdReq}:NextBunk:{BunkID}"; + } + + /// + /// salvataggio inc ache currBunk table + /// + /// + /// + 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); + } + + /// + /// Salvataggio in redis tab fogli correnti + /// + /// + /// + protected static void setCurrSheetTab(string machine, DS_App.SheetListDataTable tabella) + { + string rawData = JsonConvert.SerializeObject(tabella); + // TTL 5 sec + memLayer.ML.setRSV(redCurrSheetTabKey(machine), rawData, 2); + } + + /// + /// Recupera prossimo batch da DB (NEXT... da db x status...) + /// + 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; + } + + /// + /// Recupera SHEET da batch e sstati permessi... + /// + /// + /// + /// + /// + /// + protected int getSheetIdByBatch(int BatchID, int minVal, int maxVal, string machine) + { + int answ = 0; + try + { + DataLayer DLMan = new DataLayer(); + var tabSheet = DLMan.taSHL.getByMLStatus(BatchID, minVal, maxVal, machine); + if (tabSheet.Count > 0) + { + answ = tabSheet[0].SheetID; + } + } + catch + { } + return answ; + } + + #endregion Protected Methods + + #region Private Fields + + /// + /// Database corrente MongoDB + /// + private IMongoDatabase database; + + #endregion Private Fields + + #region Private Properties + + /// + /// Cache redis del PRIMO bunk da lavorare + /// + 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(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 + + /// + /// Verifica ed eventualmente aggiunge part da aggiornare all'elenco + /// + /// + /// + private static void addPart2Upd(ref Dictionary part2update, List partList) + { + foreach (var item in partList) + { + if (!part2update.ContainsKey(item.PartRev)) + { + part2update.Add(item.PartRev, item.PartId); + } + } + } + + /// + /// verifica che la macchina dichiarata esiste o la crea... + /// + /// + 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(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); + } + } + + /// + /// Transcodifica dati da format DB a formato PROD + /// + /// Elenco fogli da DB + /// + private static SheetWorkList convertSheetWorkList(List sheetList) + { + SheetWorkList answ; + List elSheet = new List(); + 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; + } + + /// + /// Recupera e transcodifica DA DB i dati di UN SINGOLO bunk + /// + /// + /// + 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 elSheet = new List(); + // 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; + } + + /// + /// Recupero da Redis del SUCCESSIVO bunk da lavorare + /// + /// + /// + 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(rawData); + } + catch + { } + } + return answ; + } + + /// + /// Aggiorno il record della station x la machine indicata + /// + /// + /// + /// + /// + 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(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; + } + + /// + /// Salvo in Redis il SUCCESSIVO bunk da lavorare + /// + /// + /// + 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 } } \ No newline at end of file