From 3a0f0d363f3e52133480d67bb5f025b3df88bbc7 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 15 Jan 2026 09:25:55 +0100 Subject: [PATCH] Update sim past/new events --- EgwCoreLib.Lux.Core/Generic/EventDto.cs | 56 +++----- .../Controllers/DataSimulatorController.cs | 129 +++++++++++++++++ .../Services/DataLayerServices.cs | 44 +++++- Lux.API/Lux.API.csproj | 2 +- .../Compo/Planner/CalendarPlanner.razor.cs | 2 +- .../Components/Compo/Planner/TaskDetail.razor | 4 +- Lux.UI/Components/Layout/NavMenu.razor | 8 +- Lux.UI/Components/Pages/ProdPlanner.razor.cs | 132 +++--------------- Lux.UI/Lux.UI.csproj | 2 +- Resources/ChangeLog.html | 2 +- Resources/VersNum.txt | 2 +- Resources/manifest.xml | 2 +- 12 files changed, 221 insertions(+), 164 deletions(-) create mode 100644 EgwCoreLib.Lux.Data/Controllers/DataSimulatorController.cs diff --git a/EgwCoreLib.Lux.Core/Generic/EventDto.cs b/EgwCoreLib.Lux.Core/Generic/EventDto.cs index 755eccc7..8bca9e98 100644 --- a/EgwCoreLib.Lux.Core/Generic/EventDto.cs +++ b/EgwCoreLib.Lux.Core/Generic/EventDto.cs @@ -17,6 +17,8 @@ namespace EgwCoreLib.Lux.Core.Generic #if false public int IdxDipendente { get; set; } = 0; public string CognomeNome { get; set; } = ""; + public bool Conf { get; set; } = false; + public bool IsCompany { get; set; } = false; #endif public string Abbrev { get; set; } = ""; public string Titolo { get; set; } = ""; @@ -25,9 +27,9 @@ namespace EgwCoreLib.Lux.Core.Generic public DateTime DtStart { get; set; } = DateTime.Today.AddHours(9); public DateTime DtEnd { get; set; } = DateTime.Today.AddHours(17); public string Note { get; set; } = ""; - public bool Conf { get; set; } = false; public bool IsDraggable { get; set; } = false; - public bool IsCompany { get; set; } = false; + public bool IsExpired { get; set; } = false; + public bool IsPlanned { get; set; } = true; public EventDto Clone() { @@ -38,6 +40,8 @@ namespace EgwCoreLib.Lux.Core.Generic #if false IdxDipendente = this.IdxDipendente, CognomeNome = this.CognomeNome, + Conf = this.Conf, + IsCompany = this.IsCompany, #endif Abbrev = this.Abbrev, Titolo = this.Titolo, @@ -46,9 +50,9 @@ namespace EgwCoreLib.Lux.Core.Generic DtStart = this.DtStart, DtEnd = this.DtEnd, Note = this.Note, - Conf = this.Conf, IsDraggable = this.IsDraggable, - IsCompany = this.IsCompany + IsPlanned = this.IsPlanned, + IsExpired = this.IsExpired }; } @@ -76,72 +80,48 @@ namespace EgwCoreLib.Lux.Core.Generic public string Color { - get => calcColor(CodTipo, Conf, IsCompany); + get => calcColor(CodTipo, IsPlanned, IsExpired); } public string? ForeColor { - get => calcText(CodTipo, Conf, IsCompany); + get => calcText(CodTipo, IsPlanned, IsExpired); } - private string calcColor(string codTipo, bool conf, bool isComp) + private string calcColor(string codTipo, bool isPlanned, bool isExpired) { string answ = "#EDEDED"; switch (codTipo) { case "Saomad": - answ = isComp ? "#EEDD11" : conf ? "#11CD44" : "#AAFFCD"; + answ = isExpired ? "#CDCDCD" : isPlanned ? "#11CD44" : "#D9FFE6"; break; case "Essetre": - answ = "#DD0033"; + answ = isExpired ? "#989898" : isPlanned ? "#AD1919" : "#CD6767"; break; - //case "104": - // answ = conf ? "#DE00AB" : "#FFAACD"; - // break; - - //case "MAL": - // answ = conf ? "#000" : "#696969"; - // break; - - //case "PERM": - // answ = conf ? "#9966DE" : "#CDAAFF"; - // break; - default: - answ = isComp ? "#EEDD11" : conf ? "#11CD44" : "#AAFFCD"; + answ = isExpired ? "#EEDD11" : isPlanned ? "#11CD44" : "#AAFFCD"; break; } return answ; } - private string calcText(string codTipo, bool conf, bool isComp) + private string calcText(string codTipo, bool isPlanned, bool isExpired) { string answ = "#EDEDED"; switch (codTipo) { case "Saomad": - answ = isComp ? "#000000" : conf ? "#FFFFFF" : "#000000"; + answ = isExpired ? "#000000" : isPlanned ? "#000000" : "#696969"; break; case "Essetre": - answ = "#EEDD11"; + answ = isExpired ? "#000000" : isPlanned ? "#EEDD11" : "#A39F2A"; break; - //case "104": - // answ = conf ? "#DEDEDE" : "#000000"; - // break; - - //case "MAL": - // answ = conf ? "#DEDEDE" : "#ABABAB"; - // break; - - //case "PERM": - // answ = conf ? "#DEDEDE" : "#000000"; - // break; - default: - answ = isComp ? "#000000" : conf ? "#FFFFFF" : "#000000"; + answ = isExpired ? "#000000" : isPlanned ? "#FFFFFF" : "#000000"; break; } return answ; diff --git a/EgwCoreLib.Lux.Data/Controllers/DataSimulatorController.cs b/EgwCoreLib.Lux.Data/Controllers/DataSimulatorController.cs new file mode 100644 index 00000000..5c1e4215 --- /dev/null +++ b/EgwCoreLib.Lux.Data/Controllers/DataSimulatorController.cs @@ -0,0 +1,129 @@ +using EgwCoreLib.Lux.Core.Generic; +using EgwMultiEngineManager.Data; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EgwCoreLib.Lux.Data.Controllers +{ + public class DataSimulatorController + { + #region Public Constructors + + /// + /// Controller per generazioen dati simulati + /// + public DataSimulatorController() + { + rnd = new Random(); + } + + #endregion Public Constructors + + #region Internal Methods + + /// + /// Restituisce un dizionario di dati simulati x rappresentazione in planner + /// + /// + /// + /// + internal Dictionary>? PlannerGetEvents(DateTime dtStart, DateTime dtEnd) + { + var dictAnsw = new Dictionary>(); + int idx = 1; + var simSaomad = DoSimPeriod("Saomad", idx, dtStart, dtEnd, 8, 19); + dictAnsw.Add("Saomad", simSaomad); + idx += simSaomad.Count(); + var simEssetre = DoSimPeriod("Essetre", idx, dtStart, dtEnd, 8, 19); + dictAnsw.Add("Essetre", simEssetre); + return dictAnsw; + } + + #endregion Internal Methods + + #region Private Fields + + private Random rnd = new Random(); + + #endregion Private Fields + + #region Private Methods + + /// + /// Genera un set di elementi simulati secondo i criteri ricevuti + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + private List DoSimPeriod(string codMacc, int currIdx, DateTime minDate, DateTime maxDate, int hStart = 8, int hEnd = 18, int minDur = 120, int maxDur = 360, int maxSim = 300, int minWait = 5, int maxWait = 25) + { + List currListEv = new(); + // init date cursore + DateTime oggi = DateTime.Today; + DateTime maxPlan = oggi.AddDays(20); + DateTime dtStart = minDate.AddHours(hStart); + DateTime dtEnd = dtStart; + // ciclo principale entro limiti... + while (dtStart < maxDate && maxSim > 0) + { + // definisce limite giornaliero + DateTime fineGiornata = dtStart.Date.AddHours(hEnd); + + // Verifica dtStart sia entro limite giornaliero altrimenti va alla mattina dopo.. + if (dtStart >= fineGiornata.AddMinutes(-30)) + { + dtStart = dtStart.Date.AddDays(1).AddHours(hStart); + fineGiornata = dtStart.Date.AddHours(hEnd); + } + + // Trova il prossimo giorno lavorativo (lunedì-venerdì) dopo dtStart + while (dtStart.DayOfWeek == DayOfWeek.Saturday || dtStart.DayOfWeek == DayOfWeek.Sunday) + { + dtStart = dtStart.AddDays(1); + fineGiornata = dtStart.Date.AddHours(hEnd); + } + + // Se siamo oltre la data di limEnd, interrompi + if (dtStart > maxDate) + break; + + // Calcola la fine dell'evento + dtEnd = dtStart.AddMinutes(rnd.Next(minDur, maxDur)); + + // Verifica se l'evento supera il limite orario + if (dtEnd > fineGiornata) + { + // Se supera il limite, taglia l'evento entro +/-30 minuti da hEnd + dtEnd = fineGiornata.AddMinutes(rnd.Next(-30, 30)); + } + EventDto newEv = new EventDto() + { + CodTipo = codMacc, + Abbrev = $"POR.{minDate.Year}.{currIdx:x8}", + Titolo = $"POR.{minDate.Year}.{currIdx:x8}", + Descrizione = $"Produzione {codMacc}", + DtStart = dtStart, + DtEnd = dtEnd, + IsExpired = dtEnd < oggi.AddHours(-8), + IsPlanned = dtEnd < maxPlan + }; + currListEv.Add(newEv); + dtStart = dtEnd.AddMinutes(rnd.Next(minWait, maxWait)); + currIdx++; + maxSim--; + } + return currListEv; + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs index 5ec3ccc3..9ed43bbb 100644 --- a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs +++ b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs @@ -1,4 +1,5 @@ -using EgwCoreLib.Lux.Core.RestPayload; +using EgwCoreLib.Lux.Core.Generic; +using EgwCoreLib.Lux.Core.RestPayload; using EgwCoreLib.Lux.Data.Controllers; using EgwCoreLib.Lux.Data.DbModel.Config; using EgwCoreLib.Lux.Data.DbModel.Cost; @@ -40,10 +41,13 @@ namespace EgwCoreLib.Lux.Data.Services } else { + StringBuilder sb = new StringBuilder(); //dbController = new Controllers.LuxController(_config); dbController = new LuxController(); - StringBuilder sb = new StringBuilder(); - sb.AppendLine($"DataLayerServices | LuxController OK"); + sb.AppendLine($"LuxController OK"); + dataSimController = new DataSimulatorController(); + sb.AppendLine($"DataSimController OK"); + sb.AppendLine($"LuxController OK"); Log.Info(sb.ToString()); } } @@ -1712,6 +1716,39 @@ namespace EgwCoreLib.Lux.Data.Services return fatto; } + /// + /// Restituisce un dizionario di da usare nel planner + /// + /// + /// + /// + public async Task>?> PlannerGetEvents(DateTime dtStart, DateTime dtEnd) + { + string source = "DB"; + Stopwatch sw = new Stopwatch(); + sw.Start(); + Dictionary>? result = null; + // cerco in redis... + string currKey = $"{redisBaseKey}:PlannerData:{dtStart:yyyyMMdd}:{dtEnd:yyyyMMdd}"; + RedisValue rawData = await redisDb.StringGetAsync(currKey); + //if (!string.IsNullOrEmpty($"{rawData}")) + if (rawData.HasValue && rawData.Length() > 2) + { + result = JsonConvert.DeserializeObject>>($"{rawData}"); + source = "REDIS"; + } + else + { + result = dataSimController.PlannerGetEvents(dtStart, dtEnd); + // serializzo e salvo... + rawData = JsonConvert.SerializeObject(result); + await redisDb.StringSetAsync(currKey, rawData, LongCache); + } + sw.Stop(); + Log.Debug($"PlannerGetEvents | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + return result; + } + /// /// Effettua upsert complessivo Ordine /// @@ -2479,6 +2516,7 @@ namespace EgwCoreLib.Lux.Data.Services #region Private Properties private static LuxController dbController { get; set; } = null!; + private static DataSimulatorController dataSimController { get; set; } = null!; #endregion Private Properties diff --git a/Lux.API/Lux.API.csproj b/Lux.API/Lux.API.csproj index 42233af5..aeaf26b7 100644 --- a/Lux.API/Lux.API.csproj +++ b/Lux.API/Lux.API.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 0.9.2601.1419 + 0.9.2601.1509 diff --git a/Lux.UI/Components/Compo/Planner/CalendarPlanner.razor.cs b/Lux.UI/Components/Compo/Planner/CalendarPlanner.razor.cs index b051f874..46f7361b 100644 --- a/Lux.UI/Components/Compo/Planner/CalendarPlanner.razor.cs +++ b/Lux.UI/Components/Compo/Planner/CalendarPlanner.razor.cs @@ -109,11 +109,11 @@ namespace Lux.UI.Components.Compo.Planner { // in primis copio tutto EvDtoFilt = EvDtoList; +#if false if (ShowNeedConf) { EvDtoFilt = EvDtoFilt.Where(x => !x.Conf).ToList(); } -#if false // controllo ogni toggle... if (!showChiu) { diff --git a/Lux.UI/Components/Compo/Planner/TaskDetail.razor b/Lux.UI/Components/Compo/Planner/TaskDetail.razor index c3b31e21..b9edd314 100644 --- a/Lux.UI/Components/Compo/Planner/TaskDetail.razor +++ b/Lux.UI/Components/Compo/Planner/TaskDetail.razor @@ -59,10 +59,10 @@
@model.Note
- @if (!model.Conf) + @if (!model.IsPlanned) {
  • - NON CONFERMATO + NON PIANIFICATO
  • } diff --git a/Lux.UI/Components/Layout/NavMenu.razor b/Lux.UI/Components/Layout/NavMenu.razor index 57510056..184890a4 100644 --- a/Lux.UI/Components/Layout/NavMenu.razor +++ b/Lux.UI/Components/Layout/NavMenu.razor @@ -93,7 +93,7 @@ - *@ - + @* - + *@