Compare commits
130 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 93f4f09b85 | |||
| aebae6b406 | |||
| a2bf5f4a8b | |||
| 759373b5a4 | |||
| 0ea3ee6341 | |||
| a0ffe1bc6c | |||
| 6e75f590bb | |||
| 12473b5088 | |||
| f6406f833f | |||
| a21cd16362 | |||
| d659afacc2 | |||
| 56c3ba4064 | |||
| 8d0292d789 | |||
| 419863a684 | |||
| f56a7e5164 | |||
| 0cf6ecd38f | |||
| 094ce0d181 | |||
| b4de1c9880 | |||
| 67f0f74fbe | |||
| d00b4bbb8b | |||
| dd63bb292d | |||
| 57bc790074 | |||
| 41a00ffa45 | |||
| 633b5dda6e | |||
| 5d6bef0fc8 | |||
| d24b2ada0c | |||
| 0a9ccffe28 | |||
| 207d305327 | |||
| caa4b4f590 | |||
| e45cb0595e | |||
| 77e7e39985 | |||
| b2e9ae76d4 | |||
| 460eb769dc | |||
| 5e38749c65 | |||
| 91083b6c4a | |||
| de562b1287 | |||
| 470c9a2191 | |||
| 26e36e7124 | |||
| bef0ee6000 | |||
| 9e4822d529 | |||
| 7f9685a007 | |||
| d8978f84f3 | |||
| 946f157cff | |||
| 47f1ae5cb2 | |||
| a428ecb4ab | |||
| c4b6f289af | |||
| 1cc90d2459 | |||
| e438fa3930 | |||
| 6c88e2687a | |||
| fba6eca9cc | |||
| 330e208866 | |||
| 013b21e055 | |||
| 8e763e52a4 | |||
| d5f5cf9b11 | |||
| a4810826f8 | |||
| 7f3a73ba0e | |||
| d108b74f7d | |||
| 16278b6ae0 | |||
| 1f10e8537d | |||
| a6408ba2af | |||
| 924a5017f5 | |||
| 5bcc32023a | |||
| e87d14bd8a | |||
| cbaa16a850 | |||
| cc272cac29 | |||
| b032b6bbb9 | |||
| 91174a2f67 | |||
| 2a96b63f17 | |||
| 08634b5656 | |||
| 5d63c41cf8 | |||
| de3ce0f114 | |||
| 2ec29bbe68 | |||
| 7416f6e7b5 | |||
| a604e5741b | |||
| 923094054b | |||
| c28dae0c8d | |||
| 6fb9cbe085 | |||
| 4f03661182 | |||
| dd26773590 | |||
| 75894fa3c7 | |||
| 9fc73c5c85 | |||
| 0f9c01ae82 | |||
| ea60e785f9 | |||
| 1849101028 | |||
| a1f9a958b3 | |||
| fd585aee93 | |||
| 4ecd647b1b | |||
| 8aace3fb82 | |||
| 4acf2a2970 | |||
| 9b6c449354 | |||
| c11e05123d | |||
| 862960bae4 | |||
| 4cdf0033cd | |||
| 25b75101e9 | |||
| 50dbe7691f | |||
| 9c762969ac | |||
| 09b2008f25 | |||
| baa42fbd2f | |||
| 90d4a46087 | |||
| 5b12ac47d3 | |||
| 81fd2820df | |||
| 624d6d3411 | |||
| 21fa81f09c | |||
| 0795cae1d5 | |||
| 6a0eeba75f | |||
| b476829a73 | |||
| 78c90a8e93 | |||
| 9515906e20 | |||
| c929e3cf65 | |||
| 43f0569fe3 | |||
| 2807bd9edc | |||
| c4a682cc24 | |||
| 5ef3139bd5 | |||
| 2a679504eb | |||
| 10f9ed08a8 | |||
| 374902d5f0 | |||
| 59b43f6005 | |||
| 1ad6222543 | |||
| b97394b067 | |||
| 9d35441b07 | |||
| f71ec80c16 | |||
| d1b6c804be | |||
| 391078dd06 | |||
| 55c6790d7b | |||
| 66642032bf | |||
| da76bc96f8 | |||
| 23fbacba87 | |||
| b9d67616cb | |||
| 79da055771 | |||
| 7e879fe2f6 |
@@ -98,6 +98,25 @@ namespace MP.Data.Controllers
|
||||
return ListValuesFilt("AnagArticoli", "Tipo");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco codice articoli che abbiano dati Dossier
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<string> ArticleWithDossier()
|
||||
{
|
||||
List<string> dbResult = new List<string>();
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
dbResult = dbCtx
|
||||
.DbSetDossiers
|
||||
.AsNoTracking()
|
||||
.Select(i => i.OdlNav.CodArticolo)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Eliminazione Record
|
||||
/// </summary>
|
||||
@@ -183,7 +202,7 @@ namespace MP.Data.Controllers
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
dbResult = dbCtx
|
||||
.DbSetArticoli
|
||||
.DbSetArticoli
|
||||
.FromSqlRaw("EXEC stp_ART_getUsed")
|
||||
.AsNoTracking()
|
||||
.ToList();
|
||||
@@ -313,10 +332,11 @@ namespace MP.Data.Controllers
|
||||
/// macchina (ordinato x data registrazione)
|
||||
/// </summary>
|
||||
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data macchina</param>
|
||||
/// <param name="DtRef">Data di riferimento (Massima) per estrazioen records</param>
|
||||
/// <param name="MaxRec">numero massimo record da restituire</param>
|
||||
/// <param name="CodArticolo">* = tutti, altrimenti solo x un dato articolo</param>
|
||||
/// <param name="DtStart">Data minima per estrazione records</param>
|
||||
/// <param name="DtEnd">Data Massima per estrazione records</param>
|
||||
/// <returns></returns>
|
||||
public List<Dossiers> DossiersGetLastFilt(string IdxMacchina, DateTime DtRef, int MaxRec)
|
||||
public List<Dossiers> DossiersGetLastFilt(string IdxMacchina, string CodArticolo, DateTime DtStart, DateTime DtEnd)
|
||||
{
|
||||
List<Dossiers> dbResult = new List<Dossiers>();
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
@@ -324,9 +344,11 @@ namespace MP.Data.Controllers
|
||||
dbResult = dbCtx
|
||||
.DbSetDossiers
|
||||
.AsNoTracking()
|
||||
.Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && x.DtRif <= DtRef)
|
||||
.Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && (CodArticolo == "*" || x.OdlNav.CodArticolo == CodArticolo) && (x.DtRif >= DtStart && x.DtRif <= DtEnd))
|
||||
.Include(m => m.MachineNav)
|
||||
.Include(o => o.OdlNav)
|
||||
.Include(a => a.OdlNav.ArticoloNav)
|
||||
.OrderByDescending(x => x.DtRif)
|
||||
.Take(MaxRec)
|
||||
.ToList();
|
||||
}
|
||||
return dbResult;
|
||||
@@ -355,6 +377,67 @@ namespace MP.Data.Controllers
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua salvataggio snapshot parametri (con stored) + svuota eventuale cache redis
|
||||
/// </summary>
|
||||
/// <param name="idxMacchina">macchina</param>
|
||||
/// <param name="dtMin">Data min x selezione</param>
|
||||
/// <param name="dtMax">Data MAX x selezione</param>
|
||||
public bool DossiersTakeParamsSnapshotLast(string idxMacchina, DateTime dtMin, DateTime dtMax)
|
||||
{
|
||||
bool answ = false;
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina);
|
||||
var pDtMin = new SqlParameter("@DtMin", dtMin);
|
||||
var pDtMax = new SqlParameter("@DtMax", dtMax);
|
||||
|
||||
var dbResult = dbCtx
|
||||
.Database
|
||||
.ExecuteSqlRaw("EXEC stp_FL_TakeSnapshotLast @IdxMacchina,@DtMin,@DtMax", pIdxMacchina, pDtMin, pDtMax);
|
||||
answ = true;
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update ddel campo VALORE di un dossier (che contiene json flux log serializzati)
|
||||
/// </summary>
|
||||
/// <param name="editRec">record dossier da modificare</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> DossiersUpdateValore(Dossiers editRec)
|
||||
{
|
||||
bool fatto = false;
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
var currRec = dbCtx
|
||||
.DbSetDossiers
|
||||
.Where(x => x.IdxDossier == editRec.IdxDossier)
|
||||
.FirstOrDefault();
|
||||
if (currRec != null)
|
||||
{
|
||||
currRec.Valore = editRec.Valore;
|
||||
dbCtx.Entry(currRec).State = EntityState.Modified;
|
||||
}
|
||||
else
|
||||
{
|
||||
dbCtx
|
||||
.DbSetDossiers
|
||||
.Add(editRec);
|
||||
}
|
||||
await dbCtx.SaveChangesAsync();
|
||||
fatto = true;
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione durante DossiersUpdateRecord{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco valori link (x home e navMenu laterale)
|
||||
/// </summary>
|
||||
@@ -364,6 +447,32 @@ namespace MP.Data.Controllers
|
||||
return ListLinkFilt("SpecLink");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aggiunta record EventList
|
||||
/// </summary>
|
||||
/// <param name="newRec"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> EvListInsert(EventListModel newRec)
|
||||
{
|
||||
bool fatto = false;
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
var currRec = dbCtx
|
||||
.DbSetEvList
|
||||
.Add(newRec);
|
||||
await dbCtx.SaveChangesAsync();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione durante EvListInsert{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
await Task.Delay(1);
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco ultimi n record flux log dato macchina e flusso (ordinato x data registrazione)
|
||||
/// </summary>
|
||||
@@ -409,17 +518,21 @@ namespace MP.Data.Controllers
|
||||
/// <param name="inCorso">Stato ODL: true=in corso/completato</param>
|
||||
/// <param name="codArt">Cod articolo</param>
|
||||
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
|
||||
/// <param name="startDate">Data inizio</param>
|
||||
/// <param name="endDate">Data fine</param>
|
||||
/// <returns></returns>
|
||||
public List<ODLModel> ListODLFilt(bool inCorso, string codArt, string keyRichPart)
|
||||
public List<ODLModel> ListODLFilt(bool inCorso, string codArt, string keyRichPart, string IdxMacchina, DateTime startDate, DateTime endDate)
|
||||
{
|
||||
List<ODLModel> dbResult = new List<ODLModel>();
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
dbResult = dbCtx
|
||||
.DbSetODL
|
||||
.Where(x => ((inCorso && x.DataFine == null) || (!inCorso && x.DataFine != null)) && (x.KeyRichiesta.Contains(keyRichPart) || keyRichPart == "*") && (codArt == "*" || x.CodArticolo.Contains(codArt)))
|
||||
.Where(x => ((inCorso && x.DataFine == null) || ((!inCorso && x.DataFine != null) && x.DataInizio >= startDate && x.DataInizio <= endDate)) && (x.KeyRichiesta.Contains(keyRichPart) || keyRichPart == "*") && (x.IdxMacchina.Contains(IdxMacchina) || IdxMacchina == "*") && (codArt == "*" || x.CodArticolo.Contains(codArt)))
|
||||
.AsNoTracking()
|
||||
.OrderBy(x => x.IdxOdl)
|
||||
.Include(m => m.MachineNav)
|
||||
.Include(a => a.ArticoloNav)
|
||||
.OrderByDescending(x => x.IdxOdl)
|
||||
.ToList();
|
||||
}
|
||||
return dbResult;
|
||||
@@ -440,6 +553,8 @@ namespace MP.Data.Controllers
|
||||
.DbSetPODL
|
||||
.Where(x => (x.IdxOdl == 0) && (x.KeyRichiesta.Contains(keyRichPart) || keyRichPart == "*") && (codArt == "*" || x.CodArticolo.Contains(codArt)))
|
||||
.AsNoTracking()
|
||||
.Include(m => m.MachineNav)
|
||||
.Include(a => a.ArticoloNav)
|
||||
.OrderBy(x => x.InsertDate)
|
||||
.ToList();
|
||||
}
|
||||
@@ -486,20 +601,23 @@ namespace MP.Data.Controllers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco id Macchine che abbiano dati FLuxLog
|
||||
/// Elenco id Macchine che abbiano dati FLuxLog, nel periodo indicato
|
||||
/// </summary>
|
||||
/// <param name="dtStart"></param>
|
||||
/// <param name="dtEnd"></param>
|
||||
/// <returns></returns>
|
||||
public List<string> MacchineWithFlux()
|
||||
public async Task<List<string>> MacchineWithFlux(DateTime dtStart, DateTime dtEnd)
|
||||
{
|
||||
List<string> dbResult = new List<string>();
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
dbResult = dbCtx
|
||||
.DbSetFluxLog
|
||||
.AsNoTracking()
|
||||
.Select(i => i.IdxMacchina)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
dbResult = await dbCtx
|
||||
.DbSetFluxLog
|
||||
.AsNoTracking()
|
||||
.Where(x => x.dtEvento >= dtStart && x.dtEvento <= dtEnd)
|
||||
.Select(i => i.IdxMacchina)
|
||||
.Distinct()
|
||||
.ToListAsync();
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
@@ -524,6 +642,147 @@ namespace MP.Data.Controllers
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Chiusura ODL con eventuale conferma pezzi
|
||||
/// </summary>
|
||||
/// <param name="idxOdl">idx odl da chiudere</param>
|
||||
/// <param name="idxMacchina">idx macchina</param>
|
||||
/// <param name="matrOpr">matricola operatore</param>
|
||||
/// <param name="confPezzi">indica se confermare i pezzi prima di chiudere ODL</param>
|
||||
/// <param name="confRett">Conferma con rettifica (ev 121) x pezzi lasciati in macchina</param>
|
||||
/// <param name="modoConfProd">Modo conferma produzione (0=periodo, 1=giorno, 2=turno)</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> ODLClose(int idxOdl, string idxMacchina, int matrOpr, bool confPezzi, bool confRett, int modoConfProd)
|
||||
{
|
||||
bool fatto = false;
|
||||
if (idxOdl > 0)
|
||||
{
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
DateTime adesso = DateTime.Now;
|
||||
// preparo i parametri
|
||||
var IdxODL = new SqlParameter("@IdxODL", idxOdl);
|
||||
var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina);
|
||||
|
||||
// FARE FIXME TODO !!! da valutare casi setup/autoconferma...
|
||||
#if false
|
||||
// controllo se HO pezzi da confermare...
|
||||
var statoProd = StatoProdMacchina(idxMacchina);
|
||||
if (statoProd.pezziNonConfermati < 1)
|
||||
{ }
|
||||
#endif
|
||||
|
||||
// se richiesto confermo produzione
|
||||
if (confPezzi)
|
||||
{
|
||||
var MatrApp = new SqlParameter("@MatrApp", idxMacchina);
|
||||
|
||||
/* ----------------------------------
|
||||
* CONFERMA PEZZI
|
||||
*
|
||||
* condizioni da verificare:
|
||||
* - gestione rettifica (ev121) / pezzi da LASCIARE in macchina
|
||||
* - conferma a zero pezzi (setup) oppure con i pezzi fatti e non ancora confermati
|
||||
*
|
||||
*
|
||||
*
|
||||
* */
|
||||
|
||||
// recupero i dati dei pezzi da confermare... con DbSetPzProd + exec
|
||||
// stp_PzProd_getByMacchina 'SIMUL_01'
|
||||
|
||||
// stp_ConfermaProduzCompletaFull
|
||||
/*
|
||||
* @idxMacchina NVARCHAR(50),
|
||||
@MatrApp INT,
|
||||
@dataFrom DATETIME,
|
||||
@dataTo DATETIME,
|
||||
@pezziConf INT,
|
||||
@pezziLasciati INT, -- pezzi lasciati = evento 121 (-) pre conferma e (+) dopo --> da lasciare in macchina post conferma
|
||||
@pezziScar INT = 0, -- pezzi scartati (registrati da 2016.11.20) DA INDICARE COME VALORE > 0!!! sennò faccio ABS...
|
||||
@TipoConf INT = 0, -- Tipo intervallo conferma: 0 = periodo intero, 1 = per giorni, 2 = per turni
|
||||
@DataOraApp DATETIME = NULL, -- di norma GETDATE() nel programma - serve per ricalcolo
|
||||
@TestConferma BIT = 1 -- TestConferma : 1 = verifica conf. duplicata e inserisci in ElencoConfermeProd, 0 = nessuna verifica e inserimento ( per ricalcolo )
|
||||
*/
|
||||
}
|
||||
|
||||
// ora chiudo ODL
|
||||
try
|
||||
{
|
||||
var dbResult = await dbCtx
|
||||
.DbSetStatOdl
|
||||
.FromSqlRaw("EXEC stp_ODL_fineProd @IdxODL, @IdxMacchina", IdxODL, IdxMacchina)
|
||||
.AsNoTracking()
|
||||
.ToListAsync();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione durante ODLClose{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
}
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero odl data chiave
|
||||
/// </summary>
|
||||
/// <param name="idxOdl"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public ODLModel OdlGetByKey(int idxOdl)
|
||||
{
|
||||
ODLModel dbResult = new ODLModel();
|
||||
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
dbResult = dbCtx
|
||||
.DbSetODL
|
||||
.FirstOrDefault(x => x.IdxOdl == idxOdl);
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero Odl CORRENTI
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<ODLModel> OdlGetCurrent()
|
||||
{
|
||||
List<ODLModel> dbResult = new List<ODLModel>();
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
dbResult = dbCtx
|
||||
.DbSetODL
|
||||
.Where(x => x.DataInizio != null && x.DataFine == null)
|
||||
.ToList();
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Statistiche ODL calcolate (da stored stp_STAT_ODL)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<StatODLModel>> OdlStart(int IdxOdl)
|
||||
{
|
||||
List<StatODLModel> dbResult = new List<StatODLModel>();
|
||||
if (IdxOdl > 0)
|
||||
{
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
var IdxODL = new SqlParameter("@IdxODL", IdxOdl);
|
||||
|
||||
dbResult = await dbCtx
|
||||
.DbSetStatOdl
|
||||
.FromSqlRaw("EXEC stp_STAT_ODL @IdxODL", IdxODL)
|
||||
.AsNoTracking()
|
||||
.ToListAsync();
|
||||
}
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco parametri validi x una data macchina
|
||||
/// </summary>
|
||||
@@ -538,13 +797,89 @@ namespace MP.Data.Controllers
|
||||
.DbSetFluxLog
|
||||
.AsNoTracking()
|
||||
.Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina))
|
||||
.Take(1000)
|
||||
.Select(i => i.CodFlux)
|
||||
.Distinct()
|
||||
.OrderBy(x => x)
|
||||
.ToList();
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero PODL da chiave
|
||||
/// </summary>
|
||||
/// <param name="idxPODL"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PODLModel> PODL_getByKey(int idxPODL)
|
||||
{
|
||||
PODLModel dbResult = new PODLModel();
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
dbResult = dbCtx
|
||||
.DbSetPODL
|
||||
.AsNoTracking()
|
||||
.Where(x => x.IdxPromessa == idxPODL)
|
||||
.FirstOrDefault();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione durante PODL_getByKey{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
await Task.Delay(1);
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Avvio setup ODL da PODL
|
||||
/// </summary>
|
||||
/// <param name="editRec"></param>
|
||||
/// <param name="matrOpr"></param>
|
||||
/// <param name="tcRich"></param>
|
||||
/// <param name="pzPallet"></param>
|
||||
/// <param name="note"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> PODL_startSetup(PODLModel editRec, int matrOpr, double tcRich, int pzPallet, string note)
|
||||
{
|
||||
bool answ = false;
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
try
|
||||
{
|
||||
var currRec = dbCtx
|
||||
.DbSetPODL
|
||||
.AsNoTracking()
|
||||
.Where(x => x.IdxPromessa == editRec.IdxPromessa)
|
||||
.FirstOrDefault();
|
||||
|
||||
if (currRec != null)
|
||||
{
|
||||
// eseguo stored attrezzaggio
|
||||
var IdxPromessa = new SqlParameter("@idxPromessa", editRec.IdxPromessa);
|
||||
var MatrOpr = new SqlParameter("@MatrOpr", matrOpr);
|
||||
var IdxMacchina = new SqlParameter("@IdxMacchina", editRec.IdxMacchina);
|
||||
var TCRichAttr = new SqlParameter("@TCRichAttr", tcRich);
|
||||
var PzPallet = new SqlParameter("@PzPallet", pzPallet);
|
||||
var Note = new SqlParameter("@Note", note);
|
||||
var callResult = await dbCtx
|
||||
.Database
|
||||
.ExecuteSqlRawAsync("EXEC stp_ODL_inizioSetupPromessa @idxPromessa, @MatrOpr, @IdxMacchina, @TCRichAttr, @PzPallet, @Note", IdxPromessa, MatrOpr, IdxMacchina, TCRichAttr, PzPallet, Note);
|
||||
|
||||
answ = true;
|
||||
}
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
Log.Error($"Eccezione durante PODL_doSetup{Environment.NewLine}{exc}");
|
||||
}
|
||||
}
|
||||
await Task.Delay(1);
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Eliminazione Record
|
||||
/// </summary>
|
||||
@@ -600,6 +935,8 @@ namespace MP.Data.Controllers
|
||||
currRec.KeyRichiesta = editRec.KeyRichiesta;
|
||||
currRec.NumPezzi = editRec.NumPezzi;
|
||||
currRec.Tcassegnato = editRec.Tcassegnato;
|
||||
currRec.Attivabile = editRec.Attivabile;
|
||||
currRec.Note = editRec.Note;
|
||||
dbCtx.Entry(currRec).State = EntityState.Modified;
|
||||
}
|
||||
else
|
||||
@@ -644,6 +981,26 @@ namespace MP.Data.Controllers
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stato prod macchina
|
||||
/// </summary>
|
||||
/// <param name="idxMacchina"></param>
|
||||
/// <returns></returns>
|
||||
public StatoProdModel StatoProdMacchina(string idxMacchina)
|
||||
{
|
||||
StatoProdModel dbResult = new StatoProdModel();
|
||||
using (var dbCtx = new MoonProContext(_configuration))
|
||||
{
|
||||
var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina);
|
||||
dbResult = dbCtx
|
||||
.DbSetStatoProd
|
||||
.FromSqlRaw("EXEC stp_PzProd_getByMacchina @IdxMacchina", IdxMacchina)
|
||||
.AsNoTracking()
|
||||
.FirstOrDefault();
|
||||
}
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
@@ -13,6 +13,10 @@ namespace MP.Data.DTO
|
||||
{
|
||||
public class DossierFluxLogDTO
|
||||
{
|
||||
public List<FluxLog> ODL { get; set; } = new List<FluxLog>();
|
||||
/// <summary>
|
||||
/// Elenco valori FluxLogDTO serializzato (compreso valori edit)
|
||||
/// </summary>
|
||||
public List<FluxLogDTO> ODL { get; set; } = new List<FluxLogDTO>();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MP.Data.DTO
|
||||
{
|
||||
public class FluxLogDTO
|
||||
{
|
||||
public string IdxMacchina { get; set; }
|
||||
|
||||
public DateTime dtEvento { get; set; }
|
||||
|
||||
public string CodFlux { get; set; }
|
||||
|
||||
public string Valore { get; set; }
|
||||
|
||||
public string ValoreEdit { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -23,10 +23,27 @@ namespace MP.Data.DatabaseModels
|
||||
public DateTime DtRif { get; set; }
|
||||
|
||||
[MaxLength(50)]
|
||||
public string IdxMacchina { get; set; }
|
||||
public string IdxMacchina { get; set; } = "";
|
||||
[MaxLength(50)]
|
||||
public string CodArticolo { get; set; } = "";
|
||||
|
||||
public int IdxODL { get; set; }
|
||||
public string Valore { get; set; }
|
||||
public int IdxODL { get; set; } = 0;
|
||||
|
||||
public string Valore { get; set; } = "";
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Navigazione oggetto Machine
|
||||
/// </summary>
|
||||
[ForeignKey("IdxMacchina")]
|
||||
public virtual Macchine MachineNav { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Navigazione oggetto ODL
|
||||
/// </summary>
|
||||
[ForeignKey("IdxODL")]
|
||||
public virtual ODLModel OdlNav { get; set; } = null!;
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
|
||||
#nullable disable
|
||||
// <Auto-Generated>
|
||||
// This is here so CodeMaid doesn't reorganize this document
|
||||
// </Auto-Generated>
|
||||
namespace MP.Data.DatabaseModels
|
||||
{
|
||||
[Table("EventList")]
|
||||
public partial class EventListModel
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
[MaxLength(50)]
|
||||
public string IdxMacchina { get; set; } = "NA";
|
||||
public DateTime? InizioStato { get; set; } = DateTime.Now;
|
||||
public int IdxTipo { get; set; } = 0;
|
||||
|
||||
[MaxLength(50)]
|
||||
public string CodArticolo { get; set; } = "";
|
||||
|
||||
[MaxLength(250)]
|
||||
public string Value { get; set; } = "";
|
||||
|
||||
public int MatrOpr { get; set; } = 0;
|
||||
|
||||
[MaxLength(20)]
|
||||
public string pallet { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// Navigazione oggetto Machine
|
||||
/// </summary>
|
||||
[ForeignKey("IdxMacchina")]
|
||||
public virtual Macchine MachineNav { get; set; } = null!;
|
||||
/// <summary>
|
||||
/// Navigazione oggetto Articolo
|
||||
/// </summary>
|
||||
[ForeignKey("CodArticolo")]
|
||||
public virtual AnagArticoli ArticoloNav { get; set; } = null!;
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,37 @@ namespace MP.Data.DatabaseModels
|
||||
[MaxLength(50)]
|
||||
public string CodCli { get; set; } = "";
|
||||
|
||||
[NotMapped]
|
||||
public string DurataMinuti
|
||||
{
|
||||
get
|
||||
{
|
||||
string answ = "";
|
||||
DateTime end = DataFine != null ? (DateTime)DataFine : DateTime.Now;
|
||||
var tsDurata = (end).Subtract((DateTime)DataInizio);
|
||||
if (tsDurata.TotalDays < 1)
|
||||
{
|
||||
answ = $"{tsDurata.Hours:00}h {tsDurata.Minutes:00}'";
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = $"{tsDurata.Days}gg {tsDurata.Hours:00}h";
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Navigazione oggetto Machine
|
||||
/// </summary>
|
||||
[ForeignKey("IdxMacchina")]
|
||||
public virtual Macchine MachineNav { get; set; } = null!;
|
||||
/// <summary>
|
||||
/// Navigazione oggetto Articolo
|
||||
/// </summary>
|
||||
[ForeignKey("CodArticolo")]
|
||||
public virtual AnagArticoli ArticoloNav { get; set; } = null!;
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,17 @@ namespace MP.Data.DatabaseModels
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Navigazione oggetto Machine
|
||||
/// </summary>
|
||||
[ForeignKey("IdxMacchina")]
|
||||
public virtual Macchine MachineNav { get; set; } = null!;
|
||||
/// <summary>
|
||||
/// Navigazione oggetto Articolo
|
||||
/// </summary>
|
||||
[ForeignKey("CodArticolo")]
|
||||
public virtual AnagArticoli ArticoloNav { get; set; } = null!;
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
|
||||
#nullable disable
|
||||
// <Auto-Generated>
|
||||
// This is here so CodeMaid doesn't reorganize this document
|
||||
// </Auto-Generated>
|
||||
namespace MP.Data.DatabaseModels
|
||||
{
|
||||
public partial class StatODLModel
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
[Key]
|
||||
public int IdxStato { get; set; }
|
||||
public string Descrizione { get; set; } = "";
|
||||
public string Semaforo { get; set; }
|
||||
public string Css { get; set; }
|
||||
public double TotDurata { get; set; }
|
||||
|
||||
#endregion Public Properties
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
#nullable disable
|
||||
// <Auto-Generated>
|
||||
// This is here so CodeMaid doesn't reorganize this document
|
||||
// </Auto-Generated>
|
||||
namespace MP.Data.DatabaseModels
|
||||
{
|
||||
public partial class StatoProdModel
|
||||
{
|
||||
[Key]
|
||||
public string idxMacchina { get; set; } = "NA";
|
||||
public int pezziNonConfermati { get; set; } = 0;
|
||||
public DateTime DataFrom { get; set; } = DateTime.Now;
|
||||
public DateTime DataTo { get; set; } = DateTime.Now;
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,9 @@ namespace MP.Data
|
||||
public virtual DbSet<PODLModel> DbSetPODL { get; set; }
|
||||
public virtual DbSet<FluxLog> DbSetFluxLog { get; set; }
|
||||
public virtual DbSet<Dossiers> DbSetDossiers { get; set; }
|
||||
public virtual DbSet<StatODLModel> DbSetStatOdl { get; set; }
|
||||
public virtual DbSet<StatoProdModel> DbSetStatoProd { get; set; }
|
||||
public virtual DbSet<EventListModel> DbSetEvList { get; set; }
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
@@ -298,6 +301,12 @@ namespace MP.Data
|
||||
|
||||
});
|
||||
|
||||
modelBuilder.Entity<EventListModel>(entity =>
|
||||
{
|
||||
entity.HasKey(e => new { e.IdxMacchina, e.InizioStato, e.IdxTipo});
|
||||
|
||||
});
|
||||
|
||||
OnModelCreatingPartial(modelBuilder);
|
||||
}
|
||||
|
||||
|
||||
+39
-2
@@ -57,17 +57,54 @@ namespace MP.Data
|
||||
return answ;
|
||||
}
|
||||
|
||||
public static async Task SaveToCsv<T>(List<T> reportData, string path)
|
||||
/// <summary>
|
||||
/// Effettua salvataggio in file di un generico oggetto in formato CSV
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="reportData"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="separator">Separatore da impiegare</param>
|
||||
/// <returns></returns>
|
||||
public static async Task SaveToCsv<T>(List<T> reportData, string path, char separator)
|
||||
{
|
||||
var lines = new List<string>();
|
||||
IEnumerable<PropertyDescriptor> props = TypeDescriptor.GetProperties(typeof(T)).OfType<PropertyDescriptor>();
|
||||
var header = string.Join(";", props.ToList().Select(x => x.Name));
|
||||
lines.Add(header);
|
||||
var valueLines = reportData.Select(row => string.Join(";", header.Split(';').Select(a => row.GetType().GetProperty(a).GetValue(row, null))));
|
||||
var valueLines = reportData.Select(row => string.Join(separator, header.Split(separator).Select(a => row.GetType().GetProperty(a).GetValue(row, null))));
|
||||
//var valueLines = reportData.Select(row => string.Join(";", header.Split(';').Select(a => row.GetType().GetProperty(a).GetValue(row, null))));
|
||||
lines.AddRange(valueLines);
|
||||
await Task.Run(() => File.WriteAllLines(path, lines.ToArray()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inizializzazione con periodo e arrotondamento
|
||||
/// </summary>
|
||||
/// <param name="minRound"></param>
|
||||
/// <returns></returns>
|
||||
public static DateTime InitDatetime(DateTime dtRif, int minRound)
|
||||
{
|
||||
TimeSpan DayElapsed = dtRif.Subtract(dtRif.Date);
|
||||
int minDay = (int)Math.Ceiling((double)(DayElapsed.TotalMinutes / minRound)) * minRound;
|
||||
DateTime endRounded = DateTime.Today.AddMinutes(minDay);
|
||||
return endRounded;
|
||||
}
|
||||
|
||||
public static string FormDurata(double durataMinuti)
|
||||
{
|
||||
string answ = "";
|
||||
TimeSpan tsDurata = TimeSpan.FromMinutes(durataMinuti);
|
||||
if (tsDurata.TotalDays < 1)
|
||||
{
|
||||
answ = $"{tsDurata.Hours:00}h {tsDurata.Minutes:00}'";
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = $"{tsDurata.Days}gg {tsDurata.Hours:00}h";
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<canvas id="@Id"></canvas>
|
||||
@@ -0,0 +1,60 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using MP.Data;
|
||||
using MP.SPEC.Data;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace MP.SPEC.Components.Chart
|
||||
{
|
||||
public partial class Doughnut
|
||||
{
|
||||
[Inject]
|
||||
private IJSRuntime JSRuntime { get; set; } = null!;
|
||||
|
||||
|
||||
public enum ChartType
|
||||
{
|
||||
Pie,
|
||||
Bar,
|
||||
Doughnut
|
||||
}
|
||||
|
||||
//[Parameter]
|
||||
public string Id { get; set; } = "myChart";
|
||||
|
||||
[Parameter]
|
||||
public ChartType Type { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public double[] Data { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public List<DoughnutStyling> BackgroundColor { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string[] Labels { get; set; }
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
var config = new
|
||||
{
|
||||
Type = Type.ToString().ToLower(),
|
||||
Options = new
|
||||
{
|
||||
Responsive = true,
|
||||
},
|
||||
Data = new
|
||||
{
|
||||
Datasets = new[]
|
||||
{
|
||||
new { Data = Data, BackgroundColor = BackgroundColor.Select(x=>x.color), borderColor = BackgroundColor.Select(x=>x.border), borderWidth= 0, offset= 1, borderRadius = 0
|
||||
}
|
||||
},
|
||||
Labels = Labels
|
||||
}
|
||||
};
|
||||
|
||||
await JSRuntime.InvokeVoidAsync("setup", Id, config);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<canvas id="@Id"></canvas>
|
||||
@@ -0,0 +1,162 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using MP.Data;
|
||||
|
||||
namespace MP.SPEC.Components.Chart
|
||||
{
|
||||
public partial class Line
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
[Parameter]
|
||||
public double AspRatio { get; set; } = 0;
|
||||
|
||||
[Parameter]
|
||||
public List<string> backColor { get; set; } = new List<string>();
|
||||
|
||||
[Parameter]
|
||||
public string ChartId
|
||||
{
|
||||
get
|
||||
{
|
||||
return Id;
|
||||
}
|
||||
set
|
||||
{
|
||||
Id = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public List<chartJsData.chartJsTSerie> DataTS
|
||||
{
|
||||
get
|
||||
{
|
||||
return _DataTS;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
_DataTS = value;
|
||||
//var pUpd = Task.Run(async () => await renderChart());
|
||||
//pUpd.Wait();
|
||||
}
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public List<string> Labels { get; set; } = new List<string>();
|
||||
|
||||
[Parameter]
|
||||
public List<string> lineColor { get; set; } = new List<string>();
|
||||
|
||||
[Parameter]
|
||||
public int lTens { get; set; } = 0;
|
||||
|
||||
[Parameter]
|
||||
public string MaxValue { get; set; } = "0";
|
||||
|
||||
[Parameter]
|
||||
public string MinValue { get; set; } = "0";
|
||||
|
||||
[Parameter]
|
||||
public List<string> pointColor { get; set; } = new List<string>();
|
||||
|
||||
[Parameter]
|
||||
public string Title { get; set; } = "Demo Line";
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
protected string Id { get; set; } = "CurrId";
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Inizializzazione rendering componente
|
||||
///
|
||||
/// partendo da qui: https://www.williamleme.com/posts/2020/003-chartjs-blazor/
|
||||
/// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/ https://www.tutorialsteacher.com/csharp/csharp-anonymous-type
|
||||
/// </summary>
|
||||
/// <param name="firstRender"></param>
|
||||
/// <returns></returns>
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
await renderChart();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inizializzazione rendering componente
|
||||
///
|
||||
/// partendo da qui: https://www.williamleme.com/posts/2020/003-chartjs-blazor/
|
||||
/// https://www.puresourcecode.com/dotnet/blazor/using-chart-js-with-blazor/ https://www.tutorialsteacher.com/csharp/csharp-anonymous-type
|
||||
/// </summary>
|
||||
/// <param name="firstRender"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task renderChart()
|
||||
{
|
||||
// creazione di un oggetto anonymous type con tutte le opzioni da passare a chart.js
|
||||
var config = new
|
||||
{
|
||||
type = "line",
|
||||
options = new
|
||||
{
|
||||
responsive = true,
|
||||
scales = new
|
||||
{
|
||||
yAxes = new
|
||||
{
|
||||
display = true,
|
||||
position = "right",
|
||||
ticks = new
|
||||
{
|
||||
maxTicksLimit = 10
|
||||
},
|
||||
suggestedMin = MinValue != MaxValue ? MinValue : "auto",
|
||||
suggestedMax = MinValue != MaxValue ? MaxValue : "auto"
|
||||
},
|
||||
xAxes = new
|
||||
{
|
||||
type = "time",
|
||||
distribution = "linear",
|
||||
}
|
||||
},
|
||||
plugins = new
|
||||
{
|
||||
legend = new
|
||||
{
|
||||
display = false
|
||||
},
|
||||
},
|
||||
Animation = false,
|
||||
AspectRatio = AspRatio == 0 ? "auto" : $"{AspRatio}"
|
||||
},
|
||||
data = new
|
||||
{
|
||||
labels = Labels,
|
||||
datasets = new[]{new
|
||||
{
|
||||
data = DataTS, pointBorderColor = backColor, borderColor = lineColor, backgroundColor = backColor, fill = true, PointRadius = 2, BorderWidth = 1, lineTension = lTens, stepped = false, label = Title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
;
|
||||
await JSRuntime.InvokeVoidAsync("setup", Id, config);
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private List<chartJsData.chartJsTSerie> _DataTS { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
private IJSRuntime JSRuntime { get; set; } = null!;
|
||||
|
||||
#endregion Private Properties
|
||||
}
|
||||
}
|
||||
@@ -98,7 +98,7 @@ namespace MP.SPEC.Components
|
||||
|
||||
protected int _numRecord { get; set; } = 10;
|
||||
|
||||
protected int percLoading { get; set; } = 0;
|
||||
protected int percLoading { get; set; } = 0;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
|
||||
@@ -1,27 +1,70 @@
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="px-0 py-1">
|
||||
|
||||
</div>
|
||||
|
||||
<div class="px-0 col-6">
|
||||
<div class="">
|
||||
<div class="px-0 py-1">
|
||||
<div class="px-2 input-group" id="basic-addon1">
|
||||
<label class="input-group-text" for="macchina" title="Selezionare la macchina"><i class="fa-solid fa-hard-drive"></i></label>
|
||||
<select @bind="@selMacchina" class="form-select" id="macchina" title="Selezionare la macchina">
|
||||
<option value="*">--- Tutti ---</option>
|
||||
@if (ListMacchine != null)
|
||||
{
|
||||
foreach (var item in ListMacchine)
|
||||
{
|
||||
<option value="@item">@item</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
<label class="input-group-text" for="DtRef" title="Selezionare la data da visualizzare"><i class="fa-solid fa-calendar-check"></i></label>
|
||||
<input @bind="@selDtRef" id="DtRef" class="form-control" type="datetime-local" title="Selezionare la data da visualizzare" />
|
||||
</div>
|
||||
<div class="d-flex justify-content-end">
|
||||
<a class="pt-2 text-dark" data-bs-toggle="offcanvas" data-bs-target="#paramsFilterExample" aria-controls="paramsFilterExample">
|
||||
<i class="fa-solid fa-bars"></i>
|
||||
</a>
|
||||
<div class="offcanvas offcanvas-end" tabindex="-1" id="paramsFilterExample" aria-labelledby="paramsFilterExampleLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h3 class="offcanvas-title" id="paramsFilterExampleLabel"><b>FILTRI</b></h3>
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<div>
|
||||
Seleziona i filtri per:
|
||||
</div>
|
||||
<div class="input-group p-2">
|
||||
<label class="input-group-text" for="macchina" title="Selezionare l'articolo"><i class="fa-solid fa-file"></i></label>
|
||||
<select @bind="@selArticolo" class="form-select" id="macchina" title="Selezionare la macchina">
|
||||
<option value="*">--- Tutti ---</option>
|
||||
@if (ListArticoli != null)
|
||||
{
|
||||
foreach (var item in ListArticoli)
|
||||
{
|
||||
<option value="@item">@item</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group p-2">
|
||||
<label class="input-group-text" for="macchina" title="Selezionare la macchina"><i class="fa-solid fa-hard-drive"></i></label>
|
||||
<select @bind="@selMacchina" class="form-select" id="macchina" title="Selezionare la macchina">
|
||||
<option value="*">--- Tutti ---</option>
|
||||
@if (ListMacchine != null)
|
||||
{
|
||||
foreach (var item in ListMacchine)
|
||||
{
|
||||
<option value="@item">@item</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="small mt-2">
|
||||
<label class="px-2" for="dtMin" title="Selezionare inizio periodo">Inizio Periodo</label>
|
||||
</div>
|
||||
<div class="px-2 input-group">
|
||||
<label class="input-group-text" for="dtMin" title="Selezionare inizio periodo"><i class="fa-regular fa-calendar-minus"></i></label>
|
||||
<input class="form-control" @bind="@selDtMin" id="dtMin" type="datetime-local" title="Data minima eventi da visualizzare">
|
||||
</div>
|
||||
<div class="small mt-2">
|
||||
<label class="px-2" for="dtMax" title="Selezionare fine periodo">Fine Periodo</label>
|
||||
</div>
|
||||
<div class="px-2 input-group">
|
||||
<label class="input-group-text" for="dtMax" title="Selezionare fine periodo"><i class="fa-regular fa-calendar-plus"></i></label>
|
||||
<input class="form-control" @bind="@selDtMax" id="dtMax" type="datetime-local" title="Selezionare fine periodo">
|
||||
</div>
|
||||
@*<div class="input-group p-2">
|
||||
<label class="input-group-text" for="DtMin" title="Selezionare la data da visualizzare"><i class="fa-solid fa-calendar-check"></i></label>
|
||||
<input @bind="@selDtRef" id="DtMin" class="form-control" type="datetime-local" title="Selezionare la data minima da visualizzare" />
|
||||
</div>
|
||||
<div class="input-group p-2">
|
||||
<label class="input-group-text" for="maxRecord" title="Selezionare il numero massimo di record da visualizzare"><i class="fa-solid fa-list-ol"></i></label>
|
||||
<select @bind="@selMaxRecord" class="form-select" id="maxRecord" title="Selezionare il numero massimo di record da visualizzare">
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
<option value="250">250</option>
|
||||
<option value="500">500</option>
|
||||
</select>
|
||||
</div>*@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using MP.Data.DatabaseModels;
|
||||
using MP.SPEC.Data;
|
||||
|
||||
namespace MP.SPEC.Components
|
||||
@@ -21,18 +20,54 @@ namespace MP.SPEC.Components
|
||||
[Inject]
|
||||
protected MpDataService MDService { get; set; } = null!;
|
||||
|
||||
protected DateTime selDtRef
|
||||
protected string selArticolo
|
||||
{
|
||||
get
|
||||
{
|
||||
return SelFilterDossier.DtRef;
|
||||
return SelFilterDossier.CodArticolo;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (!SelFilterDossier.CodArticolo.Equals(value))
|
||||
{
|
||||
SelFilterDossier.CurrPage = 1;
|
||||
SelFilterDossier.CodArticolo = value;
|
||||
StateHasChanged();
|
||||
Task.Delay(1);
|
||||
reportChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected DateTime selDtMax
|
||||
{
|
||||
get
|
||||
{
|
||||
return SelFilterDossier.DtEnd;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (!SelFilterDossier.DtRef.Equals(value))
|
||||
if (!SelFilterDossier.DtEnd.Equals(value))
|
||||
{
|
||||
SelFilterDossier.DtRef = value;
|
||||
SelFilterDossier.DtEnd = value;
|
||||
reportChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected DateTime selDtMin
|
||||
{
|
||||
get
|
||||
{
|
||||
return SelFilterDossier.DtStart;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (!SelFilterDossier.DtStart.Equals(value))
|
||||
{
|
||||
SelFilterDossier.DtStart = value;
|
||||
reportChange();
|
||||
}
|
||||
}
|
||||
@@ -74,6 +109,8 @@ namespace MP.SPEC.Components
|
||||
}
|
||||
}
|
||||
|
||||
protected bool showParam { get; set; } = false;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
@@ -81,8 +118,10 @@ namespace MP.SPEC.Components
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
SelFilterDossier = new SelectDossierParams();
|
||||
ListMacchine = await MDService.MacchineWithFlux();
|
||||
ListDossier = await MDService.DossiersGetLastFilt(selMacchina, selDtRef, selMaxRecord);
|
||||
DateTime dtEnd = SelFilterDossier.DtEnd;
|
||||
DateTime dtStart = dtEnd.Subtract(SelFilterDossier.DtStart).TotalDays < 15 ? SelFilterDossier.DtStart : dtEnd.AddDays(-14);
|
||||
ListMacchine = await MDService.MacchineWithFlux(dtStart, dtEnd);
|
||||
ListArticoli = await MDService.ArticleWithDossier();
|
||||
await FilterChanged.InvokeAsync(SelFilterDossier);
|
||||
}
|
||||
|
||||
@@ -95,7 +134,7 @@ namespace MP.SPEC.Components
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private List<Dossiers>? ListDossier = null;
|
||||
private List<string>? ListArticoli = null;
|
||||
private List<string>? ListMacchine = null;
|
||||
|
||||
#endregion Private Fields
|
||||
@@ -113,6 +152,11 @@ namespace MP.SPEC.Components
|
||||
FilterChanged.InvokeAsync(SelFilterDossier);
|
||||
}
|
||||
|
||||
private void toggleShowParams()
|
||||
{
|
||||
showParam = !showParam;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -17,12 +17,14 @@ else
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<button @onclick="() => unToggleTableFlux()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>
|
||||
<button @onclick="() => closeTableFlux()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>
|
||||
</th>
|
||||
<th><i class="fa-solid fa-file"></i> Articolo</th>
|
||||
<th><i class="fa-solid fa-screwdriver-wrench"></i> Fase</th>
|
||||
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
|
||||
<th><i class="fa-regular fa-calendar-days"></i> Data</th>
|
||||
<th><i class="fa-regular fa-calendar-days"></i> Data Snap</th>
|
||||
<th><i class="fa-solid fa-sliders"></i> ODL</th>
|
||||
<th><i class="fa-solid fa-circle-info"></i> DATA TYPE</th>
|
||||
@*<th><i class="fa-solid fa-circle-info"></i> DATA TYPE</th>*@
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -33,8 +35,16 @@ else
|
||||
<td>
|
||||
<button class="btn btn-primary btn-sm" @onclick="() => selRecord(record)"><i class="fa-solid fa-magnifying-glass"></i></button>
|
||||
</td>
|
||||
<td>
|
||||
@record.OdlNav.CodArticolo
|
||||
<div class="small textConsensed text-secondary">@record.OdlNav.ArticoloNav.DescArticolo</div>
|
||||
</td>
|
||||
<td>
|
||||
@tradFase(record.OdlNav.KeyRichiesta)
|
||||
</td>
|
||||
<td>
|
||||
@record.IdxMacchina
|
||||
<div class="small textConsensed text-secondary">@record.MachineNav.Descrizione</div>
|
||||
</td>
|
||||
<td>
|
||||
@record.DtRif
|
||||
@@ -42,11 +52,12 @@ else
|
||||
<td>
|
||||
@record.IdxODL
|
||||
</td>
|
||||
@*<td>
|
||||
@record.DataType
|
||||
</td>*@
|
||||
<td>
|
||||
@record.DataType
|
||||
<button @onclick="() => deleteRecord(record)" class="btn btn-danger btn-sm"><i class="bi bi-trash-fill"></i></button>
|
||||
</td>
|
||||
<td>
|
||||
<button @onclick="() => deleteRecord(record)" class="btn btn-danger btn-sm"><i class="bi bi-trash-fill"></i></button></td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
@@ -64,16 +75,26 @@ else
|
||||
<table class="table table-light table-sm table-striped small mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<button class="btn btn-info" @onclick="() => closeTableFlux()"><i class="fa-solid fa-xmark"></i></button>
|
||||
</th>
|
||||
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
|
||||
<th><i class="fa-regular fa-calendar-days"></i> Data</th>
|
||||
<th><i class="fa-solid fa-sliders"></i> Data Type</th>
|
||||
<th class="d-flex justify-content-between"> Valore <button class="btn btn-primary btn-sm py-0" @onclick="() => unToggleTableFlux()"><i class="fa-solid fa-xmark"></i></button></th>
|
||||
<th>
|
||||
<div class="d-flex justify-content-between col-12">
|
||||
<span class="col-11" style="text-align: right;"> Valore </span>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var record in listaFlux)
|
||||
{
|
||||
<tr>
|
||||
<tr class="@checkSelPar(@record)">
|
||||
<td>
|
||||
<button @onclick="() => editRecord(record)" class="btn btn-primary btn-sm" title="Modifica Record"><i class="bi bi-pencil-square"></i></button>
|
||||
</td>
|
||||
<td>
|
||||
@record.IdxMacchina
|
||||
</td>
|
||||
@@ -84,7 +105,15 @@ else
|
||||
@record.CodFlux
|
||||
</td>
|
||||
<td style="text-align: right;">
|
||||
<b>@record.Valore</b>
|
||||
@if (record.ValoreEdit != record.Valore)
|
||||
{
|
||||
<div title="Valore Modificato"><span class="small text-dark"></span><b>@record.ValoreEdit</b></div>
|
||||
<div class="small text-secondary" title="Valore Registrato">(<i>@record.Valore</i>)</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div><span class="small text-dark"></span>@record.ValoreEdit</div>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@@ -100,3 +129,5 @@ else
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using MP.Data.DatabaseModels;
|
||||
using MP.Data.DTO;
|
||||
using MP.SPEC.Data;
|
||||
|
||||
namespace MP.SPEC.Components
|
||||
{
|
||||
public partial class ListDossiers
|
||||
public partial class ListDossiers : IDisposable
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<Dossiers> RecordSel { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<FluxLogDTO> RecordSelFlux { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public SelectDossierParams SelFilter { get; set; } = null!;
|
||||
|
||||
@@ -22,6 +26,24 @@ namespace MP.SPEC.Components
|
||||
|
||||
#region Public Methods
|
||||
|
||||
private FluxLogDTO? currFluxLogDto = null;
|
||||
|
||||
|
||||
public string checkSelPar(FluxLogDTO recordSel)
|
||||
{
|
||||
string answ = "";
|
||||
if (currFluxLogDto != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
answ = (currFluxLogDto.CodFlux == recordSel.CodFlux && currFluxLogDto.dtEvento== recordSel.dtEvento) ? "table-info" : "";
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
public string checkSelect(Dossiers recordSel)
|
||||
{
|
||||
string answ = "";
|
||||
@@ -36,36 +58,16 @@ namespace MP.SPEC.Components
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Eliminazione record selezionato (previa conferma)
|
||||
/// </summary>
|
||||
/// <param name="selRec"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task deleteRecord(Dossiers selRec)
|
||||
public void Dispose()
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Eliminazione Dossier: sei sicuro di voler procedere?"))
|
||||
return;
|
||||
await Task.Delay(1);
|
||||
var done = await MDService.DossiersDeleteRecord(selRec);
|
||||
MessageService.EA_PageUpdated -= MessageService_EA_PageUpdated;
|
||||
MessageService.EA_SearchUpdated -= OnSeachUpdated;
|
||||
currRecord = null;
|
||||
await reloadData();
|
||||
await Task.Delay(1);
|
||||
SearchRecords = null;
|
||||
ListRecords = null;
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
public async Task reloadData(bool setChanged)
|
||||
{
|
||||
isLoading = true;
|
||||
SearchRecords = await MDService.DossiersGetLastFilt(SelMacchina, SelDtRef, MaxRecord);
|
||||
totalCount = SearchRecords.Count;
|
||||
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
|
||||
await Task.Delay(1);
|
||||
if (setChanged)
|
||||
{
|
||||
await InvokeAsync(() => StateHasChanged());
|
||||
}
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
@@ -84,14 +86,36 @@ namespace MP.SPEC.Components
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Eliminazione record selezionato (previa conferma)
|
||||
/// </summary>
|
||||
/// <param name="selRec"></param>
|
||||
/// <returns></returns>
|
||||
protected async Task deleteRecord(Dossiers selRec)
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Eliminazione Dossier: sei sicuro di voler procedere?"))
|
||||
return;
|
||||
await Task.Delay(1);
|
||||
var done = await MDService.DossiersDeleteRecord(selRec);
|
||||
currRecord = null;
|
||||
await reloadData(true);
|
||||
visualizzaFlux = true;
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
protected async Task editRecord(FluxLogDTO selRec)
|
||||
{
|
||||
currFluxLogDto = selRec;
|
||||
// indico record selezionato
|
||||
await RecordSelFlux.InvokeAsync(selRec);
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
MessageService.EA_PageUpdated += MessageService_EA_PageUpdated;
|
||||
MessageService.EA_SearchUpdated += OnSeachUpdated;
|
||||
|
||||
ListRecords = await MDService.DossiersGetLastFilt(SelMacchina, SelDtRef, MaxRecord);
|
||||
|
||||
await reloadData();
|
||||
ListStati = await MDService.AnagStatiComm();
|
||||
await reloadData(true);
|
||||
}
|
||||
|
||||
protected async void OnSeachUpdated()
|
||||
@@ -107,7 +131,7 @@ namespace MP.SPEC.Components
|
||||
{
|
||||
currRecord = selRec;
|
||||
await RecordSel.InvokeAsync(selRec);
|
||||
listaFlux = MDService.convertToFluxLog(selRec.Valore);
|
||||
listaFlux = MDService.getFluxLog(selRec.Valore);
|
||||
await toggleTableFlux();
|
||||
}
|
||||
|
||||
@@ -122,8 +146,13 @@ namespace MP.SPEC.Components
|
||||
#region Private Fields
|
||||
|
||||
private int _totalCount = 0;
|
||||
|
||||
private Dossiers? currRecord = null;
|
||||
|
||||
private FluxLogDTO? currRecordFlux;
|
||||
private List<Dossiers>? ListRecords;
|
||||
private List<ListValues>? ListStati;
|
||||
|
||||
private List<Dossiers>? SearchRecords;
|
||||
|
||||
#endregion Private Fields
|
||||
@@ -137,7 +166,8 @@ namespace MP.SPEC.Components
|
||||
}
|
||||
|
||||
private bool isLoading { get; set; } = false;
|
||||
private List<FluxLog>? listaFlux { get; set; } = null;
|
||||
|
||||
private List<FluxLogDTO>? listaFlux { get; set; } = null;
|
||||
|
||||
private int MaxRecord
|
||||
{
|
||||
@@ -150,9 +180,18 @@ namespace MP.SPEC.Components
|
||||
set => MessageService.numRecord = value;
|
||||
}
|
||||
|
||||
private DateTime SelDtRef
|
||||
private string SelArticolo
|
||||
{
|
||||
get => SelFilter.DtRef;
|
||||
get => SelFilter.CodArticolo;
|
||||
}
|
||||
|
||||
private DateTime SelDtEnd
|
||||
{
|
||||
get => SelFilter.DtEnd;
|
||||
}
|
||||
private DateTime SelDtStart
|
||||
{
|
||||
get => SelFilter.DtStart;
|
||||
}
|
||||
|
||||
private string SelMacchina
|
||||
@@ -181,17 +220,20 @@ namespace MP.SPEC.Components
|
||||
|
||||
private async void MessageService_EA_PageUpdated()
|
||||
{
|
||||
await reloadData();
|
||||
await reloadData(true);
|
||||
}
|
||||
|
||||
private async Task reloadData()
|
||||
private async Task reloadData(bool setChanged)
|
||||
{
|
||||
isLoading = true;
|
||||
SearchRecords = await MDService.DossiersGetLastFilt(SelMacchina, SelDtRef, MaxRecord);
|
||||
SearchRecords = await MDService.DossiersGetLastFilt(SelMacchina, SelArticolo, SelDtStart, SelDtEnd);
|
||||
totalCount = SearchRecords.Count;
|
||||
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
|
||||
await Task.Delay(1);
|
||||
await InvokeAsync(() => StateHasChanged());
|
||||
if (setChanged)
|
||||
{
|
||||
await InvokeAsync(() => StateHasChanged());
|
||||
}
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
@@ -201,8 +243,23 @@ namespace MP.SPEC.Components
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
private async Task unToggleTableFlux()
|
||||
private string tradFase(string codFase)
|
||||
{
|
||||
string answ = codFase;
|
||||
if (ListStati != null && ListStati.Count > 0)
|
||||
{
|
||||
var recSel = ListStati.FirstOrDefault(x => x.value == codFase);
|
||||
if (recSel != null)
|
||||
{
|
||||
answ = recSel.label;
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
private async Task closeTableFlux()
|
||||
{
|
||||
currFluxLogDto = null;
|
||||
currRecord = null;
|
||||
visualizzaFlux = true;
|
||||
await Task.Delay(1);
|
||||
|
||||
@@ -12,57 +12,244 @@ else if (totalCount == 0)
|
||||
else
|
||||
{
|
||||
<div class="row">
|
||||
@if (currRecord != null && !showStats && isCurrOdl)
|
||||
{
|
||||
<div class="col-6 col-lg-8">
|
||||
<button @onclick="() => forceSyncDb()" class="btn btn-success btn-sm btn-">Forza sync dati ODL <i class="bi bi-fast-forward-circle"></i></button>
|
||||
</div>
|
||||
<div class="col-6 col-lg-4 text-end">
|
||||
@*<div class="px-2 input-group" title="Selezionare Data-Ora chiusura ODL">
|
||||
<label class="input-group-text" for="dtMax"><i class="fa-regular fa-calendar-minus"></i></label>
|
||||
<input class="form-control" @bind="@selDtFine" id="dtMax" type="datetime-local">
|
||||
<button @onclick="() => chiudiOdl()" class="btn btn-danger btn-sm btn-">Registra chiusura ODL <i class="far fa-stop-circle"></i></button>
|
||||
</div>*@
|
||||
<button @onclick="() => chiudiOdl()" class="btn btn-danger btn-sm btn-">Registra chiusura ODL <i class="far fa-stop-circle"></i></button>
|
||||
</div>
|
||||
}
|
||||
<div class="col-12">
|
||||
<table class="table table-sm table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
@*<button @onclick="() => resetSel()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>*@
|
||||
<button @onclick="() => resetSel()" class="btn btn-primary btn-sm"><i class="bi bi-arrow-counterclockwise"></i></button>
|
||||
</th>
|
||||
<th><i class="fa-solid fa-file"></i> Articolo</th>
|
||||
<th><i class="fa-solid fa-screwdriver-wrench"></i> Fase</th>
|
||||
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
|
||||
<th># pz</th>
|
||||
<th><i class="fa-solid fa-clock"></i> T.Ciclo</th>
|
||||
<th><i class="fa-solid fa-play"></i> Inizio</th>
|
||||
<th><i class="fa-solid fa-pen-to-square"></i> Note</th>
|
||||
<th><i class="fa-solid fa-code-pull-request"></i> Richiesta</th>
|
||||
<th></th>
|
||||
<th><i class="fa-solid fa-circle-info"></i> Info ciclo</th>
|
||||
<th><i class="fa-solid fa-calendar-day"></i> Periodo</th>
|
||||
<th title="Durata in ore:min"><i class="fa-solid fa-clock"></i> Durata</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var record in ListRecords)
|
||||
{
|
||||
<tr class="@checkSelect(@record.CodArticolo)">
|
||||
<tr class="@checkSelect(@record.IdxOdl)">
|
||||
|
||||
<td>
|
||||
@*<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm"><i class="bi bi-pencil-square"></i></button>*@
|
||||
@if (isCurrOdl)
|
||||
{
|
||||
<button class="btn btn-primary btn-sm" @onclick="() => selRecord(record)"><i class="fa-solid fa-magnifying-glass"></i></button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-secondary btn-sm disabled"><i class="fa-solid fa-magnifying-glass"></i></button>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@record.CodArticolo
|
||||
<div class="small textConsensed text-secondary">@record.ArticoloNav.DescArticolo</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>
|
||||
@tradFase(record.KeyRichiesta)
|
||||
</div>
|
||||
@if (record.Note != "")
|
||||
{
|
||||
<div class="small textConsensed text-secondary badge text-bg-light border border-secondary rounded">
|
||||
<b class="text-dark"></b> <span class="text-wrap text-start"> @record.Note </span>
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
@record.IdxMacchina
|
||||
<div class="small textConsensed text-secondary">@record.MachineNav.Descrizione</div>
|
||||
</td>
|
||||
<td>
|
||||
@record.NumPezzi
|
||||
<div class="small textConsensed"><b>N° pezzi:</b> @record.NumPezzi</div>
|
||||
<div class="small textConsensed"><b>T. Ciclo:</b> @record.Tcassegnato.ToString("N3")</div>
|
||||
|
||||
</td>
|
||||
<td>
|
||||
@record.Tcassegnato.ToString("N3")
|
||||
<div class="small d-flex justify-content-between">
|
||||
<div>
|
||||
<div><b>@($"{@record.DataInizio:yyyy/MM/dd}")</b></div>
|
||||
<div>@($"{@record.DataInizio:ddd HH:mm:ss}")</div>
|
||||
</div>
|
||||
<div class="p-0">
|
||||
<i class="fa-solid fa-angles-right"></i>
|
||||
</div>
|
||||
<div>
|
||||
@if (@record.DataFine != null)
|
||||
{
|
||||
<div><b>@($"{@record.DataFine:yyyy/MM/dd}")</b></div>
|
||||
<div>@($"{@record.DataFine:ddd HH:mm:ss}")</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="text-secondary">
|
||||
<div><b>@($"{DateTime.Now:yyyy/MM/dd}")</b></div>
|
||||
<div>@($"{DateTime.Now:ddd HH:mm:ss}")</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>@record.DataInizio</div>
|
||||
</td>
|
||||
<td>@record.Note</td>
|
||||
<td>@record.KeyRichiesta</td>
|
||||
<td>
|
||||
@*@if (ArticoloDelEnabled(record.CodArticolo))
|
||||
{
|
||||
<button @onclick="() => deleteRecord(record)" class="btn btn-danger btn-sm"><i class="bi bi-trash-fill"></i></button>
|
||||
}*@
|
||||
<div>
|
||||
<b>@record.DurataMinuti</b>
|
||||
</div>
|
||||
<div>
|
||||
<button class="btn btn-sm btn-primary py-0" type="button" @onclick="() => selectStatRecord(record)" data-bs-toggle="modal" data-bs-target="#myModal" title="Mostra statistiche"><i class="fa-solid fa-chart-pie"></i></button>
|
||||
</div>
|
||||
<!-- Modal -->
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="modal fade" id="myModal" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered modal-xl">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-primary col-12">
|
||||
@if (statRecord != null)
|
||||
{
|
||||
<div class="col-3">
|
||||
<b class="modal-title fs-1" id="staticBackdropLabel"><b>ODL @statRecord.IdxOdl</b></b>
|
||||
</div>
|
||||
<div class="col-6 fs-5">
|
||||
<b>@statRecord.CodArticolo</b>
|
||||
<div class="small textConsensed text-light">@statRecord.ArticoloNav.DescArticolo</div>
|
||||
</div>
|
||||
<div class="col-2 fs-5">
|
||||
<b>@statRecord.IdxMacchina</b>
|
||||
<div class="small textConsensed text-light">@statRecord.MachineNav.Descrizione</div>
|
||||
</div>
|
||||
}
|
||||
<div class="col-1 text-end">
|
||||
<button type="button" class="btn btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-body col-12">
|
||||
@if (statRecord != null && showStats)
|
||||
{
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="col-8">
|
||||
<div>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width: 270px">
|
||||
<div class="small textConsensed"><b>N° pezzi:</b> @statRecord.NumPezzi</div>
|
||||
<div class="small textConsensed"><b>T. Ciclo:</b> @statRecord.Tcassegnato.ToString("N3")</div>
|
||||
</td>
|
||||
<td style="width: 300px">
|
||||
<div class="small d-flex justify-content-between">
|
||||
<div>
|
||||
<div><b>@($"{@statRecord.DataInizio:yyyy/MM/dd}")</b></div>
|
||||
<div>@($"{@statRecord.DataInizio:ddd HH:mm:ss}")</div>
|
||||
</div>
|
||||
<div class="p-0">
|
||||
<i class="fa-solid fa-angles-right"></i>
|
||||
</div>
|
||||
<div>
|
||||
@if (@statRecord.DataFine != null)
|
||||
{
|
||||
<div><b>@($"{@statRecord.DataFine:yyyy/MM/dd}")</b></div>
|
||||
<div>@($"{@statRecord.DataFine:ddd HH:mm:ss}")</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="text-secondary">
|
||||
<div><b>@($"{DateTime.Now:yyyy/MM/dd}")</b></div>
|
||||
<div>@($"{DateTime.Now:ddd HH:mm:ss}")</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<div>
|
||||
@tradFase(statRecord.KeyRichiesta)
|
||||
</div>
|
||||
@if (statRecord.Note != "")
|
||||
{
|
||||
<div class="small textConsensed text-secondary badge text-bg-light border border-secondary rounded">
|
||||
<b class="text-dark"></b> <span class="text-wrap text-start"> @statRecord.Note </span>
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div>
|
||||
@if (statRecord != null)
|
||||
{
|
||||
|
||||
@if (ListOdlStats != null)
|
||||
{
|
||||
@foreach (var stat in ListOdlStats)
|
||||
{
|
||||
<div class="p-1">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="text-uppercase">
|
||||
@stat.Descrizione
|
||||
</div>
|
||||
<div>
|
||||
<b>@(formDurata(stat.TotDurata))</b>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="progress">
|
||||
<div class="progress-bar @colorChanger(@stat.Css)" role="progressbar" aria-valuenow="0" aria-valuemin="0" style="width: @Math.Round(calcolaPerc(stat.TotDurata),0)%; background-color:@pbStyle(@stat.Css);" aria-valuemax="100">@($"{calcolaPerc(stat.TotDurata):N1}%")</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-4 dcContainer">
|
||||
@if (statRecord != null && ListOdlStats != null)
|
||||
{
|
||||
<div class="dcBox">
|
||||
<ODLPlot SelectedOdl="@statRecord.IdxOdl"></ODLPlot>
|
||||
</div>
|
||||
<div class="dcBox dcOverlay d-flex">
|
||||
<div class="align-self-center text-center w-100">
|
||||
<b class="fs-3">@statRecord.DurataMinuti</b>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -2,43 +2,35 @@ using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using MP.Data.DatabaseModels;
|
||||
using MP.SPEC.Data;
|
||||
using MP.SPEC.Services;
|
||||
|
||||
namespace MP.SPEC.Components
|
||||
{
|
||||
public partial class ListODL
|
||||
public partial class ListODL : IDisposable
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
[Parameter]
|
||||
public SelectOdlParams currFilter { get; set; } = null!;
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<bool> PagerResetReq { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string StatoSel
|
||||
{
|
||||
get => _statoSel;
|
||||
set
|
||||
{
|
||||
if (_statoSel != value)
|
||||
{
|
||||
_statoSel = value;
|
||||
var pUpd = Task.Run(async () => await reloadData());
|
||||
pUpd.Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
public EventCallback<int> updateRecordCount { get; set; }
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public string checkSelect(string CodArticolo)
|
||||
public string checkSelect(int IdxOdl)
|
||||
{
|
||||
string answ = "";
|
||||
if (currRecord != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
answ = (currRecord.CodArticolo == CodArticolo) ? "table-info" : "";
|
||||
answ = (currRecord.IdxOdl == IdxOdl) ? "table-info" : "";
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
@@ -46,6 +38,22 @@ namespace MP.SPEC.Components
|
||||
return answ;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
currRecord = null;
|
||||
SearchRecords = null;
|
||||
ListRecords = null;
|
||||
ListStati = null;
|
||||
ListOdlStats = null;
|
||||
statRecord = null;
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
public string formDurata(double durataMin)
|
||||
{
|
||||
return MP.Data.Utils.FormDurata(durataMin);
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Properties
|
||||
@@ -57,16 +65,66 @@ namespace MP.SPEC.Components
|
||||
protected MpDataService MDService { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected MessageService MessageService { get; set; } = null!;
|
||||
protected IOApiService MpIoApiCall { get; set; } = null!;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Registra chiusura ODL alla data indicata
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected async Task chiudiOdl()
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sei sicuro di voler chiudere l'ODL corrente?"))
|
||||
return;
|
||||
|
||||
if (currRecord != null)
|
||||
{
|
||||
// effettua chiusura sul DB
|
||||
await MDService.ODLClose(currRecord.IdxOdl, currRecord.IdxMacchina, 0, true);
|
||||
// ricarica...
|
||||
await selectRecord(null);
|
||||
}
|
||||
await reloadData();
|
||||
}
|
||||
|
||||
protected string colorChanger(string colorCSS)
|
||||
{
|
||||
string answ = "";
|
||||
if (colorCSS == "yellow")
|
||||
{
|
||||
answ = "text-dark";
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Richiesta invio sync all'IOB-WIN
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected async Task forceSyncDb()
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sei sicuro di voler reinviare i dati (Articoli, PODL) all'impianto?"))
|
||||
return;
|
||||
|
||||
if (currRecord != null)
|
||||
{
|
||||
await callSyncDb(currRecord.IdxMacchina);
|
||||
// ricarica...
|
||||
await selectRecord(null);
|
||||
}
|
||||
await reloadData();
|
||||
}
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
MessageService.EA_PageUpdated += MessageService_EA_PageUpdated;
|
||||
MessageService.EA_SearchUpdated += OnSeachUpdated;
|
||||
ListStati = await MDService.AnagStatiComm();
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
await reloadData();
|
||||
}
|
||||
|
||||
@@ -75,15 +133,63 @@ namespace MP.SPEC.Components
|
||||
await InvokeAsync(() =>
|
||||
{
|
||||
PagerResetReq.InvokeAsync(true);
|
||||
//currPage = 1;
|
||||
Task task = UpdateData();
|
||||
StateHasChanged();
|
||||
});
|
||||
}
|
||||
|
||||
protected async Task resetSel()
|
||||
{
|
||||
await selectRecord(null);
|
||||
await reloadData();
|
||||
}
|
||||
|
||||
protected async Task selectRecord(ODLModel? currRec)
|
||||
{
|
||||
showStats = true;
|
||||
await Task.Delay(1);
|
||||
currRecord = currRec;
|
||||
if (currRec != null)
|
||||
{
|
||||
showStats = true;
|
||||
ListOdlStats = await MDService.StatOdl(currRec.IdxOdl);
|
||||
}
|
||||
else
|
||||
{
|
||||
showStats = false;
|
||||
ListOdlStats = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task selectStatRecord(ODLModel? currRec)
|
||||
{
|
||||
showStats = true;
|
||||
await Task.Delay(1);
|
||||
statRecord = currRec;
|
||||
if (currRec != null)
|
||||
{
|
||||
showStats = true;
|
||||
ListOdlStats = await MDService.StatOdl(currRec.IdxOdl);
|
||||
}
|
||||
else
|
||||
{
|
||||
showStats = false;
|
||||
ListOdlStats = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task selRecord(ODLModel? currRec)
|
||||
{
|
||||
await Task.Delay(1);
|
||||
selDtFine = DateTime.Now;
|
||||
currRecord = currRec;
|
||||
showStats = false;
|
||||
ListOdlStats = null;
|
||||
}
|
||||
|
||||
protected async Task UpdateData()
|
||||
{
|
||||
currRecord = null;
|
||||
await selectRecord(null);
|
||||
await reloadData();
|
||||
}
|
||||
|
||||
@@ -91,56 +197,146 @@ namespace MP.SPEC.Components
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private string _statoSel = "*";
|
||||
|
||||
private ODLModel? currRecord = null;
|
||||
|
||||
private List<StatODLModel>? ListOdlStats;
|
||||
|
||||
private List<ODLModel>? ListRecords;
|
||||
|
||||
private List<ListValues>? ListStati;
|
||||
|
||||
private List<ODLModel>? SearchRecords;
|
||||
|
||||
private ODLModel? statRecord = null;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private int _totalCount { get; set; } = 0;
|
||||
|
||||
private int currPage
|
||||
{
|
||||
get => MessageService.currPage;
|
||||
set => MessageService.currPage = value;
|
||||
get => currFilter.CurrPage;
|
||||
set => currFilter.CurrPage = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indica se si tratti di ODL correnti
|
||||
/// </summary>
|
||||
private bool isCurrOdl
|
||||
{
|
||||
get => currFilter.IsActive;
|
||||
}
|
||||
|
||||
private bool isLoading { get; set; } = false;
|
||||
|
||||
private int numRecord
|
||||
{
|
||||
get => MessageService.numRecord;
|
||||
set => MessageService.numRecord = value;
|
||||
get => currFilter.NumRec;
|
||||
set => currFilter.NumRec = value;
|
||||
}
|
||||
|
||||
private string SearchVal
|
||||
{
|
||||
get => string.IsNullOrEmpty(MessageService.SearchVal) ? "*" : MessageService.SearchVal;
|
||||
}
|
||||
private DateTime selDtFine { get; set; } = DateTime.Now;
|
||||
|
||||
private bool showStats { get; set; } = false;
|
||||
|
||||
private int totalCount
|
||||
{
|
||||
get => MessageService.totalCount;
|
||||
set => MessageService.totalCount = value;
|
||||
get => _totalCount;
|
||||
set
|
||||
{
|
||||
if (_totalCount != value)
|
||||
{
|
||||
_totalCount = value;
|
||||
updateRecordCount.InvokeAsync(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private async void MessageService_EA_PageUpdated()
|
||||
/// <summary>
|
||||
/// Chiama metodo x chiedere sync DB
|
||||
/// </summary>
|
||||
/// <param name="selRec"></param>
|
||||
/// <returns></returns>
|
||||
private async Task addTask2Exe(string idxMacc, string taskName, string taskVal)
|
||||
{
|
||||
await reloadData();
|
||||
// compongo URL e chiamo
|
||||
string restUrl = $"IOB/addTask2Exe/{idxMacc}?taskName={taskName}&taskVal={taskVal}";
|
||||
try
|
||||
{
|
||||
var response = await MpIoApiCall.callMpIoUrlGet(restUrl);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private double calcolaPerc(double durata)
|
||||
{
|
||||
double answ = 0;
|
||||
|
||||
double tot = 0;
|
||||
if (ListOdlStats != null)
|
||||
{
|
||||
foreach (var item in ListOdlStats)
|
||||
{
|
||||
tot += item.TotDurata;
|
||||
}
|
||||
|
||||
double perc = (durata / tot) * 100;
|
||||
if (perc > 1)
|
||||
{
|
||||
answ = Math.Round(perc, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = Math.Round(perc, 4);
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Chiama metodo x chiedere sync DB
|
||||
/// </summary>
|
||||
/// <param name="IdxMacc"></param>
|
||||
/// <returns></returns>
|
||||
private async Task callSyncDb(string IdxMacc)
|
||||
{
|
||||
// chiamo aggiunta task SyncDb...
|
||||
await addTask2Exe(IdxMacc, "syncDbData", "");
|
||||
}
|
||||
|
||||
private string pbStyle(string css)
|
||||
{
|
||||
string answ = "";
|
||||
if (ListOdlStats != null)
|
||||
{
|
||||
if (css == "yellow")
|
||||
{
|
||||
answ = "orange";
|
||||
}
|
||||
else if (css == "blue")
|
||||
{
|
||||
answ = "#2874A6";
|
||||
}
|
||||
else
|
||||
{
|
||||
answ = css;
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
private async Task reloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
SearchRecords = await MDService.ListODLFilt(true, SearchVal, StatoSel);
|
||||
SearchRecords = await MDService.ListODLFilt(currFilter.IsActive, currFilter.SearchVal, currFilter.CodStato, currFilter.IdxMacchina, currFilter.DtStart, currFilter.DtEnd);
|
||||
totalCount = SearchRecords.Count;
|
||||
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
|
||||
await Task.Delay(1);
|
||||
@@ -148,6 +344,20 @@ namespace MP.SPEC.Components
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
private string tradFase(string codFase)
|
||||
{
|
||||
string answ = codFase;
|
||||
if (ListStati != null && ListStati.Count > 0)
|
||||
{
|
||||
var recSel = ListStati.FirstOrDefault(x => x.value == codFase);
|
||||
if (recSel != null)
|
||||
{
|
||||
answ = recSel.label;
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,10 @@ namespace MP.SPEC.Components
|
||||
MessageService.EA_SearchUpdated -= OnSeachUpdated;
|
||||
aTimer.Stop();
|
||||
aTimer.Dispose();
|
||||
currRecord = null;
|
||||
SearchRecords = null;
|
||||
ListRecords = null;
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
public void ElapsedTimer(object? source, System.Timers.ElapsedEventArgs e)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@using MP.SPEC.Components
|
||||
@using MP.SPEC.Data
|
||||
|
||||
@if (ListRecords == null)
|
||||
@if (ListRecords == null || isLoading)
|
||||
{
|
||||
<LoadingData></LoadingData>
|
||||
}
|
||||
@@ -22,33 +22,65 @@ else
|
||||
<th><i class="fa-solid fa-file"></i> Articolo</th>
|
||||
<th><i class="fa-solid fa-screwdriver-wrench"></i> Fase</th>
|
||||
<th><i class="fa-solid fa-hard-drive"></i> Macchina</th>
|
||||
<th># pz</th>
|
||||
<th><i class="fa-solid fa-clock"></i> T.Ciclo</th>
|
||||
<th><i class="fa-solid fa-pen-to-square"></i> Note</th>
|
||||
<th><i class="fa-solid fa-circle-info"></i> Info ciclo</th>
|
||||
@*<th><i class="fa-solid fa-pen-to-square"></i> Note</th>*@
|
||||
<th title="Attivabile"><i class="fa-regular fa-square-check"></i> Att</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var record in ListRecords)
|
||||
{
|
||||
<tr class="@checkSelect(@record.CodArticolo)">
|
||||
<td>
|
||||
<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm"><i class="bi bi-pencil-square"></i></button>
|
||||
<tr class="@checkSelect(@record)">
|
||||
<td class="text-nowrap">
|
||||
<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm" title="Modifica Record"><i class="bi bi-pencil-square"></i></button>
|
||||
<button @onclick="() => cloneRecord(record)" class="btn btn-info btn-sm" title="Duplica Record"><i class="bi bi-clipboard-check"></i></button>
|
||||
@if (canStartOdl(record.IdxMacchina))
|
||||
{
|
||||
<button @onclick="() => startOdl(record)" class="btn btn-success btn-sm" title="Avvia PODL">
|
||||
<i class="far fa-play-circle"></i>
|
||||
</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-secondary btn-sm disabled" title="ODL ancora in corso">
|
||||
<i class="far fa-play-circle"></i>
|
||||
</button>}
|
||||
</td>
|
||||
<td>
|
||||
@record.CodArticolo
|
||||
<div class="small textConsensed text-secondary">@record.ArticoloNav.DescArticolo</div>
|
||||
</td>
|
||||
<td>
|
||||
<div>
|
||||
@tradFase(record.KeyRichiesta)
|
||||
</div>
|
||||
@if (record.Note != "")
|
||||
{
|
||||
<div class="small textConsensed text-secondary badge text-bg-light border border-primary rounded">
|
||||
<b class="text-dark">Note:</b> @record.Note
|
||||
</div>
|
||||
}
|
||||
</td>
|
||||
<td>@tradFase(record.KeyRichiesta)</td>
|
||||
<td>
|
||||
@record.IdxMacchina
|
||||
<div class="small textConsensed text-secondary">@record.MachineNav.Descrizione</div>
|
||||
</td>
|
||||
<td>
|
||||
@record.NumPezzi
|
||||
<div class="small textConsensed"><b>N° pezzi:</b> @record.NumPezzi</div>
|
||||
<div class="small textConsensed"><b>T. Ciclo:</b> @record.Tcassegnato.ToString("N3")</div>
|
||||
</td>
|
||||
@*<td>@record.Note</td>*@
|
||||
<td>
|
||||
@record.Tcassegnato.ToString("N3")
|
||||
@if (@record.Attivabile)
|
||||
{
|
||||
<i class="fa-regular fa-square-check text-success"></i>
|
||||
}
|
||||
else
|
||||
{
|
||||
<i class="fa-regular fa-square text-secondary"></i>
|
||||
}
|
||||
</td>
|
||||
<td>@record.Note</td>
|
||||
<td>
|
||||
@if (POdlDelEnabled(record.IdxOdl))
|
||||
{
|
||||
|
||||
@@ -2,31 +2,38 @@
|
||||
using Microsoft.JSInterop;
|
||||
using MP.Data.DatabaseModels;
|
||||
using MP.SPEC.Data;
|
||||
using MP.SPEC.Services;
|
||||
|
||||
namespace MP.SPEC.Components
|
||||
{
|
||||
public partial class ListPODL
|
||||
public partial class ListPODL : IDisposable
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
[Parameter]
|
||||
public SelectPOdlParams actFilter { get; set; } = new SelectPOdlParams();
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<bool> PagerResetReq { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<PODLModel> RecordSel { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<int> updateRecordCount { get; set; }
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public string checkSelect(string CodArticolo)
|
||||
public string checkSelect(PODLModel record)
|
||||
{
|
||||
string answ = "";
|
||||
if (currRecord != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
answ = (currRecord.CodArticolo == CodArticolo) ? "table-info" : "";
|
||||
answ = ((currRecord.IdxMacchina == record.IdxMacchina) && (currRecord.CodArticolo == record.CodArticolo) && (currRecord.CodFase == record.CodFase)) ? "table-info" : "";
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
@@ -34,6 +41,15 @@ namespace MP.SPEC.Components
|
||||
return answ;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
currRecord = null;
|
||||
SearchRecords = null;
|
||||
ListRecords = null;
|
||||
ListStati = null;
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Properties
|
||||
@@ -45,12 +61,38 @@ namespace MP.SPEC.Components
|
||||
protected MpDataService MDService { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected MessageService MsgService { get; set; } = null!;
|
||||
protected IOApiService MpIoApiCall { get; set; } = null!;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected async Task cloneRecord(PODLModel selRec)
|
||||
{
|
||||
// creo record duplicato...
|
||||
PODLModel newRec = new PODLModel()
|
||||
{
|
||||
Attivabile = selRec.Attivabile,
|
||||
CodArticolo = selRec.CodArticolo,
|
||||
CodCli = selRec.CodCli,
|
||||
CodGruppo = selRec.CodGruppo,
|
||||
DueDate = selRec.DueDate,
|
||||
IdxMacchina = selRec.IdxMacchina,
|
||||
IdxOdl = selRec.IdxOdl,
|
||||
IdxPromessa = 0,
|
||||
InsertDate = selRec.InsertDate,
|
||||
KeyBCode = selRec.KeyBCode,
|
||||
KeyRichiesta = selRec.KeyRichiesta,
|
||||
Note = $"DUPLICATED - {selRec.Note}",
|
||||
NumPezzi = selRec.NumPezzi,
|
||||
Priorita = selRec.Priorita,
|
||||
PzPallet = selRec.PzPallet,
|
||||
Tcassegnato = selRec.Tcassegnato
|
||||
};
|
||||
currRecord = selRec;
|
||||
await RecordSel.InvokeAsync(newRec);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Eliminazione record selezionato (previa conferma)
|
||||
/// </summary>
|
||||
@@ -62,6 +104,7 @@ namespace MP.SPEC.Components
|
||||
return;
|
||||
await Task.Delay(1);
|
||||
var done = await MDService.PODLDeleteRecord(selRec);
|
||||
await callSyncDb(selRec.IdxMacchina);
|
||||
currRecord = null;
|
||||
await reloadData();
|
||||
await Task.Delay(1);
|
||||
@@ -69,11 +112,17 @@ namespace MP.SPEC.Components
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
MsgService.EA_PageUpdated += MessageService_EA_PageUpdated;
|
||||
MsgService.EA_SearchUpdated += OnSeachUpdated;
|
||||
MsgService.EA_StatoSearch += MsgService_EA_StatoSearch;
|
||||
//await FilterChanged.InvokeAsync(actFilter);
|
||||
ListStati = await MDService.AnagStatiComm();
|
||||
await reloadData();
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
if (!lastFilter.Equals(actFilter))
|
||||
{
|
||||
lastFilter = actFilter.clone();
|
||||
await reloadData();
|
||||
}
|
||||
}
|
||||
|
||||
protected async void OnSeachUpdated()
|
||||
@@ -94,14 +143,62 @@ namespace MP.SPEC.Components
|
||||
|
||||
protected async Task resetSel()
|
||||
{
|
||||
currRecord = null;
|
||||
await RecordSel.InvokeAsync(null);
|
||||
}
|
||||
|
||||
protected async Task selRecord(PODLModel selRec)
|
||||
{
|
||||
currRecord = selRec;
|
||||
await RecordSel.InvokeAsync(selRec);
|
||||
}
|
||||
|
||||
protected async Task startOdl(PODLModel selRec)
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Sei sicuro di voler avviare PODL selezionato?"))
|
||||
return;
|
||||
|
||||
if (selRec != null)
|
||||
{
|
||||
int idxEvento = 0;
|
||||
string evMess = "";
|
||||
// verifico ancora NON ci sia ODL corrente/aperto
|
||||
if (canStartOdl(selRec.IdxMacchina))
|
||||
{
|
||||
await callStartSetup(selRec.IdxMacchina);
|
||||
await Task.Delay(1);
|
||||
// chiamo stored stp_ODL_inizioSetupPromessa e recupero ODL corrente
|
||||
bool fatto = await MDService.POdlDoSetup(selRec);
|
||||
if (fatto)
|
||||
{
|
||||
var currPOdl = await MDService.PODL_getByKey(selRec.IdxPromessa);
|
||||
var newOdl = await MDService.OdlGetByKey(currPOdl.IdxOdl);
|
||||
|
||||
// registro evento...
|
||||
idxEvento = 2;
|
||||
evMess = $"Inizio Setup | PODL {selRec.IdxPromessa}";
|
||||
processaEvento(selRec.IdxMacchina, idxEvento, evMess, newOdl.IdxOdl, newOdl.CodArticolo);
|
||||
|
||||
// aspetto 1 sec
|
||||
await Task.Delay(1000);
|
||||
|
||||
// registro inizio produzione
|
||||
idxEvento = 2;
|
||||
evMess = $"Registrata inizio Produzione | PODL {selRec.IdxPromessa} | ODL {newOdl.IdxOdl} | ART {newOdl.CodArticolo}";
|
||||
processaEvento(selRec.IdxMacchina, idxEvento, evMess, newOdl.IdxOdl, newOdl.CodArticolo);
|
||||
|
||||
// chiamo task x IOB
|
||||
await callForceUpdate(selRec.IdxMacchina);
|
||||
await Task.Delay(1);
|
||||
await callForceUpdate(selRec.IdxMacchina);
|
||||
await Task.Delay(1);
|
||||
await callSyncDb(selRec.IdxMacchina);
|
||||
await Task.Delay(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected async Task UpdateData()
|
||||
{
|
||||
currRecord = null;
|
||||
@@ -113,9 +210,7 @@ namespace MP.SPEC.Components
|
||||
#region Private Fields
|
||||
|
||||
private PODLModel? currRecord = null;
|
||||
|
||||
private List<PODLModel>? ListRecords;
|
||||
|
||||
private List<ListValues>? ListStati;
|
||||
private List<PODLModel>? SearchRecords;
|
||||
|
||||
@@ -123,55 +218,153 @@ namespace MP.SPEC.Components
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private int _totalCount { get; set; } = 0;
|
||||
|
||||
private int currPage
|
||||
{
|
||||
get => MsgService.currPage;
|
||||
set => MsgService.currPage = value;
|
||||
get => actFilter.CurrPage;
|
||||
set => actFilter.CurrPage = value;
|
||||
}
|
||||
|
||||
private bool isLoading { get; set; } = false;
|
||||
private SelectPOdlParams lastFilter { get; set; } = new SelectPOdlParams() { CurrPage = -1 };
|
||||
|
||||
private int numRecord
|
||||
{
|
||||
get => MsgService.numRecord;
|
||||
set => MsgService.numRecord = value;
|
||||
get => actFilter.NumRec;
|
||||
set => actFilter.NumRec = value;
|
||||
}
|
||||
|
||||
private string SearchVal
|
||||
{
|
||||
get => string.IsNullOrEmpty(MsgService.SearchVal) ? "*" : MsgService.SearchVal;
|
||||
get => string.IsNullOrEmpty(actFilter.SearchVal) ? "*" : actFilter.SearchVal;
|
||||
}
|
||||
|
||||
private string StatoSel
|
||||
{
|
||||
get => MsgService.StateSel;
|
||||
set => MsgService.StateSel = value;
|
||||
get => actFilter.CodFase;
|
||||
set => actFilter.CodFase = value;
|
||||
}
|
||||
|
||||
private int totalCount
|
||||
{
|
||||
get => MsgService.totalCount;
|
||||
set => MsgService.totalCount = value;
|
||||
get => _totalCount;
|
||||
set
|
||||
{
|
||||
if (_totalCount != value)
|
||||
{
|
||||
_totalCount = value;
|
||||
updateRecordCount.InvokeAsync(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private async void MessageService_EA_PageUpdated()
|
||||
/// <summary>
|
||||
/// Chiama metodo x chiedere sync DB
|
||||
/// </summary>
|
||||
/// <param name="selRec"></param>
|
||||
/// <returns></returns>
|
||||
private async Task addTask2Exe(string idxMacc, string taskName, string taskVal)
|
||||
{
|
||||
await reloadData();
|
||||
// compongo URL e chiamo
|
||||
string restUrl = $"IOB/addTask2Exe/{idxMacc}?taskName={taskName}&taskVal={taskVal}";
|
||||
try
|
||||
{
|
||||
var response = await MpIoApiCall.callMpIoUrlGet(restUrl);
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private async void MsgService_EA_StatoSearch()
|
||||
/// <summary>
|
||||
/// Chiama metodo x chiedere force Update
|
||||
/// </summary>
|
||||
/// <param name="selRec"></param>
|
||||
/// <returns></returns>
|
||||
private async Task callForceUpdate(string IdxMacc)
|
||||
{
|
||||
await InvokeAsync(() =>
|
||||
// chiamo aggiunta task SyncDb...
|
||||
await addTask2Exe(IdxMacc, "ForceUpdate", $"SPEC|TS:{DateTime.Now:yyMMddHHmmss}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Chiama metodo x indicare inizio setup
|
||||
/// </summary>
|
||||
/// <param name="selRec"></param>
|
||||
/// <returns></returns>
|
||||
private async Task callStartSetup(string IdxMacc)
|
||||
{
|
||||
// chiamo evento inizio setup
|
||||
await addTask2Exe(IdxMacc, "startSetup", $"SPEC|TS:{DateTime.Now:yyMMddHHmmss}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Chiama metodo x chiedere sync DB
|
||||
/// </summary>
|
||||
/// <param name="IdxMacc"></param>
|
||||
/// <returns></returns>
|
||||
private async Task callSyncDb(string IdxMacc)
|
||||
{
|
||||
// chiamo aggiunta task SyncDb...
|
||||
await addTask2Exe(IdxMacc, "syncDbData", "");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// verifica se sia avviabile ODL x macchina
|
||||
/// </summary>
|
||||
/// <param name="idxMacchina"></param>
|
||||
/// <returns></returns>
|
||||
private bool canStartOdl(string idxMacchina)
|
||||
{
|
||||
// controllo se lista scaduta...
|
||||
bool answ = false;
|
||||
DateTime adesso = DateTime.Now;
|
||||
if (adesso > odlCurrExp || odlCurrList == null || odlCurrList.Count == 0)
|
||||
{
|
||||
PagerResetReq.InvokeAsync(true);
|
||||
//currPage = 1;
|
||||
Task task = UpdateData();
|
||||
StateHasChanged();
|
||||
});
|
||||
odlCurrList = MDService.OdlGetCurrent();
|
||||
odlCurrExp = adesso.AddSeconds(2);
|
||||
}
|
||||
answ = !odlCurrList.Contains(idxMacchina);
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// processa evento richiesto
|
||||
/// </summary>
|
||||
/// <param name="idxMacc"></param>
|
||||
/// <param name="idxEvento"></param>
|
||||
/// <param name="userMsg"></param>
|
||||
/// <param name="idxODL"></param>
|
||||
private async void processaEvento(string idxMacc, int idxEvento, string userMsg, int idxODL, string codArticolo)
|
||||
{
|
||||
// se manca codart calcolo...
|
||||
if (string.IsNullOrEmpty(codArticolo))
|
||||
{
|
||||
var currOdl = await MDService.OdlGetByKey(idxODL);
|
||||
if (currOdl != null)
|
||||
{
|
||||
codArticolo = currOdl.CodArticolo;
|
||||
}
|
||||
}
|
||||
|
||||
// scrivo evento scriviRigaEventoBarcode
|
||||
EventListModel newRec = new EventListModel()
|
||||
{
|
||||
IdxMacchina = idxMacc,
|
||||
InizioStato = DateTime.Now,
|
||||
IdxTipo = idxEvento,
|
||||
CodArticolo = codArticolo,
|
||||
MatrOpr = 0,
|
||||
pallet = "",
|
||||
Value = userMsg
|
||||
};
|
||||
|
||||
await MDService.EvListInsert(newRec);
|
||||
}
|
||||
|
||||
private async Task reloadData()
|
||||
@@ -182,9 +375,20 @@ namespace MP.SPEC.Components
|
||||
ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList();
|
||||
await Task.Delay(1);
|
||||
await InvokeAsync(() => StateHasChanged());
|
||||
//await updateRecordCount.InvokeAsync(totalCount);
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// scadenza validità lista ODL correnti
|
||||
/// </summary>
|
||||
private DateTime odlCurrExp = DateTime.Now.AddMinutes(-1);
|
||||
|
||||
/// <summary>
|
||||
/// Elenco ODL correnti...
|
||||
/// </summary>
|
||||
private List<string> odlCurrList = new List<string>();
|
||||
|
||||
private string tradFase(string codFase)
|
||||
{
|
||||
string answ = codFase;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
@if (@SelectedOdl != -1)
|
||||
{
|
||||
<div class="px-1 flex-fill">
|
||||
@if (isLoading)
|
||||
{
|
||||
<LoadingDataSmall></LoadingDataSmall>
|
||||
}
|
||||
else
|
||||
{
|
||||
<MP.SPEC.Components.Chart.Doughnut Type="@Chart.Doughnut.ChartType.Doughnut" Data="@Data.ToArray()" BackgroundColor="@colors"></MP.SPEC.Components.Chart.Doughnut>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using MP.Data.DatabaseModels;
|
||||
using MP.SPEC.Components;
|
||||
using MP.SPEC.Data;
|
||||
|
||||
namespace MP.SPEC.Components
|
||||
{
|
||||
public partial class ODLPlot
|
||||
{
|
||||
#region Public Properties
|
||||
|
||||
public int OdlId
|
||||
{
|
||||
get => _selParam;
|
||||
}
|
||||
|
||||
[Parameter]
|
||||
public int SelectedOdl
|
||||
{
|
||||
get => _selParam;
|
||||
set => _selParam = value;
|
||||
}
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
//protected DataLogFilter _SelFilter { get; set; } = new DataLogFilter();
|
||||
protected int _selParam { get; set; } = -1;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
private bool isLoading { get; set; } = false;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
isLoading = true;
|
||||
await Task.Delay(1);
|
||||
}
|
||||
private List<StatODLModel>? ListRecords = null;
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
await ReloadData();
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
public List<double> Data = new List<double>();
|
||||
public List<string> Labels = new List<string>();
|
||||
public List<DoughnutStyling> colors = new List<DoughnutStyling>();
|
||||
|
||||
protected async Task ReloadData()
|
||||
{
|
||||
Data.Clear();
|
||||
Labels.Clear();
|
||||
colors.Clear();
|
||||
ListRecords = await MDService.StatOdl(SelectedOdl);
|
||||
foreach (var record in ListRecords)
|
||||
{
|
||||
Data.Add(record.TotDurata);
|
||||
Labels.Add($"{record.Descrizione} - {record.TotDurata:N1}min");
|
||||
if (record.Css == "yellow")
|
||||
{
|
||||
colors.Add(new DoughnutStyling("orange", "ccc"));
|
||||
}
|
||||
else if (record.Css == "blue")
|
||||
{
|
||||
colors.Add(new DoughnutStyling("#2874A6", "ccc"));
|
||||
}
|
||||
else
|
||||
{
|
||||
colors.Add(new DoughnutStyling(record.Css, "ccc"));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
await Task.Delay(1);
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Inject]
|
||||
protected MpDataService MDService { get; set; } = null!;
|
||||
|
||||
#endregion Protected Methods
|
||||
}
|
||||
}
|
||||
@@ -1,113 +1,125 @@
|
||||
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="px-0 py-1">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="px-2">
|
||||
|
||||
@if (!liveUpdate)
|
||||
{
|
||||
<button class="btn btn-secondary" type="button" @onclick="() => toggleUpdate()" title="Click per tornare a Valori Live">
|
||||
<small>@lastUpdate</small>
|
||||
</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<button class="btn btn-primary" type="button" @onclick="() => toggleUpdate()">
|
||||
<span class="spinner-grow spinner-grow-sm" role="status" aria-hidden="true"></span>
|
||||
Valori live
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
<div class="px-2">
|
||||
@if (selMacchina != "*")
|
||||
{
|
||||
<button class="btn btn-warning" type="button" @onclick="() => takeSnapshot()">
|
||||
<i class="fa-solid fa-camera"></i>
|
||||
@snapMode
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
<div class="px-2">
|
||||
@if (snapshotDone)
|
||||
{
|
||||
<button class="btn btn-success" type="button" @onclick="() => navDossier()">
|
||||
<div class="spinner-border spinner-border-sm" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
<i class="fa-solid fa-camera"></i>
|
||||
Fatto! Mostra Dossier
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="px-0">
|
||||
<div class="d-flex justify-content-end">
|
||||
@if (showEditPar)
|
||||
<div class="d-flex justify-content-between pt-1 mb-1">
|
||||
<div class="px-2">
|
||||
@if (!liveUpdate)
|
||||
{
|
||||
<div class="px-0 input-group py-1">
|
||||
<button class="btn btn-primary" @onclick="() => toggleParams()"> <i class="fa-solid fa-arrow-right"></i></button>
|
||||
<label class="input-group-text" for="tempoAgg" title="Selezionare il tempo di aggiornamento dei dati"><i class="fa-solid fa-clock"></i></label>
|
||||
<select @bind="@selTempoAgg" class="form-select" id="tempoAgg" title="Selezionare il tempo di aggiornamento dei dati" style="width: 3em;">
|
||||
<option value="2">2</option>
|
||||
<option value="5">5</option>
|
||||
<option value="10">10</option>
|
||||
<option value="30">30</option>
|
||||
<option value="60">60</option>
|
||||
</select>
|
||||
<label class="input-group-text" for="maxRecord" title="Selezionare il numero massimo di record da visualizzare"><i class="fa-solid fa-list-ol"></i></label>
|
||||
<select @bind="@selMaxRecord" class="form-select" id="maxRecord" title="Selezionare il numero massimo di record da visualizzare">
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
<option value="250">250</option>
|
||||
<option value="500">500</option>
|
||||
<option value="1000">1000</option>
|
||||
<option value="2500">2500</option>
|
||||
<option value="5000">5000</option>
|
||||
</select>
|
||||
</div>
|
||||
<button class="btn btn-secondary" type="button" @onclick="() => toggleUpdate()" title="Click per tornare a Valori Live">
|
||||
<small>@lastUpdate</small>
|
||||
</button>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="px-2 py-1">
|
||||
<button class="btn btn-primary" @onclick="() => toggleParams()"><i class="fa-solid fa-arrow-left"></i></button>
|
||||
</div>
|
||||
<button class="btn btn-primary" type="button" @onclick="() => toggleUpdate()">
|
||||
<span class="spinner-grow spinner-grow-sm" role="status" aria-hidden="true"></span>
|
||||
Valori live
|
||||
</button>
|
||||
}
|
||||
<div class="px-0 py-1">
|
||||
<div class="px-2 input-group">
|
||||
<label class="input-group-text" for="macchina" title="Selezionare la macchina"><i class="fa-solid fa-hard-drive"></i></label>
|
||||
<select @bind="@selMacchina" class="form-select" id="macchina" title="Selezionare la macchina">
|
||||
<option value="*">--- Tutti ---</option>
|
||||
@if (ListMacchine != null)
|
||||
{
|
||||
foreach (var item in ListMacchine)
|
||||
{
|
||||
<option value="@item">@item</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
<label class="input-group-text" for="flusso" title="Selezionare il tipo di flusso"><i class="fa-solid fa-sliders"></i></label>
|
||||
<select @bind="@selFlux" class="form-select" id="flusso" title="Selezionare il tipo di flusso">
|
||||
<option value="*">--- Tutti ---</option>
|
||||
@if (ListFlux != null)
|
||||
{
|
||||
foreach (var item in ListFlux)
|
||||
{
|
||||
<option value="@item">@item</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
@if (dtMax == null)
|
||||
</div>
|
||||
<div class="px-2">
|
||||
@if (selMacchina != "*")
|
||||
{
|
||||
<button class="btn btn-warning" type="button" @onclick="() => takeSnapshot()">
|
||||
<i class="fa-solid fa-camera"></i>
|
||||
@snapMode
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
<div class="px-2">
|
||||
@if (snapshotDone)
|
||||
{
|
||||
<button class="btn btn-success" type="button" @onclick="() => navDossier()">
|
||||
<div class="spinner-border spinner-border-sm" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
<i class="fa-solid fa-camera"></i>
|
||||
Fatto! Mostra Dossier
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<a class="pt-2" data-bs-toggle="offcanvas" data-bs-target="#paramsFilterExample" aria-controls="paramsFilterExample" @onclick="setDtMax">
|
||||
<i class="fa-solid fa-bars text-dark"></i>
|
||||
</a>
|
||||
<div class="offcanvas offcanvas-end" tabindex="-1" id="paramsFilterExample" aria-labelledby="paramsFilterExampleLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h3 class="offcanvas-title" id="paramsFilterExampleLabel"><b>FILTRI</b></h3>
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<div class="small">
|
||||
<label class="px-2" for="macchina" title="Selezionare impianto">Impianto</label>
|
||||
</div>
|
||||
<div class="px-2 input-group">
|
||||
<label class="input-group-text" for="macchina" title="Selezionare impianto"><i class="fa-solid fa-hard-drive"></i></label>
|
||||
<select @bind="@selMacchina" class="form-select" id="macchina" title="Selezionare impianto">
|
||||
<option value="*">--- Tutti ---</option>
|
||||
@if (ListMacchine != null)
|
||||
{
|
||||
<button class="btn btn-primary" @onclick="() => setDtMax()"><i class="fa-regular fa-calendar-check"></i></button>
|
||||
foreach (var item in ListMacchine)
|
||||
{
|
||||
<option value="@item">@item</option>
|
||||
}
|
||||
}
|
||||
else
|
||||
</select>
|
||||
</div>
|
||||
<div class="small mt-2">
|
||||
<label class="px-2" for="flusso" title="Selezionare il parametro">Parametro</label>
|
||||
</div>
|
||||
<div class="px-2 input-group">
|
||||
<label class="input-group-text" for="flusso" title="Selezionare il parametro"><i class="fa-solid fa-sliders"></i></label>
|
||||
<select @bind="@selFlux" class="form-select" id="flusso" title="Selezionare il parametro">
|
||||
<option value="*">--- Tutti ---</option>
|
||||
@if (ListFlux != null)
|
||||
{
|
||||
<label class="input-group-text" for="flusso" title="Selezionare il tipo di flusso"><i class="fa-solid fa-sliders"></i></label>
|
||||
<input class="form" @bind="@dtMax" type="datetime-local" title="Data massima eventi da visualizzare">
|
||||
foreach (var item in ListFlux)
|
||||
{
|
||||
<option value="@item">@item</option>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</select>
|
||||
</div>
|
||||
<div class="small mt-2">
|
||||
<label class="px-2" for="dtMin" title="Selezionare inizio periodo">Inizio Periodo</label>
|
||||
</div>
|
||||
<div class="px-2 input-group">
|
||||
<label class="input-group-text" for="dtMin" title="Selezionare inizio periodo"><i class="fa-regular fa-calendar-minus"></i></label>
|
||||
<input class="form-control" @bind="@selDtMin" id="dtMin" type="datetime-local" title="Data minima eventi da visualizzare">
|
||||
</div>
|
||||
<div class="small mt-2">
|
||||
<label class="px-2" for="dtMax" title="Selezionare fine periodo">Fine Periodo</label>
|
||||
</div>
|
||||
<div class="px-2 input-group">
|
||||
<label class="input-group-text" for="dtMax" title="Selezionare fine periodo"><i class="fa-regular fa-calendar-plus"></i></label>
|
||||
<input class="form-control" @bind="@selDtMax" id="dtMax" type="datetime-local" title="Selezionare fine periodo">
|
||||
</div>
|
||||
<div class="small mt-2">
|
||||
<label class="px-2" for="tempoAgg" title="Selezionare refresh rate (sec) periodo">Refresh rate (sec)</label>
|
||||
</div>
|
||||
<div class="px-2 input-group">
|
||||
<label class="input-group-text" for="tempoAgg" title="Selezionare refresh rate (sec)"><i class="fa-solid fa-clock"></i></label>
|
||||
<select @bind="@selTempoAgg" class="form-select" id="tempoAgg" title="Selezionare refresh rate (sec)" style="width: 3em;">
|
||||
<option value="2">2</option>
|
||||
<option value="5">5</option>
|
||||
<option value="10">10</option>
|
||||
<option value="30">30</option>
|
||||
<option value="60">60</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="small mt-2">
|
||||
<label class="px-2" for="maxRecord" title="Numero massimo record da mostrare">Max Record</label>
|
||||
</div>
|
||||
<div class="px-2 input-group">
|
||||
<label class="input-group-text" for="maxRecord" title="Numero massimo record da mostrare"><i class="fa-solid fa-list-ol"></i></label>
|
||||
<select @bind="@selMaxRecord" class="form-select" id="maxRecord" title="Numero massimo record da mostrare">
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
<option value="250">250</option>
|
||||
<option value="500">500</option>
|
||||
<option value="1000">1000</option>
|
||||
<option value="2500">2500</option>
|
||||
<option value="5000">5000</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using MP.SPEC.Data;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace MP.SPEC.Components
|
||||
{
|
||||
@@ -100,7 +99,8 @@ namespace MP.SPEC.Components
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected bool showParam { get; set; } = false;
|
||||
protected bool selDt { get; set; } = false;
|
||||
protected string selMacchina
|
||||
{
|
||||
get => SelFilter.IdxMacchina;
|
||||
@@ -168,8 +168,19 @@ namespace MP.SPEC.Components
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
SelFilter = new SelectFluxParams();
|
||||
ListMacchine = await MDService.MacchineWithFlux();
|
||||
setDtMax();
|
||||
DateTime dtStart = SelFilter.dtMin != null ? (DateTime)SelFilter.dtMin : DateTime.Now.AddDays(-7);
|
||||
DateTime dtEnd = SelFilter.dtMax != null ? (DateTime)SelFilter.dtMax : DateTime.Now;
|
||||
ListMacchine = await MDService.MacchineWithFlux(dtStart, dtEnd);
|
||||
ListFlux = await MDService.ParametriGetFilt(selMacchina);
|
||||
|
||||
var configData = await MDService.ConfigGetAll();
|
||||
var currRec = configData.FirstOrDefault(x => x.Chiave == "numOreAnticipoSnapshot");
|
||||
if (currRec != null)
|
||||
{
|
||||
int.TryParse(currRec.Valore, out numOreAnticipoSnapshot);
|
||||
}
|
||||
|
||||
await FilterChanged.InvokeAsync(SelFilter);
|
||||
}
|
||||
|
||||
@@ -178,13 +189,15 @@ namespace MP.SPEC.Components
|
||||
// copio il filtro
|
||||
var currFilt = SelFilter;
|
||||
// fermo update
|
||||
currFilt.LiveUpdate = false;
|
||||
currFilt.LiveUpdate = true;
|
||||
currFilt.CurrPage = 0;
|
||||
currFilt.lastUpdate = $"{DateTime.Now:yyyy/MM/dd HH:mm:ss}";
|
||||
currFilt.dtMax = RoundDatetime(5);
|
||||
currFilt.dtMin = RoundDatetime(5).AddHours(-numOreAnticipoSnapshot);
|
||||
SelFilter = currFilt;
|
||||
}
|
||||
|
||||
|
||||
protected void startTimer()
|
||||
{
|
||||
aTimer = new System.Timers.Timer(5000);
|
||||
@@ -195,22 +208,24 @@ namespace MP.SPEC.Components
|
||||
|
||||
protected async Task takeSnapshot()
|
||||
{
|
||||
// indico snapshot fatto
|
||||
snapshotDone = true;
|
||||
startTimer();
|
||||
// fermo udpate
|
||||
liveUpdate = false;
|
||||
// se non ho data rif uso adesso...
|
||||
DateTime dtRif = SelFilter.dtRif == null ? DateTime.Now : (DateTime)SelFilter.dtRif;
|
||||
// aggiungo 2 sec
|
||||
dtRif = dtRif.AddSeconds(1);
|
||||
await MDService.DossiersTakeParamsSnapshot(selMacchina, 10, dtRif);
|
||||
DateTime dtMax = selDtMax == null ? RoundDatetime(5) : (DateTime)selDtMax;
|
||||
DateTime dtMin = selDtMin == null ? RoundDatetime(5).AddHours(-numOreAnticipoSnapshot) : (DateTime)selDtMin;
|
||||
// aggiungo 15 sec
|
||||
dtMax = dtMax.AddSeconds(15);
|
||||
await MDService.DossiersTakeParamsSnapshotLast(selMacchina, dtMin, dtMax);
|
||||
lastUpdate = $"{DateTime.Now:yyyy/MM/dd HH:mm:ss}";
|
||||
// indico snapshot fatto
|
||||
snapshotDone = true;
|
||||
startTimer();
|
||||
}
|
||||
|
||||
protected void toggleParams()
|
||||
{
|
||||
showEditPar = !showEditPar;
|
||||
selDtMax = null;
|
||||
}
|
||||
|
||||
protected async Task toggleUpdate()
|
||||
@@ -223,7 +238,7 @@ namespace MP.SPEC.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
dtMax = null;
|
||||
selDtMax = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,16 +248,18 @@ namespace MP.SPEC.Components
|
||||
|
||||
private static System.Timers.Timer aTimer = new System.Timers.Timer();
|
||||
private List<string>? ListFlux = null;
|
||||
|
||||
private List<string>? ListMacchine = null;
|
||||
|
||||
private int numOreAnticipoSnapshot = 5;
|
||||
private bool snapshotDone = false;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private DateTime? dtMax
|
||||
[Inject]
|
||||
private NavigationManager NavManager { get; set; } = null!;
|
||||
|
||||
private DateTime? selDtMax
|
||||
{
|
||||
get => SelFilter.dtMax;
|
||||
set
|
||||
@@ -252,7 +269,7 @@ namespace MP.SPEC.Components
|
||||
// copio il filtro
|
||||
var currFilt = SelFilter;
|
||||
// fermo update
|
||||
currFilt.LiveUpdate = false;
|
||||
currFilt.LiveUpdate = (value == null);
|
||||
currFilt.CurrPage = 0;
|
||||
currFilt.lastUpdate = $"{DateTime.Now:yyyy/MM/dd HH:mm:ss}";
|
||||
currFilt.dtMax = value;
|
||||
@@ -262,8 +279,25 @@ namespace MP.SPEC.Components
|
||||
}
|
||||
}
|
||||
|
||||
[Inject]
|
||||
private NavigationManager NavManager { get; set; } = null!;
|
||||
private DateTime? selDtMin
|
||||
{
|
||||
get => SelFilter.dtMin;
|
||||
set
|
||||
{
|
||||
if (SelFilter.dtMin != value)
|
||||
{
|
||||
// copio il filtro
|
||||
var currFilt = SelFilter;
|
||||
// fermo update
|
||||
currFilt.LiveUpdate = false;
|
||||
currFilt.CurrPage = 0;
|
||||
currFilt.lastUpdate = $"{DateTime.Now:yyyy/MM/dd HH:mm:ss}";
|
||||
currFilt.dtMin = value;
|
||||
SelFilter = currFilt;
|
||||
reportChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool showEditPar { get; set; } = false;
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-text">
|
||||
<span class="me-1 @leftStringCSS">@leftString</span>
|
||||
<div class="form-check form-check-sm form-switch py-1" title="Parameter View Mode (RealTime / LogData)">
|
||||
<input class="form-check-input" type="checkbox" id="mySwitch" name="setupAlarms" checked @onclick="() => toggle()">
|
||||
</div>
|
||||
<span class="@rightStringCSS">@rightString</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using System.Net.Http;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.AspNetCore.Components.Forms;
|
||||
using Microsoft.AspNetCore.Components.Routing;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.AspNetCore.Components.Web.Virtualization;
|
||||
using Microsoft.JSInterop;
|
||||
using MP.SPEC;
|
||||
using MP.SPEC.Shared;
|
||||
using MP.SPEC.Components;
|
||||
using MP.SPEC.Data;
|
||||
|
||||
namespace MP.SPEC.Components
|
||||
{
|
||||
public partial class ToggleMode
|
||||
{
|
||||
[Parameter]
|
||||
public EventCallback<SelectGlobalToggle> FilterChanged { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public SelectGlobalToggle SelFilter { get; set; } = new SelectGlobalToggle();
|
||||
|
||||
protected bool isActive
|
||||
{
|
||||
get => SelFilter.isActive;
|
||||
set
|
||||
{
|
||||
if (SelFilter.isActive != value)
|
||||
{
|
||||
SelFilter.isActive = value;
|
||||
reportChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected string leftString
|
||||
{
|
||||
get => SelFilter.leftString;
|
||||
set
|
||||
{
|
||||
if (SelFilter.leftString != value)
|
||||
{
|
||||
SelFilter.leftString = value;
|
||||
reportChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
protected string leftStringCSS
|
||||
{
|
||||
get => SelFilter.leftStringCSS;
|
||||
set
|
||||
{
|
||||
if (SelFilter.leftStringCSS != value)
|
||||
{
|
||||
SelFilter.leftStringCSS = value;
|
||||
reportChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
protected string rightString
|
||||
{
|
||||
get => SelFilter.rightString;
|
||||
set
|
||||
{
|
||||
if (SelFilter.rightString != value)
|
||||
{
|
||||
SelFilter.rightString = value;
|
||||
reportChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
protected string rightStringCSS
|
||||
{
|
||||
get => SelFilter.rightStringCSS;
|
||||
set
|
||||
{
|
||||
if (SelFilter.rightStringCSS != value)
|
||||
{
|
||||
SelFilter.rightStringCSS = value;
|
||||
reportChange();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void toggle()
|
||||
{
|
||||
var currFilt = SelFilter;
|
||||
currFilt.isActive = !currFilt.isActive;
|
||||
SelFilter = currFilt;
|
||||
if (isActive)
|
||||
{
|
||||
rightStringCSS = "fw-bold";
|
||||
leftStringCSS = "text-secondary";
|
||||
}
|
||||
else
|
||||
{
|
||||
leftStringCSS = "fw-bold";
|
||||
rightStringCSS = "text-secondary";
|
||||
}
|
||||
}
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
if (isActive)
|
||||
{
|
||||
rightStringCSS = "fw-bold";
|
||||
leftStringCSS = "text-secondary";
|
||||
}
|
||||
else
|
||||
{
|
||||
leftStringCSS = "fw-bold";
|
||||
rightStringCSS = "text-secondary";
|
||||
}
|
||||
await FilterChanged.InvokeAsync(SelFilter);
|
||||
}
|
||||
|
||||
private void reportChange()
|
||||
{
|
||||
FilterChanged.InvokeAsync(SelFilter);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Drawing;
|
||||
|
||||
namespace MP.SPEC.Data
|
||||
{
|
||||
public class DoughnutStyling
|
||||
{
|
||||
public string color { get; set; }
|
||||
public string border { get; set; }
|
||||
|
||||
public DoughnutStyling(string color, string border)
|
||||
{
|
||||
this.color = color;
|
||||
this.border = border;
|
||||
}
|
||||
}
|
||||
}
|
||||
+575
-266
@@ -82,7 +82,7 @@ namespace MP.SPEC.Data
|
||||
else
|
||||
{
|
||||
result = await Task.FromResult(dbController.AnagStatiComm());
|
||||
// serializzp e salvo...
|
||||
// serializzo e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
await redisDb.StringSetAsync(redisStatoCom, rawData, getRandTOut(redisLongTimeCache));
|
||||
stopWatch.Stop();
|
||||
@@ -113,7 +113,7 @@ namespace MP.SPEC.Data
|
||||
else
|
||||
{
|
||||
result = await Task.FromResult(dbController.AnagTipoArtLV());
|
||||
// serializzp e salvo...
|
||||
// serializzo e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
await redisDb.StringSetAsync(redisTipoArt, rawData, getRandTOut(redisLongTimeCache));
|
||||
stopWatch.Stop();
|
||||
@@ -127,6 +127,41 @@ namespace MP.SPEC.Data
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco Codice articolo con dati dossier gestiti
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<string>> ArticleWithDossier()
|
||||
{
|
||||
List<string>? result = new List<string>();
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string readType = "DB";
|
||||
string currKey = redisArtByDossier;
|
||||
// cerco in redis dato valore sel macchina...
|
||||
RedisValue rawData = redisDb.StringGet(currKey);
|
||||
if (rawData.HasValue)
|
||||
{
|
||||
result = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
|
||||
readType = "REDIS";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await Task.FromResult(dbController.ArticleWithDossier());
|
||||
// serializzo e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
|
||||
}
|
||||
if (result == null)
|
||||
{
|
||||
result = new List<string>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"ArticleWithDossier | Read from {readType}: {ts.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Eliminazione record selezionato
|
||||
/// </summary>
|
||||
@@ -242,7 +277,7 @@ namespace MP.SPEC.Data
|
||||
else
|
||||
{
|
||||
result = await Task.FromResult(dbController.ConfigGetAll());
|
||||
// serializzp e salvo...
|
||||
// serializzo e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
await redisDb.StringSetAsync(redisConfKey, rawData, getRandTOut(redisLongTimeCache));
|
||||
stopWatch.Stop();
|
||||
@@ -274,14 +309,6 @@ namespace MP.SPEC.Data
|
||||
return await Task.FromResult(dbController.ConfigUpdate(updRec));
|
||||
}
|
||||
|
||||
public List<FluxLog> convertToFluxLog(string Valore)
|
||||
{
|
||||
//string valStriped = Valore.Substring(7, Valore.Length - 8);
|
||||
//var result = JsonConvert.DeserializeObject<List<FluxLog>>(valStriped);
|
||||
var result = JsonConvert.DeserializeObject<DossierFluxLogDTO>(Valore);
|
||||
return result.ODL;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
// Clear database controller
|
||||
@@ -314,16 +341,16 @@ namespace MP.SPEC.Data
|
||||
/// macchina (ordinato x data registrazione)
|
||||
/// </summary>
|
||||
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data macchina</param>
|
||||
/// <param name="DtRef">Data di riferimento (Massima) per estrazione records</param>
|
||||
/// <param name="MaxRec">numero massimo record da restituire</param>
|
||||
/// <param name="DtStart">Data minima per estrazione records</param>
|
||||
/// <param name="DtEnd">Data Massima per estrazione records</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<Dossiers>> DossiersGetLastFilt(string IdxMacchina, DateTime DtRef, int MaxRec)
|
||||
public async Task<List<Dossiers>> DossiersGetLastFilt(string IdxMacchina, string CodArticolo, DateTime DtStart, DateTime DtEnd)
|
||||
{
|
||||
List<Dossiers>? result = new List<Dossiers>();
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string readType = "DB";
|
||||
string currKey = $"{redisDossByMac}:{IdxMacchina}";
|
||||
string currKey = $"{redisDossByMac}:{IdxMacchina}:{CodArticolo}:{DtStart:yyyyMMddHHmm}:{DtEnd:yyyyMMddHHmm}";
|
||||
// cerco in redis dato valore sel macchina...
|
||||
RedisValue rawData = redisDb.StringGet(currKey);
|
||||
if (rawData.HasValue)
|
||||
@@ -333,8 +360,8 @@ namespace MP.SPEC.Data
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await Task.FromResult(dbController.DossiersGetLastFilt(IdxMacchina, DtRef, MaxRec));
|
||||
// serializzp e salvo...
|
||||
result = await Task.FromResult(dbController.DossiersGetLastFilt(IdxMacchina, CodArticolo, DtStart, DtEnd));
|
||||
// serializzo e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache / 5));
|
||||
}
|
||||
@@ -369,6 +396,27 @@ namespace MP.SPEC.Data
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua salvataggio snapshot parametri (con stored) + svuota eventuale cache redis
|
||||
/// </summary>
|
||||
/// <param name="IdxMacchina">macchina</param>
|
||||
/// <param name="MaxSec">NUm massimo secondi per recuperare dati correnti</param>
|
||||
/// <param name="DtRif">DataOra riferimento x cui prendere valori antecedenti</param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> DossiersTakeParamsSnapshotLast(string IdxMacchina, DateTime dtMin, DateTime dtMax)
|
||||
{
|
||||
bool answ = false;
|
||||
await Task.Delay(1);
|
||||
// chiamo stored x salvare parametri
|
||||
dbController.DossiersTakeParamsSnapshotLast(IdxMacchina, dtMin, dtMax);
|
||||
// svuoto cache redis x macchina
|
||||
string currKey = $"{redisDossByMac}:{IdxMacchina}";
|
||||
redisDb.StringSet(currKey, "", TimeSpan.FromSeconds(1));
|
||||
currKey = $"{redisDossByMac}:*";
|
||||
redisDb.StringSet(currKey, "", TimeSpan.FromSeconds(1));
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restitusice elenco aziende
|
||||
/// </summary>
|
||||
@@ -392,6 +440,16 @@ namespace MP.SPEC.Data
|
||||
return Task.FromResult(dbController.ElencoLink());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aggiunta record EventList
|
||||
/// </summary>
|
||||
/// <param name="newRec"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> EvListInsert(EventListModel newRec)
|
||||
{
|
||||
return await dbController.EvListInsert(newRec);
|
||||
}
|
||||
|
||||
public async Task<bool> FlushRedisCache()
|
||||
{
|
||||
await Task.Delay(1);
|
||||
@@ -400,6 +458,505 @@ namespace MP.SPEC.Data
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco ultimi n record flux log dato macchina e flusso (ordinato x data registrazione)
|
||||
/// </summary>
|
||||
/// <param name="DtMax">Data massima (recupera eventi antecedenti)</param>
|
||||
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data macchina</param>
|
||||
/// <param name="CodFlux">*=tutti, altrimenti solo selezionato</param>
|
||||
/// <param name="MaxRec">numero massimo record da restituire</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<FluxLog>> FluxLogGetLastFilt(DateTime DtMax, string IdxMacchina, string CodFlux, int MaxRec)
|
||||
{
|
||||
List<FluxLog>? result = new List<FluxLog>();
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string readType = "DB";
|
||||
string currKey = $"{redisFluxLogFilt}:{IdxMacchina}:{CodFlux}:{MaxRec}:{DtMax:yyyyMMdd}:{DtMax:HHmm}";
|
||||
// cerco in redis dato valore sel macchina...
|
||||
RedisValue rawData = redisDb.StringGet(currKey);
|
||||
if (rawData.HasValue)
|
||||
{
|
||||
result = JsonConvert.DeserializeObject<List<FluxLog>>($"{rawData}");
|
||||
readType = "REDIS";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await Task.FromResult(dbController.FluxLogGetLastFilt(DtMax, IdxMacchina, CodFlux, MaxRec));
|
||||
// serializzo e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(10));
|
||||
}
|
||||
if (result == null)
|
||||
{
|
||||
result = new List<FluxLog>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"FluxLogGetLastFilt | Read from {readType}: {ts.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco setup dei tag conf correnti
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<Dictionary<string, List<TagData>>> getAllTags()
|
||||
{
|
||||
return Task.FromResult(currTagConf);
|
||||
}
|
||||
|
||||
public List<FluxLogDTO> getFluxLog(string Valore)
|
||||
{
|
||||
List<FluxLogDTO> answ = new List<FluxLogDTO>();
|
||||
DossierFluxLogDTO? result = JsonConvert.DeserializeObject<DossierFluxLogDTO>(Valore);
|
||||
if (result != null)
|
||||
{
|
||||
if (result.ODL != null)
|
||||
{
|
||||
answ = result
|
||||
.ODL
|
||||
.OrderBy(x => x.CodFlux)
|
||||
.ToList();
|
||||
// inizializzo SE necessario
|
||||
foreach (var item in answ)
|
||||
{
|
||||
item.ValoreEdit = String.IsNullOrEmpty(item.ValoreEdit) ? item.Valore : item.ValoreEdit;
|
||||
}
|
||||
}
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// restituisce il valore da REDIS associato al tag richeisto
|
||||
/// </summary>
|
||||
/// <param name="redKey">Chiave in cui cercare il valore</param>
|
||||
/// <returns></returns>
|
||||
public string getTagConf(string redKey)
|
||||
{
|
||||
string outVal = "";
|
||||
// cerco in REDIS la conf x l'IOB
|
||||
var rawData = redisDb.StringGet(redKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
outVal = $"{rawData}";
|
||||
}
|
||||
return outVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco ODL filtrati x stato, articolo, KeyRich (che contiene stato)
|
||||
/// </summary>
|
||||
/// <param name="inCorso">Stato ODL: true=in corso/completato</param>
|
||||
/// <param name="codArt">Cod articolo</param>
|
||||
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
|
||||
/// <param name="IdxMacchina">id macchina da cercare</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<ODLModel>> ListODLFilt(bool inCorso, string codArt, string keyRichPart, string IdxMacchina, DateTime startDate, DateTime endDate)
|
||||
{
|
||||
return await Task.FromResult(dbController.ListODLFilt(inCorso, codArt, keyRichPart, IdxMacchina, startDate, endDate));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco PODL non avviati filtrati x articolo, KeyRich (che contiene stato)
|
||||
/// </summary>
|
||||
/// <param name="codArt">Cod articolo</param>
|
||||
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<PODLModel>> ListPODLFilt(string codArt, string keyRichPart)
|
||||
{
|
||||
List<PODLModel>? result = new List<PODLModel>();
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string readType = "DB";
|
||||
string currKey = $"{redisPOdlList}:{codArt}:{keyRichPart}";
|
||||
// cerco in redis dato valore sel macchina...
|
||||
RedisValue rawData = redisDb.StringGet(currKey);
|
||||
if (rawData.HasValue)
|
||||
{
|
||||
result = JsonConvert.DeserializeObject<List<PODLModel>>($"{rawData}");
|
||||
readType = "REDIS";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await Task.FromResult(dbController.ListPODLFilt(codArt, keyRichPart));
|
||||
// serializzo e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(3));
|
||||
}
|
||||
if (result == null)
|
||||
{
|
||||
result = new List<PODLModel>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"ListPODLFilt | Read from {readType}: {ts.TotalMilliseconds}ms");
|
||||
return result;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco di tutte le macchine gestite
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<Macchine>> MacchineGetAll()
|
||||
{
|
||||
List<Macchine>? result = new List<Macchine>();
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string readType = "DB";
|
||||
string currKey = redisMacList;
|
||||
// cerco in redis dato valore sel macchina...
|
||||
RedisValue rawData = redisDb.StringGet(currKey);
|
||||
if (rawData.HasValue)
|
||||
{
|
||||
result = JsonConvert.DeserializeObject<List<Macchine>>($"{rawData}");
|
||||
readType = "REDIS";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await Task.FromResult(dbController.MacchineGetAll());
|
||||
// serializzo e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
|
||||
}
|
||||
if (result == null)
|
||||
{
|
||||
result = new List<Macchine>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"MacchineGetAll | Read from {readType}: {ts.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco id Macchine che abbiano dati FLuxLog, nel periodo indicato
|
||||
/// </summary>
|
||||
/// <param name="dtStart"></param>
|
||||
/// <param name="dtEnd"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<string>> MacchineWithFlux(DateTime dtStart, DateTime dtEnd)
|
||||
{
|
||||
List<string>? result = new List<string>();
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string readType = "DB";
|
||||
string currKey = $"{redisMacByFlux}:{dtStart:yyyyMMddHHmm}:{dtEnd:yyyyMMddHHmm}";
|
||||
// cerco in redis dato valore sel macchina...
|
||||
RedisValue rawData = redisDb.StringGet(currKey);
|
||||
if (rawData.HasValue)
|
||||
{
|
||||
result = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
|
||||
readType = "REDIS";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await dbController.MacchineWithFlux(dtStart, dtEnd);
|
||||
// serializzo e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
|
||||
}
|
||||
if (result == null)
|
||||
{
|
||||
result = new List<string>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"MacchineWithFlux | Read from {readType}: {ts.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Effettua chiusura dell'ODL indicato, andand
|
||||
/// </summary>
|
||||
/// <param name="idxOdl">idx odl da chiudere</param>
|
||||
/// <param name="idxMacchina">idx macchina</param>
|
||||
/// <param name="matrOpr">matricola operatore</param>
|
||||
/// <param name="confPezzi">indica se confermare i pezzi priam di chiudere ODL</param>
|
||||
public async Task<bool> ODLClose(int idxOdl, string idxMacchina, int matrOpr, bool confPezzi)
|
||||
{
|
||||
bool fatto = false;
|
||||
await Task.Delay(1);
|
||||
// recupero dati x conf modalità conferma
|
||||
var configData = await ConfigGetAll();
|
||||
if (configData != null)
|
||||
{
|
||||
bool confRett = false;
|
||||
var currRec = configData.FirstOrDefault(x => x.Chiave == "confRett");
|
||||
if (currRec != null)
|
||||
{
|
||||
bool.TryParse(currRec.Valore, out confRett);
|
||||
}
|
||||
int modoConfProd = 0;
|
||||
currRec = configData.FirstOrDefault(x => x.Chiave == "modoConfProd");
|
||||
if (currRec != null)
|
||||
{
|
||||
int.TryParse(currRec.Valore, out modoConfProd);
|
||||
}
|
||||
// chiamo metodo conferma!
|
||||
fatto = await dbController.ODLClose(idxOdl, idxMacchina, matrOpr, confPezzi, confRett, modoConfProd);
|
||||
}
|
||||
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Record ODL da chaive
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<ODLModel> OdlGetByKey(int IdxOdl)
|
||||
{
|
||||
await Task.Delay(1);
|
||||
var dbResult = dbController.OdlGetByKey(IdxOdl);
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ODL correnti (tutti)
|
||||
/// </summary>
|
||||
/// <param name="idxMacchina"></param>
|
||||
/// <returns></returns>
|
||||
public List<string> OdlGetCurrent()
|
||||
{
|
||||
List<string> dbResult = new List<string>();
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string readType = "DB";
|
||||
string currKey = $"{redisOdlCurrByMac}";
|
||||
// cerco in redis dato valore sel macchina...
|
||||
RedisValue rawData = redisDb.StringGet(currKey);
|
||||
if (rawData.HasValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
dbResult = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
readType = "REDIS";
|
||||
}
|
||||
else
|
||||
{
|
||||
dbResult = dbController.OdlGetCurrent().Select(x => x.IdxMacchina).Distinct().ToList();
|
||||
rawData = JsonConvert.SerializeObject(dbResult);
|
||||
redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(3));
|
||||
}
|
||||
if (dbResult == null)
|
||||
{
|
||||
dbResult = new List<string>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"OdlGetCurrent | Read from {readType}: {ts.TotalMilliseconds}ms");
|
||||
|
||||
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco di tutti i parametri filtrati x macchina
|
||||
/// </summary>
|
||||
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data macchina</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<string>> ParametriGetFilt(string IdxMacchina)
|
||||
{
|
||||
List<string>? result = new List<string>();
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string readType = "DB";
|
||||
string currKey = $"{redisFluxByMac}:{IdxMacchina}";
|
||||
// cerco in redis dato valore sel macchina...
|
||||
RedisValue rawData = redisDb.StringGet(currKey);
|
||||
if (rawData.HasValue)
|
||||
{
|
||||
result = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
|
||||
readType = "REDIS";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await Task.FromResult(dbController.ParametriGetFilt(IdxMacchina));
|
||||
// serializzo e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
|
||||
}
|
||||
if (result == null)
|
||||
{
|
||||
result = new List<string>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"ParametriGetFilt | Read from {readType}: {ts.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recupero PODL da chiave
|
||||
/// </summary>
|
||||
/// <param name="idxPODL"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PODLModel> PODL_getByKey(int idxPODL)
|
||||
{
|
||||
return await dbController.PODL_getByKey(idxPODL);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Eliminazione record selezionato
|
||||
/// </summary>
|
||||
/// <param name="currRec"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> PODLDeleteRecord(PODLModel currRec)
|
||||
{
|
||||
return await dbController.PODLDeleteRecord(currRec);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Avvio fase setup per il record selezionato
|
||||
/// </summary>
|
||||
/// <param name="currRec"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> POdlDoSetup(PODLModel currRec)
|
||||
{
|
||||
return await dbController.PODL_startSetup(currRec, 0, 1, 1, "");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aggiornamento record selezionato
|
||||
/// </summary>
|
||||
/// <param name="currRec"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> POdlUpdateRecord(PODLModel currRec)
|
||||
{
|
||||
var dbResult = await dbController.PODLUpdateRecord(currRec);
|
||||
// elimino cache redis...
|
||||
RedisValue pattern = new RedisValue($"{redisPOdlList}:*");
|
||||
bool answ = await ExecFlushRedisPattern(pattern);
|
||||
|
||||
return dbResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Statistiche ODL calcolate (da stored stp_STAT_ODL)
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<List<StatODLModel>> StatOdl(int IdxOdl)
|
||||
{
|
||||
return dbController.OdlStart(IdxOdl);
|
||||
}
|
||||
|
||||
public async Task<bool> updateDossierValue(Dossiers currDoss, FluxLogDTO editFL)
|
||||
{
|
||||
bool answ = false;
|
||||
// recupero intero set valori dossier deserializzando...
|
||||
var fluxLogList = getFluxLog(currDoss.Valore);
|
||||
await Task.Delay(1);
|
||||
|
||||
// se tutto ok
|
||||
if (fluxLogList != null)
|
||||
{
|
||||
// da provare...!!!!
|
||||
|
||||
// elimino vecchio record
|
||||
var currRec = fluxLogList.FirstOrDefault(x => x.CodFlux == editFL.CodFlux && x.dtEvento == editFL.dtEvento);
|
||||
if (currRec != null)
|
||||
{
|
||||
fluxLogList.Remove(currRec);
|
||||
// aggiungo nuovo
|
||||
fluxLogList.Add(editFL);
|
||||
}
|
||||
|
||||
// serializzo nuovamente valore
|
||||
DossierFluxLogDTO? result = new DossierFluxLogDTO();
|
||||
var ODLflux = result.ODL.ToList();
|
||||
foreach (var item in fluxLogList)
|
||||
{
|
||||
ODLflux.Add(item);
|
||||
}
|
||||
|
||||
DossierFluxLogDTO updatedResult = new DossierFluxLogDTO() { ODL = ODLflux };
|
||||
|
||||
string rawVal = JsonConvert.SerializeObject(updatedResult);
|
||||
currDoss.Valore = rawVal;
|
||||
// aggiorno record sul DB
|
||||
await dbController.DossiersUpdateValore(currDoss);
|
||||
}
|
||||
|
||||
return answ;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected Random rand = new Random();
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Restituisce un timeout dai minuti richiesti + tempo random 1..60 sec
|
||||
/// </summary>
|
||||
/// <param name="stdMinutes"></param>
|
||||
/// <returns></returns>
|
||||
protected TimeSpan getRandTOut(int stdMinutes)
|
||||
{
|
||||
double rndValue = (double)stdMinutes + (double)rand.Next(1, 60) / 60;
|
||||
return TimeSpan.FromMinutes(rndValue);
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private const string redisArtByDossier = redisBaseAddr + "SPEC:Cache:ArtByDossier";
|
||||
private const string redisBaseAddr = "MP:";
|
||||
|
||||
private const string redisConfKey = redisBaseAddr + "SPEC:Cache:Config";
|
||||
|
||||
private const string redisDossByMac = redisBaseAddr + "SPEC:Cache:DossByMac";
|
||||
|
||||
private const string redisFluxByMac = redisBaseAddr + "SPEC:Cache:FluxByMac";
|
||||
private const string redisOdlCurrByMac = redisBaseAddr + "SPEC:Cache:OdlByMac";
|
||||
|
||||
private const string redisMacByFlux = redisBaseAddr + "SPEC:Cache:MacByFlux";
|
||||
private const string redisMacList = redisBaseAddr + "SPEC:Cache:MacList";
|
||||
private const string redisPOdlList = redisBaseAddr + "SPEC:Cache:POdlList";
|
||||
private const string redisFluxLogFilt = redisBaseAddr + "SPEC:Cache:FluxLogFilt";
|
||||
|
||||
private const string redisStatoCom = redisBaseAddr + "SPEC:Cache:StatoCom";
|
||||
|
||||
private const string redisTipoArt = redisBaseAddr + "SPEC:Cache:TipoArt";
|
||||
|
||||
private static IConfiguration _configuration = null!;
|
||||
|
||||
private static ILogger<MpDataService> _logger = null!;
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto per connessione a REDIS
|
||||
/// </summary>
|
||||
private ConnectionMultiplexer redisConn = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto per connessione a REDIS modalità admin (ex flux dati)
|
||||
/// </summary>
|
||||
private ConnectionMultiplexer redisConnAdmin = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto DB redis da impiegare x chiamate R/W
|
||||
/// </summary>
|
||||
private IDatabase redisDb = null!;
|
||||
|
||||
private int redisLongTimeCache = 5;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Esegue flush memoria redis dato pattern
|
||||
/// </summary>
|
||||
@@ -429,254 +986,6 @@ namespace MP.SPEC.Data
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco ultimi n record flux log dato macchina e flusso (ordinato x data registrazione)
|
||||
/// </summary>
|
||||
/// <param name="DtMax">Data massima (recupera eventi antecedenti)</param>
|
||||
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data macchina</param>
|
||||
/// <param name="CodFlux">*=tutti, altrimenti solo selezionato</param>
|
||||
/// <param name="MaxRec">numero massimo record da restituire</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<FluxLog>> FluxLogGetLastFilt(DateTime DtMax, string IdxMacchina, string CodFlux, int MaxRec)
|
||||
{
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
var results = await Task.FromResult(dbController.FluxLogGetLastFilt(DtMax, IdxMacchina, CodFlux, MaxRec));
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"FluxLogGetLastFilt | Read from DB: {ts.TotalMilliseconds}ms");
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco setup dei tag conf correnti
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public Task<Dictionary<string, List<TagData>>> getAllTags()
|
||||
{
|
||||
return Task.FromResult(currTagConf);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// restituisce il valore da REDIS associato al tag richeisto
|
||||
/// </summary>
|
||||
/// <param name="redKey">Chiave in cui cercare il valore</param>
|
||||
/// <returns></returns>
|
||||
public string getTagConf(string redKey)
|
||||
{
|
||||
string outVal = "";
|
||||
// cerco in REDIS la conf x l'IOB
|
||||
var rawData = redisDb.StringGet(redKey);
|
||||
if (!string.IsNullOrEmpty(rawData))
|
||||
{
|
||||
outVal = $"{rawData}";
|
||||
}
|
||||
return outVal;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco ODL filtrati x stato, articolo, KeyRich (che contiene stato)
|
||||
/// </summary>
|
||||
/// <param name="inCorso">Stato ODL: true=in corso/completato</param>
|
||||
/// <param name="codArt">Cod articolo</param>
|
||||
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<ODLModel>> ListODLFilt(bool inCorso, string codArt, string keyRichPart)
|
||||
{
|
||||
return await Task.FromResult(dbController.ListODLFilt(inCorso, codArt, keyRichPart));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco PODL non avviati filtrati x articolo, KeyRich (che contiene stato)
|
||||
/// </summary>
|
||||
/// <param name="codArt">Cod articolo</param>
|
||||
/// <param name="keyRichPart">KeyRich (parziale) da cercare (es cod stato x yacht)</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<PODLModel>> ListPODLFilt(string codArt, string keyRichPart)
|
||||
{
|
||||
return await Task.FromResult(dbController.ListPODLFilt(codArt, keyRichPart));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco di tutte le macchine gestite
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<Macchine>> MacchineGetAll()
|
||||
{
|
||||
List<Macchine>? result = new List<Macchine>();
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string readType = "DB";
|
||||
string currKey = redisMacList;
|
||||
// cerco in redis dato valore sel macchina...
|
||||
RedisValue rawData = redisDb.StringGet(currKey);
|
||||
if (rawData.HasValue)
|
||||
{
|
||||
result = JsonConvert.DeserializeObject<List<Macchine>>($"{rawData}");
|
||||
readType = "REDIS";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await Task.FromResult(dbController.MacchineGetAll());
|
||||
// serializzp e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
|
||||
}
|
||||
if (result == null)
|
||||
{
|
||||
result = new List<Macchine>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"MacchineGetAll | Read from {readType}: {ts.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco ID macchine con dati FluxLog gestite
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<string>> MacchineWithFlux()
|
||||
{
|
||||
List<string>? result = new List<string>();
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string readType = "DB";
|
||||
string currKey = redisMacByFlux;
|
||||
// cerco in redis dato valore sel macchina...
|
||||
RedisValue rawData = redisDb.StringGet(currKey);
|
||||
if (rawData.HasValue)
|
||||
{
|
||||
result = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
|
||||
readType = "REDIS";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await Task.FromResult(dbController.MacchineWithFlux());
|
||||
// serializzp e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
|
||||
}
|
||||
if (result == null)
|
||||
{
|
||||
result = new List<string>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"MacchineWithFlux | Read from {readType}: {ts.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Elenco di tutti i parametri filtrati x macchina
|
||||
/// </summary>
|
||||
/// <param name="IdxMacchina">* = tutte, altrimenti solo x una data macchina</param>
|
||||
/// <returns></returns>
|
||||
public async Task<List<string>> ParametriGetFilt(string IdxMacchina)
|
||||
{
|
||||
List<string>? result = new List<string>();
|
||||
Stopwatch stopWatch = new Stopwatch();
|
||||
stopWatch.Start();
|
||||
string readType = "DB";
|
||||
string currKey = $"{redisFluxByMac}:{IdxMacchina}";
|
||||
// cerco in redis dato valore sel macchina...
|
||||
RedisValue rawData = redisDb.StringGet(currKey);
|
||||
if (rawData.HasValue)
|
||||
{
|
||||
result = JsonConvert.DeserializeObject<List<string>>($"{rawData}");
|
||||
readType = "REDIS";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = await Task.FromResult(dbController.ParametriGetFilt(IdxMacchina));
|
||||
// serializzp e salvo...
|
||||
rawData = JsonConvert.SerializeObject(result);
|
||||
redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache));
|
||||
}
|
||||
if (result == null)
|
||||
{
|
||||
result = new List<string>();
|
||||
}
|
||||
stopWatch.Stop();
|
||||
TimeSpan ts = stopWatch.Elapsed;
|
||||
Log.Debug($"ParametriGetFilt | Read from {readType}: {ts.TotalMilliseconds}ms");
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Eliminazione record selezionato
|
||||
/// </summary>
|
||||
/// <param name="currRec"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> PODLDeleteRecord(PODLModel currRec)
|
||||
{
|
||||
return await dbController.PODLDeleteRecord(currRec);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Aggiornamento record selezionato
|
||||
/// </summary>
|
||||
/// <param name="currRec"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<bool> POdlUpdateRecord(PODLModel currRec)
|
||||
{
|
||||
return await dbController.PODLUpdateRecord(currRec);
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected Random rand = new Random();
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
/// <summary>
|
||||
/// Restituisce un timeout dai minuti richiesti + tempo random 1..60 sec
|
||||
/// </summary>
|
||||
/// <param name="stdMinutes"></param>
|
||||
/// <returns></returns>
|
||||
protected TimeSpan getRandTOut(int stdMinutes)
|
||||
{
|
||||
double rndValue = (double)stdMinutes + (double)rand.Next(1, 60) / 60;
|
||||
return TimeSpan.FromMinutes(rndValue);
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private const string redisBaseAddr = "MP:";
|
||||
private const string redisConfKey = redisBaseAddr + "SPEC:Cache:Config";
|
||||
private const string redisDossByMac = redisBaseAddr + "SPEC:Cache:DossByMac";
|
||||
private const string redisFluxByMac = redisBaseAddr + "SPEC:Cache:FluxByMac";
|
||||
private const string redisMacByFlux = redisBaseAddr + "SPEC:Cache:MacByFlux";
|
||||
private const string redisMacList = redisBaseAddr + "SPEC:Cache:MacList";
|
||||
private const string redisStatoCom = redisBaseAddr + "SPEC:Cache:StatoCom";
|
||||
private const string redisTipoArt = redisBaseAddr + "SPEC:Cache:TipoArt";
|
||||
private static IConfiguration _configuration = null!;
|
||||
private static ILogger<MpDataService> _logger = null!;
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto per connessione a REDIS
|
||||
/// </summary>
|
||||
private ConnectionMultiplexer redisConn = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto per connessione a REDIS modalità admin (ex flux dati)
|
||||
/// </summary>
|
||||
private ConnectionMultiplexer redisConnAdmin = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Oggetto DB redis da impiegare x chiamate R/W
|
||||
/// </summary>
|
||||
private IDatabase redisDb = null!;
|
||||
|
||||
private int redisLongTimeCache = 5;
|
||||
|
||||
#endregion Private Fields
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -13,10 +13,14 @@
|
||||
|
||||
public int CurrPage { get; set; } = 1;
|
||||
|
||||
public DateTime DtRef { get; set; } = InitDatetime(5);
|
||||
public DateTime DtEnd { get; set; } = InitDatetime(5);
|
||||
|
||||
public DateTime DtStart { get; set; } = InitDatetime(5).AddDays(-730);
|
||||
|
||||
public string IdxMacchina { get; set; } = "*";
|
||||
|
||||
public string CodArticolo { get; set; } = "*";
|
||||
|
||||
public int MaxRecord { get; set; } = 100;
|
||||
|
||||
#endregion Public Properties
|
||||
@@ -44,17 +48,18 @@
|
||||
if (IdxMacchina != item.IdxMacchina)
|
||||
return false;
|
||||
|
||||
if (CodArticolo != item.CodArticolo)
|
||||
return false;
|
||||
|
||||
if (MaxRecord != item.MaxRecord)
|
||||
return false;
|
||||
|
||||
if (DtRef != item.DtRef)
|
||||
if (DtEnd != item.DtEnd)
|
||||
return false;
|
||||
|
||||
if (CurrPage != item.CurrPage)
|
||||
return false;
|
||||
|
||||
//if (lastUpdate != item.lastUpdate)
|
||||
// return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
public int CurrPage { get; set; } = 1;
|
||||
public DateTime? dtRif { get; set; } = null;
|
||||
public DateTime? dtMax { get; set; } = null;
|
||||
public DateTime? dtMin { get; set; } = null;
|
||||
public string IdxMacchina { get; set; } = "*";
|
||||
public string lastUpdate { get; set; } = "-";
|
||||
public bool LiveUpdate { get; set; } = true;
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
namespace MP.SPEC.Data
|
||||
{
|
||||
public class SelectGlobalToggle
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
public SelectGlobalToggle()
|
||||
{ }
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Bool: indica se il toggle è attivo
|
||||
/// </summary>
|
||||
public bool isActive { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// string: stringa da mostrare a sinistra (disattivo onInitialize)
|
||||
/// </summary>
|
||||
public string leftString { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// string: stringa da mostrare a destra (attivo onInitialize)
|
||||
/// </summary>
|
||||
public string rightString { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// string: stile stringa da mostrare a sinistra (disattivo onInitialize)
|
||||
/// </summary>
|
||||
public string leftStringCSS { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// string: stile stringa da mostrare a destra (attivo onInitialize)
|
||||
/// </summary>
|
||||
public string rightStringCSS { get; set; } = "";
|
||||
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is SelectGlobalToggle item))
|
||||
return false;
|
||||
|
||||
if (isActive != item.isActive)
|
||||
return false;
|
||||
|
||||
if (leftString != item.leftString)
|
||||
return false;
|
||||
|
||||
if (rightString != item.rightString)
|
||||
return false;
|
||||
|
||||
if (leftStringCSS != item.leftStringCSS)
|
||||
return false;
|
||||
|
||||
if (rightStringCSS != item.rightStringCSS)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using MP.Data;
|
||||
|
||||
namespace MP.SPEC.Data
|
||||
{
|
||||
public class SelectOdlParams
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
public SelectOdlParams()
|
||||
{ }
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public string CodStato { get; set; } = "*";
|
||||
public string IdxMacchina { get; set; } = "*";
|
||||
public int CurrPage { get; set; } = 1;
|
||||
public int NumRec { get; set; } = 10;
|
||||
public int TotCount { get; set; } = 0;
|
||||
public DateTime DtEnd { get; set; } = Utils.InitDatetime(DateTime.Now, 5);
|
||||
public DateTime DtStart { get; set; } = Utils.InitDatetime(DateTime.Now, 5).AddDays(-7);
|
||||
public int MaxRecord { get; set; } = 100;
|
||||
public bool IsActive { get; set; } = true;
|
||||
public string SearchVal { get; set; } = "*";
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is SelectOdlParams item))
|
||||
return false;
|
||||
|
||||
if (IsActive != item.IsActive)
|
||||
return false;
|
||||
|
||||
if (CodStato != item.CodStato)
|
||||
return false;
|
||||
|
||||
if (IdxMacchina != item.IdxMacchina)
|
||||
return false;
|
||||
|
||||
if (MaxRecord != item.MaxRecord)
|
||||
return false;
|
||||
|
||||
if (NumRec != item.NumRec)
|
||||
return false;
|
||||
|
||||
if (DtStart != item.DtStart)
|
||||
return false;
|
||||
|
||||
if (DtEnd != item.DtEnd)
|
||||
return false;
|
||||
|
||||
if (CurrPage != item.CurrPage)
|
||||
return false;
|
||||
|
||||
if (SearchVal != item.SearchVal)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
namespace MP.SPEC.Data
|
||||
{
|
||||
public class SelectPOdlParams
|
||||
{
|
||||
#region Public Constructors
|
||||
|
||||
public SelectPOdlParams()
|
||||
{ }
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public string CodFase { get; set; } = "*";
|
||||
|
||||
public int CurrPage { get; set; } = 1;
|
||||
|
||||
public string IdxMacchina { get; set; } = "*";
|
||||
|
||||
public int MaxRecord { get; set; } = 100;
|
||||
|
||||
public int NumRec { get; set; } = 10;
|
||||
|
||||
public string SearchVal { get; set; } = "*";
|
||||
|
||||
public int TotCount { get; set; } = 0;
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public SelectPOdlParams clone()
|
||||
{
|
||||
SelectPOdlParams clonedData = new SelectPOdlParams()
|
||||
{
|
||||
CodFase = this.CodFase,
|
||||
CurrPage = this.CurrPage,
|
||||
IdxMacchina = this.IdxMacchina,
|
||||
MaxRecord = this.MaxRecord,
|
||||
NumRec = this.NumRec,
|
||||
SearchVal = this.SearchVal,
|
||||
TotCount = this.TotCount
|
||||
};
|
||||
return clonedData;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (!(obj is SelectPOdlParams item))
|
||||
return false;
|
||||
|
||||
if (CodFase != item.CodFase)
|
||||
return false;
|
||||
|
||||
if (MaxRecord != item.MaxRecord)
|
||||
return false;
|
||||
|
||||
if (NumRec != item.NumRec)
|
||||
return false;
|
||||
|
||||
if (TotCount != item.TotCount)
|
||||
return false;
|
||||
|
||||
if (CurrPage != item.CurrPage)
|
||||
return false;
|
||||
|
||||
if (IdxMacchina != item.IdxMacchina)
|
||||
return false;
|
||||
|
||||
if (SearchVal != item.SearchVal)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
||||
+11
-5
@@ -5,7 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<RootNamespace>MP.SPEC</RootNamespace>
|
||||
<Version>6.16.2209.2711</Version>
|
||||
<Version>6.16.2210.1820</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -14,6 +14,16 @@
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="compilerconfig.json" />
|
||||
<None Include="wwwroot\lib\Chart.js\chart.esm.js" />
|
||||
<None Include="wwwroot\lib\Chart.js\chart.esm.min.js" />
|
||||
<None Include="wwwroot\lib\Chart.js\chart.js" />
|
||||
<None Include="wwwroot\lib\Chart.js\chart.min.js" />
|
||||
<None Include="wwwroot\lib\Chart.js\helpers.esm.js" />
|
||||
<None Include="wwwroot\lib\Chart.js\helpers.esm.min.js" />
|
||||
<None Include="wwwroot\lib\chartjs-adapter-luxon\chartjs-adapter-luxon.esm.js" />
|
||||
<None Include="wwwroot\lib\chartjs-adapter-luxon\chartjs-adapter-luxon.esm.min.js" />
|
||||
<None Include="wwwroot\lib\chartjs-adapter-luxon\chartjs-adapter-luxon.js" />
|
||||
<None Include="wwwroot\lib\chartjs-adapter-luxon\chartjs-adapter-luxon.min.js" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -21,10 +31,6 @@
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="wwwroot\lib\" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MP.Data\MP.Data.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -135,7 +135,8 @@
|
||||
{
|
||||
<tr class="@checkSelect(@record.CodArticolo)">
|
||||
<td>
|
||||
<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm"><i class="bi bi-pencil-square"></i></button>
|
||||
<button @onclick="() => selRecord(record)" class="btn btn-primary btn-sm" title="Modifica Record"><i class="bi bi-pencil-square"></i></button>
|
||||
<button @onclick="() => cloneRecord(record)" class="btn btn-info btn-sm" title="Duplica Record"><i class="bi bi-clipboard-check"></i></button>
|
||||
</td>
|
||||
<td>
|
||||
<div>@record.CodArticolo</div>
|
||||
|
||||
@@ -27,6 +27,12 @@ namespace MP.SPEC.Pages
|
||||
public void Dispose()
|
||||
{
|
||||
MessageService.EA_SearchUpdated -= OnSeachUpdated;
|
||||
currRecord = null;
|
||||
ListTipoArt = null;
|
||||
ListAziende = null;
|
||||
SearchRecords = null;
|
||||
ListRecords = null;
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
public async void OnSeachUpdated()
|
||||
@@ -136,6 +142,10 @@ namespace MP.SPEC.Pages
|
||||
}
|
||||
ListAziende = await MDService.ElencoAziende();
|
||||
ListTipoArt = await MDService.AnagTipoArtLV();
|
||||
}
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
await reloadData();
|
||||
}
|
||||
|
||||
@@ -155,6 +165,21 @@ namespace MP.SPEC.Pages
|
||||
currRecord = selRec;
|
||||
await Task.Delay(1);
|
||||
}
|
||||
protected async Task cloneRecord(AnagArticoli selRec)
|
||||
{
|
||||
// creo record duplicato...
|
||||
AnagArticoli newRec = new AnagArticoli()
|
||||
{
|
||||
Azienda = selRec.Azienda,
|
||||
CodArticolo = selRec.CodArticolo,
|
||||
DescArticolo = $"CLONE - { selRec.DescArticolo }",
|
||||
Disegno = selRec.Disegno,
|
||||
Tipo=selRec.Tipo
|
||||
};
|
||||
currRecord = newRec;
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
|
||||
protected async Task update(AnagArticoli selRec)
|
||||
{
|
||||
|
||||
@@ -14,24 +14,77 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
<DossiersFilter FilterChanged="updateFilter"></DossiersFilter>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@if (currDetFluxLogRecord != null)
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card mb-5">
|
||||
<div class="card-header bg-primary text-light">Modifica Parametro</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-3 pe-0">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text" id="inputGroup-sizing-sm">MACCHINA</span>
|
||||
<input type="text" class="form-control" disabled aria-label="Art search" aria-describedby="inputGroup-sizing-sm" @bind-value="@currDetFluxLogRecord.IdxMacchina">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3 pe-0">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text" id="inputGroup-sizing-sm">DATA</span>
|
||||
<input type="text" class="form-control" disabled aria-label="Art search" aria-describedby="inputGroup-sizing-sm" @bind-value="@currDetFluxLogRecord.dtEvento">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3 pe-0">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text" id="inputGroup-sizing-sm">DATA TYPE</span>
|
||||
<input type="text" class="form-control" disabled aria-label="Art search" aria-describedby="inputGroup-sizing-sm" @bind-value="@currDetFluxLogRecord.CodFlux">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3 pe-0">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text" id="inputGroup-sizing-sm">VALORE</span>
|
||||
<input type="text" class="form-control" aria-label="Art search" aria-describedby="inputGroup-sizing-sm" @bind-value="@currDetFluxLogRecord.ValoreEdit">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row pt-4">
|
||||
<div class="col-3 pe-0">
|
||||
</div>
|
||||
<div class="col-3 pe-0">
|
||||
</div>
|
||||
<div class="col-3 pe-0">
|
||||
<div class="d-grid gap-2">
|
||||
<button @onclick="() => cancel()" class="btn btn-warning">Annulla <i class="bi bi-x-circle"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3 pe-0">
|
||||
<div class="d-grid gap-2">
|
||||
<button @onclick="() => update(currDetFluxLogRecord)" class="btn btn-success">Save <i class="bi bi-save"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@if (isLoading)
|
||||
{
|
||||
<LoadingData></LoadingData>
|
||||
}
|
||||
else
|
||||
{
|
||||
<ListDossiers SelFilter="@currFilter" TotRecordChanged="updateTotal"></ListDossiers>
|
||||
<ListDossiers SelFilter="@currFilter" RecordSel="@selRecordDoss" RecordSelFlux="@selRecordFlux" TotRecordChanged="updateTotal"></ListDossiers>
|
||||
}
|
||||
</div>
|
||||
<div class="card-footer py-1">
|
||||
<DataPager @ref="pagerODL" PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using MP.Data.DatabaseModels;
|
||||
using MP.Data.DTO;
|
||||
using MP.SPEC.Components;
|
||||
using MP.SPEC.Data;
|
||||
|
||||
@@ -14,6 +17,12 @@ namespace MP.SPEC.Pages
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected MpDataService MDService { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected MessageService MsgService { get; set; } = null!;
|
||||
|
||||
@@ -21,6 +30,12 @@ namespace MP.SPEC.Pages
|
||||
|
||||
#region Protected Methods
|
||||
|
||||
protected async Task cancel()
|
||||
{
|
||||
currDetFluxLogRecord = null;
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
protected void ForceReload(int newNum)
|
||||
{
|
||||
numRecord = newNum;
|
||||
@@ -48,6 +63,33 @@ namespace MP.SPEC.Pages
|
||||
isFiltering = false;
|
||||
}
|
||||
|
||||
protected async Task selRecordDoss(Dossiers selDoss)
|
||||
{
|
||||
currRecordDoss = selDoss;
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
protected async Task selRecordFlux(FluxLogDTO selRec)
|
||||
{
|
||||
currDetFluxLogRecord = selRec;
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
protected async Task update(FluxLogDTO selRec)
|
||||
{
|
||||
if (!await JSRuntime.InvokeAsync<bool>("confirm", "Confermi di voler salvare le modifiche? queste saranno parte del dossier inviato all'impianto"))
|
||||
return;
|
||||
|
||||
await Task.Delay(1);
|
||||
if (currRecordDoss != null)
|
||||
{
|
||||
// METODO PER UPDATE FLUX
|
||||
await MDService.updateDossierValue(currRecordDoss, selRec);
|
||||
}
|
||||
currDetFluxLogRecord = null;
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
protected void updateTotal(int newTotCount)
|
||||
{
|
||||
totalCount = newTotCount;
|
||||
@@ -55,8 +97,20 @@ namespace MP.SPEC.Pages
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private FluxLogDTO? _currDetFluxLogRecord = null;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private FluxLogDTO? currDetFluxLogRecord
|
||||
{
|
||||
get => _currDetFluxLogRecord;
|
||||
set { _currDetFluxLogRecord = value; }
|
||||
}
|
||||
|
||||
private SelectDossierParams currFilter { get; set; } = new SelectDossierParams();
|
||||
|
||||
private int currPage
|
||||
@@ -65,6 +119,7 @@ namespace MP.SPEC.Pages
|
||||
set => MsgService.currPage = value;
|
||||
}
|
||||
|
||||
private Dossiers? currRecordDoss { get; set; } = null;
|
||||
private bool isFiltering { get; set; } = false;
|
||||
private bool isLoading { get; set; } = true;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
</div>
|
||||
<div class="card-body text-center">
|
||||
<div class="shortcuts my-5 py-5">
|
||||
<div class="shortcuts my-3 py-3">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
@if (ElencoLink == null)
|
||||
@@ -33,6 +33,7 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
foreach (var item in ElencoLink)
|
||||
{
|
||||
<a href="@item.NavigateUrl" class="shortcut">
|
||||
|
||||
+87
-17
@@ -1,34 +1,104 @@
|
||||
@page "/ODL"
|
||||
|
||||
<div class="card mb-5">
|
||||
<div class="card-header table-primary">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="px-1">
|
||||
<h3><b>ODL</b></h3>
|
||||
<div class="card-header table-primary ">
|
||||
<div class="d-flex justify-content-between col-12">
|
||||
<div class="px-1 col-4">
|
||||
<div>
|
||||
<h3><b>ODL</b></h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-2">
|
||||
<div class="input-group input-group">
|
||||
<label class="input-group-text" for="maxRecord" title="Selezionare la fase da visualizzare"><i class="fa-solid fa-screwdriver-wrench"></i></label>
|
||||
<select @bind="@selStato" class="form-select"title="Selezionare la fase da visualizzare">
|
||||
<option value="*">--- Tutti ---</option>
|
||||
@if (ListStati != null)
|
||||
<div class="col-4">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group-text">
|
||||
<span class="me-1 @leftStringCSS">Completati</span>
|
||||
<span class="form-check form-check-sm form-switch py-1" title="ODL Chiusi / Correnti">
|
||||
<input class="form-check-input" type="checkbox" id="switchActive" @bind="@isActive">
|
||||
</span>
|
||||
<span class="@rightStringCSS">In Corso</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-end">
|
||||
<a class="pt-2 text-dark" data-bs-toggle="offcanvas" data-bs-target="#paramsFilterExample" aria-controls="paramsFilterExample" @onclick="setDtMax">
|
||||
<i class="fa-solid fa-bars"></i>
|
||||
</a>
|
||||
<div class="offcanvas offcanvas-end" tabindex="-1" id="paramsFilterExample" aria-labelledby="paramsFilterExampleLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h3 class="offcanvas-title" id="paramsFilterExampleLabel"><b>FILTRI</b></h3>
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<div>
|
||||
<div>
|
||||
Seleziona i filtri per:
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<div class="small mt-2">
|
||||
<label class="px-2" for="fase" title="Selezionare inizio periodo">Fase</label>
|
||||
</div>
|
||||
<div class="input-group px-2">
|
||||
<label class="input-group-text" for="fase" title="Selezionare la fase da visualizzare"><i class="fa-solid fa-screwdriver-wrench"></i></label>
|
||||
<select @bind="@selStato" id="fase" class="form-select" title="Selezionare la fase da visualizzare">
|
||||
<option value="*">--- Tutti ---</option>
|
||||
@if (ListStati != null)
|
||||
{
|
||||
foreach (var item in ListStati)
|
||||
{
|
||||
<option value="@item.value">@item.label</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<div class="small mt-2">
|
||||
<label class="px-2" for="macchina" title="Selezionare inizio periodo">Macchina</label>
|
||||
</div>
|
||||
<div class="input-group px-2">
|
||||
<label class="input-group-text" for="macchina" title="Selezionare la macchina da visualizzare"><i class="fa-solid fa-hard-drive"></i></label>
|
||||
<select @bind="@selMacchina" id="macchina" class="form-select" title="Selezionare la macchina da visualizzare">
|
||||
<option value="*">--- Tutti ---</option>
|
||||
@if (ListMacchine != null)
|
||||
{
|
||||
foreach (var item in ListMacchine)
|
||||
{
|
||||
<option value="@item">@item</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@if (!isActive)
|
||||
{
|
||||
foreach (var item in ListStati)
|
||||
{
|
||||
<option value="@item.value">@item.label</option>
|
||||
}
|
||||
<div class="small mt-2">
|
||||
<label class="px-2" for="dtMin" title="Selezionare inizio periodo">Inizio Periodo</label>
|
||||
</div>
|
||||
<div class="px-2 input-group">
|
||||
<label class="input-group-text" for="dtMin" title="Selezionare inizio periodo"><i class="fa-regular fa-calendar-minus"></i></label>
|
||||
<input class="form-control" @bind="@selDtStart" id="dtMin" type="datetime-local" title="Data minima eventi da visualizzare">
|
||||
</div>
|
||||
<div class="small mt-2">
|
||||
<label class="px-2" for="dtMax" title="Selezionare fine periodo">Fine Periodo</label>
|
||||
</div>
|
||||
<div class="px-2 input-group">
|
||||
<label class="input-group-text" for="dtMax" title="Selezionare fine periodo"><i class="fa-regular fa-calendar-plus"></i></label>
|
||||
<input class="form-control" @bind="@selDtEnd" id="dtMax" type="datetime-local" title="Selezionare fine periodo">
|
||||
</div>
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<ListODL StatoSel="@selStato" PagerResetReq="pgResetReq"></ListODL>
|
||||
<ListODL PagerResetReq="pgResetReq" updateRecordCount="UpdateTotCount" currFilter="@currFilter"></ListODL>
|
||||
</div>
|
||||
<div class="card-footer py-1">
|
||||
<DataPager @ref="pagerODL" PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
+89
-33
@@ -7,22 +7,66 @@ namespace MP.SPEC.Pages
|
||||
{
|
||||
public partial class ODL
|
||||
{
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Inizializzazione con periodo e arrotondamento
|
||||
/// </summary>
|
||||
/// <param name="minRound"></param>
|
||||
/// <returns></returns>
|
||||
public static DateTime RoundDatetime(int minRound)
|
||||
{
|
||||
TimeSpan DayElapsed = DateTime.Now.Subtract(DateTime.Today);
|
||||
int minDay = (int)Math.Ceiling((double)(DayElapsed.TotalMinutes / minRound)) * minRound;
|
||||
DateTime endRounded = DateTime.Today.AddMinutes(minDay);
|
||||
return endRounded;
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Fields
|
||||
|
||||
protected DataPager pagerODL;
|
||||
protected DataPager pagerODL = null!;
|
||||
|
||||
#endregion Protected Fields
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
protected bool isActive
|
||||
{
|
||||
get => currFilter.IsActive;
|
||||
set => currFilter.IsActive = value;
|
||||
}
|
||||
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected MpDataService MDService { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected MessageService MsgService { get; set; } = null!;
|
||||
protected DateTime selDtEnd
|
||||
{
|
||||
get => currFilter.DtEnd;
|
||||
set
|
||||
{
|
||||
if (currFilter.DtEnd != value)
|
||||
{
|
||||
currFilter.DtEnd = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected DateTime selDtStart
|
||||
{
|
||||
get => currFilter.DtStart;
|
||||
set
|
||||
{
|
||||
if (currFilter.DtStart != value)
|
||||
{
|
||||
currFilter.DtStart = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
@@ -40,14 +84,8 @@ namespace MP.SPEC.Pages
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
// abilito ricerca...
|
||||
MsgService.ShowSearch = true;
|
||||
// resetto search
|
||||
MsgService.SearchVal = "";
|
||||
ListAziende = await MDService.ElencoAziende();
|
||||
ListStati = await MDService.AnagStatiComm();
|
||||
// carico dati
|
||||
await reloadData();
|
||||
ListMacchine = await MDService.MacchineWithFlux(currFilter.DtStart, currFilter.DtEnd);
|
||||
}
|
||||
|
||||
protected async Task pgResetReq(bool doReset)
|
||||
@@ -58,54 +96,72 @@ namespace MP.SPEC.Pages
|
||||
}
|
||||
}
|
||||
|
||||
protected void setDtMax()
|
||||
{
|
||||
// copio il filtro
|
||||
currFilter.DtEnd = RoundDatetime(5);
|
||||
currFilter.DtStart = RoundDatetime(5).AddDays(-1);
|
||||
}
|
||||
|
||||
protected void UpdateTotCount(int newTotCount)
|
||||
{
|
||||
totalCount = newTotCount;
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private MP.Data.DatabaseModels.ODLModel? currRecordOdl = null;
|
||||
private MP.Data.DatabaseModels.PODLModel? currRecordPOdl = null;
|
||||
private List<MP.Data.DatabaseModels.AnagGruppi>? ListAziende;
|
||||
private List<MP.Data.DatabaseModels.ListValues>? ListStati;
|
||||
private List<string>? ListMacchine;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
|
||||
private string currAzienda { get; set; } = "*";
|
||||
private SelectOdlParams currFilter { get; set; } = new SelectOdlParams();
|
||||
|
||||
private int currPage
|
||||
{
|
||||
get => MsgService.currPage;
|
||||
set => MsgService.currPage = value;
|
||||
get => currFilter.CurrPage;
|
||||
set => currFilter.CurrPage = value;
|
||||
}
|
||||
|
||||
private bool isLoading { get; set; } = false;
|
||||
|
||||
private int numRecord
|
||||
private string leftStringCSS
|
||||
{
|
||||
get => MsgService.numRecord;
|
||||
set => MsgService.numRecord = value;
|
||||
get => isActive ? "text-secondary" : "text-dark fw-bold";
|
||||
}
|
||||
|
||||
private string selStato { get; set; } = "*";
|
||||
private int numRecord
|
||||
{
|
||||
get => currFilter.NumRec;
|
||||
set => currFilter.NumRec = value;
|
||||
}
|
||||
|
||||
private string rightStringCSS
|
||||
{
|
||||
get => isActive ? "text-dark fw-bold" : "text-secondary";
|
||||
}
|
||||
|
||||
private string selStato
|
||||
{
|
||||
get => currFilter.CodStato;
|
||||
set => currFilter.CodStato = value;
|
||||
}
|
||||
private string selMacchina
|
||||
{
|
||||
get => currFilter.IdxMacchina;
|
||||
set => currFilter.IdxMacchina = value;
|
||||
}
|
||||
|
||||
private int totalCount
|
||||
{
|
||||
get => MsgService.totalCount;
|
||||
set => MsgService.totalCount = value;
|
||||
get => currFilter.TotCount;
|
||||
set => currFilter.TotCount = value;
|
||||
}
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
private async Task reloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
await Task.Delay(1);
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
#endregion Private Methods
|
||||
}
|
||||
}
|
||||
@@ -32,5 +32,3 @@
|
||||
<DataPager @ref="pagerODL" PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace MP.SPEC.Pages
|
||||
if (newParams.CurrPage == 0)
|
||||
{
|
||||
newParams.CurrPage = 1;
|
||||
newParams.LiveUpdate = false;
|
||||
//newParams.LiveUpdate = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
+37
-13
@@ -4,7 +4,7 @@
|
||||
<div class="card mb-5">
|
||||
<div class="card-header table-primary">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="col-6">
|
||||
<div class="col-6 col-lg-8">
|
||||
<div class="d-flex">
|
||||
<div class="px-2">
|
||||
<h3><b>P</b>romesse <b>ODL</b></h3>
|
||||
@@ -17,9 +17,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="col-6 col-lg-4">
|
||||
<div class="input-group input-group-sm">
|
||||
<label class="input-group-text" for="maxRecord" title="Selezionare l'azienda da visualizzare"><i class="fa-solid fa-industry"></i></label>
|
||||
@*<label class="input-group-text" for="maxRecord" title="Selezionare l'azienda da visualizzare"><i class="fa-solid fa-industry"></i></label>
|
||||
<select @bind="@currAzienda" class="form-select" title="Selezionare l'azienda da visualizzare">
|
||||
@if (ListAziende != null)
|
||||
{
|
||||
@@ -28,9 +28,9 @@
|
||||
<option value="@item.CodGruppo">@item.DescrGruppo</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</select>*@
|
||||
<label class="input-group-text" for="maxRecord" title="Selezionare la fase da visualizzare"><i class="fa-solid fa-screwdriver-wrench"></i></label>
|
||||
<select @bind="@selStato" class="form-select" title="Selezionare la fase da visualizzare">
|
||||
<select @bind="@currFase" class="form-select" title="Selezionare la fase da visualizzare">
|
||||
<option value="*">--- Tutti ---</option>
|
||||
@if (ListStati != null)
|
||||
{
|
||||
@@ -42,7 +42,7 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
@if (currRecord != null)
|
||||
{
|
||||
@@ -77,6 +77,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text" id="inputGroup-sizing-sm"># pz</span>
|
||||
<input type="text" class="form-control" aria-label="Num Pezzi" aria-describedby="inputGroup-sizing-sm" @bind-value="@currRecord.NumPezzi">
|
||||
<span class="input-group-text" id="inputGroup-sizing-sm">T.Ciclo</span>
|
||||
<input type="text" class="form-control" aria-label="Tempo Ciclo" aria-describedby="inputGroup-sizing-sm" @bind-value="@currRecord.Tcassegnato">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="input-group input-group-sm">
|
||||
@@ -94,7 +100,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
|
||||
<div class="col-3">
|
||||
<div class="input-group input-group-sm">
|
||||
<div class="input-group input-group-sm">
|
||||
@@ -129,6 +134,28 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="input-group input-group-sm">
|
||||
<span class="input-group-text" id="inputGroup-sizing-sm">Note</span>
|
||||
<input type="text" class="form-control" aria-label="Note" aria-describedby="inputGroup-sizing-sm" @bind-value="@currRecord.Note">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-2">
|
||||
<div class="col-3">
|
||||
<div class="input-group input-group-sm d-flex justify-content-between">
|
||||
<div class="input-group-text" id="inputGroup-sizing-sm">
|
||||
<div class="pe-3" title="Attivabile">
|
||||
Attivabile
|
||||
</div>
|
||||
<div class="form-check form-check-sm form-switch py-1" title="Attivabile">
|
||||
<input class="form-check-input" type="checkbox" id="mySwitch" name="setupAlarms" title="Attivabile" @bind="@currRecord.Attivabile">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<div class="d-grid gap-2">
|
||||
<button class="btn btn-warning" @onclick="() => cancel()">Annulla <i class="bi bi-x-circle"></i></button>
|
||||
@@ -195,13 +222,10 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<ListPODL PagerResetReq="pgResetReq" RecordSel="@selRecord"></ListPODL>
|
||||
<ListPODL PagerResetReq="pgResetReq" RecordSel="@selRecord" updateRecordCount="UpdateTotCount" actFilter="@currFilter"></ListPODL>
|
||||
}
|
||||
</div>
|
||||
<div class="card-footer py-1">
|
||||
<DataPager @ref="pagerODL" PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="isLoading" />
|
||||
<DataPager @ref="pagerODL" PageSize="numRecord" currPage="currPage" numRecordChanged="ForceReload" numPageChanged="ForceReloadPage" totalCount="totalCount" showLoading="@isLoading" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
+48
-20
@@ -3,6 +3,7 @@ using Microsoft.JSInterop;
|
||||
using MP.Data.DatabaseModels;
|
||||
using MP.SPEC.Components;
|
||||
using MP.SPEC.Data;
|
||||
using MP.SPEC.Services;
|
||||
|
||||
namespace MP.SPEC.Pages
|
||||
{
|
||||
@@ -10,7 +11,7 @@ namespace MP.SPEC.Pages
|
||||
{
|
||||
#region Protected Fields
|
||||
|
||||
protected DataPager pagerODL;
|
||||
protected DataPager pagerODL = null!;
|
||||
|
||||
protected bool reqNew = false;
|
||||
|
||||
@@ -19,16 +20,16 @@ namespace MP.SPEC.Pages
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected IJSRuntime JSRuntime { get; set; }
|
||||
protected IJSRuntime JSRuntime { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected MpDataService MDService { get; set; }
|
||||
protected MpDataService MDService { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected MessageService MsgService { get; set; }
|
||||
protected IOApiService MpIoApiCall { get; set; } = null!;
|
||||
|
||||
[Inject]
|
||||
protected NavigationManager NavManager { get; set; }
|
||||
protected NavigationManager NavManager { get; set; } = null!;
|
||||
|
||||
#endregion Protected Properties
|
||||
|
||||
@@ -66,10 +67,6 @@ namespace MP.SPEC.Pages
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
// abilito ricerca...
|
||||
MsgService.ShowSearch = true;
|
||||
// resetto search
|
||||
MsgService.SearchVal = "";
|
||||
ListAziende = await MDService.ElencoAziende();
|
||||
ListGruppiFase = await MDService.ElencoGruppiFase();
|
||||
ListMacchine = await MDService.MacchineGetAll();
|
||||
@@ -106,7 +103,7 @@ namespace MP.SPEC.Pages
|
||||
var firstArt = ListArticoli.FirstOrDefault();
|
||||
currArticolo = firstArt != null ? firstArt.CodArticolo : "";
|
||||
}
|
||||
string codExt = $"{selStato}";
|
||||
string codExt = $"{currFase}";
|
||||
string codGruppo = "";
|
||||
if (ListGruppiFase != null && ListGruppiFase.Count > 0)
|
||||
{
|
||||
@@ -150,9 +147,18 @@ namespace MP.SPEC.Pages
|
||||
return;
|
||||
await Task.Delay(1);
|
||||
var done = await MDService.POdlUpdateRecord(selRec);
|
||||
await callSyncDb(selRec);
|
||||
currRecord = null;
|
||||
await reloadData();
|
||||
// forzo update parametri
|
||||
await Task.Delay(1);
|
||||
currFase = "*";
|
||||
await Task.Delay(1);
|
||||
}
|
||||
|
||||
protected void UpdateTotCount(int newTotCount)
|
||||
{
|
||||
totalCount = newTotCount;
|
||||
}
|
||||
|
||||
#endregion Protected Methods
|
||||
@@ -175,7 +181,7 @@ namespace MP.SPEC.Pages
|
||||
|
||||
private bool addEnabled
|
||||
{
|
||||
get => selStato != "*";
|
||||
get => currFase != "*";
|
||||
}
|
||||
|
||||
private string artSearch
|
||||
@@ -220,10 +226,12 @@ namespace MP.SPEC.Pages
|
||||
}
|
||||
}
|
||||
|
||||
private SelectPOdlParams currFilter { get; set; } = new SelectPOdlParams();
|
||||
|
||||
private int currPage
|
||||
{
|
||||
get => MsgService.currPage;
|
||||
set => MsgService.currPage = value;
|
||||
get => currFilter.CurrPage;
|
||||
set => currFilter.CurrPage = value;
|
||||
}
|
||||
|
||||
private PODLModel? currRecord
|
||||
@@ -240,26 +248,46 @@ namespace MP.SPEC.Pages
|
||||
|
||||
private int numRecord
|
||||
{
|
||||
get => MsgService.numRecord;
|
||||
set => MsgService.numRecord = value;
|
||||
get => currFilter.NumRec;
|
||||
set => currFilter.NumRec = value;
|
||||
}
|
||||
|
||||
private string selStato
|
||||
private string currFase
|
||||
{
|
||||
get => MsgService.StateSel;
|
||||
set => MsgService.StateSel = value;
|
||||
get => currFilter.CodFase;
|
||||
set
|
||||
{
|
||||
if (!currFilter.CodFase.Equals(value))
|
||||
{
|
||||
currFilter.CodFase = value;
|
||||
currPage = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int totalCount
|
||||
{
|
||||
get => MsgService.totalCount;
|
||||
set => MsgService.totalCount = value;
|
||||
get => currFilter.TotCount;
|
||||
set => currFilter.TotCount = value;
|
||||
}
|
||||
|
||||
#endregion Private Properties
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Chiama metodo x chiedere sync DB
|
||||
/// </summary>
|
||||
/// <param name="selRec"></param>
|
||||
/// <returns></returns>
|
||||
private async Task callSyncDb(PODLModel selRec)
|
||||
{
|
||||
// chiamo aggiunta task SyncDb...
|
||||
string idxMacc = selRec.IdxMacchina;
|
||||
string restUrl = $"IOB/addTask2Exe/{idxMacc}?taskName=syncDbData&taskVal=";
|
||||
var response = await MpIoApiCall.callMpIoUrlGet(restUrl);
|
||||
}
|
||||
|
||||
private async Task reloadData()
|
||||
{
|
||||
isLoading = true;
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
@page "/Test"
|
||||
|
||||
<h3>Test</h3>
|
||||
|
||||
<button class="btn btn-primary" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasExample" aria-controls="offcanvasExample">
|
||||
Button with data-bs-target
|
||||
</button>
|
||||
<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvasExample" aria-labelledby="offcanvasExampleLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="offcanvasExampleLabel">Offcanvas</h5>
|
||||
<button type="button" class="btn-close text-reset" data-bs-dismiss="offcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<div>
|
||||
Some text as placeholder. In real life you can have the elements you have chosen. Like, text, images, lists, etc.
|
||||
</div>
|
||||
<div class="dropdown mt-3">
|
||||
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-bs-toggle="dropdown">
|
||||
Dropdown button
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
||||
<li><a class="dropdown-item" href="#">Action</a></li>
|
||||
<li><a class="dropdown-item" href="#">Another action</a></li>
|
||||
<li><a class="dropdown-item" href="#">Something else here</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
|
||||
}
|
||||
@@ -5,6 +5,6 @@
|
||||
|
||||
<h3>Utils</h3>
|
||||
|
||||
<div class="px-2">
|
||||
<div class="">
|
||||
<button class="btn btn-primary" @onclick="() => flushCache()"> Flush Cache </button>
|
||||
</div>
|
||||
@@ -11,14 +11,19 @@ namespace MP.SPEC.Pages
|
||||
{
|
||||
await Task.Delay(1);
|
||||
await MDService.FlushRedisCache();
|
||||
// rimando a home
|
||||
NavManager.NavigateTo("", true);
|
||||
}
|
||||
|
||||
[Inject]
|
||||
private NavigationManager NavManager { get; set; } = null!;
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Protected Properties
|
||||
|
||||
[Inject]
|
||||
protected MpDataService MDService { get; set; }
|
||||
protected MpDataService MDService { get; set; } = null!;
|
||||
|
||||
#endregion Protected Properties
|
||||
}
|
||||
|
||||
@@ -30,7 +30,12 @@
|
||||
<a class="dismiss">🗙</a>
|
||||
</div>
|
||||
|
||||
<script src="lib/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="_framework/blazor.server.js" autostart="false"></script>
|
||||
<script src="lib/chartBoot.js"></script>
|
||||
<script src="lib/modalHandler.js"></script>
|
||||
<script src="lib/Chart.js/chart.js"></script>
|
||||
|
||||
@*Gestione autoriconnessione: https://github.com/dotnet/aspnetcore/issues/38305 (vedere anche https://docs.microsoft.com/it-it/aspnet/core/blazor/fundamentals/signalr?view=aspnetcore-6.0#modify-the-reconnection-handler-blazor-server)*@
|
||||
<script>
|
||||
Blazor.start({
|
||||
@@ -39,19 +44,19 @@
|
||||
retryIntervalMilliseconds: 2000
|
||||
}
|
||||
}).then(() => {
|
||||
Object.defineProperty(Blazor.defaultReconnectionHandler, '_reconnectionDisplay', {
|
||||
get() {
|
||||
return this.__reconnectionDisplay;
|
||||
},
|
||||
set(value) {
|
||||
this.__reconnectionDisplay = {
|
||||
show: () => value.show(),
|
||||
update: (d) => value.update(d),
|
||||
rejected: (d) => document.location.reload()
|
||||
}
|
||||
Object.defineProperty(Blazor.defaultReconnectionHandler, '_reconnectionDisplay', {
|
||||
get() {
|
||||
return this.__reconnectionDisplay;
|
||||
},
|
||||
set(value) {
|
||||
this.__reconnectionDisplay = {
|
||||
show: () => value.show(),
|
||||
update: (d) => value.update(d),
|
||||
rejected: (d) => document.location.reload()
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using MP.SPEC.Components;
|
||||
using MP.SPEC.Data;
|
||||
using MP.SPEC.Services;
|
||||
using StackExchange.Redis;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
@@ -38,6 +39,9 @@ builder.Services.AddSingleton<IConnectionMultiplexer>(redisMultiplexer);
|
||||
builder.Services.AddSingleton<MpDataService>();
|
||||
builder.Services.AddScoped<MessageService>();
|
||||
|
||||
builder.Services.AddHttpClient();
|
||||
builder.Services.AddSingleton<IOApiService>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo MAPOSPEC </i>
|
||||
<h4>Versione: 6.16.2209.2711</h4>
|
||||
<h4>Versione: 6.16.2210.1820</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
6.16.2209.2711
|
||||
6.16.2210.1820
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>6.16.2209.2711</version>
|
||||
<version>6.16.2210.1820</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using MP.SPEC.Data;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace MP.SPEC.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// Classe per chiamare metodi da MP-IO
|
||||
///
|
||||
/// rif:
|
||||
/// https://www.ezzylearning.net/tutorial/making-http-requests-in-blazor-server-apps
|
||||
/// https://wellsb.com/csharp/aspnet/blazor-httpclientfactory-and-web-api/
|
||||
/// </summary>
|
||||
public class IOApiService
|
||||
{
|
||||
private readonly IHttpClientFactory _clientFactory;
|
||||
private static ILogger<MpDataService> _logger = null!;
|
||||
private static IConfiguration _configuration = null!;
|
||||
|
||||
|
||||
private static string MpIoBaseUrl = "";
|
||||
|
||||
public IOApiService(IHttpClientFactory clientFactory, IConfiguration configuration, ILogger<MpDataService> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
_logger.LogInformation("Starting IOApiService INIT");
|
||||
_configuration = configuration;
|
||||
_clientFactory = clientFactory;
|
||||
// conf url x chiamate REST
|
||||
MpIoBaseUrl = _configuration.GetValue<string>("ServerConf:MpIoBaseUrl");
|
||||
}
|
||||
/// <summary>
|
||||
/// Effettua chiamata ad MP-IO
|
||||
/// </summary>
|
||||
/// <param name="relUrl">URL metodo relativo alla base path di MP-IO</param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> callMpIoUrlGet(string relUrl)
|
||||
{
|
||||
string result = "";
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, $"{MpIoBaseUrl}{relUrl}");
|
||||
request.Headers.Add("Accept", "application/vnd.github.v3+json");
|
||||
var client = _clientFactory.CreateClient();
|
||||
var response = await client.SendAsync(request);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var stringResponse = await response.Content.ReadAsStringAsync();
|
||||
result = stringResponse;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = "NO";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,14 @@
|
||||
|
||||
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
|
||||
<nav class="flex-column">
|
||||
<div class="nav-item px-2">
|
||||
<div class="nav-item px-2 col-12">
|
||||
<NavLink class="nav-link px-2" href="" Match="NavLinkMatch.All">
|
||||
<span class="fa-solid fa-house px-2" aria-hidden="true"></span> <span class="@hideText">Home</span>
|
||||
<div class ="col-2">
|
||||
<span class="fa-solid fa-house px-2" aria-hidden="true"></span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="@hideText">Home</span>
|
||||
</div>
|
||||
</NavLink>
|
||||
</div>
|
||||
@if (ElencoLink == null)
|
||||
@@ -33,9 +38,14 @@
|
||||
{
|
||||
foreach (var item in ElencoLink)
|
||||
{
|
||||
<div class="nav-item px-2">
|
||||
<div class="nav-item px-2 col-12">
|
||||
<NavLink class="nav-link px-2" href="@item.NavigateUrl">
|
||||
<span class="@item.icona px-2" aria-hidden="true"></span> <span class="@hideText">@item.Testo</span>
|
||||
<div class="col-2">
|
||||
<span class="@item.icona px-2" aria-hidden="true"></span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="@hideText">@item.Testo</span>
|
||||
</div>
|
||||
</NavLink>
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -12,5 +12,11 @@
|
||||
"ConnectionStrings": {
|
||||
"Mp.Data": "Server=localhost\\SQLEXPRESS;Database=MoonPro; User ID=steamware;Password=viadante16; integrated security=False; MultipleActiveResultSets=True; App=Blazor.ServerApp;",
|
||||
"Redis": "localhost:6379,DefaultDatabase=13,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false"
|
||||
},
|
||||
"ServerConf": {
|
||||
"maxAge": "2000",
|
||||
"cacheCheckArtUsato": 2,
|
||||
"redisLongTimeCache": 15,
|
||||
"MpIoBaseUrl": "http://localhost/MP/IO/"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"ServerConf": {
|
||||
"maxAge": "2000",
|
||||
"cacheCheckArtUsato": 2,
|
||||
"redisLongTimeCache": 15
|
||||
"redisLongTimeCache": 15,
|
||||
"MpIoBaseUrl": "http://localhost:20967/"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,21 @@ a,
|
||||
.footer {
|
||||
line-height: 1.8em;
|
||||
}
|
||||
.dcContainer {
|
||||
width: 22rem;
|
||||
height: 22rem;
|
||||
position: relative;
|
||||
}
|
||||
.dcBox {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
.dcOverlay {
|
||||
z-index: 9;
|
||||
}
|
||||
#blazor-error-ui {
|
||||
background: lightyellow;
|
||||
bottom: 0;
|
||||
@@ -311,4 +326,23 @@ a,
|
||||
min-width: 8rem;
|
||||
min-height: 4rem;
|
||||
}
|
||||
}
|
||||
/* Colori!*/
|
||||
blue {
|
||||
color: purple;
|
||||
background-color: purple;
|
||||
}
|
||||
.dc_yellow {
|
||||
color: yellow;
|
||||
background-color: yellow;
|
||||
}
|
||||
.dc_gray {
|
||||
color: gray;
|
||||
}
|
||||
.dc_red {
|
||||
color: red;
|
||||
}
|
||||
.dc_green {
|
||||
color: green;
|
||||
background-color: green;
|
||||
}
|
||||
@@ -87,6 +87,23 @@ a, .btn-link {
|
||||
line-height: 1.8em;
|
||||
}
|
||||
|
||||
.dcContainer {
|
||||
width: 22rem;
|
||||
height: 22rem;
|
||||
position: relative;
|
||||
}
|
||||
.dcBox {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.dcOverlay {
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
#blazor-error-ui {
|
||||
background: lightyellow;
|
||||
bottom: 0;
|
||||
@@ -358,4 +375,25 @@ a, .btn-link {
|
||||
min-width: @blSCut * 8;
|
||||
min-height: @blSCut * 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Colori!*/
|
||||
blue {
|
||||
color: purple;
|
||||
background-color: purple;
|
||||
}
|
||||
.dc_yellow {
|
||||
color: yellow;
|
||||
background-color: yellow;
|
||||
}
|
||||
.dc_gray {
|
||||
color: gray;
|
||||
}
|
||||
.dc_red {
|
||||
color: red;
|
||||
}
|
||||
.dc_green {
|
||||
color: green;
|
||||
background-color: green;
|
||||
}
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
+13
File diff suppressed because one or more lines are too long
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* Chart.js v3.7.0
|
||||
* https://www.chartjs.org
|
||||
* (c) 2021 Chart.js Contributors
|
||||
* Released under the MIT License
|
||||
*/
|
||||
export { H as HALF_PI, aX as INFINITY, P as PI, aW as PITAU, aZ as QUARTER_PI, aY as RAD_PER_DEG, T as TAU, a_ as TWO_THIRDS_PI, Q as _addGrace, V as _alignPixel, a0 as _alignStartEnd, p as _angleBetween, a$ as _angleDiff, _ as _arrayUnique, a6 as _attachContext, aq as _bezierCurveTo, an as _bezierInterpolation, av as _boundSegment, al as _boundSegments, a3 as _capitalize, ak as _computeSegments, a7 as _createResolver, aH as _decimalPlaces, aP as _deprecated, a8 as _descriptors, af as _elementsEqual, M as _factorize, aJ as _filterBetween, F as _getParentNode, U as _int16Range, ah as _isBetween, ag as _isClickEvent, K as _isDomSupported, z as _isPointInArea, w as _limitValue, aI as _longestText, aK as _lookup, x as _lookupByKey, S as _measureText, aN as _merger, aO as _mergerIf, aw as _normalizeAngle, ao as _pointInLine, ai as _readValueToProps, A as _rlookupByKey, aD as _setMinAndMaxByKey, am as _steppedInterpolation, ap as _steppedLineTo, az as _textX, $ as _toLeftRightCenter, aj as _updateBezierControlPoints, as as addRoundedRectPath, aG as almostEquals, aF as almostWhole, O as callback, ad as clearCanvas, W as clipArea, aM as clone, c as color, h as createContext, ab as debounce, j as defined, aC as distanceBetweenPoints, ar as drawPoint, D as each, e as easingEffects, N as finiteOrDefault, aU as fontString, o as formatNumber, B as getAngleFromPoint, aL as getHoverColor, E as getMaximumSize, y as getRelativePosition, ax as getRtlAdapter, aT as getStyle, b as isArray, g as isFinite, a5 as isFunction, k as isNullOrUndef, q as isNumber, i as isObject, l as listenArrayEvents, L as log10, a2 as merge, a9 as mergeIf, aE as niceNum, aB as noop, ay as overrideTextDirection, G as readUsedSize, X as renderText, r as requestAnimFrame, a as resolve, f as resolveObjectKey, aA as restoreTextDirection, ac as retinaScale, ae as setsEqual, s as sign, aR as splineCurve, aS as splineCurveMonotone, J as supportsEventListenerOptions, I as throttled, R as toDegrees, n as toDimension, Z as toFont, aQ as toFontString, aV as toLineHeight, C as toPadding, m as toPercentage, t as toRadians, at as toTRBL, au as toTRBLCorners, aa as uid, Y as unclipArea, u as unlistenArrayEvents, v as valueOrDefault } from './chunks/helpers.segment.js';
|
||||
@@ -0,0 +1 @@
|
||||
export{H as HALF_PI,aX as INFINITY,P as PI,aW as PITAU,aZ as QUARTER_PI,aY as RAD_PER_DEG,T as TAU,a_ as TWO_THIRDS_PI,Q as _addGrace,V as _alignPixel,a0 as _alignStartEnd,p as _angleBetween,a$ as _angleDiff,_ as _arrayUnique,a6 as _attachContext,aq as _bezierCurveTo,an as _bezierInterpolation,av as _boundSegment,al as _boundSegments,a3 as _capitalize,ak as _computeSegments,a7 as _createResolver,aH as _decimalPlaces,aP as _deprecated,a8 as _descriptors,af as _elementsEqual,M as _factorize,aJ as _filterBetween,F as _getParentNode,U as _int16Range,ah as _isBetween,ag as _isClickEvent,K as _isDomSupported,z as _isPointInArea,w as _limitValue,aI as _longestText,aK as _lookup,x as _lookupByKey,S as _measureText,aN as _merger,aO as _mergerIf,aw as _normalizeAngle,ao as _pointInLine,ai as _readValueToProps,A as _rlookupByKey,aD as _setMinAndMaxByKey,am as _steppedInterpolation,ap as _steppedLineTo,az as _textX,$ as _toLeftRightCenter,aj as _updateBezierControlPoints,as as addRoundedRectPath,aG as almostEquals,aF as almostWhole,O as callback,ad as clearCanvas,W as clipArea,aM as clone,c as color,h as createContext,ab as debounce,j as defined,aC as distanceBetweenPoints,ar as drawPoint,D as each,e as easingEffects,N as finiteOrDefault,aU as fontString,o as formatNumber,B as getAngleFromPoint,aL as getHoverColor,E as getMaximumSize,y as getRelativePosition,ax as getRtlAdapter,aT as getStyle,b as isArray,g as isFinite,a5 as isFunction,k as isNullOrUndef,q as isNumber,i as isObject,l as listenArrayEvents,L as log10,a2 as merge,a9 as mergeIf,aE as niceNum,aB as noop,ay as overrideTextDirection,G as readUsedSize,X as renderText,r as requestAnimFrame,a as resolve,f as resolveObjectKey,aA as restoreTextDirection,ac as retinaScale,ae as setsEqual,s as sign,aR as splineCurve,aS as splineCurveMonotone,J as supportsEventListenerOptions,I as throttled,R as toDegrees,n as toDimension,Z as toFont,aQ as toFontString,aV as toLineHeight,C as toPadding,m as toPercentage,t as toRadians,at as toTRBL,au as toTRBLCorners,aa as uid,Y as unclipArea,u as unlistenArrayEvents,v as valueOrDefault}from"./chunks/helpers.segment.js";
|
||||
@@ -0,0 +1,12 @@
|
||||
///Setup del chart desiderato con id univoco
|
||||
window.setup = (id, config) => {
|
||||
var ctx = document.getElementById(id).getContext('2d');
|
||||
if (window['myChart'] instanceof Chart) {
|
||||
window['myChart'].destroy();
|
||||
window['myChart'] = new Chart(ctx, config);
|
||||
}
|
||||
else {
|
||||
window['myChart'] = new Chart(ctx, config);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*!
|
||||
* chartjs-adapter-luxon v1.1.0
|
||||
* https://www.chartjs.org
|
||||
* (c) 2021 chartjs-adapter-luxon Contributors
|
||||
* Released under the MIT license
|
||||
*/
|
||||
import { _adapters } from 'chart.js';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
const FORMATS = {
|
||||
datetime: DateTime.DATETIME_MED_WITH_SECONDS,
|
||||
millisecond: 'h:mm:ss.SSS a',
|
||||
second: DateTime.TIME_WITH_SECONDS,
|
||||
minute: DateTime.TIME_SIMPLE,
|
||||
hour: {hour: 'numeric'},
|
||||
day: {day: 'numeric', month: 'short'},
|
||||
week: 'DD',
|
||||
month: {month: 'short', year: 'numeric'},
|
||||
quarter: "'Q'q - yyyy",
|
||||
year: {year: 'numeric'}
|
||||
};
|
||||
|
||||
_adapters._date.override({
|
||||
_id: 'luxon', // DEBUG
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_create: function(time) {
|
||||
return DateTime.fromMillis(time, this.options);
|
||||
},
|
||||
|
||||
formats: function() {
|
||||
return FORMATS;
|
||||
},
|
||||
|
||||
parse: function(value, format) {
|
||||
const options = this.options;
|
||||
|
||||
if (value === null || typeof value === 'undefined') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const type = typeof value;
|
||||
if (type === 'number') {
|
||||
value = this._create(value);
|
||||
} else if (type === 'string') {
|
||||
if (typeof format === 'string') {
|
||||
value = DateTime.fromFormat(value, format, options);
|
||||
} else {
|
||||
value = DateTime.fromISO(value, options);
|
||||
}
|
||||
} else if (value instanceof Date) {
|
||||
value = DateTime.fromJSDate(value, options);
|
||||
} else if (type === 'object' && !(value instanceof DateTime)) {
|
||||
value = DateTime.fromObject(value);
|
||||
}
|
||||
|
||||
return value.isValid ? value.valueOf() : null;
|
||||
},
|
||||
|
||||
format: function(time, format) {
|
||||
const datetime = this._create(time);
|
||||
return typeof format === 'string'
|
||||
? datetime.toFormat(format, this.options)
|
||||
: datetime.toLocaleString(format);
|
||||
},
|
||||
|
||||
add: function(time, amount, unit) {
|
||||
const args = {};
|
||||
args[unit] = amount;
|
||||
return this._create(time).plus(args).valueOf();
|
||||
},
|
||||
|
||||
diff: function(max, min, unit) {
|
||||
return this._create(max).diff(this._create(min)).as(unit).valueOf();
|
||||
},
|
||||
|
||||
startOf: function(time, unit, weekday) {
|
||||
if (unit === 'isoWeek') {
|
||||
weekday = Math.trunc(Math.min(Math.max(0, weekday), 6));
|
||||
const dateTime = this._create(time);
|
||||
return dateTime.minus({days: (dateTime.weekday - weekday + 7) % 7}).startOf('day').valueOf();
|
||||
}
|
||||
return unit ? this._create(time).startOf(unit).valueOf() : time;
|
||||
},
|
||||
|
||||
endOf: function(time, unit) {
|
||||
return this._create(time).endOf(unit).valueOf();
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
import{_adapters}from"chart.js";import{DateTime}from"luxon";const FORMATS={datetime:DateTime.DATETIME_MED_WITH_SECONDS,millisecond:"h:mm:ss.SSS a",second:DateTime.TIME_WITH_SECONDS,minute:DateTime.TIME_SIMPLE,hour:{hour:"numeric"},day:{day:"numeric",month:"short"},week:"DD",month:{month:"short",year:"numeric"},quarter:"'Q'q - yyyy",year:{year:"numeric"}};_adapters._date.override({_id:"luxon",_create:function(t){return DateTime.fromMillis(t,this.options)},formats:function(){return FORMATS},parse:function(t,e){var r=this.options;if(null==t)return null;var a=typeof t;return"number"==a?t=this._create(t):"string"==a?t="string"==typeof e?DateTime.fromFormat(t,e,r):DateTime.fromISO(t,r):t instanceof Date?t=DateTime.fromJSDate(t,r):"object"!=a||t instanceof DateTime||(t=DateTime.fromObject(t)),t.isValid?t.valueOf():null},format:function(t,e){const r=this._create(t);return"string"==typeof e?r.toFormat(e,this.options):r.toLocaleString(e)},add:function(t,e,r){const a={};return a[r]=e,this._create(t).plus(a).valueOf()},diff:function(t,e,r){return this._create(t).diff(this._create(e)).as(r).valueOf()},startOf:function(t,e,r){if("isoWeek"!==e)return e?this._create(t).startOf(e).valueOf():t;{r=Math.trunc(Math.min(Math.max(0,r),6));const a=this._create(t);return a.minus({days:(a.weekday-r+7)%7}).startOf("day").valueOf()}},endOf:function(t,e){return this._create(t).endOf(e).valueOf()}});
|
||||
@@ -0,0 +1,96 @@
|
||||
/*!
|
||||
* chartjs-adapter-luxon v1.1.0
|
||||
* https://www.chartjs.org
|
||||
* (c) 2021 chartjs-adapter-luxon Contributors
|
||||
* Released under the MIT license
|
||||
*/
|
||||
(function (global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('chart.js'), require('luxon')) :
|
||||
typeof define === 'function' && define.amd ? define(['chart.js', 'luxon'], factory) :
|
||||
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Chart, global.luxon));
|
||||
}(this, (function (chart_js, luxon) { 'use strict';
|
||||
|
||||
const FORMATS = {
|
||||
datetime: luxon.DateTime.DATETIME_MED_WITH_SECONDS,
|
||||
millisecond: 'h:mm:ss.SSS a',
|
||||
second: luxon.DateTime.TIME_WITH_SECONDS,
|
||||
minute: luxon.DateTime.TIME_SIMPLE,
|
||||
hour: {hour: 'numeric'},
|
||||
day: {day: 'numeric', month: 'short'},
|
||||
week: 'DD',
|
||||
month: {month: 'short', year: 'numeric'},
|
||||
quarter: "'Q'q - yyyy",
|
||||
year: {year: 'numeric'}
|
||||
};
|
||||
|
||||
chart_js._adapters._date.override({
|
||||
_id: 'luxon', // DEBUG
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_create: function(time) {
|
||||
return luxon.DateTime.fromMillis(time, this.options);
|
||||
},
|
||||
|
||||
formats: function() {
|
||||
return FORMATS;
|
||||
},
|
||||
|
||||
parse: function(value, format) {
|
||||
const options = this.options;
|
||||
|
||||
if (value === null || typeof value === 'undefined') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const type = typeof value;
|
||||
if (type === 'number') {
|
||||
value = this._create(value);
|
||||
} else if (type === 'string') {
|
||||
if (typeof format === 'string') {
|
||||
value = luxon.DateTime.fromFormat(value, format, options);
|
||||
} else {
|
||||
value = luxon.DateTime.fromISO(value, options);
|
||||
}
|
||||
} else if (value instanceof Date) {
|
||||
value = luxon.DateTime.fromJSDate(value, options);
|
||||
} else if (type === 'object' && !(value instanceof luxon.DateTime)) {
|
||||
value = luxon.DateTime.fromObject(value);
|
||||
}
|
||||
|
||||
return value.isValid ? value.valueOf() : null;
|
||||
},
|
||||
|
||||
format: function(time, format) {
|
||||
const datetime = this._create(time);
|
||||
return typeof format === 'string'
|
||||
? datetime.toFormat(format, this.options)
|
||||
: datetime.toLocaleString(format);
|
||||
},
|
||||
|
||||
add: function(time, amount, unit) {
|
||||
const args = {};
|
||||
args[unit] = amount;
|
||||
return this._create(time).plus(args).valueOf();
|
||||
},
|
||||
|
||||
diff: function(max, min, unit) {
|
||||
return this._create(max).diff(this._create(min)).as(unit).valueOf();
|
||||
},
|
||||
|
||||
startOf: function(time, unit, weekday) {
|
||||
if (unit === 'isoWeek') {
|
||||
weekday = Math.trunc(Math.min(Math.max(0, weekday), 6));
|
||||
const dateTime = this._create(time);
|
||||
return dateTime.minus({days: (dateTime.weekday - weekday + 7) % 7}).startOf('day').valueOf();
|
||||
}
|
||||
return unit ? this._create(time).startOf(unit).valueOf() : time;
|
||||
},
|
||||
|
||||
endOf: function(time, unit) {
|
||||
return this._create(time).endOf(unit).valueOf();
|
||||
}
|
||||
});
|
||||
|
||||
})));
|
||||
@@ -0,0 +1,7 @@
|
||||
/*!
|
||||
* chartjs-adapter-luxon v1.1.0
|
||||
* https://www.chartjs.org
|
||||
* (c) 2021 chartjs-adapter-luxon Contributors
|
||||
* Released under the MIT license
|
||||
*/
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(require("chart.js"),require("luxon")):"function"==typeof define&&define.amd?define(["chart.js","luxon"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).Chart,e.luxon)}(this,(function(e,t){"use strict";const n={datetime:t.DateTime.DATETIME_MED_WITH_SECONDS,millisecond:"h:mm:ss.SSS a",second:t.DateTime.TIME_WITH_SECONDS,minute:t.DateTime.TIME_SIMPLE,hour:{hour:"numeric"},day:{day:"numeric",month:"short"},week:"DD",month:{month:"short",year:"numeric"},quarter:"'Q'q - yyyy",year:{year:"numeric"}};e._adapters._date.override({_id:"luxon",_create:function(e){return t.DateTime.fromMillis(e,this.options)},formats:function(){return n},parse:function(e,n){const r=this.options;if(null==e)return null;const i=typeof e;return"number"===i?e=this._create(e):"string"===i?e="string"==typeof n?t.DateTime.fromFormat(e,n,r):t.DateTime.fromISO(e,r):e instanceof Date?e=t.DateTime.fromJSDate(e,r):"object"!==i||e instanceof t.DateTime||(e=t.DateTime.fromObject(e)),e.isValid?e.valueOf():null},format:function(e,t){const n=this._create(e);return"string"==typeof t?n.toFormat(t,this.options):n.toLocaleString(t)},add:function(e,t,n){const r={};return r[n]=t,this._create(e).plus(r).valueOf()},diff:function(e,t,n){return this._create(e).diff(this._create(t)).as(n).valueOf()},startOf:function(e,t,n){if("isoWeek"===t){n=Math.trunc(Math.min(Math.max(0,n),6));const t=this._create(e);return t.minus({days:(t.weekday-n+7)%7}).startOf("day").valueOf()}return t?this._create(e).startOf(t).valueOf():e},endOf:function(e,t){return this._create(e).endOf(t).valueOf()}})}));
|
||||
@@ -0,0 +1,21 @@
|
||||
////TENTATIVO POPOLAMENTO HELPER PER POTER INVOCARE IL METODO DOPO
|
||||
//let helper;
|
||||
|
||||
//window.setHelper = (dotNetHelper) => {
|
||||
// helper = dotNetHelper.invokeMethodAsync('setHelper');
|
||||
// console.log(helper);
|
||||
// return dotNetHelper.invokeMethodAsync('setHelper');
|
||||
//}
|
||||
|
||||
////BECCA QUANDO LA MODALE VIENE CHIUSA ED ESEGUE
|
||||
//document.addEventListener('click', function (e) {
|
||||
// if (e.target.id === 'myModal') {
|
||||
// console.log('chiuso');
|
||||
|
||||
// //return helper.invokeMethodAsync('svuotaRecord');
|
||||
// console.log("fatto");
|
||||
// } else {
|
||||
// console.log('aperto');
|
||||
// }
|
||||
// e.stopPropagation();
|
||||
//}, false);
|
||||
@@ -4,7 +4,7 @@
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<RootNamespace>MP.Stats</RootNamespace>
|
||||
<UserSecretsId>826e877c-ba70-4253-84cb-d0b1cafd4440</UserSecretsId>
|
||||
<Version>6.16.2209.2211</Version>
|
||||
<Version>6.16.2210.1708</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace MP.Stats.Pages
|
||||
{
|
||||
isLoading = true;
|
||||
// salvo davvero!
|
||||
await MP.Data.Utils.SaveToCsv(SearchRecords, fullPath);
|
||||
await MP.Data.Utils.SaveToCsv(SearchRecords, fullPath, ';');
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace MP.Stats.Pages
|
||||
// recupero TUTTI i dati
|
||||
var allRecords = await StatService.StatDdbGetAllExport(currFilter, MessageService.SearchVal);
|
||||
// salvo davvero!
|
||||
await MP.Data.Utils.SaveToCsv(allRecords, fullPath);
|
||||
await MP.Data.Utils.SaveToCsv(allRecords, fullPath, ';');
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace MP.Stats.Pages
|
||||
isLoading = true;
|
||||
// calcolo nome file
|
||||
// salvo davvero!
|
||||
await MP.Data.Utils.SaveToCsv(SearchRecords, fullPath);
|
||||
await MP.Data.Utils.SaveToCsv(SearchRecords, fullPath, ';');
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace MP.Stats.Pages
|
||||
{
|
||||
isLoading = true;
|
||||
// salvo davvero!
|
||||
await MP.Data.Utils.SaveToCsv(SearchRecords, fullPath);
|
||||
await MP.Data.Utils.SaveToCsv(SearchRecords, fullPath, ';');
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ namespace MP.Stats.Pages
|
||||
{
|
||||
isLoading = true;
|
||||
// salvo davvero!
|
||||
await MP.Data.Utils.SaveToCsv(SearchRecords, fullPath);
|
||||
await MP.Data.Utils.SaveToCsv(SearchRecords, fullPath, ';');
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace MP.Stats.Pages
|
||||
{
|
||||
isLoading = true;
|
||||
// salvo davvero!
|
||||
await MP.Data.Utils.SaveToCsv(SearchRecords, fullPath);
|
||||
await MP.Data.Utils.SaveToCsv(SearchRecords, fullPath, ';');
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>Modulo statistiche MAPO</i>
|
||||
<h4>Versione: 6.16.2209.2211</h4>
|
||||
<h4>Versione: 6.16.2210.1708</h4>
|
||||
<br />
|
||||
Note di rilascio:
|
||||
<ul>
|
||||
|
||||
@@ -1 +1 @@
|
||||
6.16.2209.2211
|
||||
6.16.2210.1708
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>6.16.2209.2211</version>
|
||||
<version>6.16.2210.1708</version>
|
||||
<url>https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip</url>
|
||||
<changelog>https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
|
||||
Reference in New Issue
Block a user