using AppData; using Newtonsoft.Json; using NKC_SDK; using SteamWare; using System; using System.IO; using System.Web.Http; namespace NKC_WF.Controllers { public class BatchProcController : ApiController { /// /// Restituisce SE C'E' la richiesta di elaborazione BATCH corrente /// /// // GET: api/BatchProc [HttpGet] public batchRequest Get() { batchRequest answ = new batchRequest(); string redKey = ""; string redVal = ""; // in primis: controllo su redis SE HO una richiesta CURRENT di processing... string envNum = ComLib.currBatchReq; // se c'è carico "la busta" come ID if (!string.IsNullOrEmpty(envNum)) { // cerco in REDIS se ci sia l'item richiesto redKey = $"{ComLib.redOutPath}:{envNum}"; // leggo da redis la stringa... redVal = memLayer.ML.getRSV(redKey); // PROVO a deserializzare... try { answ = JsonConvert.DeserializeObject(redVal); // aggiungo LA SUA ENV NUM!!!! answ.EnvNum = envNum; } catch { } } // altrimenti NULL! else { answ = null; } return answ; } /// /// Restituisce UNA SPECIFICA richiesta di elaborazione BATCH /// /// // GET: api/BatchProc/5 [HttpGet] public batchRequest Get(int id) { batchRequest answ = new batchRequest(); // in primis: controllo su redis SE HO una richiista CURRENT di processing... string redKey = $"{ComLib.redOutPath}:{id}"; string redVal = memLayer.ML.getRSV(redKey); // se c'è carico "la busta" come ID if (!string.IsNullOrEmpty(redVal)) { // PROVO a deserializzare... try { answ = JsonConvert.DeserializeObject(redVal); } catch { } } return answ; } /// /// Processa una chiamata POST per l'invio in blocco Batch /// POST: api/BatchProc /// /// ID dell'IOB /// // POST: api/BatchProc [HttpPost] public string Post() { string answ = ""; // questa classe è derivata da Controller.Response... x cui recupero lo stream in altro modo... string content = ""; System.Web.HttpContext.Current.Request.InputStream.Position = 0; using (var reader = new StreamReader(System.Web.HttpContext.Current.Request.InputStream, System.Text.Encoding.UTF8, true, 4096, true)) { content = reader.ReadToEnd(); } //Rest System.Web.HttpContext.Current.Request.InputStream.Position = 0; // procedo a deserializzare in blocco l'oggetto... try { // DEBUG: salvo su redis x fare DEBUG string redKey = $"{ComLib.redNestAnsw}:LAST_CALL"; memLayer.ML.setRSV(redKey, content); // deserializzo. baseNestAnsw batchProcAnsw = JsonConvert.DeserializeObject(content); // se ho errori inizio a salvarli... if (batchProcAnsw.ErrorList.Count > 0) { // procedura idempotente: elimino eventuali dati della "busta" precedente... DataLayer.man.taEL.deteteByParent("", batchProcAnsw.EnvNum); // ora insert foreach (var item in batchProcAnsw.ErrorList) { // salvo log errore... DataLayer.man.taEL.insertQuery(DateTime.Now, item.ErrType, $"{batchProcAnsw.EnvNum}", $"{item.Uid}", $"{item.Description}"); } } // se non nullo... if (batchProcAnsw != null) { /************************************************* * IN BASE al tipo di risposta saprò se * - è BatchReq / OfflineOrder * - è stima iniziale o NEST dettagliato * - si tratta di una stima di validazione ITEM ... * *************************************************/ if (batchProcAnsw.OrderType == oType.BatchRequest) { if (batchProcAnsw.ProcType == 1) { int bStatus = 0; // deserializzo come BatchreqIniziale (stima) nestReplyBatchInitial rispStima = JsonConvert.DeserializeObject(content); // 2020.01.16 salvo su mongoDb la risposta... ComLib.man.saveEstAnsw(rispStima); // recupero info sul batch / KIT specifico x capire se sia di tipo "validation" bool isValidation = false; var tabOrd = DataLayer.man.taOL.getByBatch(rispStima.BatchID); if (tabOrd.Count > 0) { isValidation = tabOrd[0].OrdType == "V"; } // calcolo status del batch... switch (rispStima.ProcessStatus) { case procStatus.waiting: case procStatus.running: bStatus = 1; break; case procStatus.completed: if (isValidation) { // verifico se il tempo di procesisng stimato sia > minimo... if (rispStima.EstimatedWorktime > memLayer.ML.CRI("minValidEstSec")) { bStatus = 10; } else { bStatus = 9; } } else { bStatus = 2; } break; case procStatus.accepted: bStatus = 5; break; case procStatus.refused: if (isValidation) { bStatus = 9; } else { bStatus = 6; } break; case procStatus.error: if (isValidation) { bStatus = 9; } else { bStatus = 7; } break; case procStatus.aborted: default: if (isValidation) { bStatus = 9; } else { bStatus = 0; } break; } // SALVO info riguardo al batch running DataLayer.man.taBL.updateStatus(rispStima.BatchID, bStatus, rispStima.EnvNum, (decimal)rispStima.EstimatedWorktime / 60); // salvo udpate elenco ITEMS ComLib.updatePartsFromNesting(rispStima.PartList); // aggiorno cadPath x items che non abbiano valorizzato... DataLayer.man.taIL.updateCadPath(memLayer.ML.CRS("cadBaseBath"), rispStima.BatchID, false); // verifico IN CASO di validazione andata a buon fine --> valorizzo tabella! if (bStatus > 7) { // recupero ordine da batch if (tabOrd.Count > 0) { DataLayer.man.taIV.upsertQuery(tabOrd[0].OrderExtCode, rispStima.BatchID, bStatus, rispStima.EstimatedWorktime); } } // registro OK answ = "OK"; } else { // deserializzo come BatchreqFinale nestReplyBatchFinal rispNest = JsonConvert.DeserializeObject(content); // 2020.01.16 salvo su mongoDb la risposta... ComLib.man.saveNestAnsw(rispNest); // calcolo status del batch... int bStatus = 2; switch (rispNest.ProcessStatus) { case procStatus.waiting: case procStatus.running: bStatus = 3; break; case procStatus.completed: bStatus = 4; break; case procStatus.accepted: bStatus = 5; break; case procStatus.refused: bStatus = 6; break; case procStatus.error: bStatus = 7; break; case procStatus.aborted: default: bStatus = 2; break; } // aggiorno il resto SOLO SE status == completo... if (rispNest.ProcessStatus == procStatus.completed) { // resetto le precedenti elaborazioni: elimino dati child MA NON il batch... DataLayer.man.taBL.deleteTree(rispNest.BatchID, 0); // salvo info riguardo ai vari Bunk / Sheets / Items... ComLib.updateBunksFromNesting(rispNest.BatchID, rispNest.BunkList); // salvo info x CART & BINS previsti ComLib.updateBinsFromNesting(rispNest.BatchID, rispNest.BinList); ComLib.updateCartsFromNesting(rispNest.BatchID, rispNest.CartList); } // SALVO info riguardo al batch completato DataLayer.man.taBL.updateStatus(rispNest.BatchID, bStatus, rispNest.EnvNum, (decimal)rispNest.EstimatedWorktime / 60); // registro OK answ = "OK"; } } else if (batchProcAnsw.OrderType == oType.OfflineOrder) { // deserializzo come OfflineOrder nestReplyOffOrd rispNest = JsonConvert.DeserializeObject(content); // SALVO!!! answ = "OK"; } #if false foreach (var item in currBunk.SheetList) { DataLayer.man.taSHL.updateDate(item.SheetId, item.Printing.DtStart, item.Printing.DtEnd, item.Machining.DtStart, item.Machining.DtEnd, item.Unloading.DtStart, item.Unloading.DtEnd); } #endif } else { answ = "WRONG DATA (expected baseNestAnsw object)"; } } catch (Exception exc) { answ = "NO"; } // se tutto OK --> tolgo ultimo batch if (answ == "OK") { // invio notifica che c'è una busta da processare bool resetOk = ComLib.resetBatchReq(); // se tutto ok e ci sono da validare parts --> procedo! if (resetOk) { bool nextValidSent = ComLib.sendFirstValidationBatch(); } } // restituisco risposta return answ; } #if false // POST: api/BatchProc public void Post([FromBody]string value) { } // PUT: api/BatchProc/5 public void Put(int id, [FromBody]string value) { } // DELETE: api/BatchProc/5 public void Delete(int id) { } #endif } }