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 @@ - + @* Scratch @@ -103,9 +103,9 @@ Auth Required - + *@ - + @* @@ -134,7 +134,7 @@ - + *@ Flush Cache diff --git a/Lux.UI/Components/Pages/ProdPlanner.razor.cs b/Lux.UI/Components/Pages/ProdPlanner.razor.cs index d00bbfca..1d5b5a39 100644 --- a/Lux.UI/Components/Pages/ProdPlanner.razor.cs +++ b/Lux.UI/Components/Pages/ProdPlanner.razor.cs @@ -1,125 +1,50 @@ using EgwCoreLib.Lux.Core.Generic; +using EgwCoreLib.Lux.Data.Services; +using Microsoft.AspNetCore.Components; using System.Collections.Generic; namespace Lux.UI.Components.Pages { public partial class ProdPlanner { - #region Protected Methods + #region Protected Properties - #endregion Protected Methods + [Inject] + protected DataLayerServices DLService { get; set; } = null!; + + #endregion Protected Properties #region Private Fields - private List ListEventi { get; set; } = new(); - /// /// Periodo selezionato attuale /// private EgwCoreLib.Utils.DtUtils.Periodo PeriodoSel = new EgwCoreLib.Utils.DtUtils.Periodo(EgwCoreLib.Utils.DtUtils.PeriodSet.ThisYear); - private Random rnd = new Random(); - #endregion Private Fields + #region Private Properties + + private List ListEventi { get; set; } = new(); + + #endregion Private Properties + #region Private Methods - /// - /// Sim modalità iniziale - /// - /// - private async Task DoSimData() - { - // simulo eventi... - DateTime limStart = new DateTime(DateTime.Today.Year, 1, 1); - DateTime limEnd = new DateTime(DateTime.Today.Year, 12, 31); - await Task.Delay(50); - int idx = 1; - var simSaomad = DoSimPeriod("Saomad", idx, limStart, limEnd, 8, 19); - ListEventi.AddRange(simSaomad); - idx += ListEventi.Count(); - var simEssetre = DoSimPeriod("Essetre", idx, limStart, limEnd, 8, 19); - ListEventi.AddRange(simEssetre); - } - - /// - /// 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 = 60, int maxDur = 360, int maxSim = 500) - { - List currListEv = new(); - // init date cursore - 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 - }; - currListEv.Add(newEv); - dtStart = dtEnd.AddMinutes(rnd.Next(5, 25)); - currIdx++; - maxSim--; - } - return currListEv; - } - /// /// Legge i dati dei record completi /// private async Task ReloadData() { - if (ListEventi.Count == 0) + var rawData = await DLService.PlannerGetEvents(PeriodoSel.Inizio, PeriodoSel.Fine); + if (rawData != null && rawData.Count > 0) { - ListEventi = new List(); - //ListEventi.Clear(); - await DoSimData(); + ListEventi.Clear(); + // x ora copio i vari blocchi... + foreach (var item in rawData) + { + ListEventi.AddRange(item.Value); + } } } @@ -132,21 +57,6 @@ namespace Lux.UI.Components.Pages { PeriodoSel = newPeriod; await ReloadData(); - UpdateTable(); - } - - /// - /// Filtro e paginazione - /// - private void UpdateTable() - { -#if false - // fix paginazione - ListRecords = ListFilt - .Skip(numRecord * (currPage - 1)) - .Take(numRecord) - .ToList(); -#endif } #endregion Private Methods diff --git a/Lux.UI/Lux.UI.csproj b/Lux.UI/Lux.UI.csproj index a686676a..622ae98a 100644 --- a/Lux.UI/Lux.UI.csproj +++ b/Lux.UI/Lux.UI.csproj @@ -5,7 +5,7 @@ enable enable aspnet-Lux.UI-a758c101-a2f4-4e38-977d-1c4887dbbd50 - 0.9.2601.1419 + 0.9.2601.1509 diff --git a/Resources/ChangeLog.html b/Resources/ChangeLog.html index 49b50318..cfb17700 100644 --- a/Resources/ChangeLog.html +++ b/Resources/ChangeLog.html @@ -1,6 +1,6 @@ LUX - Web Windows MES - Versione: 0.9.2601.1419 + Versione: 0.9.2601.1509 Note di rilascio: diff --git a/Resources/VersNum.txt b/Resources/VersNum.txt index e1ff5f5c..985d5822 100644 --- a/Resources/VersNum.txt +++ b/Resources/VersNum.txt @@ -1 +1 @@ -0.9.2601.1419 +0.9.2601.1509 diff --git a/Resources/manifest.xml b/Resources/manifest.xml index 644ff962..75eccc98 100644 --- a/Resources/manifest.xml +++ b/Resources/manifest.xml @@ -1,6 +1,6 @@ - 0.9.2601.1419 + 0.9.2601.1509 http://nexus.steamware.net/repository/SWS/GPW/stable/GPW.UI.zip http://nexus.steamware.net/repository/SWS/GPW/stable/ChangeLog.html false