diff --git a/MP.Core/Utils.cs b/MP.Core/Utils.cs
index 53d2bd69..aa94c020 100644
--- a/MP.Core/Utils.cs
+++ b/MP.Core/Utils.cs
@@ -24,10 +24,13 @@ namespace MP.Core
public const string redisDecNumArtKey = redisBaseAddr + "Cache:DecNumArt";
public const string redisDossByMac = redisBaseAddr + "Cache:DossByMac";
+ public const string redisDossByMacLast = redisBaseAddr + "Cache:DossByMacLast";
public const string redisEventList = redisBaseAddr + "Cache:EventList";
public const string redisFluxByMac = redisBaseAddr + "Cache:FluxByMac";
+ public const string redisFluxByMacFirst = redisBaseAddr + "Cache:FluxByMacFirst";
+ public const string redisConfFlux = redisBaseAddr + "Cache:ConfFlux";
public const string redisFluxLogFilt = redisBaseAddr + "Cache:FluxLogFilt";
diff --git a/MP.Data/Controllers/MpIocController.cs b/MP.Data/Controllers/MpIocController.cs
index 729bdceb..73a081d3 100644
--- a/MP.Data/Controllers/MpIocController.cs
+++ b/MP.Data/Controllers/MpIocController.cs
@@ -55,6 +55,7 @@ namespace MP.Data.Controllers
}
return fatto;
}
+
///
/// Restituisce l'anagrafica STATI per intero
///
@@ -73,21 +74,21 @@ namespace MP.Data.Controllers
}
///
- /// Elenco tabella decodifica articoli / codice decimale
+ /// Record ConfFlux dato macchina (oppure tutti se vuoto)
///
- /// Vuoto = tutti / Singolo CodArt
+ ///
///
- public async Task> DecNumArtGetFiltAsync(string codArt = "")
+ public async Task> ConfFluxFiltAsync(string idxMacc)
{
- List dbResult = new List();
- using (var dbCtx = new MoonProContext(_configuration))
+ List dbResult = new();
+ using (var dbCtx = new MoonPro_FluxContext(_configuration))
{
- var query = dbCtx.DbSetDecNumArt
+ var query = dbCtx.DbSetConfFlux
.AsNoTracking()
.AsQueryable();
- if (!string.IsNullOrEmpty(codArt))
- query = query.Where(x => x.CodArticolo == codArt);
+ if (!string.IsNullOrEmpty(idxMacc))
+ query = query.Where(x => x.IdxMacchina == idxMacc);
dbResult = await query.ToListAsync();
}
@@ -153,6 +154,7 @@ namespace MP.Data.Controllers
}
return dbResult;
}
+
///
/// Intera tab dati macchina
///
@@ -205,11 +207,54 @@ namespace MP.Data.Controllers
return fatto;
}
+ ///
+ /// Elenco tabella decodifica articoli / codice decimale
+ ///
+ /// Vuoto = tutti / Singolo CodArt
+ ///
+ public async Task> DecNumArtGetFiltAsync(string codArt = "")
+ {
+ List dbResult = new List();
+ using (var dbCtx = new MoonProContext(_configuration))
+ {
+ var query = dbCtx.DbSetDecNumArt
+ .AsNoTracking()
+ .AsQueryable();
+
+ if (!string.IsNullOrEmpty(codArt))
+ query = query.Where(x => x.CodArticolo == codArt);
+
+ dbResult = await query.ToListAsync();
+ }
+ return dbResult;
+ }
+
public void Dispose()
{
_configuration = null;
}
+ ///
+ /// Stored x recuperare ultimi dossier macchina
+ ///
+ ///
+ ///
+ public async Task> DossGetLastByMaccAsync(string idxMacc)
+ {
+ List dbResult = new();
+ using (var dbCtx = new MoonPro_FluxContext(_configuration))
+ {
+ var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacc);
+
+ dbResult = await dbCtx
+ .DbSetDossiers
+ .FromSqlRaw("exec dbo.stp_DOSS_getLastByMacch @idxMacchina", IdxMacchina)
+ .AsNoTracking()
+ .ToListAsync();
+ }
+ return dbResult;
+ }
+
///
/// Aggiunta record EventList
///
@@ -260,6 +305,29 @@ namespace MP.Data.Controllers
return fatto;
}
+ ///
+ /// Chiamata x stored recupero FluxLog x macchina (first)
+ ///
+ ///
+ ///
+ ///
+ public async Task> FluxLogFirstByMaccAsync(string idxMacc, int numMax)
+ {
+ List dbResult = new();
+ using (var dbCtx = new MoonPro_FluxContext(_configuration))
+ {
+ var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacc);
+ var NumMax = new SqlParameter("@numMax", numMax);
+
+ dbResult = await dbCtx
+ .DbSetFluxLog
+ .FromSqlRaw("exec dbo.stp_FL_getFirstByMacc @IdxMacchina, @numMax", IdxMacchina, NumMax)
+ .AsNoTracking()
+ .ToListAsync();
+ }
+ return dbResult;
+ }
+
///
/// Elenco ultimi n record flux log dato macchina e flusso (ordinato x data registrazione)
///
@@ -336,25 +404,25 @@ namespace MP.Data.Controllers
}
///
- /// Record ConfFlux dato macchina (oppure tutti se vuoto)
+ /// Stored x eseguire Snapshot FluxLog (= Dossier) dato periodo
///
///
///
- public async Task> ConfFluxFiltAsync(string idxMacc)
+ public async Task FluxLogTakeSnapshotLastAsync(string idxMacc, DateTime dataInizio, DateTime dataFine)
{
- List dbResult = new();
+ bool fatto = false;
using (var dbCtx = new MoonPro_FluxContext(_configuration))
{
- var query = dbCtx.DbSetConfFlux
- .AsNoTracking()
- .AsQueryable();
+ var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacc);
+ var DataInizio = new SqlParameter("@DtMin", dataInizio);
+ var DataFine = new SqlParameter("@DtMax", dataFine);
- if (!string.IsNullOrEmpty(idxMacc))
- query = query.Where(x => x.IdxMacchina == idxMacc);
-
- dbResult = await query.ToListAsync();
+ var result = await dbCtx
+ .Database
+ .ExecuteSqlRawAsync("EXEC stp_FL_TakeSnapshotLast @IdxMacchina, @DtMin, @DtMax", IdxMacchina, DataInizio, DataFine);
+ fatto = result > 0;
}
- return dbResult;
+ return fatto;
}
public bool KeepAliveUpsert(string IdxMacc, DateTime OraServer, DateTime OraMacc)
diff --git a/MP.IOC/Controllers/IOBController.cs b/MP.IOC/Controllers/IOBController.cs
index 4f523be7..f283a8d7 100644
--- a/MP.IOC/Controllers/IOBController.cs
+++ b/MP.IOC/Controllers/IOBController.cs
@@ -103,7 +103,6 @@ namespace MP.IOC.Controllers
}
}
-
///
/// Processa una chiamata POST per l'invio di un array Json di oggetti input (EVENTI)
/// POST: IOB/evListJson/SIMUL_03
@@ -136,7 +135,6 @@ namespace MP.IOC.Controllers
return Ok(answ);
}
-#if false
///
/// Sistema Dossier/Snapshot giornalieri x impianto indicato, andando a generare 1 Dossier
/// giornaliero x ogni giornata dall'ultimo registrato alla data corrente
@@ -144,80 +142,25 @@ namespace MP.IOC.Controllers
///
///
///
- public string fixDailyDossier(string id)
+ [HttpGet("fixDailyDossier/{id}")]
+ public async Task FixDailyDossier(string id)
{
- string answ = "";
- // attenzione! poiché nell'URL il carattere "#" viene filtrato ci aspettiamo il
- // carattere "|" che poi trasformiamo ora in "#"
+ if (string.IsNullOrEmpty(id)) return BadRequest("Missing ID");
+ // Multi: gestione carattere "|" trasformato in "#"
id = id.Replace("|", "#");
- // effettuo processing
+
+ string answ = "";
try
{
- DataLayer DataLayerObj = new DataLayer();
- // verifico se si possa processare, ovvero tab ConfFlux x macchina sia valorizzata...
- var confDataMach = DataLayerObj.confFluxMach(id);
- if (confDataMach.Count > 0)
- {
- // determino ultima data da processare (inizio oggi, a mezzanotte)
- DateTime dtTo = DateTime.Today;
- DateTime dtFrom = dtTo;
- // determino data di partenza, prima da dossier esistenti
- var listaDoss = DataLayerObj.dossierLastByMach(id);
- if (listaDoss.Count > 0)
- {
- // primo giorno DOPO ultima registrazione
- dtFrom = listaDoss.OrderByDescending(x => x).FirstOrDefault().AddDays(1);
- }
- else
- {
- // ...o da fluxLog acquisiti...
- var listaFL = DataLayerObj.fluxLogFirstByMach(id);
- if (listaFL.Count > 0)
- {
- // giorno successivo a prima registrazione
- dtFrom = listaFL.OrderBy(x => x).FirstOrDefault().AddDays(1);
- }
- }
- string caller = $"takeFlogSnapshot({id})";
- DateTime dtStart = dtFrom.Date;
- DateTime dtEnd = dtFrom;
- // max 10 dossier alla volta (se non configurato diversamente)
- int maxAdd = memLayer.ML.CRI("IO_numDossMaxCreate");
- if (dtStart < dtTo)
- {
- // verifico di avere almeno 1 dossier da produrre ciclo fino ad esaurire le
- // date da processare
- while (dtStart < dtTo && maxAdd > 0)
- {
- // sistemo end
- dtEnd = dtStart.AddDays(1);
- // effettuo chiamata registrazione snapshot!
- answ = doSaveFLSnapshot(id, dtStart, dtEnd, caller);
- // incremento START...
- dtStart = dtEnd;
- // riduco il numero di chiamate ammesse x singolo task
- maxAdd--;
- }
- // reset cache dossier...
- DataLayerObj.dossierLastByMachReset(id);
- }
- else
- {
- answ = "NO more to add";
- }
- }
- else
- {
- answ = "NO ConfFluxData";
- }
+ answ = await DService.FixDailyDossierAsync(id);
}
catch (Exception exc)
{
- logger.lg.scriviLog($"Eccezione in recupero fixDailyDossier{Environment.NewLine}{exc}", tipoLog.EXCEPTION);
+ Log.Error($"Errore in FixDailyDossier{Environment.NewLine}{exc}");
+ return StatusCode(StatusCodes.Status500InternalServerError, "NO");
}
- return answ;
- }
-#endif
+ return Ok(answ);
+ }
///
/// Sistema ODL giornalieri x impianto indicato, andando a generare 1 ODL giornaliero x ogni
@@ -1237,6 +1180,47 @@ namespace MP.IOC.Controllers
#region Private Methods
+ ///
+ /// Processing effettivo EvListJson
+ ///
+ ///
+ ///
+ ///
+ private async Task processEvListJsonAsync(string idxMacc, string content)
+ {
+ string answ = "";
+ int insDone = 0;
+
+ // procedo a deserializzare in blocco l'oggetto...
+ EvJsonPayloadDto receivedData = JsonConvert.DeserializeObject(content) ?? new();
+
+ // se ho qualcosa da processare...
+ if (receivedData != null)
+ {
+ // per ogni valore --> processo!
+ try
+ {
+ foreach (var item in receivedData.eventList)
+ {
+ // formato datetime come yyyyMMddHHmmssfff -->es: 20181223180600000
+ answ = await DService.ProcessInputAsync(idxMacc, item.valore, item.dtEve.ToString("yyyyMMddHHmmssfff"), item.dtCurr.ToString("yyyyMMddHHmmssfff"), item.cnt.ToString());
+ insDone++;
+ }
+ // se vuoto --> OK!
+ if (string.IsNullOrEmpty(answ))
+ {
+ answ = $"OK {insDone} processed";
+ }
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"Errore in fase invio valori inputJson{Environment.NewLine}{exc}");
+ answ = "NO";
+ }
+ }
+ return answ;
+ }
+
///
/// Effettivo processing FLogJson
///
@@ -1349,47 +1333,6 @@ namespace MP.IOC.Controllers
return answ;
}
- ///
- /// Processing effettivo EvListJson
- ///
- ///
- ///
- ///
- private async Task processEvListJsonAsync(string idxMacc, string content)
- {
- string answ = "";
- int insDone = 0;
-
- // procedo a deserializzare in blocco l'oggetto...
- EvJsonPayloadDto receivedData = JsonConvert.DeserializeObject(content) ?? new();
-
- // se ho qualcosa da processare...
- if (receivedData != null)
- {
- // per ogni valore --> processo!
- try
- {
- foreach (var item in receivedData.eventList)
- {
- // formato datetime come yyyyMMddHHmmssfff -->es: 20181223180600000
- answ = await DService.ProcessInputAsync(idxMacc, item.valore, item.dtEve.ToString("yyyyMMddHHmmssfff"), item.dtCurr.ToString("yyyyMMddHHmmssfff"), item.cnt.ToString());
- insDone++;
- }
- // se vuoto --> OK!
- if (string.IsNullOrEmpty(answ))
- {
- answ = $"OK {insDone} processed";
- }
- }
- catch (Exception exc)
- {
- Log.Error($"Errore in fase invio valori inputJson{Environment.NewLine}{exc}");
- answ = "NO";
- }
- }
- return answ;
- }
-
///
/// Effettua processing UserLog
///
diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs
index aa67aa96..9de837b8 100644
--- a/MP.IOC/Data/MpDataService.cs
+++ b/MP.IOC/Data/MpDataService.cs
@@ -946,6 +946,80 @@ namespace MP.IOC.Data
return fatto;
}
+ ///
+ /// Task completo sistemazione dossier quotidiani mancanti
+ ///
+ ///
+ ///
+ public async Task FixDailyDossierAsync(string idxMacc)
+ {
+ string answ = "";
+ // verifico se si possa processare, ovvero tab ConfFlux x macchina sia valorizzata...
+ var confDataMach = await ConfFluxMach(idxMacc);
+ if (confDataMach.Count > 0)
+ {
+ // determino ultima data da processare (inizio oggi, a mezzanotte)
+ DateTime dtTo = DateTime.Today;
+ DateTime dtFrom = dtTo;
+ // determino data di partenza, prima da dossier esistenti
+ var listaDoss = await DossierLastByMachAsync(idxMacc);
+ if (listaDoss.Count > 0)
+ {
+ // primo giorno DOPO ultima registrazione
+ dtFrom = listaDoss.OrderByDescending(x => x).FirstOrDefault().AddDays(1);
+ }
+ else
+ {
+ // ...o da fluxLog acquisiti...
+ var listaFL = await FluxLogFirstByMachAsync(idxMacc);
+ if (listaFL.Count > 0)
+ {
+ // giorno successivo a prima registrazione
+ dtFrom = listaFL.OrderBy(x => x).FirstOrDefault().AddDays(1);
+ }
+ }
+ string caller = $"takeFlogSnapshot({idxMacc})";
+ DateTime dtStart = dtFrom.Date;
+ DateTime dtEnd = dtFrom;
+ // max 10 dossier alla volta (se non configurato diversamente)
+ int maxAdd = 1;
+ string confVal = await tryGetConfig("IO_numDossMaxCreate");
+ if (!string.IsNullOrEmpty(confVal))
+ {
+ int.TryParse(confVal, out maxAdd);
+ }
+
+ if (dtStart < dtTo)
+ {
+ // verifico di avere almeno 1 dossier da produrre ciclo fino ad esaurire le
+ // date da processare
+ while (dtStart < dtTo && maxAdd > 0)
+ {
+ // sistemo end
+ dtEnd = dtStart.AddDays(1);
+ // effettuo chiamata registrazione snapshot!
+ answ = await FluxLogSaveSnapshotAsync(idxMacc, dtStart, dtEnd, caller);
+ // incremento START...
+ dtStart = dtEnd;
+ // riduco il numero di chiamate ammesse x singolo task
+ maxAdd--;
+ }
+ // reset cache dossier...
+ await DossierLastByMachResetAsync(idxMacc);
+ answ = "OK";
+ }
+ else
+ {
+ Log.Warn("FixDailyDossierAsync | NO more to add");
+ }
+ }
+ else
+ {
+ Log.Warn("FixDailyDossierAsync | NO ConfFluxData");
+ }
+ return answ;
+ }
+
public async Task FlushRedisCache()
{
await Task.Delay(1);
@@ -1209,7 +1283,7 @@ namespace MP.IOC.Data
///
///
- /// id odl da cercare
+ /// idxMacc odl da cercare
///
public async Task> ListGiacenze(int IdxOdl)
{
@@ -1385,7 +1459,7 @@ namespace MP.IOC.Data
}
///
- /// Elenco id Macchine che abbiano dati FLuxLog, nel periodo indicato
+ /// Elenco idxMacc Macchine che abbiano dati FLuxLog, nel periodo indicato
///
///
///
@@ -3880,6 +3954,144 @@ namespace MP.IOC.Data
}
}
+ ///
+ /// Restituisce l'elenco codici flusso (da confFlux) x una macchina (se presenti) Impiegata
+ /// anche cache redis
+ ///
+ ///
+ ///
+ private async Task> ConfFluxMach(string idxMacchina)
+ {
+ List resultList = new List();
+ string tag = string.IsNullOrEmpty(idxMacchina) ? "ALL" : idxMacchina;
+ var currKey = $"{Utils.redisConfFlux}:{tag}";
+ RedisValue rawData = await redisDb.StringGetAsync(currKey);
+ if (rawData.HasValue)
+ {
+ resultList = JsonConvert.DeserializeObject>($"{rawData}") ?? new();
+ }
+ else
+ {
+ var dbData = await IocDbController.ConfFluxFiltAsync(idxMacchina);
+ resultList = dbData
+ .Select(x => x.CodFlux)
+ .ToList();
+ // serializzo e salvo...
+ rawData = JsonConvert.SerializeObject(resultList);
+ await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache));
+ }
+ if (resultList == null)
+ {
+ resultList = new();
+ }
+ return resultList;
+ }
+
+ ///
+ /// Restituisce l'elenco delle date dei dossier x una macchina (se presenti) Impiegata anche
+ /// cache redis
+ ///
+ ///
+ ///
+ private async Task> DossierLastByMachAsync(string idxMacchina)
+ {
+ List resultList = new List();
+
+ var currKey = $"{Utils.redisDossByMacLast}:{idxMacchina}";
+ RedisValue rawData = await redisDb.StringGetAsync(currKey);
+ if (rawData.HasValue)
+ {
+ resultList = JsonConvert.DeserializeObject>($"{rawData}") ?? new();
+ }
+ else
+ {
+ var dbData = await IocDbController.DossGetLastByMaccAsync(idxMacchina);
+ resultList = dbData
+ .Select(x => x.DtRif)
+ .ToList();
+ // serializzo e salvo...
+ rawData = JsonConvert.SerializeObject(resultList);
+ await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache));
+ }
+ if (resultList == null)
+ {
+ resultList = new List();
+ }
+ return resultList;
+ }
+
+ ///
+ /// Svuota la cache redis x l'elenco delle righe di confFlux x una macchina (se presenti)
+ ///
+ ///
+ ///
+ private async Task DossierLastByMachResetAsync(string idxMacchina)
+ {
+ bool answ = false;
+ var currKey = $"{Utils.redisDossByMacLast}:{idxMacchina}";
+ await redisDb.KeyDeleteAsync(currKey);
+ return answ;
+ }
+
+ ///
+ /// Restituisce l'elenco delle data-ora di confFlux x una macchina (se presenti) Impiegata
+ /// anche cache redis
+ ///
+ ///
+ /// num record da recuperare
+ ///
+ private async Task> FluxLogFirstByMachAsync(string idxMacchina, int numMax = 10)
+ {
+ List resultList = new List();
+
+ var currKey = $"{Utils.redisFluxByMacFirst}:{idxMacchina}";
+ RedisValue rawData = await redisDb.StringGetAsync(currKey);
+ if (rawData.HasValue)
+ {
+ resultList = JsonConvert.DeserializeObject>($"{rawData}") ?? new();
+ }
+ else
+ {
+ var dbData = await IocDbController.FluxLogFirstByMaccAsync(idxMacchina, numMax);
+ resultList = dbData
+ .Select(x => x.dtEvento)
+ .ToList();
+ // serializzo e salvo...
+ rawData = JsonConvert.SerializeObject(resultList);
+ await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache));
+ }
+ if (resultList == null)
+ {
+ resultList = new List();
+ }
+ return resultList;
+ }
+
+ ///
+ /// Effettua vera chiamata x salvataggio snapshot dati FluxLog
+ ///
+ ///
+ ///
+ ///
+ ///
+ private async Task FluxLogSaveSnapshotAsync(string id, DateTime dtStart, DateTime dtEnd, string caller)
+ {
+ string answ = "";
+ DateTime dataOraEvento = DateTime.Now;
+ Log.Debug($"{caller} | Richiesta snapshot dati FluxLog macchina: id: {id} | periodo: {dtStart} - {dtEnd}");
+ try
+ {
+ bool fatto = await IocDbController.FluxLogTakeSnapshotLastAsync(id, dtStart, dtEnd);
+ answ = fatto ? "OK" : "KO";
+ }
+ catch (Exception exc)
+ {
+ Log.Error($"Errore in {caller}{Environment.NewLine}{exc}");
+ answ = "NO";
+ }
+ return answ;
+ }
+
///
/// Recupero info ODL corrente da dati prod macchina
///