From 8d1e61ec8ba073c30a40beb75bfb1792b8032277 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 25 May 2026 17:14:38 +0200 Subject: [PATCH 001/102] UPdate spec x gestione PODL --- MP.Data/Controllers/MpSpecController.cs | 56 +++++++++++++++++++++++++ MP.Data/DbModels/PODLExpModel.cs | 4 +- MP.IOC/Controllers/IOBController.cs | 8 ++-- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.SPEC/Components/ListPODL.razor | 11 +++++ MP.SPEC/Data/MpDataService.cs | 10 ++--- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Articoli.razor | 2 +- MP.SPEC/Pages/Articoli.razor.cs | 16 ++----- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 15 files changed, 90 insertions(+), 33 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index efa33086..ddebcdc9 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -1415,6 +1415,34 @@ namespace MP.Data.Controllers } return dbResult; } + /// + /// Elenco PODL per composizione KIT non avviati filtrati x articolo, KeyRich (che contiene stato) + /// + /// Solo lanciati (1) o ancora disponibili (0) + /// KeyRich (parziale) da cercare (es cod stato x yacht) + /// Macchina + /// Gruppo + /// + public async Task> ListPODL_KitFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(options)) + { + var Lanc = new SqlParameter("@Lanciato", lanciato); + var KeyRich = new SqlParameter("@KeyRich", keyRichPart); + var CodGrp = new SqlParameter("@CodGruppo", codGruppo); + var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina); + var DateFrom = new SqlParameter("@DtInizio", startDate); + var DateTo = new SqlParameter("@DtFine", endDate); + + dbResult = await dbCtx + .DbSetPODLExp + .FromSqlRaw("EXEC stp_PODL_getByFiltSpecKit @Lanciato, @KeyRich, @CodGruppo, @IdxMacchina, @DtInizio, @DtFine", Lanc, KeyRich, CodGrp, IdxMacc, DateFrom, DateTo) + .AsNoTracking() + .ToListAsync(); + } + return dbResult; + } /// /// Elenco PODL non avviati filtrati x articolo, KeyRich (che contiene stato) @@ -1444,6 +1472,34 @@ namespace MP.Data.Controllers } return dbResult; } + /// + /// Elenco PODL non avviati filtrati x articolo, KeyRich (che contiene stato) - ASYNC + /// + /// Solo lanciati (1) o ancora disponibili (0) + /// KeyRich (parziale) da cercare (es cod stato x yacht) + /// Macchina + /// Gruppo + /// + public async Task> ListPODLFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(options)) + { + var Lanc = new SqlParameter("@Lanciato", lanciato); + var KeyRich = new SqlParameter("@KeyRich", keyRichPart); + var CodGrp = new SqlParameter("@CodGruppo", codGruppo); + var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina); + var DateFrom = new SqlParameter("@DtInizio", startDate); + var DateTo = new SqlParameter("@DtFine", endDate); + + dbResult = await dbCtx + .DbSetPODLExp + .FromSqlRaw("EXEC stp_PODL_getByFiltSpec @Lanciato, @KeyRich, @CodGruppo, @IdxMacchina, @DtInizio, @DtFine", Lanc, KeyRich, CodGrp, IdxMacc, DateFrom, DateTo) + .AsNoTracking() + .ToListAsync(); + } + return dbResult; + } /// /// Elenco valori ammessi x tabella/colonna diff --git a/MP.Data/DbModels/PODLExpModel.cs b/MP.Data/DbModels/PODLExpModel.cs index 05617844..8f37c529 100644 --- a/MP.Data/DbModels/PODLExpModel.cs +++ b/MP.Data/DbModels/PODLExpModel.cs @@ -39,6 +39,8 @@ namespace MP.Data.DbModels public DateTime InsertDate { get; set; } = DateTime.Now; [MaxLength(500)] public string Recipe { get; set; } = ""; + public bool IsKitParent { get; set; } = false; + public bool IsKitChild { get; set; } = false; [NotMapped] public string CodFase @@ -66,7 +68,7 @@ namespace MP.Data.DbModels [NotMapped] public bool IsKit { - get => KeyRichiesta.StartsWith("KIT"); + get => IsKitParent || IsKitChild; // KeyRichiesta.StartsWith("KIT"); } /// diff --git a/MP.IOC/Controllers/IOBController.cs b/MP.IOC/Controllers/IOBController.cs index 4a486ff9..f0ebee6c 100644 --- a/MP.IOC/Controllers/IOBController.cs +++ b/MP.IOC/Controllers/IOBController.cs @@ -147,7 +147,7 @@ namespace MP.IOC.Controllers /// /// Sistema Dossier/Snapshot giornalieri x impianto indicato, andando a generare 1 Dossier /// giornaliero x ogni giornata dall'ultimo registrato alla data corrente - /// es: http://url_site/MP/IO/IOB/fixDailyDossier/SIMUL_03 + /// es: http://url_site/MP/IOC/api/IOB/fixDailyDossier/SIMUL_03 /// /// /// @@ -174,7 +174,7 @@ namespace MP.IOC.Controllers /// /// Sistema ODL giornalieri x impianto indicato, andando a generare 1 ODL giornaliero x ogni /// giornata dall'ultimo ODL aperto alla data corrente - /// es: http://url_site/MP/IO/IOB/fixDailyOdl/SIMUL_03 + /// es: http://url_site/MP/IOC/api/IOB/fixDailyOdl/SIMUL_03 /// /// /// @@ -218,7 +218,7 @@ namespace MP.IOC.Controllers /// Sistema ODL giornalieri x impianto indicato, andando a generare 1 ODL giornaliero x ogni /// giornata dall'ultimo ODL aperto alla data corrente + conferma pezzi (es TFT x ODL /// giornalieri energia) - /// es: http://url_site/MP/IO/IOB/fixDailyOdlConfPzCount/SIMUL_03 + /// es: http://url_site/MP/IOC/api/IOB/fixDailyOdlConfPzCount/SIMUL_03 /// /// /// @@ -525,7 +525,7 @@ namespace MP.IOC.Controllers /// /// Restituisce data-ora inizio dell'odl correntemente in lavorazione sulla macchina... - /// es: http://url_site/MP/IO/IOB/getCurrOdlStart/SIMUL_03 + /// es: http://url_site/MP/IOC/api/IOB/getCurrOdlStart/SIMUL_03 /// /// /// diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index ec21f95d..272dc386 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.1119 + 8.16.2605.1208 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 480c59fb..755b20eb 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

Versione: 8.16.2605.1119

+

Versione: 8.16.2605.1208


Note di rilascio:
  • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 282e9dc7..032d5246 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.1119 +8.16.2605.1208 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 0bbcd7eb..c6da8756 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.1119 + 8.16.2605.1208 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Components/ListPODL.razor b/MP.SPEC/Components/ListPODL.razor index a651fcdf..e505b2c9 100644 --- a/MP.SPEC/Components/ListPODL.razor +++ b/MP.SPEC/Components/ListPODL.razor @@ -28,6 +28,7 @@ else } Cod + Kit Articolo Fase @if (!(showRecipeConf || showRecipeArch)) @@ -127,6 +128,16 @@ else } + + @if (record.IsKitParent) + { + P. + } + else if (record.IsKitChild) + { + .C + } +
    @record.CodArticolo diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index c0b1514c..ebbec626 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1,7 +1,5 @@ -using DnsClient.Protocol; -using EgwCoreLib.Utils; +using EgwCoreLib.Utils; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Options; using MP.Core.Conf; using MP.Core.DTO; using MP.Core.Objects; @@ -10,13 +8,11 @@ using MP.Data.Controllers; using MP.Data.DbModels; using MP.Data.MgModels; using MP.Data.Services; -using MP.SPEC.Components.ProdKit; using Newtonsoft.Json; using NLog; using StackExchange.Redis; using System.Data; using System.Diagnostics; -using ZXing; namespace MP.SPEC.Data { @@ -2463,7 +2459,7 @@ namespace MP.SPEC.Data } else { - result = await Task.FromResult(dbController.ListPODLFilt(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate)); + result = await dbController.ListPODLFiltAsync(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); @@ -2504,7 +2500,7 @@ namespace MP.SPEC.Data } else { - result = await Task.FromResult(dbController.ListPODL_KitFilt(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate)); + result = await dbController.ListPODL_KitFiltAsync(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 72831ad8..9deac4d1 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2604.2718 + 8.16.2605.2517 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Articoli.razor b/MP.SPEC/Pages/Articoli.razor index 2130edd8..a2a3c7e7 100644 --- a/MP.SPEC/Pages/Articoli.razor +++ b/MP.SPEC/Pages/Articoli.razor @@ -150,7 +150,7 @@ @foreach (var record in ListRecords) { - + diff --git a/MP.SPEC/Pages/Articoli.razor.cs b/MP.SPEC/Pages/Articoli.razor.cs index 754d6211..e3b23914 100644 --- a/MP.SPEC/Pages/Articoli.razor.cs +++ b/MP.SPEC/Pages/Articoli.razor.cs @@ -9,19 +9,11 @@ namespace MP.SPEC.Pages { #region Public Methods - public string checkSelect(string CodArticolo) + public string CheckSelect(string codArticolo) { - string answ = ""; - if (currRecord != null) - { - try - { - answ = (currRecord.CodArticolo == CodArticolo) ? "table-info" : ""; - } - catch - { } - } - return answ; + return currRecord?.CodArticolo == codArticolo + ? "table-info" + : ""; } private SelectArticoliParams currFilter = new SelectArticoliParams(); diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 133a7fea..9388728b 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

    Versione: 8.16.2604.2718

    +

    Versione: 8.16.2605.2517


    Note di rilascio:
    • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 87ec763e..45a6b113 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2604.2718 +8.16.2605.2517 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 6abb2dad..73dad968 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2604.2718 + 8.16.2605.2517 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From d20f2567361cb50ec92b71fb87f2e4cb4c2f8288 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 25 May 2026 19:05:56 +0200 Subject: [PATCH 002/102] Correzione fusioncache x RIOC --- MP.Data/DbModels/PODLExpModel.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MP.Data/DbModels/PODLExpModel.cs b/MP.Data/DbModels/PODLExpModel.cs index 8f37c529..e4590159 100644 --- a/MP.Data/DbModels/PODLExpModel.cs +++ b/MP.Data/DbModels/PODLExpModel.cs @@ -69,6 +69,7 @@ namespace MP.Data.DbModels public bool IsKit { get => IsKitParent || IsKitChild; // KeyRichiesta.StartsWith("KIT"); + //get => KeyRichiesta.StartsWith("KIT"); } /// @@ -76,6 +77,7 @@ namespace MP.Data.DbModels /// [ForeignKey("IdxMacchina")] public virtual MacchineModel MachineNav { get; set; } = null!; + /// /// Navigazione oggetto Articolo /// From 8461398ff822dace208ee20422a7bdb020ce3f02 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 25 May 2026 19:06:04 +0200 Subject: [PATCH 003/102] Update SPEC --- MP.RIOC/MP.RIOC.csproj | 3 ++- MP.RIOC/Program.cs | 3 +++ MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.SPEC/Components/ListPODL.razor | 2 +- MP.SPEC/Components/ListPODL.razor.cs | 27 +++++++++++++-------------- MP.SPEC/Data/SelectXdlParams.cs | 1 + MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 12 files changed, 27 insertions(+), 23 deletions(-) diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index 4b9d8648..a893eba8 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2605.1207 + 8.16.2605.2519 @@ -17,6 +17,7 @@ + diff --git a/MP.RIOC/Program.cs b/MP.RIOC/Program.cs index a507237f..6ba4f593 100644 --- a/MP.RIOC/Program.cs +++ b/MP.RIOC/Program.cs @@ -78,6 +78,9 @@ builder.Services.AddHttpForwarder(); var redisMux = ConnectionMultiplexer.Connect(confRedis); builder.Services.AddSingleton(redisMux); +// registrazione FusionCache +builder.Services.AddFusionCache(); + // Registrazione dei servizi custom builder.Services.AddSingleton(); builder.Services.AddSingleton(); diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index ce196314..65c07daf 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

      Versione: 8.16.2605.1207

      +

      Versione: 8.16.2605.2519


      Note di rilascio:
      • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index 57e5daf4..a68d1899 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.1207 +8.16.2605.2519 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index a43e833c..69dca7d7 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.1207 + 8.16.2605.2519 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Components/ListPODL.razor b/MP.SPEC/Components/ListPODL.razor index e505b2c9..109b0421 100644 --- a/MP.SPEC/Components/ListPODL.razor +++ b/MP.SPEC/Components/ListPODL.razor @@ -43,7 +43,7 @@ else @foreach (var record in ListRecords) { - + @if (!(showRecipeConf || showRecipeArch)) { diff --git a/MP.SPEC/Components/ListPODL.razor.cs b/MP.SPEC/Components/ListPODL.razor.cs index f11ff3d5..6250ead8 100644 --- a/MP.SPEC/Components/ListPODL.razor.cs +++ b/MP.SPEC/Components/ListPODL.razor.cs @@ -34,20 +34,11 @@ namespace MP.SPEC.Components #region Public Methods - public string checkSelect(PODLExpModel record) + public string CheckSelect(PODLExpModel thisRec) { - string answ = ""; - if (currRecord != null) - { - try - { - answ = (currRecord.IdxPromessa == record.IdxPromessa) ? "table-info" : ""; - //answ = ((SelRecord.IdxMacchina == record.IdxMacchina) && (SelRecord.CodArticolo == record.CodArticolo) && (SelRecord.CodFase == record.CodFase)) ? "table-info" : ""; - } - catch - { } - } - return answ; + return currRecord?.IdxPromessa == thisRec?.IdxPromessa + ? "table-info" + : ""; } public void Dispose() @@ -229,7 +220,15 @@ namespace MP.SPEC.Components { ListRecords = null; isLoading = true; - SearchRecords = await MDService.POdlListGetFiltAsync(hasOdl, StatoSel, macchina, reparto, selDtStart, selDtEnd); + // verifico filtro odl... + if (actFilter.ShowKit) + { + SearchRecords = await MDService.POdlListGetFiltAsync(hasOdl, StatoSel, macchina, reparto, selDtStart, selDtEnd); + } + else + { + SearchRecords = await MDService.POdlToKitListGetFiltAsync(hasOdl, StatoSel, macchina, reparto, selDtStart, selDtEnd); + } if (totalCount != SearchRecords.Count) { totalCount = SearchRecords.Count; diff --git a/MP.SPEC/Data/SelectXdlParams.cs b/MP.SPEC/Data/SelectXdlParams.cs index e91ae7c9..f36c3402 100644 --- a/MP.SPEC/Data/SelectXdlParams.cs +++ b/MP.SPEC/Data/SelectXdlParams.cs @@ -26,6 +26,7 @@ namespace MP.SPEC.Data public string SearchVal { get; set; } = "*"; public string Header { get; set; } = ""; public int TotCount { get; set; } = 0; + public bool ShowKit { get; set; } = false; #endregion Public Properties diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 9deac4d1..27d724cd 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2517 + 8.16.2605.2518 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 9388728b..8e00d0ca 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

        Versione: 8.16.2605.2517

        +

        Versione: 8.16.2605.2518


        Note di rilascio:
        • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 45a6b113..16a16eda 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2517 +8.16.2605.2518 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 73dad968..4fce2715 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2517 + 8.16.2605.2518 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From 40694e5766c666f266c98c509de07d0c724cf6dc Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Tue, 26 May 2026 16:37:54 +0200 Subject: [PATCH 004/102] Aggiunta hashset x velocizzare ricerca recipes x PODL --- MP.Data/Controllers/MpSpecController.cs | 43 ++++++++++ MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- .../Properties/PublishProfiles/IIS01.pubxml | 57 ++++++------- MP.SPEC/Components/ListPODL.razor.cs | 83 +++++++++++++------ MP.SPEC/Data/MpDataService.cs | 38 ++++++++- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 12 files changed, 174 insertions(+), 63 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index ddebcdc9..f43b0306 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -1615,6 +1615,49 @@ namespace MP.Data.Controllers return dbResult; } + /// + /// Elenco da tabella Macchine filtro x gruppo + /// + /// + /// + public async Task> MacchineGetFiltAsync(string codGruppo) + { + List dbResult = new List(); + try + { + using (var dbCtx = new MoonProContext(options)) + { + if (codGruppo == "*") + { + dbResult = await dbCtx + .DbSetMacchine + .AsNoTracking() + .OrderBy(x => x.IdxMacchina) + .ToListAsync(); + } + else + { + dbResult = await dbCtx + .DbSetGrp2Macc + .Where(g => g.CodGruppo == codGruppo) + .Join(dbCtx.DbSetMacchine, + g => g.IdxMacchina, + m => m.IdxMacchina, + (g, m) => m + ) + .AsNoTracking() + .OrderBy(x => x.IdxMacchina) + .ToListAsync(); + } + } + } + catch (Exception exc) + { + Log.Error($"Eccezione in MacchineGetFiltAsync{Environment.NewLine}{exc}"); + } + return dbResult; + } + /// /// Elenco id MacchineModel che abbiano dati FLuxLog, nel periodo indicato /// diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 272dc386..0fcaf0ac 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.1208 + 8.16.2605.2519 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 755b20eb..55973e10 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

          Versione: 8.16.2605.1208

          +

          Versione: 8.16.2605.2519


          Note di rilascio:
          • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 032d5246..a68d1899 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.1208 +8.16.2605.2519 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index c6da8756..324cc6c2 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.1208 + 8.16.2605.2519 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/Properties/PublishProfiles/IIS01.pubxml b/MP.RIOC/Properties/PublishProfiles/IIS01.pubxml index 9278d2ad..6c359c50 100644 --- a/MP.RIOC/Properties/PublishProfiles/IIS01.pubxml +++ b/MP.RIOC/Properties/PublishProfiles/IIS01.pubxml @@ -1,32 +1,33 @@  - - MSDeploy - true - Release - Any CPU - https://iis01.egalware.com/MP/RIOC/ - false - b9188473-f4ae-4f9f-be2d-70edaace0db9 - false - https://iis01.egalware.com:8172/MsDeploy.axd - Default Web Site/MP/RIOC - - false - WMSVC - true - true - jenkins - <_SavePWD>true - <_TargetId>IISWebDeploy - net8.0 - win-x64 - - - - filePath - logs\\.*\.log$ - - + + MSDeploy + true + Release + Any CPU + https://iis01.egalware.com/MP/RIOC/ + false + b9188473-f4ae-4f9f-be2d-70edaace0db9 + false + https://iis01.egalware.com:8172/MsDeploy.axd + Default Web Site/MP/RIOC + + true + WMSVC + true + true + jenkins + <_SavePWD>true + <_TargetId>IISWebDeploy + net8.0 + win-x64 + true + + + + filePath + logs\\.*\.log$ + + \ No newline at end of file diff --git a/MP.SPEC/Components/ListPODL.razor.cs b/MP.SPEC/Components/ListPODL.razor.cs index 6250ead8..66b07d13 100644 --- a/MP.SPEC/Components/ListPODL.razor.cs +++ b/MP.SPEC/Components/ListPODL.razor.cs @@ -168,28 +168,7 @@ namespace MP.SPEC.Components protected override async Task OnInitializedAsync() { - ListStati = await MDService.AnagStatiComm(); - ListArtKit = MDService.ArticoliGetByTipo("KIT", "*"); - string strMachRecipe = await MDService.ConfigTryGetAsync("MachineWithRecipe"); - if (!string.IsNullOrEmpty(strMachRecipe)) - { - bool.TryParse(strMachRecipe, out MachineWithRecipe); - } - string SPEC_PODL_gest = await MDService.ConfigTryGetAsync("SPEC_PODL_gest"); - if (!string.IsNullOrEmpty(SPEC_PODL_gest)) - { - bool.TryParse(SPEC_PODL_gest, out enableStartPODL); - } - string SPEC_ODL_gest = await MDService.ConfigTryGetAsync("SPEC_ODL_gest"); - if (!string.IsNullOrEmpty(SPEC_ODL_gest)) - { - bool.TryParse(SPEC_ODL_gest, out enableStopODL); - } - string SPEC_XODL_sync = await MDService.ConfigTryGetAsync("SPEC_XODL_sync"); - if (!string.IsNullOrEmpty(SPEC_XODL_sync)) - { - bool.TryParse(SPEC_XODL_sync, out enableForceSync); - } + await ReloadBaseData(); } protected override async Task OnParametersSetAsync() @@ -216,10 +195,56 @@ namespace MP.SPEC.Components return idxOdl == 0; } + /// + /// Caricamento dati di base + /// + /// + protected async Task ReloadBaseData() + { + ListRecords = null; + isLoading = true; + + var machines = await MDService.MacchineGetFiltAsync("*"); + + _machinesWithConf = machines + .Where(x => !string.IsNullOrEmpty(x.RecipePath)) + .Select(x => x.IdxMacchina) + .ToHashSet(); + + _machinesWithArch = machines + .Where(x => !string.IsNullOrEmpty(x.RecipeArchivePath)) + .Select(x => x.IdxMacchina) + .ToHashSet(); + + ListStati = await MDService.AnagStatiComm(); + ListArtKit = MDService.ArticoliGetByTipo("KIT", "*"); + string strMachRecipe = await MDService.ConfigTryGetAsync("MachineWithRecipe"); + if (!string.IsNullOrEmpty(strMachRecipe)) + { + bool.TryParse(strMachRecipe, out MachineWithRecipe); + } + string SPEC_PODL_gest = await MDService.ConfigTryGetAsync("SPEC_PODL_gest"); + if (!string.IsNullOrEmpty(SPEC_PODL_gest)) + { + bool.TryParse(SPEC_PODL_gest, out enableStartPODL); + } + string SPEC_ODL_gest = await MDService.ConfigTryGetAsync("SPEC_ODL_gest"); + if (!string.IsNullOrEmpty(SPEC_ODL_gest)) + { + bool.TryParse(SPEC_ODL_gest, out enableStopODL); + } + string SPEC_XODL_sync = await MDService.ConfigTryGetAsync("SPEC_XODL_sync"); + if (!string.IsNullOrEmpty(SPEC_XODL_sync)) + { + bool.TryParse(SPEC_XODL_sync, out enableForceSync); + } + } + protected async Task ReloadData() { ListRecords = null; isLoading = true; + // verifico filtro odl... if (actFilter.ShowKit) { @@ -559,10 +584,15 @@ namespace MP.SPEC.Components /// private bool machineHasRecipeArch(string idxMacchina) { - var recipeArchive = MDService.MacchineRecipeArchive(idxMacchina); - return !string.IsNullOrEmpty(recipeArchive); + return _machinesWithArch.Contains(idxMacchina); + //var recipeArchive = MDService.MacchineRecipeArchive(idxMacchina); + //return !string.IsNullOrEmpty(recipeArchive); } + + private HashSet _machinesWithConf = new(); + private HashSet _machinesWithArch = new(); + /// /// Verifica se la idxMaccSel abbia associata una ricetta (template) /// @@ -570,8 +600,9 @@ namespace MP.SPEC.Components /// private bool machineHasRecipeConf(string idxMacchina) { - var recipePath = MDService.MacchineRecipeConf(idxMacchina); - return !string.IsNullOrEmpty(recipePath); + return _machinesWithConf.Contains(idxMacchina); + //var recipePath = MDService.MacchineRecipeConf(idxMacchina); + //return !string.IsNullOrEmpty(recipePath); } /// diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index ebbec626..89945777 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1725,7 +1725,43 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.SetTag("result.count", 1); activity?.Stop(); - LogTrace($"MacchineGetAll | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"MacchineGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + return result; + } + /// + /// Elenco di tutte le macchine filtrate x gruppo + /// + /// + /// + public async Task> MacchineGetFiltAsync(string codGruppo) + { + using var activity = ActivitySource.StartActivity("MacchineGetFilt"); + List? result = new List(); + string source = "DB"; + string keyGrp = codGruppo != "*" ? codGruppo : "ALL"; + string currKey = $"{Utils.redisMacList}:{keyGrp}"; + // cerco in redis dato valore sel idxMaccSel... + RedisValue rawData = await redisDb.StringGetAsync(currKey); + if (rawData.HasValue) + { + result = JsonConvert.DeserializeObject>($"{rawData}"); + source = "REDIS"; + } + else + { + result = await dbController.MacchineGetFiltAsync(codGruppo); + // serializzo e salvo... + rawData = JsonConvert.SerializeObject(result); + await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache)); + } + if (result == null) + { + result = new List(); + } + activity?.SetTag("data.source", source); + activity?.SetTag("result.count", 1); + activity?.Stop(); + LogTrace($"MacchineGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; } diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 27d724cd..06d98519 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2518 + 8.16.2605.2616 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 8e00d0ca..68c19573 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

            Versione: 8.16.2605.2518

            +

            Versione: 8.16.2605.2616


            Note di rilascio:
            • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 16a16eda..418a7c18 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2518 +8.16.2605.2616 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 4fce2715..19b26f9f 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2518 + 8.16.2605.2616 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From a94e40a6aaa964724ecfc03c042c4984b1f62e1d Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Tue, 26 May 2026 16:38:02 +0200 Subject: [PATCH 005/102] Continuo ottimizzazione oggetti in memoria --- MP.SPEC/Components/ListPODL.razor.cs | 11 +- MP.SPEC/Data/MpDataService.cs | 148 ++++++++++++++++++++------- 2 files changed, 116 insertions(+), 43 deletions(-) diff --git a/MP.SPEC/Components/ListPODL.razor.cs b/MP.SPEC/Components/ListPODL.razor.cs index 66b07d13..3217b076 100644 --- a/MP.SPEC/Components/ListPODL.razor.cs +++ b/MP.SPEC/Components/ListPODL.razor.cs @@ -216,6 +216,7 @@ namespace MP.SPEC.Components .Select(x => x.IdxMacchina) .ToHashSet(); + ListStati = await MDService.AnagStatiComm(); ListArtKit = MDService.ArticoliGetByTipo("KIT", "*"); string strMachRecipe = await MDService.ConfigTryGetAsync("MachineWithRecipe"); @@ -354,6 +355,8 @@ namespace MP.SPEC.Components #region Private Fields private static Logger Log = LogManager.GetCurrentClassLogger(); + private HashSet _machinesWithArch = new(); + private HashSet _machinesWithConf = new(); private string currRecipeArchPath = ""; /// @@ -585,14 +588,8 @@ namespace MP.SPEC.Components private bool machineHasRecipeArch(string idxMacchina) { return _machinesWithArch.Contains(idxMacchina); - //var recipeArchive = MDService.MacchineRecipeArchive(idxMacchina); - //return !string.IsNullOrEmpty(recipeArchive); } - - private HashSet _machinesWithConf = new(); - private HashSet _machinesWithArch = new(); - /// /// Verifica se la idxMaccSel abbia associata una ricetta (template) /// @@ -601,8 +598,6 @@ namespace MP.SPEC.Components private bool machineHasRecipeConf(string idxMacchina) { return _machinesWithConf.Contains(idxMacchina); - //var recipePath = MDService.MacchineRecipeConf(idxMacchina); - //return !string.IsNullOrEmpty(recipePath); } /// diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 89945777..46079cca 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -68,22 +68,6 @@ namespace MP.SPEC.Data Log.Info("MpDataService | INIT completed"); } - /// - /// Helper trace messaggio log (SE abilitato) - /// - /// - private void LogTrace(string traceMsg, NLog.LogLevel? reqLevel = null) - { - if (!traceEnabled) - return; - - reqLevel ??= NLog.LogLevel.Debug; - - // Loggo! - Log.Log(reqLevel, traceMsg); - } - private bool traceEnabled = false; - #endregion Public Constructors #region Public Events @@ -98,6 +82,7 @@ namespace MP.SPEC.Data #region Public Properties public static MpSpecController dbController { get; set; } = null!; + public static MpMongoController mongoController { get; set; } = null!; public MessagePipe BroadastMsgPipe { get; set; } = null!; @@ -688,6 +673,20 @@ namespace MP.SPEC.Data /// public string ConfigTryGet(string keyName) { + using var activity = ActivitySource.StartActivity("ConfigTryGet"); + string source = "MEMORY"; + + EnsureConfigLoaded(); + + _configData.TryGetValue(keyName, out var value); + + activity?.SetTag("data.source", source); + activity?.Stop(); + + LogTrace($"ConfigTryGet Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + return value ?? ""; + +#if false string answ = ""; using var activity = ActivitySource.StartActivity("ConfigTryGet"); string source = "DB+REDIS"; @@ -712,7 +711,8 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"ConfigTryGet Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return answ; + return answ; +#endif } /// @@ -722,6 +722,20 @@ namespace MP.SPEC.Data /// public async Task ConfigTryGetAsync(string keyName) { + using var activity = ActivitySource.StartActivity("ConfigTryGetAsync"); + string source = "MEMORY"; + + await EnsureConfigLoadedAsync(); + + _configData.TryGetValue(keyName, out var value); + + activity?.SetTag("data.source", source); + activity?.Stop(); + + LogTrace($"ConfigTryGetAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + return value ?? ""; + +#if false string answ = ""; using var activity = ActivitySource.StartActivity("ConfigTryGetAsync"); string source = "DB+REDIS"; @@ -747,6 +761,7 @@ namespace MP.SPEC.Data activity?.Stop(); LogTrace($"ConfigTryGetAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return answ; +#endif } /// @@ -1728,6 +1743,7 @@ namespace MP.SPEC.Data LogTrace($"MacchineGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; } + /// /// Elenco di tutte le macchine filtrate x gruppo /// @@ -2037,6 +2053,24 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("ODLClose"); string source = "DB"; bool fatto = false; + + await EnsureConfigLoadedAsync(); + bool confRett = false; + _configData.TryGetValue("confRett", out var value); + if (!string.IsNullOrEmpty(value)) + { + bool.TryParse(value, out confRett); + } + int modoConfProd = 0; + _configData.TryGetValue("modoConfProd", out var vModo); + if (!string.IsNullOrEmpty(value)) + { + int.TryParse(vModo, out modoConfProd); + } + // chiamo metodo conferma! + fatto = await dbController.ODLClose(idxOdl, idxMacchina, matrOpr, confPezzi, confRett, modoConfProd); + +#if false // recupero dati x conf modalità conferma var configData = await ConfigGetAllAsync(); if (configData != null) @@ -2055,7 +2089,8 @@ namespace MP.SPEC.Data } // chiamo metodo conferma! fatto = await dbController.ODLClose(idxOdl, idxMacchina, matrOpr, confPezzi, confRett, modoConfProd); - } + } +#endif activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"ODLClose | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -2760,6 +2795,21 @@ namespace MP.SPEC.Data LogTrace($"ResetMicrostatoMacchina | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); } + /// + /// Statistiche ODL calcolate (da stored stp_STAT_ODL) + /// + /// + public Task> StatOdl(int IdxOdl) + { + using var activity = ActivitySource.StartActivity("StatOdl"); + string source = "DB"; + var result = dbController.OdlStart(IdxOdl); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"StatOdl | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return result; + } + /// /// Stato macchina /// @@ -2796,21 +2846,6 @@ namespace MP.SPEC.Data return result; } - /// - /// Statistiche ODL calcolate (da stored stp_STAT_ODL) - /// - /// - public Task> StatOdl(int IdxOdl) - { - using var activity = ActivitySource.StartActivity("StatOdl"); - string source = "DB"; - var result = dbController.OdlStart(IdxOdl); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"StatOdl | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return result; - } - /// /// Restituisce il valore da REDIS associato al tag richiesto /// @@ -2982,7 +3017,7 @@ namespace MP.SPEC.Data } /// - /// Update valore Dossier + /// Update valore Dossier /// /// /// @@ -3277,6 +3312,8 @@ namespace MP.SPEC.Data private static Logger Log = LogManager.GetCurrentClassLogger(); + private Dictionary _configData = new(); + private string MpIoNS = ""; /// @@ -3303,14 +3340,18 @@ namespace MP.SPEC.Data private int redisShortTimeCache = 2; + private bool traceEnabled = false; + #endregion Private Fields #region Private Properties +#if false /// /// Cache dati config /// - private List configData { get; set; } = new List(); + private List configData { get; set; } = new List(); +#endif #endregion Private Properties @@ -3327,6 +3368,43 @@ namespace MP.SPEC.Data ExecFlushRedisPattern(pattern); } } + private void EnsureConfigLoaded() + { + if (_configData.Count == 0) + { + var list = ConfigGetAll(); + + _configData = list + .GroupBy(x => x.Chiave) + .ToDictionary(g => g.Key, g => g.First().Valore); + } + } + private async Task EnsureConfigLoadedAsync() + { + if (_configData.Count == 0) + { + var list = await ConfigGetAllAsync(); + + _configData = list + .GroupBy(x => x.Chiave) + .ToDictionary(g => g.Key, g => g.First().Valore); + } + } + + /// + /// Helper trace messaggio log (SE abilitato) + /// + /// + private void LogTrace(string traceMsg, NLog.LogLevel? reqLevel = null) + { + if (!traceEnabled) + return; + + reqLevel ??= NLog.LogLevel.Trace; + + // Loggo! + Log.Log(reqLevel, traceMsg); + } private async Task POdlFlushCache() { From 1cefa18895b29e79d0a3872f861ee47efab9f04b Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Tue, 26 May 2026 17:49:32 +0200 Subject: [PATCH 006/102] Porting a versione 8 della struttura app x SPEC --- MP.Data/Controllers/MpSpecController.cs | 6 +- MP.Data/Services/TabDataService.cs | 2 +- MP.SPEC/App.razor | 14 --- MP.SPEC/Components/App.razor | 43 ++++++++ .../Layout}/MainLayout.razor | 0 .../Layout}/MainLayout.razor.cs | 2 +- .../Layout}/MainLayout.razor.css | 0 .../Layout}/MainLayout.razor.less | 0 .../Layout}/MainLayout.razor.min.css | 0 .../Layout}/NavMenu.razor | 0 .../Layout}/NavMenu.razor.cs | 2 +- .../Layout}/NavMenu.razor.css | 0 MP.SPEC/Components/ListODL.razor.cs | 4 +- MP.SPEC/Components/ListPODL.razor.cs | 3 +- MP.SPEC/Components/Routes.razor | 12 ++ MP.SPEC/Data/MpDataService.cs | 104 ++---------------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/_Host.cshtml | 8 -- MP.SPEC/Pages/_Layout.cshtml | 69 ------------ MP.SPEC/Program.cs | 58 +++------- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- MP.SPEC/_Imports.razor | 2 + MP.SPEC/appsettings.json | 2 +- 25 files changed, 97 insertions(+), 242 deletions(-) delete mode 100644 MP.SPEC/App.razor create mode 100644 MP.SPEC/Components/App.razor rename MP.SPEC/{Shared => Components/Layout}/MainLayout.razor (100%) rename MP.SPEC/{Shared => Components/Layout}/MainLayout.razor.cs (90%) rename MP.SPEC/{Shared => Components/Layout}/MainLayout.razor.css (100%) rename MP.SPEC/{Shared => Components/Layout}/MainLayout.razor.less (100%) rename MP.SPEC/{Shared => Components/Layout}/MainLayout.razor.min.css (100%) rename MP.SPEC/{Shared => Components/Layout}/NavMenu.razor (100%) rename MP.SPEC/{Shared => Components/Layout}/NavMenu.razor.cs (98%) rename MP.SPEC/{Shared => Components/Layout}/NavMenu.razor.css (100%) create mode 100644 MP.SPEC/Components/Routes.razor delete mode 100644 MP.SPEC/Pages/_Host.cshtml delete mode 100644 MP.SPEC/Pages/_Layout.cshtml diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index f43b0306..bdfc3780 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -412,17 +412,17 @@ namespace MP.Data.Controllers /// /// /// - public List ArticoliGetByTipo(string tipo, string azienda = "*") + public async Task> ArticoliGetByTipoAsync(string tipo, string azienda = "*") { List dbResult = new List(); using (var dbCtx = new MoonProContext(options)) { - dbResult = dbCtx + dbResult = await dbCtx .DbSetArticoli .AsNoTracking() .Where(x => x.Tipo.ToUpper() == tipo.ToUpper() && (azienda == "*" || x.Azienda.ToUpper() == azienda.ToUpper())) .OrderBy(x => x.CodArticolo) - .ToList(); + .ToListAsync(); } return dbResult; } diff --git a/MP.Data/Services/TabDataService.cs b/MP.Data/Services/TabDataService.cs index b12f9bc2..0f9f4397 100644 --- a/MP.Data/Services/TabDataService.cs +++ b/MP.Data/Services/TabDataService.cs @@ -392,7 +392,7 @@ namespace MP.Data.Services } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"ArticoliGetByTipo | Read from {readType}: {ts.TotalMilliseconds}ms"); + Log.Debug($"ArticoliGetByTipoAsync | Read from {readType}: {ts.TotalMilliseconds}ms"); return result; } diff --git a/MP.SPEC/App.razor b/MP.SPEC/App.razor deleted file mode 100644 index 7431d6a1..00000000 --- a/MP.SPEC/App.razor +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - Not found - -

              Sorry, there's nothing at this address.

              -
              -
              -
              -
              diff --git a/MP.SPEC/Components/App.razor b/MP.SPEC/Components/App.razor new file mode 100644 index 00000000..7c2bdacb --- /dev/null +++ b/MP.SPEC/Components/App.razor @@ -0,0 +1,43 @@ + + + + + + + @* *@ + @* *@ + + + + + + MP-SPEC + + + + + + + + @* *@ + + + + + + + + +
              + An error has occurred. + Reload + 🗙 +
              + + + + + + + + diff --git a/MP.SPEC/Shared/MainLayout.razor b/MP.SPEC/Components/Layout/MainLayout.razor similarity index 100% rename from MP.SPEC/Shared/MainLayout.razor rename to MP.SPEC/Components/Layout/MainLayout.razor diff --git a/MP.SPEC/Shared/MainLayout.razor.cs b/MP.SPEC/Components/Layout/MainLayout.razor.cs similarity index 90% rename from MP.SPEC/Shared/MainLayout.razor.cs rename to MP.SPEC/Components/Layout/MainLayout.razor.cs index dffbf458..725d3227 100644 --- a/MP.SPEC/Shared/MainLayout.razor.cs +++ b/MP.SPEC/Components/Layout/MainLayout.razor.cs @@ -1,4 +1,4 @@ -namespace MP.SPEC.Shared +namespace MP.SPEC.Components.Layout { public partial class MainLayout { diff --git a/MP.SPEC/Shared/MainLayout.razor.css b/MP.SPEC/Components/Layout/MainLayout.razor.css similarity index 100% rename from MP.SPEC/Shared/MainLayout.razor.css rename to MP.SPEC/Components/Layout/MainLayout.razor.css diff --git a/MP.SPEC/Shared/MainLayout.razor.less b/MP.SPEC/Components/Layout/MainLayout.razor.less similarity index 100% rename from MP.SPEC/Shared/MainLayout.razor.less rename to MP.SPEC/Components/Layout/MainLayout.razor.less diff --git a/MP.SPEC/Shared/MainLayout.razor.min.css b/MP.SPEC/Components/Layout/MainLayout.razor.min.css similarity index 100% rename from MP.SPEC/Shared/MainLayout.razor.min.css rename to MP.SPEC/Components/Layout/MainLayout.razor.min.css diff --git a/MP.SPEC/Shared/NavMenu.razor b/MP.SPEC/Components/Layout/NavMenu.razor similarity index 100% rename from MP.SPEC/Shared/NavMenu.razor rename to MP.SPEC/Components/Layout/NavMenu.razor diff --git a/MP.SPEC/Shared/NavMenu.razor.cs b/MP.SPEC/Components/Layout/NavMenu.razor.cs similarity index 98% rename from MP.SPEC/Shared/NavMenu.razor.cs rename to MP.SPEC/Components/Layout/NavMenu.razor.cs index 0d2208e9..87d2a650 100644 --- a/MP.SPEC/Shared/NavMenu.razor.cs +++ b/MP.SPEC/Components/Layout/NavMenu.razor.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Mvc.RazorPages; using MP.SPEC.Data; -namespace MP.SPEC.Shared +namespace MP.SPEC.Components.Layout { public partial class NavMenu : IDisposable { diff --git a/MP.SPEC/Shared/NavMenu.razor.css b/MP.SPEC/Components/Layout/NavMenu.razor.css similarity index 100% rename from MP.SPEC/Shared/NavMenu.razor.css rename to MP.SPEC/Components/Layout/NavMenu.razor.css diff --git a/MP.SPEC/Components/ListODL.razor.cs b/MP.SPEC/Components/ListODL.razor.cs index f0cf41b7..480caa30 100644 --- a/MP.SPEC/Components/ListODL.razor.cs +++ b/MP.SPEC/Components/ListODL.razor.cs @@ -1,8 +1,6 @@ using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.DataProtection; using Microsoft.JSInterop; using MP.Data.DbModels; -using MP.SPEC.Components; using MP.SPEC.Data; using MP.SPEC.Services; using NLog; @@ -209,7 +207,7 @@ namespace MP.SPEC.Components protected override async Task OnInitializedAsync() { ListStati = await MDService.AnagStatiComm(); - ListArtKit = MDService.ArticoliGetByTipo("KIT", "*"); + ListArtKit = await MDService.ArticoliGetByTipoAsync("KIT", "*"); string SPEC_PODL_gest = await MDService.ConfigTryGetAsync("SPEC_PODL_gest"); if (!string.IsNullOrEmpty(SPEC_PODL_gest)) { diff --git a/MP.SPEC/Components/ListPODL.razor.cs b/MP.SPEC/Components/ListPODL.razor.cs index 3217b076..29151abe 100644 --- a/MP.SPEC/Components/ListPODL.razor.cs +++ b/MP.SPEC/Components/ListPODL.razor.cs @@ -216,9 +216,8 @@ namespace MP.SPEC.Components .Select(x => x.IdxMacchina) .ToHashSet(); - ListStati = await MDService.AnagStatiComm(); - ListArtKit = MDService.ArticoliGetByTipo("KIT", "*"); + ListArtKit = await MDService.ArticoliGetByTipoAsync("KIT", "*"); string strMachRecipe = await MDService.ConfigTryGetAsync("MachineWithRecipe"); if (!string.IsNullOrEmpty(strMachRecipe)) { diff --git a/MP.SPEC/Components/Routes.razor b/MP.SPEC/Components/Routes.razor new file mode 100644 index 00000000..37c2f803 --- /dev/null +++ b/MP.SPEC/Components/Routes.razor @@ -0,0 +1,12 @@ + + + + + + + Not found + +

              Sorry, there's nothing at this address.

              +
              +
              +
              diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 46079cca..5d7405d1 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -417,15 +417,15 @@ namespace MP.SPEC.Data /// /// /// - public List ArticoliGetByTipo(string tipo, string azienda = "*") + public async Task> ArticoliGetByTipoAsync(string tipo, string azienda = "*") { - using var activity = ActivitySource.StartActivity("ArticoliGetByTipo"); + using var activity = ActivitySource.StartActivity("ArticoliGetByTipoAsync"); List? result = new List(); string source = "DB"; string sKey = string.IsNullOrEmpty(tipo) ? "ALL" : tipo; string currKey = $"{Utils.redisArtList}:{azienda}:Tipo:{sKey}"; // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); + RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); @@ -433,10 +433,10 @@ namespace MP.SPEC.Data } else { - result = dbController.ArticoliGetByTipo(tipo, azienda); + result = await dbController.ArticoliGetByTipoAsync(tipo, azienda); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); + await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache)); } if (result == null) { @@ -445,7 +445,7 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.SetTag("result.count", result.Count); activity?.Stop(); - LogTrace($"ArticoliGetByTipo | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ArticoliGetByTipoAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; } @@ -685,34 +685,6 @@ namespace MP.SPEC.Data LogTrace($"ConfigTryGet Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return value ?? ""; - -#if false - string answ = ""; - using var activity = ActivitySource.StartActivity("ConfigTryGet"); - string source = "DB+REDIS"; - // preselezione valori - if (configData == null || configData.Count == 0) - { - configData = ConfigGetAll(); - } - var currRec = configData.FirstOrDefault(x => x.Chiave == keyName); - - // se non trovato provo a ricaricare.. - if (currRec == null) - { - configData = ConfigGetAll(); - currRec = configData.FirstOrDefault(x => x.Chiave == keyName); - } - // verifico se ci sia il dato... - if (currRec != null) - { - answ = currRec.Valore; - } - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"ConfigTryGet Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return answ; -#endif } /// @@ -732,36 +704,8 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ConfigTryGetAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ConfigTryGetAsync | {keyName} | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return value ?? ""; - -#if false - string answ = ""; - using var activity = ActivitySource.StartActivity("ConfigTryGetAsync"); - string source = "DB+REDIS"; - // preselezione valori - if (configData == null || configData.Count == 0) - { - configData = await ConfigGetAllAsync(); - } - var currRec = configData.FirstOrDefault(x => x.Chiave == keyName); - - // se non trovato provo a ricaricare.. - if (currRec != null) - { - configData = await ConfigGetAllAsync(); - currRec = configData.FirstOrDefault(x => x.Chiave == keyName); - } - // verifico se ci sia il dato... - if (currRec != null) - { - answ = currRec.Valore; - } - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"ConfigTryGetAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return answ; -#endif } /// @@ -2070,27 +2014,6 @@ namespace MP.SPEC.Data // chiamo metodo conferma! fatto = await dbController.ODLClose(idxOdl, idxMacchina, matrOpr, confPezzi, confRett, modoConfProd); -#if false - // recupero dati x conf modalità conferma - var configData = await ConfigGetAllAsync(); - 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); - } -#endif activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"ODLClose | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -3344,17 +3267,6 @@ namespace MP.SPEC.Data #endregion Private Fields - #region Private Properties - -#if false - /// - /// Cache dati config - /// - private List configData { get; set; } = new List(); -#endif - - #endregion Private Properties - #region Private Methods /// @@ -3368,6 +3280,7 @@ namespace MP.SPEC.Data ExecFlushRedisPattern(pattern); } } + private void EnsureConfigLoaded() { if (_configData.Count == 0) @@ -3379,6 +3292,7 @@ namespace MP.SPEC.Data .ToDictionary(g => g.Key, g => g.First().Valore); } } + private async Task EnsureConfigLoadedAsync() { if (_configData.Count == 0) diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 06d98519..e978a1c1 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2616 + 8.16.2605.2617 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/_Host.cshtml b/MP.SPEC/Pages/_Host.cshtml deleted file mode 100644 index cc60006b..00000000 --- a/MP.SPEC/Pages/_Host.cshtml +++ /dev/null @@ -1,8 +0,0 @@ -@page "/" -@namespace MP.SPEC.Pages -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers -@{ - Layout = "_Layout"; -} - - \ No newline at end of file diff --git a/MP.SPEC/Pages/_Layout.cshtml b/MP.SPEC/Pages/_Layout.cshtml deleted file mode 100644 index ce82407f..00000000 --- a/MP.SPEC/Pages/_Layout.cshtml +++ /dev/null @@ -1,69 +0,0 @@ -@using Microsoft.AspNetCore.Components.Web -@namespace MP.SPEC.Pages -@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers - - - - - MP-SPEC - - - - - - - - - - - - - - @RenderBody() - -
              - - An error has occurred. This application may no longer respond until reloaded. - - - An unhandled exception has occurred. See browser dev tools for details. - - Reload - 🗙 -
              - - - - - - - - - @*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)*@ - - - diff --git a/MP.SPEC/Program.cs b/MP.SPEC/Program.cs index 23fcc447..b91a66a0 100644 --- a/MP.SPEC/Program.cs +++ b/MP.SPEC/Program.cs @@ -1,10 +1,6 @@ using Microsoft.AspNetCore.Authentication.Negotiate; -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.StaticFiles; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.FileProviders; -using Microsoft.JSInterop; using MP.AppAuth.Services; using MP.Data.Services; using MP.SPEC.Components; @@ -12,7 +8,6 @@ using MP.SPEC.Data; using MP.SPEC.Services; using NLog; using NLog.Targets; -using NLog.Targets.OpenTelemetryProtocol; using NLog.Web; using OpenTelemetry.Resources; using OpenTelemetry.Trace; @@ -21,14 +16,6 @@ using StackExchange.Redis; var builder = WebApplication.CreateBuilder(args); -/*-------------------- - * Note migrazione startup.cs --> program.cs: - * - * - https://stackoverflow.com/questions/69722872/asp-net-core-6-how-to-access-ConfMan-during-startup - * - https://docs.microsoft.com/en-us/aspnet/core/migration/50-to-60?view=aspnetcore-5.0&tabs=visual-studio#where-do-i-put-state-that-was-stored-as-fields-in-my-program-or-startup-class - * - * */ - ConfigurationManager configuration = builder.Configuration; var logger = LogManager.Setup() @@ -141,10 +128,13 @@ builder.Services.AddAuthorization(options => options.FallbackPolicy = options.DefaultPolicy; }); -// redis replliminare +//setup Blazor +builder.Services.AddRazorComponents() + .AddInteractiveServerComponents(); + +// redis preliminare builder.Services.AddSingleton(redisMultiplexer); builder.Services.AddRazorPages(); -builder.Services.AddServerSideBlazor(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); @@ -153,20 +143,10 @@ builder.Services.AddScoped(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); -#if false -builder.Services.AddBlazoredLocalStorage(); -builder.Services.AddBlazoredSessionStorage(); -#endif + // aggiunta helper local/session storage service builder.Services.AddScoped(); builder.Services.AddScoped(); -//builder.Services.AddScoped(); -//builder.Services.AddScoped(); -//builder.Services.AddScoped(sp => -// new SessionStorageService(sp.GetRequiredService())); -//builder.Services.AddScoped(sp => -// new LocalStorageService(sp.GetRequiredService())); - builder.Services.AddHttpClient(); @@ -179,7 +159,9 @@ logger.Info("Build App"); // aggiunt base URL x routing corretto -app.UsePathBase(configuration.GetValue("SpecialConf:AppUrl")); +string baseUrl = configuration.GetValue("SpecialConf:AppUrl") ?? ""; +app.UsePathBase(baseUrl); +logger.Info($"BaseUrl: {baseUrl}"); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) @@ -193,6 +175,13 @@ app.UseHttpsRedirection(); app.UseStaticFiles(); +app.UseRouting(); + +app.UseAuthentication(); +app.UseAuthorization(); + +app.UseAntiforgery(); + // gestione static files: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-8.0 string BasePathOdlReturn = configuration.GetValue("ServerConf:BasePathOdlReturn") ?? configuration.GetValue("OptConf:BasePathOdlReturn") ?? ""; if (!string.IsNullOrEmpty(BasePathOdlReturn)) @@ -234,19 +223,8 @@ if (!string.IsNullOrEmpty(BasePathOdlReturn)) } } -app.UseRouting(); - -app.UseAuthentication(); -app.UseAuthorization(); - -app.UseEndpoints(endpoints => -{ - endpoints.MapControllers(); - endpoints.MapBlazorHub(); - endpoints.MapFallbackToPage("/_Host"); -}); -//app.MapBlazorHub(); -//app.MapFallbackToPage("/_Host"); +app.MapRazorComponents() + .AddInteractiveServerRenderMode(); logger.Info("Run App"); diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 68c19573..323e79be 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

              Versione: 8.16.2605.2616

              +

              Versione: 8.16.2605.2617


              Note di rilascio:
              • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 418a7c18..e207479d 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2616 +8.16.2605.2617 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 19b26f9f..68083a5c 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2616 + 8.16.2605.2617 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/_Imports.razor b/MP.SPEC/_Imports.razor index 8af8acff..1e775e6f 100644 --- a/MP.SPEC/_Imports.razor +++ b/MP.SPEC/_Imports.razor @@ -1,5 +1,6 @@ @using System.Net.Http @using Microsoft.AspNetCore.Authorization +@using Microsoft.AspNetCore.Components @using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms @using Microsoft.AspNetCore.Components.Routing @@ -15,6 +16,7 @@ @using MP.SPEC.Components @using MP.SPEC.Components.Chart @using MP.SPEC.Components.Fermate +@using MP.SPEC.Components.Layout @using MP.SPEC.Components.ProdKit @using MP.SPEC.Components.Reparti @using EgwCoreLib.Razor \ No newline at end of file diff --git a/MP.SPEC/appsettings.json b/MP.SPEC/appsettings.json index a061328d..bf3f1ae9 100644 --- a/MP.SPEC/appsettings.json +++ b/MP.SPEC/appsettings.json @@ -81,7 +81,7 @@ "maxChar4Scroll": 21 }, "SpecialConf": { - "AppUrl": "/MP/SPEC", + "AppUrl": "/MP/SPEC/", "CodApp": "MP-SPEC", "CodModulo": "MP-SPEC" } From 8c995d4c440375de7106e66e21e1e5c0d486a2bc Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Tue, 26 May 2026 19:01:01 +0200 Subject: [PATCH 007/102] Update caching SPEC --- MP.Data/Controllers/MpSpecController.cs | 26 +-- MP.Data/Services/ListSelectDataSrv.cs | 7 +- MP.SPEC/Components/ListDossiers.razor.cs | 2 +- MP.SPEC/Components/ListPODL.razor.cs | 27 +-- MP.SPEC/Data/MpDataService.cs | 271 +++++++++++++++++++---- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Articoli.razor.cs | 2 +- MP.SPEC/Pages/PODL.razor.cs | 12 +- MP.SPEC/Program.cs | 8 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 12 files changed, 272 insertions(+), 91 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index bdfc3780..9847a5ad 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -456,18 +456,18 @@ namespace MP.Data.Controllers /// /// /// - public List ArticoliGetSearch(int numRecord, string azienda = "*", string searchVal = "") + public async Task> ArticoliGetSearchAsync(int numRecord, string azienda = "*", string searchVal = "") { List dbResult = new List(); using (var dbCtx = new MoonProContext(options)) { - dbResult = dbCtx - .DbSetArticoli - .AsNoTracking() - .Where(x => (azienda == "*" || x.Azienda.ToUpper() == azienda.ToUpper()) && (string.IsNullOrEmpty(searchVal) || x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal))) - .OrderBy(x => x.CodArticolo) - .Take(numRecord) - .ToList(); + dbResult = await dbCtx + .DbSetArticoli + .AsNoTracking() + .Where(x => (azienda == "*" || x.Azienda.ToUpper() == azienda.ToUpper()) && (string.IsNullOrEmpty(searchVal) || x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal))) + .OrderBy(x => x.CodArticolo) + .Take(numRecord) + .ToListAsync(); } return dbResult; } @@ -1891,15 +1891,15 @@ namespace MP.Data.Controllers /// Recupero Odl CORRENTI ///
              /// - public List OdlGetCurrent() + public async Task> OdlGetCurrentAsync() { List dbResult = new List(); using (var dbCtx = new MoonProContext(options)) { - dbResult = dbCtx - .DbSetODL - .Where(x => x.DataInizio != null && x.DataFine == null) - .ToList(); + dbResult = await dbCtx + .DbSetODL + .Where(x => x.DataInizio != null && x.DataFine == null) + .ToListAsync(); } return dbResult; } diff --git a/MP.Data/Services/ListSelectDataSrv.cs b/MP.Data/Services/ListSelectDataSrv.cs index b541ee06..2e49fc21 100644 --- a/MP.Data/Services/ListSelectDataSrv.cs +++ b/MP.Data/Services/ListSelectDataSrv.cs @@ -70,10 +70,7 @@ namespace MP.Data.Services } else { - result = dbController.ArticoliGetSearch(numRecord, azienda, searchVal); -#if false - result = await Task.FromResult(dbController.ArticoliGetSearch(numRecord, azienda, searchVal)); -#endif + result = await dbController.ArticoliGetSearchAsync(numRecord, azienda, searchVal); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await _redisDb.StringSetAsync(currKey, rawData, LongCache); @@ -83,7 +80,7 @@ namespace MP.Data.Services result = new List(); } sw.Stop(); - Log.Debug($"ArticoliGetSearch | azienda: {azienda} | searchVal: {searchVal} | numRecord: {numRecord} | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + Log.Debug($"ArticoliGetSearchAsync | azienda: {azienda} | searchVal: {searchVal} | numRecord: {numRecord} | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } diff --git a/MP.SPEC/Components/ListDossiers.razor.cs b/MP.SPEC/Components/ListDossiers.razor.cs index 1da69a82..f26032dd 100644 --- a/MP.SPEC/Components/ListDossiers.razor.cs +++ b/MP.SPEC/Components/ListDossiers.razor.cs @@ -234,7 +234,7 @@ namespace MP.SPEC.Components ListStati = await MDService.AnagStatiComm(); selAzienda = await MDService.ConfigTryGetAsync("AZIENDA"); giacenzeConf = await MDService.ConfigTryGetAsync("SPEC_ShowGiacenze"); - ListArticoli = await MDService.ArticoliGetSearch(100000, selAzienda, ""); + ListArticoli = await MDService.ArticoliGetSearchAsync(100000, selAzienda, ""); ListMacchine = MDService.MacchineGetFilt("*"); await ReloadData(true); } diff --git a/MP.SPEC/Components/ListPODL.razor.cs b/MP.SPEC/Components/ListPODL.razor.cs index 29151abe..44897fbc 100644 --- a/MP.SPEC/Components/ListPODL.razor.cs +++ b/MP.SPEC/Components/ListPODL.razor.cs @@ -204,6 +204,9 @@ namespace MP.SPEC.Components ListRecords = null; isLoading = true; + var list = await MDService.OdlGetCurrentAsync(); + _odlCurrSet = list.ToHashSet(); + var machines = await MDService.MacchineGetFiltAsync("*"); _machinesWithConf = machines @@ -244,7 +247,7 @@ namespace MP.SPEC.Components { ListRecords = null; isLoading = true; - + await UpdateOdlList(); // verifico filtro odl... if (actFilter.ShowKit) { @@ -259,8 +262,7 @@ namespace MP.SPEC.Components totalCount = SearchRecords.Count; } ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); - await Task.Delay(1); - await InvokeAsync(() => StateHasChanged()); + //await InvokeAsync(() => StateHasChanged()); isLoading = false; } @@ -356,6 +358,7 @@ namespace MP.SPEC.Components private static Logger Log = LogManager.GetCurrentClassLogger(); private HashSet _machinesWithArch = new(); private HashSet _machinesWithConf = new(); + private HashSet _odlCurrSet = new(); private string currRecipeArchPath = ""; /// @@ -567,18 +570,16 @@ namespace MP.SPEC.Components /// private bool canStartOdl(string idxMacchina) { - // controllo se lista scaduta... - bool answ = false; - DateTime adesso = DateTime.Now; - if (adesso > odlCurrExp || odlCurrList == null || odlCurrList.Count == 0) - { - odlCurrList = MDService.OdlGetCurrent(); - odlCurrExp = adesso.AddSeconds(2); - } - answ = !odlCurrList.Contains(idxMacchina); - return answ; + return !_odlCurrSet.Contains(idxMacchina); } + private async Task UpdateOdlList() + { + var list = await MDService.OdlGetCurrentAsync(); + _odlCurrSet = list.ToHashSet(); + } + + /// /// Verifica se la idxMaccSel abbia associata un path x ricette (elenco) /// diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 5d7405d1..79499830 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1,5 +1,6 @@ using EgwCoreLib.Utils; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; using MP.Core.Conf; using MP.Core.DTO; using MP.Core.Objects; @@ -20,10 +21,11 @@ namespace MP.SPEC.Data { #region Public Constructors - public MpDataService(IConfiguration configuration) + public MpDataService(IConfiguration configuration, IMemoryCache memoryCache) { - // fix oggetto configurazion + // salvataggio oggetti _configuration = configuration; + _memoryCache = memoryCache; // Verifica conf trace... traceEnabled = _configuration.GetValue("Otel:EnableTracing", false); Log.Info($"MpDataService | INIT | Trace enabled: {traceEnabled}"); @@ -298,7 +300,18 @@ namespace MP.SPEC.Data LogTrace($"AnagKeyValGetAll Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; } + public async Task> AnagStatiComm() + { + return await GetOrCreateCachedAsync( + operationName: "AnagStatiComm", + memKey: "ANAG_STATI_COMM_MEM", + redisKey: Utils.redisStatoCom, + memoryTtl: TimeSpan.FromMinutes(5), + dbFactory: () => Task.FromResult(dbController.AnagStatiComm() ?? new List()) + ); + } +#if false public async Task> AnagStatiComm() { using var activity = ActivitySource.StartActivity("AnagStatiComm"); @@ -327,7 +340,8 @@ namespace MP.SPEC.Data activity?.Stop(); LogTrace($"AnagStatiComm Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; - } + } +#endif public async Task> AnagTipoArtLV() { @@ -417,6 +431,25 @@ namespace MP.SPEC.Data /// /// /// + public async Task> ArticoliGetByTipoAsync(string tipo, string azienda = "*") + { + string sKey = string.IsNullOrWhiteSpace(tipo) ? "ALL" : tipo.Trim(); + + string redisKey = $"{Utils.redisArtList}:{azienda}:Tipo:{sKey}"; + string memKey = $"MEM:{redisKey}"; + + return await GetOrCreateCachedAsync( + operationName: "ArticoliGetByTipoAsync", + memKey: memKey, + redisKey: redisKey, + // ✅ TTL lungo (dato abbastanza statico) + memoryTtl: TimeSpan.FromMinutes(5), + dbFactory: async () => + await dbController.ArticoliGetByTipoAsync(tipo, azienda) + ?? new List() + ); + } +#if false public async Task> ArticoliGetByTipoAsync(string tipo, string azienda = "*") { using var activity = ActivitySource.StartActivity("ArticoliGetByTipoAsync"); @@ -447,7 +480,8 @@ namespace MP.SPEC.Data activity?.Stop(); LogTrace($"ArticoliGetByTipoAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; - } + } +#endif /// /// Restitusice elenco articoli cercati @@ -455,38 +489,115 @@ namespace MP.SPEC.Data /// /// /// - public async Task> ArticoliGetSearch(int numRecord, string azienda, string searchVal) + public async Task> ArticoliGetSearchAsync(int numRecord, string azienda, string searchVal) { - using var activity = ActivitySource.StartActivity("ArticoliGetSearch"); - List? result = new List(); - string source = "DB"; - string sKey = string.IsNullOrEmpty(searchVal) ? "***" : searchVal; - string currKey = $"{Utils.redisArtList}:{azienda}:{sKey}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) + string sKey = string.IsNullOrWhiteSpace(searchVal) ? "***" : searchVal.Trim(); + + string memKey = $"ART_SEARCH_MEM:{azienda}:{sKey}:{numRecord}"; + string redisKey = $"{Utils.redisArtList}:{azienda}:{sKey}:{numRecord}"; + + return await GetOrCreateCachedAsync( + operationName: "ArticoliGetSearchAsync", + memKey: memKey, + redisKey: redisKey, + memoryTtl: TimeSpan.FromMinutes(2), + dbFactory: async () => + await dbController.ArticoliGetSearchAsync(numRecord, azienda, searchVal) + ?? new List() + ); + } + + + /// + /// Helper per gestione cache a 3 livelli: MEMORY, REDIS e DB con opzioni + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + private async Task GetOrCreateCachedAsync(string operationName, string memKey, string redisKey, TimeSpan memoryTtl, Func> dbFactory, Func? serialize = null, Func? deserialize = null) + { + using var activity = ActivitySource.StartActivity(operationName); + + string source = "NA"; + T result; + + // ✅ default serializer (fallback) + serialize ??= (obj) => JsonConvert.SerializeObject(obj); + deserialize ??= (str) => JsonConvert.DeserializeObject(str)!; + + // ✅ 1. MEMORY + if (_memoryCache.TryGetValue(memKey, out T cached)) { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; + result = cached; + source = "MEMORY"; } else { - result = await Task.FromResult(dbController.ArticoliGetSearch(numRecord, azienda, searchVal)); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache / 5)); - } - if (result == null) - { - result = new List(); + // ✅ 2. MISS → factory + result = await _memoryCache.GetOrCreateAsync(memKey, async entry => + { + entry.AbsoluteExpirationRelativeToNow = memoryTtl; + + // 👉 REDIS + try + { + var rawData = await redisDb.StringGetAsync(redisKey); + + if (rawData.HasValue) + { + source = "REDIS"; + return deserialize(rawData!); + } + } + catch (Exception ex) + { + LogTrace($"Redis error on {operationName}: {ex.Message}"); + } + + // 👉 DB + source = "DB"; + + var dbResult = await dbFactory(); + + var safeResult = dbResult == null ? default! : dbResult; + + try + { + await redisDb.StringSetAsync( + redisKey, + serialize(safeResult), + getRandTOut(redisLongTimeCache) + ); + } + catch (Exception ex) + { + LogTrace($"Redis SET error on {operationName}: {ex.Message}"); + } + + return safeResult; + })!; } + + // ✅ logging e tracing centralizzati activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"ArticoliGetSearch | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + + if (result is System.Collections.ICollection coll) + activity?.SetTag("result.count", coll.Count); + else + activity?.SetTag("result.count", result != null ? 1 : 0); + + LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return result; } + /// /// Aggiornamento record selezionato /// @@ -704,7 +815,7 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ConfigTryGetAsync | {keyName} | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ConfigTryGetAsync | {keyName} | {source} | {activity?.Duration.TotalMilliseconds}ms"); return value ?? ""; } @@ -1687,7 +1798,7 @@ namespace MP.SPEC.Data LogTrace($"MacchineGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; } - + private readonly IMemoryCache _memoryCache; /// /// Elenco di tutte le macchine filtrate x gruppo /// @@ -1695,32 +1806,51 @@ namespace MP.SPEC.Data /// public async Task> MacchineGetFiltAsync(string codGruppo) { - using var activity = ActivitySource.StartActivity("MacchineGetFilt"); - List? result = new List(); + using var activity = ActivitySource.StartActivity("MacchineGetFiltAsync"); string source = "DB"; + string keyGrp = codGruppo != "*" ? codGruppo : "ALL"; - string currKey = $"{Utils.redisMacList}:{keyGrp}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = await redisDb.StringGetAsync(currKey); + string memKey = $"MACCHINE_MEM:{keyGrp}"; + string redisKey = $"{Utils.redisMacList}:{keyGrp}"; + + // ✅ 1. MEMORY CACHE + if (_memoryCache.TryGetValue(memKey, out List cached)) + { + source = "MEMORY"; + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"MacchineGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + return cached; + } + + List result; + + // ✅ 2. REDIS + var rawData = await redisDb.StringGetAsync(redisKey); + if (rawData.HasValue) { - result = JsonConvert.DeserializeObject>($"{rawData}"); + result = JsonConvert.DeserializeObject>(rawData!) ?? new(); source = "REDIS"; } else { + // ✅ 3. DB result = await dbController.MacchineGetFiltAsync(codGruppo); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); + + await redisDb.StringSetAsync( + redisKey, + JsonConvert.SerializeObject(result), + getRandTOut(redisLongTimeCache) + ); } + + // ✅ salva in RAM (IMPORTANTISSIMO), TTL 1 minuto + _memoryCache.Set(memKey, result, TimeSpan.FromMinutes(1)); + activity?.SetTag("data.source", source); - activity?.SetTag("result.count", 1); activity?.Stop(); + LogTrace($"MacchineGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; } @@ -2040,6 +2170,32 @@ namespace MP.SPEC.Data /// /// /// + + public async Task> OdlGetCurrentAsync() + { + string redisKey = Utils.redisOdlCurrByMac; + string memKey = $"MEM:{redisKey}"; + + return await GetOrCreateCachedAsync( + operationName: "OdlGetCurrentAsync", + memKey: memKey, + redisKey: redisKey, + // ✅ TTL molto corto (come avevi: 3 secondi) + memoryTtl: TimeSpan.FromSeconds(3), + dbFactory: async () => + { + var rawData = await dbController.OdlGetCurrentAsync(); + var dbResult = rawData + .Select(x => x.IdxMacchina) + .Distinct() + .ToList(); + + return dbResult ?? new List(); + } + ); + } + +#if false public List OdlGetCurrent() { using var activity = ActivitySource.StartActivity("OdlGetCurrent"); @@ -2068,7 +2224,8 @@ namespace MP.SPEC.Data activity?.Stop(); LogTrace($"OdlGetCurrent | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return dbResult; - } + } +#endif /// /// elenco TUTTI gli ODL @@ -2479,6 +2636,31 @@ namespace MP.SPEC.Data /// Data inizio /// Data fine /// + public async Task> POdlToKitListGetFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) + { + string currKey = $"{Utils.redisPOdlList}_kit:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; + + // ✅ stessa chiave per memoria (puoi anche prefissare) + string memKey = $"MEM:{currKey}"; + + return await GetOrCreateCachedAsync( + operationName: "POdlToKitListGetFiltAsync", + memKey: memKey, + redisKey: currKey, + // ✅ TTL RAM breve (coerente con redisShortTimeCache) + memoryTtl: TimeSpan.FromSeconds(redisShortTimeCache), + dbFactory: async () => + await dbController.ListPODL_KitFiltAsync( + lanciato, + keyRichPart, + idxMacchina, + codGruppo, + startDate, + endDate + ) ?? new List() + ); + } +#if false public async Task> POdlToKitListGetFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) { using var activity = ActivitySource.StartActivity("POdlToKitListGetFiltAsync"); @@ -2508,7 +2690,8 @@ namespace MP.SPEC.Data activity?.Stop(); LogTrace($"POdlToKitListGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; - } + } +#endif /// /// Chiamata salvataggio ricetta + refresh REDIS diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index e978a1c1..8ce4107b 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2617 + 8.16.2605.2619 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Articoli.razor.cs b/MP.SPEC/Pages/Articoli.razor.cs index e3b23914..008bbc19 100644 --- a/MP.SPEC/Pages/Articoli.razor.cs +++ b/MP.SPEC/Pages/Articoli.razor.cs @@ -335,7 +335,7 @@ namespace MP.SPEC.Pages private async Task ReloadData() { isLoading = true; - SearchRecords = await MDService.ArticoliGetSearch(100000, selAzienda, SearchVal); + SearchRecords = await MDService.ArticoliGetSearchAsync(100000, selAzienda, SearchVal); ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); isLoading = false; } diff --git a/MP.SPEC/Pages/PODL.razor.cs b/MP.SPEC/Pages/PODL.razor.cs index ce20588b..23054a1a 100644 --- a/MP.SPEC/Pages/PODL.razor.cs +++ b/MP.SPEC/Pages/PODL.razor.cs @@ -1,17 +1,14 @@ #if false using Blazored.LocalStorage; #endif +using EgwCoreLib.Razor; using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; using MP.Data.DbModels; -using MP.SPEC.Components; +using MP.Data.Services; using MP.SPEC.Data; using MP.SPEC.Services; using NLog; -using System.Reflection.PortableExecutable; -using EgwCoreLib.Razor; -using Microsoft.AspNetCore.DataProtection; -using MP.Data.Services; namespace MP.SPEC.Pages { @@ -501,9 +498,8 @@ namespace MP.SPEC.Pages private async Task ReloadData() { isLoading = true; - await Task.Delay(1); - ListMacchine = MDService.MacchineGetFilt(selReparto); - ListArticoli = await MDService.ArticoliGetSearch(100, currAzienda, artSearch); + ListMacchine = await MDService.MacchineGetFiltAsync(selReparto); + ListArticoli = await MDService.ArticoliGetSearchAsync(100, currAzienda, artSearch); if (ListGruppiFase != null) { var firstGroup = ListGruppiFase.Where(x => x.CodGruppo == selReparto).FirstOrDefault(); diff --git a/MP.SPEC/Program.cs b/MP.SPEC/Program.cs index b91a66a0..5b8365ff 100644 --- a/MP.SPEC/Program.cs +++ b/MP.SPEC/Program.cs @@ -132,9 +132,13 @@ builder.Services.AddAuthorization(options => builder.Services.AddRazorComponents() .AddInteractiveServerComponents(); -// redis preliminare -builder.Services.AddSingleton(redisMultiplexer); builder.Services.AddRazorPages(); + +// memory + redis preliminare +builder.Services.AddMemoryCache(); +builder.Services.AddSingleton(redisMultiplexer); + +// altri servizi builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 323e79be..dca5987a 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

              Versione: 8.16.2605.2617

              +

              Versione: 8.16.2605.2619


              Note di rilascio:
              • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index e207479d..5ea9eaa9 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2617 +8.16.2605.2619 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 68083a5c..b079c1c6 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2617 + 8.16.2605.2619 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From 20a16471a98323dcb73926ba67ac53c64d3ef5a8 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Tue, 26 May 2026 19:14:10 +0200 Subject: [PATCH 008/102] Ancora ottimizzazione azioni calcolo/update/display --- MP.SPEC/Components/ListPODL.razor.cs | 52 ++++++++++++++++++++++++++-- MP.SPEC/Data/MpDataService.cs | 22 +++++++++++- 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/MP.SPEC/Components/ListPODL.razor.cs b/MP.SPEC/Components/ListPODL.razor.cs index 44897fbc..b131fcac 100644 --- a/MP.SPEC/Components/ListPODL.razor.cs +++ b/MP.SPEC/Components/ListPODL.razor.cs @@ -171,11 +171,22 @@ namespace MP.SPEC.Components await ReloadBaseData(); } + private string? _lastPadCodXdl; + private bool _initialized; + protected override async Task OnParametersSetAsync() { - if (!lastFilter.Equals(actFilter)) + // esempio: verifica parametri minimi + if (string.IsNullOrEmpty(padCodXdl) || actFilter == null) + return; + + if (!_initialized || !lastFilter.Equals(actFilter) || _lastPadCodXdl != padCodXdl) { + _initialized = true; + lastFilter = actFilter.clone(); + _lastPadCodXdl = padCodXdl; + await ReloadData(); } } @@ -243,6 +254,41 @@ namespace MP.SPEC.Components } } + protected async Task ReloadData() + { + isLoading = true; + ListRecords = null; + + // ✅ lancia in parallelo + var odlTask = UpdateOdlList(); + + Task> searchTask; + + if (actFilter.ShowKit) + { + searchTask = MDService.POdlListGetFiltAsync(hasOdl, StatoSel, macchina, reparto, selDtStart, selDtEnd); + } + else + { + searchTask = MDService.POdlToKitListGetFiltAsync(hasOdl, StatoSel, macchina, reparto, selDtStart, selDtEnd); + } + + // ✅ aspetta tutto insieme + await Task.WhenAll(odlTask, searchTask); + + SearchRecords = searchTask.Result; + + totalCount = SearchRecords.Count; + + ListRecords = SearchRecords + .Skip(numRecord * (currPage - 1)) + .Take(numRecord) + .ToList(); + + isLoading = false; + } + +#if false protected async Task ReloadData() { ListRecords = null; @@ -262,9 +308,9 @@ namespace MP.SPEC.Components totalCount = SearchRecords.Count; } ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); - //await InvokeAsync(() => StateHasChanged()); isLoading = false; - } + } +#endif protected async Task resetSel(bool forceUpdate) { diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 79499830..4014b17d 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1804,6 +1804,25 @@ namespace MP.SPEC.Data ///
              /// /// + public async Task> MacchineGetFiltAsync(string codGruppo) + { + string keyGrp = codGruppo != "*" ? codGruppo : "ALL"; + + string redisKey = $"{Utils.redisMacList}:{keyGrp}"; + string memKey = $"MACCHINE_MEM:{keyGrp}"; + + return await GetOrCreateCachedAsync( + operationName: "MacchineGetFiltAsync", + memKey: memKey, + redisKey: redisKey, + // ✅ TTL coerente con il tuo requisito (prima avevi 1 minuto) + memoryTtl: TimeSpan.FromMinutes(1), + dbFactory: async () => + await dbController.MacchineGetFiltAsync(codGruppo) + ?? new List() + ); + } +#if false public async Task> MacchineGetFiltAsync(string codGruppo) { using var activity = ActivitySource.StartActivity("MacchineGetFiltAsync"); @@ -1853,7 +1872,8 @@ namespace MP.SPEC.Data LogTrace($"MacchineGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; - } + } +#endif /// /// Verifica se la idxMaccSel abbia un codice PATH ricette associato From 9e4594f8b4dc8528e662f9ccb4f4da3e8e30ff20 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 08:51:30 +0200 Subject: [PATCH 009/102] Review cache con FusionCache --- Directory.Packages.props | 2 +- MP.Data/Controllers/MpSpecController.cs | 25 +- MP.SPEC/Data/MpDataService.cs | 432 +++++++++++++++++++----- MP.SPEC/MP.SPEC.csproj | 6 +- MP.SPEC/Program.cs | 24 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- MP.SPEC/appsettings.json | 3 +- 9 files changed, 397 insertions(+), 101 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 71c44dc1..aee39b65 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -24,7 +24,7 @@ - + diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 9847a5ad..cb8d41ef 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -342,9 +342,9 @@ namespace MP.Data.Controllers /// Elenco valori ammessi x Stati commessa (es Yacht Baglietto) /// /// - public List AnagStatiComm() + public Task> AnagStatiCommAsync() { - return ListValuesFilt("PODL", "StatoComm"); + return ListValuesFiltAsync("PODL", "StatoComm"); } /// @@ -1522,6 +1522,27 @@ namespace MP.Data.Controllers return dbResult; } + /// + /// Elenco valori ammessi x tabella/colonna Async + /// + /// + /// + /// + public async Task> ListValuesFiltAsync(string tabName, string fieldName) + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(options)) + { + dbResult = await dbCtx + .DbSetListValues + .Where(x => x.TableName == tabName && x.FieldName == fieldName) + .AsNoTracking() + .OrderBy(x => x.ordinal) + .ToListAsync(); + } + return dbResult; + } + /// /// Elenco Macchine dato operatore secondo gruppi (macchine/operatore) /// diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 4014b17d..8370b7cf 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1,6 +1,5 @@ using EgwCoreLib.Utils; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Caching.Memory; using MP.Core.Conf; using MP.Core.DTO; using MP.Core.Objects; @@ -14,6 +13,7 @@ using NLog; using StackExchange.Redis; using System.Data; using System.Diagnostics; +using ZiggyCreatures.Caching.Fusion; namespace MP.SPEC.Data { @@ -21,11 +21,11 @@ namespace MP.SPEC.Data { #region Public Constructors - public MpDataService(IConfiguration configuration, IMemoryCache memoryCache) + public MpDataService(IConfiguration configuration, IFusionCache cache) { // salvataggio oggetti _configuration = configuration; - _memoryCache = memoryCache; + _cache = cache; // Verifica conf trace... traceEnabled = _configuration.GetValue("Otel:EnableTracing", false); Log.Info($"MpDataService | INIT | Trace enabled: {traceEnabled}"); @@ -300,15 +300,16 @@ namespace MP.SPEC.Data LogTrace($"AnagKeyValGetAll Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; } + public async Task> AnagStatiComm() { - return await GetOrCreateCachedAsync( - operationName: "AnagStatiComm", - memKey: "ANAG_STATI_COMM_MEM", - redisKey: Utils.redisStatoCom, - memoryTtl: TimeSpan.FromMinutes(5), - dbFactory: () => Task.FromResult(dbController.AnagStatiComm() ?? new List()) - ); + return await GetOrFetchAsync( + operationName: "AnagStatiCommAsync", + cacheKey: Utils.redisStatoCom, + expiration: TimeSpan.FromMinutes(5), + fetchFunc: async () => + await dbController.AnagStatiCommAsync() ?? new List() + ); } #if false @@ -345,7 +346,7 @@ namespace MP.SPEC.Data public async Task> AnagTipoArtLV() { - using var activity = ActivitySource.StartActivity("AnagStatiComm"); + using var activity = ActivitySource.StartActivity("AnagStatiCommAsync"); string source = "DB"; List? result = new List(); // cerco in redis... @@ -438,16 +439,28 @@ namespace MP.SPEC.Data string redisKey = $"{Utils.redisArtList}:{azienda}:Tipo:{sKey}"; string memKey = $"MEM:{redisKey}"; - return await GetOrCreateCachedAsync( - operationName: "ArticoliGetByTipoAsync", - memKey: memKey, - redisKey: redisKey, - // ✅ TTL lungo (dato abbastanza statico) - memoryTtl: TimeSpan.FromMinutes(5), - dbFactory: async () => - await dbController.ArticoliGetByTipoAsync(tipo, azienda) + return await GetOrFetchAsync( + operationName: "ArticoliGetByTipoAsync", + cacheKey: redisKey, + expiration: TimeSpan.FromMinutes(2), + fetchFunc: async () => + await dbController.ArticoliGetByTipoAsync(tipo, azienda) ?? new List() - ); + ); + + +#if false + return await GetOrCreateCachedAsync( + operationName: "ArticoliGetByTipoAsync", + memKey: memKey, + redisKey: redisKey, + // ✅ TTL lungo (dato abbastanza statico) + memoryTtl: TimeSpan.FromMinutes(5), + dbFactory: async () => + await dbController.ArticoliGetByTipoAsync(tipo, azienda) + ?? new List() + ); +#endif } #if false public async Task> ArticoliGetByTipoAsync(string tipo, string azienda = "*") @@ -496,18 +509,161 @@ namespace MP.SPEC.Data string memKey = $"ART_SEARCH_MEM:{azienda}:{sKey}:{numRecord}"; string redisKey = $"{Utils.redisArtList}:{azienda}:{sKey}:{numRecord}"; - return await GetOrCreateCachedAsync( - operationName: "ArticoliGetSearchAsync", - memKey: memKey, - redisKey: redisKey, - memoryTtl: TimeSpan.FromMinutes(2), - dbFactory: async () => - await dbController.ArticoliGetSearchAsync(numRecord, azienda, searchVal) + return await GetOrFetchAsync( + operationName: "ArticoliGetSearchAsync", + cacheKey: redisKey, + expiration: TimeSpan.FromMinutes(2), + fetchFunc: async () => + await dbController.ArticoliGetSearchAsync(numRecord, azienda, searchVal) ?? new List() - ); + ); + +#if false + return await GetOrCreateCachedAsync( + operationName: "ArticoliGetSearchAsync", + memKey: memKey, + redisKey: redisKey, + memoryTtl: TimeSpan.FromMinutes(2), + dbFactory: async () => + await dbController.ArticoliGetSearchAsync(numRecord, azienda, searchVal) + ?? new List() + ); +#endif } + /// + /// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria + tracking attività + /// + /// + /// + /// + /// + /// + private async Task GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tags) + { + using var activity = ActivitySource.StartActivity(operationName); + string source; + var tryGet = await _cache.TryGetAsync(cacheKey); + if (tryGet.HasValue) + { + source = "MEMORY"; + var result = tryGet.Value!; + activity?.SetTag("data.source", source); + LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); + return result; + } + bool fromDb = false; + var final = await _cache.GetOrSetAsync( + cacheKey, + async _ => + { + fromDb = true; + return await fetchFunc(); + }, + opt => + { + opt.SetDuration(expiration) + .SetFailSafe(true); + + //if (tags != null && tags.Length > 0) + // opt.SetTags(tags); + + }); + + source = fromDb ? "DB" : "REDIS"; + activity?.SetTag("data.source", source); + LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); + return final!; + } + +#if false + private async Task GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration) + { + using var activity = ActivitySource.StartActivity(operationName); + + string source; + T result; + + // ✅ 1. Tenta MEMORY / DISTRIBUTED (senza factory) + var memTry = await _cache.TryGetAsync(cacheKey); + + if (memTry.HasValue) + { + result = memTry.Value!; + source = "MEMORY"; + } + else + { + bool fromDb = false; + + // ✅ 2. fallback con factory + result = await _cache.GetOrSetAsync( + cacheKey, + async _ => + { + fromDb = true; + return await fetchFunc(); + }, + options => options.SetDuration(expiration) + )!; + + source = fromDb ? "DB" : "REDIS"; + } + + // ✅ tracing e log + activity?.SetTag("data.source", source); + + if (result is System.Collections.ICollection coll) + activity?.SetTag("result.count", coll.Count); + else + activity?.SetTag("result.count", result != null ? 1 : 0); + + LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); + + return result; + } +#endif + + /// + /// Cancellazione FusionCache (totale) + /// + /// + public async Task FlushCacheAsync() + { + bool fatto = false; + await _cache.ClearAsync(); + fatto = true; + return fatto; + } + + /// + /// Cancellazione FusionCache dato elenco tags + /// + /// + public async Task FlushCacheByTagsAsync(List listTags) + { + bool fatto = false; + foreach (var item in listTags) + { + await _cache.RemoveByTagAsync(item); + } + fatto = true; + return fatto; + } + /// + /// Cancellazione FusionCache dato singolo tag + /// + /// + public async Task FlushCacheByTagAsync(string tag) + { + bool fatto = false; + await _cache.RemoveByTagAsync(tag); + fatto = true; + return fatto; + } + +#if false /// /// Helper per gestione cache a 3 livelli: MEMORY, REDIS e DB con opzioni /// @@ -527,12 +683,20 @@ namespace MP.SPEC.Data string source = "NA"; T result; + string groupKey = memKey.Split(':')[0]; // es: "MACCHINE_MEM" + + _memoryKeys.AddOrUpdate( + groupKey, + _ => new HashSet { memKey }, + (_, set) => { set.Add(memKey); return set; } + ); + // ✅ default serializer (fallback) serialize ??= (obj) => JsonConvert.SerializeObject(obj); deserialize ??= (str) => JsonConvert.DeserializeObject(str)!; // ✅ 1. MEMORY - if (_memoryCache.TryGetValue(memKey, out T cached)) + if (_cache.TryGetValue(memKey, out T cached)) { result = cached; source = "MEMORY"; @@ -540,24 +704,17 @@ namespace MP.SPEC.Data else { // ✅ 2. MISS → factory - result = await _memoryCache.GetOrCreateAsync(memKey, async entry => + result = await _cache.GetOrCreateAsync(memKey, async entry => { entry.AbsoluteExpirationRelativeToNow = memoryTtl; // 👉 REDIS - try - { - var rawData = await redisDb.StringGetAsync(redisKey); + var rawData = await redisDb.StringGetAsync(redisKey); - if (rawData.HasValue) - { - source = "REDIS"; - return deserialize(rawData!); - } - } - catch (Exception ex) + if (rawData.HasValue) { - LogTrace($"Redis error on {operationName}: {ex.Message}"); + source = "REDIS"; + return deserialize(rawData!); } // 👉 DB @@ -567,18 +724,11 @@ namespace MP.SPEC.Data var safeResult = dbResult == null ? default! : dbResult; - try - { - await redisDb.StringSetAsync( - redisKey, - serialize(safeResult), - getRandTOut(redisLongTimeCache) - ); - } - catch (Exception ex) - { - LogTrace($"Redis SET error on {operationName}: {ex.Message}"); - } + await redisDb.StringSetAsync( + redisKey, + serialize(safeResult), + getRandTOut(redisLongTimeCache) + ); return safeResult; })!; @@ -595,8 +745,64 @@ namespace MP.SPEC.Data LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds}ms"); return result; - } + } + /// + /// Invalidazione di una chiave in memoria e Redis + /// + /// + /// + /// + public async Task InvalidateCacheAsync(string memKey, string redisKey) + { + // ✅ memoria + _cache.Remove(memKey); + + // ✅ redis + await redisDb.KeyDeleteAsync(redisKey); + + LogTrace($"Cache invalidated | {memKey}"); + } + private readonly ConcurrentDictionary> _memoryKeys = new(); + /// + /// Invalidazione cache da pattern + /// + /// + /// + public async Task InvalidateCacheByPatternAsync(string pattern) + { + // ✅ MEMORY (pattern match semplice) + var keysToRemove = _memoryKeys.Keys + .Where(k => k.Contains(pattern.Replace("*", ""))) + .ToList(); + + foreach (var key in keysToRemove) + { + if (_memoryKeys.TryRemove(key, out var subKeys)) + { + foreach (var k in subKeys) + { + _cache.Remove(k); + } + } + } + + // ✅ REDIS + var masterEndpoint = redisConn.GetEndPoints() + .Where(ep => redisConn.GetServer(ep).IsConnected && !redisConn.GetServer(ep).IsReplica) + .FirstOrDefault(); + var server = redisConn.GetServer(masterEndpoint); + + var redisKeys = server.Keys(pattern: pattern); + + foreach (var rk in redisKeys) + { + await redisDb.KeyDeleteAsync(rk); + } + + LogTrace($"Cache invalidated by pattern | {pattern}"); + } +#endif /// /// Aggiornamento record selezionato @@ -1798,7 +2004,7 @@ namespace MP.SPEC.Data LogTrace($"MacchineGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; } - private readonly IMemoryCache _memoryCache; + private readonly IFusionCache _cache; /// /// Elenco di tutte le macchine filtrate x gruppo /// @@ -1811,16 +2017,27 @@ namespace MP.SPEC.Data string redisKey = $"{Utils.redisMacList}:{keyGrp}"; string memKey = $"MACCHINE_MEM:{keyGrp}"; - return await GetOrCreateCachedAsync( - operationName: "MacchineGetFiltAsync", - memKey: memKey, - redisKey: redisKey, - // ✅ TTL coerente con il tuo requisito (prima avevi 1 minuto) - memoryTtl: TimeSpan.FromMinutes(1), - dbFactory: async () => - await dbController.MacchineGetFiltAsync(codGruppo) + return await GetOrFetchAsync( + operationName: "MacchineGetFiltAsync", + cacheKey: redisKey, + expiration: TimeSpan.FromMinutes(5), + fetchFunc: async () => + await dbController.MacchineGetFiltAsync(codGruppo) ?? new List() - ); + ); + +#if false + return await GetOrCreateCachedAsync( + operationName: "MacchineGetFiltAsync", + memKey: memKey, + redisKey: redisKey, + // ✅ TTL coerente con il tuo requisito (prima avevi 1 minuto) + memoryTtl: TimeSpan.FromMinutes(1), + dbFactory: async () => + await dbController.MacchineGetFiltAsync(codGruppo) + ?? new List() + ); +#endif } #if false public async Task> MacchineGetFiltAsync(string codGruppo) @@ -2196,23 +2413,41 @@ namespace MP.SPEC.Data string redisKey = Utils.redisOdlCurrByMac; string memKey = $"MEM:{redisKey}"; - return await GetOrCreateCachedAsync( - operationName: "OdlGetCurrentAsync", - memKey: memKey, - redisKey: redisKey, - // ✅ TTL molto corto (come avevi: 3 secondi) - memoryTtl: TimeSpan.FromSeconds(3), - dbFactory: async () => - { - var rawData = await dbController.OdlGetCurrentAsync(); - var dbResult = rawData - .Select(x => x.IdxMacchina) - .Distinct() - .ToList(); + return await GetOrFetchAsync( + operationName: "OdlGetCurrentAsync", + cacheKey: redisKey, + expiration: TimeSpan.FromSeconds(3), + fetchFunc: async () => + { + var rawData = await dbController.OdlGetCurrentAsync(); + var dbResult = rawData + .Select(x => x.IdxMacchina) + .Distinct() + .ToList(); - return dbResult ?? new List(); - } - ); + return dbResult ?? new List(); + } + ); + +#if false + return await GetOrCreateCachedAsync( + operationName: "OdlGetCurrentAsync", + memKey: memKey, + redisKey: redisKey, + // ✅ TTL molto corto (come avevi: 3 secondi) + memoryTtl: TimeSpan.FromSeconds(3), + dbFactory: async () => + { + var rawData = await dbController.OdlGetCurrentAsync(); + var dbResult = rawData + .Select(x => x.IdxMacchina) + .Distinct() + .ToList(); + + return dbResult ?? new List(); + } + ); +#endif } #if false @@ -2658,18 +2893,16 @@ namespace MP.SPEC.Data /// public async Task> POdlToKitListGetFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) { - string currKey = $"{Utils.redisPOdlList}_kit:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; + string redisKey = $"{Utils.redisPOdlList}_kit:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; // ✅ stessa chiave per memoria (puoi anche prefissare) - string memKey = $"MEM:{currKey}"; + string memKey = $"MEM:{redisKey}"; - return await GetOrCreateCachedAsync( - operationName: "POdlToKitListGetFiltAsync", - memKey: memKey, - redisKey: currKey, - // ✅ TTL RAM breve (coerente con redisShortTimeCache) - memoryTtl: TimeSpan.FromSeconds(redisShortTimeCache), - dbFactory: async () => + return await GetOrFetchAsync( + operationName: "POdlToKitListGetFiltAsync", + cacheKey: redisKey, + expiration: TimeSpan.FromSeconds(redisShortTimeCache), + fetchFunc: async () => await dbController.ListPODL_KitFiltAsync( lanciato, keyRichPart, @@ -2678,7 +2911,26 @@ namespace MP.SPEC.Data startDate, endDate ) ?? new List() - ); + ); + +#if false + return await GetOrCreateCachedAsync( + operationName: "POdlToKitListGetFiltAsync", + memKey: memKey, + redisKey: redisKey, + // ✅ TTL RAM breve (coerente con redisShortTimeCache) + memoryTtl: TimeSpan.FromSeconds(redisShortTimeCache), + dbFactory: async () => + await dbController.ListPODL_KitFiltAsync( + lanciato, + keyRichPart, + idxMacchina, + codGruppo, + startDate, + endDate + ) ?? new List() + ); +#endif } #if false public async Task> POdlToKitListGetFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 8ce4107b..66b09440 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2619 + 8.16.2605.2708 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en @@ -42,6 +42,7 @@ + @@ -52,6 +53,9 @@ + + + diff --git a/MP.SPEC/Program.cs b/MP.SPEC/Program.cs index 5b8365ff..4209457e 100644 --- a/MP.SPEC/Program.cs +++ b/MP.SPEC/Program.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Authentication.Negotiate; using Microsoft.AspNetCore.StaticFiles; +using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.FileProviders; using MP.AppAuth.Services; using MP.Data.Services; @@ -12,7 +13,9 @@ using NLog.Web; using OpenTelemetry.Resources; using OpenTelemetry.Trace; using StackExchange.Redis; - +using ZiggyCreatures.Caching.Fusion; +using ZiggyCreatures.Caching.Fusion.Backplane.StackExchangeRedis; +using ZiggyCreatures.Caching.Fusion.Serialization.NewtonsoftJson; var builder = WebApplication.CreateBuilder(args); @@ -30,7 +33,7 @@ string connStringRedis = configuration.GetConnectionString("Redis") ?? "localhos //string connStringRedis = ConfMan.GetConnectionString("RedisAdmin"); string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":")); // avvio oggetto shared x redis... -var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); +IConnectionMultiplexer redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); // ==================================================================== @@ -135,9 +138,24 @@ builder.Services.AddRazorComponents() builder.Services.AddRazorPages(); // memory + redis preliminare -builder.Services.AddMemoryCache(); builder.Services.AddSingleton(redisMultiplexer); +// ✅ Distributed cache (necessario per FusionCache) +builder.Services.AddStackExchangeRedisCache(options => +{ + options.Configuration = connStringRedis; +}); + +// ✅ FusionCache +builder.Services.AddFusionCache() + .WithDistributedCache(sp => sp.GetRequiredService()) + .WithSerializer(new FusionCacheNewtonsoftJsonSerializer()) + .WithBackplane(new RedisBackplane(new RedisBackplaneOptions + { + ConnectionMultiplexerFactory = () => Task.FromResult(redisMultiplexer) + })); + + // altri servizi builder.Services.AddSingleton(); builder.Services.AddSingleton(); diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index dca5987a..59e7e6d9 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

              Versione: 8.16.2605.2619

              +

              Versione: 8.16.2605.2708


              Note di rilascio:
              • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 5ea9eaa9..933735f6 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2619 +8.16.2605.2708 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index b079c1c6..02e7a70d 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2619 + 8.16.2605.2708 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/appsettings.json b/MP.SPEC/appsettings.json index bf3f1ae9..712e6fcb 100644 --- a/MP.SPEC/appsettings.json +++ b/MP.SPEC/appsettings.json @@ -2,7 +2,8 @@ "Logging": { "LogLevel": { "Default": "Information", - "Microsoft.AspNetCore": "Warning" + "Microsoft.AspNetCore": "Warning", + "ZiggyCreatures.Caching.Fusion": "Warning" } }, "NLog": { From 1eb51852405f1ba12016a2c699332aadc312ae99 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 09:46:55 +0200 Subject: [PATCH 010/102] Continuo refactor con cache Fusion --- MP.Data/Controllers/MpSpecController.cs | 24 +++++++++- MP.SPEC/Components/CmpTop.razor.cs | 4 +- MP.SPEC/Data/MpDataService.cs | 13 +++-- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Articoli.razor.cs | 2 +- MP.SPEC/Pages/PODL.razor.cs | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- refactor_spec.md | 63 +++++++++++++++++++++++++ 10 files changed, 100 insertions(+), 16 deletions(-) create mode 100644 refactor_spec.md diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index cb8d41ef..5c39a619 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -164,9 +164,9 @@ namespace MP.Data.Controllers /// Elenco Gruppi tipo Azienda ///
              /// - public List AnagGruppiAziende() + public Task> AnagGruppiAziendeAsync() { - return AnagGruppiGetTipo("AZIENDA"); + return AnagGruppiGetTipoAsync("AZIENDA"); } /// @@ -241,6 +241,26 @@ namespace MP.Data.Controllers return dbResult; } + /// + /// Gruppi x tipo modalità Async + /// + /// + /// + public async Task> AnagGruppiGetTipoAsync(string tipoGruppo) + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(options)) + { + dbResult = await dbCtx + .DbSetAnagGruppi + .Where(x => x.TipoGruppo == tipoGruppo) + .AsNoTracking() + .OrderBy(x => x.CodGruppo) + .ToListAsync(); + } + return dbResult; + } + /// /// Elenco Gruppi tipo REPARTO (x associazione Macchine-Operatori) /// diff --git a/MP.SPEC/Components/CmpTop.razor.cs b/MP.SPEC/Components/CmpTop.razor.cs index c7d26602..593b6a6a 100644 --- a/MP.SPEC/Components/CmpTop.razor.cs +++ b/MP.SPEC/Components/CmpTop.razor.cs @@ -1,12 +1,9 @@ -using Amazon.Runtime.Internal.Endpoints.StandardLibrary; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Authorization; -using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.JSInterop; using MP.AppAuth.Services; using MP.SPEC.Data; using MP.SPEC.Extensions; -using System; namespace MP.SPEC.Components { @@ -56,6 +53,7 @@ namespace MP.SPEC.Components protected async Task FlushCache() { await MDService.FlushRedisCache(); + await MDService.FlushCacheAsync(); await ForceReload(); // rimando a pagina corrente NavManager.NavigateTo(NavManager.Uri, true); diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 8370b7cf..6cc2b305 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -306,7 +306,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "AnagStatiCommAsync", cacheKey: Utils.redisStatoCom, - expiration: TimeSpan.FromMinutes(5), + expiration: TimeSpan.FromMinutes(redisLongTimeCache), fetchFunc: async () => await dbController.AnagStatiCommAsync() ?? new List() ); @@ -633,6 +633,7 @@ namespace MP.SPEC.Data { bool fatto = false; await _cache.ClearAsync(); + _configData.Clear(); fatto = true; return fatto; } @@ -648,6 +649,7 @@ namespace MP.SPEC.Data { await _cache.RemoveByTagAsync(item); } + _configData.Clear(); fatto = true; return fatto; } @@ -659,6 +661,7 @@ namespace MP.SPEC.Data { bool fatto = false; await _cache.RemoveByTagAsync(tag); + _configData.Clear(); fatto = true; return fatto; } @@ -1198,14 +1201,14 @@ namespace MP.SPEC.Data /// Restitusice elenco aziende /// /// - public List ElencoAziende() + public async Task> ElencoAziendeAsync() { - using var activity = ActivitySource.StartActivity("ElencoAziende"); + using var activity = ActivitySource.StartActivity("ElencoAziendeAsync"); string source = "DB"; - var listAz = dbController.AnagGruppiAziende(); + var listAz = await dbController.AnagGruppiAziendeAsync(); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ElencoAziende | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ElencoAziendeAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return listAz; } diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 66b09440..26cb8e72 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2708 + 8.16.2605.2709 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Articoli.razor.cs b/MP.SPEC/Pages/Articoli.razor.cs index 008bbc19..accea5f3 100644 --- a/MP.SPEC/Pages/Articoli.razor.cs +++ b/MP.SPEC/Pages/Articoli.razor.cs @@ -176,7 +176,7 @@ namespace MP.SPEC.Pages { selAzienda = "*"; } - ListAziende = MDService.ElencoAziende(); + ListAziende = await MDService.ElencoAziendeAsync(); ListTipoArt = await MDService.AnagTipoArtLV(); } diff --git a/MP.SPEC/Pages/PODL.razor.cs b/MP.SPEC/Pages/PODL.razor.cs index 23054a1a..aaf0d96c 100644 --- a/MP.SPEC/Pages/PODL.razor.cs +++ b/MP.SPEC/Pages/PODL.razor.cs @@ -129,7 +129,7 @@ namespace MP.SPEC.Pages protected override async Task OnInitializedAsync() { await getReparto(); - ListAziende = MDService.ElencoAziende(); + ListAziende = await MDService.ElencoAziendeAsync(); var allGruppiData = MDService.ElencoGruppiFase(); if (allGruppiData != null) { diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 59e7e6d9..ff33fc09 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

              Versione: 8.16.2605.2708

              +

              Versione: 8.16.2605.2709


              Note di rilascio:
              • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 933735f6..0dfa7efa 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2708 +8.16.2605.2709 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 02e7a70d..dcbc0eb7 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2708 + 8.16.2605.2709 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/refactor_spec.md b/refactor_spec.md new file mode 100644 index 00000000..2b8a587c --- /dev/null +++ b/refactor_spec.md @@ -0,0 +1,63 @@ +# Refactoring Plan: MpDataService Cache Layer Upgrade + +## Objective +Migrate all data access methods in `MpDataService.cs` to use the unified multi-level cache stack (IMemoryCache via `IFusionCache` + Redis + DB) using the `GetOrFetchAsync` pattern. + +## Current State +- Some methods use a manual "Redis + DB" approach (checking `redisDb.StringGet`, deserializing, and then `StringSet` on miss). +- Some methods use the new `GetOrFetchAsync` pattern (Memory + Redis + DB). +- `GetOrFetchAsync` leverages `IFusionCache`, which handles the multi-level complexity and provides better resiliency (fail-safe). + +## Target Pattern: `GetOrFetchAsync` +All read methods should be refactored to: +1. Use `GetOrFetchAsync` to abstract cache management. +2. Define a `cacheKey` (typically matching the existing Redis key). +3. Provide an `expiration` (TimeSpan). +4. Provide a `fetchFunc` that calls the `dbController` method. + +## Proposed Work Items + +### 1. Analysis & Categorization +Identify all methods in `MpDataService.cs` that currently implement manual Redis caching. + +**Candidates for Refactoring (Redis + DB -> Multi-level):** +- `AnagEventiGeneral` (Lines 166-195) +- `AnagEventiGetByMacch` (Lines 201-230) +- `AnagKeyValGetAll` (Lines 273-302) +- `AnagTipoArtLV` (Lines 347-375) +- `ArticleWithDossier` (Lines 381-410) +- `ConfigGetAll` (Lines 907-936) +- `ConfigGetAllAsync` (Lines 943-970) +- `DbDedupStats` (Lines 1046-1067) +- `ElencoGruppiFase` (Lines 1216-1249) +- `ElencoRepartiDTO` (Lines 1267-1303) +- `FluxLogGetLastFilt` (Lines 1569-1605) +- `FluxLogPareto` (Lines 1609-1640) +- `MacchineRecipeArchive` (Lines 2100-2128) +- `MacchineRecipeConf` (Lines 2131-2163) +- `MacchineWithFlux` (Lines 2171-2200) +- `OdlByBatch` (Lines 2308-2336) +- `OdlListAll` (Lines 2490-2499) - *Currently no cache, needs addition?* +- `OdlListGetFilt` (Lines 2513-2542) +- `OperatoriGetFilt` (Lines 2549-2577) +- `ParametriGetFilt` (Lines 2585-2614) +- `POdlGetByKey` (Lines 2658-2697) +- `POdlGetByOdl` (Lines 2705-2744) +- `POdlListByKitParent` (Lines 2770-2800) +- `POdlListGetFilt` (Lines 2812-2841) +- `TksScore` (Lines 3343-3372) +- `VocabolarioGetAll` (Lines 3445-3477) +- `WipKitFilt` (Lines 3543-3570) + +### 2. Implementation Steps +For each candidate method: +1. **Convert to Async**: If the method is synchronous (e.g., `AnagEventiGeneral`), convert it to `Task` to match the `GetOrFetchAsync` signature. +2. **Map Keys**: Ensure the `cacheKey` passed to `GetOrFetchAsync` is identical to the old Redis key to prevent cache fragmentation. +3. **Set Expiration**: Use appropriate `TimeSpan` (e.g., `redisLongTimeCache` or `redisShortTimeCache` converted to `TimeSpan`). +4. **Cleanup**: Remove manual `JsonConvert` logic and `redisDb.StringGet/Set` calls. +5. **Verify Tracing**: Ensure `ActivitySource` and `LogTrace` are preserved or integrated within the `GetOrFetchAsync` wrapper. + +### 3. Validation +- Ensure all refactored methods are still called correctly by consumers. +- Verify that `GetOrFetchAsync` correctly hits Memory first, then Redis, then DB. +- Confirm that `LogTrace` still reports the correct source (MEMORY, REDIS, or DB). From e328c4e6f1360857880c9a743986a2e21ca3c7da Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 12:00:15 +0200 Subject: [PATCH 011/102] Fix metodi accesso dati SPEC con assistant --- MP.Core/DTO/CountResultDto.cs | 7 + MP.Data/Controllers/MpSpecController.cs | 93 +++- MP.Data/MoonProContext.cs | 6 + MP.SPEC/Data/MpDataService.cs | 569 +++++++----------------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Articoli.razor.cs | 163 ++++--- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 9 files changed, 351 insertions(+), 495 deletions(-) create mode 100644 MP.Core/DTO/CountResultDto.cs diff --git a/MP.Core/DTO/CountResultDto.cs b/MP.Core/DTO/CountResultDto.cs new file mode 100644 index 00000000..c55a390b --- /dev/null +++ b/MP.Core/DTO/CountResultDto.cs @@ -0,0 +1,7 @@ +namespace MP.Core.DTO +{ + public class CountResultDto + { + public int NumCount { get; set; } + } +} diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 5c39a619..96be09c7 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -371,9 +371,9 @@ namespace MP.Data.Controllers /// Elenco valori ammessi x Tipo articoli ///
              /// - public List AnagTipoArtLV() + public Task> AnagTipoArtLvAsync() { - return ListValuesFilt("AnagArticoli", "Tipo"); + return ListValuesFiltAsync("AnagArticoli", "Tipo"); } /// @@ -395,6 +395,35 @@ namespace MP.Data.Controllers return dbResult; } + /// + /// Conteggio num articoli Async + /// + /// + public async Task ArticoliCountAsync() + { + using var dbCtx = new MoonProContext(options); + var result = await dbCtx + .DbSetArticoli + .CountAsync(); + return result; + } + + /// + /// Elenco tabella Articoli IMPIEGATI (da stored stp_ART_getUsed) Async + /// + /// + public async Task ArticoliCountUsedAsync() + { + using var dbCtx = new MoonProContext(options); + var result = await dbCtx + .DbSetCounter + .FromSqlRaw("EXEC stp_ART_CountUsed") + .AsNoTracking() + .ToListAsync(); + + return result.FirstOrDefault()?.NumCount ?? 0; + } + /// /// Eliminazione Record /// @@ -492,6 +521,24 @@ namespace MP.Data.Controllers return dbResult; } + /// + /// Elenco tabella Articoli NON IMPIEGATI (da stored stp_ART_getUsed) Async + /// + /// + public async Task> ArticoliGetUnusedAsync() + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(options)) + { + dbResult = await dbCtx + .DbSetArticoli + .FromSqlRaw("EXEC stp_ART_getNotUsed") + .AsNoTracking() + .ToListAsync(); + } + return dbResult; + } + /// /// Elenco tabella Articoli IMPIEGATI (da stored stp_ART_getUsed) /// @@ -510,6 +557,24 @@ namespace MP.Data.Controllers return dbResult; } + /// + /// Elenco tabella Articoli IMPIEGATI (da stored stp_ART_getUsed) Async + /// + /// + public async Task> ArticoliGetUsedAsync() + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(options)) + { + dbResult = await dbCtx + .DbSetArticoli + .FromSqlRaw("EXEC stp_ART_getUsed") + .AsNoTracking() + .ToListAsync(); + } + return dbResult; + } + /// /// Update Record /// @@ -569,6 +634,24 @@ namespace MP.Data.Controllers return dbResult; } + /// + /// Elenco da tabella Config Async + /// + /// + public async Task> ConfigGetAllAsync() + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(options)) + { + dbResult = await dbCtx + .DbSetConfig + .AsNoTracking() + .OrderBy(x => x.Chiave) + .ToListAsync(); + } + return dbResult; + } + /// /// Update record config /// @@ -1435,6 +1518,7 @@ namespace MP.Data.Controllers } return dbResult; } + /// /// Elenco PODL per composizione KIT non avviati filtrati x articolo, KeyRich (che contiene stato) /// @@ -1492,6 +1576,7 @@ namespace MP.Data.Controllers } return dbResult; } + /// /// Elenco PODL non avviati filtrati x articolo, KeyRich (che contiene stato) - ASYNC /// @@ -1521,6 +1606,7 @@ namespace MP.Data.Controllers return dbResult; } +#if false /// /// Elenco valori ammessi x tabella/colonna /// @@ -1540,7 +1626,8 @@ namespace MP.Data.Controllers .ToList(); } return dbResult; - } + } +#endif /// /// Elenco valori ammessi x tabella/colonna Async diff --git a/MP.Data/MoonProContext.cs b/MP.Data/MoonProContext.cs index 0d65c590..2789eb05 100644 --- a/MP.Data/MoonProContext.cs +++ b/MP.Data/MoonProContext.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; +using MP.Core.DTO; using MP.Data.DbModels; using MP.Data.DbModels.Anag; using NLog; @@ -41,6 +42,7 @@ namespace MP.Data #region Public Properties + public virtual DbSet DbSetCounter { get; set; } public virtual DbSet DbSetDbSize { get; set; } public virtual DbSet DbSetAlarmLog { get; set; } @@ -155,6 +157,10 @@ namespace MP.Data { modelBuilder.HasAnnotation("Relational:Collation", "SQL_Latin1_General_CP1_CI_AS"); + + modelBuilder.Entity().HasNoKey(); + + modelBuilder.Entity(entity => { entity.HasKey(e => e.CodArticolo); diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 6cc2b305..14939557 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -82,20 +82,18 @@ namespace MP.SPEC.Data #endregion Public Events #region Public Properties - public static MpSpecController dbController { get; set; } = null!; - public static MpMongoController mongoController { get; set; } = null!; - public MessagePipe BroadastMsgPipe { get; set; } = null!; - - /// - /// Dizionario dei tag configurati per IOB - /// public Dictionary> currTagConf { get; set; } = new Dictionary>(); + // Cache per controllo eliminazione articoli (Smart HashSet approach) + private HashSet _usedArtIdsCache = new(); + private HashSet _unusedArtIdsCache = new(); + private DateTime _artCacheExpiry = DateTime.MinValue; #endregion Public Properties + #region Public Methods /// @@ -312,41 +310,9 @@ namespace MP.SPEC.Data ); } -#if false - public async Task> AnagStatiComm() + public async Task> AnagTipoArtLvAsync() { - using var activity = ActivitySource.StartActivity("AnagStatiComm"); - string source = "DB"; - List? result = new List(); - // cerco in redis... - RedisValue rawData = await redisDb.StringGetAsync(Utils.redisStatoCom); - if (!string.IsNullOrEmpty($"{rawData}")) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await Task.FromResult(dbController.AnagStatiComm()); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(Utils.redisStatoCom, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"AnagStatiComm Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; - } -#endif - - public async Task> AnagTipoArtLV() - { - using var activity = ActivitySource.StartActivity("AnagStatiCommAsync"); + using var activity = ActivitySource.StartActivity("AnagTipoArtLvAsync"); string source = "DB"; List? result = new List(); // cerco in redis... @@ -358,7 +324,7 @@ namespace MP.SPEC.Data } else { - result = await Task.FromResult(dbController.AnagTipoArtLV()); + result = await dbController.AnagTipoArtLvAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(Utils.redisTipoArt, rawData, getRandTOut(redisLongTimeCache)); @@ -370,7 +336,7 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.SetTag("result.count", result.Count); activity?.Stop(); - LogTrace($"AnagTipoArtLV Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"AnagTipoArtLvAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; } @@ -437,7 +403,6 @@ namespace MP.SPEC.Data string sKey = string.IsNullOrWhiteSpace(tipo) ? "ALL" : tipo.Trim(); string redisKey = $"{Utils.redisArtList}:{azienda}:Tipo:{sKey}"; - string memKey = $"MEM:{redisKey}"; return await GetOrFetchAsync( operationName: "ArticoliGetByTipoAsync", @@ -448,53 +413,7 @@ namespace MP.SPEC.Data ?? new List() ); - -#if false - return await GetOrCreateCachedAsync( - operationName: "ArticoliGetByTipoAsync", - memKey: memKey, - redisKey: redisKey, - // ✅ TTL lungo (dato abbastanza statico) - memoryTtl: TimeSpan.FromMinutes(5), - dbFactory: async () => - await dbController.ArticoliGetByTipoAsync(tipo, azienda) - ?? new List() - ); -#endif } -#if false - public async Task> ArticoliGetByTipoAsync(string tipo, string azienda = "*") - { - using var activity = ActivitySource.StartActivity("ArticoliGetByTipoAsync"); - List? result = new List(); - string source = "DB"; - string sKey = string.IsNullOrEmpty(tipo) ? "ALL" : tipo; - string currKey = $"{Utils.redisArtList}:{azienda}:Tipo:{sKey}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.ArticoliGetByTipoAsync(tipo, azienda); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"ArticoliGetByTipoAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; - } -#endif /// /// Restitusice elenco articoli cercati @@ -517,18 +436,6 @@ namespace MP.SPEC.Data await dbController.ArticoliGetSearchAsync(numRecord, azienda, searchVal) ?? new List() ); - -#if false - return await GetOrCreateCachedAsync( - operationName: "ArticoliGetSearchAsync", - memKey: memKey, - redisKey: redisKey, - memoryTtl: TimeSpan.FromMinutes(2), - dbFactory: async () => - await dbController.ArticoliGetSearchAsync(numRecord, azienda, searchVal) - ?? new List() - ); -#endif } /// @@ -550,6 +457,7 @@ namespace MP.SPEC.Data var result = tryGet.Value!; activity?.SetTag("data.source", source); + activity?.Stop(); LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); return result; } @@ -573,57 +481,11 @@ namespace MP.SPEC.Data source = fromDb ? "DB" : "REDIS"; activity?.SetTag("data.source", source); + activity?.Stop(); LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); return final!; } -#if false - private async Task GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration) - { - using var activity = ActivitySource.StartActivity(operationName); - - string source; - T result; - - // ✅ 1. Tenta MEMORY / DISTRIBUTED (senza factory) - var memTry = await _cache.TryGetAsync(cacheKey); - - if (memTry.HasValue) - { - result = memTry.Value!; - source = "MEMORY"; - } - else - { - bool fromDb = false; - - // ✅ 2. fallback con factory - result = await _cache.GetOrSetAsync( - cacheKey, - async _ => - { - fromDb = true; - return await fetchFunc(); - }, - options => options.SetDuration(expiration) - )!; - - source = fromDb ? "DB" : "REDIS"; - } - - // ✅ tracing e log - activity?.SetTag("data.source", source); - - if (result is System.Collections.ICollection coll) - activity?.SetTag("result.count", coll.Count); - else - activity?.SetTag("result.count", result != null ? 1 : 0); - - LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); - - return result; - } -#endif /// /// Cancellazione FusionCache (totale) @@ -666,146 +528,6 @@ namespace MP.SPEC.Data return fatto; } -#if false - /// - /// Helper per gestione cache a 3 livelli: MEMORY, REDIS e DB con opzioni - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - private async Task GetOrCreateCachedAsync(string operationName, string memKey, string redisKey, TimeSpan memoryTtl, Func> dbFactory, Func? serialize = null, Func? deserialize = null) - { - using var activity = ActivitySource.StartActivity(operationName); - - string source = "NA"; - T result; - - string groupKey = memKey.Split(':')[0]; // es: "MACCHINE_MEM" - - _memoryKeys.AddOrUpdate( - groupKey, - _ => new HashSet { memKey }, - (_, set) => { set.Add(memKey); return set; } - ); - - // ✅ default serializer (fallback) - serialize ??= (obj) => JsonConvert.SerializeObject(obj); - deserialize ??= (str) => JsonConvert.DeserializeObject(str)!; - - // ✅ 1. MEMORY - if (_cache.TryGetValue(memKey, out T cached)) - { - result = cached; - source = "MEMORY"; - } - else - { - // ✅ 2. MISS → factory - result = await _cache.GetOrCreateAsync(memKey, async entry => - { - entry.AbsoluteExpirationRelativeToNow = memoryTtl; - - // 👉 REDIS - var rawData = await redisDb.StringGetAsync(redisKey); - - if (rawData.HasValue) - { - source = "REDIS"; - return deserialize(rawData!); - } - - // 👉 DB - source = "DB"; - - var dbResult = await dbFactory(); - - var safeResult = dbResult == null ? default! : dbResult; - - await redisDb.StringSetAsync( - redisKey, - serialize(safeResult), - getRandTOut(redisLongTimeCache) - ); - - return safeResult; - })!; - } - - // ✅ logging e tracing centralizzati - activity?.SetTag("data.source", source); - - if (result is System.Collections.ICollection coll) - activity?.SetTag("result.count", coll.Count); - else - activity?.SetTag("result.count", result != null ? 1 : 0); - - LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds}ms"); - - return result; - } - - /// - /// Invalidazione di una chiave in memoria e Redis - /// - /// - /// - /// - public async Task InvalidateCacheAsync(string memKey, string redisKey) - { - // ✅ memoria - _cache.Remove(memKey); - - // ✅ redis - await redisDb.KeyDeleteAsync(redisKey); - - LogTrace($"Cache invalidated | {memKey}"); - } - private readonly ConcurrentDictionary> _memoryKeys = new(); - /// - /// Invalidazione cache da pattern - /// - /// - /// - public async Task InvalidateCacheByPatternAsync(string pattern) - { - // ✅ MEMORY (pattern match semplice) - var keysToRemove = _memoryKeys.Keys - .Where(k => k.Contains(pattern.Replace("*", ""))) - .ToList(); - - foreach (var key in keysToRemove) - { - if (_memoryKeys.TryRemove(key, out var subKeys)) - { - foreach (var k in subKeys) - { - _cache.Remove(k); - } - } - } - - // ✅ REDIS - var masterEndpoint = redisConn.GetEndPoints() - .Where(ep => redisConn.GetServer(ep).IsConnected && !redisConn.GetServer(ep).IsReplica) - .FirstOrDefault(); - var server = redisConn.GetServer(masterEndpoint); - - var redisKeys = server.Keys(pattern: pattern); - - foreach (var rk in redisKeys) - { - await redisDb.KeyDeleteAsync(rk); - } - - LogTrace($"Cache invalidated by pattern | {pattern}"); - } -#endif /// /// Aggiornamento record selezionato @@ -824,6 +546,7 @@ namespace MP.SPEC.Data return fatto; } + /// /// Verifica se sia possiubile cancellare articolo dato suo CodArt cercando su redis o su /// tab veto da DB @@ -833,69 +556,160 @@ namespace MP.SPEC.Data public bool ArticoloDelEnabled(object CodArt) { using var activity = ActivitySource.StartActivity("ArticoloDelEnabled"); - string source = "DB"; - bool answ = false; string codArticolo = $"{CodArt}"; - int cacheCheckArtUsato = 1; - int.TryParse(_configuration.GetValue("ServerConf:cacheCheckArtUsato"), out cacheCheckArtUsato); - TimeSpan TTLCache = getRandTOut(cacheCheckArtUsato); - // cerco in cache redis... - string redKeyArtUsed = $"{Utils.redKeyArtUsed}:{codArticolo}"; - string redKeyTabCheckArt = Utils.redKeyTabCheckArt; - var rawData = redisDb.StringGet(redKeyArtUsed); - if (!string.IsNullOrEmpty(rawData)) + + int numUsed = _usedArtIdsCache.Count; + int numUnused = _unusedArtIdsCache.Count; + bool usato = true; + string source = "MEMORY"; + // 1. Controllo immediato sulla cache locale (HashSet) x eventuale refresh + if (DateTime.Now >= _artCacheExpiry || (numUsed + numUnused) <= 0) { - bool.TryParse(rawData, out answ); + source = "DB/REDIS"; + // Fallback sincrono minimo per non rompere il componente Blazor + // Nota: Questo è un workaround per la firma sincrona. + var task = EnsureArtCacheLoadedAsync(false); + task.Wait(); + + // rileggo + numUsed = _usedArtIdsCache.Count; + numUnused = _unusedArtIdsCache.Count; + } + + // verifico quale sia l'elenco + if (numUsed > 0) + { + usato = _usedArtIdsCache.Contains(codArticolo); } else { - // controllo non sia stato mai prodotto sennò non posso cancellare... - try - { - // cerco in cache se ci sia la tabella con gli articoli impiegati... - var rawTable = redisDb.StringGet(redKeyTabCheckArt); - List? artList = new List(); - if (!string.IsNullOrEmpty(rawTable)) - { - artList = JsonConvert.DeserializeObject>($"{rawTable}"); - } - // rileggo... - if (artList == null || artList.Count == 0) - { - artList = new List(); - var tabArticoli = dbController.ArticoliGetUsed(); - var codList = tabArticoli.Select(x => x.CodArticolo); - foreach (string cod in codList) - { - artList.Add(cod); - } - // SE fosse vuoto aggiungo comunque il cado "ND"... - if (artList.Count == 0) - { - artList.Add("ND"); - } - // salvo - rawTable = JsonConvert.SerializeObject(artList); - redisDb.StringSet(redKeyTabCheckArt, rawTable, TTLCache); - } - // cerco nella tabella: se ci fosse --> disabilitato delete - bool usato = false; - if (artList != null && artList.Count > 0) - { - usato = artList.Contains(codArticolo); - } - answ = !usato; - redisDb.StringSet(redKeyArtUsed, $"{answ}", TTLCache); - } - catch - { } + usato = !_unusedArtIdsCache.Contains(codArticolo); } + activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ArticoloDelEnabled | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return answ; + LogTrace($"ArticoloDelEnabled | Cod: {codArticolo} | Source: {source}"); + return !usato; } + /// + /// Caricamento asincrono della cache degli articoli (Used/Unused) + /// + public async Task EnsureArtCacheLoadedAsync(bool forceReload) + { + if (!forceReload && (DateTime.Now < _artCacheExpiry && (_usedArtIdsCache.Count > 0 || _unusedArtIdsCache.Count > 0))) + return; + + try + { + // verifico quale sia il set + piccolo + int totalCount = await dbController.ArticoliCountAsync(); + int usedCount = await dbController.ArticoliCountUsedAsync(); + + if (usedCount <= (totalCount - usedCount)) + { + var usedList = await dbController.ArticoliGetUsedAsync(); + _usedArtIdsCache = new HashSet(usedList.Select(x => x.CodArticolo)); + _unusedArtIdsCache.Clear(); + } + else + { + var unusedList = await dbController.ArticoliGetUnusedAsync(); + _unusedArtIdsCache = new HashSet(unusedList.Select(x => x.CodArticolo)); + _usedArtIdsCache.Clear(); + } + _artCacheExpiry = DateTime.Now.AddMinutes(15); // TTL ragionevole per la cache locale + } + catch (Exception ex) + { + Log.Error($"Errore nel caricamento cache articoli: {ex.Message}"); + _artCacheExpiry = DateTime.Now.AddSeconds(1); // Retry breve in caso di errore + } + } + +#if false + /// + /// Verifica se sia possiubile cancellare articolo dato suo CodArt cercando su redis o su + /// tab veto da DB + /// + /// + /// + public async Task ArticoloDelEnabledAsync(object CodArt) + { + using var activity = ActivitySource.StartActivity("ArticoloDelEnabledAsync"); + string codArticolo = $"{CodArt}"; + + int cacheCheckArtUsato = 1; + int.TryParse(_configuration.GetValue("ServerConf:cacheCheckArtUsato"), out cacheCheckArtUsato); + TimeSpan ttl = getRandTOut(cacheCheckArtUsato); + + // 1. Controllo cache locale (Smart HashSet) + // Se siamo nel periodo di validità della cache locale, facciamo il controllo istantaneo + if (DateTime.Now < _artCacheExpiry) + { + // Se la nostra cache corrente contiene l'ID (o se stiamo usando la lista degli unused) + // Nota: la logica dipende da quale lista è stata caricata. + // Per semplicità, se abbiamo caricato gli "usati", cerchiamo tra quelli. + // Se abbiamo caricato gli "unused", l'articolo è eliminabile se è nel set. + // Ma per evitare confusione, gestiamo il refresh globale. + } + + // 2. Fallback su GetOrFetchAsync per garantire la sincronizzazione e l'uso di FusionCache (L1/L2) + // Usiamo un approccio che carichi la lista più piccola in memoria. + + // Per evitare complessità di switching lato client, usiamo la lista degli "usati" come riferimento + // principale nella cache distribuita, ma ottimizziamo il caricamento. + + bool usato = false; + string source = "DB"; + + // Controllo se l'ID è già presente nella nostra cache locale degli "usati" + if (DateTime.Now < _artCacheExpiry && _usedArtIdsCache.Contains(codArticolo)) + { + usato = true; + source = "MEMORY(USED)"; + } + else if (DateTime.Now < _artCacheExpiry && _unusedArtIdsCache.Contains(codArticolo)) + { + usato = false; + source = "MEMORY(UNUSED)"; + } + else + { + // Cache scaduta o non presente: ricalcoliamo la strategia + int totalCount = await dbController.ArticoliCountAsync(); + int usedCount = await dbController.ArticoliCountUsedAsync(); + + if (usedCount <= (totalCount - usedCount)) + { + // Gli usati sono meno o uguali agli unused: carichiamo gli usati + var usedList = await dbController.ArticoliGetUsedAsync(); + _usedArtIdsCache = new HashSet(usedList.Select(x => x.CodArticolo)); + _unusedArtIdsCache.Clear(); + usato = _usedArtIdsCache.Contains(codArticolo); + source = "DB+MEMORY(USED)"; + } + else + { + // Gli unused sono meno: carichiamo gli unused + var unusedList = await dbController.ArticoliGetUnusedAsync(); + _unusedArtIdsCache = new HashSet(unusedList.Select(x => x.CodArticolo)); + _usedArtIdsCache.Clear(); + usato = !_unusedArtIdsCache.Contains(codArticolo); + source = "DB+MEMORY(UNUSED)"; + } + _artCacheExpiry = DateTime.Now.AddMinutes(cacheCheckArtUsato); + } + + bool answ = !usato; + + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"ArticoloDelEnabledAsync | Cod: {codArticolo} | Usato: {usato} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } +#endif + public string CalcRecipe(RecipeModel currRecipe) { using var activity = ActivitySource.StartActivity("CalcRecipe"); @@ -956,7 +770,7 @@ namespace MP.SPEC.Data } else { - result = await Task.FromResult(dbController.ConfigGetAll()); + result = await dbController.ConfigGetAllAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(Utils.redisConfKey, rawData, getRandTOut(redisLongTimeCache)); @@ -1198,18 +1012,18 @@ namespace MP.SPEC.Data } /// - /// Restitusice elenco aziende + /// Restituisce elenco aziende /// /// public async Task> ElencoAziendeAsync() { - using var activity = ActivitySource.StartActivity("ElencoAziendeAsync"); - string source = "DB"; - var listAz = await dbController.AnagGruppiAziendeAsync(); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"ElencoAziendeAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return listAz; + return await GetOrFetchAsync( + operationName: "ElencoAziendeAsync", + cacheKey: $"{Utils.redisAnagGruppi}:Aziende", + expiration: TimeSpan.FromMinutes(redisLongTimeCache * 2), + fetchFunc: async () => + await dbController.AnagGruppiAziendeAsync() ?? new List() + ); } /// @@ -2898,9 +2712,6 @@ namespace MP.SPEC.Data { string redisKey = $"{Utils.redisPOdlList}_kit:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; - // ✅ stessa chiave per memoria (puoi anche prefissare) - string memKey = $"MEM:{redisKey}"; - return await GetOrFetchAsync( operationName: "POdlToKitListGetFiltAsync", cacheKey: redisKey, @@ -2916,57 +2727,7 @@ namespace MP.SPEC.Data ) ?? new List() ); -#if false - return await GetOrCreateCachedAsync( - operationName: "POdlToKitListGetFiltAsync", - memKey: memKey, - redisKey: redisKey, - // ✅ TTL RAM breve (coerente con redisShortTimeCache) - memoryTtl: TimeSpan.FromSeconds(redisShortTimeCache), - dbFactory: async () => - await dbController.ListPODL_KitFiltAsync( - lanciato, - keyRichPart, - idxMacchina, - codGruppo, - startDate, - endDate - ) ?? new List() - ); -#endif } -#if false - public async Task> POdlToKitListGetFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) - { - using var activity = ActivitySource.StartActivity("POdlToKitListGetFiltAsync"); - List? result = new List(); - string source = "DB"; - string currKey = $"{Utils.redisPOdlList}_kit:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.ListPODL_KitFiltAsync(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"POdlToKitListGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; - } -#endif /// /// Chiamata salvataggio ricetta + refresh REDIS diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 26cb8e72..03db7fb4 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2709 + 8.16.2605.2711 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Articoli.razor.cs b/MP.SPEC/Pages/Articoli.razor.cs index accea5f3..2f1ad8f5 100644 --- a/MP.SPEC/Pages/Articoli.razor.cs +++ b/MP.SPEC/Pages/Articoli.razor.cs @@ -16,8 +16,6 @@ namespace MP.SPEC.Pages : ""; } - private SelectArticoliParams currFilter = new SelectArticoliParams(); - public void Dispose() { currRecord = null; @@ -51,51 +49,6 @@ namespace MP.SPEC.Pages [Inject] protected NavigationManager NavManager { get; set; } = null!; - protected int totalCount - { - get - { - int answ = 0; - if (SearchRecords != null) - { - answ = SearchRecords.Count; - } - return answ; - } - } - - #endregion Protected Properties - - #region Protected Methods - - private bool isNewArt = false; - - /// - /// Crea nuovo record e va in editing... - /// - /// - protected async Task addNew() - { - isNewArt = true; - currRecord = new AnagArticoliModel() - { - CodArticolo = $"_NEW_{DateTime.Now:yyyyMMdd.HHmmss}", - DescArticolo = "Nuovo articolo", - Azienda = selAzienda != "*" ? selAzienda : "MAPO", - Disegno = "", - Tipo = "ART", - CurrRev = "", - ProdRev = "" - }; - await Task.Delay(1); - } - - protected async Task resetSearch() - { - SearchVal = ""; - await ReloadData(); - } - protected string searchCss { get => string.IsNullOrEmpty(searchVal) ? "btn-secondary" : "btn-primary"; @@ -123,9 +76,43 @@ namespace MP.SPEC.Pages } } } - private string searchVal { get; set; } = ""; - private string chkDisabled => isNewArt ? "" : "disabled"; + protected int totalCount + { + get + { + int answ = 0; + if (SearchRecords != null) + { + answ = SearchRecords.Count; + } + return answ; + } + } + + #endregion Protected Properties + + #region Protected Methods + + /// + /// Crea nuovo record e va in editing... + /// + /// + protected async Task addNew() + { + isNewArt = true; + currRecord = new AnagArticoliModel() + { + CodArticolo = $"_NEW_{DateTime.Now:yyyyMMdd.HHmmss}", + DescArticolo = "Nuovo articolo", + Azienda = selAzienda != "*" ? selAzienda : "MAPO", + Disegno = "", + Tipo = "ART", + CurrRev = "", + ProdRev = "" + }; + await Task.Delay(1); + } protected async Task cancel() { @@ -134,6 +121,24 @@ namespace MP.SPEC.Pages await Task.Delay(1); } + protected async Task cloneRecord(AnagArticoliModel selRec) + { + isNewArt = true; + // creo record duplicato... + AnagArticoliModel newRec = new AnagArticoliModel() + { + Azienda = selRec.Azienda, + CodArticolo = $"clone-{selRec.CodArticolo}", + DescArticolo = $"CLONE - {selRec.DescArticolo}", + Disegno = selRec.Disegno, + Tipo = selRec.Tipo, + CurrRev = "", + ProdRev = "" + }; + currRecord = newRec; + await Task.Delay(1); + } + /// /// Eliminazione record selezionato (previa conferma) /// @@ -163,21 +168,7 @@ namespace MP.SPEC.Pages protected override async Task OnInitializedAsync() { numRecord = 10; -#if false - configData = await MDService.ConfigGetAll(); - var currRec = configData.FirstOrDefault(x => x.Chiave == "AZIENDA"); - if (currRec != null) - { - selAzienda = currRec.Valore; - } -#endif - selAzienda = await MDService.ConfigTryGetAsync("AZIENDA"); - if (string.IsNullOrEmpty(selAzienda)) - { - selAzienda = "*"; - } - ListAziende = await MDService.ElencoAziendeAsync(); - ListTipoArt = await MDService.AnagTipoArtLV(); + await ReloadBaseData(); } protected override async Task OnParametersSetAsync() @@ -191,6 +182,12 @@ namespace MP.SPEC.Pages currRecord = null; } + protected async Task resetSearch() + { + SearchVal = ""; + await ReloadData(); + } + protected async Task resetSel() { isNewArt = false; @@ -204,24 +201,6 @@ namespace MP.SPEC.Pages currRecord = selRec; await Task.Delay(1); } - protected async Task cloneRecord(AnagArticoliModel selRec) - { - isNewArt = true; - // creo record duplicato... - AnagArticoliModel newRec = new AnagArticoliModel() - { - Azienda = selRec.Azienda, - CodArticolo = $"clone-{selRec.CodArticolo}", - DescArticolo = $"CLONE - {selRec.DescArticolo}", - Disegno = selRec.Disegno, - Tipo = selRec.Tipo, - CurrRev = "", - ProdRev = "" - }; - currRecord = newRec; - await Task.Delay(1); - } - protected async Task update(AnagArticoliModel selRec) { @@ -245,7 +224,9 @@ namespace MP.SPEC.Pages #region Private Fields private string _selAzienda = "*"; + private SelectArticoliParams currFilter = new SelectArticoliParams(); private AnagArticoliModel? currRecord = null; + private bool isNewArt = false; private List? ListAziende; private List? ListRecords; private List? ListTipoArt; @@ -257,6 +238,7 @@ namespace MP.SPEC.Pages private int _currPage { get; set; } = 1; private int _numRecord { get; set; } = 10; + private string chkDisabled => isNewArt ? "" : "disabled"; private int currPage { @@ -288,6 +270,8 @@ namespace MP.SPEC.Pages } } + private string searchVal { get; set; } = ""; + private string selAzienda { get => _selAzienda; @@ -328,8 +312,19 @@ namespace MP.SPEC.Pages /// private bool ArticoloDelEnabled(string codArt) { - bool answ = MDService.ArticoloDelEnabled(codArt); - return answ; + return MDService.ArticoloDelEnabled(codArt); + } + + private async Task ReloadBaseData() + { + await MDService.EnsureArtCacheLoadedAsync(true); + selAzienda = await MDService.ConfigTryGetAsync("AZIENDA"); + if (string.IsNullOrEmpty(selAzienda)) + { + selAzienda = "*"; + } + ListAziende = await MDService.ElencoAziendeAsync(); + ListTipoArt = await MDService.AnagTipoArtLvAsync(); } private async Task ReloadData() diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index ff33fc09..7c5344ed 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

              Versione: 8.16.2605.2709

              +

              Versione: 8.16.2605.2711


              Note di rilascio:
              • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 0dfa7efa..2d0a2c5c 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2709 +8.16.2605.2711 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index dcbc0eb7..2b8bd731 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2709 + 8.16.2605.2711 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From 95376917562b6b9d97d6af448b1996c64c37e18f Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 12:05:27 +0200 Subject: [PATCH 012/102] Ancora update gestione elenco articoli --- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Articoli.razor | 2 +- MP.SPEC/Pages/Articoli.razor.cs | 11 +++++++---- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 03db7fb4..bbf38c07 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2711 + 8.16.2605.2712 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Articoli.razor b/MP.SPEC/Pages/Articoli.razor index a2a3c7e7..c6c7fb6c 100644 --- a/MP.SPEC/Pages/Articoli.razor +++ b/MP.SPEC/Pages/Articoli.razor @@ -118,7 +118,7 @@
    - @if (ListRecords == null) + @if (ListRecords == null || isLoading) { } diff --git a/MP.SPEC/Pages/Articoli.razor.cs b/MP.SPEC/Pages/Articoli.razor.cs index 2f1ad8f5..0d7dbfe8 100644 --- a/MP.SPEC/Pages/Articoli.razor.cs +++ b/MP.SPEC/Pages/Articoli.razor.cs @@ -248,8 +248,7 @@ namespace MP.SPEC.Pages if (_currPage != value) { _currPage = value; - var pUpd = Task.Run(async () => await ReloadData()); - pUpd.Wait(); + UpdateTable(); } } } @@ -264,8 +263,7 @@ namespace MP.SPEC.Pages if (_numRecord != value) { _numRecord = value; - var pUpd = Task.Run(async () => await ReloadData()); - pUpd.Wait(); + UpdateTable(); } } } @@ -331,6 +329,11 @@ namespace MP.SPEC.Pages { isLoading = true; SearchRecords = await MDService.ArticoliGetSearchAsync(100000, selAzienda, SearchVal); + UpdateTable(); + } + + private void UpdateTable() + { ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); isLoading = false; } diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 7c5344ed..5cc963d2 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

    Versione: 8.16.2605.2711

    +

    Versione: 8.16.2605.2712


    Note di rilascio:
    • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 2d0a2c5c..5daceb39 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2711 +8.16.2605.2712 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 2b8bd731..c715daef 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2711 + 8.16.2605.2712 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From 13d42d95657005b2d01dd5541ceb37ff5e7a7412 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 14:07:59 +0200 Subject: [PATCH 013/102] Cleanup codice --- MP.SPEC/Data/MpDataService.cs | 198 ------------------------------ MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- 5 files changed, 4 insertions(+), 202 deletions(-) diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 14939557..777ad5e8 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -627,88 +627,6 @@ namespace MP.SPEC.Data } } -#if false - /// - /// Verifica se sia possiubile cancellare articolo dato suo CodArt cercando su redis o su - /// tab veto da DB - /// - /// - /// - public async Task ArticoloDelEnabledAsync(object CodArt) - { - using var activity = ActivitySource.StartActivity("ArticoloDelEnabledAsync"); - string codArticolo = $"{CodArt}"; - - int cacheCheckArtUsato = 1; - int.TryParse(_configuration.GetValue("ServerConf:cacheCheckArtUsato"), out cacheCheckArtUsato); - TimeSpan ttl = getRandTOut(cacheCheckArtUsato); - - // 1. Controllo cache locale (Smart HashSet) - // Se siamo nel periodo di validità della cache locale, facciamo il controllo istantaneo - if (DateTime.Now < _artCacheExpiry) - { - // Se la nostra cache corrente contiene l'ID (o se stiamo usando la lista degli unused) - // Nota: la logica dipende da quale lista è stata caricata. - // Per semplicità, se abbiamo caricato gli "usati", cerchiamo tra quelli. - // Se abbiamo caricato gli "unused", l'articolo è eliminabile se è nel set. - // Ma per evitare confusione, gestiamo il refresh globale. - } - - // 2. Fallback su GetOrFetchAsync per garantire la sincronizzazione e l'uso di FusionCache (L1/L2) - // Usiamo un approccio che carichi la lista più piccola in memoria. - - // Per evitare complessità di switching lato client, usiamo la lista degli "usati" come riferimento - // principale nella cache distribuita, ma ottimizziamo il caricamento. - - bool usato = false; - string source = "DB"; - - // Controllo se l'ID è già presente nella nostra cache locale degli "usati" - if (DateTime.Now < _artCacheExpiry && _usedArtIdsCache.Contains(codArticolo)) - { - usato = true; - source = "MEMORY(USED)"; - } - else if (DateTime.Now < _artCacheExpiry && _unusedArtIdsCache.Contains(codArticolo)) - { - usato = false; - source = "MEMORY(UNUSED)"; - } - else - { - // Cache scaduta o non presente: ricalcoliamo la strategia - int totalCount = await dbController.ArticoliCountAsync(); - int usedCount = await dbController.ArticoliCountUsedAsync(); - - if (usedCount <= (totalCount - usedCount)) - { - // Gli usati sono meno o uguali agli unused: carichiamo gli usati - var usedList = await dbController.ArticoliGetUsedAsync(); - _usedArtIdsCache = new HashSet(usedList.Select(x => x.CodArticolo)); - _unusedArtIdsCache.Clear(); - usato = _usedArtIdsCache.Contains(codArticolo); - source = "DB+MEMORY(USED)"; - } - else - { - // Gli unused sono meno: carichiamo gli unused - var unusedList = await dbController.ArticoliGetUnusedAsync(); - _unusedArtIdsCache = new HashSet(unusedList.Select(x => x.CodArticolo)); - _usedArtIdsCache.Clear(); - usato = !_unusedArtIdsCache.Contains(codArticolo); - source = "DB+MEMORY(UNUSED)"; - } - _artCacheExpiry = DateTime.Now.AddMinutes(cacheCheckArtUsato); - } - - bool answ = !usato; - - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"ArticoloDelEnabledAsync | Cod: {codArticolo} | Usato: {usato} | {activity?.Duration.TotalMilliseconds}ms"); - return answ; - } -#endif public string CalcRecipe(RecipeModel currRecipe) { @@ -1842,72 +1760,7 @@ namespace MP.SPEC.Data await dbController.MacchineGetFiltAsync(codGruppo) ?? new List() ); - -#if false - return await GetOrCreateCachedAsync( - operationName: "MacchineGetFiltAsync", - memKey: memKey, - redisKey: redisKey, - // ✅ TTL coerente con il tuo requisito (prima avevi 1 minuto) - memoryTtl: TimeSpan.FromMinutes(1), - dbFactory: async () => - await dbController.MacchineGetFiltAsync(codGruppo) - ?? new List() - ); -#endif } -#if false - public async Task> MacchineGetFiltAsync(string codGruppo) - { - using var activity = ActivitySource.StartActivity("MacchineGetFiltAsync"); - string source = "DB"; - - string keyGrp = codGruppo != "*" ? codGruppo : "ALL"; - string memKey = $"MACCHINE_MEM:{keyGrp}"; - string redisKey = $"{Utils.redisMacList}:{keyGrp}"; - - // ✅ 1. MEMORY CACHE - if (_memoryCache.TryGetValue(memKey, out List cached)) - { - source = "MEMORY"; - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"MacchineGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return cached; - } - - List result; - - // ✅ 2. REDIS - var rawData = await redisDb.StringGetAsync(redisKey); - - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>(rawData!) ?? new(); - source = "REDIS"; - } - else - { - // ✅ 3. DB - result = await dbController.MacchineGetFiltAsync(codGruppo); - - await redisDb.StringSetAsync( - redisKey, - JsonConvert.SerializeObject(result), - getRandTOut(redisLongTimeCache) - ); - } - - // ✅ salva in RAM (IMPORTANTISSIMO), TTL 1 minuto - _memoryCache.Set(memKey, result, TimeSpan.FromMinutes(1)); - - activity?.SetTag("data.source", source); - activity?.Stop(); - - LogTrace($"MacchineGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; - } -#endif /// /// Verifica se la idxMaccSel abbia un codice PATH ricette associato @@ -2245,59 +2098,8 @@ namespace MP.SPEC.Data return dbResult ?? new List(); } ); - -#if false - return await GetOrCreateCachedAsync( - operationName: "OdlGetCurrentAsync", - memKey: memKey, - redisKey: redisKey, - // ✅ TTL molto corto (come avevi: 3 secondi) - memoryTtl: TimeSpan.FromSeconds(3), - dbFactory: async () => - { - var rawData = await dbController.OdlGetCurrentAsync(); - var dbResult = rawData - .Select(x => x.IdxMacchina) - .Distinct() - .ToList(); - - return dbResult ?? new List(); - } - ); -#endif } -#if false - public List OdlGetCurrent() - { - using var activity = ActivitySource.StartActivity("OdlGetCurrent"); - List? dbResult = new List(); - string source = "DB"; - string currKey = $"{Utils.redisOdlCurrByMac}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - dbResult = JsonConvert.DeserializeObject>($"{rawData}"); - source = "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(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", dbResult.Count); - activity?.Stop(); - LogTrace($"OdlGetCurrent | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return dbResult; - } -#endif /// /// elenco TUTTI gli ODL diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 84ec23fb..6b61fa36 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2605.0414 + 8.16.2605.2713 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index c29e503f..709dcffb 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

      Versione: 8.16.2605.0414

      +

      Versione: 8.16.2605.2713


      Note di rilascio:
        diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 6b8be000..12119c44 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.0414 +8.16.2605.2713 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index 58cf6bff..8e8abd19 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.0414 + 8.16.2605.2713 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false From 38b8f37d30bd88f3089ff2efccb0a33941737a01 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 14:11:31 +0200 Subject: [PATCH 014/102] Riorganizzazione codice MpDataService --- MP.SPEC/Data/MpDataService.cs | 283 +++++++++++++++++----------------- 1 file changed, 140 insertions(+), 143 deletions(-) diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 777ad5e8..7a2894cb 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -82,18 +82,14 @@ namespace MP.SPEC.Data #endregion Public Events #region Public Properties + public static MpSpecController dbController { get; set; } = null!; public static MpMongoController mongoController { get; set; } = null!; public MessagePipe BroadastMsgPipe { get; set; } = null!; public Dictionary> currTagConf { get; set; } = new Dictionary>(); - // Cache per controllo eliminazione articoli (Smart HashSet approach) - private HashSet _usedArtIdsCache = new(); - private HashSet _unusedArtIdsCache = new(); - private DateTime _artCacheExpiry = DateTime.MinValue; #endregion Public Properties - #region Public Methods /// @@ -412,7 +408,6 @@ namespace MP.SPEC.Data await dbController.ArticoliGetByTipoAsync(tipo, azienda) ?? new List() ); - } /// @@ -438,97 +433,6 @@ namespace MP.SPEC.Data ); } - /// - /// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria + tracking attività - /// - /// - /// - /// - /// - /// - private async Task GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tags) - { - using var activity = ActivitySource.StartActivity(operationName); - string source; - var tryGet = await _cache.TryGetAsync(cacheKey); - if (tryGet.HasValue) - { - source = "MEMORY"; - var result = tryGet.Value!; - - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); - return result; - } - bool fromDb = false; - var final = await _cache.GetOrSetAsync( - cacheKey, - async _ => - { - fromDb = true; - return await fetchFunc(); - }, - opt => - { - opt.SetDuration(expiration) - .SetFailSafe(true); - - //if (tags != null && tags.Length > 0) - // opt.SetTags(tags); - - }); - - source = fromDb ? "DB" : "REDIS"; - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); - return final!; - } - - - /// - /// Cancellazione FusionCache (totale) - /// - /// - public async Task FlushCacheAsync() - { - bool fatto = false; - await _cache.ClearAsync(); - _configData.Clear(); - fatto = true; - return fatto; - } - - /// - /// Cancellazione FusionCache dato elenco tags - /// - /// - public async Task FlushCacheByTagsAsync(List listTags) - { - bool fatto = false; - foreach (var item in listTags) - { - await _cache.RemoveByTagAsync(item); - } - _configData.Clear(); - fatto = true; - return fatto; - } - /// - /// Cancellazione FusionCache dato singolo tag - /// - /// - public async Task FlushCacheByTagAsync(string tag) - { - bool fatto = false; - await _cache.RemoveByTagAsync(tag); - _configData.Clear(); - fatto = true; - return fatto; - } - - /// /// Aggiornamento record selezionato /// @@ -546,7 +450,6 @@ namespace MP.SPEC.Data return fatto; } - /// /// Verifica se sia possiubile cancellare articolo dato suo CodArt cercando su redis o su /// tab veto da DB @@ -592,42 +495,6 @@ namespace MP.SPEC.Data return !usato; } - /// - /// Caricamento asincrono della cache degli articoli (Used/Unused) - /// - public async Task EnsureArtCacheLoadedAsync(bool forceReload) - { - if (!forceReload && (DateTime.Now < _artCacheExpiry && (_usedArtIdsCache.Count > 0 || _unusedArtIdsCache.Count > 0))) - return; - - try - { - // verifico quale sia il set + piccolo - int totalCount = await dbController.ArticoliCountAsync(); - int usedCount = await dbController.ArticoliCountUsedAsync(); - - if (usedCount <= (totalCount - usedCount)) - { - var usedList = await dbController.ArticoliGetUsedAsync(); - _usedArtIdsCache = new HashSet(usedList.Select(x => x.CodArticolo)); - _unusedArtIdsCache.Clear(); - } - else - { - var unusedList = await dbController.ArticoliGetUnusedAsync(); - _unusedArtIdsCache = new HashSet(unusedList.Select(x => x.CodArticolo)); - _usedArtIdsCache.Clear(); - } - _artCacheExpiry = DateTime.Now.AddMinutes(15); // TTL ragionevole per la cache locale - } - catch (Exception ex) - { - Log.Error($"Errore nel caricamento cache articoli: {ex.Message}"); - _artCacheExpiry = DateTime.Now.AddSeconds(1); // Retry breve in caso di errore - } - } - - public string CalcRecipe(RecipeModel currRecipe) { using var activity = ActivitySource.StartActivity("CalcRecipe"); @@ -1037,6 +904,41 @@ namespace MP.SPEC.Data return result; } + /// + /// Caricamento asincrono della cache degli articoli (Used/Unused) + /// + public async Task EnsureArtCacheLoadedAsync(bool forceReload) + { + if (!forceReload && (DateTime.Now < _artCacheExpiry && (_usedArtIdsCache.Count > 0 || _unusedArtIdsCache.Count > 0))) + return; + + try + { + // verifico quale sia il set + piccolo + int totalCount = await dbController.ArticoliCountAsync(); + int usedCount = await dbController.ArticoliCountUsedAsync(); + + if (usedCount <= (totalCount - usedCount)) + { + var usedList = await dbController.ArticoliGetUsedAsync(); + _usedArtIdsCache = new HashSet(usedList.Select(x => x.CodArticolo)); + _unusedArtIdsCache.Clear(); + } + else + { + var unusedList = await dbController.ArticoliGetUnusedAsync(); + _unusedArtIdsCache = new HashSet(unusedList.Select(x => x.CodArticolo)); + _usedArtIdsCache.Clear(); + } + _artCacheExpiry = DateTime.Now.AddMinutes(15); // TTL ragionevole per la cache locale + } + catch (Exception ex) + { + Log.Error($"Errore nel caricamento cache articoli: {ex.Message}"); + _artCacheExpiry = DateTime.Now.AddSeconds(1); // Retry breve in caso di errore + } + } + /// /// Aggiunta record EventList /// @@ -1189,6 +1091,48 @@ namespace MP.SPEC.Data return fatto; } + /// + /// Cancellazione FusionCache (totale) + /// + /// + public async Task FlushCacheAsync() + { + bool fatto = false; + await _cache.ClearAsync(); + _configData.Clear(); + fatto = true; + return fatto; + } + + /// + /// Cancellazione FusionCache dato singolo tag + /// + /// + public async Task FlushCacheByTagAsync(string tag) + { + bool fatto = false; + await _cache.RemoveByTagAsync(tag); + _configData.Clear(); + fatto = true; + return fatto; + } + + /// + /// Cancellazione FusionCache dato elenco tags + /// + /// + public async Task FlushCacheByTagsAsync(List listTags) + { + bool fatto = false; + foreach (var item in listTags) + { + await _cache.RemoveByTagAsync(item); + } + _configData.Clear(); + fatto = true; + return fatto; + } + public async Task FlushCacheFluxLog() { using var activity = ActivitySource.StartActivity("FlushCacheFluxLog"); @@ -1739,7 +1683,7 @@ namespace MP.SPEC.Data LogTrace($"MacchineGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; } - private readonly IFusionCache _cache; + /// /// Elenco di tutte le macchine filtrate x gruppo /// @@ -2072,12 +2016,6 @@ namespace MP.SPEC.Data return dbResult; } - /// - /// ODL correnti (tutti) - /// - /// - /// - public async Task> OdlGetCurrentAsync() { string redisKey = Utils.redisOdlCurrByMac; @@ -2100,7 +2038,11 @@ namespace MP.SPEC.Data ); } - + /// + /// ODL correnti (tutti) + /// + /// + /// /// /// elenco TUTTI gli ODL /// @@ -2528,7 +2470,6 @@ namespace MP.SPEC.Data endDate ) ?? new List() ); - } /// @@ -3256,8 +3197,17 @@ namespace MP.SPEC.Data private static Logger Log = LogManager.GetCurrentClassLogger(); + private readonly IFusionCache _cache; + + private DateTime _artCacheExpiry = DateTime.MinValue; + private Dictionary _configData = new(); + private HashSet _unusedArtIdsCache = new(); + + // Cache per controllo eliminazione articoli (Smart HashSet approach) + private HashSet _usedArtIdsCache = new(); + private string MpIoNS = ""; /// @@ -3326,6 +3276,53 @@ namespace MP.SPEC.Data } } + /// + /// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria + tracking attività + /// + /// + /// + /// + /// + /// + private async Task GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tags) + { + using var activity = ActivitySource.StartActivity(operationName); + string source; + var tryGet = await _cache.TryGetAsync(cacheKey); + if (tryGet.HasValue) + { + source = "MEMORY"; + var result = tryGet.Value!; + + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); + return result; + } + bool fromDb = false; + var final = await _cache.GetOrSetAsync( + cacheKey, + async _ => + { + fromDb = true; + return await fetchFunc(); + }, + opt => + { + opt.SetDuration(expiration) + .SetFailSafe(true); + + //if (tags != null && tags.Length > 0) + // opt.SetTags(tags); + }); + + source = fromDb ? "DB" : "REDIS"; + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); + return final!; + } + /// /// Helper trace messaggio log (SE abilitato) /// From e2e9111860a9396afa694858a5dbc0004ecec744 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 14:45:51 +0200 Subject: [PATCH 015/102] Inizio update agents e modifiche x pagina ART con async vari e num records --- AGENTS.md | 110 ++++++------------------------- AGENTS.pdf | Bin 0 -> 33556 bytes MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Articoli.razor | 6 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- Refactor_Plan.md | 49 ++++++++++++++ refactor_spec.md | 63 ------------------ 9 files changed, 76 insertions(+), 160 deletions(-) create mode 100644 AGENTS.pdf create mode 100644 Refactor_Plan.md delete mode 100644 refactor_spec.md diff --git a/AGENTS.md b/AGENTS.md index 9c089229..16215e2e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,94 +1,22 @@ -# CI to Local Workflow Guide +# MAPO-CORE Agent Instructions -This document describes how the GitLab CI pipeline in this repository translates to local commands that can be run on your machine. It also contains helper scripts and environment variables used by the CI. +## Core Context +- **Primary Goal**: Optimization and refactoring of the `MP-SPEC.sln` solution, focusing on migrating legacy Redis/DB caching to `FusionCache` (Memory + Redis + DB) in `MP.SPEC\Data\MpDataService.cs`. +- **Language**: C# (primary), PowerShell (scripts). +- **Documentation/Comments**: MUST be in **Italiano**. +- **Code Style**: Maintain existing region organization (`#region Public Methods`, etc.). -## Environment Variables -All variables listed below are interpolated in the CI templates. When running locally you can set them in a PowerShell profile or via `dotnet` arguments. +## Development Workflow +- **Build & Verification**: + - Use a PowerShell script to build the solution to ensure continuous compilability. + - Always verify that changes do not leave partial traces of old classes that break compilation. +- **Refactoring Strategy (`MpDataService.cs`)**: + - Use `GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tags)` as the standard for all data access. + - Target methods currently using manual `redisDb.StringGetAsync` / `StringSetAsync` patterns. +- **Testing**: + - Check the codebase for existing testing patterns before proposing new ones. -| Variable | Description | Typical value | -|----------|--------------|---------------| -| `SOL_NAME` | Solution name to restore | **MP-STATS.sln** | -| `PROJ_PATH` | Directory containing the main project | **MP.Stats** | -| `APP_NAME` | Main project file name (without `.csproj`) | **MP.Stats** | -| `NUGET_PATH` | NuGet credential file | **`C:\\Users\\samuele.steamw\AppData\Roaming\NuGet\Credentials.config`** | -| `NEXUS_PATH` | Nexus host URL | **https://nexus.steamware.net** | -| `DEST` | Artifacts output folder | **bin\publish** | -| `VERS_MAIN`, `VERS_MAIN_APP`, `VERSSUB` | Version strings used in packaging | **1.0.0** / -| `NEXUS_PASSWD` | Nexus password (secure via CI secret) | *Secret* | - -## Build Pipeline (`buildjob`) – Local Equivalent - -The CI first restores NuGet packages and then builds the solution for the selected `APP_NAME`. - -```powershell -# 1. Restore -#$env:SOL_NAME.sln is resolved by the .nuget-fix script -# In PowerShell: dotnet restore "MP-STATS.sln" - -# 2. Build -# $env:APP_NAME/$env:APP_NAME.csproj points to the project file -# In PowerShell: dotnet build "MP.Stats/MP.Stats.csproj" -``` - -### Helper: `.nuget-fix` -The `.nuget-fix` PowerShell script removes any stale NuGet sources that conflict with the Nexus proxy and re‑adds the latest proxy source with credentials. Ensure this script runs *before* `dotnet restore`. - -## Deploy Pipeline (`deployjob`) – Local Equivalent - -Deployment in CI rebuilds the project, publishes it, hashes the output, and uploads it to Nexus. The same steps can be executed locally. - -```powershell -# 1. Rebuild (same as Build) -# dotnet build "MP.Stats/MP.Stats.csproj" - -# 2. Publish to a local folder -# The `dotnet publish` command mimics the CI publish step. The `-c Release` ensures a Release build. -# In PowerShell: -# dotnet publish "MP.Stats/MP.Stats.csproj" -c Release -o publish - -# 3. Create hashes (MD5 & SHA1) -# The .hashBuild template generates .md5 and .sha1 files alongside the ZIP. A simple replacement can be -# 1. Zip the folder: `Compress-Archive -Path publish -DestinationPath $(APP_NAME).zip` -# 2. Generate hashes: -# (Get-FileHash -Algorithm MD5 "$(APP_NAME).zip").Hash | Out-File "$(APP_NAME).md5" -# (Get-FileHash -Algorithm SHA1 "$(APP_NAME).zip").Hash | Out-File "$(APP_NAME).sha1" - -# 4. Upload to Nexus (requires `curl`) -# Example curl command (CI uses `nexus-curl` script): -# $curl -u $(NUGET_USER):$(NEXUS_PASSWD) "$(NEXUS_PATH)/repository/$(APP_NAME)" -T "$(APP_NAME).zip" -``` - -## Installer & Release -The **installer** template copies the published artifacts to a staging folder and optionally creates installers. The **release** template bumps version numbers, updates the `nuspec`, generates a changelog, and pushes the packages to Nexus. - -Generally these steps are CI‑only, but you can repeat the same `dotnet pack` / `nuget push` commands locally if needed. - -## Common Issues & Fixes - -* _NuGet authentication errors_: Run `.nuget-fix` to reset the sources. -* _Missing SDK_: Verify `dotnet --list-sdks` includes at least one SDK. -* _Hashes not matching_: Ensure the ZIP file is identical to the one CI produced (same path, no hidden files). - -## Quick Start -```powershell -# Restore -.\.nuget-fix - -# Build - -dotnet restore "MP-STATS.sln" -dotnet build "MP.Stats/MP.Stats.csproj" - -# Publish & run - -dotnet publish "MP.Stats/MP.Stats.csproj" -c Release -o publish -dotnet run --project "MP.Stats/MP.Stats.csproj" - -# For hot‑reload during development - -dotnet watch run --project "MP.Stats/MP.Stats.csproj" -``` - ---- - -Feel free to adjust paths or environment variable names if your local setup differs. +## Architecture Notes +- **Multi-Layer Caching**: The system is transitioning from a dual-layer (Redis + DB) to a triple-layer approach via `IFusionCache`. +- **Service Responsibility**: `MpDataService` is the central hub for data access, interacting with `MpSpecController` (EFCore) and `MpMongoController` (MongoDB). +- **Key Management**: Cache keys are heavily managed via `Utils.redis...` constants. diff --git a/AGENTS.pdf b/AGENTS.pdf new file mode 100644 index 0000000000000000000000000000000000000000..be4b911e6068b76cf9e9fb20d459af71d0732ac2 GIT binary patch literal 33556 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

        {x0_nWL_z*5DJoBZ?e zDmrS#kGcQ^&bQo`u5$>9q1;*7he{Br^^fj3MNVw4) zgx{%~!OEfRHg9RRTmIK9YzoxKu#1kSS3GIY6spvM^xpZW70@Y0XrEssozzTHE>=k$ z?49K7gX8O4SrD*r6FjjdwmMgaR|I03h1wA_5!Z*S#|@=?RTtg7t!>|RJ)*!Z8=2VN zv`rgLjDu>+W!ZpBwQCW*{c3oFQD?rL9?e81!OdOLCWVb%*#qZ(5NW79s;4z?XYT&D zA0*ZLFi(N(4FgLKq2md9aqQsZS62y|irevtXRGdNLldgDEmJOk-dFHfk<>XWZa)8( zo}Zyj%?LTr3MBZkM7E(pgi#ookrDIcl^Ufr zL0TX6`+!`Fw8~qQbR671b4uZdfJxApgP(LpDRy6gxOkj7WMf;tS>4f>6bciZ+qq|* z6jBrmaq-_Yes}7A)MUfb1=hRuOTBVR)3oif4?apJg+1>&De3|WBL+E!o`golU=&%tS<=pDJp11%M<+N03YW|rL!e{$2YQVZ zZMX?UOieNYOnvEcsa$ktDWM|S&ed4<4>Y6Fs0cGDs<@f`^>FnP42-;xV5v1y*funUCfr36Rp0mA*f>G+782T` zwezd&pwCG9<$B_9ktjC)nvzZRP7zHzN@-U{z*S-F#QnmK{z|k1P0=#w^SNp_W~q!e z%BeP?R5M$X%+j@=#wP4ddn6)=bex}2xqTlary}5#U2tGz^8W*f2~b`kjEE-dA5KRi z805qn z?`YF&Bk7P&bD^N-s{m9U!{xuJ{l0eb3^Er2ng{uJct4&1zsEoK8D48<%Z+T4-Ct}p zJ^Cw$x_b!g{7yqBYKxT5q?X$q6EJ&s**!Y$bqP8$zxw=kmdL32((aUre32*@FC;bh zu+914b0?T(`fkhZe#I7M0E2OvfqCa$uJ*lw^qn-yv3cI0yl$JWDlX0w8O+vNuaQvT zz;VF*3N={8xk86cGOebd%qyO?tjv0h{H%T-{)DnMH7RNsjkkZ-Re z9HaOJg_)@Cai}DpV`=XFOND$w3#~wzIXCC9(g|`s-fI!@%b3;h?3Xd|B5CQ#bT~=I6uCxO$p9#_T?byXWVh#p2PJGu(_O&-)l^ zYR%VsS~^fC%m#W8Rph}}55d>RiY)24?w*)IXiG6!3z~_Pf|nrJRTj7u;~ufjl|?C8 z&T1SFb=4}H*HNzthUd3A6;r)Cw7}YPimljBM3@%xYM`AxD?(Vr-= z^!+A0{Y*7fGgnMPS7zUZNNiNk^q2we7fjW(e1l_W38CmA-l|p z9^Vi#get#@zJW)SCT#5K<_$#`{lI#s(ul)z(@WDb-mMM@J`TM;6=}T9$H2Kvl6MR-xX3TfPRKnRW554sg;)Vh7wH|t+e?DXE!ZN zORchbyoou@l@_fQRi`k}VOGr*R^}>;3p}E?K}wDTU^bGIqFjs8gadND3w8OEFivKy zDxFOhRkrEbwSN<0i#LzBvpm zWiT%7B@(QJJhZC>g&JY_Mc+&M?wzlcG)irQE+BNmhXSscTlN75NVkUtYKazKalg6% zzN3;z=4>A=ct#CxN%9_t(Fg^_N@W3hzoFhTVN~o-a|alIT>z~5W+!9pFy9;q=)&cO;#-i$ELhB-N@F(z?c<>PM z(V}(!#Nr{PS(A8B0pq{JDV~aO`bJ#j!S&lUbtnxLl7p$;hNg#XFDsx@Ht*PrkQCaT zqH7Idtdv!Ir`6?8j~c$BoK|_h8hW$qb|YR?b4i^Sb0>64Arf&%Wna43clK=Lz&;5u z9CX11aDBrQb4A!f`NG2&@?yPet3Q(RXCvPr0Om6n7XWwECA6P!C$!@wU+7qwuz(uC z?wu^#ztdO09dvZF%HKVsGpe$EmanATsFAq454sye`djn)m#tw6tX;Z$9~LldwC=bd zQJzw`9*S&bta<$JPE3mF1YZ868Kp6N|B!8^$PNl z5s|gknQ(RSWNY-wY(TgD_S*QSi?5<7FI&9xiL_})IN*NVMG+>^sUGb{8=iZ1{ms(t z>&UlCfytYJr|NgrELcIjf;Z9hf|{`p@qWI%)<{&1v+w{Deoz+B911dju+^M3r0tkV zcs3#mfa9H0_Ll(K4&?ZslN=bn$lokBzDV*HJF$?1=8%l=Lw_ABgMh%?ZRAsAUS%_1 z$1YScxg1L_`1i=a9@{RgQl4tex{dz+`MWO(G9JV9LS673cfUJ&ZDy;69L`De&pYj2 z_hF5Rlyb6Bckc3m5qHA!0|izrrKui5@Bxw$Lbq~LzLTYK_ZAJgkh?D$a!4mri}{0q zhldH;1cl!b&dM-(LY~*mu32#B0};I`dp%_y)%Y| z@s3@dnZkW!SD2akjY!Je*lMDi?>Cr3)gJ*)N@04;=P7*_=WF|clV}% zqpZ<+fjIc|M7uGPIpQUUfruS*qi*(#U^!1>el2sTlcx0RaVkXXrp#t>REXGO z8KhoKNU5W4G~Azb#j9YHNzOLGP%dcLnH)}8b5kVYt2CH1=7b*_@$tWwh zIYsm%!;I(V;HlTUKAkv1;+`^(?b`tjUm(&@2X!M34@MJDY%!$ngH9Y#qD~q~M0JiB zKsl(vmA+m?@H=?v=z1NWW99j7!d1vxPmT6bSVSSe7Bq?4ZZI>gFS``blunb!xs`;v?5JmOPVWIhFXIftEtDLRfNqbMg|w+^*k0?b_zA zH7dVC+SsY@9+d}7o!u&VZ-ZU+sCH`3qTUKBW})Y?5c(#PMfV)>J{I9%)UsNkqTmhKJv``;mqm%DmbI{bn-dnJ zEe%zrR#)6Gr3W-hz)^6Lq?pzyBlh3-GYtTMVS~!?sCk1_7;dCWepjs%K8A#u1m)Rc zuM~#8BX&P6!K~o~*w0 zCm1N;V6JZ^qx>nd(l-SHm|^GyfQFyg9e{(Lg_eM}0$4t-qm(Vk| zRs}G#(6V!|Gc&P&GI#oR;>PBtW{vu`;0>H z9~6*=m6e&6g@vAt9YDjx$V|&d&qmJ#V5Fy~2Qbhxar|rQ6Ab)o@k!YkGXnlncz=1r ze*=yT|6`+pf3bgmRsUu1-$Xy1{WbeU|Mh{!e--{mzDiC8j{l&MLK4D%r~Z0j{LDi_ zSlL!gLRd!M?vs8r`b^v0(d{3xk{j?dX$cz>+rPM@qOqy@Cv)irAQ$-DZNT_*YXUh3 zBVz}18&d%Jf6P9GN=|lmR>szUSMPHJ0T?>9zZj$z8_VCg=mCsuY_#l5pF14reC{v+ z&|+d@qNV>_lTX0#KNJ6b^{K+~2_6DiSXgNpSQwd@0Zgm_W_kcCD=RGr2jk}?GvlY{ z{}}23m^nUA85wCASlKw(bO0>O0ImP(vNF(rUitIh>3rTVfY$%-R0qKR86W$90@3-r z2f}Lqg#Mp}{~u`S|HeNuaxnZ)`cWrl!p5H-uK&Uf2ESDZ!gu=o=dV)dIQG-%{(BGt z2IlFn3gU=uZ?R1$`67hVh%Yw>i%TUujiMfd>uc0pxAbOt-)V2=Bm(fntTE~M&5vy3 zZ8)GuY60i-eLJ(M`X)~Bzq|qtx7T3O@=`rKe=Mab9oA#%-#8tExu{uo+6(Rwn96{| z1j`?ZEUGaO7)dl(tAto~+W7C&?Ers&6)})q8`Rh`2oxq84JjY*G0*l!DAG5Z?R@n8 z|B8F-s5qLf(K|tdLvVK|z@RfQxCVE3C%6Q6cXtgQB)CIxcXuafa0yQCD>s%q%&-!7FGGM1jA6E>3r_jvC32;F>QS`VtSuo%%$QEFNbDJ&oH zmGk$iplQ%&`)dZ@?DJ?xsa@>P_HtTsIay;;waj;-Ka`T2T2<)z*_e0vh1@?gBeU2r z$$prSCTwS!pWrInxr3%_O-BFkQT&Id{jWj%r$_yx-~Q>akU{mobZs$PNb-t5J@Ky& z{6X@6MzM(@WJE!_JA{k<+Za-UL|Da6)zaH+uAe_cF~f

        ZW2Rt1do?JM*FIsOhG{&Rp}!%gVox`|h*( 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 enable MP.SPEC - 8.16.2605.2712 + 8.16.2605.2714 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Articoli.razor b/MP.SPEC/Pages/Articoli.razor index c6c7fb6c..e20b654c 100644 --- a/MP.SPEC/Pages/Articoli.razor +++ b/MP.SPEC/Pages/Articoli.razor @@ -19,10 +19,10 @@

        - + - @if (ListAziende != null) { foreach (var item in ListAziende) @@ -31,6 +31,8 @@ } } + +
    diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 5cc963d2..f9337c57 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

    Versione: 8.16.2605.2712

    +

    Versione: 8.16.2605.2714


    Note di rilascio:
    • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 5daceb39..55b93cf6 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2712 +8.16.2605.2714 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index c715daef..a591e4cf 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2712 + 8.16.2605.2714 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/Refactor_Plan.md b/Refactor_Plan.md new file mode 100644 index 00000000..93467761 --- /dev/null +++ b/Refactor_Plan.md @@ -0,0 +1,49 @@ +# Piano di Refactoring: Migrazione a FusionCache in `MpDataService.cs` + +## Obiettivo +Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCache` per implementare un approccio multi-layer (Memory + Redis + DB), standardizzando l'accesso ai dati. + +## Analisi dello stato attuale +- **Classe target**: `MP.SPEC\Data\MpDataService.cs` +- **Pattern attuale**: Molti metodi utilizzano manualmente `redisDb.StringGetAsync` e `redisDb.StringSetAsync` con serializzazione JSON manuale. +- **Metodo Standard**: `GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tags)`. + +## Strategia di Migrazione + +### 1. Identificazione Metodi Target +Andrò a mappare tutti i metodi in `MpDataService.cs` che: +- Utilizzano `redisDb` direttamente per la lettura/scrittura. +- Gestiscono manualmente la serializzazione/deserializzazione con `JsonConvert`. +- Gestiscono manualmente il fallback dal Redis al DB. + +### 2. Classificazione Metodi +I metodi verranno suddivisi in: +- **Lettura (Cache-aside)**: Metodi che recuperano dati. Questi saranno i candidati principali per `GetOrFetchAsync`. +- **Scrittura/Invalidazione**: Metodi che aggiornano il DB e devono invalidare la cache (es. `AnagGruppiUpsert`, `ArticoliUpdateRecord`). Questi dovranno utilizzare `_cache.RemoveByTagAsync` o `_cache.RemoveAsync`. + +### 3. Piano di Implementazione (Step-by-Step) + +#### Fase 1: Analisi e Mapping +- [ ] Identificare ogni occorrenza di `redisDb.StringGet` / `StringGetAsync` in `MpDataService.cs`. +- [ ] Verificare se la chiave di cache utilizzata è gestita tramite `Utils.redis...`. + +#### Fase 2: Refactoring Metodi di Lettura +Per ogni metodo di lettura individuato: +- [ ] Sostituire la logica `if (rawData.HasValue) { ... } else { ... }` con la chiamata a `GetOrFetchAsync`. +- [ ] Assicurarsi che il `fetchFunc` esegua la chiamata al `dbController`. +- [ ] Configurare correttamente il `TimeSpan expiration` (usando le costanti esistenti come `redisLongTimeCache` o `redisShortTimeCache`). +- [ ] Aggiungere i tag appropriati per permettere l'invalidazione granulare. + +#### Fase 3: Refactoring Metodi di Scrittura e Invalidazione +- [ ] Sostituire le chiamate manuali a `ExecFlushRedisPattern` o `redisDb.KeyDelete` con i metodi di invalidazione di `IFusionCache`. +- [ ] Utilizzare i tag per invalidare gruppi di dati correlati invece di pattern Redis generici quando possibile. + +#### Fase 4: Verifica +- [ ] Verificare la compilazione della soluzione tramite script PowerShell. +- [ ] Controllare che i log (NLog) continuino a riflettere correttamente le operazioni. + +## Rischi e Mitigazioni +- **Rischio**: Discrepanza nelle chiavi di cache tra vecchio e nuovo sistema. + - *Mitigazione*: Utilizzare rigorosamente le costanti in `Utils.redis...` per garantire che le chiavi siano identiche o gestite dal nuovo sistema. +- **Rischio**: Errori di serializzazione. + - *Mitigazione*: `FusionCache` gestisce la serializzazione, ma è necessario assicurarsi che i tipi di ritorno siano compatibili con le aspettative dei chiamanti. diff --git a/refactor_spec.md b/refactor_spec.md deleted file mode 100644 index 2b8a587c..00000000 --- a/refactor_spec.md +++ /dev/null @@ -1,63 +0,0 @@ -# Refactoring Plan: MpDataService Cache Layer Upgrade - -## Objective -Migrate all data access methods in `MpDataService.cs` to use the unified multi-level cache stack (IMemoryCache via `IFusionCache` + Redis + DB) using the `GetOrFetchAsync` pattern. - -## Current State -- Some methods use a manual "Redis + DB" approach (checking `redisDb.StringGet`, deserializing, and then `StringSet` on miss). -- Some methods use the new `GetOrFetchAsync` pattern (Memory + Redis + DB). -- `GetOrFetchAsync` leverages `IFusionCache`, which handles the multi-level complexity and provides better resiliency (fail-safe). - -## Target Pattern: `GetOrFetchAsync` -All read methods should be refactored to: -1. Use `GetOrFetchAsync` to abstract cache management. -2. Define a `cacheKey` (typically matching the existing Redis key). -3. Provide an `expiration` (TimeSpan). -4. Provide a `fetchFunc` that calls the `dbController` method. - -## Proposed Work Items - -### 1. Analysis & Categorization -Identify all methods in `MpDataService.cs` that currently implement manual Redis caching. - -**Candidates for Refactoring (Redis + DB -> Multi-level):** -- `AnagEventiGeneral` (Lines 166-195) -- `AnagEventiGetByMacch` (Lines 201-230) -- `AnagKeyValGetAll` (Lines 273-302) -- `AnagTipoArtLV` (Lines 347-375) -- `ArticleWithDossier` (Lines 381-410) -- `ConfigGetAll` (Lines 907-936) -- `ConfigGetAllAsync` (Lines 943-970) -- `DbDedupStats` (Lines 1046-1067) -- `ElencoGruppiFase` (Lines 1216-1249) -- `ElencoRepartiDTO` (Lines 1267-1303) -- `FluxLogGetLastFilt` (Lines 1569-1605) -- `FluxLogPareto` (Lines 1609-1640) -- `MacchineRecipeArchive` (Lines 2100-2128) -- `MacchineRecipeConf` (Lines 2131-2163) -- `MacchineWithFlux` (Lines 2171-2200) -- `OdlByBatch` (Lines 2308-2336) -- `OdlListAll` (Lines 2490-2499) - *Currently no cache, needs addition?* -- `OdlListGetFilt` (Lines 2513-2542) -- `OperatoriGetFilt` (Lines 2549-2577) -- `ParametriGetFilt` (Lines 2585-2614) -- `POdlGetByKey` (Lines 2658-2697) -- `POdlGetByOdl` (Lines 2705-2744) -- `POdlListByKitParent` (Lines 2770-2800) -- `POdlListGetFilt` (Lines 2812-2841) -- `TksScore` (Lines 3343-3372) -- `VocabolarioGetAll` (Lines 3445-3477) -- `WipKitFilt` (Lines 3543-3570) - -### 2. Implementation Steps -For each candidate method: -1. **Convert to Async**: If the method is synchronous (e.g., `AnagEventiGeneral`), convert it to `Task` to match the `GetOrFetchAsync` signature. -2. **Map Keys**: Ensure the `cacheKey` passed to `GetOrFetchAsync` is identical to the old Redis key to prevent cache fragmentation. -3. **Set Expiration**: Use appropriate `TimeSpan` (e.g., `redisLongTimeCache` or `redisShortTimeCache` converted to `TimeSpan`). -4. **Cleanup**: Remove manual `JsonConvert` logic and `redisDb.StringGet/Set` calls. -5. **Verify Tracing**: Ensure `ActivitySource` and `LogTrace` are preserved or integrated within the `GetOrFetchAsync` wrapper. - -### 3. Validation -- Ensure all refactored methods are still called correctly by consumers. -- Verify that `GetOrFetchAsync` correctly hits Memory first, then Redis, then DB. -- Confirm that `LogTrace` still reports the correct source (MEMORY, REDIS, or DB). From 8580acdb0c2cffbfbf4df1390b7f7fb2cde742f5 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 14:46:04 +0200 Subject: [PATCH 016/102] Ancora update ART --- MP.Data/Controllers/MpSpecController.cs | 8 +-- MP.SPEC/Data/MpDataService.cs | 8 +-- MP.SPEC/Pages/Articoli.razor | 6 +- MP.SPEC/Pages/Articoli.razor.cs | 78 ++++++++++++++++--------- 4 files changed, 60 insertions(+), 40 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 96be09c7..9808cc32 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -656,20 +656,20 @@ namespace MP.Data.Controllers /// Update record config ///
/// - public bool ConfigUpdate(ConfigModel updRec) + public async Task ConfigUpdateAsync(ConfigModel updRec) { bool fatto = false; ConfigModel dbResult = new ConfigModel(); using (var dbCtx = new MoonProContext(options)) { - dbResult = dbCtx + dbResult = await dbCtx .DbSetConfig .Where(x => x.Chiave == updRec.Chiave) - .FirstOrDefault(); + .FirstOrDefaultAsync(); if (dbResult != null) { dbResult.Valore = updRec.Valore; - dbCtx.SaveChanges(); + await dbCtx.SaveChangesAsync(); fatto = true; } } diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 7a2894cb..08d03270 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -631,14 +631,14 @@ namespace MP.SPEC.Data /// Update chiave config ///
/// - public bool ConfigUpdate(ConfigModel updRec) + public async Task ConfigUpdateAsync(ConfigModel updRec) { - using var activity = ActivitySource.StartActivity("ConfigUpdate"); + using var activity = ActivitySource.StartActivity("ConfigUpdateAsync"); string source = "DB"; - var updRes = dbController.ConfigUpdate(updRec); + var updRes = await dbController.ConfigUpdateAsync(updRec); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ConfigUpdate Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ConfigUpdateAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return updRes; } diff --git a/MP.SPEC/Pages/Articoli.razor b/MP.SPEC/Pages/Articoli.razor index e20b654c..4a655d60 100644 --- a/MP.SPEC/Pages/Articoli.razor +++ b/MP.SPEC/Pages/Articoli.razor @@ -19,10 +19,10 @@
- + - @if (ListAziende != null) { foreach (var item in ListAziende) @@ -32,7 +32,7 @@ } - +
diff --git a/MP.SPEC/Pages/Articoli.razor.cs b/MP.SPEC/Pages/Articoli.razor.cs index 0d7dbfe8..ce9bd81e 100644 --- a/MP.SPEC/Pages/Articoli.razor.cs +++ b/MP.SPEC/Pages/Articoli.razor.cs @@ -65,13 +65,15 @@ namespace MP.SPEC.Pages if (searchVal != value) { searchVal = value; +#if false var pUpd = Task.Run(async () => - { - ListRecords = null; - await Task.Delay(1); - await ReloadData(); - }); - pUpd.Wait(); + { + ListRecords = null; + await Task.Delay(1); + await ReloadDataAsync(); + }); + pUpd.Wait(); +#endif } } } @@ -117,7 +119,7 @@ namespace MP.SPEC.Pages protected async Task cancel() { currRecord = null; - await ReloadData(); + await ReloadDataAsync(); await Task.Delay(1); } @@ -151,7 +153,7 @@ namespace MP.SPEC.Pages await Task.Delay(1); var done = await MDService.ArticoliDeleteRecord(selRec); currRecord = null; - await ReloadData(); + await ReloadDataAsync(); await Task.Delay(1); } @@ -173,7 +175,7 @@ namespace MP.SPEC.Pages protected override async Task OnParametersSetAsync() { - await ReloadData(); + await ReloadDataAsync(); } protected void ResetData() @@ -185,7 +187,7 @@ namespace MP.SPEC.Pages protected async Task resetSearch() { SearchVal = ""; - await ReloadData(); + await ReloadDataAsync(); } protected async Task resetSel() @@ -209,14 +211,14 @@ namespace MP.SPEC.Pages await Task.Delay(1); var done = await MDService.ArticoliUpdateRecord(selRec); currRecord = null; - await ReloadData(); + await ReloadDataAsync(); await Task.Delay(1); } protected async Task UpdateData() { currRecord = null; - await ReloadData(); + await ReloadDataAsync(); } #endregion Protected Methods @@ -230,6 +232,7 @@ namespace MP.SPEC.Pages private List? ListAziende; private List? ListRecords; private List? ListTipoArt; + private int maxNumRecord = 5000; private List? SearchRecords; #endregion Private Fields @@ -278,24 +281,41 @@ namespace MP.SPEC.Pages if (value != _selAzienda) { _selAzienda = value; +#if false var pUpd = Task.Run(async () => - { - // svuoto cache redis... - ConfigModel updRec = new ConfigModel() - { - Chiave = "AZIENDA", - Valore = value - }; - MDService.ConfigUpdate(updRec); - await MDService.ConfigResetCache(); - // ricarico - await Task.Delay(1); - await ReloadData(); - }); - pUpd.Wait(); + { + // svuoto cache redis... + ConfigModel updRec = new ConfigModel() + { + Chiave = "AZIENDA", + Valore = value + }; + MDService.ConfigUpdate(updRec); + await MDService.ConfigResetCache(); + // ricarico + await Task.Delay(1); + await ReloadDataAsync(); + }); + pUpd.Wait(); +#endif } } } + private async Task ReloadAziendaAsync() + { + isLoading = true; + // svuoto cache redis... + ConfigModel updRec = new ConfigModel() + { + Chiave = "AZIENDA", + Valore = selAzienda + }; + await MDService.ConfigUpdateAsync(updRec); + await MDService.ConfigResetCache(); + // ricarico + await ReloadDataAsync(); + } + private bool ShowCharts { get; set; } = false; @@ -325,16 +345,16 @@ namespace MP.SPEC.Pages ListTipoArt = await MDService.AnagTipoArtLvAsync(); } - private async Task ReloadData() + private async Task ReloadDataAsync() { isLoading = true; - SearchRecords = await MDService.ArticoliGetSearchAsync(100000, selAzienda, SearchVal); + SearchRecords = await MDService.ArticoliGetSearchAsync(maxNumRecord, selAzienda, SearchVal); UpdateTable(); } private void UpdateTable() { - ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); + ListRecords = SearchRecords?.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList() ?? new(); isLoading = false; } From 9d513edab480d1c5ad44ed730a95618cea36f93c Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 14:47:49 +0200 Subject: [PATCH 017/102] Update plan interventi --- Refactor_Plan.md | 66 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/Refactor_Plan.md b/Refactor_Plan.md index 93467761..ad4963cd 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -28,15 +28,67 @@ I metodi verranno suddivisi in: - [ ] Verificare se la chiave di cache utilizzata è gestita tramite `Utils.redis...`. #### Fase 2: Refactoring Metodi di Lettura -Per ogni metodo di lettura individuato: -- [ ] Sostituire la logica `if (rawData.HasValue) { ... } else { ... }` con la chiamata a `GetOrFetchAsync`. -- [ ] Assicurarsi che il `fetchFunc` esegua la chiamata al `dbController`. -- [ ] Configurare correttamente il `TimeSpan expiration` (usando le costanti esistenti come `redisLongTimeCache` o `redisShortTimeCache`). -- [ ] Aggiungere i tag appropriati per permettere l'invalidazione granulare. +- [x] `ActionGetReq` (Completato) +- [ ] `AnagEventiGeneral` +- [ ] `AnagEventiGetByMacch` +- [ ] `AnagKeyValGetAll` +- [ ] `AnagStatiComm` +- [ ] `AnagTipoArtLvAsync` +- [ ] `ArticleWithDossier` +- [ ] `ConfigGetAll` +- [ ] `ConfigGetAllAsync` +- [ ] `DbDedupStats` +- [ ] `DossiersGetLastFilt` +- [ ] `ElencoGruppiFase` +- [ ] `ElencoRepartiDTO` +- [ ] `ExpiryReloadParamGet` +- [ ] `IobInfo` +- [ ] `IstKitFilt` +- [ ] `ListGiacenze` +- [ ] `ListPODL_ByCodArt` +- [ ] `MacchineGetFilt` +- [ ] `MacchineRecipeArchive` +- [ ] `MacchineRecipeConf` +- [ ] `MacchineWithFlux` +- [ ] `MachIobConf` +- [ ] `MseGetAll` +- [ ] `OdlByBatch` +- [ ] `OdlGetCurrentAsync` +- [ ] `OdlListGetFilt` +- [ ] `OperatoriGetFilt` +- [ ] `ParametriGetFilt` +- [ ] `POdlGetByKey` +- [ ] `POdlGetByOdl` +- [ ] `POdlListByKitParent` +- [ ] `POdlListGetFilt` +- [ ] `POdlListGetFiltAsync` +- [ ] `ProcFLStats` +- [ ] `StatoMacchina` +- [ ] `TagConfGetKey` +- [ ] `TemplateKitFilt` +- [ ] `TksScore` +- [ ] `VocabolarioGetAll` +- [ ] `WipKitFilt` #### Fase 3: Refactoring Metodi di Scrittura e Invalidazione -- [ ] Sostituire le chiamate manuali a `ExecFlushRedisPattern` o `redisDb.KeyDelete` con i metodi di invalidazione di `IFusionCache`. -- [ ] Utilizzare i tag per invalidare gruppi di dati correlati invece di pattern Redis generici quando possibile. +- [ ] `AnagGruppiDelete` +- [ ] `AnagGruppiUpsert` +- [ ] `ArticoliDeleteRecord` +- [ ] `ArticoliUpdateRecord` +- [ ] `ConfigResetCache` +- [ ] `DossiersDeleteRecord` +- [ ] `DossiersTakeParamsSnapshotLast` +- [ ] `IstKitDelete` +- [ ] `IstKitInsertByWKS` +- [ ] `IstKitUpsert` +- [ ] `PodlIstKitDelete` +- [ ] `POdlDoSetup` +- [ ] `POdlUpdateRecipe` +- [ ] `POdlUpdateRecord` +- [ ] `RecipeSetByPODL` +- [ ] `TemplateKitDelete` +- [ ] `TemplateKitUpsert` + #### Fase 4: Verifica - [ ] Verificare la compilazione della soluzione tramite script PowerShell. From fcf3bc84002afc706d157fb411d7b531089a76be Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 16:20:09 +0200 Subject: [PATCH 018/102] Update ricerfa articoli x tipo --- MP.Data/Controllers/MpSpecController.cs | 48 +++++++-- MP.SPEC/Components/ListDossiers.razor.cs | 2 +- MP.SPEC/Components/SelectCodArt.razor.cs | 2 +- MP.SPEC/Data/MpDataService.cs | 9 +- MP.SPEC/Pages/Articoli.razor | 75 ++++++++++---- MP.SPEC/Pages/Articoli.razor.cs | 122 +++++++---------------- 6 files changed, 137 insertions(+), 121 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 9808cc32..969105e9 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -502,25 +502,51 @@ namespace MP.Data.Controllers /// Elenco tabella Articoli da filtro /// /// + /// /// /// /// - public async Task> ArticoliGetSearchAsync(int numRecord, string azienda = "*", string searchVal = "") + public async Task> ArticoliGetSearchAsync(int numRecord, string tipoArt = "*", string azienda = "*", string searchVal = "") { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) + using var dbCtx = new MoonProContext(options); + IQueryable query = dbCtx.DbSetArticoli + .AsNoTracking(); + + // filtro tipo articolo + if (tipoArt != "*") { - dbResult = await dbCtx - .DbSetArticoli - .AsNoTracking() - .Where(x => (azienda == "*" || x.Azienda.ToUpper() == azienda.ToUpper()) && (string.IsNullOrEmpty(searchVal) || x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal))) - .OrderBy(x => x.CodArticolo) - .Take(numRecord) - .ToListAsync(); + //query = query.Where(x => x.Tipo.ToLower() == tipoArt.ToLower()); + query = query.Where(x => EF.Functions.Like(x.Tipo, tipoArt)); + } - return dbResult; + // filtro azienda + if (azienda != "*") + { + //query = query.Where(x => x.Azienda.ToLower() == azienda.ToLower()); + query = query.Where(x => EF.Functions.Like(x.Azienda, azienda)); + + } + // filtro ricerca + if (!string.IsNullOrWhiteSpace(searchVal)) + { + //query = query.Where(x => + // x.CodArticolo.Contains(searchVal) || + // x.DescArticolo.Contains(searchVal) || + // x.Disegno.Contains(searchVal)); + string pattern = $"%{searchVal}%"; + query = query.Where(x => + EF.Functions.Like(x.CodArticolo, pattern) || + EF.Functions.Like(x.DescArticolo, pattern) || + EF.Functions.Like(x.Disegno, pattern)); + } + + return await query + .OrderBy(x => x.CodArticolo) + .Take(numRecord) + .ToListAsync(); } + /// /// Elenco tabella Articoli NON IMPIEGATI (da stored stp_ART_getUsed) Async /// diff --git a/MP.SPEC/Components/ListDossiers.razor.cs b/MP.SPEC/Components/ListDossiers.razor.cs index f26032dd..2947870b 100644 --- a/MP.SPEC/Components/ListDossiers.razor.cs +++ b/MP.SPEC/Components/ListDossiers.razor.cs @@ -234,7 +234,7 @@ namespace MP.SPEC.Components ListStati = await MDService.AnagStatiComm(); selAzienda = await MDService.ConfigTryGetAsync("AZIENDA"); giacenzeConf = await MDService.ConfigTryGetAsync("SPEC_ShowGiacenze"); - ListArticoli = await MDService.ArticoliGetSearchAsync(100000, selAzienda, ""); + ListArticoli = await MDService.ArticoliGetSearchAsync(100000, "*", selAzienda, ""); ListMacchine = MDService.MacchineGetFilt("*"); await ReloadData(true); } diff --git a/MP.SPEC/Components/SelectCodArt.razor.cs b/MP.SPEC/Components/SelectCodArt.razor.cs index 29b051aa..36cb41db 100644 --- a/MP.SPEC/Components/SelectCodArt.razor.cs +++ b/MP.SPEC/Components/SelectCodArt.razor.cs @@ -108,7 +108,7 @@ namespace MP.SPEC.Components if (!ListArtDisabled) { Log.Debug("START GetArticoli"); - var rawData = await MDataService.ArticoliGetSearch(10000, "*", searchVal); + var rawData = await MDataService.ArticoliGetSearch(10000, "*", "*", searchVal); // trasformo! if (rawData != null) { diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 08d03270..5bb2bfd7 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -416,19 +416,18 @@ namespace MP.SPEC.Data /// /// /// - public async Task> ArticoliGetSearchAsync(int numRecord, string azienda, string searchVal) + public async Task> ArticoliGetSearchAsync(int numRecord, string tipoArt, string azienda, string searchVal) { string sKey = string.IsNullOrWhiteSpace(searchVal) ? "***" : searchVal.Trim(); - string memKey = $"ART_SEARCH_MEM:{azienda}:{sKey}:{numRecord}"; - string redisKey = $"{Utils.redisArtList}:{azienda}:{sKey}:{numRecord}"; + string redisKey = $"{Utils.redisArtList}:{tipoArt}:{azienda}:{sKey}:{numRecord}"; return await GetOrFetchAsync( operationName: "ArticoliGetSearchAsync", cacheKey: redisKey, - expiration: TimeSpan.FromMinutes(2), + expiration: TimeSpan.FromMinutes(redisLongTimeCache), fetchFunc: async () => - await dbController.ArticoliGetSearchAsync(numRecord, azienda, searchVal) + await dbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal) ?? new List() ); } diff --git a/MP.SPEC/Pages/Articoli.razor b/MP.SPEC/Pages/Articoli.razor index 4a655d60..6d484868 100644 --- a/MP.SPEC/Pages/Articoli.razor +++ b/MP.SPEC/Pages/Articoli.razor @@ -12,17 +12,31 @@

Articoli

- + @if (CanAdd) + { + + }
+ + - - + + - @if (ListAziende != null) { foreach (var item in ListAziende) @@ -47,11 +61,11 @@
Codice - @if(isNewArt) + @if (isNewArt) { } - else + else { } @@ -83,15 +97,31 @@
Tipo - + @if (ListTipoArt != null) { - + foreach (var item in ListTipoArt) + { + + } } - } - + + } + else + { + + } +
@@ -102,12 +132,12 @@
- +
- +
@@ -154,8 +184,15 @@ { - - + + @if (record.Tipo.Equals("KIT")) + { + + } + else + { + + }
@record.CodArticolo
@@ -171,7 +208,7 @@ @record.Azienda - @if (ArticoloDelEnabled(record.CodArticolo)) + @if (ArticoloDelEnabled(record)) { } @@ -191,7 +228,7 @@
\ No newline at end of file diff --git a/MP.SPEC/Pages/Articoli.razor.cs b/MP.SPEC/Pages/Articoli.razor.cs index ce9bd81e..7e531d58 100644 --- a/MP.SPEC/Pages/Articoli.razor.cs +++ b/MP.SPEC/Pages/Articoli.razor.cs @@ -26,16 +26,6 @@ namespace MP.SPEC.Pages GC.Collect(); } - public async void OnSeachUpdated() - { - await InvokeAsync(() => - { - currPage = 1; - Task task = UpdateData(); - StateHasChanged(); - }); - } - #endregion Public Methods #region Protected Properties @@ -49,10 +39,7 @@ namespace MP.SPEC.Pages [Inject] protected NavigationManager NavManager { get; set; } = null!; - protected string searchCss - { - get => string.IsNullOrEmpty(searchVal) ? "btn-secondary" : "btn-primary"; - } + private string searchCss => string.IsNullOrEmpty(searchVal) ? "btn-secondary" : "btn-primary"; protected string SearchVal { @@ -62,35 +49,12 @@ namespace MP.SPEC.Pages // salvo solo se 3+ chars if (value.Length > 2 || string.IsNullOrEmpty(value)) { - if (searchVal != value) - { - searchVal = value; -#if false - var pUpd = Task.Run(async () => - { - ListRecords = null; - await Task.Delay(1); - await ReloadDataAsync(); - }); - pUpd.Wait(); -#endif - } + searchVal = value; } } } - protected int totalCount - { - get - { - int answ = 0; - if (SearchRecords != null) - { - answ = SearchRecords.Count; - } - return answ; - } - } + protected int totalCount = 0; #endregion Protected Properties @@ -100,30 +64,26 @@ namespace MP.SPEC.Pages /// Crea nuovo record e va in editing... /// /// - protected async Task addNew() + protected void AddNew() { isNewArt = true; currRecord = new AnagArticoliModel() { CodArticolo = $"_NEW_{DateTime.Now:yyyyMMdd.HHmmss}", DescArticolo = "Nuovo articolo", - Azienda = selAzienda != "*" ? selAzienda : "MAPO", + Azienda = !selAzienda.Equals("*") ? selAzienda : "MAPO", Disegno = "", - Tipo = "ART", + Tipo = !selTipoArt.Equals("*") ? selTipoArt : "ART", CurrRev = "", ProdRev = "" }; - await Task.Delay(1); } - protected async Task cancel() - { - currRecord = null; - await ReloadDataAsync(); - await Task.Delay(1); - } - - protected async Task cloneRecord(AnagArticoliModel selRec) + /// + /// Cloning record + /// + /// + protected void cloneRecord(AnagArticoliModel selRec) { isNewArt = true; // creo record duplicato... @@ -138,7 +98,6 @@ namespace MP.SPEC.Pages ProdRev = "" }; currRecord = newRec; - await Task.Delay(1); } /// @@ -184,10 +143,10 @@ namespace MP.SPEC.Pages currRecord = null; } - protected async Task resetSearch() + protected async Task ResetSearch() { SearchVal = ""; - await ReloadDataAsync(); + await ResetDataAsync(); } protected async Task resetSel() @@ -204,19 +163,18 @@ namespace MP.SPEC.Pages await Task.Delay(1); } - protected async Task update(AnagArticoliModel selRec) + protected async Task UpdateAsync(AnagArticoliModel selRec) { if (!await JSRuntime.InvokeAsync("confirm", "Confermi di voler salvare le modifiche?")) return; - await Task.Delay(1); + var done = await MDService.ArticoliUpdateRecord(selRec); - currRecord = null; - await ReloadDataAsync(); - await Task.Delay(1); + await ResetDataAsync(); } - protected async Task UpdateData() + protected async Task ResetDataAsync() { + currPage = 1; currRecord = null; await ReloadDataAsync(); } @@ -239,9 +197,8 @@ namespace MP.SPEC.Pages #region Private Properties - private int _currPage { get; set; } = 1; - private int _numRecord { get; set; } = 10; - private string chkDisabled => isNewArt ? "" : "disabled"; + private int _currPage = 1; + private int _numRecord = 10; private int currPage { @@ -281,26 +238,14 @@ namespace MP.SPEC.Pages if (value != _selAzienda) { _selAzienda = value; -#if false - var pUpd = Task.Run(async () => - { - // svuoto cache redis... - ConfigModel updRec = new ConfigModel() - { - Chiave = "AZIENDA", - Valore = value - }; - MDService.ConfigUpdate(updRec); - await MDService.ConfigResetCache(); - // ricarico - await Task.Delay(1); - await ReloadDataAsync(); - }); - pUpd.Wait(); -#endif } } } + /// + /// Tipo articolo selezionato + /// + private string selTipoArt = "*"; + private async Task ReloadAziendaAsync() { isLoading = true; @@ -313,7 +258,7 @@ namespace MP.SPEC.Pages await MDService.ConfigUpdateAsync(updRec); await MDService.ConfigResetCache(); // ricarico - await ReloadDataAsync(); + await ResetDataAsync(); } @@ -328,9 +273,12 @@ namespace MP.SPEC.Pages /// /// /// - private bool ArticoloDelEnabled(string codArt) + private bool ArticoloDelEnabled(AnagArticoliModel currRec) { - return MDService.ArticoloDelEnabled(codArt); + if (currRec.Tipo.Equals("KIT")) + return false; + + return MDService.ArticoloDelEnabled(currRec.CodArticolo); } private async Task ReloadBaseData() @@ -345,10 +293,16 @@ namespace MP.SPEC.Pages ListTipoArt = await MDService.AnagTipoArtLvAsync(); } + /// + /// Verifica cablata x add tutto tranne KIT + /// + private bool CanAdd => !selTipoArt.Equals("KIT"); + private async Task ReloadDataAsync() { isLoading = true; - SearchRecords = await MDService.ArticoliGetSearchAsync(maxNumRecord, selAzienda, SearchVal); + SearchRecords = await MDService.ArticoliGetSearchAsync(maxNumRecord, selTipoArt, selAzienda, SearchVal); + totalCount = SearchRecords.Count; UpdateTable(); } From e30e9808339101a78fca1f36b03947939edde650 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 16:31:24 +0200 Subject: [PATCH 019/102] Completo update gestione articoli editabili (KIT no...) --- MP.SPEC/Pages/PODL.razor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MP.SPEC/Pages/PODL.razor.cs b/MP.SPEC/Pages/PODL.razor.cs index aaf0d96c..9cd43918 100644 --- a/MP.SPEC/Pages/PODL.razor.cs +++ b/MP.SPEC/Pages/PODL.razor.cs @@ -499,7 +499,7 @@ namespace MP.SPEC.Pages { isLoading = true; ListMacchine = await MDService.MacchineGetFiltAsync(selReparto); - ListArticoli = await MDService.ArticoliGetSearchAsync(100, currAzienda, artSearch); + ListArticoli = await MDService.ArticoliGetSearchAsync(100, "*", currAzienda, artSearch); if (ListGruppiFase != null) { var firstGroup = ListGruppiFase.Where(x => x.CodGruppo == selReparto).FirstOrDefault(); From 0526a81e8e43f5de23683aa1616b3a9038d8f64c Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 16:31:30 +0200 Subject: [PATCH 020/102] ancora fix gestione KIT --- MP-TAB3/Components/SelectCodArt.razor.cs | 2 +- MP-TAB3/Components/TcHistoryFilter.razor.cs | 2 +- MP.Data/Controllers/MpSpecController.cs | 22 --------------- MP.Data/Services/ListSelectDataSrv.cs | 8 +++--- MP.IOC/Data/MpDataService.cs | 31 +++++++++++---------- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Articoli.razor.cs | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 14 files changed, 32 insertions(+), 51 deletions(-) diff --git a/MP-TAB3/Components/SelectCodArt.razor.cs b/MP-TAB3/Components/SelectCodArt.razor.cs index f1a0b850..4fb4dd3b 100644 --- a/MP-TAB3/Components/SelectCodArt.razor.cs +++ b/MP-TAB3/Components/SelectCodArt.razor.cs @@ -105,7 +105,7 @@ namespace MP_TAB3.Components if (!ListArtDisabled) { Log.Debug("START GetArticoli"); - var rawData = await MDataService.ArticoliGetSearch(10000, "*", searchVal); + var rawData = await MDataService.ArticoliGetSearch(10000,"*", "*", searchVal); // trasformo! if (rawData != null) { diff --git a/MP-TAB3/Components/TcHistoryFilter.razor.cs b/MP-TAB3/Components/TcHistoryFilter.razor.cs index 004c0bab..f9898a35 100644 --- a/MP-TAB3/Components/TcHistoryFilter.razor.cs +++ b/MP-TAB3/Components/TcHistoryFilter.razor.cs @@ -137,7 +137,7 @@ namespace MP_TAB3.Components if (!ListArtDisabled) { Log.Debug("START GetArticoli"); - var rawData = await MDataService.ArticoliGetSearch(10000, "*", searchVal); + var rawData = await MDataService.ArticoliGetSearch(10000,"*", "*", searchVal); // trasformo! if (rawData != null) { diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 969105e9..3a06287d 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -476,28 +476,6 @@ namespace MP.Data.Controllers return dbResult; } - /// - /// Elenco tabella Articoli da filtro - /// - /// - /// - /// - public List ArticoliGetSearch(int numRecord, string searchVal = "") - { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbSetArticoli - .AsNoTracking() - .Where(x => x.CodArticolo.Contains(searchVal) || x.DescArticolo.Contains(searchVal) || x.Disegno.Contains(searchVal) || string.IsNullOrEmpty(searchVal)) - .OrderBy(x => x.CodArticolo) - .Take(numRecord) - .ToList(); - } - return dbResult; - } - /// /// Elenco tabella Articoli da filtro /// diff --git a/MP.Data/Services/ListSelectDataSrv.cs b/MP.Data/Services/ListSelectDataSrv.cs index 2e49fc21..1452f71a 100644 --- a/MP.Data/Services/ListSelectDataSrv.cs +++ b/MP.Data/Services/ListSelectDataSrv.cs @@ -54,14 +54,14 @@ namespace MP.Data.Services /// cod azienda, * = tutte /// Ricerca testuale /// - public async Task> ArticoliGetSearch(int numRecord, string azienda, string searchVal) + public async Task> ArticoliGetSearch(int numRecord, string tipoArt, string azienda, string searchVal) { string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); List? result = new List(); // cerco in _redisConn... - string currKey = $"{redisBaseKey}:Art:{azienda}:{searchVal}:{numRecord}"; + string currKey = $"{redisBaseKey}:Art:{azienda}:{tipoArt}:{searchVal}:{numRecord}"; RedisValue rawData = await _redisDb.StringGetAsync(currKey); if (rawData.HasValue) { @@ -70,7 +70,7 @@ namespace MP.Data.Services } else { - result = await dbController.ArticoliGetSearchAsync(numRecord, azienda, searchVal); + result = await dbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await _redisDb.StringSetAsync(currKey, rawData, LongCache); @@ -80,7 +80,7 @@ namespace MP.Data.Services result = new List(); } sw.Stop(); - Log.Debug($"ArticoliGetSearchAsync | azienda: {azienda} | searchVal: {searchVal} | numRecord: {numRecord} | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + Log.Trace($"ArticoliGetSearchAsync | azienda: {azienda} | tipoArt: {tipoArt} | searchVal: {searchVal} | numRecord: {numRecord} | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs index 922965f3..8a0b1373 100644 --- a/MP.IOC/Data/MpDataService.cs +++ b/MP.IOC/Data/MpDataService.cs @@ -371,7 +371,7 @@ namespace MP.IOC.Data } else { - result = await Task.FromResult(SpecDbController.AnagStatiComm()); + result = await SpecDbController.AnagStatiCommAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(Utils.redisStatoCom, rawData, getRandTOut(redisLongTimeCache)); @@ -425,7 +425,7 @@ namespace MP.IOC.Data } else { - result = await Task.FromResult(SpecDbController.AnagTipoArtLV()); + result = await SpecDbController.AnagTipoArtLvAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(Utils.redisTipoArt, rawData, getRandTOut(redisLongTimeCache)); @@ -527,16 +527,18 @@ namespace MP.IOC.Data /// Restitusice elenco articoli cercati /// /// + /// + /// /// /// - public async Task> ArticoliGetSearch(int numRecord, string azienda, string searchVal) + public async Task> ArticoliGetSearchAsync(int numRecord, string tipoArt, string azienda, string searchVal) { List? result = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); string readType = "DB"; string sKey = string.IsNullOrEmpty(searchVal) ? "***" : searchVal; - string currKey = $"{Utils.redisArtList}:{azienda}:{sKey}"; + string currKey = $"{Utils.redisArtList}:{azienda}:{tipoArt}:{sKey}"; // cerco in redis dato valOut sel macchina... RedisValue rawData = redisDb.StringGet(currKey); if (rawData.HasValue) @@ -546,7 +548,7 @@ namespace MP.IOC.Data } else { - result = await Task.FromResult(SpecDbController.ArticoliGetSearch(numRecord, azienda, searchVal)); + result = await SpecDbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache / 5)); @@ -557,7 +559,7 @@ namespace MP.IOC.Data } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"ArticoliGetSearch | Read from {readType}: {ts.TotalMilliseconds}ms"); + Log.Debug($"ArticoliGetSearchAsync | Read from {readType}: {ts.TotalMilliseconds}ms"); return result; } @@ -1095,9 +1097,9 @@ namespace MP.IOC.Data /// Update chiave config /// /// - public async Task ConfigUpdate(ConfigModel updRec) + public Task ConfigUpdateAsync(ConfigModel updRec) { - return await Task.FromResult(SpecDbController.ConfigUpdate(updRec)); + return SpecDbController.ConfigUpdateAsync(updRec); } /// @@ -1310,7 +1312,7 @@ namespace MP.IOC.Data /// public Task> ElencoAziende() { - return Task.FromResult(SpecDbController.AnagGruppiAziende()); + return SpecDbController.AnagGruppiAziendeAsync(); } /// @@ -2513,7 +2515,7 @@ namespace MP.IOC.Data /// /// /// - public List OdlGetCurrent() + public async Task> OdlGetCurrentAsync() { List? dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); @@ -2521,7 +2523,7 @@ namespace MP.IOC.Data string readType = "DB"; string currKey = $"{Utils.redisOdlCurrByMac}"; // cerco in redis dato valOut sel macchina... - RedisValue rawData = redisDb.StringGet(currKey); + RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { try @@ -2534,9 +2536,10 @@ namespace MP.IOC.Data } else { - dbResult = SpecDbController.OdlGetCurrent().Select(x => x.IdxMacchina).Distinct().ToList(); + var rawList = await SpecDbController.OdlGetCurrentAsync(); + dbResult = rawList.Select(x => x.IdxMacchina).Distinct().ToList(); rawData = JsonConvert.SerializeObject(dbResult); - redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(3)); + await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(3)); } if (dbResult == null) { @@ -2544,7 +2547,7 @@ namespace MP.IOC.Data } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"OdlGetCurrent | Read from {readType}: {ts.TotalMilliseconds}ms"); + Log.Debug($"OdlGetCurrentAsync | Read from {readType}: {ts.TotalMilliseconds}ms"); return dbResult; } diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 0fcaf0ac..62cbd0db 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.2519 + 8.16.2605.2716 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 55973e10..0f957edb 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

Versione: 8.16.2605.2519

+

Versione: 8.16.2605.2716


Note di rilascio:
  • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index a68d1899..9a3dbb19 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2519 +8.16.2605.2716 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 324cc6c2..13b44d66 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2519 + 8.16.2605.2716 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 5cae1802..d1b23d66 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2714 + 8.16.2605.2716 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Articoli.razor.cs b/MP.SPEC/Pages/Articoli.razor.cs index 7e531d58..771bff51 100644 --- a/MP.SPEC/Pages/Articoli.razor.cs +++ b/MP.SPEC/Pages/Articoli.razor.cs @@ -269,7 +269,7 @@ namespace MP.SPEC.Pages #region Private Methods /// - /// Seleziona record x editing + /// Verifica cancellabilità record /// /// /// diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index f9337c57..6f105936 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

    Versione: 8.16.2605.2714

    +

    Versione: 8.16.2605.2716


    Note di rilascio:
    • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 55b93cf6..9a3dbb19 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2714 +8.16.2605.2716 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index a591e4cf..003046c0 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2714 + 8.16.2605.2716 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From 15605f2a008da1293a2b6da9483d4fec94ef199f Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 19:12:31 +0200 Subject: [PATCH 021/102] Update gestione tags x eliminazione cache ottimizzata --- MP.Data/Controllers/MpSpecController.cs | 24 ++++++------- MP.SPEC/Data/MpDataService.cs | 46 ++++++++++--------------- MP.SPEC/Pages/RepStop.razor.cs | 2 +- 3 files changed, 29 insertions(+), 43 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 3a06287d..938a45e0 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -122,21 +122,17 @@ namespace MP.Data.Controllers /// Nome Table x filtro (std: EvList) /// Nome Field x filtro (std: Common) /// - public List AnagEventiGeneral(string TableName = "EvList", string FieldName = "Common") + public async Task> AnagEventiGeneralAsync(string TableName = "EvList", string FieldName = "Common") { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - var pTableName = new SqlParameter("@TableName", TableName); - var pFieldName = new SqlParameter("@FieldName", FieldName); - dbResult = dbCtx - .DbSetVSEB - .FromSqlRaw("exec dbo.stp_vseb_getGenerallyAvailable @TableName, @FieldName", pTableName, pFieldName) - .AsNoTracking() - .AsEnumerable() - .ToList(); - } - return dbResult; + using var dbCtx = new MoonProContext(options); + var pTableName = new SqlParameter("@TableName", TableName); + var pFieldName = new SqlParameter("@FieldName", FieldName); + var dbResult = await dbCtx + .DbSetVSEB + .FromSqlRaw("exec dbo.stp_vseb_getGenerallyAvailable @TableName, @FieldName", pTableName, pFieldName) + .AsNoTracking() + .ToListAsync(); + return dbResult ?? new(); } /// diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 5bb2bfd7..21b88660 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -157,35 +157,25 @@ namespace MP.SPEC.Data /// Elenco EVENTI validi x ogni macchina secondo conf standard macchina /// /// - public List AnagEventiGeneral() + public async Task> AnagEventiGeneralAsync() { - using var activity = ActivitySource.StartActivity("AnagEventiGeneral"); - string source = "DB"; - List? result = new List(); - // cerco in redisConn... - string currKey = $"{Utils.redisEventList}:VSEB:GENERAL"; - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = dbController.AnagEventiGeneral(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"AnagEventiGeneral | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return result; + string redisKey = $"{Utils.redisEventList}:VSEB:GENERAL"; + + return await GetOrFetchAsync( + operationName: "AnagEventiGeneralAsync", + cacheKey: redisKey, + expiration: getRandTOut(redisLongTimeCache), + fetchFunc: async () => + { + RedisValue rawData = await redisDb.StringGetAsync(redisKey); + if (rawData.HasValue) + { + return JsonConvert.DeserializeObject>($"{rawData}") ?? new List(); + } + + return await dbController.AnagEventiGeneralAsync() ?? new List(); + } + ); } /// diff --git a/MP.SPEC/Pages/RepStop.razor.cs b/MP.SPEC/Pages/RepStop.razor.cs index 2bc4bd0c..20317090 100644 --- a/MP.SPEC/Pages/RepStop.razor.cs +++ b/MP.SPEC/Pages/RepStop.razor.cs @@ -212,7 +212,7 @@ namespace MP.SPEC.Pages private async Task ReloadData() { CurrMSE = await MDService.MseGetAll(false); - SearchFermate = MDService.AnagEventiGeneral(); + SearchFermate = await MDService.AnagEventiGeneralAsync(); } #endregion Private Methods From d8bc1379be3f8a1bfc421a10d6c462363d97581d Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 19:12:57 +0200 Subject: [PATCH 022/102] Ancora update componenti con review tags --- MP.SPEC/Components/ListPODL.razor.cs | 6 +- MP.SPEC/Data/MpDataService.cs | 110 +++++++++++++++------------ MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 6 files changed, 67 insertions(+), 57 deletions(-) diff --git a/MP.SPEC/Components/ListPODL.razor.cs b/MP.SPEC/Components/ListPODL.razor.cs index b131fcac..e6ac8080 100644 --- a/MP.SPEC/Components/ListPODL.razor.cs +++ b/MP.SPEC/Components/ListPODL.razor.cs @@ -215,7 +215,7 @@ namespace MP.SPEC.Components ListRecords = null; isLoading = true; - var list = await MDService.OdlGetCurrentAsync(); + var list = await MDService.MachineWithOdlAsync(); _odlCurrSet = list.ToHashSet(); var machines = await MDService.MacchineGetFiltAsync("*"); @@ -610,7 +610,7 @@ namespace MP.SPEC.Components } /// - /// verifica se sia avviabile ODL x idxMaccSel + /// Verifica se sia avviabile ODL x idxMaccSel /// /// /// @@ -621,7 +621,7 @@ namespace MP.SPEC.Components private async Task UpdateOdlList() { - var list = await MDService.OdlGetCurrentAsync(); + var list = await MDService.MachineWithOdlAsync(); _odlCurrSet = list.ToHashSet(); } diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 21b88660..eb470669 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -159,22 +159,15 @@ namespace MP.SPEC.Data /// public async Task> AnagEventiGeneralAsync() { - string redisKey = $"{Utils.redisEventList}:VSEB:GENERAL"; - return await GetOrFetchAsync( operationName: "AnagEventiGeneralAsync", - cacheKey: redisKey, + cacheKey: $"{Utils.redisEventList}:VSEB:GENERAL", expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => { - RedisValue rawData = await redisDb.StringGetAsync(redisKey); - if (rawData.HasValue) - { - return JsonConvert.DeserializeObject>($"{rawData}") ?? new List(); - } - return await dbController.AnagEventiGeneralAsync() ?? new List(); - } + }, + tagList: [Utils.redisEventList] ); } @@ -292,7 +285,8 @@ namespace MP.SPEC.Data cacheKey: Utils.redisStatoCom, expiration: TimeSpan.FromMinutes(redisLongTimeCache), fetchFunc: async () => - await dbController.AnagStatiCommAsync() ?? new List() + await dbController.AnagStatiCommAsync() ?? new List(), + tagList: [Utils.redisStatoCom] ); } @@ -395,8 +389,8 @@ namespace MP.SPEC.Data cacheKey: redisKey, expiration: TimeSpan.FromMinutes(2), fetchFunc: async () => - await dbController.ArticoliGetByTipoAsync(tipo, azienda) - ?? new List() + await dbController.ArticoliGetByTipoAsync(tipo, azienda) ?? new List(), + tagList: [Utils.redisArtList, $"{Utils.redisArtList}:Tipo"] ); } @@ -417,8 +411,8 @@ namespace MP.SPEC.Data cacheKey: redisKey, expiration: TimeSpan.FromMinutes(redisLongTimeCache), fetchFunc: async () => - await dbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal) - ?? new List() + await dbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal) ?? new List(), + tagList: [Utils.redisArtList, $"{Utils.redisArtList}:Search"] ); } @@ -480,7 +474,7 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ArticoloDelEnabled | Cod: {codArticolo} | Source: {source}"); + LogTrace($"ArticoloDelEnabled | Cod: {codArticolo} | {source} | {activity?.Duration.TotalMilliseconds}ms"); return !usato; } @@ -796,7 +790,8 @@ namespace MP.SPEC.Data cacheKey: $"{Utils.redisAnagGruppi}:Aziende", expiration: TimeSpan.FromMinutes(redisLongTimeCache * 2), fetchFunc: async () => - await dbController.AnagGruppiAziendeAsync() ?? new List() + await dbController.AnagGruppiAziendeAsync() ?? new List(), + tagList: [Utils.redisAnagGruppi, $"{Utils.redisAnagGruppi}:Aziende"] ); } @@ -1086,11 +1081,9 @@ namespace MP.SPEC.Data /// public async Task FlushCacheAsync() { - bool fatto = false; - await _cache.ClearAsync(); + await _cache.ClearAsync(allowFailSafe: false); _configData.Clear(); - fatto = true; - return fatto; + return true; } /// @@ -1099,11 +1092,11 @@ namespace MP.SPEC.Data /// public async Task FlushCacheByTagAsync(string tag) { - bool fatto = false; + if (string.IsNullOrWhiteSpace(tag)) return false; + await _cache.RemoveByTagAsync(tag); _configData.Clear(); - fatto = true; - return fatto; + return true; } /// @@ -1112,14 +1105,17 @@ namespace MP.SPEC.Data /// public async Task FlushCacheByTagsAsync(List listTags) { - bool fatto = false; - foreach (var item in listTags) - { - await _cache.RemoveByTagAsync(item); - } + if (listTags == null || listTags.Count == 0) return false; + + // Generiamo i Task di rimozione ed eseguiamoli in parallelo su Redis/L1 + var tasks = listTags + .Where(tag => !string.IsNullOrWhiteSpace(tag)) + .Select(tag => _cache.RemoveByTagAsync(tag).AsTask()); + + await Task.WhenAll(tasks); + _configData.Clear(); - fatto = true; - return fatto; + return true; } public async Task FlushCacheFluxLog() @@ -1681,9 +1677,7 @@ namespace MP.SPEC.Data public async Task> MacchineGetFiltAsync(string codGruppo) { string keyGrp = codGruppo != "*" ? codGruppo : "ALL"; - string redisKey = $"{Utils.redisMacList}:{keyGrp}"; - string memKey = $"MACCHINE_MEM:{keyGrp}"; return await GetOrFetchAsync( operationName: "MacchineGetFiltAsync", @@ -1691,7 +1685,8 @@ namespace MP.SPEC.Data expiration: TimeSpan.FromMinutes(5), fetchFunc: async () => await dbController.MacchineGetFiltAsync(codGruppo) - ?? new List() + ?? new List(), + tagList: [Utils.redisMacList] ); } @@ -2005,13 +2000,12 @@ namespace MP.SPEC.Data return dbResult; } - public async Task> OdlGetCurrentAsync() + public async Task> MachineWithOdlAsync() { string redisKey = Utils.redisOdlCurrByMac; - string memKey = $"MEM:{redisKey}"; return await GetOrFetchAsync( - operationName: "OdlGetCurrentAsync", + operationName: "MachineWithOdlAsync", cacheKey: redisKey, expiration: TimeSpan.FromSeconds(3), fetchFunc: async () => @@ -2023,7 +2017,8 @@ namespace MP.SPEC.Data .ToList(); return dbResult ?? new List(); - } + }, + tagList: [Utils.redisOdlCurrByMac] ); } @@ -2448,7 +2443,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "POdlToKitListGetFiltAsync", cacheKey: redisKey, - expiration: TimeSpan.FromSeconds(redisShortTimeCache), + expiration: TimeSpan.FromSeconds(redisShortTimeCache * 5), fetchFunc: async () => await dbController.ListPODL_KitFiltAsync( lanciato, @@ -2457,7 +2452,8 @@ namespace MP.SPEC.Data codGruppo, startDate, endDate - ) ?? new List() + ) ?? new List(), + tagList: [Utils.redisPOdlList, $"{Utils.redisPOdlList}_kit"] ); } @@ -3273,7 +3269,7 @@ namespace MP.SPEC.Data /// /// /// - private async Task GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tags) + private async Task GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tagList) { using var activity = ActivitySource.StartActivity(operationName); string source; @@ -3289,6 +3285,13 @@ namespace MP.SPEC.Data return result; } bool fromDb = false; + // cache in redis + var cacheOptions = new FusionCacheEntryOptions() + .SetDuration(expiration) + .SetFailSafe(true); + // cache in RAM per 1/3 del tempo x risparmiare risorse + cacheOptions.MemoryCacheDuration = expiration / 3; + var final = await _cache.GetOrSetAsync( cacheKey, async _ => @@ -3296,19 +3299,26 @@ namespace MP.SPEC.Data fromDb = true; return await fetchFunc(); }, - opt => - { - opt.SetDuration(expiration) - .SetFailSafe(true); - - //if (tags != null && tags.Length > 0) - // opt.SetTags(tags); - }); + options: cacheOptions, + tags: tagList + ); source = fromDb ? "DB" : "REDIS"; activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); + // switch log in base a source.. + switch (source) + { + case "DB": + LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms", reqLevel: NLog.LogLevel.Info); + break; + case "REDIS": + LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms", reqLevel: NLog.LogLevel.Debug); + break; + default: + LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); + break; + } return final!; } diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index d1b23d66..639786b0 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2716 + 8.16.2605.2719 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 6f105936..3f685ead 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

      Versione: 8.16.2605.2716

      +

      Versione: 8.16.2605.2719


      Note di rilascio:
      • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 9a3dbb19..a3677dd7 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2716 +8.16.2605.2719 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 003046c0..2bef6128 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2716 + 8.16.2605.2719 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From 2fce840ed9ae4cecb7c6bd193271d563b6768273 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 19:28:13 +0200 Subject: [PATCH 023/102] Preparazione metodi Async pre conversione FusionCache --- MP.Data/Controllers/MpSpecController.cs | 24 ++++++- MP.SPEC/Components/Layout/NavMenu.razor.cs | 5 +- MP.SPEC/Components/ListODL.razor | 4 +- MP.SPEC/Components/ListODL.razor.cs | 4 +- MP.SPEC/Components/ListPODL.razor | 4 +- MP.SPEC/Components/ListPODL.razor.cs | 4 +- MP.SPEC/Components/ProdKit/KitVerify.razor | 4 +- MP.SPEC/Components/ProdKit/KitVerify.razor.cs | 8 +-- MP.SPEC/Data/MpDataService.cs | 18 ++--- MP.SPEC/Pages/Index.razor.cs | 3 +- MP.SPEC/Pages/KIT.razor | 4 +- MP.SPEC/Pages/KIT.razor.cs | 71 +++++++++++-------- 12 files changed, 90 insertions(+), 63 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 938a45e0..c1d5e02d 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -871,9 +871,9 @@ namespace MP.Data.Controllers /// Elenco valori link (x home e navMenu laterale) ///
      /// - public List ElencoLink() + public Task> ElencoLinkAsync() { - return ListLinkFilt("SpecLink"); + return ListLinkFiltAsync("SpecLink"); } /// @@ -1412,6 +1412,26 @@ namespace MP.Data.Controllers return dbResult; } + /// + /// Elenco link JQM dato filtro tipo, Async + /// + /// + /// + public async Task> ListLinkFiltAsync(string tipoLink) + { + List dbResult = new List(); + using (var dbCtx = new MoonProContext(options)) + { + dbResult = await dbCtx + .DbSetLinkMenu + .Where(x => x.TipoLink == tipoLink) + .AsNoTracking() + .OrderBy(x => x.Ordine) + .ToListAsync(); + } + return dbResult; + } + /// /// Elenco ODL filtrati x stato, articolo, KeyRich (che contiene stato) /// diff --git a/MP.SPEC/Components/Layout/NavMenu.razor.cs b/MP.SPEC/Components/Layout/NavMenu.razor.cs index 87d2a650..1bc7153e 100644 --- a/MP.SPEC/Components/Layout/NavMenu.razor.cs +++ b/MP.SPEC/Components/Layout/NavMenu.razor.cs @@ -1,5 +1,4 @@ using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Mvc.RazorPages; using MP.SPEC.Data; namespace MP.SPEC.Components.Layout @@ -62,9 +61,9 @@ namespace MP.SPEC.Components.Layout return MsgService.HasRole(Ruolo); } - protected override void OnInitialized() + protected override async Task OnInitializedAsync() { - ElencoLink = MDService.ElencoLink(); + ElencoLink = await MDService.ElencoLinkAsync(); MService.EA_PageUpdated += OnPageUpdate; } diff --git a/MP.SPEC/Components/ListODL.razor b/MP.SPEC/Components/ListODL.razor index 0922b913..c7f09dfa 100644 --- a/MP.SPEC/Components/ListODL.razor +++ b/MP.SPEC/Components/ListODL.razor @@ -11,7 +11,7 @@ else
      @if (showKitDetail) { - + } @if (currRecord != null && !showStats && isCurrOdl) { @@ -109,7 +109,7 @@ else @record.CodArticolo @if (CheckIsKit(record.CodArticolo)) { - + }
      @record.DescArticolo
      diff --git a/MP.SPEC/Components/ListODL.razor.cs b/MP.SPEC/Components/ListODL.razor.cs index 480caa30..c5791926 100644 --- a/MP.SPEC/Components/ListODL.razor.cs +++ b/MP.SPEC/Components/ListODL.razor.cs @@ -191,11 +191,11 @@ namespace MP.SPEC.Components return answ; } - protected void KitToggleDetail(string? selCodArt) + protected async Task KitToggleDetailAsync(string? selCodArt) { if (!string.IsNullOrEmpty(selCodArt)) { - ListKitTemplate = MDService.TemplateKitFilt(selCodArt, ""); + ListKitTemplate = await MDService.TemplateKitFiltAsync(selCodArt, ""); } else { diff --git a/MP.SPEC/Components/ListPODL.razor b/MP.SPEC/Components/ListPODL.razor index 109b0421..ac739a63 100644 --- a/MP.SPEC/Components/ListPODL.razor +++ b/MP.SPEC/Components/ListPODL.razor @@ -16,7 +16,7 @@ else
      @if (showKitDetail) { - + } @@ -143,7 +143,7 @@ else @record.CodArticolo @if (CheckIsKit(record.CodArticolo)) { - + }
      @record.DescArticolo
      diff --git a/MP.SPEC/Components/ListPODL.razor.cs b/MP.SPEC/Components/ListPODL.razor.cs index e6ac8080..4b75606b 100644 --- a/MP.SPEC/Components/ListPODL.razor.cs +++ b/MP.SPEC/Components/ListPODL.razor.cs @@ -151,11 +151,11 @@ namespace MP.SPEC.Components await RecordEdit.InvokeAsync(selRec); } - protected void KitToggleDetail(PODLExpModel? recSel) + protected async Task KitToggleDetailAsync(PODLExpModel? recSel) { if (recSel != null) { - ListKitTemplate = MDService.TemplateKitFilt(recSel.CodArticolo, ""); + ListKitTemplate = await MDService.TemplateKitFiltAsync(recSel.CodArticolo, ""); ListPOdlKit = MDService.POdlListByKitParent(recSel.IdxPromessa); } else diff --git a/MP.SPEC/Components/ProdKit/KitVerify.razor b/MP.SPEC/Components/ProdKit/KitVerify.razor index 96e5f8ba..6ead57b4 100644 --- a/MP.SPEC/Components/ProdKit/KitVerify.razor +++ b/MP.SPEC/Components/ProdKit/KitVerify.razor @@ -16,7 +16,7 @@ { @if (doShowDetail) { - + }
      @@ -33,7 +33,7 @@ { diff --git a/MP.SPEC/Components/ProdKit/KitVerify.razor.cs b/MP.SPEC/Components/ProdKit/KitVerify.razor.cs index 13868a07..96c13bc6 100644 --- a/MP.SPEC/Components/ProdKit/KitVerify.razor.cs +++ b/MP.SPEC/Components/ProdKit/KitVerify.razor.cs @@ -41,17 +41,17 @@ namespace MP.SPEC.Components.ProdKit #region Protected Methods - protected void KitToggleDetail(TksScoreModel? currRec) + protected async Task KitToggleDetailAsync(TksScoreModel? currRec) { CodArtParent = currRec != null ? currRec.CodArtParent : ""; if (!string.IsNullOrEmpty(CodArtParent)) { - ListKitTemplate = MDService.TemplateKitFilt(CodArtParent, ""); + ListKitTemplate = await MDService.TemplateKitFiltAsync(CodArtParent, ""); totalKitCount = ListKitTemplate.Count; ListRecKitPODL = PodlRecords - .Where(x => !string.IsNullOrEmpty(x.KeyRichiesta) + .Where(x => !string.IsNullOrEmpty(x.KeyRichiesta) && x.KeyRichiesta.StartsWith("KIT") - && x.CodArticolo==CodArtParent) + && x.CodArticolo == CodArtParent) .ToList(); } else diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index eb470669..13acb697 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -838,14 +838,14 @@ namespace MP.SPEC.Data /// Elenco link validi /// /// - public List ElencoLink() + public async Task> ElencoLinkAsync() { - using var activity = ActivitySource.StartActivity("ElencoLink"); + using var activity = ActivitySource.StartActivity("ElencoLinkAsync"); string source = "DB"; - var linkList = dbController.ElencoLink(); + var linkList = await dbController.ElencoLinkAsync(); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ElencoLink | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ElencoLinkAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return linkList; } @@ -2773,14 +2773,14 @@ namespace MP.SPEC.Data /// /// /// - public List TemplateKitFilt(string codParent, string codChild) + public async Task> TemplateKitFiltAsync(string codParent, string codChild) { - using var activity = ActivitySource.StartActivity("TemplateKitFilt"); + using var activity = ActivitySource.StartActivity("TemplateKitFiltAsync"); string source = "DB"; List? result = new List(); // cerco in redis... string currKey = $"{Utils.redisKitTempl}:{codParent}:{codChild}"; - RedisValue rawData = redisDb.StringGet(currKey); + RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); @@ -2791,7 +2791,7 @@ namespace MP.SPEC.Data result = dbController.TemplateKitFilt(codParent, codChild); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache)); + await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache)); } if (result == null) { @@ -2800,7 +2800,7 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.SetTag("result.count", result.Count); activity?.Stop(); - LogTrace($"TemplateKitFilt | {source} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"TemplateKitFiltAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); return result; } diff --git a/MP.SPEC/Pages/Index.razor.cs b/MP.SPEC/Pages/Index.razor.cs index 0dad9401..5fbbf699 100644 --- a/MP.SPEC/Pages/Index.razor.cs +++ b/MP.SPEC/Pages/Index.razor.cs @@ -1,5 +1,4 @@ using Microsoft.AspNetCore.Components; -using MP.AppAuth.Models; using MP.Data.DbModels; using MP.SPEC.Data; @@ -38,7 +37,7 @@ namespace MP.SPEC.Pages protected override async Task OnInitializedAsync() { // recupero elenco link - ElencoLink = MDService.ElencoLink(); + ElencoLink = await MDService.ElencoLinkAsync(); currAzienda = await MDService.ConfigTryGetAsync("AZIENDA"); await Task.Delay(1); } diff --git a/MP.SPEC/Pages/KIT.razor b/MP.SPEC/Pages/KIT.razor index 2596ab1e..8b46229c 100644 --- a/MP.SPEC/Pages/KIT.razor +++ b/MP.SPEC/Pages/KIT.razor @@ -29,12 +29,12 @@ }
      - +
      - +
      diff --git a/MP.SPEC/Pages/KIT.razor.cs b/MP.SPEC/Pages/KIT.razor.cs index b40dece1..30eb1275 100644 --- a/MP.SPEC/Pages/KIT.razor.cs +++ b/MP.SPEC/Pages/KIT.razor.cs @@ -1,5 +1,4 @@ using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.DataProtection; using Microsoft.JSInterop; using MP.Data.DbModels; using MP.SPEC.Data; @@ -56,9 +55,6 @@ namespace MP.SPEC.Pages if (sCodChild != value) { sCodChild = value; - currPage = 1; - ListRecords = null; - ReloadData(); } } } @@ -75,9 +71,6 @@ namespace MP.SPEC.Pages if (sCodParent != value) { sCodParent = value; - currPage = 1; - ListRecords = null; - ReloadData(); } } } @@ -142,8 +135,7 @@ namespace MP.SPEC.Pages protected async Task DoCancel() { EditRecord = null; - ReloadData(); - await Task.Delay(1); + await ResetDataAsync(); } protected async Task DoClone(TemplateKitModel selRec) @@ -170,11 +162,9 @@ namespace MP.SPEC.Pages if (!await JSRuntime.InvokeAsync("confirm", "Eliminazione riga KIT: sei sicuro di voler procedere?")) return; - await Task.Delay(1); var done = await MDService.TemplateKitDelete(selRec); EditRecord = null; - ReloadData(); - await Task.Delay(1); + await ResetDataAsync(); } /// @@ -203,8 +193,7 @@ namespace MP.SPEC.Pages await Task.Delay(1); var done = await MDService.TemplateKitUpsert(selRec, CodAzienda); EditRecord = null; - ReloadData(); - await Task.Delay(1); + await ResetDataAsync(); } protected override void OnInitialized() @@ -237,15 +226,15 @@ namespace MP.SPEC.Pages } } - protected override void OnParametersSet() + protected override Task OnParametersSetAsync() { - ReloadData(); + return ReloadDataAsync(); } - protected void ResetChild() + protected async Task ResetChild() { SearchChild = ""; - ReloadData(); + await ReloadDataAsync(); } protected void ResetData() @@ -253,10 +242,10 @@ namespace MP.SPEC.Pages EditRecord = null; } - protected void ResetParent() + protected async Task ResetParent() { SearchParent = ""; - ReloadData(); + await ReloadDataAsync(); } protected void ResetSel() @@ -280,10 +269,10 @@ namespace MP.SPEC.Pages numRecord = newNum; } - protected void UpdateData() + protected async Task UpdateData() { EditRecord = null; - ReloadData(); + await ReloadDataAsync(); } #endregion Protected Methods @@ -305,6 +294,7 @@ namespace MP.SPEC.Pages private bool enabKitCount = false; private bool enabKitSearch = false; + private List? ListRecords; private int minChar = 2; @@ -329,7 +319,7 @@ namespace MP.SPEC.Pages if (_currPage != value) { _currPage = value; - ReloadData(); + UpdateTable(); } } } @@ -344,7 +334,7 @@ namespace MP.SPEC.Pages if (_numRecord != value) { _numRecord = value; - ReloadData(); + UpdateTable(); } } } @@ -357,18 +347,25 @@ namespace MP.SPEC.Pages #region Private Methods - private void ReloadData() + /// + /// reeload dati + paginazione + /// + /// + private async Task ReloadDataAsync() { isLoading = true; - SearchRecords = MDService.TemplateKitFilt(SearchParent, SearchChild); + SearchRecords = await MDService.TemplateKitFiltAsync(SearchParent, SearchChild); totalCount = SearchRecords.Count; // conto i kit = distinct... kitCount = SearchRecords.GroupBy(x => x.CodArtParent).Count(); - ListRecords = SearchRecords - .Skip(numRecord * (currPage - 1)) - .Take(numRecord) - .ToList(); - isLoading = false; + UpdateTable(); + } + + private Task ResetDataAsync() + { + currPage = 1; + ListRecords = null; + return ReloadDataAsync(); } /// @@ -392,6 +389,18 @@ namespace MP.SPEC.Pages } } + /// + /// Paginazione dati + /// + private void UpdateTable() + { + ListRecords = SearchRecords? + .Skip(numRecord * (currPage - 1)) + .Take(numRecord) + .ToList() ?? new(); + isLoading = false; + } + #endregion Private Methods } } \ No newline at end of file From 47a952c2040cf422d6d7bdcc2c58853eedfa0c77 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 19:39:10 +0200 Subject: [PATCH 024/102] FIX IOC --- MP.IOC/Data/MpDataService.cs | 8 +++++--- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs index 8a0b1373..7976ffbb 100644 --- a/MP.IOC/Data/MpDataService.cs +++ b/MP.IOC/Data/MpDataService.cs @@ -1354,10 +1354,12 @@ namespace MP.IOC.Data return Task.FromResult(result); } - public Task> ElencoLink() +#if false + public Task> ElencoLinkAsync() { - return Task.FromResult(SpecDbController.ElencoLink()); - } + return SpecDbController.ElencoLinkAsync(); + } +#endif /// /// Aggiunta record EventList diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 62cbd0db..5163209d 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.2716 + 8.16.2605.2719 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 0f957edb..35c7cf13 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

      Versione: 8.16.2605.2716

      +

      Versione: 8.16.2605.2719


      Note di rilascio:
      • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 9a3dbb19..a3677dd7 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2716 +8.16.2605.2719 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 13b44d66..7c9ea58b 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2716 + 8.16.2605.2719 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false From 44c19a2c5fc27f0aebf65489887770e8ddc6065a Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 27 May 2026 19:45:29 +0200 Subject: [PATCH 025/102] Update metodi async con FusionCache --- MP.Core/Utils.cs | 2 + MP.Data/Controllers/MpSpecController.cs | 16 ++-- MP.Data/Services/TabDataService.cs | 2 +- MP.SPEC/Data/MpDataService.cs | 111 +++++++++++++----------- 4 files changed, 70 insertions(+), 61 deletions(-) diff --git a/MP.Core/Utils.cs b/MP.Core/Utils.cs index df5f8ec3..81d30f39 100644 --- a/MP.Core/Utils.cs +++ b/MP.Core/Utils.cs @@ -13,6 +13,8 @@ namespace MP.Core public const string redisAnagGruppi = redisBaseAddr + "Cache:AnagGruppi"; public const string redisAnagStati = redisBaseAddr + "Cache:AnagStati"; + public const string redisLinkMenu = redisBaseAddr + "Cache:LinkMenu"; + public const string redisArtByDossier = redisBaseAddr + "Cache:ArtByDossier"; public const string redisArtList = redisBaseAddr + "Cache:ArtList"; diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index c1d5e02d..e040f492 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -2531,17 +2531,15 @@ namespace MP.Data.Controllers /// /// /// - public List TemplateKitFilt(string KitCode, string codChild) + public async Task> TemplateKitFiltAsync(string KitCode, string codChild) { List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbSetTempKit - .Where(x => (string.IsNullOrEmpty(KitCode) && string.IsNullOrEmpty(codChild)) || (x.CodArtParent.Contains(KitCode) && !string.IsNullOrEmpty(KitCode)) || (x.CodArtChild.Contains(codChild) && !string.IsNullOrEmpty(codChild))) - .AsNoTracking() - .ToList(); - } + using var dbCtx = new MoonProContext(options); + dbResult = await dbCtx + .DbSetTempKit + .Where(x => (string.IsNullOrEmpty(KitCode) && string.IsNullOrEmpty(codChild)) || (x.CodArtParent.Contains(KitCode) && !string.IsNullOrEmpty(KitCode)) || (x.CodArtChild.Contains(codChild) && !string.IsNullOrEmpty(codChild))) + .AsNoTracking() + .ToListAsync(); return dbResult; } diff --git a/MP.Data/Services/TabDataService.cs b/MP.Data/Services/TabDataService.cs index 0f9f4397..51ad1231 100644 --- a/MP.Data/Services/TabDataService.cs +++ b/MP.Data/Services/TabDataService.cs @@ -3498,7 +3498,7 @@ namespace MP.Data.Services result = new List(); } sw.Stop(); - Log.Debug($"TemplateKitFilt | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + Log.Debug($"TemplateKitFiltAsync | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 13acb697..8c23d654 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -290,6 +290,7 @@ namespace MP.SPEC.Data ); } +#if false public async Task> AnagTipoArtLvAsync() { using var activity = ActivitySource.StartActivity("AnagTipoArtLvAsync"); @@ -318,6 +319,22 @@ namespace MP.SPEC.Data activity?.Stop(); LogTrace($"AnagTipoArtLvAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; + } +#endif + + /// + /// Restituisce elenco tipi articolo livello anagrafica + /// + /// + public async Task> AnagTipoArtLvAsync() + { + return await GetOrFetchAsync( + operationName: "AnagTipoArtLvAsync", + cacheKey: Utils.redisTipoArt, + expiration: TimeSpan.FromMinutes(redisLongTimeCache), + fetchFunc: async () => await dbController.AnagTipoArtLvAsync() ?? new List(), + tagList: [Utils.redisTipoArt] + ); } /// @@ -835,18 +852,18 @@ namespace MP.SPEC.Data } /// - /// Elenco link validi + /// Elenco link validi per il menu /// /// public async Task> ElencoLinkAsync() { - using var activity = ActivitySource.StartActivity("ElencoLinkAsync"); - string source = "DB"; - var linkList = await dbController.ElencoLinkAsync(); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"ElencoLinkAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return linkList; + return await GetOrFetchAsync( + operationName: "ElencoLinkAsync", + cacheKey: Utils.redisLinkMenu, + expiration: TimeSpan.FromMinutes(redisLongTimeCache), + fetchFunc: async () => await dbController.ElencoLinkAsync() ?? new List(), + tagList: [Utils.redisLinkMenu] + ); } /// @@ -1797,6 +1814,28 @@ namespace MP.SPEC.Data return result; } + public async Task> MachineWithOdlAsync() + { + string redisKey = Utils.redisOdlCurrByMac; + + return await GetOrFetchAsync( + operationName: "MachineWithOdlAsync", + cacheKey: redisKey, + expiration: TimeSpan.FromSeconds(3), + fetchFunc: async () => + { + var rawData = await dbController.OdlGetCurrentAsync(); + var dbResult = rawData + .Select(x => x.IdxMacchina) + .Distinct() + .ToList(); + + return dbResult ?? new List(); + }, + tagList: [Utils.redisOdlCurrByMac] + ); + } + /// /// Recupero info Machine-IOB x TAB (da info registrate IOB-WIN --> MP-IO) /// @@ -2000,28 +2039,6 @@ namespace MP.SPEC.Data return dbResult; } - public async Task> MachineWithOdlAsync() - { - string redisKey = Utils.redisOdlCurrByMac; - - return await GetOrFetchAsync( - operationName: "MachineWithOdlAsync", - cacheKey: redisKey, - expiration: TimeSpan.FromSeconds(3), - fetchFunc: async () => - { - var rawData = await dbController.OdlGetCurrentAsync(); - var dbResult = rawData - .Select(x => x.IdxMacchina) - .Distinct() - .ToList(); - - return dbResult ?? new List(); - }, - tagList: [Utils.redisOdlCurrByMac] - ); - } - /// /// ODL correnti (tutti) /// @@ -2770,33 +2787,23 @@ namespace MP.SPEC.Data /// /// Elenco Template KIT da ricerca /// - /// - /// + /// Codice articolo padre + /// Codice articolo figlio /// public async Task> TemplateKitFiltAsync(string codParent, string codChild) { using var activity = ActivitySource.StartActivity("TemplateKitFiltAsync"); string source = "DB"; - List? result = new List(); - // cerco in redis... string currKey = $"{Utils.redisKitTempl}:{codParent}:{codChild}"; - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = dbController.TemplateKitFilt(codParent, codChild); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } + + var result = await GetOrFetchAsync( + operationName: "TemplateKitFiltAsync", + cacheKey: currKey, + expiration: TimeSpan.FromMinutes(redisLongTimeCache), + fetchFunc: async () => await dbController.TemplateKitFiltAsync(codParent, codChild) ?? new List(), + tagList: [Utils.redisKitTempl] + ); + activity?.SetTag("data.source", source); activity?.SetTag("result.count", result.Count); activity?.Stop(); @@ -3312,9 +3319,11 @@ namespace MP.SPEC.Data case "DB": LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms", reqLevel: NLog.LogLevel.Info); break; + case "REDIS": LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms", reqLevel: NLog.LogLevel.Debug); break; + default: LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); break; From 102dffcc65513d8cee505090645f156a7b212641 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 07:52:20 +0200 Subject: [PATCH 026/102] Continuo fix con nuova cache x metodi MpDataService --- MP.SPEC/Data/MpDataService.cs | 32 -------------------------------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- Refactor_Plan.md | 3 +++ 6 files changed, 7 insertions(+), 36 deletions(-) diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 8c23d654..efdfdcf6 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -290,38 +290,6 @@ namespace MP.SPEC.Data ); } -#if false - public async Task> AnagTipoArtLvAsync() - { - using var activity = ActivitySource.StartActivity("AnagTipoArtLvAsync"); - string source = "DB"; - List? result = new List(); - // cerco in redis... - RedisValue rawData = await redisDb.StringGetAsync(Utils.redisTipoArt); - if (!string.IsNullOrEmpty($"{rawData}")) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.AnagTipoArtLvAsync(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(Utils.redisTipoArt, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"AnagTipoArtLvAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; - } -#endif - /// /// Restituisce elenco tipi articolo livello anagrafica /// diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 639786b0..8de497e6 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2719 + 8.16.2605.2807 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 3f685ead..02c9ef35 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

        Versione: 8.16.2605.2719

        +

        Versione: 8.16.2605.2807


        Note di rilascio:
        • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index a3677dd7..1cf9982d 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2719 +8.16.2605.2807 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 2bef6128..98823e78 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2719 + 8.16.2605.2807 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/Refactor_Plan.md b/Refactor_Plan.md index ad4963cd..0388a4d9 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -29,6 +29,9 @@ I metodi verranno suddivisi in: #### Fase 2: Refactoring Metodi di Lettura - [x] `ActionGetReq` (Completato) +- [x] `TemplateKitFiltAsync` +- [x] `AnagTipoArtLvAsync` +- [x] `ElencoLinkAsync` - [ ] `AnagEventiGeneral` - [ ] `AnagEventiGetByMacch` - [ ] `AnagKeyValGetAll` From 3210225c1b1ca7d1c678d8af69d18c83abfa7222 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 08:03:42 +0200 Subject: [PATCH 027/102] Renaming metodo --- MP.SPEC/Components/DossiersFilter.razor.cs | 2 +- MP.SPEC/Data/MpDataService.cs | 6 +++--- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/MP.SPEC/Components/DossiersFilter.razor.cs b/MP.SPEC/Components/DossiersFilter.razor.cs index 32b021dc..723965e0 100644 --- a/MP.SPEC/Components/DossiersFilter.razor.cs +++ b/MP.SPEC/Components/DossiersFilter.razor.cs @@ -133,7 +133,7 @@ namespace MP.SPEC.Components 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(); + ListArticoli = await MDService.ArticleWithDossierAsync(); await FilterChanged.InvokeAsync(SelFilterDossier); } diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index efdfdcf6..f0d0ebce 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -309,9 +309,9 @@ namespace MP.SPEC.Data /// Elenco Codice articolo con dati dossier gestiti ///
        /// - public async Task> ArticleWithDossier() + public async Task> ArticleWithDossierAsync() { - using var activity = ActivitySource.StartActivity("ArticleWithDossier"); + using var activity = ActivitySource.StartActivity("ArticleWithDossierAsync"); List? result = new List(); string source = "DB"; string currKey = Utils.redisArtByDossier; @@ -336,7 +336,7 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.SetTag("result.count", result.Count); activity?.Stop(); - LogTrace($"ArticleWithDossier | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ArticleWithDossierAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; } diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 8de497e6..de389880 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2807 + 8.16.2605.2808 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 02c9ef35..1fc88236 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

        Versione: 8.16.2605.2807

        +

        Versione: 8.16.2605.2808


        Note di rilascio:
        • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 1cf9982d..828db479 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2807 +8.16.2605.2808 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 98823e78..ad15ce10 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2807 + 8.16.2605.2808 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From 6ab59ec1e5a604107ef61187a28b77ec3486c2a2 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 08:27:14 +0200 Subject: [PATCH 028/102] Aggiunta script x compilazione parallela, spostamento progetti old/disuso, limite paralleo a 3 per evitare errori --- MP-TAB.sln | 37 ------- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP-WAMON.sln | 43 -------- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- build_all_par.ps1 | 157 ++++++++++++++++++++++++++++++ 35 files changed, 189 insertions(+), 112 deletions(-) delete mode 100644 MP-TAB.sln delete mode 100644 MP-WAMON.sln create mode 100644 build_all_par.ps1 diff --git a/MP-TAB.sln b/MP-TAB.sln deleted file mode 100644 index 339f020e..00000000 --- a/MP-TAB.sln +++ /dev/null @@ -1,37 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.32126.317 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.Data", "MP.Data\MP.Data.csproj", "{10BA8450-301D-49C7-8E1E-21B7469C225C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP-TAB", "MP-TAB\MP-TAB\MP-TAB.csproj", "{9141D627-EE10-4BF6-9A2C-AAC6845E185F}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP-TAB.Client", "MP-TAB\MP-TAB.Client\MP-TAB.Client.csproj", "{28559808-58F2-424B-B65C-062AA59839EC}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {10BA8450-301D-49C7-8E1E-21B7469C225C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {10BA8450-301D-49C7-8E1E-21B7469C225C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {10BA8450-301D-49C7-8E1E-21B7469C225C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {10BA8450-301D-49C7-8E1E-21B7469C225C}.Release|Any CPU.Build.0 = Release|Any CPU - {9141D627-EE10-4BF6-9A2C-AAC6845E185F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9141D627-EE10-4BF6-9A2C-AAC6845E185F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9141D627-EE10-4BF6-9A2C-AAC6845E185F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9141D627-EE10-4BF6-9A2C-AAC6845E185F}.Release|Any CPU.Build.0 = Release|Any CPU - {28559808-58F2-424B-B65C-062AA59839EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {28559808-58F2-424B-B65C-062AA59839EC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {28559808-58F2-424B-B65C-062AA59839EC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {28559808-58F2-424B-B65C-062AA59839EC}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {632D11D1-088B-4795-97E5-048534002558} - EndGlobalSection -EndGlobal diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index a078167b..d2018285 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2604.2718 + 8.16.2605.2808 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 133a7fea..1fc88236 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

          Versione: 8.16.2604.2718

          +

          Versione: 8.16.2605.2808


          Note di rilascio:
          • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 87ec763e..828db479 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2604.2718 +8.16.2605.2808 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index 6613f4d9..58e7ba81 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2604.2718 + 8.16.2605.2808 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP-WAMON.sln b/MP-WAMON.sln deleted file mode 100644 index d0829635..00000000 --- a/MP-WAMON.sln +++ /dev/null @@ -1,43 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.32126.317 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.Data", "MP.Data\MP.Data.csproj", "{10BA8450-301D-49C7-8E1E-21B7469C225C}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MP.Mon", "MP.Mon\MP.Mon.csproj", "{7780FA7A-3597-4098-81C1-DC9AD6AE7A98}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MP.WASM.Mon.Server", "MP.WASM.Mon\Server\MP.WASM.Mon.Server.csproj", "{4A98B7F4-4EC6-4284-9D6C-63203DB981B1}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MP.WASM.Mon.Client", "MP.WASM.Mon\Client\MP.WASM.Mon.Client.csproj", "{9BF7BDE7-016A-458C-8791-494FD4204301}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {10BA8450-301D-49C7-8E1E-21B7469C225C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {10BA8450-301D-49C7-8E1E-21B7469C225C}.Debug|Any CPU.Build.0 = Debug|Any CPU - {10BA8450-301D-49C7-8E1E-21B7469C225C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {10BA8450-301D-49C7-8E1E-21B7469C225C}.Release|Any CPU.Build.0 = Release|Any CPU - {7780FA7A-3597-4098-81C1-DC9AD6AE7A98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7780FA7A-3597-4098-81C1-DC9AD6AE7A98}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7780FA7A-3597-4098-81C1-DC9AD6AE7A98}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7780FA7A-3597-4098-81C1-DC9AD6AE7A98}.Release|Any CPU.Build.0 = Release|Any CPU - {4A98B7F4-4EC6-4284-9D6C-63203DB981B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4A98B7F4-4EC6-4284-9D6C-63203DB981B1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4A98B7F4-4EC6-4284-9D6C-63203DB981B1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4A98B7F4-4EC6-4284-9D6C-63203DB981B1}.Release|Any CPU.Build.0 = Release|Any CPU - {9BF7BDE7-016A-458C-8791-494FD4204301}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9BF7BDE7-016A-458C-8791-494FD4204301}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9BF7BDE7-016A-458C-8791-494FD4204301}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9BF7BDE7-016A-458C-8791-494FD4204301}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {632D11D1-088B-4795-97E5-048534002558} - EndGlobalSection -EndGlobal diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index 7019b116..2d758695 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2604.2716 + 8.16.2605.2808 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index d27ae967..f21a80e9 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

            Versione: 8.16.2604.2716

            +

            Versione: 8.16.2605.2808


            Note di rilascio:
            • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index e7a88a55..828db479 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2604.2716 +8.16.2605.2808 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index e7edcec6..d1535baa 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2604.2716 + 8.16.2605.2808 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 5163209d..15eee620 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.2719 + 8.16.2605.2808 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 35c7cf13..8a235ada 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

              Versione: 8.16.2605.2719

              +

              Versione: 8.16.2605.2808


              Note di rilascio:
              • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index a3677dd7..828db479 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2719 +8.16.2605.2808 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 7c9ea58b..b9aa95bf 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2719 + 8.16.2605.2808 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 4f1a232f..dd8f7d78 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2605.0811 + 8.16.2605.2808 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 65e63b56..474c8f3d 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                Versione: 8.16.2605.0811

                +

                Versione: 8.16.2605.2808


                Note di rilascio:
                  diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 3249ffa8..828db479 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.0811 +8.16.2605.2808 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index e201bc34..fc2d24fe 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.0811 + 8.16.2605.2808 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index 83044cfe..34adfe61 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2604.2718 + 8.16.2605.2808 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 133a7fea..1fc88236 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                  Versione: 8.16.2604.2718

                  +

                  Versione: 8.16.2605.2808


                  Note di rilascio:
                  • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 87ec763e..828db479 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2604.2718 +8.16.2605.2808 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index 6546b902..5d52ff5f 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2604.2718 + 8.16.2605.2808 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 7fe982a9..3601b540 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 6.16.2604.2715 + 8.16.2605.2808 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index abc709a8..e99d3083 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                    Versione: 6.16.2604.2715

                    +

                    Versione: 8.16.2605.2808


                    Note di rilascio:
                      diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index b53e4a5d..828db479 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -6.16.2604.2715 +8.16.2605.2808 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 9906d5bb..70a2dbb7 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 6.16.2604.2715 + 8.16.2605.2808 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index a893eba8..fa7dd417 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2605.2519 + 8.16.2605.2808 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index 65c07daf..98241e80 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                      Versione: 8.16.2605.2519

                      +

                      Versione: 8.16.2605.2808


                      Note di rilascio:
                      • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index a68d1899..828db479 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2519 +8.16.2605.2808 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index 69dca7d7..67258ee2 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2519 + 8.16.2605.2808 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 6b61fa36..d793d9c7 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2605.2713 + 8.16.2605.2808 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index 709dcffb..bf5b6ad9 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                        Versione: 8.16.2605.2713

                        +

                        Versione: 8.16.2605.2808


                        Note di rilascio:
                          diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 12119c44..828db479 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2713 +8.16.2605.2808 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index 8e8abd19..6a52562d 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2713 + 8.16.2605.2808 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false diff --git a/build_all_par.ps1 b/build_all_par.ps1 new file mode 100644 index 00000000..687234a3 --- /dev/null +++ b/build_all_par.ps1 @@ -0,0 +1,157 @@ +# --- CONFIGURAZIONE --- +$pattern = "MP-*.sln" +$sharedProjectPath = ".\MP.Data\MP.Data.csproj" + +# Controllo robusto del parametro --agent (cerca in tutti gli argomenti passati) +$agentMode = $args -contains "--agent" + +# Avvia il cronometro per calcolare il tempo totale +$stopwatch = [System.Diagnostics.Stopwatch]::StartNew() + +# 1. Trova l'MSBuild ufficiale di Visual Studio 2022 +$vsPaths = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -version "[17.0,18.0)" -products * -requires Microsoft.Component.MSBuild -property installationPath +if (-not $vsPaths) { + if ($agentMode) { exit 1 } + Write-Host "❌ Impossibile trovare Visual Studio 2022!" -ForegroundColor Red + Exit +} +$msbuildPath = Join-Path $vsPaths[0] "MSBuild\Current\Bin\MSBuild.exe" + +if (-not $agentMode) { + Write-Host "🎯 Usando MSBuild di VS2022: $msbuildPath" -ForegroundColor Gray +} + +# Cerca tutte le soluzioni escludendo cartelle di build +$solutions = Get-ChildItem -Path . -Filter $pattern -Recurse | Where-Object { + $_.FullName -notmatch '\\(bin|obj|\\.git|\\.vs)\\.' +} + +if ($solutions.Count -eq 0) { + if ($agentMode) { exit 1 } + Write-Host "⚠️ Nessuna soluzione trovata che corrisponde al pattern: $pattern" -ForegroundColor Yellow + Exit +} + +if (-not $agentMode) { + Write-Host "🚀 Trovate $($solutions.Count) soluzioni univoche." -ForegroundColor Magenta +} + +# FASE 1: Compilazione preventiva del progetto comune +if (Test-Path $sharedProjectPath) { + if (-not $agentMode) { Write-Host "`n📦 Fase 1: Compilazione del progetto comune condiviso..." -ForegroundColor Cyan } + + # AGGIORNAMENTO: Se siamo in agentMode silenziamo completamente MSBuild (/v:q) e ridirigiamo l'output + if ($agentMode) { + & $msbuildPath $sharedProjectPath /p:Configuration=Release /v:q /nologo > $null 2>&1 + } + else { + & $msbuildPath $sharedProjectPath /p:Configuration=Release /v:m /nologo + } + + if ($LASTEXITCODE -ne 0) { + if (-not $agentMode) { Write-Host "❌ Errore critico: Impossibile compilare il progetto comune. Interruzione." -ForegroundColor Red } + exit 1 + } + if (-not $agentMode) { Write-Host "✅ Progetto comune pronto." -ForegroundColor Green } +} + +# FASE 2: Compilazione parallela iniziale +if (-not $agentMode) { + Write-Host "`n🛠️ Fase 2: Avvio compilazione parallela delle soluzioni (Max 4)..." -ForegroundColor Magenta + Write-Host "==================================================" -ForegroundColor Magenta +} + +$parallelResults = $solutions | ForEach-Object -Parallel { + $solName = $_.Name + $solPath = $_.FullName + $msb = $using:msbuildPath + + # Aggiunto /nologo per evitare intestazioni ripetute nei log interni + $log = & $msb $solPath /p:Configuration=Release /m:1 /p:BuildInParallel=false /v:m /nologo 2>&1 + + [PSCustomObject]@{ + Name = $solName + FullName = $solPath + Success = ($LASTEXITCODE -eq 0) + Log = $log + } +} -ThrottleLimit 3 + +# --- ANALISI PRIMO ROUND E FASE 3 (RETRY SEQUENZIALE) --- +$successSolutions = @() +$failedToRetry = @() + +foreach ($res in $parallelResults) { + if ($res.Success) { + if (-not $agentMode) { Write-Host "✅ $($res.Name) compilata con successo (in parallelo)!" -ForegroundColor Green } + $successSolutions += $res.Name + } + else { + if (-not $agentMode) { Write-Host "⚠️ $($res.Name) fallita in parallelo. Accodata per il recupero sequenziale..." -ForegroundColor Yellow } + $failedToRetry += $res + } +} + +# Se ci sono falliti, li rieseguiamo UNO ALLA VOLTA pulendo la cache +if ($failedToRetry.Count -gt 0) { + if (-not $agentMode) { + Write-Host "`n🔄 Fase 3: Riesecuzione sequenziale dei task falliti ($($failedToRetry.Count) soluzioni)..." -ForegroundColor Magenta + Write-Host "==================================================" -ForegroundColor Magenta + } + + foreach ($failedRes in $failedToRetry) { + if (-not $agentMode) { Write-Host "⏳ Ripristino e compilazione sequenziale: $($failedRes.Name)..." -ForegroundColor Cyan } + + & $msbuildPath $failedRes.FullName /t:Restore /v:q /nologo > $null 2>&1 + & $msbuildPath $failedRes.FullName /t:Clean /v:q /p:Configuration=Release /nologo > $null 2>&1 + $retryLog = & $msbuildPath $failedRes.FullName /t:Build /p:Configuration=Release /v:m /nologo 2>&1 + + if ($LASTEXITCODE -eq 0) { + if (-not $agentMode) { Write-Host "✅ FALSO ALLARME: $($failedRes.Name) compilata correttamente in sequenziale!" -ForegroundColor Green } + $successSolutions += $failedRes.Name + } + else { + if (-not $agentMode) { Write-Host "❌ ERRORE REALE: $($failedRes.Name) è fallita anche in sequenziale." -ForegroundColor Red } + $failedRes.Log = $retryLog + } + } +} + +# Ferma il cronometro e calcola il tempo trascorso +$stopwatch.Stop() +$elapsedTime = "{0:mm\:ss}" -f $stopwatch.Elapsed + +# --- ELABORAZIONE DEI RISULTATI FINALI --- +$totalCount = $solutions.Count +$successCount = $successSolutions.Count +$failCount = $totalCount - $successCount +$failColor = if ($failCount -gt 0) { "Red" } else { "Gray" } + +# --- RIEPILOGO FINALE --- +if (-not $agentMode) { + Write-Host "`n==================================================" -ForegroundColor Magenta + Write-Host "🏁 Processo di verifica completato in $elapsedTime!" -ForegroundColor Magenta + Write-Host "==================================================" -ForegroundColor Magenta + Write-Host " Soluzioni Totali: $totalCount" -ForegroundColor White + Write-Host " Successi totali: $successCount" -ForegroundColor Green + Write-Host " Errori reali: $failCount" -ForegroundColor $failColor + Write-Host " Tempo impiegato: $elapsedTime" -ForegroundColor Cyan + + if ($failCount -gt 0) { + Write-Host "`n❌ Elenco delle soluzioni con ERRORI REALI:" -ForegroundColor Red + foreach ($res in $parallelResults) { + if ($successSolutions -notcontains $res.Name) { + Write-Host " - $($res.Name)" -ForegroundColor Red + Write-Host " 👉 Ultimi dettagli errore:" -ForegroundColor DarkRed + $res.Log | Where-Object { $_ -match "error" } | Select-Object -First 3 | Write-Host -ForegroundColor Gray + } + } + } + else { + Write-Host "`n🎉 Eccellente! Tutte le soluzioni compilano senza errori." -ForegroundColor Green + } + Write-Host "==================================================" -ForegroundColor Magenta +} + +# Exit code standard per ambienti automatizzati (0 = Successo, 1 = Fallimento) +if ($failCount -gt 0) { exit 1 } else { exit 0 } \ No newline at end of file From 966209f573810e43020ca30f4b076f1e0d5190f5 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 08:34:01 +0200 Subject: [PATCH 029/102] Update metodi + parametrizzazione build_par --- MP.SPEC/Data/MpDataService.cs | 34 +++++++--------------------------- build_all_par.ps1 | 6 ++++-- 2 files changed, 11 insertions(+), 29 deletions(-) diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index f0d0ebce..3361f169 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -311,33 +311,13 @@ namespace MP.SPEC.Data /// public async Task> ArticleWithDossierAsync() { - using var activity = ActivitySource.StartActivity("ArticleWithDossierAsync"); - List? result = new List(); - string source = "DB"; - string currKey = Utils.redisArtByDossier; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "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(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"ArticleWithDossierAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + return await GetOrFetchAsync( + operationName: "ArticleWithDossierAsync", + cacheKey: Utils.redisArtByDossier, + expiration: TimeSpan.FromMinutes(redisLongTimeCache), + fetchFunc: async () => await Task.FromResult(dbController.ArticleWithDossier()) ?? new List(), + tagList: [Utils.redisArtByDossier] + ); } /// diff --git a/build_all_par.ps1 b/build_all_par.ps1 index 687234a3..9cd56ce2 100644 --- a/build_all_par.ps1 +++ b/build_all_par.ps1 @@ -55,9 +55,11 @@ if (Test-Path $sharedProjectPath) { if (-not $agentMode) { Write-Host "✅ Progetto comune pronto." -ForegroundColor Green } } +$numPar=3 + # FASE 2: Compilazione parallela iniziale if (-not $agentMode) { - Write-Host "`n🛠️ Fase 2: Avvio compilazione parallela delle soluzioni (Max 4)..." -ForegroundColor Magenta + Write-Host "`n🛠️ Fase 2: Avvio compilazione parallela delle soluzioni (Max $($numPar))..." -ForegroundColor Magenta Write-Host "==================================================" -ForegroundColor Magenta } @@ -75,7 +77,7 @@ $parallelResults = $solutions | ForEach-Object -Parallel { Success = ($LASTEXITCODE -eq 0) Log = $log } -} -ThrottleLimit 3 +} -ThrottleLimit $numPar # --- ANALISI PRIMO ROUND E FASE 3 (RETRY SEQUENZIALE) --- $successSolutions = @() From 74083fac93aedc289cd67bdf1e7e5ae954dba506 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 08:46:45 +0200 Subject: [PATCH 030/102] Fix naming + pulizia metodi nonn usati --- MP.SPEC/Components/ListDossiers.razor.cs | 4 +- MP.SPEC/Components/ListODL.razor.cs | 2 +- MP.SPEC/Components/ListPODL.razor.cs | 2 +- MP.SPEC/Data/MpDataService.cs | 89 ++++-------------------- MP.SPEC/Pages/ODL.razor.cs | 2 +- MP.SPEC/Pages/PODL.razor.cs | 2 +- 6 files changed, 20 insertions(+), 81 deletions(-) diff --git a/MP.SPEC/Components/ListDossiers.razor.cs b/MP.SPEC/Components/ListDossiers.razor.cs index 2947870b..037de309 100644 --- a/MP.SPEC/Components/ListDossiers.razor.cs +++ b/MP.SPEC/Components/ListDossiers.razor.cs @@ -231,7 +231,7 @@ namespace MP.SPEC.Components { await MDService.ConfigResetCache(); ListGruppiFase = MDService.ElencoGruppiFase(); - ListStati = await MDService.AnagStatiComm(); + ListStati = await MDService.AnagStatiCommAsync(); selAzienda = await MDService.ConfigTryGetAsync("AZIENDA"); giacenzeConf = await MDService.ConfigTryGetAsync("SPEC_ShowGiacenze"); ListArticoli = await MDService.ArticoliGetSearchAsync(100000, "*", selAzienda, ""); @@ -436,7 +436,7 @@ namespace MP.SPEC.Components private async Task ReloadData(bool setChanged) { isLoading = true; - SearchRecords = await MDService.DossiersGetLastFilt(SelMacchina, SelArticolo, SelDtStart, SelDtEnd, MaxRec); + SearchRecords = await MDService.DossiersGetLastFiltAsync(SelMacchina, SelArticolo, SelDtStart, SelDtEnd, MaxRec); totalCount = SearchRecords.Count; ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); await Task.Delay(1); diff --git a/MP.SPEC/Components/ListODL.razor.cs b/MP.SPEC/Components/ListODL.razor.cs index c5791926..47129602 100644 --- a/MP.SPEC/Components/ListODL.razor.cs +++ b/MP.SPEC/Components/ListODL.razor.cs @@ -206,7 +206,7 @@ namespace MP.SPEC.Components protected override async Task OnInitializedAsync() { - ListStati = await MDService.AnagStatiComm(); + ListStati = await MDService.AnagStatiCommAsync(); ListArtKit = await MDService.ArticoliGetByTipoAsync("KIT", "*"); string SPEC_PODL_gest = await MDService.ConfigTryGetAsync("SPEC_PODL_gest"); if (!string.IsNullOrEmpty(SPEC_PODL_gest)) diff --git a/MP.SPEC/Components/ListPODL.razor.cs b/MP.SPEC/Components/ListPODL.razor.cs index 4b75606b..533f647a 100644 --- a/MP.SPEC/Components/ListPODL.razor.cs +++ b/MP.SPEC/Components/ListPODL.razor.cs @@ -230,7 +230,7 @@ namespace MP.SPEC.Components .Select(x => x.IdxMacchina) .ToHashSet(); - ListStati = await MDService.AnagStatiComm(); + ListStati = await MDService.AnagStatiCommAsync(); ListArtKit = await MDService.ArticoliGetByTipoAsync("KIT", "*"); string strMachRecipe = await MDService.ConfigTryGetAsync("MachineWithRecipe"); if (!string.IsNullOrEmpty(strMachRecipe)) diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 3361f169..0a2f1715 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -171,41 +171,6 @@ namespace MP.SPEC.Data ); } - /// - /// Elenco EVENTI validi x macchina - /// - /// - public List AnagEventiGetByMacch(string IdxMacch) - { - using var activity = ActivitySource.StartActivity("AnagEventiGetByMacch"); - string source = "DB"; - List? result = new List(); - // cerco in redisConn... - string currKey = $"{Utils.redisEventList}:VSEB:{IdxMacch}"; - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = dbController.AnagEventiGetByMacc(IdxMacch); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"AnagEventiGetByMacch | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return result; - } - /// /// Delete record AnagraficaGruppi /// @@ -243,42 +208,7 @@ namespace MP.SPEC.Data return result; } - /// - /// Elenco Gruppi - /// - /// - public async Task> AnagKeyValGetAll() - { - // nuovo oggetto span activity - using var activity = ActivitySource.StartActivity("AnagKeyValGetAll"); - string source = "DB"; - List? result = new List(); - // cerco in redis... - RedisValue rawData = await redisDb.StringGetAsync(Utils.redisAKVKey); - if (!string.IsNullOrEmpty($"{rawData}")) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await Task.FromResult(dbController.AnagKeyValGetAll()); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(Utils.redisConfKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"AnagKeyValGetAll Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; - } - - public async Task> AnagStatiComm() + public async Task> AnagStatiCommAsync() { return await GetOrFetchAsync( operationName: "AnagStatiCommAsync", @@ -346,9 +276,7 @@ namespace MP.SPEC.Data public async Task> ArticoliGetByTipoAsync(string tipo, string azienda = "*") { string sKey = string.IsNullOrWhiteSpace(tipo) ? "ALL" : tipo.Trim(); - string redisKey = $"{Utils.redisArtList}:{azienda}:Tipo:{sKey}"; - return await GetOrFetchAsync( operationName: "ArticoliGetByTipoAsync", cacheKey: redisKey, @@ -527,12 +455,19 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("ConfigResetCache"); string source = "REDIS"; - await redisDb.StringSetAsync(Utils.redisConfKey, ""); + await ResetConfigCache(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"ConfigResetCache Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); } + private async Task ResetConfigCache() + { + await redisDb.StringSetAsync(Utils.redisConfKey, ""); + List tags2del = new List() { Utils.redisConfKey }; + await FlushCacheByTagsAsync(tags2del); + } + /// /// Restituisce valore della stringa (SE disponibile) /// @@ -584,6 +519,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("ConfigUpdateAsync"); string source = "DB"; var updRes = await dbController.ConfigUpdateAsync(updRec); + await ResetConfigCache(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"ConfigUpdateAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -655,7 +591,7 @@ namespace MP.SPEC.Data /// Data Massima per estrazione records /// Num Max records da recuperare /// - public async Task> DossiersGetLastFilt(string IdxMacchina, string CodArticolo, DateTime DtStart, DateTime DtEnd, int MaxRec) + public async Task> DossiersGetLastFiltAsync(string IdxMacchina, string CodArticolo, DateTime DtStart, DateTime DtEnd, int MaxRec) { using var activity = ActivitySource.StartActivity("DossiersGetLastFiltAsync"); List? result = new List(); @@ -3332,6 +3268,9 @@ namespace MP.SPEC.Data await ExecFlushRedisPatternAsync(pattern); pattern = new RedisValue($"{Utils.redisArtList}:*"); await ExecFlushRedisPatternAsync(pattern); + // elimino anche in FusionCache + List tags2del = new List() { Utils.redisArtList, Utils.redisArtByDossier }; + await FlushCacheByTagsAsync(tags2del); activity?.SetTag("data.source", "REDIS"); } diff --git a/MP.SPEC/Pages/ODL.razor.cs b/MP.SPEC/Pages/ODL.razor.cs index a364953f..fbc11aa7 100644 --- a/MP.SPEC/Pages/ODL.razor.cs +++ b/MP.SPEC/Pages/ODL.razor.cs @@ -110,7 +110,7 @@ namespace MP.SPEC.Pages { ListGruppiFase = allGruppiData.Where(x => x.SelEnabled).ToList(); } - ListStati = await MDService.AnagStatiComm(); + ListStati = await MDService.AnagStatiCommAsync(); ListMacchine = MDService.MacchineGetFilt(selReparto); padCodXdl = await MDService.ConfigTryGetAsync("PadCodXdl"); } diff --git a/MP.SPEC/Pages/PODL.razor.cs b/MP.SPEC/Pages/PODL.razor.cs index 9cd43918..1a6b35ac 100644 --- a/MP.SPEC/Pages/PODL.razor.cs +++ b/MP.SPEC/Pages/PODL.razor.cs @@ -135,7 +135,7 @@ namespace MP.SPEC.Pages { ListGruppiFase = allGruppiData.Where(x => x.SelEnabled).ToList(); } - ListStati = await MDService.AnagStatiComm(); + ListStati = await MDService.AnagStatiCommAsync(); currAzienda = await MDService.ConfigTryGetAsync("AZIENDA"); padCodXdl = await MDService.ConfigTryGetAsync("padCodXdl"); useFasi4KeyRich = await MDService.ConfigTryGetAsync("SPEC_KeyRichiesta"); From 0476b78d09d62ec92f055953cbefc60bb4271456 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 08:57:20 +0200 Subject: [PATCH 031/102] Continuo fix metodi cache x SPEC --- MP.SPEC/Data/MpDataService.cs | 344 ++++++++++------------------------ 1 file changed, 95 insertions(+), 249 deletions(-) diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 0a2f1715..4f4a43c1 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -419,32 +419,13 @@ namespace MP.SPEC.Data /// public async Task> ConfigGetAllAsync() { - using var activity = ActivitySource.StartActivity("ConfigGetAllAsync"); - string source = "REDIS"; - List? result = new List(); - // cerco in redis... - RedisValue rawData = await redisDb.StringGetAsync(Utils.redisConfKey); - if (!string.IsNullOrEmpty($"{rawData}")) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.ConfigGetAllAsync(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(Utils.redisConfKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"ConfigGetAllAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + return await GetOrFetchAsync( + operationName: "ConfigGetAllAsync", + cacheKey: Utils.redisConfKey, + expiration: TimeSpan.FromMinutes(redisLongTimeCache), + fetchFunc: async () => await dbController.ConfigGetAllAsync() ?? new List(), + tagList: [Utils.redisConfKey] + ); } /// @@ -461,13 +442,6 @@ namespace MP.SPEC.Data LogTrace($"ConfigResetCache Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); } - private async Task ResetConfigCache() - { - await redisDb.StringSetAsync(Utils.redisConfKey, ""); - List tags2del = new List() { Utils.redisConfKey }; - await FlushCacheByTagsAsync(tags2del); - } - /// /// Restituisce valore della stringa (SE disponibile) /// @@ -593,33 +567,14 @@ namespace MP.SPEC.Data /// public async Task> DossiersGetLastFiltAsync(string IdxMacchina, string CodArticolo, DateTime DtStart, DateTime DtEnd, int MaxRec) { - using var activity = ActivitySource.StartActivity("DossiersGetLastFiltAsync"); - List? result = new List(); - string source = "DB"; string currKey = $"{Utils.redisDossByMac}:{IdxMacchina}:{CodArticolo}:{DtStart:yyyyMMddHHmm}:{DtEnd:yyyyMMddHHmm}:{MaxRec}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.DossiersGetLastFiltAsync(IdxMacchina, CodArticolo, DtStart, DtEnd, MaxRec); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache / 5)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"DossiersGetLastFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + return await GetOrFetchAsync( + operationName: "DossiersGetLastFiltAsync", + cacheKey: currKey, + expiration: TimeSpan.FromMinutes(redisLongTimeCache / 5), + fetchFunc: async () => await dbController.DossiersGetLastFiltAsync(IdxMacchina, CodArticolo, DtStart, DtEnd, MaxRec) ?? new List(), + tagList: [Utils.redisDossByMac] + ); } /// @@ -1312,42 +1267,6 @@ namespace MP.SPEC.Data return mongoController.InitRecipe(confPath, idxPODL, CalcArgs); } - /// - /// Recupero info IOB x TAB (da info registrate IOB-WIN--> MP-IO) - /// - /// - /// - public async Task IobInfo(string IdxMacchina) - { - using var activity = ActivitySource.StartActivity("IobInfo"); - string source = "DB"; - IOB_data? result = new IOB_data(); - // cerco in redis... - string currKey = redHashMpIO($"hM2IOB:{IdxMacchina}"); - RedisValue rawData = await redisDb.StringGetAsync(currKey); - //if (!string.IsNullOrEmpty($"{rawData}")) - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject($"{rawData}"); - source = "REDIS"; - } - else - { - Log.Error($"Errore: non trovato valore valido in REDIS | key: {currKey}"); - Log.Info($"REDIS | conf: {redisConn.Configuration}"); - Log.Info($" --> Valore trovato:{Environment.NewLine}{rawData}"); - } - if (result == null) - { - result = new IOB_data(); - LogTrace($"Init valore default | IdxMacchina: {IdxMacchina}"); - } - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"IobInfo per {IdxMacchina} | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return result; - } - /// /// Elimina record + svuotamento cache /// @@ -1923,28 +1842,6 @@ namespace MP.SPEC.Data return dbResult; } - /// - /// ODL correnti (tutti) - /// - /// - /// - /// - /// elenco TUTTI gli ODL - /// - /// - /// - public List OdlListAll() - { - using var activity = ActivitySource.StartActivity("OdlListAll"); - List? result = new List(); - string source = "DB"; - result = dbController.OdlListAll(); - activity?.SetTag("data.source", "DB"); - activity?.Stop(); - LogTrace($"OdlListAll | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; - } - /// /// Elenco ODL filtrati x stato, articolo, KeyRich (che contiene stato) /// @@ -2544,28 +2441,6 @@ namespace MP.SPEC.Data return answ; } - /// - /// Effettua reset microstato macchina - /// - /// - public async Task ResetMicrostatoMacchina(string idxMacchina) - { - using var activity = ActivitySource.StartActivity("ResetMicrostatoMacchina"); - string source = "DB"; - // salvo microstato 0... - MicroStatoMacchinaModel newRecMS = new MicroStatoMacchinaModel() - { - IdxMacchina = idxMacchina, - InizioStato = DateTime.Now, - IdxMicroStato = 0, - Value = "FER" - }; - var result = await dbController.MicroStatoMacchinaUpsert(newRecMS); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"ResetMicrostatoMacchina | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - } - /// /// Statistiche ODL calcolate (da stored stp_STAT_ODL) /// @@ -2617,37 +2492,6 @@ namespace MP.SPEC.Data return result; } - /// - /// Restituisce il valore da REDIS associato al tag richiesto - /// - /// Chiave in cui cercare il valore - /// - public string TagConfGetKey(string redKey) - { - string outVal = ""; - using var activity = ActivitySource.StartActivity("TagConfGetKey"); - string source = "REDIS"; - // cerco in REDIS la conf x l'IOB - var rawData = redisDb.StringGet(redKey); - if (!string.IsNullOrEmpty(rawData)) - { - outVal = $"{rawData}"; - } - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"TagConfGetKey | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return outVal; - } - - /// - /// Elenco setup dei tag conf correnti - /// - /// - public Dictionary> TagsGetAll() - { - return currTagConf; - } - /// /// Elimina record + svuotamento cache /// @@ -2777,54 +2621,6 @@ namespace MP.SPEC.Data return answ; } - /// - /// Update valore Dossier - /// - /// - /// - /// - public async Task updateDossierValue(DossierModel currDoss, FluxLogDTO editFL) - { - using var activity = ActivitySource.StartActivity("updateDossierValue"); - string source = "DB"; - bool answ = false; - // recupero intero set valori dossier deserializzando... - var fluxLogList = FluxLogDtoGetByFlux(currDoss.Valore); - // 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); - } - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"updateDossierValue | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return answ; - } - /// /// Elenco completo tabella Vocabolario /// @@ -2878,25 +2674,6 @@ namespace MP.SPEC.Data return fatto; } - /// - /// Elimina i record associati al keyFilt indicato - /// - /// - public bool WipKitDeleteGroup(string KeyFilt) - { - using var activity = ActivitySource.StartActivity("WipKitDeleteGroup"); - string source = "DB"; - bool fatto = false; - // salvo - fatto = dbController.WipKitDeleteGroup(KeyFilt); - // svuoto cache - EmptyWipCache(); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"WipKitDeleteGroup Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return fatto; - } - /// /// Elimina i record più vecchi della data-ora indicata /// @@ -2973,18 +2750,6 @@ namespace MP.SPEC.Data #endregion Public Methods - #region Protected Fields - - protected Random rand = new Random(); - - #endregion Protected Fields - - #region Protected Properties - - protected string canCacheParametri { get; set; } = ""; - - #endregion Protected Properties - #region Protected Methods /// @@ -3084,6 +2849,8 @@ namespace MP.SPEC.Data // Cache per controllo eliminazione articoli (Smart HashSet approach) private HashSet _usedArtIdsCache = new(); + private string canCacheParametri = ""; + private string MpIoNS = ""; /// @@ -3091,6 +2858,8 @@ namespace MP.SPEC.Data /// private List ObjVocabolario = new List(); + private Random rand = new Random(); + /// /// Oggetto per connessione a REDIS /// @@ -3274,6 +3043,83 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", "REDIS"); } + private async Task ResetConfigCache() + { + await redisDb.StringSetAsync(Utils.redisConfKey, ""); + List tags2del = new List() { Utils.redisConfKey }; + await FlushCacheByTagsAsync(tags2del); + } + +#if false + /// + /// Update valore Dossier + /// + /// + /// + /// + public async Task updateDossierValue(DossierModel currDoss, FluxLogDTO editFL) + { + using var activity = ActivitySource.StartActivity("updateDossierValue"); + string source = "DB"; + bool answ = false; + // recupero intero set valori dossier deserializzando... + var fluxLogList = FluxLogDtoGetByFlux(currDoss.Valore); + // 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); + } + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"updateDossierValue | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } +#endif +#if false + /// + /// Elimina i record associati al keyFilt indicato + /// + /// + public bool WipKitDeleteGroup(string KeyFilt) + { + using var activity = ActivitySource.StartActivity("WipKitDeleteGroup"); + string source = "DB"; + bool fatto = false; + // salvo + fatto = dbController.WipKitDeleteGroup(KeyFilt); + // svuoto cache + EmptyWipCache(); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"WipKitDeleteGroup Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + return fatto; + } +#endif + /// /// Reset macchine e gruppi /// From 195f975c6ac1fa1dedec254390ea96779b178aa0 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 09:17:17 +0200 Subject: [PATCH 032/102] Ancora update metodi + udpate async generico --- MP.Data/Controllers/MpSpecController.cs | 27 ++-- MP.SPEC/Components/ListDossiers.razor.cs | 2 +- MP.SPEC/Components/ListGiacenze.razor.cs | 2 +- MP.SPEC/Data/MpDataService.cs | 149 +++-------------------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/ODL.razor.cs | 2 +- MP.SPEC/Pages/PODL.razor.cs | 2 +- MP.SPEC/Pages/Podl2Kit.razor.cs | 62 +++++----- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 11 files changed, 66 insertions(+), 188 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index e040f492..0d2a1351 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -194,9 +194,9 @@ namespace MP.Data.Controllers /// Elenco Gruppi tipo Fasi /// /// - public List AnagGruppiFase() + public Task> AnagGruppiFaseAsync() { - return AnagGruppiGetTipo("FASE"); + return AnagGruppiGetTipoAsync("FASE"); } /// @@ -1352,24 +1352,15 @@ namespace MP.Data.Controllers /// /// id odl da cercare /// - public List ListGiacenze(int IdxOdl) + public async Task> ListGiacenzeAsync(int IdxOdl) { List dbResult = new List(); - using (var dbCtx = new MoonPro_InveContext(_configuration)) - { - try - { - dbResult = dbCtx - .DbGiacenzeData - .AsNoTracking() - .Where(x => x.IdxOdl == IdxOdl) - .ToList(); - } - catch (Exception exc) - { - Log.Error($"Eccezione durante ListGiacenze{Environment.NewLine}{exc}"); - } - } + using var dbCtx = new MoonPro_InveContext(_configuration); + dbResult = await dbCtx + .DbGiacenzeData + .Where(x => x.IdxOdl == IdxOdl) + .AsNoTracking() + .ToListAsync(); return dbResult; } diff --git a/MP.SPEC/Components/ListDossiers.razor.cs b/MP.SPEC/Components/ListDossiers.razor.cs index 037de309..a6d463ad 100644 --- a/MP.SPEC/Components/ListDossiers.razor.cs +++ b/MP.SPEC/Components/ListDossiers.razor.cs @@ -230,7 +230,7 @@ namespace MP.SPEC.Components protected override async Task OnInitializedAsync() { await MDService.ConfigResetCache(); - ListGruppiFase = MDService.ElencoGruppiFase(); + ListGruppiFase = await MDService.ElencoGruppiFaseAsync(); ListStati = await MDService.AnagStatiCommAsync(); selAzienda = await MDService.ConfigTryGetAsync("AZIENDA"); giacenzeConf = await MDService.ConfigTryGetAsync("SPEC_ShowGiacenze"); diff --git a/MP.SPEC/Components/ListGiacenze.razor.cs b/MP.SPEC/Components/ListGiacenze.razor.cs index 24f37bbe..542e02c7 100644 --- a/MP.SPEC/Components/ListGiacenze.razor.cs +++ b/MP.SPEC/Components/ListGiacenze.razor.cs @@ -42,7 +42,7 @@ namespace MP.SPEC.Components protected override async Task OnParametersSetAsync() { - elencoGiacenze = await MDService.ListGiacenze(IdxOdl); + elencoGiacenze = await MDService.ListGiacenzeAsync(IdxOdl); } #endregion Protected Methods diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 4f4a43c1..9fb69510 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -652,44 +652,21 @@ namespace MP.SPEC.Data } /// - /// Restitusice elenco Fasi + /// Restituisce elenco Fasi /// /// - public List ElencoGruppiFase() + public async Task> ElencoGruppiFaseAsync() { - using var activity = ActivitySource.StartActivity("ElencoGruppiFase"); - List result = new List(); - string source = "DB"; - string currKey = $"{Utils.redisAnagGruppi}:FASE"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - var rawResult = JsonConvert.DeserializeObject>($"{rawData}"); - if (rawResult != null) - { - result = rawResult; - } - source = "REDIS"; - } - else - { - result = dbController.AnagGruppiFase(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache / 5)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"ElencoGruppiFase | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + return await GetOrFetchAsync( + operationName: "ElencoGruppiFaseAsync", + cacheKey: $"{Utils.redisAnagGruppi}:FASE", + expiration: TimeSpan.FromMinutes(redisLongTimeCache / 5), + fetchFunc: async () => await dbController.AnagGruppiFaseAsync() ?? new List(), + tagList: [Utils.redisAnagGruppi] + ); } + /// /// Elenco link validi per il menu /// @@ -1369,38 +1346,20 @@ namespace MP.SPEC.Data } /// + /// Elenco giacenze filtrate x IdxOdl /// /// id odl da cercare /// - public async Task> ListGiacenze(int IdxOdl) + public async Task> ListGiacenzeAsync(int IdxOdl) { - using var activity = ActivitySource.StartActivity("ListGiacenze"); - List? result = new List(); - string source = "DB"; string currKey = $"{Utils.redisGiacenzaList}:{IdxOdl}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await Task.FromResult(dbController.ListGiacenze(IdxOdl)); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"ListGiacenze | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + return await GetOrFetchAsync( + operationName: "ListGiacenzeAsync", + cacheKey: currKey, + expiration: TimeSpan.FromSeconds(redisShortTimeCache), + fetchFunc: async () => await dbController.ListGiacenzeAsync(IdxOdl) ?? new List(), + tagList: [Utils.redisGiacenzaList] + ); } /// @@ -3050,76 +3009,6 @@ namespace MP.SPEC.Data await FlushCacheByTagsAsync(tags2del); } -#if false - /// - /// Update valore Dossier - /// - /// - /// - /// - public async Task updateDossierValue(DossierModel currDoss, FluxLogDTO editFL) - { - using var activity = ActivitySource.StartActivity("updateDossierValue"); - string source = "DB"; - bool answ = false; - // recupero intero set valori dossier deserializzando... - var fluxLogList = FluxLogDtoGetByFlux(currDoss.Valore); - // 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); - } - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"updateDossierValue | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return answ; - } -#endif -#if false - /// - /// Elimina i record associati al keyFilt indicato - /// - /// - public bool WipKitDeleteGroup(string KeyFilt) - { - using var activity = ActivitySource.StartActivity("WipKitDeleteGroup"); - string source = "DB"; - bool fatto = false; - // salvo - fatto = dbController.WipKitDeleteGroup(KeyFilt); - // svuoto cache - EmptyWipCache(); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"WipKitDeleteGroup Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return fatto; - } -#endif - /// /// Reset macchine e gruppi /// diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index de389880..e9b08d76 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2808 + 8.16.2605.2809 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/ODL.razor.cs b/MP.SPEC/Pages/ODL.razor.cs index fbc11aa7..2b759d2d 100644 --- a/MP.SPEC/Pages/ODL.razor.cs +++ b/MP.SPEC/Pages/ODL.razor.cs @@ -105,7 +105,7 @@ namespace MP.SPEC.Pages protected override async Task OnInitializedAsync() { await getReparto(); - var allGruppiData = MDService.ElencoGruppiFase(); + var allGruppiData = await MDService.ElencoGruppiFaseAsync(); if (allGruppiData != null) { ListGruppiFase = allGruppiData.Where(x => x.SelEnabled).ToList(); diff --git a/MP.SPEC/Pages/PODL.razor.cs b/MP.SPEC/Pages/PODL.razor.cs index 1a6b35ac..8e866756 100644 --- a/MP.SPEC/Pages/PODL.razor.cs +++ b/MP.SPEC/Pages/PODL.razor.cs @@ -130,7 +130,7 @@ namespace MP.SPEC.Pages { await getReparto(); ListAziende = await MDService.ElencoAziendeAsync(); - var allGruppiData = MDService.ElencoGruppiFase(); + var allGruppiData = await MDService.ElencoGruppiFaseAsync(); if (allGruppiData != null) { ListGruppiFase = allGruppiData.Where(x => x.SelEnabled).ToList(); diff --git a/MP.SPEC/Pages/Podl2Kit.razor.cs b/MP.SPEC/Pages/Podl2Kit.razor.cs index 9e8e270a..d2158b2d 100644 --- a/MP.SPEC/Pages/Podl2Kit.razor.cs +++ b/MP.SPEC/Pages/Podl2Kit.razor.cs @@ -1,12 +1,8 @@ using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.JSInterop; using MP.Data.DbModels; using MP.Data.Services; -using MP.SPEC.Components; using MP.SPEC.Data; -using NLog.Layouts; -using System.Reflection.PortableExecutable; namespace MP.SPEC.Pages { @@ -37,10 +33,6 @@ namespace MP.SPEC.Pages [Inject] protected IJSRuntime JSRuntime { get; set; } = null!; -#if false - [Inject] - protected ILocalStorageService localStorage { get; set; } = null!; -#endif [Inject] protected ILocalStorageService localStorage { get; set; } = null!; @@ -59,13 +51,17 @@ namespace MP.SPEC.Pages if (sCodComm != value) { sCodComm = value; - currPage = 1; - ListRecords = null; - ReloadData(); } } } + private async Task ResetDataAsync() + { + currPage = 1; + ListRecords = null; + await ReloadDataAsync(); + } + protected string sParentCss { get => string.IsNullOrEmpty(sCodComm) ? "btn-secondary" : "btn-primary"; @@ -120,8 +116,7 @@ namespace MP.SPEC.Pages protected async Task DoCancel() { EditRecord = null; - ReloadData(); - await Task.Delay(1); + await ResetDataAsync(); } /// @@ -137,8 +132,7 @@ namespace MP.SPEC.Pages await Task.Delay(1); var done = await MDService.IstKitDelete(selRec); EditRecord = null; - ReloadData(); - await Task.Delay(1); + await ResetDataAsync(); } protected async Task DoUpdate(IstanzeKitModel selRec) @@ -149,8 +143,7 @@ namespace MP.SPEC.Pages await Task.Delay(1); var done = await MDService.IstKitUpsert(selRec); EditRecord = null; - ReloadData(); - await Task.Delay(1); + await ResetDataAsync(); } protected override void OnInitialized() @@ -176,9 +169,9 @@ namespace MP.SPEC.Pages setBaseFilt(); } - protected override void OnParametersSet() + protected override async Task OnParametersSetAsync() { - ReloadData(); + await ReloadDataAsync(); } protected void ResetData() @@ -191,10 +184,10 @@ namespace MP.SPEC.Pages idxMaccSel = "*"; } - protected void ResetParent() + protected async Task ResetParent() { SearchComm = ""; - ReloadData(); + await ResetDataAsync(); } protected void resetReparto() @@ -228,10 +221,10 @@ namespace MP.SPEC.Pages numRecord = newNum; } - protected void UpdateData() + protected async Task UpdateData() { EditRecord = null; - ReloadData(); + await ResetDataAsync(); } #endregion Protected Methods @@ -311,7 +304,7 @@ namespace MP.SPEC.Pages if (_currPage != value) { _currPage = value; - ReloadData(); + UpdateTable(); } } } @@ -342,7 +335,7 @@ namespace MP.SPEC.Pages if (_numRecord != value) { _numRecord = value; - ReloadData(); + UpdateTable(); } } } @@ -359,11 +352,11 @@ namespace MP.SPEC.Pages #region Private Methods - private void ReloadData() + private async Task ReloadDataAsync() { isLoading = true; // leggo dati x filtro - var allGruppiData = MDService.ElencoGruppiFase(); + var allGruppiData = await MDService.ElencoGruppiFaseAsync(); if (allGruppiData != null) { ListGruppiFase = allGruppiData.Where(x => x.SelEnabled).ToList(); @@ -373,10 +366,15 @@ namespace MP.SPEC.Pages totalCount = SearchRecords.Count; // conto i kit = distinct... kitCount = SearchRecords.GroupBy(x => x.CodArtParent).Count(); - ListRecords = SearchRecords - .Skip(numRecord * (currPage - 1)) - .Take(numRecord) - .ToList(); + UpdateTable(); + } + + private void UpdateTable() + { + ListRecords = SearchRecords? + .Skip(numRecord * (currPage - 1)) + .Take(numRecord) + .ToList() ?? new(); isLoading = false; } @@ -423,7 +421,7 @@ namespace MP.SPEC.Pages currPage = 1; // salvo filtro reparto x utente... spostare in componente? await localStorage.SetItemAsync("reparto", repartoSel); - ReloadData(); + await ReloadDataAsync(); currFilter = newParams; isLoading = false; } diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 1fc88236..64ea7d73 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                          Versione: 8.16.2605.2808

                          +

                          Versione: 8.16.2605.2809


                          Note di rilascio:
                          • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 828db479..c5710be8 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2808 +8.16.2605.2809 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index ad15ce10..bb10b8fa 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2808 + 8.16.2605.2809 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From 31682e57daab2469d19596092f77ce44fd7a393b Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 09:40:36 +0200 Subject: [PATCH 033/102] Fix csv export warning + ottimizzazione e fix warnings vari metodi Core --- Egw.Core/Utils.cs | 27 ++++++++++++--------- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.Core/DTO/FluxLogDTO.cs | 12 ++++------ MP.Core/DTO/MappaStatoExplDTO.cs | 18 +++++++------- MP.Core/DTO/ParetoFluxLogDTO.cs | 8 +++---- MP.Core/DTO/ULogJsonPayloadDto.cs | 2 +- MP.Core/Utils.cs | 40 ++++++++++++------------------- 10 files changed, 53 insertions(+), 62 deletions(-) diff --git a/Egw.Core/Utils.cs b/Egw.Core/Utils.cs index 91376768..49b26d0d 100644 --- a/Egw.Core/Utils.cs +++ b/Egw.Core/Utils.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Reflection; namespace Egw.Core { @@ -19,14 +14,24 @@ namespace Egw.Core /// public static async Task SaveToCsv(List reportData, string path, char separator) { + // 1. Recuperiamo le proprietà del tipo T una sola volta (Risolve i problemi di performance) + PropertyInfo[] properties = typeof(T).GetProperties(); + var lines = new List(); - IEnumerable props = TypeDescriptor.GetProperties(typeof(T)).OfType(); - var header = string.Join(";", props.ToList().Select(x => x.Name)); + + // 2. Creiamo l'header usando il separatore corretto (Risolve il bug del ";" fisso) + var header = string.Join(separator, properties.Select(p => p.Name)); lines.Add(header); - 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)))); + + // 3. Estraiamo i valori gestendo i possibili null (Risolve il tuo warning) + var valueLines = reportData + .Where(row => row != null) + .Select(row => string.Join(separator, properties.Select(p => p.GetValue(row)?.ToString() ?? string.Empty))); + lines.AddRange(valueLines); - await Task.Run(() => File.WriteAllLines(path, lines.ToArray())); + + // 4. Utilizziamo il metodo di scrittura asincrono nativo di .NET + await File.WriteAllLinesAsync(path, lines); } } } diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index d2018285..16fb5d0d 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2605.2808 + 8.16.2605.2809 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 1fc88236..64ea7d73 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                            Versione: 8.16.2605.2808

                            +

                            Versione: 8.16.2605.2809


                            Note di rilascio:
                            • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 828db479..c5710be8 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2808 +8.16.2605.2809 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index 58e7ba81..f993cc62 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2808 + 8.16.2605.2809 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.Core/DTO/FluxLogDTO.cs b/MP.Core/DTO/FluxLogDTO.cs index 3b28e2c1..fcc54437 100644 --- a/MP.Core/DTO/FluxLogDTO.cs +++ b/MP.Core/DTO/FluxLogDTO.cs @@ -1,17 +1,15 @@ -using System; - -namespace MP.Core.DTO +namespace MP.Core.DTO { public class FluxLogDTO { - public string IdxMacchina { get; set; } + public string IdxMacchina { get; set; } = string.Empty; public DateTime dtEvento { get; set; } - public string CodFlux { get; set; } + public string CodFlux { get; set; } = string.Empty; - public string Valore { get; set; } + public string Valore { get; set; } = string.Empty; - public string ValoreEdit { get; set; } + public string ValoreEdit { get; set; } = string.Empty; } } \ No newline at end of file diff --git a/MP.Core/DTO/MappaStatoExplDTO.cs b/MP.Core/DTO/MappaStatoExplDTO.cs index 12fe6b44..353f7975 100644 --- a/MP.Core/DTO/MappaStatoExplDTO.cs +++ b/MP.Core/DTO/MappaStatoExplDTO.cs @@ -9,20 +9,20 @@ namespace MP.Core.DTO { public int RowNum { get; set; } public DateTime? LastUpdate { get; set; } - public string IdxMacchina { get; set; } - public string CodMacchina { get; set; } - public string Nome { get; set; } - public string Url { get; set; } + public string IdxMacchina { get; set; } = string.Empty; + public string CodMacchina { get; set; } = string.Empty; + public string Nome { get; set; } = string.Empty; + public string Url { get; set; } = string.Empty; public int? IdxOdl { get; set; } = 0; public int? IdxPOdl { get; set; } = 0; - public string CodArticolo { get; set; } - public string Disegno { get; set; } + public string CodArticolo { get; set; } = string.Empty; + public string Disegno { get; set; } = string.Empty; public int NumPezzi { get; set; } = 0; public decimal TCAssegnato { get; set; } = 0; public DateTime? DataInizioOdl { get; set; } - public string Semaforo { get; set; } + public string Semaforo { get; set; } = string.Empty; public int? IdxStato { get; set; } - public string DescrizioneStato { get; set; } + public string DescrizioneStato { get; set; } = string.Empty; public double? Durata { get; set; } public int PezziProd { get; set; } = 0; public int PezziConf { get; set; } = 0; @@ -65,7 +65,7 @@ namespace MP.Core.DTO get { int answ = 0; - if(NumPezzi < PezziProd) + if (NumPezzi < PezziProd) { answ = Math.Abs(NumPezzi - PezziProd); } diff --git a/MP.Core/DTO/ParetoFluxLogDTO.cs b/MP.Core/DTO/ParetoFluxLogDTO.cs index 94aea2c1..6b5e7239 100644 --- a/MP.Core/DTO/ParetoFluxLogDTO.cs +++ b/MP.Core/DTO/ParetoFluxLogDTO.cs @@ -1,11 +1,9 @@ -using System; - -namespace MP.Core.DTO +namespace MP.Core.DTO { public class ParetoFluxLogDTO { - public string IdxMacchina { get; set; } - public string CodFlux { get; set; } + public string IdxMacchina { get; set; } = string.Empty; + public string CodFlux { get; set; } = string.Empty; public int Qty { get; set; } } } \ No newline at end of file diff --git a/MP.Core/DTO/ULogJsonPayloadDto.cs b/MP.Core/DTO/ULogJsonPayloadDto.cs index bdd43e75..c81acc86 100644 --- a/MP.Core/DTO/ULogJsonPayloadDto.cs +++ b/MP.Core/DTO/ULogJsonPayloadDto.cs @@ -7,7 +7,7 @@ { #region Public Properties - public List fluxData { get; set; } + public List fluxData { get; set; } = new(); #endregion Public Properties } diff --git a/MP.Core/Utils.cs b/MP.Core/Utils.cs index 81d30f39..318b63c9 100644 --- a/MP.Core/Utils.cs +++ b/MP.Core/Utils.cs @@ -13,35 +13,25 @@ namespace MP.Core public const string redisAnagGruppi = redisBaseAddr + "Cache:AnagGruppi"; public const string redisAnagStati = redisBaseAddr + "Cache:AnagStati"; - public const string redisLinkMenu = redisBaseAddr + "Cache:LinkMenu"; - public const string redisArtByDossier = redisBaseAddr + "Cache:ArtByDossier"; - public const string redisArtList = redisBaseAddr + "Cache:ArtList"; - public const string redisBaseAddr = "MP:"; - public const string redisConfFlux = redisBaseAddr + "Cache:ConfFlux"; public const string redisConfKey = redisBaseAddr + "Cache:Config"; - public const string redisDecNumArtKey = redisBaseAddr + "Cache:DecNumArt"; - public const string redisDossByMac = redisBaseAddr + "Cache:DossByMac"; public const string redisDossByMacLast = redisBaseAddr + "Cache:DossByMacLast"; - public const string redisEventList = redisBaseAddr + "Cache:EventList"; - public const string redisFluxByMac = redisBaseAddr + "Cache:FluxByMac"; public const string redisFluxByMacFirst = redisBaseAddr + "Cache:FluxByMacFirst"; public const string redisFluxLogFilt = redisBaseAddr + "Cache:FluxLogFilt"; - public const string redisGiacenzaList = redisBaseAddr + "Cache:GiacenzaList"; - public const string redisKit = redisBaseAddr + "Cache:Kit"; public const string redisKitInst = redisBaseAddr + "Cache:Kit:Inst"; public const string redisKitScore = redisBaseAddr + "Cache:Kit:Score"; public const string redisKitTempl = redisBaseAddr + "Cache:Kit:Templ"; public const string redisKitWip = redisBaseAddr + "Cache:Kit:Wip"; + public const string redisLinkMenu = redisBaseAddr + "Cache:LinkMenu"; public const string redisMacByFlux = redisBaseAddr + "Cache:MacByFlux"; public const string redisMacList = redisBaseAddr + "Cache:MacList"; @@ -90,12 +80,12 @@ namespace MP.Core public static string redKeyArtUsed { - get => RedHash($"SPEC:Cache:CheckArtUsed"); + get => RedHash($"SPEC:Cache:CheckArtUsed").ToString(); } public static string redKeyTabCheckArt { - get => RedHash($"CACHE:TabCheckArt"); + get => RedHash($"CACHE:TabCheckArt").ToString(); } #endregion Public Properties @@ -182,7 +172,7 @@ namespace MP.Core /// /// Chiave override per i valori in caso di dati che accedono al dominio dati di un altra app (es: baseAddr x IO legacy) /// - public static RedisKey RedKeyCurrObjItems(string idxMacchina, string baseAddr = null) + public static RedisKey RedKeyCurrObjItems(string idxMacchina, string? baseAddr = null) { var prefix = (baseAddr ?? redisBaseAddr).TrimEnd(':'); return (RedisKey)$"{prefix}:CurrentParameters:{idxMacchina}"; @@ -194,7 +184,7 @@ namespace MP.Core /// /// Chiave override per i valori in caso di dati che accedono al dominio dati di un altra app (es: baseAddr x IO legacy) /// - public static RedisKey RedKeyDatiMacc(string idxMacchina, string baseAddr = null) + public static RedisKey RedKeyDatiMacc(string idxMacchina, string? baseAddr = null) { var prefix = (baseAddr ?? redisBaseAddr).TrimEnd(':'); return (RedisKey)$"{prefix}:DtMac:{idxMacchina}"; @@ -214,7 +204,7 @@ namespace MP.Core /// /// Chiave override per i valori in caso di dati che accedono al dominio dati di un altra app (es: baseAddr x IO legacy) /// - public static RedisKey RedKeyIobConfYaml(string idxMacchina, string baseAddr = null) + public static RedisKey RedKeyIobConfYaml(string idxMacchina, string? baseAddr = null) { var prefix = (baseAddr ?? redisBaseAddr).TrimEnd(':'); return (RedisKey)$"{prefix}:IOB:{idxMacchina}:ConfYaml"; @@ -226,7 +216,7 @@ namespace MP.Core /// /// Chiave override per i valori in caso di dati che accedono al dominio dati di un altra app (es: baseAddr x IO legacy) /// - public static RedisKey RedKeyIobMemMap(string idxMacchina, string baseAddr = null) + public static RedisKey RedKeyIobMemMap(string idxMacchina, string? baseAddr = null) { var prefix = (baseAddr ?? redisBaseAddr).TrimEnd(':'); return (RedisKey)$"{prefix}:MemMap:{idxMacchina}"; @@ -239,7 +229,7 @@ namespace MP.Core /// /// Chiave override per i valori in caso di dati che accedono al dominio dati di un altra app (es: baseAddr x IO legacy) /// - public static RedisKey RedKeyLastFLog(string idxMacchina, string flog, string baseAddr = null) + public static RedisKey RedKeyLastFLog(string idxMacchina, string flog, string? baseAddr = null) { var prefix = (baseAddr ?? redisBaseAddr).TrimEnd(':'); return (RedisKey)$"{prefix}:FLOG:{idxMacchina}:{flog}"; @@ -251,7 +241,7 @@ namespace MP.Core /// /// /// - public static RedisKey RedKeyMach2Iob(string idxMacchina, string baseAddr = null) + public static RedisKey RedKeyMach2Iob(string idxMacchina, string? baseAddr = null) { var prefix = (baseAddr ?? redisBaseAddr).TrimEnd(':'); return (RedisKey)$"{prefix}:hM2IOB:{idxMacchina}"; @@ -263,7 +253,7 @@ namespace MP.Core /// /// /// - public static RedisKey RedKeyMachIobConf(string idxMacchina, string baseAddr = null) + public static RedisKey RedKeyMachIobConf(string idxMacchina, string? baseAddr = null) { var prefix = (baseAddr ?? redisBaseAddr).TrimEnd(':'); return (RedisKey)$"{prefix}:IOB:{idxMacchina}:MachIobConf"; @@ -275,7 +265,7 @@ namespace MP.Core /// /// Chiave override per i valori in caso di dati che accedono al dominio dati di un altra app (es: baseAddr x IO legacy) /// - public static RedisKey RedKeyMsmi(string idxMacchina, string baseAddr = null) + public static RedisKey RedKeyMsmi(string idxMacchina, string? baseAddr = null) { var prefix = (baseAddr ?? redisBaseAddr).TrimEnd(':'); return (RedisKey)$"{prefix}:hMSMI:{idxMacchina}"; @@ -287,7 +277,7 @@ namespace MP.Core /// /// Chiave override per i valori in caso di dati che accedono al dominio dati di un altra app (es: baseAddr x IO legacy) /// - public static RedisKey RedKeyOptPar(string idxMacchina, string baseAddr = null) + public static RedisKey RedKeyOptPar(string idxMacchina, string? baseAddr = null) { var prefix = (baseAddr ?? redisBaseAddr).TrimEnd(':'); return (RedisKey)$"{prefix}:OptPar:{idxMacchina}"; @@ -299,7 +289,7 @@ namespace MP.Core /// /// Chiave override per i valori in caso di dati che accedono al dominio dati di un altra app (es: baseAddr x IO legacy) /// - public static RedisKey RedKeyPzCount(string idxMacchina, string baseAddr = null) + public static RedisKey RedKeyPzCount(string idxMacchina, string? baseAddr = null) { var prefix = (baseAddr ?? redisBaseAddr).TrimEnd(':'); return (RedisKey)$"{prefix}:PzCount:{idxMacchina}"; @@ -311,7 +301,7 @@ namespace MP.Core ///
                          /// /// - public static RedisKey RedKeySavedTask2ExeMacc(string idxMacchina, string baseAddr = null) + public static RedisKey RedKeySavedTask2ExeMacc(string idxMacchina, string? baseAddr = null) { var prefix = (baseAddr ?? redisBaseAddr).TrimEnd(':'); return (RedisKey)$"{prefix}:SavedTask:{idxMacchina}"; @@ -323,7 +313,7 @@ namespace MP.Core /// /// Chiave override per i valori in caso di dati che accedono al dominio dati di un altra app (es: baseAddr x IO legacy) /// - public static RedisKey RedKeyTask2ExeMacc(string idxMacchina, string baseAddr = null) + public static RedisKey RedKeyTask2ExeMacc(string idxMacchina, string? baseAddr = null) { var prefix = (baseAddr ?? redisBaseAddr).TrimEnd(':'); return (RedisKey)$"{prefix}:ExeTask:{idxMacchina}"; From ce59a00d020399318e6e0fcce69832af14a9d4d4 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 09:41:22 +0200 Subject: [PATCH 034/102] Correzioni warnings in TaskMan --- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- MP.TaskMan/Controllers/MpTaskController.cs | 13 ++------ MP.TaskMan/Services/TaskService.cs | 37 ++++++++++------------ MP.TaskMan/TaskExeList.razor.cs | 29 ++++++++++------- MP.TaskMan/TaskList.razor.cs | 7 ++-- MP.TaskMan/TaskListTable.razor.cs | 5 ++- 29 files changed, 67 insertions(+), 72 deletions(-) diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index 2d758695..b03cdbda 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2605.2808 + 8.16.2605.2809 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index f21a80e9..8829f265 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                          Versione: 8.16.2605.2808

                          +

                          Versione: 8.16.2605.2809


                          Note di rilascio:
                          • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index 828db479..c5710be8 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2808 +8.16.2605.2809 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index d1535baa..46859ddf 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2808 + 8.16.2605.2809 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index dd8f7d78..2c60b1aa 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2605.2808 + 8.16.2605.2809 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 474c8f3d..241e7d7d 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                            Versione: 8.16.2605.2808

                            +

                            Versione: 8.16.2605.2809


                            Note di rilascio:
                              diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 828db479..c5710be8 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2808 +8.16.2605.2809 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index fc2d24fe..6f8aeb69 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2808 + 8.16.2605.2809 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index 34adfe61..d59e8e78 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2605.2808 + 8.16.2605.2809 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 1fc88236..64ea7d73 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                              Versione: 8.16.2605.2808

                              +

                              Versione: 8.16.2605.2809


                              Note di rilascio:
                              • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 828db479..c5710be8 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2808 +8.16.2605.2809 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index 5d52ff5f..a39501a5 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2808 + 8.16.2605.2809 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 3601b540..85d82cfd 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2605.2808 + 8.16.2605.2809 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index e99d3083..a67c97db 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                Versione: 8.16.2605.2808

                                +

                                Versione: 8.16.2605.2809


                                Note di rilascio:
                                  diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 828db479..c5710be8 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2808 +8.16.2605.2809 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 70a2dbb7..5fffba9d 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2808 + 8.16.2605.2809 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index fa7dd417..d997ea7a 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2605.2808 + 8.16.2605.2809 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index 98241e80..9ecf5dd5 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                  Versione: 8.16.2605.2808

                                  +

                                  Versione: 8.16.2605.2809


                                  Note di rilascio:
                                  • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index 828db479..c5710be8 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2808 +8.16.2605.2809 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index 67258ee2..375ab3ee 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2808 + 8.16.2605.2809 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index d793d9c7..dd106114 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2605.2808 + 8.16.2605.2809 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index bf5b6ad9..3c0aaeec 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                    Versione: 8.16.2605.2808

                                    +

                                    Versione: 8.16.2605.2809


                                    Note di rilascio:
                                      diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 828db479..c5710be8 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2808 +8.16.2605.2809 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index 6a52562d..0f083e08 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2808 + 8.16.2605.2809 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false diff --git a/MP.TaskMan/Controllers/MpTaskController.cs b/MP.TaskMan/Controllers/MpTaskController.cs index 0ccb73bf..fadf73d4 100644 --- a/MP.TaskMan/Controllers/MpTaskController.cs +++ b/MP.TaskMan/Controllers/MpTaskController.cs @@ -2,16 +2,11 @@ using Microsoft.Extensions.Configuration; using MP.TaskMan.Models; using NLog; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using static MP.TaskMan.Objects.Enums; namespace MP.TaskMan.Controllers { - public class MpTaskController : IDisposable + public class MpTaskController { #region Public Constructors @@ -87,11 +82,7 @@ namespace MP.TaskMan.Controllers return dtNext; } - public void Dispose() - { - _configuration = null; - } - + /// /// Chiamata esecuzione di un singolo task programmato, SE in stato abilitato /// diff --git a/MP.TaskMan/Services/TaskService.cs b/MP.TaskMan/Services/TaskService.cs index 7727f72a..abbf331e 100644 --- a/MP.TaskMan/Services/TaskService.cs +++ b/MP.TaskMan/Services/TaskService.cs @@ -16,7 +16,7 @@ using static MP.TaskMan.Objects.Enums; namespace MP.TaskMan.Services { - public class TaskService : BaseServ, IDisposable + public class TaskService : BaseServ { #region Public Constructors @@ -88,15 +88,6 @@ namespace MP.TaskMan.Services #region Public Methods - public void Dispose() - { - // Clear database controller - MLController.Dispose(); - // redis dispose - redisConn = null; - redisDb = null; - } - /// /// Chiamata esecuzione di un singolo task programmato /// @@ -136,18 +127,22 @@ namespace MP.TaskMan.Services { var callResp = await RCallService.CallRestGet(TaskRec.Command, TaskRec.Args); DateTime dtEnd = DateTime.Now; - string formattedJson = JValue.Parse(callResp.Content).ToString(Formatting.Indented); - TaskExecModel tExeMod = new TaskExecModel() + if (callResp != null && !string.IsNullOrEmpty(callResp.Content)) { - DtEnd = dtEnd, - DtStart = dtStart, - IsError = callResp.StatusCode != System.Net.HttpStatusCode.OK, - TaskId = TaskRec.TaskId, - // deserializzazione come json indentato?!? - Result = formattedJson// $"{callResp.Content}".Replace("\"", ""), - }; - // salvo su DB - answ = MLController.TaskExecSaveExecuted(TaskRec.TaskId, SchedNext, tExeMod); + + string formattedJson = JValue.Parse(callResp.Content).ToString(Formatting.Indented); + TaskExecModel tExeMod = new TaskExecModel() + { + DtEnd = dtEnd, + DtStart = dtStart, + IsError = callResp.StatusCode != System.Net.HttpStatusCode.OK, + TaskId = TaskRec.TaskId, + // deserializzazione come json indentato?!? + Result = formattedJson// $"{callResp.Content}".Replace("\"", ""), + }; + // salvo su DB + answ = MLController.TaskExecSaveExecuted(TaskRec.TaskId, SchedNext, tExeMod); + } } break; diff --git a/MP.TaskMan/TaskExeList.razor.cs b/MP.TaskMan/TaskExeList.razor.cs index 2ffdad04..8fa45d62 100644 --- a/MP.TaskMan/TaskExeList.razor.cs +++ b/MP.TaskMan/TaskExeList.razor.cs @@ -95,8 +95,8 @@ namespace MP.TaskMan private static Logger Log = LogManager.GetCurrentClassLogger(); - private List ListRecords; - private List SearchRecords; + private List ListRecords = new(); + private List SearchRecords = new(); #endregion Private Fields @@ -112,19 +112,26 @@ namespace MP.TaskMan private async Task ReloadData() { - SearchRecords = await TService.TaskExecGetFilt(CurrRecord.TaskId, 1000, ""); - // se non tutti filtro... - if (ShowErrorMode != 0) + if (CurrRecord != null) { - if (ShowErrorMode == 1) + SearchRecords = await TService.TaskExecGetFilt(CurrRecord.TaskId, 1000, ""); + // se non tutti filtro... + if (ShowErrorMode != 0) { - SearchRecords = SearchRecords.FindAll(x => x.IsError); - } - else if (ShowErrorMode == 2) - { - SearchRecords = SearchRecords.FindAll(x => !x.IsError); + if (ShowErrorMode == 1) + { + SearchRecords = SearchRecords.FindAll(x => x.IsError); + } + else if (ShowErrorMode == 2) + { + SearchRecords = SearchRecords.FindAll(x => !x.IsError); + } } } + else + { + SearchRecords = new(); + } totalCount = SearchRecords.Count; ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); } diff --git a/MP.TaskMan/TaskList.razor.cs b/MP.TaskMan/TaskList.razor.cs index 09de8099..30eabb1a 100644 --- a/MP.TaskMan/TaskList.razor.cs +++ b/MP.TaskMan/TaskList.razor.cs @@ -205,8 +205,11 @@ namespace MP.TaskMan protected void ResetData() { - TService.rollBackEdit(currRecord); - currRecord = null; + if (currRecord != null) + { + TService.rollBackEdit(currRecord); + currRecord = null; + } } protected double righDiv(double num, double den) diff --git a/MP.TaskMan/TaskListTable.razor.cs b/MP.TaskMan/TaskListTable.razor.cs index 58d7f59f..2449ca37 100644 --- a/MP.TaskMan/TaskListTable.razor.cs +++ b/MP.TaskMan/TaskListTable.razor.cs @@ -10,10 +10,10 @@ namespace MP.TaskMan #region Public Properties [Parameter] - public int CodGroup { get; set; } = 0; + public List AllRecords { get; set; } = new List(); [Parameter] - public List AllRecords { get; set; } = new List(); + public int CodGroup { get; set; } = 0; [Parameter] public EventCallback EC_Cancel { get; set; } @@ -207,7 +207,6 @@ namespace MP.TaskMan private int currPage = 1; private TaskListModel? DetailTaskId = null; - private bool isLoading = false; private List ListRecords = new List(); private int maxOrdinal = 999; private int minOrdinal = 0; From e4d56be0afe3205cea1b8fc266169532fc79b06d Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 10:33:00 +0200 Subject: [PATCH 035/102] Correzioni warnings vari e test compilazione, fix applicazioni CORE in generale --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.Data/Controllers/MpIocController.cs | 10 +-- MP.Data/MoonProContext.cs | 43 +------------ MP.Data/MoonPro_UtilsContext.cs | 21 +----- MP.Data/Services/IOC/IocService.cs | 12 ++-- MP.Data/Services/MessageService.cs | 18 ------ MP.Data/Services/OrderDataSrv.cs | 5 -- MP.Data/Services/TabDataService.cs | 64 +------------------ MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/Data/MpDataService.cs | 29 ++++----- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- .../Components/ProdKit/KitComposer.razor.cs | 5 +- .../Components/ProdKit/KitDetailModal.razor | 29 ++++++--- MP.SPEC/Components/ProdKit/Manager.razor.cs | 6 +- .../Components/Reparti/ListOperatori.razor.cs | 2 - MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Giacenze.razor.cs | 5 +- MP.SPEC/Pages/Podl2Kit.razor.cs | 4 +- MP.SPEC/Pages/ProdPlanner.razor | 3 +- MP.SPEC/Program.cs | 7 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- MP.SPEC/Services/IOApiService.cs | 6 +- MP.Stats/Components/ChartEnergy.razor | 3 +- MP.Stats/Components/ChartJs/Chart.razor | 6 +- MP.Stats/MP.Stats.csproj | 6 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- 55 files changed, 108 insertions(+), 246 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index 16fb5d0d..b1aaa6d2 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2605.2809 + 8.16.2605.2810 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 64ea7d73..a6dbd98e 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                      Versione: 8.16.2605.2809

                                      +

                                      Versione: 8.16.2605.2810


                                      Note di rilascio:
                                      • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index c5710be8..7076e6d6 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2809 +8.16.2605.2810 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index f993cc62..b832aa5a 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2809 + 8.16.2605.2810 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.Data/Controllers/MpIocController.cs b/MP.Data/Controllers/MpIocController.cs index 4c3cb3be..c452739b 100644 --- a/MP.Data/Controllers/MpIocController.cs +++ b/MP.Data/Controllers/MpIocController.cs @@ -346,14 +346,14 @@ namespace MP.Data.Controllers using var dbCtx = new MoonProContext(options); bool fatto = false; - var dbResult = dbCtx - .DbSetConfig - .Where(x => x.Chiave == updRec.Chiave) - .FirstOrDefault(); + var dbResult = await dbCtx + .DbSetConfig + .Where(x => x.Chiave == updRec.Chiave) + .FirstOrDefaultAsync(); if (dbResult != null) { dbResult.Valore = updRec.Valore; - fatto = dbCtx.SaveChanges() > 0; + fatto = await dbCtx.SaveChangesAsync() > 0; } return fatto; diff --git a/MP.Data/MoonProContext.cs b/MP.Data/MoonProContext.cs index 2789eb05..16fef1fa 100644 --- a/MP.Data/MoonProContext.cs +++ b/MP.Data/MoonProContext.cs @@ -1,9 +1,7 @@ using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; using MP.Core.DTO; using MP.Data.DbModels; using MP.Data.DbModels.Anag; -using NLog; #nullable disable // @@ -13,27 +11,9 @@ namespace MP.Data { public partial class MoonProContext : DbContext { - #region Private Fields - - private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); - - private IConfiguration _configuration; - - #endregion Private Fields #region Public Constructors - //public MoonProContext(IConfiguration configuration) - //{ - // _configuration = configuration; - //} - - //public MoonProContext(DbContextOptions options, IConfiguration configuration) - //: base(options) - //{ - // _configuration = configuration; - //} - public MoonProContext(DbContextOptions options) : base(options) { } @@ -92,7 +72,6 @@ namespace MP.Data public virtual DbSet DbSetRegWithCheck { get; set; } public virtual DbSet DbSetSignalLog { get; set; } - public virtual DbSet DbSetStAct { get; set; } public virtual DbSet DbSetStActRow { get; set; } public virtual DbSet DbSetStAnagGruppi { get; set; } @@ -130,26 +109,8 @@ namespace MP.Data { if (!optionsBuilder.IsConfigured) { - string connString = _configuration.GetConnectionString("MP.Data"); - if (string.IsNullOrEmpty(connString)) - { - connString = _configuration.GetConnectionString("MP.All"); - } - if (string.IsNullOrEmpty(connString)) - { - connString = _configuration.GetConnectionString("MP.Land"); - } - if (string.IsNullOrEmpty(connString)) - { - connString = _configuration.GetConnectionString("MP.Mon"); - } - if (string.IsNullOrEmpty(connString)) - { - connString = _configuration.GetConnectionString("MP.STATS"); - } - - optionsBuilder.UseSqlServer(connString); - //optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=MoonPro;Trusted_Connection=True;"); + // fallback si spera non necessario + optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=MoonPro;Trusted_Connection=True;"); } } diff --git a/MP.Data/MoonPro_UtilsContext.cs b/MP.Data/MoonPro_UtilsContext.cs index edb248e1..a7c673e3 100644 --- a/MP.Data/MoonPro_UtilsContext.cs +++ b/MP.Data/MoonPro_UtilsContext.cs @@ -1,8 +1,6 @@ using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; using MP.Data.DbModels.Mtc; using MP.Data.DbModels.Utils; -using NLog; using System; #nullable disable @@ -13,14 +11,6 @@ namespace MP.Data { public partial class MoonPro_UtilsContext : DbContext { - #region Private Fields - - private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); - - private IConfiguration _configuration; - - #endregion Private Fields - #region Public Constructors /// @@ -66,15 +56,8 @@ namespace MP.Data { if (!optionsBuilder.IsConfigured) { - string connString = _configuration.GetConnectionString("MP.Utils"); - if (!string.IsNullOrEmpty(connString)) - { - optionsBuilder.UseSqlServer(connString); - } - else - { - optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=MoonPro_Utils;Trusted_Connection=True;"); - } + // fallback (si spera non necessario) + optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=MoonPro_Utils;Trusted_Connection=True;"); } } diff --git a/MP.Data/Services/IOC/IocService.cs b/MP.Data/Services/IOC/IocService.cs index c3a8369e..416ad3e6 100644 --- a/MP.Data/Services/IOC/IocService.cs +++ b/MP.Data/Services/IOC/IocService.cs @@ -468,10 +468,6 @@ namespace MP.Data.Services.IOC /// private async Task GetOrFetchAsync(string cacheKey, Func> fetchFunc, TimeSpan expiration) { - // GetOrSetAsync di Fusion cache: - // - TryGetValue, se mancasse crea un lock solo per QUELLA key - // - Esegue fetchFunc (la logica Redis + DB) - // - Salva in memoria e rilascia il lock return await _cache.GetOrSetAsync( cacheKey, async ct => await fetchFunc(), @@ -1066,19 +1062,19 @@ namespace MP.Data.Services.IOC string currVals = $"idxMacchina: {idxMacchina} | valOut: {valore} | dtEve: {dtEve} | dtCurr:{dtCurr}"; if (dtEve == null || dtCurr == null) { - Log.Warn($"procInput: null found | {currVals}"); + Log.Warn($"{_className} | procInput: null found | {currVals}"); } else if (dtEve.Length < 17 || dtCurr.Length < 17) { - Log.Info($"procInput: invalid data | {currVals}"); + Log.Info($"{_className} | procInput: invalid data | {currVals}"); } else if (string.IsNullOrEmpty(idxMacchina)) { - Log.Info($"procInput: missing IdxMacchina | {currVals}"); + Log.Info($"{_className} | procInput: missing IdxMacchina | {currVals}"); } else if (string.IsNullOrEmpty(valore)) { - Log.Info($"procInput: missing valOut | {currVals}"); + Log.Info($"{_className} | procInput: missing valOut | {currVals}"); } else { diff --git a/MP.Data/Services/MessageService.cs b/MP.Data/Services/MessageService.cs index 38d4db11..dda06848 100644 --- a/MP.Data/Services/MessageService.cs +++ b/MP.Data/Services/MessageService.cs @@ -47,10 +47,6 @@ namespace MP.Data.Services public event Action EA_OperUpdated = null!; - public event Action EA_PageUpdated = null!; - - public event Action EA_ResetFooterTimer = null!; - #endregion Public Events #region Public Properties @@ -707,26 +703,12 @@ namespace MP.Data.Services private AnagOperatoriModel? _rigaOper; - /// - /// Durata cache lunga IN SECONDI - /// - private int cacheTtlLong = 60 * 5; - - /// - /// Durata cache breve IN SECONDI - /// - private int cacheTtlShort = 60 * 1; - - private string lastIdxMacc = ""; - private DateTime lastUserUpd = DateTime.Now; private Logger Log = LogManager.GetCurrentClassLogger(); private string redisBaseKey = "MP:TAB:User"; - private Random rnd = new Random(); - #endregion Private Fields #region Private Properties diff --git a/MP.Data/Services/OrderDataSrv.cs b/MP.Data/Services/OrderDataSrv.cs index 19a08304..f6865451 100644 --- a/MP.Data/Services/OrderDataSrv.cs +++ b/MP.Data/Services/OrderDataSrv.cs @@ -1,16 +1,11 @@ using Microsoft.Extensions.Configuration; -using MP.Core.Conf; using MP.Data.DbModels; using Newtonsoft.Json; using NLog; using StackExchange.Redis; using System; using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; -using System.Data; using System.Diagnostics; -using System.IO; -using System.Linq; using System.Text; using System.Threading.Tasks; diff --git a/MP.Data/Services/TabDataService.cs b/MP.Data/Services/TabDataService.cs index 51ad1231..f16614b2 100644 --- a/MP.Data/Services/TabDataService.cs +++ b/MP.Data/Services/TabDataService.cs @@ -3945,75 +3945,13 @@ namespace MP.Data.Services #region Private Methods - /// - /// Esegue flush memoria _redisConn dato pat2Flush, metodo sincrono - /// - /// - /// - private bool ExecFlushRedisPattern(RedisValue pat2Flush) - { - bool answ = false; - var masterEndpoint = _redisConn.GetEndPoints() - .Where(ep => _redisConn.GetServer(ep).IsConnected && !_redisConn.GetServer(ep).IsReplica) - .FirstOrDefault(); - - // sepattern è "*" elimino intero DB... - if (masterEndpoint != null && (pat2Flush.Equals(new RedisValue("*")) || pat2Flush == RedisValue.Null)) - { - _redisConn.GetServer(masterEndpoint).FlushDatabase(database: _redisDb.Database); - } - else - { - var server = _redisConn.GetServer(masterEndpoint); - var keys = server.Keys(database: _redisDb.Database, pattern: pat2Flush, pageSize: 1000); - var batch = new List(); - foreach (var key in keys) - { - batch.Add(key); - - // Flush in batches of 1000 - if (batch.Count >= 1000) - { - foreach (var item in batch) - _redisDb.KeyDelete(item); - - batch.Clear(); - } - } - - // Flush remaining keys - foreach (var item in batch) - _redisDb.KeyDelete(item); - } - answ = true; -#if false - var listEndpoints = redisConn.GetEndPoints(); - foreach (var endPoint in listEndpoints) - { - //var server = redisConnAdmin.GetServer(listEndpoints[0]); - var server = redisConn.GetServer(endPoint); - if (server != null) - { - var keyList = server.Keys(redisDb.Database, pattern); - foreach (var item in keyList) - { - redisDb.KeyDelete(item); - } - answ = true; - } - } -#endif - // notifico update ai client in ascolto x reset cache - NotifyReloadRequest($"FlushRedisCache | {pat2Flush}"); - return answ; - } /// /// Esegue flush memoria _redisConn dato pat2Flush in async /// /// /// - private async Task ExecFlushRedisPatternAsync(RedisValue pat2Flush) + private async new Task ExecFlushRedisPatternAsync(RedisValue pat2Flush) { bool answ = false; var masterEndpoint = _redisConn.GetEndPoints() diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index b03cdbda..44ab5ad6 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2605.2809 + 8.16.2605.2810 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index 8829f265..109e6a53 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                        Versione: 8.16.2605.2809

                                        +

                                        Versione: 8.16.2605.2810


                                        Note di rilascio:
                                        • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index c5710be8..7076e6d6 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2809 +8.16.2605.2810 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index 46859ddf..a1c72ade 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2809 + 8.16.2605.2810 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs index 7976ffbb..945616a5 100644 --- a/MP.IOC/Data/MpDataService.cs +++ b/MP.IOC/Data/MpDataService.cs @@ -1319,7 +1319,7 @@ namespace MP.IOC.Data /// Restitusice elenco fasi ///
                                        /// - public Task> ElencoGruppiFase() + public async Task> ElencoGruppiFaseAsync() { List result = new List(); Stopwatch stopWatch = new Stopwatch(); @@ -1327,7 +1327,7 @@ namespace MP.IOC.Data string readType = "DB"; string currKey = $"{Utils.redisAnagGruppi}"; // cerco in redis dato valOut sel macchina... - RedisValue rawData = redisDb.StringGet(currKey); + RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { var rawResult = JsonConvert.DeserializeObject>($"{rawData}"); @@ -1339,10 +1339,10 @@ namespace MP.IOC.Data } else { - result = SpecDbController.AnagGruppiFase(); + result = await SpecDbController.AnagGruppiFaseAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache / 5)); + await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache / 5)); } if (result == null) { @@ -1350,17 +1350,10 @@ namespace MP.IOC.Data } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"ElencoGruppiFase | Read from {readType}: {ts.TotalMilliseconds}ms"); - return Task.FromResult(result); + Log.Debug($"ElencoGruppiFaseAsync | Read from {readType}: {ts.TotalMilliseconds}ms"); + return result; } -#if false - public Task> ElencoLinkAsync() - { - return SpecDbController.ElencoLinkAsync(); - } -#endif - /// /// Aggiunta record EventList /// @@ -1803,7 +1796,7 @@ namespace MP.IOC.Data ///
                          /// idxMacc odl da cercare /// - public async Task> ListGiacenze(int IdxOdl) + public async Task> ListGiacenzeAsync(int IdxOdl) { List? result = new List(); Stopwatch stopWatch = new Stopwatch(); @@ -1811,7 +1804,7 @@ namespace MP.IOC.Data string readType = "DB"; string currKey = $"{Utils.redisGiacenzaList}:{IdxOdl}"; // cerco in redis dato valOut sel macchina... - RedisValue rawData = redisDb.StringGet(currKey); + RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); @@ -1819,10 +1812,10 @@ namespace MP.IOC.Data } else { - result = await Task.FromResult(SpecDbController.ListGiacenze(IdxOdl)); + result = await SpecDbController.ListGiacenzeAsync(IdxOdl); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); + await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); } if (result == null) { @@ -1830,7 +1823,7 @@ namespace MP.IOC.Data } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"ListGiacenze | Read from {readType}: {ts.TotalMilliseconds}ms"); + Log.Debug($"ListGiacenzeAsync | Read from {readType}: {ts.TotalMilliseconds}ms"); return result; } diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 15eee620..0ff59adf 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.2808 + 8.16.2605.2810 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 8a235ada..748a7459 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                          Versione: 8.16.2605.2808

                          +

                          Versione: 8.16.2605.2810


                          Note di rilascio:
                          • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 828db479..7076e6d6 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2808 +8.16.2605.2810 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index b9aa95bf..56f086fc 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2808 + 8.16.2605.2810 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 2c60b1aa..31066432 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2605.2809 + 8.16.2605.2810 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 241e7d7d..1b09f5c9 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                            Versione: 8.16.2605.2809

                            +

                            Versione: 8.16.2605.2810


                            Note di rilascio:
                              diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index c5710be8..7076e6d6 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2809 +8.16.2605.2810 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index 6f8aeb69..27aee25f 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2809 + 8.16.2605.2810 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index d59e8e78..861c941f 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2605.2809 + 8.16.2605.2810 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 64ea7d73..a6dbd98e 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                              Versione: 8.16.2605.2809

                              +

                              Versione: 8.16.2605.2810


                              Note di rilascio:
                              • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index c5710be8..7076e6d6 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2809 +8.16.2605.2810 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index a39501a5..c612fe2c 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2809 + 8.16.2605.2810 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 85d82cfd..e426e70d 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2605.2809 + 8.16.2605.2810 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index a67c97db..e6a0d1b2 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                Versione: 8.16.2605.2809

                                +

                                Versione: 8.16.2605.2810


                                Note di rilascio:
                                  diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index c5710be8..7076e6d6 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2809 +8.16.2605.2810 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 5fffba9d..f1739aad 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2809 + 8.16.2605.2810 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index d997ea7a..714b489b 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2605.2809 + 8.16.2605.2810 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index 9ecf5dd5..62b22040 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                  Versione: 8.16.2605.2809

                                  +

                                  Versione: 8.16.2605.2810


                                  Note di rilascio:
                                  • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index c5710be8..7076e6d6 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2809 +8.16.2605.2810 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index 375ab3ee..5b4df2e1 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2809 + 8.16.2605.2810 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Components/ProdKit/KitComposer.razor.cs b/MP.SPEC/Components/ProdKit/KitComposer.razor.cs index c27d4ea9..8e5af742 100644 --- a/MP.SPEC/Components/ProdKit/KitComposer.razor.cs +++ b/MP.SPEC/Components/ProdKit/KitComposer.razor.cs @@ -10,10 +10,10 @@ namespace MP.SPEC.Components.ProdKit #region Public Properties [Parameter] - public EventCallback EC_ListUpdated { get; set; } + public EventCallback EC_ListCleared { get; set; } [Parameter] - public EventCallback EC_ListCleared { get; set; } + public EventCallback EC_ListUpdated { get; set; } [Parameter] public string KeyFilt { get; set; } = ""; @@ -75,7 +75,6 @@ namespace MP.SPEC.Components.ProdKit #region Private Fields - private PODLExpModel? currRec = null; private List ListRecords = new List(); #endregion Private Fields diff --git a/MP.SPEC/Components/ProdKit/KitDetailModal.razor b/MP.SPEC/Components/ProdKit/KitDetailModal.razor index 25fc0836..1c815937 100644 --- a/MP.SPEC/Components/ProdKit/KitDetailModal.razor +++ b/MP.SPEC/Components/ProdKit/KitDetailModal.razor @@ -80,20 +80,31 @@
      - @foreach (var record in ListTK) + @if (ListTK == null) { - - - } + else + { + foreach (var record in ListTK) + { + + + + + + } + }
      - + @record.CodArtParent @record.ChildFound / @numRecWsm
      - @record.CodArtParent - - @record.CodArtChild - -
      @record.Qty
      +
      +
      No data found
      + @record.CodArtParent + + @record.CodArtChild + +
      @record.Qty
      +
      } diff --git a/MP.SPEC/Components/ProdKit/Manager.razor.cs b/MP.SPEC/Components/ProdKit/Manager.razor.cs index 283763bf..c1bf0bc7 100644 --- a/MP.SPEC/Components/ProdKit/Manager.razor.cs +++ b/MP.SPEC/Components/ProdKit/Manager.razor.cs @@ -2,8 +2,6 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Authorization; using MP.Data.DbModels; using MP.SPEC.Data; -using System; -using System.Reflection.PortableExecutable; namespace MP.SPEC.Components.ProdKit { @@ -105,7 +103,7 @@ namespace MP.SPEC.Components.ProdKit } currPodlRec = selRec; isComposing = true; - await EC_IsComposing.InvokeAsync(true); + await EC_IsComposing.InvokeAsync(isComposing); // rileggo ReloadData(); @@ -166,7 +164,7 @@ namespace MP.SPEC.Components.ProdKit } ReloadData(); isComposing = false; - await EC_IsComposing.InvokeAsync(false); + await EC_IsComposing.InvokeAsync(isComposing); } private async Task SetHasOdl(bool setHasOdl) diff --git a/MP.SPEC/Components/Reparti/ListOperatori.razor.cs b/MP.SPEC/Components/Reparti/ListOperatori.razor.cs index eab82552..a6cedabb 100644 --- a/MP.SPEC/Components/Reparti/ListOperatori.razor.cs +++ b/MP.SPEC/Components/Reparti/ListOperatori.razor.cs @@ -62,8 +62,6 @@ namespace MP.SPEC.Components.Reparti private int currPage = 1; - private AnagOperatoriModel? EditRecord = null; - private bool isLoading = false; private List? ListAvail; diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index e9b08d76..ceaa572e 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2809 + 8.16.2605.2810 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Giacenze.razor.cs b/MP.SPEC/Pages/Giacenze.razor.cs index e79e5ff8..8f0907d9 100644 --- a/MP.SPEC/Pages/Giacenze.razor.cs +++ b/MP.SPEC/Pages/Giacenze.razor.cs @@ -33,7 +33,10 @@ namespace MP.SPEC.Pages var uri = NavManager.ToAbsoluteUri(NavManager.Uri); if (QueryHelpers.ParseQuery(uri.Query).TryGetValue("IdxOdl", out var _idxOdl)) { - IdxOdl = int.Parse(_idxOdl); + if (!string.IsNullOrEmpty(_idxOdl)) + { + IdxOdl = int.Parse(_idxOdl.ToString()); + } } odlExp = MDService.OdlByKey(IdxOdl); } diff --git a/MP.SPEC/Pages/Podl2Kit.razor.cs b/MP.SPEC/Pages/Podl2Kit.razor.cs index d2158b2d..8846fa07 100644 --- a/MP.SPEC/Pages/Podl2Kit.razor.cs +++ b/MP.SPEC/Pages/Podl2Kit.razor.cs @@ -246,9 +246,9 @@ namespace MP.SPEC.Pages private List ListMacchine = new List(); - private List? ListRecords; + private List? ListRecords = new(); - private List? ListStati; + private List? ListStati = new(); private int minChar = 2; diff --git a/MP.SPEC/Pages/ProdPlanner.razor b/MP.SPEC/Pages/ProdPlanner.razor index 2142f878..87f4c4a9 100644 --- a/MP.SPEC/Pages/ProdPlanner.razor +++ b/MP.SPEC/Pages/ProdPlanner.razor @@ -11,7 +11,8 @@
- +
inserire calendar planner
+ @* *@
diff --git a/MP.SPEC/Program.cs b/MP.SPEC/Program.cs index 4209457e..997d8354 100644 --- a/MP.SPEC/Program.cs +++ b/MP.SPEC/Program.cs @@ -226,8 +226,11 @@ if (!string.IsNullOrEmpty(BasePathOdlReturn)) // https://harrybellamy.com/posts/getting-mime-types-from-file-extensions-in-net-core/ foreach (var item in mimeDict) { - // Add new mappings - provider.Mappings[item.Key] = item.Value; + if (!string.IsNullOrEmpty(item.Value)) + { + // Add new mappings + provider.Mappings[item.Key] = item.Value; + } } } diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 64ea7d73..a6dbd98e 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

Versione: 8.16.2605.2809

+

Versione: 8.16.2605.2810


Note di rilascio:
  • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index c5710be8..7076e6d6 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2809 +8.16.2605.2810 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index bb10b8fa..9ea0c762 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2809 + 8.16.2605.2810 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Services/IOApiService.cs b/MP.SPEC/Services/IOApiService.cs index 05f70c25..d0372db3 100644 --- a/MP.SPEC/Services/IOApiService.cs +++ b/MP.SPEC/Services/IOApiService.cs @@ -1,7 +1,5 @@ -using Microsoft.Extensions.Configuration; -using MP.SPEC.Data; +using MP.SPEC.Data; using NLog; -using System.Text.Json; namespace MP.SPEC.Services { @@ -21,7 +19,7 @@ namespace MP.SPEC.Services _configuration = configuration; _clientFactory = clientFactory; // conf url x chiamate REST - MpIoBaseUrl = _configuration.GetValue("ServerConf:MpIoBaseUrl"); + MpIoBaseUrl = _configuration.GetValue("ServerConf:MpIoBaseUrl") ?? "MoonPro"; } #endregion Public Constructors diff --git a/MP.Stats/Components/ChartEnergy.razor b/MP.Stats/Components/ChartEnergy.razor index af03a9bb..9c5146f3 100644 --- a/MP.Stats/Components/ChartEnergy.razor +++ b/MP.Stats/Components/ChartEnergy.razor @@ -1,5 +1,4 @@ -@using ChartJs - +
    @if (RawData == null || RawData.Count == 0) { diff --git a/MP.Stats/Components/ChartJs/Chart.razor b/MP.Stats/Components/ChartJs/Chart.razor index 7be94585..abfd3f21 100644 --- a/MP.Stats/Components/ChartJs/Chart.razor +++ b/MP.Stats/Components/ChartJs/Chart.razor @@ -16,13 +16,13 @@ public ChartType Type { get; set; } [Parameter] - public string[]? Data { get; set; } + public string[] Data { get; set; } [Parameter] - public string[]? BackgroundColor { get; set; } + public string[] BackgroundColor { get; set; } [Parameter] - public string[]? Labels { get; set; } + public string[] Labels { get; set; } protected override async Task OnAfterRenderAsync(bool firstRender) { diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index dd106114..58026ccc 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,10 +4,14 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2605.2809 + 8.16.2605.2810 true en + + + $(NoWarn);1591 + diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index 3c0aaeec..f5b91a1b 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

    Versione: 8.16.2605.2809

    +

    Versione: 8.16.2605.2810


    Note di rilascio:
      diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index c5710be8..7076e6d6 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2809 +8.16.2605.2810 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index 0f083e08..a6ac78c4 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2809 + 8.16.2605.2810 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false From 25c38f5bcb8708d0f1660cde4eb4a1ef1c3e8fbc Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 10:42:39 +0200 Subject: [PATCH 036/102] Preprocess per cambio metodi Async --- MP.Data/Controllers/MpSpecController.cs | 47 +++++++++------------- MP.SPEC/Components/DossiersFilter.razor.cs | 2 +- MP.SPEC/Components/FLStatusList.razor.cs | 2 +- MP.SPEC/Components/ParamsFilter.razor.cs | 2 +- MP.SPEC/Data/MpDataService.cs | 16 ++++---- 5 files changed, 31 insertions(+), 38 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 0d2a1351..652a1412 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -1096,21 +1096,17 @@ namespace MP.Data.Controllers /// Elenco Gruppi /// /// - public List FluxLogPareto(string idxMacchina, DateTime dtFrom, DateTime dtTo) + public async Task> FluxLogParetoAsync(string idxMacchina, DateTime dtFrom, DateTime dtTo) { - List dbResult = new List(); - using (var dbCtx = new MoonPro_FluxContext(_configuration)) - { - dbResult = dbCtx - .DbSetFluxLog - .Where(x => (string.IsNullOrEmpty(idxMacchina) || x.IdxMacchina == idxMacchina) && (dtFrom <= x.dtEvento && x.dtEvento <= dtTo)) - .AsNoTracking() - .GroupBy(x => x.CodFlux) - .Select(g => new ParetoFluxLogDTO() { IdxMacchina = idxMacchina, CodFlux = g.Key, Qty = g.Count() }) - .OrderByDescending(x => x.Qty) - .ToList(); - } - return dbResult; + using var dbCtx = new MoonPro_FluxContext(_configuration); + return await dbCtx + .DbSetFluxLog + .Where(x => (string.IsNullOrEmpty(idxMacchina) || x.IdxMacchina == idxMacchina) && (dtFrom <= x.dtEvento && x.dtEvento <= dtTo)) + .AsNoTracking() + .GroupBy(x => x.CodFlux) + .Select(g => new ParetoFluxLogDTO() { IdxMacchina = idxMacchina, CodFlux = g.Key, Qty = g.Count() }) + .OrderByDescending(x => x.Qty) + .ToListAsync() ?? new(); } /// @@ -1803,20 +1799,17 @@ namespace MP.Data.Controllers /// /// /// - public async Task> MacchineWithFlux(DateTime dtStart, DateTime dtEnd) + public async Task> MacchineWithFluxAsync(DateTime dtStart, DateTime dtEnd) { - List dbResult = new List(); - using (var dbCtx = new MoonPro_FluxContext(_configuration)) - { - dbResult = await dbCtx - .DbSetFluxLog - .AsNoTracking() - .Where(x => x.dtEvento >= dtStart && x.dtEvento <= dtEnd) - .Select(i => i.IdxMacchina) - .Distinct() - .ToListAsync(); - } - return dbResult; + using var dbCtx = new MoonPro_FluxContext(_configuration); + return await dbCtx + .DbSetFluxLog + .AsNoTracking() + .Where(x => x.dtEvento >= dtStart && x.dtEvento <= dtEnd) + .Select(i => i.IdxMacchina) + .Distinct() + .ToListAsync() ?? new(); + } /// diff --git a/MP.SPEC/Components/DossiersFilter.razor.cs b/MP.SPEC/Components/DossiersFilter.razor.cs index 723965e0..3f4f0d11 100644 --- a/MP.SPEC/Components/DossiersFilter.razor.cs +++ b/MP.SPEC/Components/DossiersFilter.razor.cs @@ -132,7 +132,7 @@ namespace MP.SPEC.Components SelFilterDossier.MaxRecord = 1000; DateTime dtEnd = SelFilterDossier.DtEnd; DateTime dtStart = dtEnd.Subtract(SelFilterDossier.DtStart).TotalDays < 15 ? SelFilterDossier.DtStart : dtEnd.AddDays(-14); - ListMacchine = await MDService.MacchineWithFlux(dtStart, dtEnd); + ListMacchine = await MDService.MacchineWithFluxAsync(dtStart, dtEnd); ListArticoli = await MDService.ArticleWithDossierAsync(); await FilterChanged.InvokeAsync(SelFilterDossier); } diff --git a/MP.SPEC/Components/FLStatusList.razor.cs b/MP.SPEC/Components/FLStatusList.razor.cs index c1493d3e..7f453aef 100644 --- a/MP.SPEC/Components/FLStatusList.razor.cs +++ b/MP.SPEC/Components/FLStatusList.razor.cs @@ -116,7 +116,7 @@ namespace MP.SPEC.Components { idxMaccLast = IdxMaccSel; lastPeriodo = CurrPeriodo; - ListComplete = await MDataServ.FluxLogPareto(IdxMaccSel, CurrPeriodo.Inizio, CurrPeriodo.Fine); + ListComplete = await MDataServ.FluxLogParetoAsync(IdxMaccSel, CurrPeriodo.Inizio, CurrPeriodo.Fine); TotalCount = ListComplete.Count; TotalRecords = ListComplete.Sum(x => x.Qty); FluxList = ListComplete.Select(x => x.CodFlux).ToList(); diff --git a/MP.SPEC/Components/ParamsFilter.razor.cs b/MP.SPEC/Components/ParamsFilter.razor.cs index 6bb8c6e4..f2507145 100644 --- a/MP.SPEC/Components/ParamsFilter.razor.cs +++ b/MP.SPEC/Components/ParamsFilter.razor.cs @@ -181,7 +181,7 @@ namespace MP.SPEC.Components setDtSnap(); DateTime dtStart = SelFilter.dtMin != null ? (DateTime)SelFilter.dtMin : DateTime.Now.AddMonths(-1); DateTime dtEnd = SelFilter.dtMax != null ? (DateTime)SelFilter.dtMax : DateTime.Today.AddDays(1); - ListMacchine = await MDService.MacchineWithFlux(dtStart, dtEnd); + ListMacchine = await MDService.MacchineWithFluxAsync(dtStart, dtEnd); ListFlux = await MDService.ParametriGetFilt(selMacchina); var configData = await MDService.ConfigGetAllAsync(); diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 9fb69510..1ebed9ac 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1105,9 +1105,9 @@ namespace MP.SPEC.Data /// Elenco Gruppi /// /// - public async Task> FluxLogPareto(string idxMacchina, DateTime dtFrom, DateTime dtTo) + public async Task> FluxLogParetoAsync(string idxMacchina, DateTime dtFrom, DateTime dtTo) { - using var activity = ActivitySource.StartActivity("FluxLogPareto"); + using var activity = ActivitySource.StartActivity("FluxLogParetoAsync"); string source = "DB"; List? result = new List(); // cerco in redis... @@ -1120,7 +1120,7 @@ namespace MP.SPEC.Data } else { - result = await Task.FromResult(dbController.FluxLogPareto(idxMacchina, dtFrom, dtTo)); + result = await dbController.FluxLogParetoAsync(idxMacchina, dtFrom, dtTo); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(redKey, rawData, getRandTOut(redisLongTimeCache)); @@ -1132,7 +1132,7 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.SetTag("result.count", result.Count); activity?.Stop(); - LogTrace($"FluxLogPareto | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"FluxLogParetoAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; } @@ -1545,9 +1545,9 @@ namespace MP.SPEC.Data /// /// /// - public async Task> MacchineWithFlux(DateTime dtStart, DateTime dtEnd) + public async Task> MacchineWithFluxAsync(DateTime dtStart, DateTime dtEnd) { - using var activity = ActivitySource.StartActivity("MacchineWithFlux"); + using var activity = ActivitySource.StartActivity("MacchineWithFluxAsync"); List? result = new List(); string source = "DB"; string currKey = $"{Utils.redisMacByFlux}:{dtStart:yyyyMMddHHmm}:{dtEnd:yyyyMMddHHmm}"; @@ -1560,7 +1560,7 @@ namespace MP.SPEC.Data } else { - result = await dbController.MacchineWithFlux(dtStart, dtEnd); + result = await dbController.MacchineWithFluxAsync(dtStart, dtEnd); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); @@ -1572,7 +1572,7 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.SetTag("result.count", result.Count); activity?.Stop(); - LogTrace($"MacchineWithFlux | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"MacchineWithFluxAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; } From b946e40608be4813098fc548a8b270ada5f0e2a3 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 11:09:55 +0200 Subject: [PATCH 037/102] Preparazione metodi x spostamento cache Async --- MP.Data/Controllers/MpSpecController.cs | 49 ++++----- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.SPEC/Components/ProdKit/Manager.razor.cs | 21 ++-- MP.SPEC/Components/ScratchPodlKit.razor | 2 +- MP.SPEC/Components/ScratchPodlKit.razor.cs | 54 +++++----- MP.SPEC/Data/MpDataService.cs | 104 +++++++------------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Podl2Kit.razor.cs | 4 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 14 files changed, 101 insertions(+), 149 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 652a1412..4186b6d5 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -1273,18 +1273,14 @@ namespace MP.Data.Controllers /// /// /// - public List IstKitFilt(string keyKit, string keyExtOrd) + public async Task> IstKitFiltAsync(string keyKit, string keyExtOrd) { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx + using var dbCtx = new MoonProContext(options); + return await dbCtx .DbSetInstKit .Where(x => (string.IsNullOrEmpty(keyKit) && string.IsNullOrEmpty(keyExtOrd)) || (x.KeyKit.Contains(keyKit) && !string.IsNullOrEmpty(keyKit)) || (x.KeyExtOrd.Contains(keyExtOrd) && !string.IsNullOrEmpty(keyExtOrd))) .AsNoTracking() - .ToList(); - } - return dbResult; + .ToListAsync() ?? new(); } /// @@ -2590,22 +2586,19 @@ namespace MP.Data.Controllers /// /// /// - public List TksScore(string KeyFilt, int MaxResult) + public async Task> TksScoreAsync(string KeyFilt, int MaxResult) { List dbResult = new List(); if (!string.IsNullOrEmpty(KeyFilt)) { - using (var dbCtx = new MoonProContext(options)) - { - var pKeyFilt = new SqlParameter("@KeyFilt", KeyFilt); - var pMaxRes = new SqlParameter("@maxResult", MaxResult); - - dbResult = dbCtx - .DbSetTksScore - .FromSqlRaw("EXEC stp_TKS_Search @KeyFilt, @maxResult", pKeyFilt, pMaxRes) - .AsNoTracking() - .ToList(); - } + using var dbCtx = new MoonProContext(options); + var pKeyFilt = new SqlParameter("@KeyFilt", KeyFilt); + var pMaxRes = new SqlParameter("@maxResult", MaxResult); + dbResult = await dbCtx + .DbSetTksScore + .FromSqlRaw("EXEC stp_TKS_Search @KeyFilt, @maxResult", pKeyFilt, pMaxRes) + .AsNoTracking() + .ToListAsync(); } return dbResult; } @@ -2712,20 +2705,18 @@ namespace MP.Data.Controllers /// /// /// - public List WipKitFilt(string KeyFilt) + public async Task> WipKitFiltAsync(string KeyFilt) { List dbResult = new List(); // solo se filtro valido... if (!string.IsNullOrEmpty(KeyFilt)) { - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbSetWipKit - .Where(x => x.KeyFilt.Contains(KeyFilt)) - .AsNoTracking() - .ToList(); - } + using var dbCtx = new MoonProContext(options); + dbResult = await dbCtx + .DbSetWipKit + .Where(x => x.KeyFilt.Contains(KeyFilt)) + .AsNoTracking() + .ToListAsync(); } return dbResult; } diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 31066432..2792aac7 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2605.2810 + 8.16.2605.2811 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 1b09f5c9..0b3d6084 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

      Versione: 8.16.2605.2810

      +

      Versione: 8.16.2605.2811


      Note di rilascio:
        diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 7076e6d6..378864b8 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2810 +8.16.2605.2811 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index 27aee25f..0ef06353 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2810 + 8.16.2605.2811 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Components/ProdKit/Manager.razor.cs b/MP.SPEC/Components/ProdKit/Manager.razor.cs index c1bf0bc7..73b7368f 100644 --- a/MP.SPEC/Components/ProdKit/Manager.razor.cs +++ b/MP.SPEC/Components/ProdKit/Manager.razor.cs @@ -68,10 +68,9 @@ namespace MP.SPEC.Components.ProdKit DateTime oggi = DateTime.Today; } - protected override void OnParametersSet() + protected override async Task OnParametersSetAsync() { - //base.OnParametersSet(); - ReloadData(); + await ReloadDataAsync(); } /// @@ -106,7 +105,7 @@ namespace MP.SPEC.Components.ProdKit await EC_IsComposing.InvokeAsync(isComposing); // rileggo - ReloadData(); + await ReloadDataAsync(); } } @@ -162,7 +161,7 @@ namespace MP.SPEC.Components.ProdKit { calcKitCode(); } - ReloadData(); + await ReloadDataAsync(); isComposing = false; await EC_IsComposing.InvokeAsync(isComposing); } @@ -171,7 +170,7 @@ namespace MP.SPEC.Components.ProdKit { ActFilt.HasOdl = setHasOdl; await EC_FiltUpdated.InvokeAsync(ActFilt); - ReloadData(); + await ReloadDataAsync(); } private async Task ForceReset() @@ -184,13 +183,13 @@ namespace MP.SPEC.Components.ProdKit await EC_FiltUpdated.InvokeAsync(ActFilt); } - private void ReloadData() + private async Task ReloadDataAsync() { listPOdlCheck = new List(); - listPOdlAct = MDService.POdlListGetFilt(ActFilt.HasOdl, ActFilt.CodFase, ActFilt.IdxMacchina, ActFilt.CodReparto, ActFilt.DtStart, ActFilt.DtEnd); - listWSM = MDService.WipKitFilt(keyFilt); - listTSM = MDService.TksScore(keyFilt, 1000, true); - listIKP = MDService.IstKitFilt("", ""); + listPOdlAct = await MDService.POdlListGetFiltAsync(ActFilt.HasOdl, ActFilt.CodFase, ActFilt.IdxMacchina, ActFilt.CodReparto, ActFilt.DtStart, ActFilt.DtEnd); + listWSM = await MDService.WipKitFiltAsync(keyFilt); + listTSM = await MDService.TksScoreAsync(keyFilt, 1000, true); + listIKP = await MDService.IstKitFiltAsync("", ""); // verifico se ho score 100%... var recMaxScore = listTSM .Where(x => x.TotalScore == 1) diff --git a/MP.SPEC/Components/ScratchPodlKit.razor b/MP.SPEC/Components/ScratchPodlKit.razor index 97b46602..49004db1 100644 --- a/MP.SPEC/Components/ScratchPodlKit.razor +++ b/MP.SPEC/Components/ScratchPodlKit.razor @@ -12,7 +12,7 @@
        - +
    diff --git a/MP.SPEC/Components/ScratchPodlKit.razor.cs b/MP.SPEC/Components/ScratchPodlKit.razor.cs index e51d9229..a9c7c38a 100644 --- a/MP.SPEC/Components/ScratchPodlKit.razor.cs +++ b/MP.SPEC/Components/ScratchPodlKit.razor.cs @@ -46,13 +46,17 @@ namespace MP.SPEC.Components if (sCodComm != value) { sCodComm = value; - currPage = 1; - ListRecords = null; - ReloadData(); } } } + private async Task ResetDataAsync() + { + currPage = 1; + ListRecords = null; + await ReloadDataAsync(); + } + protected string sParentCss { get => string.IsNullOrEmpty(sCodComm) ? "btn-secondary" : "btn-primary"; @@ -92,8 +96,7 @@ namespace MP.SPEC.Components protected async Task DoCancel() { EditRecord = null; - ReloadData(); - await Task.Delay(1); + await ResetDataAsync(); } /// @@ -106,11 +109,9 @@ namespace MP.SPEC.Components if (!await JSRuntime.InvokeAsync("confirm", "Eliminazione riga Istanza KIT: sei sicuro di voler procedere?")) return; - await Task.Delay(1); var done = await MDService.IstKitDelete(selRec); EditRecord = null; - ReloadData(); - await Task.Delay(1); + await ResetDataAsync(); } protected async Task DoUpdate(IstanzeKitModel selRec) @@ -118,11 +119,9 @@ namespace MP.SPEC.Components if (!await JSRuntime.InvokeAsync("confirm", "Confermi di voler salvare le modifiche?")) return; - await Task.Delay(1); var done = await MDService.IstKitUpsert(selRec); EditRecord = null; - ReloadData(); - await Task.Delay(1); + await ResetDataAsync(); } protected override void OnInitialized() @@ -147,20 +146,16 @@ namespace MP.SPEC.Components } } - protected override void OnParametersSet() + protected override async Task OnParametersSetAsync() { - ReloadData(); + await ReloadDataAsync(); } - protected void ResetData() - { - EditRecord = null; - } - protected void ResetParent() + protected async Task ResetParent() { SearchComm = ""; - ReloadData(); + await ResetDataAsync(); } protected void ResetSel() @@ -184,10 +179,10 @@ namespace MP.SPEC.Components numRecord = newNum; } - protected void UpdateData() + protected async Task UpdateData() { EditRecord = null; - ReloadData(); + await ResetDataAsync(); } #endregion Protected Methods @@ -242,7 +237,7 @@ namespace MP.SPEC.Components if (_currPage != value) { _currPage = value; - ReloadData(); + ReloadDataAsync(); } } } @@ -257,7 +252,7 @@ namespace MP.SPEC.Components if (_numRecord != value) { _numRecord = value; - ReloadData(); + ReloadDataAsync(); } } } @@ -270,17 +265,22 @@ namespace MP.SPEC.Components #region Private Methods - private void ReloadData() + private async Task ReloadDataAsync() { isLoading = true; - SearchRecords = MDService.IstKitFilt("", ""); + SearchRecords = await MDService.IstKitFiltAsync("", ""); totalCount = SearchRecords.Count; // conto i kit = distinct... kitCount = SearchRecords.GroupBy(x => x.CodArtParent).Count(); - ListRecords = SearchRecords + UpdateTable(); + } + + private void UpdateTable() + { + ListRecords = SearchRecords? .Skip(numRecord * (currPage - 1)) .Take(numRecord) - .ToList(); + .ToList() ?? new(); isLoading = false; } diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 1ebed9ac..0bd00253 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1102,38 +1102,19 @@ namespace MP.SPEC.Data } /// - /// Elenco Gruppi + /// Elenco FluxLog in modalità Pareto /// /// public async Task> FluxLogParetoAsync(string idxMacchina, DateTime dtFrom, DateTime dtTo) { - using var activity = ActivitySource.StartActivity("FluxLogParetoAsync"); - string source = "DB"; - List? result = new List(); - // cerco in redis... string redKey = $"{Utils.redisParetoFLKey}:{idxMacchina}:{dtFrom:yyyyMMdd}:{dtTo:yyyyMMdd}"; - RedisValue rawData = await redisDb.StringGetAsync(redKey); - if (!string.IsNullOrEmpty($"{rawData}")) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.FluxLogParetoAsync(idxMacchina, dtFrom, dtTo); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(redKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"FluxLogParetoAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + return await GetOrFetchAsync( + operationName: "FluxLogParetoAsync", + cacheKey: redKey, + expiration: TimeSpan.FromMinutes(redisLongTimeCache), + fetchFunc: async () => await dbController.FluxLogParetoAsync(idxMacchina, dtFrom, dtTo) ?? new List(), + tagList: [Utils.redisParetoFLKey] + ); } /// @@ -1270,14 +1251,14 @@ namespace MP.SPEC.Data /// /// /// - public List IstKitFilt(string keyKit, string keyExtOrd) + public async Task> IstKitFiltAsync(string keyKit, string keyExtOrd) { - using var activity = ActivitySource.StartActivity("IstKitFilt"); + using var activity = ActivitySource.StartActivity("IstKitFiltAsync"); string source = "DB"; List? result = new List(); // cerco in redis... string currKey = $"{Utils.redisKitInst}:{keyKit}:{keyExtOrd}"; - RedisValue rawData = redisDb.StringGet(currKey); + RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); @@ -1285,10 +1266,10 @@ namespace MP.SPEC.Data } else { - result = dbController.IstKitFilt(keyKit, keyExtOrd); + result = await dbController.IstKitFiltAsync(keyKit, keyExtOrd); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache)); + await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache)); } if (result == null) { @@ -1297,7 +1278,7 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.SetTag("result.count", result.Count); activity?.Stop(); - LogTrace($"IstKitFilt | {source} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"IstKitFiltAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); return result; } @@ -1547,33 +1528,14 @@ namespace MP.SPEC.Data /// public async Task> MacchineWithFluxAsync(DateTime dtStart, DateTime dtEnd) { - using var activity = ActivitySource.StartActivity("MacchineWithFluxAsync"); - List? result = new List(); - string source = "DB"; string currKey = $"{Utils.redisMacByFlux}:{dtStart:yyyyMMddHHmm}:{dtEnd:yyyyMMddHHmm}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.MacchineWithFluxAsync(dtStart, dtEnd); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"MacchineWithFluxAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + return await GetOrFetchAsync( + operationName: "MacchineWithFluxAsync", + cacheKey: currKey, + expiration: TimeSpan.FromMinutes(redisLongTimeCache), + fetchFunc: async () => await dbController.MacchineWithFluxAsync(dtStart, dtEnd) ?? new List(), + tagList: [Utils.redisMacByFlux] + ); } public async Task> MachineWithOdlAsync() @@ -2526,14 +2488,14 @@ namespace MP.SPEC.Data /// /// /// - public List TksScore(string KeyFilt, int MaxResult, bool ForceDb) + public async Task> TksScoreAsync(string KeyFilt, int MaxResult, bool ForceDb) { - using var activity = ActivitySource.StartActivity("TksScore"); + using var activity = ActivitySource.StartActivity("TksScoreAsync"); string source = "DB"; List? result = new List(); // cerco in redis... string currKey = $"{Utils.redisKitScore}:{KeyFilt}:{MaxResult}"; - RedisValue rawData = redisDb.StringGet(currKey); + RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue && !ForceDb) { result = JsonConvert.DeserializeObject>($"{rawData}"); @@ -2541,10 +2503,10 @@ namespace MP.SPEC.Data } else { - result = dbController.TksScore(KeyFilt, MaxResult); + result = await dbController.TksScoreAsync(KeyFilt, MaxResult); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache)); + await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache)); } if (result == null) { @@ -2553,7 +2515,7 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.SetTag("result.count", result.Count); activity?.Stop(); - LogTrace($"TksScore | {source} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"TksScoreAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); return result; } @@ -2657,14 +2619,14 @@ namespace MP.SPEC.Data /// /// /// - public List WipKitFilt(string KeyFilt) + public async Task> WipKitFiltAsync(string KeyFilt) { - using var activity = ActivitySource.StartActivity("WipKitFilt"); + using var activity = ActivitySource.StartActivity("WipKitFiltAsync"); string source = "DB"; List? result = new List(); // cerco in redis... string currKey = $"{Utils.redisKitWip}:{KeyFilt}"; - RedisValue rawData = redisDb.StringGet(currKey); + RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); @@ -2672,10 +2634,10 @@ namespace MP.SPEC.Data } else { - result = dbController.WipKitFilt(KeyFilt); + result = await dbController.WipKitFiltAsync(KeyFilt); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache)); + await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache)); } if (result == null) { @@ -2684,7 +2646,7 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.SetTag("result.count", result.Count); activity?.Stop(); - LogTrace($"WipKitFilt | {source} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"WipKitFiltAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); return result; } diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index ceaa572e..8f6e41c9 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2810 + 8.16.2605.2811 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Podl2Kit.razor.cs b/MP.SPEC/Pages/Podl2Kit.razor.cs index 8846fa07..f73d2fe0 100644 --- a/MP.SPEC/Pages/Podl2Kit.razor.cs +++ b/MP.SPEC/Pages/Podl2Kit.razor.cs @@ -361,8 +361,8 @@ namespace MP.SPEC.Pages { ListGruppiFase = allGruppiData.Where(x => x.SelEnabled).ToList(); } - ListMacchine = MDService.MacchineGetFilt(repartoSel); - SearchRecords = MDService.IstKitFilt("", ""); + ListMacchine = await MDService.MacchineGetFiltAsync(repartoSel); + SearchRecords = await MDService.IstKitFiltAsync("", ""); totalCount = SearchRecords.Count; // conto i kit = distinct... kitCount = SearchRecords.GroupBy(x => x.CodArtParent).Count(); diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index a6dbd98e..9b69bf46 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

    Versione: 8.16.2605.2810

    +

    Versione: 8.16.2605.2811


    Note di rilascio:
    • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 7076e6d6..378864b8 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2810 +8.16.2605.2811 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 9ea0c762..d3e3fe22 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2810 + 8.16.2605.2811 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From 5165a2cabbc2936a4ee4cad29e39289a25969cff Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 11:12:51 +0200 Subject: [PATCH 038/102] Fix compilazione IOC --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/Data/MpDataService.cs | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- 29 files changed, 29 insertions(+), 29 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index b1aaa6d2..c757dd3b 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2605.2810 + 8.16.2605.2811 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index a6dbd98e..9b69bf46 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

      Versione: 8.16.2605.2810

      +

      Versione: 8.16.2605.2811


      Note di rilascio:
      • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 7076e6d6..378864b8 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2810 +8.16.2605.2811 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index b832aa5a..4cb4eb56 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2810 + 8.16.2605.2811 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index 44ab5ad6..358dafad 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2605.2810 + 8.16.2605.2811 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index 109e6a53..75b640ea 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

        Versione: 8.16.2605.2810

        +

        Versione: 8.16.2605.2811


        Note di rilascio:
        • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index 7076e6d6..378864b8 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2810 +8.16.2605.2811 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index a1c72ade..a82d5b1c 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2810 + 8.16.2605.2811 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs index 945616a5..5d90ab3d 100644 --- a/MP.IOC/Data/MpDataService.cs +++ b/MP.IOC/Data/MpDataService.cs @@ -2020,7 +2020,7 @@ namespace MP.IOC.Data } else { - result = await SpecDbController.MacchineWithFlux(dtStart, dtEnd); + result = await SpecDbController.MacchineWithFluxAsync(dtStart, dtEnd); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 0ff59adf..b1390e67 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.2810 + 8.16.2605.2811 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 748a7459..4f14e552 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

          Versione: 8.16.2605.2810

          +

          Versione: 8.16.2605.2811


          Note di rilascio:
          • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 7076e6d6..378864b8 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2810 +8.16.2605.2811 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 56f086fc..64384a3d 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2810 + 8.16.2605.2811 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index 861c941f..d8b8627b 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2605.2810 + 8.16.2605.2811 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index a6dbd98e..9b69bf46 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

            Versione: 8.16.2605.2810

            +

            Versione: 8.16.2605.2811


            Note di rilascio:
            • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 7076e6d6..378864b8 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2810 +8.16.2605.2811 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index c612fe2c..b54a4a6a 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2810 + 8.16.2605.2811 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index e426e70d..486a2b09 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2605.2810 + 8.16.2605.2811 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index e6a0d1b2..165f4249 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

              Versione: 8.16.2605.2810

              +

              Versione: 8.16.2605.2811


              Note di rilascio:
                diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 7076e6d6..378864b8 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2810 +8.16.2605.2811 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index f1739aad..28774385 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2810 + 8.16.2605.2811 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index 714b489b..1be669a4 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2605.2810 + 8.16.2605.2811 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index 62b22040..b461f521 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                Versione: 8.16.2605.2810

                +

                Versione: 8.16.2605.2811


                Note di rilascio:
                • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index 7076e6d6..378864b8 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2810 +8.16.2605.2811 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index 5b4df2e1..1d5465b5 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2810 + 8.16.2605.2811 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 58026ccc..31531020 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2605.2810 + 8.16.2605.2811 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index f5b91a1b..f1c8b025 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                  Versione: 8.16.2605.2810

                  +

                  Versione: 8.16.2605.2811


                  Note di rilascio:
                    diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 7076e6d6..378864b8 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2810 +8.16.2605.2811 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index a6ac78c4..21f52685 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2810 + 8.16.2605.2811 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false From 2854f2f6cedf301a1117dae8fb7c6d84e086fbdc Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 11:18:17 +0200 Subject: [PATCH 039/102] Fix warnings --- MP.SPEC/Components/ScratchPodlKit.razor.cs | 4 ++-- MP.SPEC/Extensions/NavigationManagerExtension.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/MP.SPEC/Components/ScratchPodlKit.razor.cs b/MP.SPEC/Components/ScratchPodlKit.razor.cs index a9c7c38a..aadf1a85 100644 --- a/MP.SPEC/Components/ScratchPodlKit.razor.cs +++ b/MP.SPEC/Components/ScratchPodlKit.razor.cs @@ -237,7 +237,7 @@ namespace MP.SPEC.Components if (_currPage != value) { _currPage = value; - ReloadDataAsync(); + UpdateTable(); } } } @@ -252,7 +252,7 @@ namespace MP.SPEC.Components if (_numRecord != value) { _numRecord = value; - ReloadDataAsync(); + UpdateTable(); } } } diff --git a/MP.SPEC/Extensions/NavigationManagerExtension.cs b/MP.SPEC/Extensions/NavigationManagerExtension.cs index 9383180a..29df1a58 100644 --- a/MP.SPEC/Extensions/NavigationManagerExtension.cs +++ b/MP.SPEC/Extensions/NavigationManagerExtension.cs @@ -16,7 +16,7 @@ namespace MP.SPEC.Extensions /// /// /// - public static T ExtractQueryStringByKey(this NavigationManager navManager, string key) + public static T? ExtractQueryStringByKey(this NavigationManager navManager, string key) { var uri = navManager.ToAbsoluteUri(navManager.Uri); QueryHelpers.ParseQuery(uri.Query) From d731187d621e5e41152ed1c4f78d3e88ab3112a9 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 11:22:42 +0200 Subject: [PATCH 040/102] Aggiunta secondo helper estrazione dati navManager --- .../Extensions/NavigationManagerExtension.cs | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/MP.SPEC/Extensions/NavigationManagerExtension.cs b/MP.SPEC/Extensions/NavigationManagerExtension.cs index 29df1a58..5e3e5780 100644 --- a/MP.SPEC/Extensions/NavigationManagerExtension.cs +++ b/MP.SPEC/Extensions/NavigationManagerExtension.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.WebUtilities; +using System.ComponentModel; namespace MP.SPEC.Extensions { @@ -8,7 +9,7 @@ namespace MP.SPEC.Extensions #region Public Methods /// - /// Estensione metodo NavigationManager x recupero querystring + /// Estensione metodo NavigationManager x recupero querystring int/string /// /// https://code-maze.com/query-strings-blazor-webassembly/ /// @@ -34,6 +35,46 @@ namespace MP.SPEC.Extensions return default; } + /// + /// Estensione metodo NavigationManager x recupero querystring di ogni tipo + /// + /// es: navManager.ExtractQueryStringByKey("isAdmin") + /// + /// + /// + /// + /// + public static T? ExtractQueryStringByKeyGeneric(this NavigationManager navManager, string key) + { + var uri = navManager.ToAbsoluteUri(navManager.Uri); + + // Estrai il valore associato alla chiave + if (!QueryHelpers.ParseQuery(uri.Query).TryGetValue(key, out var queryValue)) + { + return default; + } + + var stringValue = queryValue.ToString(); + + try + { + // Ottieni il convertitore dinamico per il tipo T + var converter = TypeDescriptor.GetConverter(typeof(T)); + if (converter != null && converter.CanConvertFrom(typeof(string))) + { + return (T?)converter.ConvertFromString(stringValue); + } + + // Fallback nel caso il convertitore standard non basti + return (T?)Convert.ChangeType(stringValue, typeof(T)); + } + catch + { + // Se la conversione fallisce (es. il testo non è un numero valido), ritorna il default + return default; + } + } + /// /// Recupero base page /// From 92703f6bbdc2a61c0d11401fa9f6a4eb2fb4273f Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 11:22:59 +0200 Subject: [PATCH 041/102] Update caching --- MP.SPEC/Data/MpDataService.cs | 66 ++++++++--------------------------- 1 file changed, 14 insertions(+), 52 deletions(-) diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 0bd00253..4e2a0c2a 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1253,33 +1253,14 @@ namespace MP.SPEC.Data /// public async Task> IstKitFiltAsync(string keyKit, string keyExtOrd) { - using var activity = ActivitySource.StartActivity("IstKitFiltAsync"); - string source = "DB"; - List? result = new List(); - // cerco in redis... string currKey = $"{Utils.redisKitInst}:{keyKit}:{keyExtOrd}"; - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.IstKitFiltAsync(keyKit, keyExtOrd); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"IstKitFiltAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return result; + return await GetOrFetchAsync( + operationName: "IstKitFiltAsync", + cacheKey: currKey, + expiration: TimeSpan.FromMinutes(redisLongTimeCache), + fetchFunc: async () => await dbController.IstKitFiltAsync(keyKit, keyExtOrd) ?? new List(), + tagList: [Utils.redisKitInst] + ); } /// @@ -2116,33 +2097,14 @@ namespace MP.SPEC.Data /// public async Task> POdlListGetFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) { - using var activity = ActivitySource.StartActivity("POdlListGetFiltAsync"); - List? result = new List(); - string source = "DB"; string currKey = $"{Utils.redisPOdlList}:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.ListPODLFiltAsync(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"POdlListGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + return await GetOrFetchAsync( + operationName: "POdlListGetFiltAsync", + cacheKey: currKey, + expiration: TimeSpan.FromSeconds(redisShortTimeCache), + fetchFunc: async () => await dbController.ListPODLFiltAsync(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate) ?? new List(), + tagList: [Utils.redisPOdlList] + ); } /// From 9df2a7853f1635a922a54e14c6106f3f7ba35234 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 12:11:53 +0200 Subject: [PATCH 042/102] Preparazione metodi async x pagina ODL --- MP.Data/Controllers/MpSpecController.cs | 25 ++--- MP.SPEC/Components/ListODL.razor.cs | 45 ++++++--- MP.SPEC/Data/MpDataService.cs | 123 +++++++++--------------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 7 files changed, 87 insertions(+), 114 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 4186b6d5..1b5bab5b 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -2198,25 +2198,14 @@ namespace MP.Data.Controllers /// /// /// - public PODLModel PODL_getByOdl(int idxODL) + public async Task PODL_getByOdlAsync(int idxODL) { - PODLModel dbResult = new PODLModel(); - using (var dbCtx = new MoonProContext(options)) - { - try - { - dbResult = dbCtx - .DbSetPODL - .AsNoTracking() - .Where(x => x.IdxOdl == idxODL) - .FirstOrDefault(); - } - catch (Exception exc) - { - Log.Error($"Eccezione durante PODL_getByOdl{Environment.NewLine}{exc}"); - } - } - return dbResult; + using var dbCtx = new MoonProContext(options); + return await dbCtx + .DbSetPODL + .AsNoTracking() + .Where(x => x.IdxOdl == idxODL) + .FirstOrDefaultAsync() ?? new(); } /// diff --git a/MP.SPEC/Components/ListODL.razor.cs b/MP.SPEC/Components/ListODL.razor.cs index 47129602..7347ec53 100644 --- a/MP.SPEC/Components/ListODL.razor.cs +++ b/MP.SPEC/Components/ListODL.razor.cs @@ -123,7 +123,7 @@ namespace MP.SPEC.Components // ricarica... await selRecord(null); } - await ReloadData(); + await ReloadDataAsync(); } /// @@ -151,18 +151,12 @@ namespace MP.SPEC.Components // ricarica... await selRecord(null); } - await ReloadData(); + await ReloadDataAsync(); } protected int getPodl(int idxOdl) { - int answ = 0; - var pOdlData = MDService.POdlGetByOdl(idxOdl); - if (pOdlData != null) - { - answ = pOdlData.IdxPromessa; - } - return answ; + return _podlLocalCache.TryGetValue(idxOdl, out var val) ? val : 0; } /// @@ -227,13 +221,13 @@ namespace MP.SPEC.Components protected override async Task OnParametersSetAsync() { - await ReloadData(); + await ReloadDataAsync(); } protected async Task resetSel() { await selRecord(null); - await ReloadData(); + await ReloadDataAsync(); } protected async Task selBrowseRecord(ODLExpModel? currRec) @@ -276,7 +270,7 @@ namespace MP.SPEC.Components protected async Task UpdateData() { await selRecord(null); - await ReloadData(); + await ReloadDataAsync(); } #endregion Protected Methods @@ -360,14 +354,39 @@ namespace MP.SPEC.Components #region Private Methods - private async Task ReloadData() + private async Task ReloadDataAsync() { isLoading = true; SearchRecords = await MDService.OdlListGetFilt(currFilter.IsActive, currFilter.SearchVal, currFilter.CodFase, currFilter.CodReparto, currFilter.IdxMacchina, currFilter.DtStart, currFilter.DtEnd); + await ReloadPOdlData(); totalCount = SearchRecords.Count; ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); isLoading = false; } + private Dictionary _podlLocalCache = new(); + private async Task ReloadPOdlData() + { + _podlLocalCache.Clear(); + if (SearchRecords != null) + { + // 1. Popolo la cache locale in parallelo sfruttando la velocità di FusionCache + var tasks = SearchRecords.Select(async odl => + { + int podl = 0; + var pOdlData = await MDService.POdlGetByOdlAsync(odl.IdxOdl); // Tua nuova versione Async + if (pOdlData != null) + { + podl = pOdlData.IdxPromessa; + } + return (odl.IdxOdl, podl); + }); + + var infoSalvate = await Task.WhenAll(tasks); + + // 2. Trasformazione dei risultati in un dizionario per l'accesso immediato (O(1)) nell'HTML + _podlLocalCache = infoSalvate.ToDictionary(x => x.IdxOdl, x => x.podl); + } + } private async Task reloadStatsData(ODLExpModel? currRec) { diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 4e2a0c2a..d12b3fed 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -213,7 +213,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "AnagStatiCommAsync", cacheKey: Utils.redisStatoCom, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.AnagStatiCommAsync() ?? new List(), tagList: [Utils.redisStatoCom] @@ -229,7 +229,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "AnagTipoArtLvAsync", cacheKey: Utils.redisTipoArt, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.AnagTipoArtLvAsync() ?? new List(), tagList: [Utils.redisTipoArt] ); @@ -244,7 +244,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ArticleWithDossierAsync", cacheKey: Utils.redisArtByDossier, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await Task.FromResult(dbController.ArticleWithDossier()) ?? new List(), tagList: [Utils.redisArtByDossier] ); @@ -302,7 +302,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ArticoliGetSearchAsync", cacheKey: redisKey, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal) ?? new List(), tagList: [Utils.redisArtList, $"{Utils.redisArtList}:Search"] @@ -422,7 +422,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ConfigGetAllAsync", cacheKey: Utils.redisConfKey, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.ConfigGetAllAsync() ?? new List(), tagList: [Utils.redisConfKey] ); @@ -676,7 +676,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ElencoLinkAsync", cacheKey: Utils.redisLinkMenu, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.ElencoLinkAsync() ?? new List(), tagList: [Utils.redisLinkMenu] ); @@ -1111,7 +1111,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "FluxLogParetoAsync", cacheKey: redKey, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.FluxLogParetoAsync(idxMacchina, dtFrom, dtTo) ?? new List(), tagList: [Utils.redisParetoFLKey] ); @@ -1257,7 +1257,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "IstKitFiltAsync", cacheKey: currKey, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.IstKitFiltAsync(keyKit, keyExtOrd) ?? new List(), tagList: [Utils.redisKitInst] ); @@ -1513,7 +1513,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "MacchineWithFluxAsync", cacheKey: currKey, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.MacchineWithFluxAsync(dtStart, dtEnd) ?? new List(), tagList: [Utils.redisMacByFlux] ); @@ -1946,16 +1946,16 @@ namespace MP.SPEC.Data /// /// /// - public PODLModel POdlGetByOdl(int idxODL) + public async Task POdlGetByOdlAsync(int idxODL) { PODLModel result = new PODLModel(); if (idxODL != 0) { - using var activity = ActivitySource.StartActivity("POdlGetByOdl"); + using var activity = ActivitySource.StartActivity("POdlGetByOdlAsync"); string source = "DB"; string currKey = $"{Utils.redisPOdlByOdl}:{idxODL}"; // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); + RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { var rawResult = JsonConvert.DeserializeObject($"{rawData}"); @@ -1967,10 +1967,10 @@ namespace MP.SPEC.Data } else { - result = dbController.PODL_getByOdl(idxODL); + result = await dbController.PODL_getByOdlAsync(idxODL); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); + await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache)); } if (result == null) { @@ -1979,7 +1979,7 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.SetTag("result.count", 1); activity?.Stop(); - Log.Trace($"POdlGetByOdl | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + Log.Trace($"POdlGetByOdlAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); } else { @@ -2054,47 +2054,6 @@ namespace MP.SPEC.Data /// Data inizio /// Data fine /// - public List POdlListGetFilt(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) - { - using var activity = ActivitySource.StartActivity("POdlListGetFiltAsync"); - List? result = new List(); - string source = "DB"; - string currKey = $"{Utils.redisPOdlList}:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = dbController.ListPODLFilt(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"POdlListGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; - } - - /// - /// Elenco PODL (Async) non avviati filtrati x articolo, KeyRich (che contiene stato) - /// - /// Solo lanciati (1) o ancora disponibili (0) - /// KeyRich (parziale) da cercare (es cod stato x yacht) - /// Macchina - /// Gruppo - /// Data inizio - /// Data fine - /// public async Task> POdlListGetFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) { string currKey = $"{Utils.redisPOdlList}:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; @@ -2122,20 +2081,20 @@ namespace MP.SPEC.Data string redisKey = $"{Utils.redisPOdlList}_kit:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; return await GetOrFetchAsync( - operationName: "POdlToKitListGetFiltAsync", - cacheKey: redisKey, - expiration: TimeSpan.FromSeconds(redisShortTimeCache * 5), - fetchFunc: async () => - await dbController.ListPODL_KitFiltAsync( - lanciato, - keyRichPart, - idxMacchina, - codGruppo, - startDate, - endDate - ) ?? new List(), - tagList: [Utils.redisPOdlList, $"{Utils.redisPOdlList}_kit"] - ); + operationName: "POdlToKitListGetFiltAsync", + cacheKey: redisKey, + expiration: TimeSpan.FromSeconds(redisShortTimeCache * 5), + fetchFunc: async () => + await dbController.ListPODL_KitFiltAsync( + lanciato, + keyRichPart, + idxMacchina, + codGruppo, + startDate, + endDate + ) ?? new List(), + tagList: [Utils.redisPOdlList, $"{Utils.redisPOdlList}_kit"] + ); } /// @@ -2410,7 +2369,7 @@ namespace MP.SPEC.Data var result = await GetOrFetchAsync( operationName: "TemplateKitFiltAsync", cacheKey: currKey, - expiration: TimeSpan.FromMinutes(redisLongTimeCache), + expiration: TimeSpan.FromSeconds(redisLongTimeCache), fetchFunc: async () => await dbController.TemplateKitFiltAsync(codParent, codChild) ?? new List(), tagList: [Utils.redisKitTempl] ); @@ -2468,7 +2427,7 @@ namespace MP.SPEC.Data result = await dbController.TksScoreAsync(KeyFilt, MaxResult); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache)); + await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(redisLongTimeCache)); } if (result == null) { @@ -2599,7 +2558,7 @@ namespace MP.SPEC.Data result = await dbController.WipKitFiltAsync(KeyFilt); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromMinutes(redisLongTimeCache)); + await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(redisLongTimeCache)); } if (result == null) { @@ -2636,14 +2595,14 @@ namespace MP.SPEC.Data #region Protected Methods /// - /// Restituisce un timeout dai minuti richiesti + tempo random -15..+15 sec + /// Restituisce un timeout dal valore secondi richiesti + tempo random -10..+10 sec /// - /// + /// /// - protected TimeSpan getRandTOut(double stdMinutes) + protected TimeSpan getRandTOut(double durationSec) { - double rndValue = stdMinutes + (double)rand.Next(-15, 15) / 60; - return TimeSpan.FromMinutes(rndValue); + double rndValue = durationSec + (double)rand.Next(-5, 5); + return TimeSpan.FromSeconds(rndValue); } /// @@ -2758,9 +2717,15 @@ namespace MP.SPEC.Data /// private IDatabase redisDb = null!; + /// + /// Durata cache breve standard (5 sec) + /// private int redisLongTimeCache = 5; - private int redisShortTimeCache = 2; + /// + /// Durata cache long standard (5min) + /// + private int redisShortTimeCache = 300; private bool traceEnabled = false; diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 8f6e41c9..3b9749c9 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2811 + 8.16.2605.2812 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 9b69bf46..c2315960 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                    Versione: 8.16.2605.2811

                    +

                    Versione: 8.16.2605.2812


                    Note di rilascio:
                    • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 378864b8..5f877377 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2811 +8.16.2605.2812 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index d3e3fe22..82abe1dc 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2811 + 8.16.2605.2812 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From e424218b01ffbadcc31ce2435679a5484a6c82da Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 12:14:18 +0200 Subject: [PATCH 043/102] Fix cache duration --- MP.SPEC/Data/MpDataService.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index d12b3fed..908adf2a 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -2718,14 +2718,14 @@ namespace MP.SPEC.Data private IDatabase redisDb = null!; /// - /// Durata cache breve standard (5 sec) + /// Durata cache Lunga standard (300 sec) /// - private int redisLongTimeCache = 5; + private int redisLongTimeCache = 300; /// - /// Durata cache long standard (5min) + /// Durata cache Breve standard (5 sec) /// - private int redisShortTimeCache = 300; + private int redisShortTimeCache = 5; private bool traceEnabled = false; From a1447c38c31e2a4870d18a0c7dc67552e79a5520 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 12:27:40 +0200 Subject: [PATCH 044/102] Fix durate random cache --- MP.SPEC/Data/MpDataService.cs | 45 ++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 908adf2a..8d061509 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -213,7 +213,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "AnagStatiCommAsync", cacheKey: Utils.redisStatoCom, - expiration: TimeSpan.FromSeconds(redisLongTimeCache), + expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.AnagStatiCommAsync() ?? new List(), tagList: [Utils.redisStatoCom] @@ -229,7 +229,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "AnagTipoArtLvAsync", cacheKey: Utils.redisTipoArt, - expiration: TimeSpan.FromSeconds(redisLongTimeCache), + expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.AnagTipoArtLvAsync() ?? new List(), tagList: [Utils.redisTipoArt] ); @@ -244,7 +244,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ArticleWithDossierAsync", cacheKey: Utils.redisArtByDossier, - expiration: TimeSpan.FromSeconds(redisLongTimeCache), + expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => await Task.FromResult(dbController.ArticleWithDossier()) ?? new List(), tagList: [Utils.redisArtByDossier] ); @@ -280,7 +280,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ArticoliGetByTipoAsync", cacheKey: redisKey, - expiration: TimeSpan.FromMinutes(2), + expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.ArticoliGetByTipoAsync(tipo, azienda) ?? new List(), tagList: [Utils.redisArtList, $"{Utils.redisArtList}:Tipo"] @@ -302,7 +302,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ArticoliGetSearchAsync", cacheKey: redisKey, - expiration: TimeSpan.FromSeconds(redisLongTimeCache), + expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal) ?? new List(), tagList: [Utils.redisArtList, $"{Utils.redisArtList}:Search"] @@ -422,7 +422,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ConfigGetAllAsync", cacheKey: Utils.redisConfKey, - expiration: TimeSpan.FromSeconds(redisLongTimeCache), + expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.ConfigGetAllAsync() ?? new List(), tagList: [Utils.redisConfKey] ); @@ -571,7 +571,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "DossiersGetLastFiltAsync", cacheKey: currKey, - expiration: TimeSpan.FromMinutes(redisLongTimeCache / 5), + expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.DossiersGetLastFiltAsync(IdxMacchina, CodArticolo, DtStart, DtEnd, MaxRec) ?? new List(), tagList: [Utils.redisDossByMac] ); @@ -644,7 +644,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ElencoAziendeAsync", cacheKey: $"{Utils.redisAnagGruppi}:Aziende", - expiration: TimeSpan.FromMinutes(redisLongTimeCache * 2), + expiration: getRandTOut(redisLongTimeCache * 2), fetchFunc: async () => await dbController.AnagGruppiAziendeAsync() ?? new List(), tagList: [Utils.redisAnagGruppi, $"{Utils.redisAnagGruppi}:Aziende"] @@ -660,7 +660,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ElencoGruppiFaseAsync", cacheKey: $"{Utils.redisAnagGruppi}:FASE", - expiration: TimeSpan.FromMinutes(redisLongTimeCache / 5), + expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.AnagGruppiFaseAsync() ?? new List(), tagList: [Utils.redisAnagGruppi] ); @@ -676,7 +676,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ElencoLinkAsync", cacheKey: Utils.redisLinkMenu, - expiration: TimeSpan.FromSeconds(redisLongTimeCache), + expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.ElencoLinkAsync() ?? new List(), tagList: [Utils.redisLinkMenu] ); @@ -1111,7 +1111,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "FluxLogParetoAsync", cacheKey: redKey, - expiration: TimeSpan.FromSeconds(redisLongTimeCache), + expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.FluxLogParetoAsync(idxMacchina, dtFrom, dtTo) ?? new List(), tagList: [Utils.redisParetoFLKey] ); @@ -1257,7 +1257,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "IstKitFiltAsync", cacheKey: currKey, - expiration: TimeSpan.FromSeconds(redisLongTimeCache), + expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.IstKitFiltAsync(keyKit, keyExtOrd) ?? new List(), tagList: [Utils.redisKitInst] ); @@ -1318,7 +1318,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ListGiacenzeAsync", cacheKey: currKey, - expiration: TimeSpan.FromSeconds(redisShortTimeCache), + expiration: getRandTOut(redisShortTimeCache), fetchFunc: async () => await dbController.ListGiacenzeAsync(IdxOdl) ?? new List(), tagList: [Utils.redisGiacenzaList] ); @@ -1423,7 +1423,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "MacchineGetFiltAsync", cacheKey: redisKey, - expiration: TimeSpan.FromMinutes(5), + expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.MacchineGetFiltAsync(codGruppo) ?? new List(), @@ -1513,7 +1513,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "MacchineWithFluxAsync", cacheKey: currKey, - expiration: TimeSpan.FromSeconds(redisLongTimeCache), + expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.MacchineWithFluxAsync(dtStart, dtEnd) ?? new List(), tagList: [Utils.redisMacByFlux] ); @@ -1526,7 +1526,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "MachineWithOdlAsync", cacheKey: redisKey, - expiration: TimeSpan.FromSeconds(3), + expiration: getRandTOut(redisShortTimeCache), fetchFunc: async () => { var rawData = await dbController.OdlGetCurrentAsync(); @@ -2060,7 +2060,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "POdlListGetFiltAsync", cacheKey: currKey, - expiration: TimeSpan.FromSeconds(redisShortTimeCache), + expiration: getRandTOut(redisShortTimeCache), fetchFunc: async () => await dbController.ListPODLFiltAsync(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate) ?? new List(), tagList: [Utils.redisPOdlList] ); @@ -2083,7 +2083,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "POdlToKitListGetFiltAsync", cacheKey: redisKey, - expiration: TimeSpan.FromSeconds(redisShortTimeCache * 5), + expiration: getRandTOut(redisShortTimeCache * 5), fetchFunc: async () => await dbController.ListPODL_KitFiltAsync( lanciato, @@ -2369,7 +2369,7 @@ namespace MP.SPEC.Data var result = await GetOrFetchAsync( operationName: "TemplateKitFiltAsync", cacheKey: currKey, - expiration: TimeSpan.FromSeconds(redisLongTimeCache), + expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.TemplateKitFiltAsync(codParent, codChild) ?? new List(), tagList: [Utils.redisKitTempl] ); @@ -2595,14 +2595,15 @@ namespace MP.SPEC.Data #region Protected Methods /// - /// Restituisce un timeout dal valore secondi richiesti + tempo random -10..+10 sec + /// Restituisce un timeout dal valore secondi richiesti + tempo random +/-3% /// /// /// protected TimeSpan getRandTOut(double durationSec) { - double rndValue = durationSec + (double)rand.Next(-5, 5); - return TimeSpan.FromSeconds(rndValue); + double noise = (rand.NextDouble() * 0.06) - 0.03; + double rValue = durationSec * (1 + noise); + return TimeSpan.FromSeconds(rValue); } /// From f3b02436ee4701645ef5bc9a789f85bfa06b433b Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 12:28:57 +0200 Subject: [PATCH 045/102] Refresh build vers --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index c757dd3b..6c909a6d 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2605.2811 + 8.16.2605.2812 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 9b69bf46..c2315960 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                      Versione: 8.16.2605.2811

                      +

                      Versione: 8.16.2605.2812


                      Note di rilascio:
                      • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 378864b8..5f877377 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2811 +8.16.2605.2812 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index 4cb4eb56..ba6fd404 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2811 + 8.16.2605.2812 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index 358dafad..763f7653 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2605.2811 + 8.16.2605.2812 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index 75b640ea..54e45418 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                        Versione: 8.16.2605.2811

                        +

                        Versione: 8.16.2605.2812


                        Note di rilascio:
                        • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index 378864b8..5f877377 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2811 +8.16.2605.2812 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index a82d5b1c..56b8c6b5 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2811 + 8.16.2605.2812 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 2792aac7..fec65860 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2605.2811 + 8.16.2605.2812 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 0b3d6084..bce40d5e 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                          Versione: 8.16.2605.2811

                          +

                          Versione: 8.16.2605.2812


                          Note di rilascio:
                            diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 378864b8..5f877377 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2811 +8.16.2605.2812 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index 0ef06353..d0ac5107 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2811 + 8.16.2605.2812 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index d8b8627b..077521b3 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2605.2811 + 8.16.2605.2812 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 9b69bf46..c2315960 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                            Versione: 8.16.2605.2811

                            +

                            Versione: 8.16.2605.2812


                            Note di rilascio:
                            • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 378864b8..5f877377 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2811 +8.16.2605.2812 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index b54a4a6a..880b032e 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2811 + 8.16.2605.2812 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 486a2b09..5e4cc6cb 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2605.2811 + 8.16.2605.2812 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index 165f4249..6a166642 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                              Versione: 8.16.2605.2811

                              +

                              Versione: 8.16.2605.2812


                              Note di rilascio:
                                diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 378864b8..5f877377 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2811 +8.16.2605.2812 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 28774385..1682cbce 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2811 + 8.16.2605.2812 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index 1be669a4..e4c6dc00 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2605.2811 + 8.16.2605.2812 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index b461f521..d4fbb8ec 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                Versione: 8.16.2605.2811

                                +

                                Versione: 8.16.2605.2812


                                Note di rilascio:
                                • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index 378864b8..5f877377 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2811 +8.16.2605.2812 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index 1d5465b5..057cc8fa 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2811 + 8.16.2605.2812 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 31531020..cd1b64b0 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2605.2811 + 8.16.2605.2812 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index f1c8b025..d9d4dbb0 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                  Versione: 8.16.2605.2811

                                  +

                                  Versione: 8.16.2605.2812


                                  Note di rilascio:
                                    diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 378864b8..5f877377 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2811 +8.16.2605.2812 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index 21f52685..8eb3c0dc 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2811 + 8.16.2605.2812 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false From 3f4a64e83370bdf02f47b19590079dc8574854cd Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 12:29:59 +0200 Subject: [PATCH 046/102] Fix IOC dataService --- MP.IOC/Data/MpDataService.cs | 47 ------------------------------------ 1 file changed, 47 deletions(-) diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs index 5d90ab3d..74af58a3 100644 --- a/MP.IOC/Data/MpDataService.cs +++ b/MP.IOC/Data/MpDataService.cs @@ -2751,53 +2751,6 @@ namespace MP.IOC.Data return result; } - /// - /// Recupero PODL da IdxODL - /// - /// - /// - public PODLModel POdlGetByOdl(int idxODL) - { - PODLModel result = new PODLModel(); - if (idxODL != 0) - { - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - string currKey = $"{Utils.redisPOdlByOdl}:{idxODL}"; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - var rawResult = JsonConvert.DeserializeObject($"{rawData}"); - if (rawResult != null) - { - result = rawResult; - } - readType = "REDIS"; - } - else - { - result = SpecDbController.PODL_getByOdl(idxODL); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new PODLModel(); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Trace($"POdlGetByOdl | Read from {readType}: {ts.TotalMilliseconds}ms"); - } - else - { - Log.Debug("Errore IdxODL = 0"); - } - return result; - } - /// /// Elenco PODL non avviati filtrati x articolo, KeyRich (che contiene stato) /// From 7be59894e4c2d9f8dddfb57f1c39681f765b69d3 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 12:39:57 +0200 Subject: [PATCH 047/102] Update cache su altri metodi --- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.SPEC/Data/MpDataService.cs | 118 ++++++++------------------------ 5 files changed, 34 insertions(+), 92 deletions(-) diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index b1390e67..a246b3c4 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.2811 + 8.16.2605.2812 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 4f14e552..809025c0 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                    Versione: 8.16.2605.2811

                                    +

                                    Versione: 8.16.2605.2812


                                    Note di rilascio:
                                    • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 378864b8..5f877377 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2811 +8.16.2605.2812 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 64384a3d..5e69e8ec 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2811 + 8.16.2605.2812 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 8d061509..2928da0e 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1948,44 +1948,14 @@ namespace MP.SPEC.Data /// public async Task POdlGetByOdlAsync(int idxODL) { - PODLModel result = new PODLModel(); - if (idxODL != 0) - { - using var activity = ActivitySource.StartActivity("POdlGetByOdlAsync"); - string source = "DB"; - string currKey = $"{Utils.redisPOdlByOdl}:{idxODL}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - var rawResult = JsonConvert.DeserializeObject($"{rawData}"); - if (rawResult != null) - { - result = rawResult; - } - source = "REDIS"; - } - else - { - result = await dbController.PODL_getByOdlAsync(idxODL); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new PODLModel(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", 1); - activity?.Stop(); - Log.Trace($"POdlGetByOdlAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - } - else - { - Log.Debug("Errore IdxODL = 0"); - } - return result; + string currKey = $"{Utils.redisPOdlByOdl}:{idxODL}"; + return await GetOrFetchAsync( + operationName: "POdlGetByOdlAsync", + cacheKey: currKey, + expiration: TimeSpan.FromMinutes(redisLongTimeCache), + fetchFunc: async () => await dbController.PODL_getByOdlAsync(idxODL) ?? new(), + tagList: [Utils.redisPOdlByOdl] + ); } /// @@ -2411,33 +2381,24 @@ namespace MP.SPEC.Data /// public async Task> TksScoreAsync(string KeyFilt, int MaxResult, bool ForceDb) { - using var activity = ActivitySource.StartActivity("TksScoreAsync"); - string source = "DB"; - List? result = new List(); - // cerco in redis... string currKey = $"{Utils.redisKitScore}:{KeyFilt}:{MaxResult}"; - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue && !ForceDb) + + if (ForceDb) { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; + // Se ForceDb è true, saltiamo il GetOrFetchAsync per forzare il fetch dal DB + // e aggiornare la cache. + var result = await dbController.TksScoreAsync(KeyFilt, MaxResult) ?? new List(); + await _cache.SetAsync(currKey, result, TimeSpan.FromMinutes(redisLongTimeCache), tags: [Utils.redisKitScore]); + return result; } - else - { - result = await dbController.TksScoreAsync(KeyFilt, MaxResult); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"TksScoreAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return result; + + return await GetOrFetchAsync( + operationName: "TksScoreAsync", + cacheKey: currKey, + expiration: TimeSpan.FromMinutes(redisLongTimeCache), + fetchFunc: async () => await dbController.TksScoreAsync(KeyFilt, MaxResult) ?? new List(), + tagList: [Utils.redisKitScore] + ); } /// @@ -2542,33 +2503,14 @@ namespace MP.SPEC.Data /// public async Task> WipKitFiltAsync(string KeyFilt) { - using var activity = ActivitySource.StartActivity("WipKitFiltAsync"); - string source = "DB"; - List? result = new List(); - // cerco in redis... string currKey = $"{Utils.redisKitWip}:{KeyFilt}"; - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.WipKitFiltAsync(KeyFilt); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"WipKitFiltAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return result; + return await GetOrFetchAsync( + operationName: "WipKitFiltAsync", + cacheKey: currKey, + expiration: TimeSpan.FromMinutes(redisLongTimeCache), + fetchFunc: async () => await dbController.WipKitFiltAsync(KeyFilt) ?? new List(), + tagList: [Utils.redisKitWip] + ); } /// From 4daaf6ffd09acce96802e8189604421d17672bea Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 12:47:03 +0200 Subject: [PATCH 048/102] Ancora refactor metodi + documentazione --- MP.Data/Controllers/MpSpecController.cs | 28 ++++++--------- MP.IOC/Data/MpDataService.cs | 2 +- MP.SPEC/Components/ListPARAMS.razor.cs | 2 +- MP.SPEC/Data/MpDataService.cs | 48 +++++++------------------ Refactor_Plan.md | 22 ++++++------ 5 files changed, 34 insertions(+), 68 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 1b5bab5b..5b899582 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -491,14 +491,12 @@ namespace MP.Data.Controllers { //query = query.Where(x => x.Tipo.ToLower() == tipoArt.ToLower()); query = query.Where(x => EF.Functions.Like(x.Tipo, tipoArt)); - } // filtro azienda if (azienda != "*") { //query = query.Where(x => x.Azienda.ToLower() == azienda.ToLower()); query = query.Where(x => EF.Functions.Like(x.Azienda, azienda)); - } // filtro ricerca if (!string.IsNullOrWhiteSpace(searchVal)) @@ -520,7 +518,6 @@ namespace MP.Data.Controllers .ToListAsync(); } - /// /// Elenco tabella Articoli NON IMPIEGATI (da stored stp_ART_getUsed) Async /// @@ -1076,20 +1073,16 @@ namespace MP.Data.Controllers /// *=tutti, altrimenti solo selezionato /// numero massimo record da restituire /// - public List FluxLogGetLastFilt(DateTime DtMax, DateTime DtMin, string IdxMacchina, string CodFlux, int MaxRec) + public async Task> FluxLogGetLastFiltAsync(DateTime DtMax, DateTime DtMin, string IdxMacchina, string CodFlux, int MaxRec) { - List dbResult = new List(); - using (var dbCtx = new MoonPro_FluxContext(_configuration)) - { - dbResult = dbCtx - .DbSetFluxLog - .AsNoTracking() - .Where(x => (x.dtEvento >= DtMin && x.dtEvento <= DtMax) && (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && (CodFlux == "*" || x.CodFlux == CodFlux)) - .OrderByDescending(x => x.dtEvento) - .Take(MaxRec) - .ToList(); - } - return dbResult; + using var dbCtx = new MoonPro_FluxContext(_configuration); + return await dbCtx + .DbSetFluxLog + .AsNoTracking() + .Where(x => (x.dtEvento >= DtMin && x.dtEvento <= DtMax) && (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && (CodFlux == "*" || x.CodFlux == CodFlux)) + .OrderByDescending(x => x.dtEvento) + .Take(MaxRec) + .ToListAsync() ?? new(); } /// @@ -1629,7 +1622,7 @@ namespace MP.Data.Controllers .ToList(); } return dbResult; - } + } #endif /// @@ -1805,7 +1798,6 @@ namespace MP.Data.Controllers .Select(i => i.IdxMacchina) .Distinct() .ToListAsync() ?? new(); - } /// diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs index 74af58a3..2237d76c 100644 --- a/MP.IOC/Data/MpDataService.cs +++ b/MP.IOC/Data/MpDataService.cs @@ -1541,7 +1541,7 @@ namespace MP.IOC.Data } else { - result = await Task.FromResult(SpecDbController.FluxLogGetLastFilt(DtMax, DtMin, IdxMacchina, CodFlux, MaxRec)); + result = await SpecDbController.FluxLogGetLastFiltAsync(DtMax, DtMin, IdxMacchina, CodFlux, MaxRec); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); if (string.IsNullOrEmpty(canCacheParametri)) diff --git a/MP.SPEC/Components/ListPARAMS.razor.cs b/MP.SPEC/Components/ListPARAMS.razor.cs index 4e254b81..f65ba554 100644 --- a/MP.SPEC/Components/ListPARAMS.razor.cs +++ b/MP.SPEC/Components/ListPARAMS.razor.cs @@ -108,7 +108,7 @@ namespace MP.SPEC.Components dataTo = (DateTime)SelDtMax; } - SearchRecords = await MDService.FluxLogGetLastFilt(dataTo, dataFrom, SelMacchina, SelFlux, MaxRecord, RefreshPeriod / 1000); + SearchRecords = await MDService.FluxLogGetLastFiltAsync(dataTo, dataFrom, SelMacchina, SelFlux, MaxRecord, RefreshPeriod / 1000); totalCount = SearchRecords.Count; ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); await Task.Delay(1); diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 2928da0e..533b6855 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -571,7 +571,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "DossiersGetLastFiltAsync", cacheKey: currKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: getRandTOut(redisLongTimeCache * 5), fetchFunc: async () => await dbController.DossiersGetLastFiltAsync(IdxMacchina, CodArticolo, DtStart, DtEnd, MaxRec) ?? new List(), tagList: [Utils.redisDossByMac] ); @@ -1055,50 +1055,26 @@ namespace MP.SPEC.Data } /// - /// Elenco ultimi n record flux log dato idxMaccSel e flusso (ordinato x data registrazione) + /// Elenco FluxLog in modalità filtro /// /// Data massima x eventi /// Data minima x eventi /// * = tutte, altrimenti solo x una data idxMaccSel /// *=tutti, altrimenti solo selezionato /// numero massimo record da restituire + /// durata cache in secondi /// - public async Task> FluxLogGetLastFilt(DateTime DtMax, DateTime DtMin, string IdxMacchina, string CodFlux, int MaxRec, double redisCacheSec) + public async Task> FluxLogGetLastFiltAsync(DateTime DtMax, DateTime DtMin, string IdxMacchina, string CodFlux, int MaxRec, double redisCacheSec) { - using var activity = ActivitySource.StartActivity("FluxLogGetLastFilt"); - List? result = new List(); - string source = "DB"; string currKey = $"{Utils.redisFluxLogFilt}:{IdxMacchina}:{CodFlux}:{MaxRec}:{DtMax:yyyyMMddHHmm}:{DtMin:yyyyMMddHHmm}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await Task.FromResult(dbController.FluxLogGetLastFilt(DtMax, DtMin, IdxMacchina, CodFlux, MaxRec)); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - if (string.IsNullOrEmpty(canCacheParametri)) - { - canCacheParametri = await ConfigTryGetAsync("SPEC_ParametriEnableRedisCache"); - } - if (canCacheParametri != "false") - { - redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisCacheSec)); - } - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"FluxLogGetLastFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + + return await GetOrFetchAsync( + operationName: "FluxLogGetLastFiltAsync", + cacheKey: currKey, + expiration: TimeSpan.FromSeconds(redisCacheSec), + fetchFunc: async () => await dbController.FluxLogGetLastFiltAsync(DtMax, DtMin, IdxMacchina, CodFlux, MaxRec) ?? new List(), + tagList: [Utils.redisFluxLogFilt] + ); } /// diff --git a/Refactor_Plan.md b/Refactor_Plan.md index 0388a4d9..c4097387 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -32,6 +32,16 @@ I metodi verranno suddivisi in: - [x] `TemplateKitFiltAsync` - [x] `AnagTipoArtLvAsync` - [x] `ElencoLinkAsync` +- [x] `ConfigGetAllAsync` +- [x] `DossiersGetLastFiltAsync` +- [x] `ElencoGruppiFaseAsync` +- [x] `IstKitFiltAsync` +- [x] `ListGiacenzeAsync` +- [x] `MacchineWithFluxAsync` +- [x] `POdlListGetFiltAsync` +- [x] `TksScoreAsync` +- [x] `WipKitFiltAsync` +- [x] `POdlGetByOdlAsync` - [ ] `AnagEventiGeneral` - [ ] `AnagEventiGetByMacch` - [ ] `AnagKeyValGetAll` @@ -39,20 +49,14 @@ I metodi verranno suddivisi in: - [ ] `AnagTipoArtLvAsync` - [ ] `ArticleWithDossier` - [ ] `ConfigGetAll` -- [ ] `ConfigGetAllAsync` - [ ] `DbDedupStats` -- [ ] `DossiersGetLastFilt` -- [ ] `ElencoGruppiFase` - [ ] `ElencoRepartiDTO` - [ ] `ExpiryReloadParamGet` - [ ] `IobInfo` -- [ ] `IstKitFilt` -- [ ] `ListGiacenze` - [ ] `ListPODL_ByCodArt` - [ ] `MacchineGetFilt` - [ ] `MacchineRecipeArchive` - [ ] `MacchineRecipeConf` -- [ ] `MacchineWithFlux` - [ ] `MachIobConf` - [ ] `MseGetAll` - [ ] `OdlByBatch` @@ -61,17 +65,11 @@ I metodi verranno suddivisi in: - [ ] `OperatoriGetFilt` - [ ] `ParametriGetFilt` - [ ] `POdlGetByKey` -- [ ] `POdlGetByOdl` - [ ] `POdlListByKitParent` -- [ ] `POdlListGetFilt` -- [ ] `POdlListGetFiltAsync` - [ ] `ProcFLStats` - [ ] `StatoMacchina` - [ ] `TagConfGetKey` -- [ ] `TemplateKitFilt` -- [ ] `TksScore` - [ ] `VocabolarioGetAll` -- [ ] `WipKitFilt` #### Fase 3: Refactoring Metodi di Scrittura e Invalidazione - [ ] `AnagGruppiDelete` From b8fd2c992fd1374ad5ed014dcd9bc4b7f4533a2f Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 13:07:31 +0200 Subject: [PATCH 049/102] Ancora update async (preliminare) --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index 6c909a6d..a1369640 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2605.2812 + 8.16.2605.2813 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index c2315960..27cc5bf1 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                      Versione: 8.16.2605.2812

                                      +

                                      Versione: 8.16.2605.2813


                                      Note di rilascio:
                                      • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 5f877377..44370d54 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2812 +8.16.2605.2813 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index ba6fd404..1f1848d9 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2812 + 8.16.2605.2813 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false From 47326e653512e06078d6349c88b4914510c9b00d Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 13:07:37 +0200 Subject: [PATCH 050/102] Altri fix async --- MP.Data/Controllers/MpSpecController.cs | 49 +++++------- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.SPEC/Components/ListDossiers.razor.cs | 2 +- MP.SPEC/Components/ListPODL.razor.cs | 8 +- .../Controllers/RecipeArchiveController.cs | 6 +- MP.SPEC/Data/MpDataService.cs | 73 +++++------------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/FluxLogStatus.razor.cs | 12 +-- MP.SPEC/Pages/GroupMacOprMan.razor.cs | 77 ++++++++++--------- MP.SPEC/Pages/ODL.razor.cs | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- Refactor_Plan.md | 65 ++++++++++++++++ 41 files changed, 191 insertions(+), 167 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 5b899582..236c15e4 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -2076,40 +2076,31 @@ namespace MP.Data.Controllers ///
                                      /// /// - public List OperatoriGetFilt(string codGruppo) + public async Task> OperatoriGetFiltAsync(string codGruppo) { List dbResult = new List(); - try + using var dbCtx = new MoonProContext(options); + if (codGruppo == "*") { - using (var dbCtx = new MoonProContext(options)) - { - if (codGruppo == "*") - { - dbResult = dbCtx - .DbOperatori - .AsNoTracking() - .OrderBy(x => x.MatrOpr) - .ToList(); - } - else - { - dbResult = dbCtx - .DbSetGrp2Oper - .Where(g => g.CodGruppo == codGruppo) - .Join(dbCtx.DbOperatori, - g => g.MatrOpr, - m => m.MatrOpr, - (g, m) => m - ) - .AsNoTracking() - .OrderBy(x => x.MatrOpr) - .ToList(); - } - } + dbResult = await dbCtx + .DbOperatori + .AsNoTracking() + .OrderBy(x => x.MatrOpr) + .ToListAsync(); } - catch (Exception exc) + else { - Log.Error($"Eccezione in OperatoriGetFilt{Environment.NewLine}{exc}"); + dbResult = await dbCtx + .DbSetGrp2Oper + .Where(g => g.CodGruppo == codGruppo) + .Join(dbCtx.DbOperatori, + g => g.MatrOpr, + m => m.MatrOpr, + (g, m) => m + ) + .AsNoTracking() + .OrderBy(x => x.MatrOpr) + .ToListAsync(); } return dbResult; } diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index 763f7653..c0efe24e 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2605.2812 + 8.16.2605.2813 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index 54e45418..4bee3c34 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                      Versione: 8.16.2605.2812

                                      +

                                      Versione: 8.16.2605.2813


                                      Note di rilascio:
                                      • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index 5f877377..44370d54 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2812 +8.16.2605.2813 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index 56b8c6b5..8607ff63 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2812 + 8.16.2605.2813 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index a246b3c4..ebb58f99 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.2812 + 8.16.2605.2813 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 809025c0..35048e17 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                        Versione: 8.16.2605.2812

                                        +

                                        Versione: 8.16.2605.2813


                                        Note di rilascio:
                                        • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 5f877377..44370d54 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2812 +8.16.2605.2813 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 5e69e8ec..f27bc7f5 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2812 + 8.16.2605.2813 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index fec65860..031dfb6e 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2605.2812 + 8.16.2605.2813 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index bce40d5e..8a6e8d56 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                          Versione: 8.16.2605.2812

                                          +

                                          Versione: 8.16.2605.2813


                                          Note di rilascio:
                                            diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 5f877377..44370d54 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2812 +8.16.2605.2813 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index d0ac5107..20889b50 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2812 + 8.16.2605.2813 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index 077521b3..4785d316 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2605.2812 + 8.16.2605.2813 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index c2315960..27cc5bf1 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                            Versione: 8.16.2605.2812

                                            +

                                            Versione: 8.16.2605.2813


                                            Note di rilascio:
                                            • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 5f877377..44370d54 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2812 +8.16.2605.2813 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index 880b032e..b7f7a499 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2812 + 8.16.2605.2813 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 5e4cc6cb..6bdfd81f 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2605.2812 + 8.16.2605.2813 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index 6a166642..6157c881 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                              Versione: 8.16.2605.2812

                                              +

                                              Versione: 8.16.2605.2813


                                              Note di rilascio:
                                                diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 5f877377..44370d54 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2812 +8.16.2605.2813 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 1682cbce..fcda10d7 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2812 + 8.16.2605.2813 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index e4c6dc00..2d6e755f 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2605.2812 + 8.16.2605.2813 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index d4fbb8ec..60808d02 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                Versione: 8.16.2605.2812

                                                +

                                                Versione: 8.16.2605.2813


                                                Note di rilascio:
                                                • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index 5f877377..44370d54 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2812 +8.16.2605.2813 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index 057cc8fa..3c7d9eba 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2812 + 8.16.2605.2813 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Components/ListDossiers.razor.cs b/MP.SPEC/Components/ListDossiers.razor.cs index a6d463ad..fb2caf8c 100644 --- a/MP.SPEC/Components/ListDossiers.razor.cs +++ b/MP.SPEC/Components/ListDossiers.razor.cs @@ -235,7 +235,7 @@ namespace MP.SPEC.Components selAzienda = await MDService.ConfigTryGetAsync("AZIENDA"); giacenzeConf = await MDService.ConfigTryGetAsync("SPEC_ShowGiacenze"); ListArticoli = await MDService.ArticoliGetSearchAsync(100000, "*", selAzienda, ""); - ListMacchine = MDService.MacchineGetFilt("*"); + ListMacchine = await MDService.MacchineGetFiltAsync("*"); await ReloadData(true); } diff --git a/MP.SPEC/Components/ListPODL.razor.cs b/MP.SPEC/Components/ListPODL.razor.cs index 533f647a..582f189b 100644 --- a/MP.SPEC/Components/ListPODL.razor.cs +++ b/MP.SPEC/Components/ListPODL.razor.cs @@ -128,18 +128,18 @@ namespace MP.SPEC.Components await Task.Delay(1); } - protected void doShowRecipeArch(PODLExpModel selRec) + protected async Task doShowRecipeArch(PODLExpModel selRec) { currRecord = selRec; - currRecipeArchPath = MDService.MacchineRecipeArchive(selRec.IdxMacchina); + currRecipeArchPath = await MDService.MacchineRecipeArchiveAsync(selRec.IdxMacchina); showRecipeArch = true; showRecipeConf = false; } - protected void doShowRecipeConf(PODLExpModel selRec) + protected async Task doShowRecipeConf(PODLExpModel selRec) { currRecord = selRec; - currRecipePath = MDService.MacchineRecipeConf(selRec.IdxMacchina); + currRecipePath = await MDService.MacchineRecipeConfAsync(selRec.IdxMacchina); showRecipeArch = false; showRecipeConf = true; } diff --git a/MP.SPEC/Controllers/RecipeArchiveController.cs b/MP.SPEC/Controllers/RecipeArchiveController.cs index ca7352ce..31114e5c 100644 --- a/MP.SPEC/Controllers/RecipeArchiveController.cs +++ b/MP.SPEC/Controllers/RecipeArchiveController.cs @@ -28,7 +28,7 @@ namespace MP.SPEC.Controllers public async Task GetByPODL(string idxMacc, int idxPODL) { string answ = ""; - string archPath = DService.MacchineRecipeArchive(idxMacc); + string archPath = await DService.MacchineRecipeArchiveAsync(idxMacc); var podlData = await DService.POdlGetByKey(idxPODL); if (podlData != null) { @@ -43,10 +43,10 @@ namespace MP.SPEC.Controllers } [HttpGet("GetFile")] - public string GetFile(string idxMacc, string fileName) + public async Task GetFile(string idxMacc, string fileName) { string answ = ""; - string archPath = DService.MacchineRecipeArchive(idxMacc); + string archPath = await DService.MacchineRecipeArchiveAsync(idxMacc); if (!string.IsNullOrEmpty(archPath)) { string fullPath = Path.Combine(archPath, fileName); diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 533b6855..a54e488d 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1349,43 +1349,6 @@ namespace MP.SPEC.Data return result; } - /// - /// Elenco di tutte le macchine filtrate x gruppo - /// - /// - /// - public List MacchineGetFilt(string codGruppo) - { - using var activity = ActivitySource.StartActivity("MacchineGetFilt"); - List? result = new List(); - string source = "DB"; - string keyGrp = codGruppo != "*" ? codGruppo : "ALL"; - string currKey = $"{Utils.redisMacList}:{keyGrp}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = dbController.MacchineGetFilt(codGruppo); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", 1); - activity?.Stop(); - LogTrace($"MacchineGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; - } - /// /// Elenco di tutte le macchine filtrate x gruppo /// @@ -1412,14 +1375,14 @@ namespace MP.SPEC.Data ///
                                      /// /// - public string MacchineRecipeArchive(string idxMacchina) + public async Task MacchineRecipeArchiveAsync(string idxMacchina) { - using var activity = ActivitySource.StartActivity("MacchineRecipeArchive"); + using var activity = ActivitySource.StartActivity("MacchineRecipeArchiveAsync"); string? result = ""; string source = "DB"; string currKey = $"{Utils.redisMacRecipePath}:{idxMacchina}"; // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); + RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject($"{rawData}"); @@ -1428,17 +1391,17 @@ namespace MP.SPEC.Data else { //recupero elenco macchine... - var machineList = MacchineGetFilt("*"); + var machineList = await MacchineGetFiltAsync("*"); var currMach = machineList.Where(x => x.IdxMacchina == idxMacchina).FirstOrDefault(); result = currMach != null ? currMach.RecipeArchivePath : null; // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); + await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache)); } activity?.SetTag("data.source", source); activity?.SetTag("result.count", 1); activity?.Stop(); - LogTrace($"MacchineRecipeArchive | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"MacchineRecipeArchiveAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result ?? ""; } @@ -1447,14 +1410,14 @@ namespace MP.SPEC.Data ///
                                      /// /// - public string MacchineRecipeConf(string idxMacchina) + public async Task MacchineRecipeConfAsync(string idxMacchina) { - using var activity = ActivitySource.StartActivity("MacchineRecipeConf"); + using var activity = ActivitySource.StartActivity("MacchineRecipeConfAsync"); string? result = ""; string source = "DB"; string currKey = $"{Utils.redisMacRecipeConf}:{idxMacchina}"; // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); + RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject($"{rawData}"); @@ -1463,17 +1426,17 @@ namespace MP.SPEC.Data else { //recupero elenco macchine... - var machineList = MacchineGetFilt("*"); + var machineList = await MacchineGetFiltAsync("*"); var currMach = machineList.Where(x => x.IdxMacchina == idxMacchina).FirstOrDefault(); result = currMach != null ? currMach.RecipePath : null; // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); + await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache)); } activity?.SetTag("data.source", source); activity?.SetTag("result.count", 1); activity?.Stop(); - LogTrace($"MacchineRecipeConf | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"MacchineRecipeConfAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result ?? ""; } @@ -1767,15 +1730,15 @@ namespace MP.SPEC.Data ///
                                      /// /// - public List OperatoriGetFilt(string codGruppo) + public async Task> OperatoriGetFiltAsync(string codGruppo) { - using var activity = ActivitySource.StartActivity("OperatoriGetFilt"); + using var activity = ActivitySource.StartActivity("OperatoriGetFiltAsync"); List? result = new List(); string source = "DB"; string keyGrp = codGruppo != "*" ? codGruppo : "ALL"; string currKey = $"{Utils.redisOprList}:{keyGrp}"; // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); + RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); @@ -1783,10 +1746,10 @@ namespace MP.SPEC.Data } else { - result = dbController.OperatoriGetFilt(codGruppo); + result = await dbController.OperatoriGetFiltAsync(codGruppo); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); + await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache)); } if (result == null) { @@ -1794,7 +1757,7 @@ namespace MP.SPEC.Data } activity?.SetTag("result.count", result.Count); activity?.Stop(); - LogTrace($"OperatoriGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); activity?.SetTag("data.source", source); + LogTrace($"OperatoriGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); activity?.SetTag("data.source", source); return result; } diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 3b9749c9..c2064311 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2812 + 8.16.2605.2813 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/FluxLogStatus.razor.cs b/MP.SPEC/Pages/FluxLogStatus.razor.cs index 846ecdf1..1b0d3ff8 100644 --- a/MP.SPEC/Pages/FluxLogStatus.razor.cs +++ b/MP.SPEC/Pages/FluxLogStatus.razor.cs @@ -120,17 +120,17 @@ namespace MP.SPEC.Pages isReindexing = false; } - protected override void OnInitialized() + protected override async Task OnInitializedAsync() { ReloadStats(); - ReloadData(); + await ReloadDataAsync(); } - protected void ReloadMacchine() + protected async Task ReloadMacchineAsync() { if (ListMacchineAll == null || ListMacchineAll.Count == 0) { - var rawData = MDataServ.MacchineGetFilt("*"); + var rawData = await MDataServ.MacchineGetFiltAsync("*"); // trasformo! if (rawData != null) { @@ -218,9 +218,9 @@ namespace MP.SPEC.Pages #region Private Methods - private void ReloadData() + private async Task ReloadDataAsync() { - ReloadMacchine(); + await ReloadMacchineAsync(); DateTime dtEnd = DateTime.Today.AddDays(1); DateTime dtStart = dtEnd.AddMonths(-1); CurrPeriodo = new Periodo(dtStart, dtEnd); diff --git a/MP.SPEC/Pages/GroupMacOprMan.razor.cs b/MP.SPEC/Pages/GroupMacOprMan.razor.cs index 8bd01f77..9e5c2bb1 100644 --- a/MP.SPEC/Pages/GroupMacOprMan.razor.cs +++ b/MP.SPEC/Pages/GroupMacOprMan.razor.cs @@ -1,8 +1,6 @@ -using DnsClient.Protocol; using Microsoft.AspNetCore.Components; using MP.Core.DTO; using MP.Data.DbModels; -using MP.Data.Services; using MP.SPEC.Data; namespace MP.SPEC.Pages @@ -24,13 +22,26 @@ namespace MP.SPEC.Pages [Inject] protected MpDataService MDService { get; set; } = null!; + protected string SearchVal + { + get => searchVal; + set + { + if (searchVal != value) + { + searchVal = value; + ReloadDataAsync(); + } + } + } + #endregion Protected Properties #region Protected Methods protected override void OnInitialized() { - ReloadData(); + ReloadDataAsync(); } #endregion Protected Methods @@ -41,10 +52,17 @@ namespace MP.SPEC.Pages private bool isLoading = false; + private string searchVal = ""; + #endregion Private Fields #region Private Properties + private string btnSearchCss + { + get => string.IsNullOrWhiteSpace(SearchVal) ? "btn-secondary" : "btn-primary"; + } + private string CssMain { get => ShowDetail ? "col-3" : "col-12"; @@ -65,17 +83,22 @@ namespace MP.SPEC.Pages { CodGruppo = ""; } - ReloadData(); + ReloadDataAsync(); } - private void ReloadData() + private async Task ReloadBaseDataAsync() + { + ListMacchineAll = await MDService.MacchineGetFiltAsync("*"); + var listRaw = await MDService.OperatoriGetFiltAsync("*"); + ListOperatoriAll = listRaw.Where(x => x.isEnabled).ToList(); + } + + private async Task ReloadDataAsync() { isLoading = true; ListMacchine?.Clear(); - ListMacchineAll = MDService.MacchineGetFilt("*"); - ListOperatoriAll= MDService.OperatoriGetFilt("*").Where(x => x.isEnabled).ToList(); var rawList = MDService.ElencoRepartiDTO(); - if(string.IsNullOrEmpty(SearchVal)) + if (string.IsNullOrEmpty(SearchVal)) { ListReparti = rawList; } @@ -85,51 +108,33 @@ namespace MP.SPEC.Pages } if (!string.IsNullOrEmpty(CodGruppo)) { - ReloadDetail(); + await ReloadDetailAsync(); } isLoading = false; } - private void ReloadDetail() + private async Task ReloadDetailAsync() { if (!string.IsNullOrEmpty(CodGruppo)) { - ListMacchine = MDService.MacchineGetFilt(CodGruppo); - ListOperatori = MDService.OperatoriGetFilt(CodGruppo).Where(x => x.isEnabled).ToList(); + ListMacchine = await MDService.MacchineGetFiltAsync(CodGruppo); + ListOperatori = (await MDService.OperatoriGetFiltAsync(CodGruppo)) + .Where(x => x.isEnabled).ToList(); } } - private void SetCodGruppo(string CodGruppoSel) - { - isLoading = true; - CodGruppo = CodGruppoSel; - ReloadDetail(); - isLoading = false; - } - - private string btnSearchCss - { - get => string.IsNullOrWhiteSpace(SearchVal) ? "btn-secondary" : "btn-primary"; - } - private void ResetSearch() { SearchVal = ""; } - protected string SearchVal + private async Task SetCodGruppo(string CodGruppoSel) { - get => searchVal; - set - { - if (searchVal != value) - { - searchVal = value; - ReloadData(); - } - } + isLoading = true; + CodGruppo = CodGruppoSel; + await ReloadDetailAsync(); + isLoading = false; } - private string searchVal = ""; #endregion Private Methods } diff --git a/MP.SPEC/Pages/ODL.razor.cs b/MP.SPEC/Pages/ODL.razor.cs index 2b759d2d..af684446 100644 --- a/MP.SPEC/Pages/ODL.razor.cs +++ b/MP.SPEC/Pages/ODL.razor.cs @@ -111,7 +111,7 @@ namespace MP.SPEC.Pages ListGruppiFase = allGruppiData.Where(x => x.SelEnabled).ToList(); } ListStati = await MDService.AnagStatiCommAsync(); - ListMacchine = MDService.MacchineGetFilt(selReparto); + ListMacchine = await MDService.MacchineGetFiltAsync(selReparto); padCodXdl = await MDService.ConfigTryGetAsync("PadCodXdl"); } diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index c2315960..27cc5bf1 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                      Versione: 8.16.2605.2812

                                      +

                                      Versione: 8.16.2605.2813


                                      Note di rilascio:
                                      • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 5f877377..44370d54 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2812 +8.16.2605.2813 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 82abe1dc..bc74aaa7 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2812 + 8.16.2605.2813 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index cd1b64b0..c7bb86f3 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2605.2812 + 8.16.2605.2813 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index d9d4dbb0..685536af 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                        Versione: 8.16.2605.2812

                                        +

                                        Versione: 8.16.2605.2813


                                        Note di rilascio:
                                          diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 5f877377..44370d54 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2812 +8.16.2605.2813 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index 8eb3c0dc..c19d4a3b 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2812 + 8.16.2605.2813 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false diff --git a/Refactor_Plan.md b/Refactor_Plan.md index c4097387..b39f393f 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -42,6 +42,71 @@ I metodi verranno suddivisi in: - [x] `TksScoreAsync` - [x] `WipKitFiltAsync` - [x] `POdlGetByOdlAsync` +- [x] `FluxLogGetLastFiltAsync` +- [x] `FluxLogParetoAsync` +- [ ] `AnagEventiGeneral` +- [ ] `AnagEventiGetByMacch` +- [ ] `AnagKeyValGetAll` +- [ ] `AnagStatiComm` +- [ ] `AnagTipoArtLvAsync` +- [ ] `ArticleWithDossier` +- [ ] `ConfigGetAll` +- [ ] `DbDedupStats` +- [ ] `ElencoRepartiDTO` +- [ ] `ExpiryReloadParamGet` +- [ ] `IobInfo` +- [ ] `ListPODL_ByCodArt` +- [ ] `MacchineGetFilt` +- [ ] `MacchineRecipeArchive` +- [ ] `MacchineRecipeConf` +- [ ] `MachIobConf` +- [ ] `MseGetAll` +- [ ] `OdlByBatch` +- [ ] `OdlGetCurrentAsync` +- [ ] `OdlListGetFilt` +- [ ] `OperatoriGetFilt` +- [ ] `ParametriGetFilt` +- [ ] `POdlGetByKey` +- [ ] `POdlListByKitParent` +- [ ] `ProcFLStats` +- [ ] `StatoMacchina` +- [ ] `TagConfGetKey` +- [ ] `VocabolarioGetAll` + +#### Fase 3: Refactoring Metodi di Scrittura e Invalidazione +- [ ] `AnagGruppiDelete` +- [ ] `AnagGruppiUpsert` +- [ ] `ArticoliDeleteRecord` +- [ ] `ArticoliUpdateRecord` +- [ ] `ConfigResetCache` +- [ ] `DossiersDeleteRecord` +- [ ] `DossiersTakeParamsSnapshotLast` +- [ ] `IstKitDelete` +- [ ] `IstKitInsertByWKS` +- [ ] `IstKitUpsert` +- [ ] `PodlIstKitDelete` +- [ ] `POdlDoSetup` +- [ ] `POdlUpdateRecipe` +- [ ] `POdlUpdateRecord` +- [ ] `RecipeSetByPODL` +- [ ] `TemplateKitDelete` +- [ ] `TemplateKitUpsert` Fase 2: Refactoring Metodi di Lettura +- [x] `ActionGetReq` (Completato) +- [x] `TemplateKitFiltAsync` +- [x] `AnagTipoArtLvAsync` +- [x] `ElencoLinkAsync` +- [x] `ConfigGetAllAsync` +- [x] `DossiersGetLastFiltAsync` +- [x] `ElencoGruppiFaseAsync` +- [x] `IstKitFiltAsync` +- [x] `ListGiacenzeAsync` +- [x] `MacchineWithFluxAsync` +- [x] `POdlListGetFiltAsync` +- [x] `TksScoreAsync` +- [x] `WipKitFiltAsync` +- [x] `POdlGetByOdlAsync` +- [x] `FluxLogGetLastFiltAsync` +- [x] `FluxLogParetoAsync` - [ ] `AnagEventiGeneral` - [ ] `AnagEventiGetByMacch` - [ ] `AnagKeyValGetAll` From c45dab1c31b9d0a10e314df8470be68cd313d36e Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 14:49:20 +0200 Subject: [PATCH 051/102] Update metodi cache su SPEC --- MP.SPEC/Data/MpDataService.cs | 128 ++++++++++--------------------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 5 files changed, 46 insertions(+), 90 deletions(-) diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index a54e488d..3c49b185 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1377,32 +1377,19 @@ namespace MP.SPEC.Data /// public async Task MacchineRecipeArchiveAsync(string idxMacchina) { - using var activity = ActivitySource.StartActivity("MacchineRecipeArchiveAsync"); - string? result = ""; - string source = "DB"; string currKey = $"{Utils.redisMacRecipePath}:{idxMacchina}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject($"{rawData}"); - source = "REDIS"; - } - else - { - //recupero elenco macchine... - var machineList = await MacchineGetFiltAsync("*"); - var currMach = machineList.Where(x => x.IdxMacchina == idxMacchina).FirstOrDefault(); - result = currMach != null ? currMach.RecipeArchivePath : null; - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", 1); - activity?.Stop(); - LogTrace($"MacchineRecipeArchiveAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result ?? ""; + return await GetOrFetchAsync( + operationName: "MacchineRecipeArchiveAsync", + cacheKey: currKey, + expiration: getRandTOut(redisLongTimeCache), + fetchFunc: async () => + { + var machineList = await MacchineGetFiltAsync("*"); + var currMach = machineList.FirstOrDefault(x => x.IdxMacchina == idxMacchina); + return currMach?.RecipeArchivePath ?? ""; + }, + tagList: [Utils.redisMacRecipePath] + ); } /// @@ -1412,34 +1399,39 @@ namespace MP.SPEC.Data /// public async Task MacchineRecipeConfAsync(string idxMacchina) { - using var activity = ActivitySource.StartActivity("MacchineRecipeConfAsync"); - string? result = ""; - string source = "DB"; string currKey = $"{Utils.redisMacRecipeConf}:{idxMacchina}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject($"{rawData}"); - source = "REDIS"; - } - else - { - //recupero elenco macchine... - var machineList = await MacchineGetFiltAsync("*"); - var currMach = machineList.Where(x => x.IdxMacchina == idxMacchina).FirstOrDefault(); - result = currMach != null ? currMach.RecipePath : null; - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", 1); - activity?.Stop(); - LogTrace($"MacchineRecipeConfAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result ?? ""; + return await GetOrFetchAsync( + operationName: "MacchineRecipeConfAsync", + cacheKey: currKey, + expiration: getRandTOut(redisLongTimeCache), + fetchFunc: async () => + { + var machineList = await MacchineGetFiltAsync("*"); + var currMach = machineList.FirstOrDefault(x => x.IdxMacchina == idxMacchina); + return currMach?.RecipePath ?? ""; + }, + tagList: [Utils.redisMacRecipeConf] + ); } + /// + /// Elenco operatori filtrati x gruppo + /// + /// + /// + public async Task> OperatoriGetFiltAsync(string codGruppo) + { + string keyGrp = codGruppo != "*" ? codGruppo : "ALL"; + string currKey = $"{Utils.redisOprList}:{keyGrp}"; + + return await GetOrFetchAsync( + operationName: "OperatoriGetFiltAsync", + cacheKey: currKey, + expiration: getRandTOut(redisLongTimeCache), + fetchFunc: async () => await dbController.OperatoriGetFiltAsync(codGruppo) ?? new List(), + tagList: [Utils.redisOprList] + ); + } /// /// Elenco id Macchine che abbiano dati FLuxLog, nel periodo indicato /// @@ -1725,42 +1717,6 @@ namespace MP.SPEC.Data return result; } - /// - /// Elenco operatori filtrati x gruppo - /// - /// - /// - public async Task> OperatoriGetFiltAsync(string codGruppo) - { - using var activity = ActivitySource.StartActivity("OperatoriGetFiltAsync"); - List? result = new List(); - string source = "DB"; - string keyGrp = codGruppo != "*" ? codGruppo : "ALL"; - string currKey = $"{Utils.redisOprList}:{keyGrp}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.OperatoriGetFiltAsync(codGruppo); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"OperatoriGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); activity?.SetTag("data.source", source); - return result; - } - /// /// Elenco di tutti i parametri filtrati x idxMaccSel /// diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index c2064311..89bc4b9e 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2813 + 8.16.2605.2814 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 27cc5bf1..4a3ba3b7 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                          Versione: 8.16.2605.2813

                                          +

                                          Versione: 8.16.2605.2814


                                          Note di rilascio:
                                          • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 44370d54..6454cfbd 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2813 +8.16.2605.2814 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index bc74aaa7..8c6b95c1 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2813 + 8.16.2605.2814 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From 2f4bb9c1b81d195b328920c4f01872e6e109101e Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 14:49:32 +0200 Subject: [PATCH 052/102] Aggiunta gestione controllo articoli in Istanze KIT come chil --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.Data/Controllers/MpSpecController.cs | 32 ++++++++---- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.SPEC/Data/MpDataService.cs | 67 +++++++++++++++++++------ MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- 34 files changed, 106 insertions(+), 57 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index a1369640..824d4710 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2605.2813 + 8.16.2605.2814 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 27cc5bf1..4a3ba3b7 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                            Versione: 8.16.2605.2813

                                            +

                                            Versione: 8.16.2605.2814


                                            Note di rilascio:
                                            • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 44370d54..6454cfbd 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2813 +8.16.2605.2814 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index 1f1848d9..7f38c389 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2813 + 8.16.2605.2814 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 236c15e4..63e33058 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -379,15 +379,13 @@ namespace MP.Data.Controllers public List ArticleWithDossier() { List dbResult = new List(); - using (var dbCtx = new MoonPro_FluxContext(_configuration)) - { - dbResult = dbCtx - .DbSetDossiers - .AsNoTracking() - .Select(i => i.CodArticolo) - .Distinct() - .ToList(); - } + using var dbCtx = new MoonPro_FluxContext(_configuration); + dbResult = dbCtx + .DbSetDossiers + .AsNoTracking() + .Select(i => i.CodArticolo) + .Distinct() + .ToList(); return dbResult; } @@ -572,6 +570,22 @@ namespace MP.Data.Controllers return dbResult; } + /// + /// Elenco Articoli che sono in KIT Child + /// + /// + public async Task> ArticoliInKitAsync() + { + List dbResult = new List(); + using var dbCtx = new MoonProContext(options); + dbResult = await dbCtx + .DbSetArticoli + .FromSqlRaw("EXEC stp_TempKIT_getArtChild") + .AsNoTracking() + .ToListAsync(); + return dbResult; + } + /// /// Update Record /// diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index c0efe24e..8f59e4d6 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2605.2813 + 8.16.2605.2814 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index 4bee3c34..a7cd6871 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                              Versione: 8.16.2605.2813

                                              +

                                              Versione: 8.16.2605.2814


                                              Note di rilascio:
                                              • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index 44370d54..6454cfbd 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2813 +8.16.2605.2814 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index 8607ff63..b834439b 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2813 + 8.16.2605.2814 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index ebb58f99..afca689d 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.2813 + 8.16.2605.2814 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 35048e17..a66dda6f 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                Versione: 8.16.2605.2813

                                                +

                                                Versione: 8.16.2605.2814


                                                Note di rilascio:
                                                • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 44370d54..6454cfbd 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2813 +8.16.2605.2814 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index f27bc7f5..5857f651 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2813 + 8.16.2605.2814 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 031dfb6e..4598fb26 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2605.2813 + 8.16.2605.2814 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 8a6e8d56..4870a12b 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                  Versione: 8.16.2605.2813

                                                  +

                                                  Versione: 8.16.2605.2814


                                                  Note di rilascio:
                                                    diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 44370d54..6454cfbd 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2813 +8.16.2605.2814 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index 20889b50..04e9d50e 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2813 + 8.16.2605.2814 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index 4785d316..105ef2d7 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2605.2813 + 8.16.2605.2814 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 27cc5bf1..4a3ba3b7 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                    Versione: 8.16.2605.2813

                                                    +

                                                    Versione: 8.16.2605.2814


                                                    Note di rilascio:
                                                    • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 44370d54..6454cfbd 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2813 +8.16.2605.2814 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index b7f7a499..7243b6d7 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2813 + 8.16.2605.2814 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 6bdfd81f..b97e8d09 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2605.2813 + 8.16.2605.2814 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index 6157c881..cf498c8a 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                                      Versione: 8.16.2605.2813

                                                      +

                                                      Versione: 8.16.2605.2814


                                                      Note di rilascio:
                                                        diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 44370d54..6454cfbd 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2813 +8.16.2605.2814 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index fcda10d7..85a76b76 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2813 + 8.16.2605.2814 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index 2d6e755f..c1490005 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2605.2813 + 8.16.2605.2814 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index 60808d02..49048720 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                        Versione: 8.16.2605.2813

                                                        +

                                                        Versione: 8.16.2605.2814


                                                        Note di rilascio:
                                                        • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index 44370d54..6454cfbd 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2813 +8.16.2605.2814 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index 3c7d9eba..c2fcb518 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2813 + 8.16.2605.2814 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 3c49b185..34d7a820 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -287,6 +287,23 @@ namespace MP.SPEC.Data ); } + /// + /// Elenco articoli contenuti in Kit (come child), non eliminabli + /// + /// + public async Task> ArticoliInKitAsync() + { + string redisKey = $"{Utils.redisArtList}:InKit"; + return await GetOrFetchAsync( + operationName: "ArticoliInKitAsync", + cacheKey: redisKey, + expiration: getRandTOut(redisLongTimeCache), + fetchFunc: async () => + await dbController.ArticoliInKitAsync() ?? new List(), + tagList: [Utils.redisArtList, $"{Utils.redisArtList}:InKit"] + ); + } + /// /// Restitusice elenco articoli cercati /// @@ -337,8 +354,8 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("ArticoloDelEnabled"); string codArticolo = $"{CodArt}"; - int numUsed = _usedArtIdsCache.Count; - int numUnused = _unusedArtIdsCache.Count; + int numUsed = _listCodArtUsed.Count; + int numUnused = _listCodArtNotUsed.Count; bool usato = true; string source = "MEMORY"; // 1. Controllo immediato sulla cache locale (HashSet) x eventuale refresh @@ -351,20 +368,24 @@ namespace MP.SPEC.Data task.Wait(); // rileggo - numUsed = _usedArtIdsCache.Count; - numUnused = _unusedArtIdsCache.Count; + numUsed = _listCodArtUsed.Count; + numUnused = _listCodArtNotUsed.Count; } // verifico quale sia l'elenco if (numUsed > 0) { - usato = _usedArtIdsCache.Contains(codArticolo); + usato = _listCodArtUsed.Contains(codArticolo); } else { - usato = !_unusedArtIdsCache.Contains(codArticolo); + usato = !_listCodArtNotUsed.Contains(codArticolo); + } + // verifico infine anche che NON sia nell'elenco degli articoli in KIT + if (!usato) + { + usato = _listCodArtInKit.Contains(CodArt); } - activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"ArticoloDelEnabled | Cod: {codArticolo} | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -726,7 +747,7 @@ namespace MP.SPEC.Data ///
                                          public async Task EnsureArtCacheLoadedAsync(bool forceReload) { - if (!forceReload && (DateTime.Now < _artCacheExpiry && (_usedArtIdsCache.Count > 0 || _unusedArtIdsCache.Count > 0))) + if (!forceReload && (DateTime.Now < _artCacheExpiry && (_listCodArtUsed.Count > 0 || _listCodArtNotUsed.Count > 0))) return; try @@ -738,16 +759,20 @@ namespace MP.SPEC.Data if (usedCount <= (totalCount - usedCount)) { var usedList = await dbController.ArticoliGetUsedAsync(); - _usedArtIdsCache = new HashSet(usedList.Select(x => x.CodArticolo)); - _unusedArtIdsCache.Clear(); + _listCodArtUsed = new HashSet(usedList.Select(x => x.CodArticolo)); + _listCodArtNotUsed.Clear(); } else { var unusedList = await dbController.ArticoliGetUnusedAsync(); - _unusedArtIdsCache = new HashSet(unusedList.Select(x => x.CodArticolo)); - _usedArtIdsCache.Clear(); + _listCodArtNotUsed = new HashSet(unusedList.Select(x => x.CodArticolo)); + _listCodArtUsed.Clear(); } - _artCacheExpiry = DateTime.Now.AddMinutes(15); // TTL ragionevole per la cache locale + // calcolo anche elenco articoli impiegati in istanzanKIT + var listInKit = await dbController.ArticoliInKitAsync(); + _listCodArtInKit = new HashSet(listInKit.Select(x => x.CodArticolo)); + + _artCacheExpiry = DateTime.Now.AddMinutes(5); // TTL ragionevole per la cache locale } catch (Exception ex) { @@ -2524,10 +2549,20 @@ namespace MP.SPEC.Data private Dictionary _configData = new(); - private HashSet _unusedArtIdsCache = new(); + /// + /// Elenco CodArticolo NON usati (per verifica eliminabilità) + /// + private HashSet _listCodArtNotUsed = new(); - // Cache per controllo eliminazione articoli (Smart HashSet approach) - private HashSet _usedArtIdsCache = new(); + /// + /// Elenco CodArticolo usati (per verifica eliminabilità) + /// + private HashSet _listCodArtUsed = new(); + + /// + /// Elenco CodArticolo usati in istanza KIT (per verifica eliminabilità) + /// + private HashSet _listCodArtInKit = new(); private string canCacheParametri = ""; diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index c7bb86f3..5b01670f 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2605.2813 + 8.16.2605.2814 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index 685536af..da0c952c 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                          Versione: 8.16.2605.2813

                                          +

                                          Versione: 8.16.2605.2814


                                          Note di rilascio:
                                            diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 44370d54..6454cfbd 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2813 +8.16.2605.2814 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index c19d4a3b..a68ee3ba 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2813 + 8.16.2605.2814 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false From 8d9c450ed962a343c4214380d7a3e2636c60fb3d Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 15:35:33 +0200 Subject: [PATCH 053/102] Update timing scadenza cache articoli non eliminabili --- MP.SPEC/Data/MpDataService.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 34d7a820..64bf7064 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -772,7 +772,7 @@ namespace MP.SPEC.Data var listInKit = await dbController.ArticoliInKitAsync(); _listCodArtInKit = new HashSet(listInKit.Select(x => x.CodArticolo)); - _artCacheExpiry = DateTime.Now.AddMinutes(5); // TTL ragionevole per la cache locale + _artCacheExpiry = DateTime.Now.AddMinutes(15); // TTL ragionevole per la cache locale } catch (Exception ex) { @@ -941,6 +941,7 @@ namespace MP.SPEC.Data { await _cache.ClearAsync(allowFailSafe: false); _configData.Clear(); + _artCacheExpiry = DateTime.Now.AddHours(-1); return true; } From 53910dcd6249e8ed002645d01c3c89a5382f4333 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 16:36:53 +0200 Subject: [PATCH 054/102] Ancora update x ottimizzazione gestione lista articoli e dati in cache vari --- MP.Core/Utils.cs | 1 + MP.SPEC/Components/ListDossiers.razor | 25 +++------- MP.SPEC/Components/ListDossiers.razor.cs | 22 ++++++--- MP.SPEC/Components/ListODL.razor.cs | 33 ++++++++++++- MP.SPEC/Components/SelArticolo.razor | 10 ++++ MP.SPEC/Components/SelArticolo.razor.cs | 61 ++++++++++++++++++++++++ MP.SPEC/Data/MpDataService.cs | 53 ++++++++++---------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- Refactor_Plan.md | 3 ++ 12 files changed, 160 insertions(+), 56 deletions(-) create mode 100644 MP.SPEC/Components/SelArticolo.razor create mode 100644 MP.SPEC/Components/SelArticolo.razor.cs diff --git a/MP.Core/Utils.cs b/MP.Core/Utils.cs index 318b63c9..07d3d6f9 100644 --- a/MP.Core/Utils.cs +++ b/MP.Core/Utils.cs @@ -31,6 +31,7 @@ namespace MP.Core public const string redisKitScore = redisBaseAddr + "Cache:Kit:Score"; public const string redisKitTempl = redisBaseAddr + "Cache:Kit:Templ"; public const string redisKitWip = redisBaseAddr + "Cache:Kit:Wip"; + public const string redisIobConf = redisBaseAddr + "Cache:IobConf"; public const string redisLinkMenu = redisBaseAddr + "Cache:LinkMenu"; public const string redisMacByFlux = redisBaseAddr + "Cache:MacByFlux"; diff --git a/MP.SPEC/Components/ListDossiers.razor b/MP.SPEC/Components/ListDossiers.razor index 8b233bdc..a497db87 100644 --- a/MP.SPEC/Components/ListDossiers.razor +++ b/MP.SPEC/Components/ListDossiers.razor @@ -79,8 +79,8 @@ else } - + @if (currRecordClone != null) { @@ -141,9 +141,10 @@ else
                                            - ARTICOLI - - + + @* + *@
                                            - -
                                            @@ -186,16 +185,9 @@ else
                                            } - - - - - - -
                                            @@ -344,8 +336,3 @@ else } - - - - - diff --git a/MP.SPEC/Components/ListDossiers.razor.cs b/MP.SPEC/Components/ListDossiers.razor.cs index fb2caf8c..778e8cb9 100644 --- a/MP.SPEC/Components/ListDossiers.razor.cs +++ b/MP.SPEC/Components/ListDossiers.razor.cs @@ -222,11 +222,6 @@ namespace MP.SPEC.Components } } - //prtected bool hasLic - //{ - // get => selAzienda == "GIACOVELLI"; - //} - protected override async Task OnInitializedAsync() { await MDService.ConfigResetCache(); @@ -234,11 +229,22 @@ namespace MP.SPEC.Components ListStati = await MDService.AnagStatiCommAsync(); selAzienda = await MDService.ConfigTryGetAsync("AZIENDA"); giacenzeConf = await MDService.ConfigTryGetAsync("SPEC_ShowGiacenze"); - ListArticoli = await MDService.ArticoliGetSearchAsync(100000, "*", selAzienda, ""); +#if false + ListArticoli = await MDService.ArticoliGetSearchAsync(100000, "*", selAzienda, ""); +#endif ListMacchine = await MDService.MacchineGetFiltAsync("*"); await ReloadData(true); } + /// + /// Ricerca articoli + /// + private string SearchArt = ""; + /// + /// Num min car x ricerca + /// + private int SearchMinChar = 3; + protected override async Task OnParametersSetAsync() { if (!lastFilter.Equals(SelFilter)) @@ -314,7 +320,9 @@ namespace MP.SPEC.Components private DossierModel? currRecordClone = null; - private List? ListArticoli; +#if false + private List? ListArticoli; +#endif private List? ListGruppiFase; private List? ListMacchine; diff --git a/MP.SPEC/Components/ListODL.razor.cs b/MP.SPEC/Components/ListODL.razor.cs index 7347ec53..dac1a05d 100644 --- a/MP.SPEC/Components/ListODL.razor.cs +++ b/MP.SPEC/Components/ListODL.razor.cs @@ -166,6 +166,7 @@ namespace MP.SPEC.Components /// protected bool HasFolderMan(string idxMacc) { +#if false bool answ = true; // cerco nella LUT if (MachHasFolderLut.ContainsKey(idxMacc)) @@ -182,9 +183,35 @@ namespace MP.SPEC.Components MachHasFolderLut.Add(idxMacc, answ); } } - return answ; + return answ; +#endif + return MachHasFolderLut.ContainsKey(idxMacc) ? MachHasFolderLut[idxMacc] : false; } + + private async Task ReloadLutData() + { + if (SearchRecords != null) + { + foreach (var item in SearchRecords) + { + string rawVal = ""; + bool answ = false; + var machData = await MDService.MachIobConfAsync(item.IdxMacchina); + if (machData.ContainsKey(KeyFolderMan)) + { + rawVal = machData[KeyFolderMan]; + if (rawVal != null) + { + bool.TryParse((string)rawVal, out answ); + MachHasFolderLut.Add(item.IdxMacchina, answ); + } + } + } + } + } + + protected async Task KitToggleDetailAsync(string? selCodArt) { if (!string.IsNullOrEmpty(selCodArt)) @@ -359,10 +386,12 @@ namespace MP.SPEC.Components isLoading = true; SearchRecords = await MDService.OdlListGetFilt(currFilter.IsActive, currFilter.SearchVal, currFilter.CodFase, currFilter.CodReparto, currFilter.IdxMacchina, currFilter.DtStart, currFilter.DtEnd); await ReloadPOdlData(); + await ReloadLutData(); totalCount = SearchRecords.Count; ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); isLoading = false; } + private Dictionary _podlLocalCache = new(); private async Task ReloadPOdlData() { @@ -373,7 +402,7 @@ namespace MP.SPEC.Components var tasks = SearchRecords.Select(async odl => { int podl = 0; - var pOdlData = await MDService.POdlGetByOdlAsync(odl.IdxOdl); // Tua nuova versione Async + var pOdlData = await MDService.POdlGetByOdlAsync(odl.IdxOdl); if (pOdlData != null) { podl = pOdlData.IdxPromessa; diff --git a/MP.SPEC/Components/SelArticolo.razor b/MP.SPEC/Components/SelArticolo.razor new file mode 100644 index 00000000..996f21b6 --- /dev/null +++ b/MP.SPEC/Components/SelArticolo.razor @@ -0,0 +1,10 @@ + \ No newline at end of file diff --git a/MP.SPEC/Components/SelArticolo.razor.cs b/MP.SPEC/Components/SelArticolo.razor.cs new file mode 100644 index 00000000..dd26d88b --- /dev/null +++ b/MP.SPEC/Components/SelArticolo.razor.cs @@ -0,0 +1,61 @@ +using Microsoft.AspNetCore.Components; +using MP.Data.DbModels; +using MP.SPEC.Data; + +namespace MP.SPEC.Components +{ + public partial class SelArticolo + { + // Parametri per il Two-Way Data Binding + [Parameter] + public string Value { get; set; } + + [Parameter] + public EventCallback ValueChanged { get; set; } + + // Parametri di filtro + [Parameter] + public string SearchVal { get; set; } = ""; + [Parameter] + public string SelAzienda { get; set; } = "*"; + + [Inject] + protected MpDataService MDService { get; set; } = null!; + + private List? ListArticoli; + + // Variabili di appoggio per tracciare il cambio dei filtri + private string _oldSearchVal = string.Empty; + private string _oldSelAzienda = string.Empty; + + private int maxNum = 100; + + protected override async Task OnInitializedAsync() + { + await CaricaArticoli(); + } + + protected override async Task OnParametersSetAsync() + { + if (SearchVal != _oldSearchVal || SelAzienda != _oldSelAzienda) + { + _oldSearchVal = SearchVal; + _oldSelAzienda = SelAzienda; + + await CaricaArticoli(); + } + } + + private async Task CaricaArticoli() + { + ListArticoli = await MDService.ArticoliGetSearchAsync(maxNum, "*", SelAzienda, SearchVal); + } + + private async Task OnSelectionChanged(ChangeEventArgs e) + { + Value = e.Value?.ToString(); + // Notifica il componente padre della variazione + await ValueChanged.InvokeAsync(Value); + } + } +} \ No newline at end of file diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 64bf7064..cab5679e 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1503,50 +1503,55 @@ namespace MP.SPEC.Data /// /// /// - public Dictionary MachIobConf(string IdxMacchina) + public async Task> MachIobConfAsync(string IdxMacchina) { - using var activity = ActivitySource.StartActivity("MachIobConf"); + string redisKey = Utils.redisIobConf; + + return await GetOrFetchAsync( + operationName: "MachIobConfAsync", + cacheKey: redisKey, + expiration: getRandTOut(redisShortTimeCache), + fetchFunc: async () => + { + Dictionary result = new Dictionary(); + // cerco in redis... + string currKey = redHashMpIO($"IOB:{IdxMacchina}:MachIobConfAsync"); + if (await redisDb.KeyExistsAsync(currKey)) + { + result = (await redisDb.HashGetAllAsync(currKey)) + .ToDictionary(x => $"{x.Name}", x => $"{x.Value}"); + } + return result; + }, + tagList: [Utils.redisIobConf] + ); +#if false + using var activity = ActivitySource.StartActivity("MachIobConfAsync"); string source = "DB"; Dictionary result = new Dictionary(); // cerco in redis... - string currKey = redHashMpIO($"IOB:{IdxMacchina}:MachIobConf"); + string currKey = redHashMpIO($"IOB:{IdxMacchina}:MachIobConfAsync"); try { - result = redisDb - .HashGetAll(currKey) + result = (await redisDb.HashGetAllAsync(currKey)) .ToDictionary(x => $"{x.Name}", x => $"{x.Value}"); source = "REDIS"; } catch (Exception exc) { - Log.Error($"Errore in MachIobConf{Environment.NewLine}{exc}"); + Log.Error($"Errore in MachIobConfAsync{Environment.NewLine}{exc}"); } if (result == null) { result = new Dictionary(); - LogTrace($"Init valore default MachIobConf | IdxMacchina: {IdxMacchina}"); + LogTrace($"Init valore default MachIobConfAsync | IdxMacchina: {IdxMacchina}"); } activity?.SetTag("data.source", source); activity?.SetTag("result.count", result.Count); activity?.Stop(); - LogTrace($"MachIobConf per {IdxMacchina} | {source} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"MachIobConfAsync per {IdxMacchina} | {source} | {activity?.Duration.TotalMilliseconds}ms"); return result; - } - - /// - /// Recupero singolo recordo info Machine-IOB x TAB (da info registrate IOB-WIN --> MP-IO) - /// - /// - /// - public string MachIobConfVal(string IdxMacchina, string Key) - { - string answ = ""; - var currList = MachIobConf(IdxMacchina); - if (currList.ContainsKey(Key)) - { - answ = currList[Key]; - } - return answ; +#endif } /// diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 89bc4b9e..374536c4 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2814 + 8.16.2605.2816 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 4a3ba3b7..cd4875b2 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                            Versione: 8.16.2605.2814

                                            +

                                            Versione: 8.16.2605.2816


                                            Note di rilascio:
                                            • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 6454cfbd..d0d2d8ea 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2814 +8.16.2605.2816 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 8c6b95c1..964f1191 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2814 + 8.16.2605.2816 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/Refactor_Plan.md b/Refactor_Plan.md index b39f393f..59363611 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -44,6 +44,9 @@ I metodi verranno suddivisi in: - [x] `POdlGetByOdlAsync` - [x] `FluxLogGetLastFiltAsync` - [x] `FluxLogParetoAsync` +- [x] `OperatoriGetFiltAsync` +- [x] `MacchineRecipeArchiveAsync` +- [x] `MacchineRecipeConfAsync` - [ ] `AnagEventiGeneral` - [ ] `AnagEventiGetByMacch` - [ ] `AnagKeyValGetAll` From e0d0f7b493f93077f90bb6953387a924a896925c Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 16:54:27 +0200 Subject: [PATCH 055/102] Update conf scadenze rapide/lunghe x cache --- MP.Core/Utils.cs | 1 + MP.SPEC/Data/MpDataService.cs | 13 +++++++------ MP.SPEC/appsettings.Development.json | 1 - MP.SPEC/appsettings.Production.json | 3 ++- MP.SPEC/appsettings.Staging.json | 1 - MP.SPEC/appsettings.json | 3 ++- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/MP.Core/Utils.cs b/MP.Core/Utils.cs index 07d3d6f9..6d978777 100644 --- a/MP.Core/Utils.cs +++ b/MP.Core/Utils.cs @@ -17,6 +17,7 @@ namespace MP.Core public const string redisArtList = redisBaseAddr + "Cache:ArtList"; public const string redisBaseAddr = "MP:"; public const string redisConfFlux = redisBaseAddr + "Cache:ConfFlux"; + public const string redisConfAll = redisBaseAddr + "Cache:ConfigAll"; public const string redisConfKey = redisBaseAddr + "Cache:Config"; public const string redisDecNumArtKey = redisBaseAddr + "Cache:DecNumArt"; public const string redisDossByMac = redisBaseAddr + "Cache:DossByMac"; diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index cab5679e..844322fd 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -34,7 +34,8 @@ namespace MP.SPEC.Data redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis") ?? "localhost:6379"); redisConnAdmin = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("RedisAdmin") ?? "localhost:6379"); redisDb = redisConn.GetDatabase(); - // leggo cache lungo periodo + // leggo cache lungo/cordo periodo + int.TryParse(_configuration.GetValue("ServerConf:redisShortTimeCache"), out redisShortTimeCache); int.TryParse(_configuration.GetValue("ServerConf:redisLongTimeCache"), out redisLongTimeCache); // setup MsgPipe @@ -410,7 +411,7 @@ namespace MP.SPEC.Data string source = "REDIS"; List? result = new List(); // cerco in redis... - RedisValue rawData = redisDb.StringGet(Utils.redisConfKey); + RedisValue rawData = redisDb.StringGet($"{Utils.redisConfKey}_sync"); if (!string.IsNullOrEmpty($"{rawData}")) { result = JsonConvert.DeserializeObject>($"{rawData}"); @@ -421,7 +422,7 @@ namespace MP.SPEC.Data result = dbController.ConfigGetAll(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(Utils.redisConfKey, rawData, getRandTOut(redisLongTimeCache)); + redisDb.StringSet($"{Utils.redisConfKey}_sync", rawData, getRandTOut(redisLongTimeCache)); } if (result == null) { @@ -442,10 +443,10 @@ namespace MP.SPEC.Data { return await GetOrFetchAsync( operationName: "ConfigGetAllAsync", - cacheKey: Utils.redisConfKey, - expiration: getRandTOut(redisLongTimeCache), + cacheKey: Utils.redisConfAll, + expiration: getRandTOut(redisLongTimeCache * 2), fetchFunc: async () => await dbController.ConfigGetAllAsync() ?? new List(), - tagList: [Utils.redisConfKey] + tagList: [Utils.redisConfAll] ); } diff --git a/MP.SPEC/appsettings.Development.json b/MP.SPEC/appsettings.Development.json index de8e232d..8c2753ce 100644 --- a/MP.SPEC/appsettings.Development.json +++ b/MP.SPEC/appsettings.Development.json @@ -14,7 +14,6 @@ "ServerConf": { "maxAge": "2000", "cacheCheckArtUsato": 2, - "redisLongTimeCache": 15, "MpIoBaseUrl": "https://iis01.egalware.com/MP/IO/" } } diff --git a/MP.SPEC/appsettings.Production.json b/MP.SPEC/appsettings.Production.json index 07c7752c..1424dd3f 100644 --- a/MP.SPEC/appsettings.Production.json +++ b/MP.SPEC/appsettings.Production.json @@ -27,7 +27,8 @@ "ServerConf": { "maxAge": "2000", "cacheCheckArtUsato": 2, - "redisLongTimeCache": 15, + "redisShortTimeCache": 10, + "redisLongTimeCache": 600, "MpIoBaseUrl": "http://localhost/MP/IO/", "MpIoNS": "MoonPro:SQL2016DEV:MoonPro", "BasePathOdlReturn": "\\\\iis01\\W$\\Files\\ODL", diff --git a/MP.SPEC/appsettings.Staging.json b/MP.SPEC/appsettings.Staging.json index d61f5682..531d2258 100644 --- a/MP.SPEC/appsettings.Staging.json +++ b/MP.SPEC/appsettings.Staging.json @@ -14,7 +14,6 @@ "ServerConf": { "maxAge": "2000", "cacheCheckArtUsato": 2, - "redisLongTimeCache": 15, "MpIoBaseUrl": "http://localhost/MP/IO/" } } diff --git a/MP.SPEC/appsettings.json b/MP.SPEC/appsettings.json index 712e6fcb..ff3e5c10 100644 --- a/MP.SPEC/appsettings.json +++ b/MP.SPEC/appsettings.json @@ -68,7 +68,8 @@ "ServerConf": { "maxAge": "2000", "cacheCheckArtUsato": "2", - "redisLongTimeCache": "15", + "redisShortTimeCache": 5, + "redisLongTimeCache": 120, "MpIoBaseUrl": "http://localhost:20967/", "MpIoNS": "MoonPro:SQL2016DEV:MoonPro", "BasePathOdlReturn": "\\\\iis01\\ODL\\ftpdata\\syncfolder", From 6b49cb29fe697943d8ef8d6cc3fda32db739a496 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 18:49:10 +0200 Subject: [PATCH 056/102] Ancora updaate caching e gestione oggetti --- MP.Data/Controllers/MpSpecController.cs | 62 ++++--- MP.Data/Services/TabDataService.cs | 2 +- MP.SPEC/Components/DossiersFilter.razor | 24 +-- MP.SPEC/Components/DossiersFilter.razor.cs | 47 +++--- MP.SPEC/Components/ListODL.razor.cs | 6 +- MP.SPEC/Components/ParamsFilter.razor.cs | 4 +- MP.SPEC/Data/MpDataService.cs | 166 +++++++++++++------ MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Articoli.razor | 9 +- MP.SPEC/Pages/DOSS.razor | 25 +-- MP.SPEC/Pages/DOSS.razor.cs | 6 +- MP.SPEC/Pages/RepStop.razor.cs | 4 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- MP.SPEC/appsettings.Production.json | 1 + MP.SPEC/appsettings.json | 1 + Refactor_Plan.md | 184 ++++++--------------- 18 files changed, 281 insertions(+), 268 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 63e33058..dd60d20d 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -2124,22 +2124,18 @@ namespace MP.Data.Controllers ///
                                            /// /// - public List ParametriGetFilt(string IdxMacchina) + public async Task> ParametriGetFiltAsync(string IdxMacchina) { - List dbResult = new List(); - using (var dbCtx = new MoonPro_FluxContext(_configuration)) - { - dbResult = dbCtx - .DbSetFluxLog - .AsNoTracking() - .Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina)) - .Take(1000) - .Select(i => i.CodFlux) - .Distinct() - .OrderBy(x => x) - .ToList(); - } - return dbResult; + using var dbCtx = new MoonPro_FluxContext(_configuration); + return await dbCtx + .DbSetFluxLog + .AsNoTracking() + .Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina)) + .Take(1000) + .Select(i => i.CodFlux) + .Distinct() + .OrderBy(x => x) + .ToListAsync(); } /// @@ -2205,6 +2201,24 @@ namespace MP.Data.Controllers .FirstOrDefaultAsync() ?? new(); } + /// + /// Dizionario associazione ODL/PODL + /// + /// + /// + public async Task> PODL_getDictOdlPodl(List missingIds) + { + if (missingIds == null || !missingIds.Any()) + return new Dictionary(); + + using var dbCtx = new MoonProContext(options); + return await dbCtx + .DbSetPODL + .AsNoTracking() + .Where(x => missingIds.Contains(x.IdxOdl)) + .ToDictionaryAsync(x => x.IdxOdl, x => x.IdxPromessa); + } + /// /// Avvio setup ODL da PODL /// @@ -2451,18 +2465,14 @@ namespace MP.Data.Controllers /// /// /// - public StatoMacchineModel StatoMacchina(string idxMacchina) + public async Task StatoMacchinaAsync(string idxMacchina) { - StatoMacchineModel dbResult = new StatoMacchineModel(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbSetStatoMacc - .Where(x => x.IdxMacchina == idxMacchina) - .AsNoTracking() - .FirstOrDefault(); - } - return dbResult; + using var dbCtx = new MoonProContext(options); + return await dbCtx + .DbSetStatoMacc + .Where(x => x.IdxMacchina == idxMacchina) + .AsNoTracking() + .FirstOrDefaultAsync(); } /// diff --git a/MP.Data/Services/TabDataService.cs b/MP.Data/Services/TabDataService.cs index f16614b2..2b6f631d 100644 --- a/MP.Data/Services/TabDataService.cs +++ b/MP.Data/Services/TabDataService.cs @@ -3417,7 +3417,7 @@ namespace MP.Data.Services result = new StatoMacchineModel(); } sw.Stop(); - Log.Debug($"StatoMacchina | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + Log.Debug($"StatoMacchinaAsync | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } diff --git a/MP.SPEC/Components/DossiersFilter.razor b/MP.SPEC/Components/DossiersFilter.razor index 4c5528a4..93ef3275 100644 --- a/MP.SPEC/Components/DossiersFilter.razor +++ b/MP.SPEC/Components/DossiersFilter.razor @@ -5,13 +5,13 @@
                                            @**@ @if (selMacchina != "*") - { - - } - @if (selArticolo != "*") - { - - } + { + + } + @if (selArticolo != "*") + { + + }
                                            }
                                            @@ -34,7 +34,7 @@
                                            - @if (ListArticoli != null) { @@ -50,7 +50,7 @@
                                            - @if (ListMacchine != null) { @@ -67,14 +67,14 @@
                                            - +
                                            - +
                                            @@ -82,7 +82,7 @@
                                            - +
                                            diff --git a/MP.SPEC/Components/DossiersFilter.razor.cs b/MP.SPEC/Components/DossiersFilter.razor.cs index 3f4f0d11..a061c8c7 100644 --- a/MP.SPEC/Components/DossiersFilter.razor.cs +++ b/MP.SPEC/Components/DossiersFilter.razor.cs @@ -30,26 +30,11 @@ namespace MP.SPEC.Components { if (!SelFilterDossier.CodArticolo.Equals(value)) { - SelFilterDossier.CurrPage = 1; SelFilterDossier.CodArticolo = value; - StateHasChanged(); - Task.Delay(1); - reportChange(); } } } - private bool filtActive - { - get => selMacchina != "*" || selArticolo != "*"; - } - protected void resetMacchina() - { - selMacchina = "*"; - } - protected void resetArticolo() - { - selArticolo = "*"; - } + protected DateTime selDtMax { get @@ -62,7 +47,6 @@ namespace MP.SPEC.Components if (!SelFilterDossier.DtEnd.Equals(value)) { SelFilterDossier.DtEnd = value; - reportChange(); } } } @@ -79,7 +63,6 @@ namespace MP.SPEC.Components if (!SelFilterDossier.DtStart.Equals(value)) { SelFilterDossier.DtStart = value; - reportChange(); } } } @@ -94,11 +77,7 @@ namespace MP.SPEC.Components { if (!SelFilterDossier.IdxMacchina.Equals(value)) { - SelFilterDossier.CurrPage = 1; SelFilterDossier.IdxMacchina = value; - StateHasChanged(); - Task.Delay(1); - reportChange(); } } } @@ -115,7 +94,6 @@ namespace MP.SPEC.Components if (!SelFilterDossier.MaxRecord.Equals(value)) { SelFilterDossier.MaxRecord = value; - reportChange(); } } } @@ -128,8 +106,6 @@ namespace MP.SPEC.Components protected override async Task OnInitializedAsync() { - SelFilterDossier = new SelectDossierParams(); - SelFilterDossier.MaxRecord = 1000; DateTime dtEnd = SelFilterDossier.DtEnd; DateTime dtStart = dtEnd.Subtract(SelFilterDossier.DtStart).TotalDays < 15 ? SelFilterDossier.DtStart : dtEnd.AddDays(-14); ListMacchine = await MDService.MacchineWithFluxAsync(dtStart, dtEnd); @@ -137,6 +113,16 @@ namespace MP.SPEC.Components await FilterChanged.InvokeAsync(SelFilterDossier); } + protected void resetArticolo() + { + selArticolo = "*"; + } + + protected void resetMacchina() + { + selMacchina = "*"; + } + protected void toggleParams() { showEditPar = !showEditPar; @@ -147,21 +133,28 @@ namespace MP.SPEC.Components #region Private Fields private List? ListArticoli = null; + private List? ListMacchine = null; #endregion Private Fields #region Private Properties + private bool filtActive + { + get => selMacchina != "*" || selArticolo != "*"; + } + private bool showEditPar { get; set; } = false; #endregion Private Properties #region Private Methods - private void reportChange() + private Task ReportChangeAsync() { - FilterChanged.InvokeAsync(SelFilterDossier); + SelFilterDossier.CurrPage = 1; + return FilterChanged.InvokeAsync(SelFilterDossier); } private void toggleShowParams() diff --git a/MP.SPEC/Components/ListODL.razor.cs b/MP.SPEC/Components/ListODL.razor.cs index dac1a05d..55e93867 100644 --- a/MP.SPEC/Components/ListODL.razor.cs +++ b/MP.SPEC/Components/ListODL.razor.cs @@ -398,6 +398,9 @@ namespace MP.SPEC.Components _podlLocalCache.Clear(); if (SearchRecords != null) { + var listIdx = SearchRecords.Select(x => x.IdxOdl).ToList(); + _podlLocalCache = await MDService.PODL_getDictOdlPodl(listIdx); +#if false // 1. Popolo la cache locale in parallelo sfruttando la velocità di FusionCache var tasks = SearchRecords.Select(async odl => { @@ -413,7 +416,8 @@ namespace MP.SPEC.Components var infoSalvate = await Task.WhenAll(tasks); // 2. Trasformazione dei risultati in un dizionario per l'accesso immediato (O(1)) nell'HTML - _podlLocalCache = infoSalvate.ToDictionary(x => x.IdxOdl, x => x.podl); + _podlLocalCache = infoSalvate.ToDictionary(x => x.IdxOdl, x => x.podl); +#endif } } diff --git a/MP.SPEC/Components/ParamsFilter.razor.cs b/MP.SPEC/Components/ParamsFilter.razor.cs index f2507145..ad7246bb 100644 --- a/MP.SPEC/Components/ParamsFilter.razor.cs +++ b/MP.SPEC/Components/ParamsFilter.razor.cs @@ -109,7 +109,7 @@ namespace MP.SPEC.Components SelFilter.CurrPage = 1; SelFilter.IdxMacchina = value; SelFilter.CodFlux = "*"; - ListFlux = MDService.ParametriGetFilt(selMacchina).Result; + ListFlux = MDService.ParametriGetFiltAsync(selMacchina).Result; StateHasChanged(); Task.Delay(1); reportChange(); @@ -182,7 +182,7 @@ namespace MP.SPEC.Components DateTime dtStart = SelFilter.dtMin != null ? (DateTime)SelFilter.dtMin : DateTime.Now.AddMonths(-1); DateTime dtEnd = SelFilter.dtMax != null ? (DateTime)SelFilter.dtMax : DateTime.Today.AddDays(1); ListMacchine = await MDService.MacchineWithFluxAsync(dtStart, dtEnd); - ListFlux = await MDService.ParametriGetFilt(selMacchina); + ListFlux = await MDService.ParametriGetFiltAsync(selMacchina); var configData = await MDService.ConfigGetAllAsync(); var currRec = configData.FirstOrDefault(x => x.Chiave == "numOreAnticipoSnapshot"); diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 844322fd..01c92078 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -28,6 +28,7 @@ namespace MP.SPEC.Data _cache = cache; // Verifica conf trace... traceEnabled = _configuration.GetValue("Otel:EnableTracing", false); + slowLogThresh = _configuration.GetValue("ServerConf:slowLogThresh", 1); Log.Info($"MpDataService | INIT | Trace enabled: {traceEnabled}"); // setup compoenti REDIS @@ -389,7 +390,10 @@ namespace MP.SPEC.Data } activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ArticoloDelEnabled | Cod: {codArticolo} | {source} | {activity?.Duration.TotalMilliseconds}ms"); + if (activity?.Duration.TotalMilliseconds > slowLogThresh) + { + LogTrace($"ArticoloDelEnabled | Cod: {codArticolo} | {source} | {activity?.Duration.TotalMilliseconds}ms"); + } return !usato; } @@ -480,8 +484,10 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.Stop(); - - LogTrace($"ConfigTryGet Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + if (activity?.Duration.TotalMilliseconds > slowLogThresh) + { + LogTrace($"ConfigTryGet | {keyName} | {source} | {activity?.Duration.TotalMilliseconds}ms"); + } return value ?? ""; } @@ -501,8 +507,10 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.Stop(); - - LogTrace($"ConfigTryGetAsync | {keyName} | {source} | {activity?.Duration.TotalMilliseconds}ms"); + if (activity?.Duration.TotalMilliseconds > slowLogThresh) + { + LogTrace($"ConfigTryGetAsync | {keyName} | {source} | {activity?.Duration.TotalMilliseconds}ms"); + } return value ?? ""; } @@ -1754,35 +1762,16 @@ namespace MP.SPEC.Data ///
                                            /// * = tutte, altrimenti solo x una data idxMaccSel /// - public async Task> ParametriGetFilt(string IdxMacchina) + public async Task> ParametriGetFiltAsync(string IdxMacchina) { - using var activity = ActivitySource.StartActivity("ParametriGetFilt"); - List? result = new List(); - string source = "DB"; string currKey = $"{Utils.redisFluxByMac}:{IdxMacchina}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "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(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"ParametriGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + return await GetOrFetchAsync( + operationName: "ParametriGetFiltAsync", + cacheKey: currKey, + expiration: getRandTOut(redisShortTimeCache), + fetchFunc: async () => await dbController.ParametriGetFiltAsync(IdxMacchina) ?? new(), + tagList: [Utils.redisFluxByMac] + ); } /// @@ -1885,6 +1874,75 @@ namespace MP.SPEC.Data ); } + /// + /// Restituisce dizionario ODL/PODL data lista IdxOdl + /// + /// + /// + public async Task> PODL_getDictOdlPodl(List idxOdlList) + { + if (idxOdlList == null || !idxOdlList.Any()) + return new Dictionary(); + + var distinctIds = idxOdlList.Distinct().ToList(); + + var resultDictionary = new Dictionary(); + var missingIds = new List(); + + // STEP 1: Controllo rapido in FusionCache (L1/Memory cache) + foreach (var id in distinctIds) + { + var cacheKey = $"val:{id}"; + var cachedValue = await _cache.TryGetAsync(cacheKey); + + if (cachedValue.HasValue) + { + resultDictionary[id] = cachedValue.Value; + } + else + { + // ID non presente in cache, andrà cercato tramite il servizio EF + missingIds.Add(id); + } + } + + // STEP 2: Se ci sono cache miss, interroghiamo il servizio EF Core + if (missingIds.Any()) + { + // Riceviamo direttamente un Dictionary ottimizzato da EF Core + Dictionary dbResults = await dbController.PODL_getDictOdlPodl(missingIds); + + // STEP 3: Scriviamo i risultati in cache e li uniamo al dizionario finale + foreach (var kvp in dbResults) + { + var id = kvp.Key; + var targetValue = kvp.Value; + + resultDictionary[id] = targetValue; + + // Salvataggio atomico e globale su FusionCache + var cacheKey = $"val:{id}"; + await _cache.SetAsync(cacheKey, targetValue, TimeSpan.FromMinutes(30)); + } + + // STEP 4 [Altamente Consigliato]: Cache Penetration Protection + // Se un ID era tra i "missing" ma NON è presente nei risultati del DB, significa che non esiste. + // Salviamo un valore sentinella (es. 0 o -1) per evitare di ricontrollare il DB al prossimo giro. + foreach (var id in missingIds) + { + if (!dbResults.ContainsKey(id)) + { + resultDictionary[id] = 0; // Imposta un default per l'output corrente + + var cacheKey = $"val:{id}"; + await _cache.SetAsync(cacheKey, 0, TimeSpan.FromMinutes(2)); // Scadenza breve per i record inesistenti + } + } + } + + return resultDictionary; + } + /// /// Effettua il task di eliminazione PODL KIT + istanze + riattivazione PODL originali disattivate tramite stored /// @@ -2200,15 +2258,25 @@ namespace MP.SPEC.Data /// /// /// - public StatoMacchineModel StatoMacchina(string idxMacchina) + public async Task StatoMacchinaAsync(string idxMacchina) { - using var activity = ActivitySource.StartActivity("StatoMacchina"); + string currKey = $"{Utils.redisStatoMacch}:{idxMacchina}"; + + return await GetOrFetchAsync( + operationName: "StatoMacchinaAsync", + cacheKey: currKey, + expiration: getRandTOut(redisLongTimeCache), + fetchFunc: async () => await dbController.StatoMacchinaAsync(idxMacchina) ?? new(), + tagList: [Utils.redisStatoMacch] + ); +#if false + using var activity = ActivitySource.StartActivity("StatoMacchinaAsync"); // setup parametri costanti string source = "DB"; StatoMacchineModel? result = new StatoMacchineModel(); // cerco in redisConn... string currKey = $"{Utils.redisStatoMacch}:{idxMacchina}"; - RedisValue rawData = redisDb.StringGet(currKey); + RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject($"{rawData}"); @@ -2219,7 +2287,7 @@ namespace MP.SPEC.Data result = dbController.StatoMacchina(idxMacchina); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(1)); + await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(1)); } if (result == null) { @@ -2227,8 +2295,9 @@ namespace MP.SPEC.Data } activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"StatoMacchina | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return result; + LogTrace($"StatoMacchinaAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return result; +#endif } /// @@ -2259,23 +2328,15 @@ namespace MP.SPEC.Data /// public async Task> TemplateKitFiltAsync(string codParent, string codChild) { - using var activity = ActivitySource.StartActivity("TemplateKitFiltAsync"); - string source = "DB"; string currKey = $"{Utils.redisKitTempl}:{codParent}:{codChild}"; - var result = await GetOrFetchAsync( + return await GetOrFetchAsync( operationName: "TemplateKitFiltAsync", cacheKey: currKey, expiration: getRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.TemplateKitFiltAsync(codParent, codChild) ?? new List(), tagList: [Utils.redisKitTempl] ); - - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"TemplateKitFiltAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return result; } /// @@ -2649,6 +2710,11 @@ namespace MP.SPEC.Data } } + /// + /// Soglia minima (ms) per log timing in console + /// + private double slowLogThresh = 0; + /// /// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria + tracking attività /// @@ -2669,7 +2735,11 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); + // se supero la soglia loggo... + if (activity?.Duration.TotalMilliseconds > slowLogThresh) + { + LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); + } return result; } bool fromDb = false; diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 374536c4..37b640a7 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2816 + 8.16.2605.2818 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Articoli.razor b/MP.SPEC/Pages/Articoli.razor index 6d484868..b6acc65c 100644 --- a/MP.SPEC/Pages/Articoli.razor +++ b/MP.SPEC/Pages/Articoli.razor @@ -116,7 +116,14 @@ { foreach (var item in ListTipoArt) { - + if (item.value.Equals("KIT")) + { + + } + else + { + + } } } diff --git a/MP.SPEC/Pages/DOSS.razor b/MP.SPEC/Pages/DOSS.razor index 202c48f5..f6ac1afa 100644 --- a/MP.SPEC/Pages/DOSS.razor +++ b/MP.SPEC/Pages/DOSS.razor @@ -6,16 +6,21 @@

                                            DOSSIERS

                                            -
                                            - @if (isFiltering) - { - - filtro x macchina / periodo - } - else - { - - } +
                                            +
                                            +
                                            max rec: @currFilter.MaxRecord
                                            +
                                            + @if (isFiltering) + { + + filtro x macchina / periodo + } + else + { + + } +
                                            +
                                            diff --git a/MP.SPEC/Pages/DOSS.razor.cs b/MP.SPEC/Pages/DOSS.razor.cs index 7e7198e4..7b0eaccc 100644 --- a/MP.SPEC/Pages/DOSS.razor.cs +++ b/MP.SPEC/Pages/DOSS.razor.cs @@ -1,9 +1,8 @@ +using EgwCoreLib.Razor; using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; using MP.Data.DbModels; -using MP.SPEC.Components; using MP.SPEC.Data; -using EgwCoreLib.Razor; namespace MP.SPEC.Pages { @@ -43,7 +42,6 @@ namespace MP.SPEC.Pages isLoading = true; isFiltering = true; // fix pagina - await Task.Delay(1); var modFilter = currFilter; modFilter.CurrPage = 1; currFilter = modFilter; @@ -71,7 +69,7 @@ namespace MP.SPEC.Pages #region Private Properties - private SelectDossierParams currFilter { get; set; } = new SelectDossierParams(); + private SelectDossierParams currFilter = new SelectDossierParams() { MaxRecord = 200, CurrPage = 1 }; private int currPage { diff --git a/MP.SPEC/Pages/RepStop.razor.cs b/MP.SPEC/Pages/RepStop.razor.cs index 20317090..846538ff 100644 --- a/MP.SPEC/Pages/RepStop.razor.cs +++ b/MP.SPEC/Pages/RepStop.razor.cs @@ -136,7 +136,7 @@ namespace MP.SPEC.Pages foreach (var idxMacc in CurrMachSel) { DateTime adesso = DateTime.Now.Floor(TimeSpan.FromSeconds(1)); - var rigaStato = MDService.StatoMacchina(idxMacc); + var rigaStato = await MDService.StatoMacchinaAsync(idxMacc); string valData = $"SPEC | FRep.Fine | {MService.DomainName}\\{MService.UserName}"; // chiamo stored @@ -175,7 +175,7 @@ namespace MP.SPEC.Pages // se conferma ciclo x ogni macchina e registro foreach (var idxMacc in CurrMachSel) { - var rigaStato = MDService.StatoMacchina(idxMacc); + var rigaStato = await MDService.StatoMacchinaAsync(idxMacc); // preparo info utente x Value... string valData = $"SPEC | FRep.Inizio | {MService.DomainName}\\{MService.UserName}"; diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index cd4875b2..83fcea16 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                            Versione: 8.16.2605.2816

                                            +

                                            Versione: 8.16.2605.2818


                                            Note di rilascio:
                                            • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index d0d2d8ea..dc9f3309 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2816 +8.16.2605.2818 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 964f1191..7314d35a 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2816 + 8.16.2605.2818 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/appsettings.Production.json b/MP.SPEC/appsettings.Production.json index 1424dd3f..f4ebc6a0 100644 --- a/MP.SPEC/appsettings.Production.json +++ b/MP.SPEC/appsettings.Production.json @@ -29,6 +29,7 @@ "cacheCheckArtUsato": 2, "redisShortTimeCache": 10, "redisLongTimeCache": 600, + "slowLogThresh": 200, "MpIoBaseUrl": "http://localhost/MP/IO/", "MpIoNS": "MoonPro:SQL2016DEV:MoonPro", "BasePathOdlReturn": "\\\\iis01\\W$\\Files\\ODL", diff --git a/MP.SPEC/appsettings.json b/MP.SPEC/appsettings.json index ff3e5c10..683abe14 100644 --- a/MP.SPEC/appsettings.json +++ b/MP.SPEC/appsettings.json @@ -70,6 +70,7 @@ "cacheCheckArtUsato": "2", "redisShortTimeCache": 5, "redisLongTimeCache": 120, + "slowLogThresh": 1, "MpIoBaseUrl": "http://localhost:20967/", "MpIoNS": "MoonPro:SQL2016DEV:MoonPro", "BasePathOdlReturn": "\\\\iis01\\ODL\\ftpdata\\syncfolder", diff --git a/Refactor_Plan.md b/Refactor_Plan.md index 59363611..9bf60fed 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -3,143 +3,67 @@ ## Obiettivo Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCache` per implementare un approccio multi-layer (Memory + Redis + DB), standardizzando l'accesso ai dati. -## Analisi dello stato attuale -- **Classe target**: `MP.SPEC\Data\MpDataService.cs` -- **Pattern attuale**: Molti metodi utilizzano manualmente `redisDb.StringGetAsync` e `redisDb.StringSetAsync` con serializzazione JSON manuale. -- **Metodo Standard**: `GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tags)`. - ## Strategia di Migrazione +- **Metodo Standard**: `GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tagList)`. +- **Invalidazione**: Utilizzare i tag tramite `FlushCacheByTagsAsync`. -### 1. Identificazione Metodi Target -Andrò a mappare tutti i metodi in `MpDataService.cs` che: -- Utilizzano `redisDb` direttamente per la lettura/scrittura. -- Gestiscono manualmente la serializzazione/deserializzazione con `JsonConvert`. -- Gestiscono manualmente il fallback dal Redis al DB. +## Stato Avanzamento -### 2. Classificazione Metodi -I metodi verranno suddivisi in: -- **Lettura (Cache-aside)**: Metodi che recuperano dati. Questi saranno i candidati principali per `GetOrFetchAsync`. -- **Scrittura/Invalidazione**: Metodi che aggiornano il DB e devono invalidare la cache (es. `AnagGruppiUpsert`, `ArticoliUpdateRecord`). Questi dovranno utilizzare `_cache.RemoveByTagAsync` o `_cache.RemoveAsync`. +### Fase 1: Analisi e Mapping (Completata) -### 3. Piano di Implementazione (Step-by-Step) +### Fase 2: Refactoring Metodi di Lettura (Cache-aside) -#### Fase 1: Analisi e Mapping -- [ ] Identificare ogni occorrenza di `redisDb.StringGet` / `StringGetAsync` in `MpDataService.cs`. -- [ ] Verificare se la chiave di cache utilizzata è gestita tramite `Utils.redis...`. +#### ✅ Completati (Migrati con `GetOrFetchAsync`) +- `ActionGetReq` +- `AnagEventiGeneralAsync` +- `AnagStatiCommAsync` +- `AnagTipoArtLvAsync` +- `ArticleWithDossierAsync` +- `ArticoliGetByTipoAsync` +- `ArticoliGetSearchAsync` +- `ConfigGetAllAsync` +- `DossiersGetLastFiltAsync` +- `ElencoAziendeAsync` +- `ElencoGruppiFaseAsync` +- `ElencoLinkAsync` +- `FluxLogGetLastFiltAsync` +- `FluxLogParetoAsync` +- `OperatoriGetFiltAsync` +- `POdlGetByOdlAsync` +- `POdlListGetFiltAsync` +- `TksScoreAsync` +- `WipKitFiltAsync` +- `MacchineRecipeArchiveAsync` +- `MacchineRecipeConfAsync` -#### Fase 2: Refactoring Metodi di Lettura -- [x] `ActionGetReq` (Completato) -- [x] `TemplateKitFiltAsync` -- [x] `AnagTipoArtLvAsync` -- [x] `ElencoLinkAsync` -- [x] `ConfigGetAllAsync` -- [x] `DossiersGetLastFiltAsync` -- [x] `ElencoGruppiFaseAsync` -- [x] `IstKitFiltAsync` -- [x] `ListGiacenzeAsync` -- [x] `MacchineWithFluxAsync` -- [x] `POdlListGetFiltAsync` -- [x] `TksScoreAsync` -- [x] `WipKitFiltAsync` -- [x] `POdlGetByOdlAsync` -- [x] `FluxLogGetLastFiltAsync` -- [x] `FluxLogParetoAsync` -- [x] `OperatoriGetFiltAsync` -- [x] `MacchineRecipeArchiveAsync` -- [x] `MacchineRecipeConfAsync` -- [ ] `AnagEventiGeneral` -- [ ] `AnagEventiGetByMacch` -- [ ] `AnagKeyValGetAll` -- [ ] `AnagStatiComm` -- [ ] `AnagTipoArtLvAsync` -- [ ] `ArticleWithDossier` -- [ ] `ConfigGetAll` -- [ ] `DbDedupStats` -- [ ] `ElencoRepartiDTO` -- [ ] `ExpiryReloadParamGet` -- [ ] `IobInfo` -- [ ] `ListPODL_ByCodArt` -- [ ] `MacchineGetFilt` -- [ ] `MacchineRecipeArchive` -- [ ] `MacchineRecipeConf` -- [ ] `MachIobConf` -- [ ] `MseGetAll` -- [ ] `OdlByBatch` -- [ ] `OdlGetCurrentAsync` -- [ ] `OdlListGetFilt` -- [ ] `OperatoriGetFilt` -- [ ] `ParametriGetFilt` -- [ ] `POdlGetByKey` -- [ ] `POdlListByKitParent` -- [ ] `ProcFLStats` -- [ ] `StatoMacchina` -- [ ] `TagConfGetKey` -- [ ] `VocabolarioGetAll` +#### ⏳ In corso / Da Migrare +- `AnagEventiGetByMacch` +- `AnagKeyValGetAll` +- `ConfigGetAll` (Sincrono) +- `ConfigTryGet` (Sincrono) +- `ConfigTryGetAsync` +- `DbDedupStats` +- `ElencoRepartiDTO` +- `ExpiryReloadParamGet` +- `IobInfo` +- `ListPODL_ByCodArt` +- `MacchineGetFilt` +- `MachIobConf` +- `MachIobConfVal` +- `MseGetAll` +- `OdlByBatch` +- `OdlGetCurrentAsync` +- `OdlListGetFilt` +- `OperatoriGetFilt` (Sincrono) +- `ParametriGetFilt` +- `POdlGetByKey` +- `POdlListByKitParent` +- `ProcFLStats` +- `StatoMacchina` +- `TagConfGetKey` +- `VocabolarioGetAll` -#### Fase 3: Refactoring Metodi di Scrittura e Invalidazione -- [ ] `AnagGruppiDelete` -- [ ] `AnagGruppiUpsert` -- [ ] `ArticoliDeleteRecord` -- [ ] `ArticoliUpdateRecord` -- [ ] `ConfigResetCache` -- [ ] `DossiersDeleteRecord` -- [ ] `DossiersTakeParamsSnapshotLast` -- [ ] `IstKitDelete` -- [ ] `IstKitInsertByWKS` -- [ ] `IstKitUpsert` -- [ ] `PodlIstKitDelete` -- [ ] `POdlDoSetup` -- [ ] `POdlUpdateRecipe` -- [ ] `POdlUpdateRecord` -- [ ] `RecipeSetByPODL` -- [ ] `TemplateKitDelete` -- [ ] `TemplateKitUpsert` Fase 2: Refactoring Metodi di Lettura -- [x] `ActionGetReq` (Completato) -- [x] `TemplateKitFiltAsync` -- [x] `AnagTipoArtLvAsync` -- [x] `ElencoLinkAsync` -- [x] `ConfigGetAllAsync` -- [x] `DossiersGetLastFiltAsync` -- [x] `ElencoGruppiFaseAsync` -- [x] `IstKitFiltAsync` -- [x] `ListGiacenzeAsync` -- [x] `MacchineWithFluxAsync` -- [x] `POdlListGetFiltAsync` -- [x] `TksScoreAsync` -- [x] `WipKitFiltAsync` -- [x] `POdlGetByOdlAsync` -- [x] `FluxLogGetLastFiltAsync` -- [x] `FluxLogParetoAsync` -- [ ] `AnagEventiGeneral` -- [ ] `AnagEventiGetByMacch` -- [ ] `AnagKeyValGetAll` -- [ ] `AnagStatiComm` -- [ ] `AnagTipoArtLvAsync` -- [ ] `ArticleWithDossier` -- [ ] `ConfigGetAll` -- [ ] `DbDedupStats` -- [ ] `ElencoRepartiDTO` -- [ ] `ExpiryReloadParamGet` -- [ ] `IobInfo` -- [ ] `ListPODL_ByCodArt` -- [ ] `MacchineGetFilt` -- [ ] `MacchineRecipeArchive` -- [ ] `MacchineRecipeConf` -- [ ] `MachIobConf` -- [ ] `MseGetAll` -- [ ] `OdlByBatch` -- [ ] `OdlGetCurrentAsync` -- [ ] `OdlListGetFilt` -- [ ] `OperatoriGetFilt` -- [ ] `ParametriGetFilt` -- [ ] `POdlGetByKey` -- [ ] `POdlListByKitParent` -- [ ] `ProcFLStats` -- [ ] `StatoMacchina` -- [ ] `TagConfGetKey` -- [ ] `VocabolarioGetAll` - -#### Fase 3: Refactoring Metodi di Scrittura e Invalidazione +### Fase 3: Refactoring Metodi di Scrittura e Invalidazione - [ ] `AnagGruppiDelete` - [ ] `AnagGruppiUpsert` - [ ] `ArticoliDeleteRecord` From 37044040c4c7b7e2b31811f0faec3b44ed9d01fe Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 18:59:54 +0200 Subject: [PATCH 057/102] Altra ottimizzazione letture cache async --- MP.Data/Controllers/MpSpecController.cs | 34 +++++++++--------- MP.Data/Services/OrderDataSrv.cs | 4 +-- MP.SPEC/Components/AskCloseOdl.razor.cs | 2 +- MP.SPEC/Components/ListDossiers.razor.cs | 36 +++++++------------ MP.SPEC/Components/ListODL.razor.cs | 4 +-- MP.SPEC/Components/SelArticolo.razor.cs | 44 +++++++++++++++++------- MP.SPEC/Data/MpDataService.cs | 26 ++++++++++---- MP.SPEC/Pages/GroupMacOprMan.razor | 4 +-- MP.SPEC/Pages/GroupMacOprMan.razor.cs | 11 +++--- 9 files changed, 91 insertions(+), 74 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index dd60d20d..1dac52bb 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -1433,26 +1433,24 @@ namespace MP.Data.Controllers /// Data inizio /// Data fine /// - public List ListODLFilt(bool inCorso, string codArt, string keyRichPart, string Reparto, string IdxMacchina, DateTime startDate, DateTime endDate) + public async Task> ListODLFiltAsync(bool inCorso, string codArt, string keyRichPart, string Reparto, string IdxMacchina, DateTime startDate, DateTime endDate) { List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - var InCorso = new SqlParameter("@InCorso", inCorso); - var CodArt = new SqlParameter("@CodArt", codArt); - var KeyRich = new SqlParameter("@KeyRich", keyRichPart); - var CodGruppo = new SqlParameter("@CodGruppo", Reparto); - var IdxMacc = new SqlParameter("@IdxMacchina", IdxMacchina); - var DataFrom = new SqlParameter("@DataFrom", startDate); - var DataTo = new SqlParameter("@DataTo", endDate); + using var dbCtx = new MoonProContext(options); - dbResult = dbCtx - .DbSetODLExp - .FromSqlRaw("EXEC stp_ODL_getByFiltSpec @InCorso, @CodArt, @KeyRich, @CodGruppo, @IdxMacchina, @DataFrom, @DataTo", InCorso, CodArt, KeyRich, CodGruppo, IdxMacc, DataFrom, DataTo) - .AsNoTracking() - .ToList(); - } - return dbResult; + var InCorso = new SqlParameter("@InCorso", inCorso); + var CodArt = new SqlParameter("@CodArt", codArt); + var KeyRich = new SqlParameter("@KeyRich", keyRichPart); + var CodGruppo = new SqlParameter("@CodGruppo", Reparto); + var IdxMacc = new SqlParameter("@IdxMacchina", IdxMacchina); + var DataFrom = new SqlParameter("@DataFrom", startDate); + var DataTo = new SqlParameter("@DataTo", endDate); + + return await dbCtx + .DbSetODLExp + .FromSqlRaw("EXEC stp_ODL_getByFiltSpec @InCorso, @CodArt, @KeyRich, @CodGruppo, @IdxMacchina, @DataFrom, @DataTo", InCorso, CodArt, KeyRich, CodGruppo, IdxMacc, DataFrom, DataTo) + .AsNoTracking() + .ToListAsync(); } /// @@ -2206,7 +2204,7 @@ namespace MP.Data.Controllers /// /// /// - public async Task> PODL_getDictOdlPodl(List missingIds) + public async Task> PODL_getDictOdlPodlAsync(List missingIds) { if (missingIds == null || !missingIds.Any()) return new Dictionary(); diff --git a/MP.Data/Services/OrderDataSrv.cs b/MP.Data/Services/OrderDataSrv.cs index f6865451..42e0efdb 100644 --- a/MP.Data/Services/OrderDataSrv.cs +++ b/MP.Data/Services/OrderDataSrv.cs @@ -109,7 +109,7 @@ namespace MP.Data.Services } else { - result = await Task.FromResult(dbController.ListODLFilt(inCorso, CodArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate)); + result = await dbController.ListODLFiltAsync(inCorso, CodArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await _redisDb.StringSetAsync(currKey, rawData, LongCache); @@ -119,7 +119,7 @@ namespace MP.Data.Services result = new List(); } sw.Stop(); - Log.Debug($"ListODLFilt | CodArt: {CodArt} | IdxMacchina: {IdxMacchina} | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + Log.Debug($"ListODLFiltAsync | CodArt: {CodArt} | IdxMacchina: {IdxMacchina} | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } diff --git a/MP.SPEC/Components/AskCloseOdl.razor.cs b/MP.SPEC/Components/AskCloseOdl.razor.cs index 98fe22f4..d82ff0ea 100644 --- a/MP.SPEC/Components/AskCloseOdl.razor.cs +++ b/MP.SPEC/Components/AskCloseOdl.razor.cs @@ -76,7 +76,7 @@ namespace MP.SPEC.Components { DateTime oggi = DateTime.Today; // recupero idxMaccSel x ODL... - var elencoOdl = await MDService.OdlListGetFilt(true, "*", "*", "*", "*", DateTime.Today.AddMonths(-1), DateTime.Today.AddDays(1)); + var elencoOdl = await MDService.OdlListGetFiltAsync(true, "*", "*", "*", "*", DateTime.Today.AddMonths(-1), DateTime.Today.AddDays(1)); var currOdl = elencoOdl.FirstOrDefault(x => x.IdxOdl == idxOdl); if (currOdl != null && currOdl.IdxOdl == idxOdl) { diff --git a/MP.SPEC/Components/ListDossiers.razor.cs b/MP.SPEC/Components/ListDossiers.razor.cs index 778e8cb9..72530118 100644 --- a/MP.SPEC/Components/ListDossiers.razor.cs +++ b/MP.SPEC/Components/ListDossiers.razor.cs @@ -78,8 +78,8 @@ namespace MP.SPEC.Components #region Protected Fields - protected string selAzienda = "*"; protected string giacenzeConf = "false"; + protected string selAzienda = "*"; #endregion Protected Fields @@ -229,22 +229,10 @@ namespace MP.SPEC.Components ListStati = await MDService.AnagStatiCommAsync(); selAzienda = await MDService.ConfigTryGetAsync("AZIENDA"); giacenzeConf = await MDService.ConfigTryGetAsync("SPEC_ShowGiacenze"); -#if false - ListArticoli = await MDService.ArticoliGetSearchAsync(100000, "*", selAzienda, ""); -#endif ListMacchine = await MDService.MacchineGetFiltAsync("*"); await ReloadData(true); } - /// - /// Ricerca articoli - /// - private string SearchArt = ""; - /// - /// Num min car x ricerca - /// - private int SearchMinChar = 3; - protected override async Task OnParametersSetAsync() { if (!lastFilter.Equals(SelFilter)) @@ -277,7 +265,6 @@ namespace MP.SPEC.Components if (alert) { - await Task.Delay(1); if (currRecord != null) { // serializzo valore x flux log... @@ -288,8 +275,7 @@ namespace MP.SPEC.Components await MDService.DossiersUpdateValore(currRecord); currFluxLogDto = null; isEditing = false; - await Task.Delay(1); - StateHasChanged(); + await InvokeAsync(StateHasChanged); } return; } @@ -320,16 +306,19 @@ namespace MP.SPEC.Components private DossierModel? currRecordClone = null; -#if false - private List? ListArticoli; -#endif private List? ListGruppiFase; private List? ListMacchine; + private List? ListRecords; private List? ListStati; + /// + /// Ricerca articoli + /// + private string SearchArt = ""; + private List? SearchRecords; #endregion Private Fields @@ -354,6 +343,11 @@ namespace MP.SPEC.Components private List? listaFlux { get; set; } = null; + private int MaxRec + { + get => SelFilter.MaxRecord; + } + private int MaxRecord { get => SelFilter.MaxRecord; @@ -387,10 +381,6 @@ namespace MP.SPEC.Components { get => SelFilter.IdxMacchina; } - private int MaxRec - { - get => SelFilter.MaxRecord; - } private int totalCount { diff --git a/MP.SPEC/Components/ListODL.razor.cs b/MP.SPEC/Components/ListODL.razor.cs index 55e93867..9d100587 100644 --- a/MP.SPEC/Components/ListODL.razor.cs +++ b/MP.SPEC/Components/ListODL.razor.cs @@ -384,7 +384,7 @@ namespace MP.SPEC.Components private async Task ReloadDataAsync() { isLoading = true; - SearchRecords = await MDService.OdlListGetFilt(currFilter.IsActive, currFilter.SearchVal, currFilter.CodFase, currFilter.CodReparto, currFilter.IdxMacchina, currFilter.DtStart, currFilter.DtEnd); + SearchRecords = await MDService.OdlListGetFiltAsync(currFilter.IsActive, currFilter.SearchVal, currFilter.CodFase, currFilter.CodReparto, currFilter.IdxMacchina, currFilter.DtStart, currFilter.DtEnd); await ReloadPOdlData(); await ReloadLutData(); totalCount = SearchRecords.Count; @@ -399,7 +399,7 @@ namespace MP.SPEC.Components if (SearchRecords != null) { var listIdx = SearchRecords.Select(x => x.IdxOdl).ToList(); - _podlLocalCache = await MDService.PODL_getDictOdlPodl(listIdx); + _podlLocalCache = await MDService.PODL_getDictOdlPodlAsync(listIdx); #if false // 1. Popolo la cache locale in parallelo sfruttando la velocità di FusionCache var tasks = SearchRecords.Select(async odl => diff --git a/MP.SPEC/Components/SelArticolo.razor.cs b/MP.SPEC/Components/SelArticolo.razor.cs index dd26d88b..e7293b35 100644 --- a/MP.SPEC/Components/SelArticolo.razor.cs +++ b/MP.SPEC/Components/SelArticolo.razor.cs @@ -6,29 +6,30 @@ namespace MP.SPEC.Components { public partial class SelArticolo { - // Parametri per il Two-Way Data Binding + #region Public Properties + [Parameter] - public string Value { get; set; } + public string SearchVal { get; set; } = ""; + + [Parameter] + public string SelAzienda { get; set; } = "*"; + + [Parameter] + public string Value { get; set; } = null!; [Parameter] public EventCallback ValueChanged { get; set; } - // Parametri di filtro - [Parameter] - public string SearchVal { get; set; } = ""; - [Parameter] - public string SelAzienda { get; set; } = "*"; + #endregion Public Properties + + #region Protected Properties [Inject] protected MpDataService MDService { get; set; } = null!; - private List? ListArticoli; + #endregion Protected Properties - // Variabili di appoggio per tracciare il cambio dei filtri - private string _oldSearchVal = string.Empty; - private string _oldSelAzienda = string.Empty; - - private int maxNum = 100; + #region Protected Methods protected override async Task OnInitializedAsync() { @@ -46,6 +47,21 @@ namespace MP.SPEC.Components } } + #endregion Protected Methods + + #region Private Fields + + // Variabili di appoggio per tracciare il cambio dei filtri + private string _oldSearchVal = string.Empty; + + private string _oldSelAzienda = string.Empty; + private List? ListArticoli; + private int maxNum = 100; + + #endregion Private Fields + + #region Private Methods + private async Task CaricaArticoli() { ListArticoli = await MDService.ArticoliGetSearchAsync(maxNum, "*", SelAzienda, SearchVal); @@ -57,5 +73,7 @@ namespace MP.SPEC.Components // Notifica il componente padre della variazione await ValueChanged.InvokeAsync(Value); } + + #endregion Private Methods } } \ No newline at end of file diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 01c92078..c378c733 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1726,9 +1726,20 @@ namespace MP.SPEC.Data /// Data inizio /// Data fine /// - public async Task> OdlListGetFilt(bool inCorso, string codArt, string keyRichPart, string Reparto, string IdxMacchina, DateTime startDate, DateTime endDate) + public async Task> OdlListGetFiltAsync(bool inCorso, string codArt, string keyRichPart, string Reparto, string IdxMacchina, DateTime startDate, DateTime endDate) { - using var activity = ActivitySource.StartActivity("OdlListGetFilt"); + + string currKey = $"{Utils.redisOdlList}:{inCorso}:{codArt}:{keyRichPart}:{Reparto}:{IdxMacchina}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; + return await GetOrFetchAsync( + operationName: "OdlListGetFiltAsync", + cacheKey: currKey, + expiration: getRandTOut(redisShortTimeCache), + fetchFunc: async () => await dbController.ListODLFiltAsync(inCorso, codArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate) ?? new(), + tagList: [Utils.redisOdlList] + ); + +#if false + using var activity = ActivitySource.StartActivity("OdlListGetFiltAsync"); List? result = new List(); string source = "DB"; string currKey = $"{Utils.redisOdlList}:{inCorso}:{codArt}:{keyRichPart}:{Reparto}:{IdxMacchina}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; @@ -1741,7 +1752,7 @@ namespace MP.SPEC.Data } else { - result = await Task.FromResult(dbController.ListODLFilt(inCorso, codArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate)); + result = await dbController.ListODLFiltAsync(inCorso, codArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); @@ -1753,8 +1764,9 @@ namespace MP.SPEC.Data activity?.SetTag("data.source", source); activity?.SetTag("result.count", result.Count); activity?.Stop(); - LogTrace($"OdlListGetFilt | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + LogTrace($"OdlListGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + return result; +#endif } /// @@ -1879,7 +1891,7 @@ namespace MP.SPEC.Data /// /// /// - public async Task> PODL_getDictOdlPodl(List idxOdlList) + public async Task> PODL_getDictOdlPodlAsync(List idxOdlList) { if (idxOdlList == null || !idxOdlList.Any()) return new Dictionary(); @@ -1910,7 +1922,7 @@ namespace MP.SPEC.Data if (missingIds.Any()) { // Riceviamo direttamente un Dictionary ottimizzato da EF Core - Dictionary dbResults = await dbController.PODL_getDictOdlPodl(missingIds); + Dictionary dbResults = await dbController.PODL_getDictOdlPodlAsync(missingIds); // STEP 3: Scriviamo i risultati in cache e li uniamo al dizionario finale foreach (var kvp in dbResults) diff --git a/MP.SPEC/Pages/GroupMacOprMan.razor b/MP.SPEC/Pages/GroupMacOprMan.razor index 066214f9..df08cb90 100644 --- a/MP.SPEC/Pages/GroupMacOprMan.razor +++ b/MP.SPEC/Pages/GroupMacOprMan.razor @@ -16,11 +16,11 @@ @if (ShowDetail) { - + } else { - + } diff --git a/MP.SPEC/Pages/GroupMacOprMan.razor.cs b/MP.SPEC/Pages/GroupMacOprMan.razor.cs index 9e5c2bb1..f9f63a52 100644 --- a/MP.SPEC/Pages/GroupMacOprMan.razor.cs +++ b/MP.SPEC/Pages/GroupMacOprMan.razor.cs @@ -30,7 +30,6 @@ namespace MP.SPEC.Pages if (searchVal != value) { searchVal = value; - ReloadDataAsync(); } } } @@ -38,10 +37,10 @@ namespace MP.SPEC.Pages #endregion Protected Properties #region Protected Methods - - protected override void OnInitialized() + protected override async Task OnInitializedAsync() { - ReloadDataAsync(); + await ReloadBaseDataAsync(); + await ReloadDataAsync(); } #endregion Protected Methods @@ -77,13 +76,13 @@ namespace MP.SPEC.Pages #region Private Methods - private void ForceReload(bool doForce) + private async Task ForceReload(bool doForce) { if (doForce) { CodGruppo = ""; } - ReloadDataAsync(); + await ReloadDataAsync(); } private async Task ReloadBaseDataAsync() From 3660306c52ecc903bdad1848cc833e9fdd5aa1c3 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 19:06:53 +0200 Subject: [PATCH 058/102] Fix metodi IOC (ancora da ottimizzare cmq) --- MP.IOC/Data/MpDataService.cs | 123 ------------------------------- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- 9 files changed, 8 insertions(+), 131 deletions(-) diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs index 2237d76c..73bd612f 100644 --- a/MP.IOC/Data/MpDataService.cs +++ b/MP.IOC/Data/MpDataService.cs @@ -2547,129 +2547,6 @@ namespace MP.IOC.Data return dbResult; } - /// - /// elenco TUTTI gli ODL - /// - /// - /// - public List OdlListAll() - { - List? result = new List(); - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - result = SpecDbController.OdlListAll(); - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"OdlListAll | Read from {readType}: {ts.TotalMilliseconds}ms"); - return result; - } - - /// - /// Elenco ODL filtrati x stato, articolo, KeyRich (che contiene stato) - /// - /// Stato ODL: true=in corso/completato - /// Cod articolo - /// KeyRich (parziale) da cercare (es cod stato x yacht) - /// Reparto selezionato - /// Macchina selezionata - /// Data inizio - /// Data fine - /// - public async Task> OdlListGetFilt(bool inCorso, string codArt, string keyRichPart, string Reparto, string IdxMacchina, DateTime startDate, DateTime endDate) - { - List? result = new List(); - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - string currKey = $"{Utils.redisOdlList}:{inCorso}:{codArt}:{keyRichPart}:{Reparto}:{IdxMacchina}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - readType = "REDIS"; - } - else - { - result = await Task.FromResult(SpecDbController.ListODLFilt(inCorso, codArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate)); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); - } - if (result == null) - { - result = new List(); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"OdlListGetFilt | Read from {readType}: {ts.TotalMilliseconds}ms"); - return result; - } - - /// - /// Elenco di tutti i parametri filtrati x macchina - /// - /// * = tutte, altrimenti solo x una data macchina - /// - public async Task> ParametriGetFilt(string IdxMacchina) - { - List? result = new List(); - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - string currKey = $"{Utils.redisFluxByMac}:{IdxMacchina}"; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - readType = "REDIS"; - } - else - { - result = await Task.FromResult(SpecDbController.ParametriGetFilt(IdxMacchina)); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"ParametriGetFilt | Read from {readType}: {ts.TotalMilliseconds}ms"); - return result; - } - - /// - /// Eliminazione record selezionato - /// - /// - /// - public async Task POdlDeleteRecord(PODLExpModel currRec) - { - var dbResult = await SpecDbController.PODLDeleteRecord(currRec); - // elimino cache redis... - await POdlFlushCache(); - await Task.Delay(1); - return dbResult; - } - - /// - /// Avvio fase setup per il record selezionato - /// - /// - /// - public async Task POdlDoSetup(PODLExpModel currRec) - { - var dbResult = await SpecDbController.PODL_startSetup(currRec, 0, 1, 1, "", DateTime.Now); - // elimino cache redis... - await POdlFlushCache(); - await Task.Delay(1); - return dbResult; - } /// /// Recupero PODL da chiave diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index afca689d..f2557c5e 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.2814 + 8.16.2605.2819 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index a66dda6f..bde316d6 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                              Versione: 8.16.2605.2814

                                              +

                                              Versione: 8.16.2605.2819


                                              Note di rilascio:
                                              • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 6454cfbd..aa4264a2 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2814 +8.16.2605.2819 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 5857f651..e7f0f84a 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2814 + 8.16.2605.2819 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 4598fb26..36f5d62a 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2605.2814 + 8.16.2605.2819 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 4870a12b..918ead93 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                Versione: 8.16.2605.2814

                                                +

                                                Versione: 8.16.2605.2819


                                                Note di rilascio:
                                                  diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 6454cfbd..aa4264a2 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2814 +8.16.2605.2819 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index 04e9d50e..d30c43f4 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2814 + 8.16.2605.2819 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false From ff36dadadc68ec4f9688ccecd60b9b32a2eb6741 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 28 May 2026 19:07:14 +0200 Subject: [PATCH 059/102] refresh compilazioni test --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index 824d4710..f2064d96 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2605.2814 + 8.16.2605.2819 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 4a3ba3b7..f187aa8a 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                  Versione: 8.16.2605.2814

                                                  +

                                                  Versione: 8.16.2605.2819


                                                  Note di rilascio:
                                                  • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 6454cfbd..aa4264a2 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2814 +8.16.2605.2819 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index 7f38c389..90bdebf9 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2814 + 8.16.2605.2819 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index 8f59e4d6..d8e1cd31 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2605.2814 + 8.16.2605.2819 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index a7cd6871..9887bb6f 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                                    Versione: 8.16.2605.2814

                                                    +

                                                    Versione: 8.16.2605.2819


                                                    Note di rilascio:
                                                    • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index 6454cfbd..aa4264a2 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2814 +8.16.2605.2819 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index b834439b..419be244 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2814 + 8.16.2605.2819 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index 105ef2d7..3a2c8b3e 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2605.2814 + 8.16.2605.2819 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 4a3ba3b7..f187aa8a 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                      Versione: 8.16.2605.2814

                                                      +

                                                      Versione: 8.16.2605.2819


                                                      Note di rilascio:
                                                      • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 6454cfbd..aa4264a2 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2814 +8.16.2605.2819 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index 7243b6d7..663f4293 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2814 + 8.16.2605.2819 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index b97e8d09..a039e89a 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2605.2814 + 8.16.2605.2819 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index cf498c8a..c0708518 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                                        Versione: 8.16.2605.2814

                                                        +

                                                        Versione: 8.16.2605.2819


                                                        Note di rilascio:
                                                          diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 6454cfbd..aa4264a2 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2814 +8.16.2605.2819 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 85a76b76..179be88b 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2814 + 8.16.2605.2819 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index c1490005..a8ef99d6 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2605.2814 + 8.16.2605.2819 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index 49048720..c59c6bbf 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                          Versione: 8.16.2605.2814

                                                          +

                                                          Versione: 8.16.2605.2819


                                                          Note di rilascio:
                                                          • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index 6454cfbd..aa4264a2 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2814 +8.16.2605.2819 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index c2fcb518..f1bc26dd 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2814 + 8.16.2605.2819 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 37b640a7..658f6ef1 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2818 + 8.16.2605.2819 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 83fcea16..f187aa8a 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                            Versione: 8.16.2605.2818

                                                            +

                                                            Versione: 8.16.2605.2819


                                                            Note di rilascio:
                                                            • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index dc9f3309..aa4264a2 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2818 +8.16.2605.2819 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 7314d35a..24db78b5 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2818 + 8.16.2605.2819 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 5b01670f..2c71b44f 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2605.2814 + 8.16.2605.2819 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index da0c952c..98e8275e 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                                              Versione: 8.16.2605.2814

                                                              +

                                                              Versione: 8.16.2605.2819


                                                              Note di rilascio:
                                                                diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 6454cfbd..aa4264a2 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2814 +8.16.2605.2819 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index a68ee3ba..4a7e00e5 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2814 + 8.16.2605.2819 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false From 116d7395c9bb4300c014a10554c34ca87bb6004f Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 29 May 2026 07:23:54 +0200 Subject: [PATCH 060/102] Ancora update metodi SPEC --- MP.Data/Controllers/MpSpecController.cs | 57 +++- MP.SPEC/Components/ListDossiers.razor.cs | 2 +- MP.SPEC/Components/ParamsFilter.razor.cs | 2 +- MP.SPEC/Data/MpDataService.cs | 407 +++++++++-------------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Articoli.razor | 13 +- MP.SPEC/Pages/Articoli.razor.cs | 7 +- MP.SPEC/Pages/Giacenze.razor.cs | 2 +- MP.SPEC/Pages/PARAMS.razor.cs | 22 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 12 files changed, 224 insertions(+), 296 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 1dac52bb..b8d88d7e 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -401,7 +401,44 @@ namespace MP.Data.Controllers .CountAsync(); return result; } + /// + /// Conteggio articoli data condizione ricerca + /// + /// + /// + /// + /// + public async Task ArticoliCountSearchAsync(string tipoArt = "*", string azienda = "*", string searchVal = "") + { + using var dbCtx = new MoonProContext(options); + IQueryable query = dbCtx.DbSetArticoli.AsNoTracking(); + // filtro tipo articolo + if (tipoArt != "*") + { + //query = query.Where(x => x.Tipo.ToLower() == tipoArt.ToLower()); + query = query.Where(x => EF.Functions.Like(x.Tipo, tipoArt)); + } + // filtro azienda + if (azienda != "*") + { + //query = query.Where(x => x.Azienda.ToLower() == azienda.ToLower()); + query = query.Where(x => EF.Functions.Like(x.Azienda, azienda)); + } + // filtro ricerca + if (!string.IsNullOrWhiteSpace(searchVal)) + { + string pattern = $"%{searchVal}%"; + query = query.Where(x => + EF.Functions.Like(x.CodArticolo, pattern) || + EF.Functions.Like(x.DescArticolo, pattern) || + EF.Functions.Like(x.Disegno, pattern)); + } + + return await query + .OrderBy(x => x.CodArticolo) + .CountAsync(); + } /// /// Elenco tabella Articoli IMPIEGATI (da stored stp_ART_getUsed) Async /// @@ -499,10 +536,6 @@ namespace MP.Data.Controllers // filtro ricerca if (!string.IsNullOrWhiteSpace(searchVal)) { - //query = query.Where(x => - // x.CodArticolo.Contains(searchVal) || - // x.DescArticolo.Contains(searchVal) || - // x.Disegno.Contains(searchVal)); string pattern = $"%{searchVal}%"; query = query.Where(x => EF.Functions.Like(x.CodArticolo, pattern) || @@ -651,16 +684,12 @@ namespace MP.Data.Controllers /// public async Task> ConfigGetAllAsync() { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = await dbCtx - .DbSetConfig - .AsNoTracking() - .OrderBy(x => x.Chiave) - .ToListAsync(); - } - return dbResult; + using var dbCtx = new MoonProContext(options); + return await dbCtx + .DbSetConfig + .AsNoTracking() + .OrderBy(x => x.Chiave) + .ToListAsync() ?? new(); } /// diff --git a/MP.SPEC/Components/ListDossiers.razor.cs b/MP.SPEC/Components/ListDossiers.razor.cs index 72530118..31d1b9b3 100644 --- a/MP.SPEC/Components/ListDossiers.razor.cs +++ b/MP.SPEC/Components/ListDossiers.razor.cs @@ -224,7 +224,7 @@ namespace MP.SPEC.Components protected override async Task OnInitializedAsync() { - await MDService.ConfigResetCache(); + await MDService.ConfigResetCacheAsync(); ListGruppiFase = await MDService.ElencoGruppiFaseAsync(); ListStati = await MDService.AnagStatiCommAsync(); selAzienda = await MDService.ConfigTryGetAsync("AZIENDA"); diff --git a/MP.SPEC/Components/ParamsFilter.razor.cs b/MP.SPEC/Components/ParamsFilter.razor.cs index ad7246bb..8b3c784d 100644 --- a/MP.SPEC/Components/ParamsFilter.razor.cs +++ b/MP.SPEC/Components/ParamsFilter.razor.cs @@ -171,7 +171,7 @@ namespace MP.SPEC.Components protected override async Task OnInitializedAsync() { SelFilter = new SelectFluxParams(); - await MDService.ConfigResetCache(); + await MDService.ConfigResetCacheAsync(); var result = await MDService.ConfigTryGetAsync("SPEC_ParamTempoAgg"); if (result != null) { diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index c378c733..4becd8d6 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -90,6 +90,15 @@ namespace MP.SPEC.Data public MessagePipe BroadastMsgPipe { get; set; } = null!; public Dictionary> currTagConf { get; set; } = new Dictionary>(); + /// + /// Expiry DateTime x refresh pagina parametri + /// + public DateTime DtParamExpiry + { + get => _dtParamExpiry; + set => _dtParamExpiry = value; + } + #endregion Public Properties #region Public Methods @@ -252,6 +261,33 @@ namespace MP.SPEC.Data ); } + public async Task ArticoliCountAsync() + { + string redisKey = $"{Utils.redisArtList}:Count"; + return await GetOrFetchAsync( + operationName: "ArticoliCountAsync", + cacheKey: redisKey, + expiration: getRandTOut(redisLongTimeCache), + fetchFunc: async () => + await dbController.ArticoliCountAsync(), + tagList: [Utils.redisArtList, $"{Utils.redisArtList}:CountAll"] + ); + } + + public async Task ArticoliCountSearchAsync(string tipo = "*", string azienda = "*", string searchVal = "") + { + string sKey = string.IsNullOrWhiteSpace(tipo) ? "ALL" : tipo.Trim(); + string redisKey = $"{Utils.redisArtList}:{azienda}:{sKey}:{searchVal}:Count"; + return await GetOrFetchAsync( + operationName: "ArticoliCountSearchAsync", + cacheKey: redisKey, + expiration: getRandTOut(redisLongTimeCache), + fetchFunc: async () => + await dbController.ArticoliCountSearchAsync(tipo, azienda, searchVal), + tagList: [Utils.redisArtList, $"{Utils.redisArtList}:CountSearch"] + ); + } + /// /// Eliminazione record selezionato /// @@ -278,7 +314,7 @@ namespace MP.SPEC.Data public async Task> ArticoliGetByTipoAsync(string tipo, string azienda = "*") { string sKey = string.IsNullOrWhiteSpace(tipo) ? "ALL" : tipo.Trim(); - string redisKey = $"{Utils.redisArtList}:{azienda}:Tipo:{sKey}"; + string redisKey = $"{Utils.redisArtList}:{azienda}:{sKey}"; return await GetOrFetchAsync( operationName: "ArticoliGetByTipoAsync", cacheKey: redisKey, @@ -289,23 +325,6 @@ namespace MP.SPEC.Data ); } - /// - /// Elenco articoli contenuti in Kit (come child), non eliminabli - /// - /// - public async Task> ArticoliInKitAsync() - { - string redisKey = $"{Utils.redisArtList}:InKit"; - return await GetOrFetchAsync( - operationName: "ArticoliInKitAsync", - cacheKey: redisKey, - expiration: getRandTOut(redisLongTimeCache), - fetchFunc: async () => - await dbController.ArticoliInKitAsync() ?? new List(), - tagList: [Utils.redisArtList, $"{Utils.redisArtList}:InKit"] - ); - } - /// /// Restitusice elenco articoli cercati /// @@ -328,6 +347,23 @@ namespace MP.SPEC.Data ); } + /// + /// Elenco articoli contenuti in Kit (come child), non eliminabli + /// + /// + public async Task> ArticoliInKitAsync() + { + string redisKey = $"{Utils.redisArtList}:InKit"; + return await GetOrFetchAsync( + operationName: "ArticoliInKitAsync", + cacheKey: redisKey, + expiration: getRandTOut(redisLongTimeCache), + fetchFunc: async () => + await dbController.ArticoliInKitAsync() ?? new List(), + tagList: [Utils.redisArtList, $"{Utils.redisArtList}:InKit"] + ); + } + /// /// Aggiornamento record selezionato /// @@ -458,14 +494,14 @@ namespace MP.SPEC.Data /// Reset dati cache config /// /// - public async Task ConfigResetCache() + public async Task ConfigResetCacheAsync() { - using var activity = ActivitySource.StartActivity("ConfigResetCache"); + using var activity = ActivitySource.StartActivity("ConfigResetCacheAsync"); string source = "REDIS"; await ResetConfigCache(); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ConfigResetCache Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ConfigResetCacheAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); } /// @@ -696,7 +732,6 @@ namespace MP.SPEC.Data ); } - /// /// Elenco link validi per il menu /// @@ -901,47 +936,6 @@ namespace MP.SPEC.Data return answ; } - /// - /// Imposta in redis la scadenza della pagina x il reload - /// - /// - /// - public DateTime ExpiryReloadParamGet() - { - using var activity = ActivitySource.StartActivity("ExpiryReloadParamGet"); - string source = "REDIS"; - DateTime dtRif = DateTime.Now; - string currKey = $"{Utils.redisParamPageExp}"; - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - dtRif = JsonConvert.DeserializeObject($"{rawData}"); - } - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"ExpiryReloadParamGet | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return dtRif; - } - - /// - /// Imposta in redis la scadenza della pagina x il reload - /// - /// - /// - public bool ExpiryReloadParamSet(DateTime expTime) - { - using var activity = ActivitySource.StartActivity("ExpiryReloadParamSet"); - string source = "REDIS"; - bool fatto = false; - string currKey = $"{Utils.redisParamPageExp}"; - string rawData = JsonConvert.SerializeObject(expTime); - fatto = redisDb.StringSet(currKey, rawData); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"ExpiryReloadParamSet | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return fatto; - } - /// /// Cancellazione FusionCache (totale) /// @@ -1449,24 +1443,6 @@ namespace MP.SPEC.Data ); } - /// - /// Elenco operatori filtrati x gruppo - /// - /// - /// - public async Task> OperatoriGetFiltAsync(string codGruppo) - { - string keyGrp = codGruppo != "*" ? codGruppo : "ALL"; - string currKey = $"{Utils.redisOprList}:{keyGrp}"; - - return await GetOrFetchAsync( - operationName: "OperatoriGetFiltAsync", - cacheKey: currKey, - expiration: getRandTOut(redisLongTimeCache), - fetchFunc: async () => await dbController.OperatoriGetFiltAsync(codGruppo) ?? new List(), - tagList: [Utils.redisOprList] - ); - } /// /// Elenco id Macchine che abbiano dati FLuxLog, nel periodo indicato /// @@ -1534,33 +1510,6 @@ namespace MP.SPEC.Data }, tagList: [Utils.redisIobConf] ); -#if false - using var activity = ActivitySource.StartActivity("MachIobConfAsync"); - string source = "DB"; - Dictionary result = new Dictionary(); - // cerco in redis... - string currKey = redHashMpIO($"IOB:{IdxMacchina}:MachIobConfAsync"); - try - { - result = (await redisDb.HashGetAllAsync(currKey)) - .ToDictionary(x => $"{x.Name}", x => $"{x.Value}"); - source = "REDIS"; - } - catch (Exception exc) - { - Log.Error($"Errore in MachIobConfAsync{Environment.NewLine}{exc}"); - } - if (result == null) - { - result = new Dictionary(); - LogTrace($"Init valore default MachIobConfAsync | IdxMacchina: {IdxMacchina}"); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"MachIobConfAsync per {IdxMacchina} | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return result; -#endif } /// @@ -1728,7 +1677,6 @@ namespace MP.SPEC.Data /// public async Task> OdlListGetFiltAsync(bool inCorso, string codArt, string keyRichPart, string Reparto, string IdxMacchina, DateTime startDate, DateTime endDate) { - string currKey = $"{Utils.redisOdlList}:{inCorso}:{codArt}:{keyRichPart}:{Reparto}:{IdxMacchina}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; return await GetOrFetchAsync( operationName: "OdlListGetFiltAsync", @@ -1737,36 +1685,25 @@ namespace MP.SPEC.Data fetchFunc: async () => await dbController.ListODLFiltAsync(inCorso, codArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate) ?? new(), tagList: [Utils.redisOdlList] ); + } -#if false - using var activity = ActivitySource.StartActivity("OdlListGetFiltAsync"); - List? result = new List(); - string source = "DB"; - string currKey = $"{Utils.redisOdlList}:{inCorso}:{codArt}:{keyRichPart}:{Reparto}:{IdxMacchina}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.ListODLFiltAsync(inCorso, codArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"OdlListGetFiltAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; -#endif + /// + /// Elenco operatori filtrati x gruppo + /// + /// + /// + public async Task> OperatoriGetFiltAsync(string codGruppo) + { + string keyGrp = codGruppo != "*" ? codGruppo : "ALL"; + string currKey = $"{Utils.redisOprList}:{keyGrp}"; + + return await GetOrFetchAsync( + operationName: "OperatoriGetFiltAsync", + cacheKey: currKey, + expiration: getRandTOut(redisLongTimeCache), + fetchFunc: async () => await dbController.OperatoriGetFiltAsync(codGruppo) ?? new List(), + tagList: [Utils.redisOprList] + ); } /// @@ -1786,6 +1723,75 @@ namespace MP.SPEC.Data ); } + /// + /// Restituisce dizionario ODL/PODL data lista IdxOdl + /// + /// + /// + public async Task> PODL_getDictOdlPodlAsync(List idxOdlList) + { + if (idxOdlList == null || !idxOdlList.Any()) + return new Dictionary(); + + var distinctIds = idxOdlList.Distinct().ToList(); + + var resultDictionary = new Dictionary(); + var missingIds = new List(); + + // STEP 1: Controllo rapido in FusionCache (L1/Memory cache) + foreach (var id in distinctIds) + { + var cacheKey = $"val:{id}"; + var cachedValue = await _cache.TryGetAsync(cacheKey); + + if (cachedValue.HasValue) + { + resultDictionary[id] = cachedValue.Value; + } + else + { + // ID non presente in cache, andrà cercato tramite il servizio EF + missingIds.Add(id); + } + } + + // STEP 2: Se ci sono cache miss, interroghiamo il servizio EF Core + if (missingIds.Any()) + { + // Riceviamo direttamente un Dictionary ottimizzato da EF Core + Dictionary dbResults = await dbController.PODL_getDictOdlPodlAsync(missingIds); + + // STEP 3: Scriviamo i risultati in cache e li uniamo al dizionario finale + foreach (var kvp in dbResults) + { + var id = kvp.Key; + var targetValue = kvp.Value; + + resultDictionary[id] = targetValue; + + // Salvataggio atomico e globale su FusionCache + var cacheKey = $"val:{id}"; + await _cache.SetAsync(cacheKey, targetValue, TimeSpan.FromMinutes(30)); + } + + // STEP 4 [Altamente Consigliato]: Cache Penetration Protection + // Se un ID era tra i "missing" ma NON è presente nei risultati del DB, significa che non esiste. + // Salviamo un valore sentinella (es. 0 o -1) per evitare di ricontrollare il DB al prossimo giro. + foreach (var id in missingIds) + { + if (!dbResults.ContainsKey(id)) + { + resultDictionary[id] = 0; // Imposta un default per l'output corrente + + var cacheKey = $"val:{id}"; + await _cache.SetAsync(cacheKey, 0, TimeSpan.FromMinutes(2)); // Scadenza breve per i record inesistenti + } + } + } + + return resultDictionary; + } + /// /// Eliminazione record selezionato /// @@ -1886,75 +1892,6 @@ namespace MP.SPEC.Data ); } - /// - /// Restituisce dizionario ODL/PODL data lista IdxOdl - /// - /// - /// - public async Task> PODL_getDictOdlPodlAsync(List idxOdlList) - { - if (idxOdlList == null || !idxOdlList.Any()) - return new Dictionary(); - - var distinctIds = idxOdlList.Distinct().ToList(); - - var resultDictionary = new Dictionary(); - var missingIds = new List(); - - // STEP 1: Controllo rapido in FusionCache (L1/Memory cache) - foreach (var id in distinctIds) - { - var cacheKey = $"val:{id}"; - var cachedValue = await _cache.TryGetAsync(cacheKey); - - if (cachedValue.HasValue) - { - resultDictionary[id] = cachedValue.Value; - } - else - { - // ID non presente in cache, andrà cercato tramite il servizio EF - missingIds.Add(id); - } - } - - // STEP 2: Se ci sono cache miss, interroghiamo il servizio EF Core - if (missingIds.Any()) - { - // Riceviamo direttamente un Dictionary ottimizzato da EF Core - Dictionary dbResults = await dbController.PODL_getDictOdlPodlAsync(missingIds); - - // STEP 3: Scriviamo i risultati in cache e li uniamo al dizionario finale - foreach (var kvp in dbResults) - { - var id = kvp.Key; - var targetValue = kvp.Value; - - resultDictionary[id] = targetValue; - - // Salvataggio atomico e globale su FusionCache - var cacheKey = $"val:{id}"; - await _cache.SetAsync(cacheKey, targetValue, TimeSpan.FromMinutes(30)); - } - - // STEP 4 [Altamente Consigliato]: Cache Penetration Protection - // Se un ID era tra i "missing" ma NON è presente nei risultati del DB, significa che non esiste. - // Salviamo un valore sentinella (es. 0 o -1) per evitare di ricontrollare il DB al prossimo giro. - foreach (var id in missingIds) - { - if (!dbResults.ContainsKey(id)) - { - resultDictionary[id] = 0; // Imposta un default per l'output corrente - - var cacheKey = $"val:{id}"; - await _cache.SetAsync(cacheKey, 0, TimeSpan.FromMinutes(2)); // Scadenza breve per i record inesistenti - } - } - } - - return resultDictionary; - } - /// /// Effettua il task di eliminazione PODL KIT + istanze + riattivazione PODL originali disattivate tramite stored /// @@ -2281,35 +2218,6 @@ namespace MP.SPEC.Data fetchFunc: async () => await dbController.StatoMacchinaAsync(idxMacchina) ?? new(), tagList: [Utils.redisStatoMacch] ); -#if false - using var activity = ActivitySource.StartActivity("StatoMacchinaAsync"); - // setup parametri costanti - string source = "DB"; - StatoMacchineModel? result = new StatoMacchineModel(); - // cerco in redisConn... - string currKey = $"{Utils.redisStatoMacch}:{idxMacchina}"; - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject($"{rawData}"); - source = "REDIS"; - } - else - { - result = dbController.StatoMacchina(idxMacchina); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(1)); - } - if (result == null) - { - result = new StatoMacchineModel(); - } - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"StatoMacchinaAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return result; -#endif } /// @@ -2385,7 +2293,7 @@ namespace MP.SPEC.Data if (ForceDb) { - // Se ForceDb è true, saltiamo il GetOrFetchAsync per forzare il fetch dal DB + // Se ForceDb è true, saltiamo il GetOrFetchAsync per forzare il fetch dal DB // e aggiornare la cache. var result = await dbController.TksScoreAsync(KeyFilt, MaxResult) ?? new List(); await _cache.SetAsync(currKey, result, TimeSpan.FromMinutes(redisLongTimeCache), tags: [Utils.redisKitScore]); @@ -2620,14 +2528,16 @@ namespace MP.SPEC.Data private static readonly ActivitySource ActivitySource = new ActivitySource("MP.DATA.Tracer"); private static IConfiguration _configuration = null!; - private static Logger Log = LogManager.GetCurrentClassLogger(); - private readonly IFusionCache _cache; - private DateTime _artCacheExpiry = DateTime.MinValue; - private Dictionary _configData = new(); + private DateTime _dtParamExpiry = DateTime.Now; + + /// + /// Elenco CodArticolo usati in istanza KIT (per verifica eliminabilità) + /// + private HashSet _listCodArtInKit = new(); /// /// Elenco CodArticolo NON usati (per verifica eliminabilità) @@ -2639,11 +2549,6 @@ namespace MP.SPEC.Data /// private HashSet _listCodArtUsed = new(); - /// - /// Elenco CodArticolo usati in istanza KIT (per verifica eliminabilità) - /// - private HashSet _listCodArtInKit = new(); - private string canCacheParametri = ""; private string MpIoNS = ""; @@ -2680,6 +2585,11 @@ namespace MP.SPEC.Data /// private int redisShortTimeCache = 5; + /// + /// Soglia minima (ms) per log timing in console + /// + private double slowLogThresh = 0; + private bool traceEnabled = false; #endregion Private Fields @@ -2722,11 +2632,6 @@ namespace MP.SPEC.Data } } - /// - /// Soglia minima (ms) per log timing in console - /// - private double slowLogThresh = 0; - /// /// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria + tracking attività /// diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 658f6ef1..c680ce10 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2819 + 8.16.2605.2907 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Articoli.razor b/MP.SPEC/Pages/Articoli.razor index b6acc65c..f50e61eb 100644 --- a/MP.SPEC/Pages/Articoli.razor +++ b/MP.SPEC/Pages/Articoli.razor @@ -19,8 +19,8 @@ -
                                                                -
                                                                +
                                                                +
                                                                - + + + - @if (ListAziende != null) { foreach (var item in ListAziende) @@ -45,8 +47,7 @@ } } - - + #: @availRecord
                                                                diff --git a/MP.SPEC/Pages/Articoli.razor.cs b/MP.SPEC/Pages/Articoli.razor.cs index 771bff51..47ac03bc 100644 --- a/MP.SPEC/Pages/Articoli.razor.cs +++ b/MP.SPEC/Pages/Articoli.razor.cs @@ -190,7 +190,9 @@ namespace MP.SPEC.Pages private List? ListAziende; private List? ListRecords; private List? ListTipoArt; - private int maxNumRecord = 5000; + private int maxNumRecord = 1000; + private int availRecord = 1000; + private int totRecord = 0; private List? SearchRecords; #endregion Private Fields @@ -256,7 +258,7 @@ namespace MP.SPEC.Pages Valore = selAzienda }; await MDService.ConfigUpdateAsync(updRec); - await MDService.ConfigResetCache(); + await MDService.ConfigResetCacheAsync(); // ricarico await ResetDataAsync(); } @@ -302,6 +304,7 @@ namespace MP.SPEC.Pages { isLoading = true; SearchRecords = await MDService.ArticoliGetSearchAsync(maxNumRecord, selTipoArt, selAzienda, SearchVal); + availRecord = await MDService.ArticoliCountSearchAsync(selTipoArt, selAzienda, searchVal); totalCount = SearchRecords.Count; UpdateTable(); } diff --git a/MP.SPEC/Pages/Giacenze.razor.cs b/MP.SPEC/Pages/Giacenze.razor.cs index 8f0907d9..479af5cd 100644 --- a/MP.SPEC/Pages/Giacenze.razor.cs +++ b/MP.SPEC/Pages/Giacenze.razor.cs @@ -26,7 +26,7 @@ namespace MP.SPEC.Pages protected override async Task OnInitializedAsync() { - await MDService.ConfigResetCache(); + await MDService.ConfigResetCacheAsync(); giacenzeConf = await MDService.ConfigTryGetAsync("SPEC_ShowGiacenze"); await Task.Delay(1); padCodXdl = await MDService.ConfigTryGetAsync("PadCodXdl"); diff --git a/MP.SPEC/Pages/PARAMS.razor.cs b/MP.SPEC/Pages/PARAMS.razor.cs index fd1a75e4..73204309 100644 --- a/MP.SPEC/Pages/PARAMS.razor.cs +++ b/MP.SPEC/Pages/PARAMS.razor.cs @@ -1,9 +1,8 @@ -using Microsoft.AspNetCore.Components; +using EgwCoreLib.Razor; +using Microsoft.AspNetCore.Components; using MP.Data.DbModels; -using MP.SPEC.Components; using MP.SPEC.Data; using NLog; -using EgwCoreLib.Razor; namespace MP.SPEC.Pages { @@ -23,7 +22,7 @@ namespace MP.SPEC.Pages public void ElapsedTimer(object? source, System.Timers.ElapsedEventArgs e) { // controllo se sia scaduto tempo massimo (in redis) x ricaricare pagina in modo completo... - var dtRif = MDService.ExpiryReloadParamGet(); + var dtRif = MDService.DtParamExpiry; if (dtRif > DateTime.Now) { Log.Trace("----- Elapsed check PARAMS.cs -----"); @@ -32,7 +31,7 @@ namespace MP.SPEC.Pages { var pUpd = Task.Run(async () => { - MDService.ExpiryReloadParamSet(DateTime.Now.AddSeconds(intForceReload)); + MDService.DtParamExpiry = DateTime.Now.AddSeconds(intForceReload); aTimer.Elapsed -= ElapsedTimer; aTimer.Stop(); aTimer.Close(); @@ -91,7 +90,6 @@ namespace MP.SPEC.Pages { updFilter.lastUpdate = updFilter.lastUpdate == "-" ? $"{adesso:yyyy/MM/dd HH:mm:ss}" : updFilter.lastUpdate; updFilter.IdxMacchina = newRec.IdxMacchina; - //updFilter.CodFlux = newRec.CodFlux; } else { @@ -124,7 +122,6 @@ namespace MP.SPEC.Pages currPage = newNum; DateTime adesso = DateTime.Now.AddSeconds(1); var updFilter = currFilter; - //updFilter.LiveUpdate = (currPage == 1); updFilter.LiveUpdate = (currFilter.CurrPage == 1); updFilter.lastUpdate = updFilter.LiveUpdate ? "-" : $"{adesso:yyyy/MM/dd HH:mm:ss}"; // salvo filtro @@ -211,10 +208,10 @@ namespace MP.SPEC.Pages private void setExpiryReload() { // verifico se ho una scadenza expiry del periodo desiderato, sennò imposto nuova... - var dtRif = MDService.ExpiryReloadParamGet(); + var dtRif = MDService.DtParamExpiry; if (dtRif <= DateTime.Now) { - MDService.ExpiryReloadParamSet(DateTime.Now.AddSeconds(intForceReload)); + MDService.DtParamExpiry = DateTime.Now.AddSeconds(intForceReload); } } @@ -222,18 +219,11 @@ namespace MP.SPEC.Pages { isFiltering = false; isLoading = true; - await Task.Delay(1); currPage = 1; if (newParams.CurrPage == 0) { newParams.CurrPage = 1; - //newParams.LiveUpdate = false; } - else - { - //newParams.LiveUpdate = (currPage == 1); - } - await Task.Delay(1); await InvokeAsync(() => StateHasChanged()); currFilter = newParams; isLoading = false; diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index f187aa8a..df4ddb74 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                Versione: 8.16.2605.2819

                                                                +

                                                                Versione: 8.16.2605.2907


                                                                Note di rilascio:
                                                                • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index aa4264a2..9badb5e0 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2819 +8.16.2605.2907 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 24db78b5..c4e2bf54 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2819 + 8.16.2605.2907 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From b0be426c6283186385da707ddbab2e72b844b4c7 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 29 May 2026 07:24:00 +0200 Subject: [PATCH 061/102] refresh compiile --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- 32 files changed, 32 insertions(+), 32 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index f2064d96..24212401 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2605.2819 + 8.16.2605.2907 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index f187aa8a..df4ddb74 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                  Versione: 8.16.2605.2819

                                                                  +

                                                                  Versione: 8.16.2605.2907


                                                                  Note di rilascio:
                                                                  • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index aa4264a2..9badb5e0 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2819 +8.16.2605.2907 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index 90bdebf9..d26f6752 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2819 + 8.16.2605.2907 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index d8e1cd31..d97f422a 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2605.2819 + 8.16.2605.2907 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index 9887bb6f..d2983759 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                                                    Versione: 8.16.2605.2819

                                                                    +

                                                                    Versione: 8.16.2605.2907


                                                                    Note di rilascio:
                                                                    • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index aa4264a2..9badb5e0 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2819 +8.16.2605.2907 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index 419be244..c4f54211 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2819 + 8.16.2605.2907 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index f2557c5e..c0012b86 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.2819 + 8.16.2605.2907 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index bde316d6..b5bb6646 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                                      Versione: 8.16.2605.2819

                                                                      +

                                                                      Versione: 8.16.2605.2907


                                                                      Note di rilascio:
                                                                      • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index aa4264a2..9badb5e0 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2819 +8.16.2605.2907 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index e7f0f84a..402bdbd2 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2819 + 8.16.2605.2907 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 36f5d62a..180ba1cc 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2605.2819 + 8.16.2605.2907 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 918ead93..75967f1b 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                                        Versione: 8.16.2605.2819

                                                                        +

                                                                        Versione: 8.16.2605.2907


                                                                        Note di rilascio:
                                                                          diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index aa4264a2..9badb5e0 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2819 +8.16.2605.2907 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index d30c43f4..5d7d8de9 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2819 + 8.16.2605.2907 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index 3a2c8b3e..3a846b66 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2605.2819 + 8.16.2605.2907 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index f187aa8a..df4ddb74 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                          Versione: 8.16.2605.2819

                                                                          +

                                                                          Versione: 8.16.2605.2907


                                                                          Note di rilascio:
                                                                          • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index aa4264a2..9badb5e0 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2819 +8.16.2605.2907 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index 663f4293..0c4426f0 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2819 + 8.16.2605.2907 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index a039e89a..c6122009 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2605.2819 + 8.16.2605.2907 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index c0708518..8d002a99 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                                                            Versione: 8.16.2605.2819

                                                                            +

                                                                            Versione: 8.16.2605.2907


                                                                            Note di rilascio:
                                                                              diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index aa4264a2..9badb5e0 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2819 +8.16.2605.2907 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 179be88b..efdb7b7a 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2819 + 8.16.2605.2907 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index a8ef99d6..7f255a6b 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2605.2819 + 8.16.2605.2907 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index c59c6bbf..20231bff 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                                              Versione: 8.16.2605.2819

                                                                              +

                                                                              Versione: 8.16.2605.2907


                                                                              Note di rilascio:
                                                                              • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index aa4264a2..9badb5e0 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2819 +8.16.2605.2907 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index f1bc26dd..285de5c8 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2819 + 8.16.2605.2907 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 2c71b44f..d44879d1 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2605.2819 + 8.16.2605.2907 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index 98e8275e..a1e7f04e 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                                                                Versione: 8.16.2605.2819

                                                                                +

                                                                                Versione: 8.16.2605.2907


                                                                                Note di rilascio:
                                                                                  diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index aa4264a2..9badb5e0 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2819 +8.16.2605.2907 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index 4a7e00e5..f58d9206 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2819 + 8.16.2605.2907 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false From 15fe6644183dca00ba8b14cf84b2611affc42c1e Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 29 May 2026 07:47:30 +0200 Subject: [PATCH 062/102] Rimozione metodi sync x SPEC --- .../Components/ProdKit/GestKitPodl.razor.cs | 14 ++-- MP.SPEC/Components/ProdKit/Manager.razor.cs | 2 +- MP.SPEC/Components/ScratchPodlKit.razor.cs | 15 ++-- MP.SPEC/Data/MpDataService.cs | 69 ------------------- MP.SPEC/Pages/KIT.razor.cs | 12 ++-- MP.SPEC/Pages/Podl2Kit.razor.cs | 14 ++-- 6 files changed, 28 insertions(+), 98 deletions(-) diff --git a/MP.SPEC/Components/ProdKit/GestKitPodl.razor.cs b/MP.SPEC/Components/ProdKit/GestKitPodl.razor.cs index bac741bc..af54bc10 100644 --- a/MP.SPEC/Components/ProdKit/GestKitPodl.razor.cs +++ b/MP.SPEC/Components/ProdKit/GestKitPodl.razor.cs @@ -115,22 +115,22 @@ namespace MP.SPEC.Components.ProdKit } } - protected override void OnInitialized() + protected override async Task OnInitializedAsync() { numRecord = 5; // gestione di base dei KIT - string rawVal = MDService.ConfigTryGet("OptAdmKitEnabled"); + string rawVal = await MDService.ConfigTryGetAsync("OptAdmKitEnabled"); if (!string.IsNullOrEmpty(rawVal)) { bool.TryParse(rawVal, out OptAdmKitEnabled); } // conf variabili decodifica - regExp_KO = MDService.ConfigTryGet("regExp_KO"); - regExp_OK = MDService.ConfigTryGet("regExp_OK"); - regExp_KitStart = MDService.ConfigTryGet("regExp_KitStart"); - regExp_KitSave = MDService.ConfigTryGet("regExp_KitSave"); + regExp_KO = await MDService.ConfigTryGetAsync("regExp_KO"); + regExp_OK = await MDService.ConfigTryGetAsync("regExp_OK"); + regExp_KitStart = await MDService.ConfigTryGetAsync("regExp_KitStart"); + regExp_KitSave = await MDService.ConfigTryGetAsync("regExp_KitSave"); // altre variabili - rawVal = MDService.ConfigTryGet("SPEC_nArtSearch"); + rawVal = await MDService.ConfigTryGetAsync("SPEC_nArtSearch"); if (!string.IsNullOrEmpty(rawVal)) { int.TryParse(rawVal, out minChar); diff --git a/MP.SPEC/Components/ProdKit/Manager.razor.cs b/MP.SPEC/Components/ProdKit/Manager.razor.cs index 73b7368f..543c26df 100644 --- a/MP.SPEC/Components/ProdKit/Manager.razor.cs +++ b/MP.SPEC/Components/ProdKit/Manager.razor.cs @@ -40,7 +40,7 @@ namespace MP.SPEC.Components.ProdKit isLoading = false; if (string.IsNullOrEmpty(padCodXdl)) { - padCodXdl = MDService.ConfigTryGet("padCodXdl"); + padCodXdl = await MDService.ConfigTryGetAsync("padCodXdl"); } currPodlRec = null; // recupero user... diff --git a/MP.SPEC/Components/ScratchPodlKit.razor.cs b/MP.SPEC/Components/ScratchPodlKit.razor.cs index aadf1a85..9f29a46f 100644 --- a/MP.SPEC/Components/ScratchPodlKit.razor.cs +++ b/MP.SPEC/Components/ScratchPodlKit.razor.cs @@ -123,23 +123,22 @@ namespace MP.SPEC.Components EditRecord = null; await ResetDataAsync(); } - - protected override void OnInitialized() + protected override async Task OnInitializedAsync() { numRecord = 10; // gestione di base dei KIT - string rawVal = MDService.ConfigTryGet("OptAdmKitEnabled"); + string rawVal = await MDService.ConfigTryGetAsync("OptAdmKitEnabled"); if (!string.IsNullOrEmpty(rawVal)) { bool.TryParse(rawVal, out OptAdmKitEnabled); } // conf variabili decodifica - regExp_KO = MDService.ConfigTryGet("regExp_KO"); - regExp_OK = MDService.ConfigTryGet("regExp_OK"); - regExp_KitStart = MDService.ConfigTryGet("regExp_KitStart"); - regExp_KitSave = MDService.ConfigTryGet("regExp_KitSave"); + regExp_KO = await MDService.ConfigTryGetAsync("regExp_KO"); + regExp_OK = await MDService.ConfigTryGetAsync("regExp_OK"); + regExp_KitStart = await MDService.ConfigTryGetAsync("regExp_KitStart"); + regExp_KitSave = await MDService.ConfigTryGetAsync("regExp_KitSave"); // altre variabili - rawVal = MDService.ConfigTryGet("SPEC_nArtSearch"); + rawVal = await MDService.ConfigTryGetAsync("SPEC_nArtSearch"); if (!string.IsNullOrEmpty(rawVal)) { int.TryParse(rawVal, out minChar); diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 4becd8d6..aa03794f 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -441,40 +441,6 @@ namespace MP.SPEC.Data return result; } - /// - /// Recupero tab config in modalità Sincrona - /// - /// - public List ConfigGetAll() - { - using var activity = ActivitySource.StartActivity("ConfigGetAll"); - string source = "REDIS"; - List? result = new List(); - // cerco in redis... - RedisValue rawData = redisDb.StringGet($"{Utils.redisConfKey}_sync"); - if (!string.IsNullOrEmpty($"{rawData}")) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - } - else - { - source = "DB"; - result = dbController.ConfigGetAll(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet($"{Utils.redisConfKey}_sync", rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"ConfigGetAll Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; - } - /// /// Recupero tab config in modalità Asincrona /// @@ -504,29 +470,6 @@ namespace MP.SPEC.Data LogTrace($"ConfigResetCacheAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); } - /// - /// Restituisce valore della stringa (SE disponibile) - /// - /// - /// - public string ConfigTryGet(string keyName) - { - using var activity = ActivitySource.StartActivity("ConfigTryGet"); - string source = "MEMORY"; - - EnsureConfigLoaded(); - - _configData.TryGetValue(keyName, out var value); - - activity?.SetTag("data.source", source); - activity?.Stop(); - if (activity?.Duration.TotalMilliseconds > slowLogThresh) - { - LogTrace($"ConfigTryGet | {keyName} | {source} | {activity?.Duration.TotalMilliseconds}ms"); - } - return value ?? ""; - } - /// /// Restituisce valore della stringa (SE disponibile) - modalità async /// @@ -2608,18 +2551,6 @@ namespace MP.SPEC.Data } } - private void EnsureConfigLoaded() - { - if (_configData.Count == 0) - { - var list = ConfigGetAll(); - - _configData = list - .GroupBy(x => x.Chiave) - .ToDictionary(g => g.Key, g => g.First().Valore); - } - } - private async Task EnsureConfigLoadedAsync() { if (_configData.Count == 0) diff --git a/MP.SPEC/Pages/KIT.razor.cs b/MP.SPEC/Pages/KIT.razor.cs index 30eb1275..afc11b64 100644 --- a/MP.SPEC/Pages/KIT.razor.cs +++ b/MP.SPEC/Pages/KIT.razor.cs @@ -196,30 +196,30 @@ namespace MP.SPEC.Pages await ResetDataAsync(); } - protected override void OnInitialized() + protected override async Task OnInitializedAsync() { numRecord = 10; - string rawVal = MDService.ConfigTryGet("SPEC_nArtSearch"); + string rawVal = await MDService.ConfigTryGetAsync("SPEC_nArtSearch"); if (!string.IsNullOrEmpty(rawVal)) { int.TryParse(rawVal, out minChar); } - rawVal = MDService.ConfigTryGet("AZIENDA"); + rawVal = await MDService.ConfigTryGetAsync("AZIENDA"); if (!string.IsNullOrEmpty(rawVal)) { CodAzienda = rawVal; } - rawVal = MDService.ConfigTryGet("SPEC_Kit_enabCount"); + rawVal = await MDService.ConfigTryGetAsync("SPEC_Kit_enabCount"); if (!string.IsNullOrEmpty(rawVal)) { bool.TryParse(rawVal, out enabKitCount); } - rawVal = MDService.ConfigTryGet("SPEC_Kit_enabSearch"); + rawVal = await MDService.ConfigTryGetAsync("SPEC_Kit_enabSearch"); if (!string.IsNullOrEmpty(rawVal)) { bool.TryParse(rawVal, out enabKitSearch); } - rawVal = MDService.ConfigTryGet("SPEC_Kit_enabFreeCodArt"); + rawVal = await MDService.ConfigTryGetAsync("SPEC_Kit_enabFreeCodArt"); if (!string.IsNullOrEmpty(rawVal)) { bool.TryParse(rawVal, out enabFreeCodArt); diff --git a/MP.SPEC/Pages/Podl2Kit.razor.cs b/MP.SPEC/Pages/Podl2Kit.razor.cs index f73d2fe0..ab58f170 100644 --- a/MP.SPEC/Pages/Podl2Kit.razor.cs +++ b/MP.SPEC/Pages/Podl2Kit.razor.cs @@ -146,22 +146,22 @@ namespace MP.SPEC.Pages await ResetDataAsync(); } - protected override void OnInitialized() + protected override async Task OnInitializedAsync() { numRecord = 10; // gestione di base dei KIT - string rawVal = MDService.ConfigTryGet("OptAdmKitEnabled"); + string rawVal = await MDService.ConfigTryGetAsync("OptAdmKitEnabled"); if (!string.IsNullOrEmpty(rawVal)) { bool.TryParse(rawVal, out OptAdmKitEnabled); } // conf variabili decodifica - regExp_KO = MDService.ConfigTryGet("regExp_KO"); - regExp_OK = MDService.ConfigTryGet("regExp_OK"); - regExp_KitStart = MDService.ConfigTryGet("regExp_KitStart"); - regExp_KitSave = MDService.ConfigTryGet("regExp_KitSave"); + regExp_KO = await MDService.ConfigTryGetAsync("regExp_KO"); + regExp_OK = await MDService.ConfigTryGetAsync("regExp_OK"); + regExp_KitStart = await MDService.ConfigTryGetAsync("regExp_KitStart"); + regExp_KitSave = await MDService.ConfigTryGetAsync("regExp_KitSave"); // altre variabili - rawVal = MDService.ConfigTryGet("SPEC_nArtSearch"); + rawVal = await MDService.ConfigTryGetAsync("SPEC_nArtSearch"); if (!string.IsNullOrEmpty(rawVal)) { int.TryParse(rawVal, out minChar); From f697e2413aa9d62a03bcdd65ed9670822475f623 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 29 May 2026 07:54:37 +0200 Subject: [PATCH 063/102] Ripartenza da refactor plan x nuova sessione --- Refactor_Plan.md | 73 +++------------------------------------------- Refactor_Plan.pdf | Bin 0 -> 70907 bytes 2 files changed, 4 insertions(+), 69 deletions(-) create mode 100644 Refactor_Plan.pdf diff --git a/Refactor_Plan.md b/Refactor_Plan.md index 9bf60fed..9acc4787 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -1,5 +1,9 @@ # Piano di Refactoring: Migrazione a FusionCache in `MpDataService.cs` +Stiamo lavorando sul progetto MP-SPEC.sln, dentro la cartella MP-SPEC (ed i progetti da cui dipende). + +Voglio ottimizzare il file Data\MpDataService.cs + ## Obiettivo Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCache` per implementare un approccio multi-layer (Memory + Redis + DB), standardizzando l'accesso ai dati. @@ -13,75 +17,6 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa ### Fase 2: Refactoring Metodi di Lettura (Cache-aside) -#### ✅ Completati (Migrati con `GetOrFetchAsync`) -- `ActionGetReq` -- `AnagEventiGeneralAsync` -- `AnagStatiCommAsync` -- `AnagTipoArtLvAsync` -- `ArticleWithDossierAsync` -- `ArticoliGetByTipoAsync` -- `ArticoliGetSearchAsync` -- `ConfigGetAllAsync` -- `DossiersGetLastFiltAsync` -- `ElencoAziendeAsync` -- `ElencoGruppiFaseAsync` -- `ElencoLinkAsync` -- `FluxLogGetLastFiltAsync` -- `FluxLogParetoAsync` -- `OperatoriGetFiltAsync` -- `POdlGetByOdlAsync` -- `POdlListGetFiltAsync` -- `TksScoreAsync` -- `WipKitFiltAsync` -- `MacchineRecipeArchiveAsync` -- `MacchineRecipeConfAsync` - -#### ⏳ In corso / Da Migrare -- `AnagEventiGetByMacch` -- `AnagKeyValGetAll` -- `ConfigGetAll` (Sincrono) -- `ConfigTryGet` (Sincrono) -- `ConfigTryGetAsync` -- `DbDedupStats` -- `ElencoRepartiDTO` -- `ExpiryReloadParamGet` -- `IobInfo` -- `ListPODL_ByCodArt` -- `MacchineGetFilt` -- `MachIobConf` -- `MachIobConfVal` -- `MseGetAll` -- `OdlByBatch` -- `OdlGetCurrentAsync` -- `OdlListGetFilt` -- `OperatoriGetFilt` (Sincrono) -- `ParametriGetFilt` -- `POdlGetByKey` -- `POdlListByKitParent` -- `ProcFLStats` -- `StatoMacchina` -- `TagConfGetKey` -- `VocabolarioGetAll` - -### Fase 3: Refactoring Metodi di Scrittura e Invalidazione -- [ ] `AnagGruppiDelete` -- [ ] `AnagGruppiUpsert` -- [ ] `ArticoliDeleteRecord` -- [ ] `ArticoliUpdateRecord` -- [ ] `ConfigResetCache` -- [ ] `DossiersDeleteRecord` -- [ ] `DossiersTakeParamsSnapshotLast` -- [ ] `IstKitDelete` -- [ ] `IstKitInsertByWKS` -- [ ] `IstKitUpsert` -- [ ] `PodlIstKitDelete` -- [ ] `POdlDoSetup` -- [ ] `POdlUpdateRecipe` -- [ ] `POdlUpdateRecord` -- [ ] `RecipeSetByPODL` -- [ ] `TemplateKitDelete` -- [ ] `TemplateKitUpsert` - #### Fase 4: Verifica - [ ] Verificare la compilazione della soluzione tramite script PowerShell. diff --git a/Refactor_Plan.pdf b/Refactor_Plan.pdf new file mode 100644 index 0000000000000000000000000000000000000000..18fab5be581e81f1f6cbe0f5bd3f67da1e32f66a GIT binary patch literal 70907 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

                                                                                  el-6*zk(koQj2N#h)SbkG=M?LZs*~Q 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 Date: Fri, 29 May 2026 08:33:43 +0200 Subject: [PATCH 064/102] Update gestione vocabolario con FusionCache --- AGENTS.md | 6 +- MP.Data/Controllers/MpSpecController.cs | 31 ++++++--- MP.SPEC/Data/MpDataService.cs | 92 +++++++++++-------------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- Refactor_Plan.md | 84 +++++++++++++++++++++- 8 files changed, 153 insertions(+), 68 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 16215e2e..1a45c898 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,10 +5,11 @@ - **Language**: C# (primary), PowerShell (scripts). - **Documentation/Comments**: MUST be in **Italiano**. - **Code Style**: Maintain existing region organization (`#region Public Methods`, etc.). +- **Reference Docs**: See `Refactor_Plan.md` for the current migration status and detailed strategy. ## Development Workflow - **Build & Verification**: - - Use a PowerShell script to build the solution to ensure continuous compilability. + - Use `./build_all_par.ps1 --agent` to build all solutions silently. - Always verify that changes do not leave partial traces of old classes that break compilation. - **Refactoring Strategy (`MpDataService.cs`)**: - Use `GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tags)` as the standard for all data access. @@ -19,4 +20,5 @@ ## Architecture Notes - **Multi-Layer Caching**: The system is transitioning from a dual-layer (Redis + DB) to a triple-layer approach via `IFusionCache`. - **Service Responsibility**: `MpDataService` is the central hub for data access, interacting with `MpSpecController` (EFCore) and `MpMongoController` (MongoDB). -- **Key Management**: Cache keys are heavily managed via `Utils.redis...` constants. +- **Key Management**: Cache keys are heavily managed via `Utils.redis...` constants. Use these to prevent key mismatches. + diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index b8d88d7e..d2a22b27 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -2627,21 +2627,36 @@ namespace MP.Data.Controllers } ///

                                                                                  - /// Elenco Vocabolario (completo) + /// Elenco Vocabolario di una lingua /// /// - public List VocabolarioGetAll() + public Dictionary VocabolarioGetLang(string lingua) { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx + using var dbCtx = new MoonProContext(options); + var rawList = dbCtx .DbSetVocabolario .AsNoTracking() + .Where(x => x.Lingua.ToLower() == lingua.ToLower()) .OrderBy(x => x.Lemma) .ToList(); - } - return dbResult; + // Proietto in dizionario + return rawList + .DistinctBy(t => t.Lemma, StringComparer.OrdinalIgnoreCase) + .ToDictionary(t => t.Lemma, t => t.Traduzione, StringComparer.OrdinalIgnoreCase); + } + + /// + /// Elenco Vocabolario (completo) async + /// + /// + public async Task> VocabolarioGetAllAsync() + { + using var dbCtx = new MoonProContext(options); + return await dbCtx + .DbSetVocabolario + .AsNoTracking() + .OrderBy(x => x.Lemma) + .ToListAsync() ?? new(); } /// diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index aa03794f..e3a4ff68 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -961,8 +961,6 @@ namespace MP.SPEC.Data string source = "REDIS"; RedisValue pattern = Utils.RedValue("*"); bool answ = await ExecFlushRedisPatternAsync(pattern); - // rileggo vocabolario.,.. - ObjVocabolario = VocabolarioGetAll(); activity?.Stop(); LogTrace($"FlushRedisCache | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return answ; @@ -2260,53 +2258,31 @@ namespace MP.SPEC.Data /// public string Traduci(string lemma, string lingua) { - string answ = $"[{lemma}]"; - // verifico se ho qualcosa nell'obj vocabolario... - if (ObjVocabolario == null || ObjVocabolario.Count == 0) - { - // inizializzo il vocabolario... - ObjVocabolario = VocabolarioGetAll(); - } - var record = ObjVocabolario.Where(x => x.Lingua == lingua && x.Lemma == lemma).FirstOrDefault(); - if (record != null) - { - answ = record.Traduzione; - } - return answ; - } + if (string.IsNullOrWhiteSpace(lemma)) return string.Empty; + if (string.IsNullOrWhiteSpace(lingua)) return lemma; - /// - /// Elenco completo tabella Vocabolario - /// - /// - public List VocabolarioGetAll() - { - List? result = new List(); - using var activity = ActivitySource.StartActivity("VocabolarioGetAll"); - string source = "REDIS"; - // cerco in redis... - RedisValue rawData = redisDb.StringGet(Utils.redisVocabolario); - if (!string.IsNullOrEmpty($"{rawData}")) + string linguaKey = lingua.ToLowerInvariant().Trim(); + string cacheKey = $"vocab:{linguaKey}"; + + // FusionCache gestisce il lock e recupera l'intero dizionario della lingua. + // Se è in L1 (Memory), restituisce l'oggetto C# istantaneamente. + // Se non c'è, passa a L2 (Redis) o invoca la factory per caricarlo. + var dizionarioLingua = _cache.GetOrSet>( + cacheKey, + _ => dbController.VocabolarioGetLang(linguaKey), + options => options + .SetDuration(TimeSpan.FromHours(8)) // Durata logica della cache + .SetFailSafe(true, TimeSpan.FromHours(1)) // Se Redis/DB è giù, usa i vecchi dati L1 + ); + + // Ricerca O(1) nel dizionario in memoria + if (dizionarioLingua != null && dizionarioLingua.TryGetValue(lemma, out var traduzione)) { - result = JsonConvert.DeserializeObject>($"{rawData}"); + return traduzione; } - else - { - result = dbController.VocabolarioGetAll(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(Utils.redisVocabolario, rawData, getRandTOut(redisLongTimeCache / 5)); - source = "DB"; - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"VocabolarioGetAll Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + + // Fallback: se la parola non è censita, restituisce il lemma originale + return lemma; } /// @@ -2496,11 +2472,6 @@ namespace MP.SPEC.Data private string MpIoNS = ""; - /// - /// Oggetto vocabolario x uso continuo traduzione - /// - private List ObjVocabolario = new List(); - private Random rand = new Random(); /// @@ -2551,6 +2522,10 @@ namespace MP.SPEC.Data } } + /// + /// Verifica caricamento dizionario ConfigData + /// + /// private async Task EnsureConfigLoadedAsync() { if (_configData.Count == 0) @@ -2562,6 +2537,21 @@ namespace MP.SPEC.Data .ToDictionary(g => g.Key, g => g.First().Valore); } } + /// + /// Verifica caricamento Vocabolario + /// + /// + private async Task EnsureVocabolarioLoadedAsync() + { + if (_configData.Count == 0) + { + var list = await ConfigGetAllAsync(); + + _configData = list + .GroupBy(x => x.Chiave) + .ToDictionary(g => g.Key, g => g.First().Valore); + } + } /// /// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria + tracking attività diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index c680ce10..24597231 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2907 + 8.16.2605.2908 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index df4ddb74..7f15ac9a 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                                  Versione: 8.16.2605.2907

                                                                                  +

                                                                                  Versione: 8.16.2605.2908


                                                                                  Note di rilascio:
                                                                                  • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 9badb5e0..2fdfac52 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2907 +8.16.2605.2908 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index c4e2bf54..103d2e8c 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2907 + 8.16.2605.2908 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/Refactor_Plan.md b/Refactor_Plan.md index 9acc4787..a6679d5d 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -14,16 +14,94 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa ## Stato Avanzamento ### Fase 1: Analisi e Mapping (Completata) +- Analisi di `MpDataService.cs` effettuata. +- Identificati i metodi con caching manuale (Redis/DB) e quelli già migrati a `GetOrFetchAsync`. -### Fase 2: Refactoring Metodi di Lettura (Cache-aside) +# Piano di Refactoring: Migrazione a FusionCache in `MpDataService.cs` +Stiamo lavorando sul progetto MP-SPEC.sln, dentro la cartella MP-SPEC (ed i progetti da cui dipende). -#### Fase 4: Verifica +Voglio ottimizzare il file Data\MpDataService.cs + +## Obiettivo +Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCache` per implementare un approccio multi-layer (Memory + Redis + DB), standardizzando l'accesso ai dati. + +## Strategia di Migrazione +- **Metodo Standard**: `GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tagList)`. +- **Invalidazione**: Utilizzare i tag tramite `FlushCacheByTagsAsync`. + +## Stato Avanzamento + +### Fase 1: Analisi e Mapping (Completata) +- Analisi di `MpDataService.cs` effettuata. +- Identificati i metodi con caching manuale (Redis/DB) e quelli già migrati a `GetOrFetchAsync`. + +### Fase 2: Refactoring Metodi di Lettura (Cache-aside) (In corso) + +#### ✅ Metodi Migrati (Usano già `GetOrFetchAsync`) +- `AnagEventiGeneralAsync` +- `AnagStatiCommAsync` +- `AnagTipoArtLvAsync` +- `ArticleWithDossierAsync` +- `ArticoliCountAsync` +- `ArticoliCountSearchAsync` +- `ArticoliGetByTipoAsync` +- `ArticoliGetSearchAsync` +- `ArticoliInKitAsync` +- `ConfigGetAllAsync` +- `DossiersGetLastFiltAsync` +- `ElencoAziendeAsync` +- `ElencoGruppiFaseAsync` +- `ElencoLinkAsync` +- `IstKitFiltAsync` +- `ListGiacenzeAsync` +- `MacchineGetFiltAsync` +- `MacchineRecipeArchiveAsync` +- `MacchineRecipeConfAsync` +- `MacchineWithFluxAsync` +- `MachineWithOdlAsync` +- `MachIobConfAsync` +- `OdlListGetFiltAsync` +- `OperatoriGetFiltAsync` +- `ParametriGetFiltAsync` +- `PODL_getDictOdlPodlAsync` (Parziale/Ibrido) +- `POdlGetByOdlAsync` +- `POdlToKitListGetFiltAsync` +- `StatoMacchinaAsync` +- `TksScoreAsync` +- `WipKitFiltAsync` + +#### 🛠️ Metodi da Migrare (Usano ancora Redis/DB manuale) +- [ ] Migrazione di `ActionGetReq` (linea 110: usa `redisDb.StringGetAsync`). +- [ ] Migrazione di `ActionSetReq` (linea 136: usa `BroadastMsgPipe.saveAndSendMessage`). +- [ ] Migrazione di `AnagGruppiDelete`/`Upsert` (linea 189/208: usa `ExecFlushRedisPattern`). +- [ ] Migrazione di `ArticoliDeleteRecord`/`UpdateRecord` (linea 296/372: usa `resetCacheArticoli`). +- [ ] Migrazione di `DbDedupStats` (linea 516: usa `redisDb.StringGet`). +- [ ] Migrazione di `DossiersDeleteRecord` (linea 554: usa `ExecFlushRedisPatternAsync`). +- [ ] Migrazione di `DossiersTakeParamsSnapshotLast` (linea 613: usa `ExecFlushRedisPatternAsync`). +- [ ] Migrazione di `ElencoRepartiDTO` (linea 697: usa `redisDb.StringGet` e `StringSet`). +- [ ] Migrazione di `MseGetAll` (linea 1460: usa `redisDb.StringGet` e `StringSetAsync`). +- [ ] Migrazione di `OdlByBatch` (linea 1512: usa `redisDb.StringGet` e `StringSet`). +- [ ] Migrazione di `OdlByKey` (linea 1546: usa `redisDb.StringGet` e `StringSet`). +- [ ] Migrazione di `PODL_getByKey` (linea 1779: usa `redisDb.StringGet` e `StringSet`). +- [ ] Migrazione di `PodlIstKitDelete` (linea 1842: usa `ExecFlushRedisPattern`). +- [ ] Migrazione di `POdlListByKitParent` (linea 1863: usa `redisDb.StringGet` e `StringSet`). +- [ ] Migrazione di `ProcFLStats` (linea 1992: usa `redisDb.StringSet`). +- [ ] Migrazione di `RecDbMaintStat` (linea 2451: usa `redisDb.StringSet`). +- [ ] Migrazione di `VocabolarioGetAll` (linea 2278: usa `redisDb.StringGet` e `StringSet`). + +### Fase 4: Verifica - [ ] Verificare la compilazione della soluzione tramite script PowerShell. -- [ ] Controllare che i log (NLog) continuino a riflettere correttamente le operazioni. +- [ ] Controllare che i log (NLog) continuano a riflettere correttamente le operazioni. ## Rischi e Mitigazioni - **Rischio**: Discrepanza nelle chiavi di cache tra vecchio e nuovo sistema. - *Mitigazione*: Utilizzare rigorosamente le costanti in `Utils.redis...` per garantire che le chiavi siano identiche o gestite dal nuovo sistema. - **Rischio**: Errori di serializzazione. - *Mitigazione*: `FusionCache` gestisce la serializzazione, ma è necessario assicurarsi che i tipi di ritorno siano compatibili con le aspettative dei chiamanti. + + +### Fase 4: Verifica +- [ ] Verificare la compilazione della soluzione tramite script PowerShell. +- [ ] Controllare che i log (NLog) continuano a riflettere correttamente le operazioni. + From 582004c60583d52f6dcf1049630922ed80061420 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 29 May 2026 08:40:22 +0200 Subject: [PATCH 065/102] Rimosso vocabolario da IOC(non serve...) + cleanup generale IOC e SPEC per pulizia --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.Data/Controllers/MpSpecController.cs | 7 +- MP.Data/Services/ListSelectDataSrv.cs | 6 - MP.Data/Services/OrderDataSrv.cs | 6 - MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/Data/MpDataService.cs | 1348 +---------------------- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.SPEC/Data/MpDataService.cs | 1 - MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- Refactor_Plan.md | 35 +- 38 files changed, 67 insertions(+), 1400 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index 24212401..722b07cd 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2605.2907 + 8.16.2605.2908 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index df4ddb74..7f15ac9a 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                                    Versione: 8.16.2605.2907

                                                                                    +

                                                                                    Versione: 8.16.2605.2908


                                                                                    Note di rilascio:
                                                                                    • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 9badb5e0..2fdfac52 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2907 +8.16.2605.2908 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index d26f6752..a3387c78 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2907 + 8.16.2605.2908 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index d2a22b27..32575fc1 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -15,7 +15,7 @@ using static EgwCoreLib.Utils.DtUtils; namespace MP.Data.Controllers { - public class MpSpecController : IDisposable + public class MpSpecController { #region Public Constructors @@ -734,11 +734,6 @@ namespace MP.Data.Controllers return dbResult; } - public void Dispose() - { - _configuration = null; - } - /// /// Eliminazione di un dossier /// diff --git a/MP.Data/Services/ListSelectDataSrv.cs b/MP.Data/Services/ListSelectDataSrv.cs index 1452f71a..80cc2102 100644 --- a/MP.Data/Services/ListSelectDataSrv.cs +++ b/MP.Data/Services/ListSelectDataSrv.cs @@ -254,12 +254,6 @@ namespace MP.Data.Services { if (!_disposed) { - if (disposing) - { - // Free managed resources here - dbController.Dispose(); - } - // Free unmanaged resources here _disposed = true; } diff --git a/MP.Data/Services/OrderDataSrv.cs b/MP.Data/Services/OrderDataSrv.cs index 42e0efdb..e974f441 100644 --- a/MP.Data/Services/OrderDataSrv.cs +++ b/MP.Data/Services/OrderDataSrv.cs @@ -131,12 +131,6 @@ namespace MP.Data.Services { if (!_disposed) { - if (disposing) - { - // Free managed resources here - dbController.Dispose(); - } - // Free unmanaged resources here _disposed = true; } diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index d97f422a..a797534f 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2605.2907 + 8.16.2605.2908 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index d2983759..d596732c 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                                                                      Versione: 8.16.2605.2907

                                                                                      +

                                                                                      Versione: 8.16.2605.2908


                                                                                      Note di rilascio:
                                                                                      • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index 9badb5e0..2fdfac52 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2907 +8.16.2605.2908 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index c4f54211..501709a5 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2907 + 8.16.2605.2908 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs index 73bd612f..f11e2a3c 100644 --- a/MP.IOC/Data/MpDataService.cs +++ b/MP.IOC/Data/MpDataService.cs @@ -19,7 +19,7 @@ using static MP.Core.Objects.Enums; namespace MP.IOC.Data { - public class MpDataService : IDisposable + public class MpDataService { #region Public Constructors @@ -97,51 +97,6 @@ namespace MP.IOC.Data #region Public Methods - /// - /// Recupera eventuali azioni richieste - /// - /// - public async Task ActionGetReq() - { - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - DisplayAction? result = null; - // cerco in redis... - RedisValue rawData = await redisDb.StringGetAsync(Utils.redisActionReq); - if (!string.IsNullOrEmpty($"{rawData}")) - { - result = JsonConvert.DeserializeObject($"{rawData}"); - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"ActionGetReq Read from REDIS: {ts.TotalMilliseconds}ms"); - } - if (result == null) - { - result = new DisplayAction(); - } - return result; - } - - /// - /// Salva richiesta azione - /// - /// - /// - public bool ActionSetReq(DisplayAction? act2save) - { - bool fatto = false; - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - // cerco in redis... - string rawData = JsonConvert.SerializeObject(act2save); - // invio broadcast + salvo in redis - BroadastMsgPipe.saveAndSendMessage(Utils.redisActionReq, rawData); - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"ActionSetReq REDIS send to broadcast + Write cache: {ts.TotalMilliseconds}ms"); - return fatto; - } - /// /// Verifica se sia da reinviare un tName alla macchina dall'elenco di quelli salvati (in /// modalità upsert) se non scaduti @@ -355,37 +310,6 @@ namespace MP.IOC.Data return answ; } - public async Task> AnagStatiComm() - { - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - List? result = new List(); - // cerco in redis... - RedisValue rawData = await redisDb.StringGetAsync(Utils.redisStatoCom); - if (!string.IsNullOrEmpty($"{rawData}")) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"AnagStatiComm Read from REDIS: {ts.TotalMilliseconds}ms"); - } - else - { - result = await SpecDbController.AnagStatiCommAsync(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(Utils.redisStatoCom, rawData, getRandTOut(redisLongTimeCache)); - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"AnagStatiComm Read from DB: {ts.TotalMilliseconds}ms"); - } - if (result == null) - { - result = new List(); - } - return result; - } - /// /// Restituisce l'anagrafica STATI per intero /// @@ -410,83 +334,6 @@ namespace MP.IOC.Data return dbResult; } - public async Task> AnagTipoArtLV() - { - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string source = "DB"; - List? result = new List(); - // cerco in redis... - RedisValue rawData = await redisDb.StringGetAsync(Utils.redisTipoArt); - if (!string.IsNullOrEmpty($"{rawData}")) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await SpecDbController.AnagTipoArtLvAsync(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(Utils.redisTipoArt, rawData, getRandTOut(redisLongTimeCache)); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"AnagTipoArtLV Read from {source}: {ts.TotalMilliseconds}ms"); - if (result == null) - { - result = new List(); - } - return result; - } - - /// - /// Elenco Codice articolo con dati dossier gestiti - /// - /// - public async Task> ArticleWithDossier() - { - List? result = new List(); - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - string currKey = Utils.redisArtByDossier; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - readType = "REDIS"; - } - else - { - result = await Task.FromResult(SpecDbController.ArticleWithDossier()); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"ArticleWithDossier | Read from {readType}: {ts.TotalMilliseconds}ms"); - return result; - } - - /// - /// Eliminazione record selezionato - /// - /// - /// - public async Task ArticoliDeleteRecord(AnagArticoliModel currRec) - { - bool fatto = await SpecDbController.ArticoliDeleteRecord(currRec); - await resetCacheArticoli(); - return fatto; - } - /// /// Elenco ultimi articoli data amcchina /// @@ -523,125 +370,6 @@ namespace MP.IOC.Data return result; } - /// - /// Restitusice elenco articoli cercati - /// - /// - /// - /// - /// - /// - public async Task> ArticoliGetSearchAsync(int numRecord, string tipoArt, string azienda, string searchVal) - { - List? result = new List(); - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - string sKey = string.IsNullOrEmpty(searchVal) ? "***" : searchVal; - string currKey = $"{Utils.redisArtList}:{azienda}:{tipoArt}:{sKey}"; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - readType = "REDIS"; - } - else - { - result = await SpecDbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache / 5)); - } - if (result == null) - { - result = new List(); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"ArticoliGetSearchAsync | Read from {readType}: {ts.TotalMilliseconds}ms"); - return result; - } - - /// - /// Aggiornamento record selezionato - /// - /// - /// - public async Task ArticoliUpdateRecord(AnagArticoliModel currRec) - { - bool fatto = await SpecDbController.ArticoliUpdateRecord(currRec); - await resetCacheArticoli(); - return fatto; - } - - /// - /// Verifica se sia possiubile cancellare articolo dato suo CodArt cercando su redis o su - /// tab veto da DB - /// - /// - /// - public bool ArticoloDelEnabled(object CodArt) - { - bool answ = false; - string codArticolo = $"{CodArt}"; - int cacheCheckArtUsato = 1; - int.TryParse(_configuration.GetValue("ServerConf:cacheCheckArtUsato"), out cacheCheckArtUsato); - TimeSpan TTLCache = getRandTOut(cacheCheckArtUsato); - // cerco in cache redis... - string redKeyArtUsed = $"{Utils.redKeyArtUsed}:{codArticolo}"; - string redKeyTabCheckArt = Utils.redKeyTabCheckArt; - var rawData = redisDb.StringGet(redKeyArtUsed); - if (!string.IsNullOrEmpty(rawData)) - { - bool.TryParse(rawData, out answ); - } - else - { - // controllo non sia stato mai prodotto sennò non posso cancellare... - try - { - // cerco in cache se ci sia la tabella con gli articoli impiegati... - var rawTable = redisDb.StringGet(redKeyTabCheckArt); - List? artList = new List(); - if (!string.IsNullOrEmpty(rawTable)) - { - artList = JsonConvert.DeserializeObject>($"{rawTable}"); - } - // rileggo... - if (artList == null || artList.Count == 0) - { - artList = new List(); - var tabArticoli = SpecDbController.ArticoliGetUsed(); - var codList = tabArticoli.Select(x => x.CodArticolo); - foreach (string cod in codList) - { - artList.Add(cod); - } - // SE fosse vuoto aggiungo comunque il cado "ND"... - if (artList.Count == 0) - { - artList.Add("ND"); - } - // salvo - rawTable = JsonConvert.SerializeObject(artList); - redisDb.StringSet(redKeyTabCheckArt, rawTable, TTLCache); - } - // cerco nella tabella: se ci fosse --> disabilitato delete - bool usato = false; - if (artList != null && artList.Count > 0) - { - usato = artList.Contains(codArticolo); - } - answ = !usato; - redisDb.StringSet(redKeyArtUsed, $"{answ}", TTLCache); - } - catch - { } - } - return answ; - } - /// /// Effettua split ODL /// @@ -1084,59 +812,6 @@ namespace MP.IOC.Data return result; } - /// - /// Reset dati cache config - /// - /// - public async Task ConfigResetCache() - { - await redisDb.StringSetAsync(Utils.redisConfKey, ""); - } - - /// - /// Update chiave config - /// - /// - public Task ConfigUpdateAsync(ConfigModel updRec) - { - return SpecDbController.ConfigUpdateAsync(updRec); - } - - /// - /// Elenco completo valori DatiMacchine - /// - /// - public async Task> DatiMacchineGetAll() - { - List? result = new List(); - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - string currKey = $"{Utils.redisBaseAddr}:TabDatiMacchine:ALL"; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - readType = "REDIS"; - } - else - { - result = await Task.FromResult(SpecDbController.DatiMacchineGetAll()); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"DatiMacchineGetAll | Read from {readType}: {ts.TotalMilliseconds}ms"); - return result; - } - public async Task> DecNumArtGetFiltAsync(string codArt = "") { List result = new(); @@ -1158,17 +833,6 @@ namespace MP.IOC.Data return result; } - /// - /// Dispose del connettore ai dati - /// - public void Dispose() - { - // Clear database controller - SpecDbController.Dispose(); - mongoController.Dispose(); - redisConn.Dispose(); - } - /// /// Restituisce l'elenco delle date dei dossier x una macchina (se presenti) Impiegata anche /// cache redis @@ -1199,202 +863,6 @@ namespace MP.IOC.Data return result; } - /// - /// Eliminazione di un dossier - /// - /// record dossier da eliminare - /// - public async Task DossiersDeleteRecord(DossierModel selRecord) - { - bool result = false; - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - result = await SpecDbController.DossiersDeleteRecord(selRecord); - // elimino cache redis... - RedisValue pattern = new RedisValue($"{Utils.redisDossByMac}:*"); - bool answ = await RedisFlushPatternAsync(pattern); - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"DossiersDeleteRecord | IdxMacchina {selRecord.IdxMacchina} | DtRif {selRecord.DtRif} | IdxODL {selRecord.IdxODL} | {ts.TotalMilliseconds}ms"); - return result; - } - - /// - /// Elenco ultimi n record DOssiers (che contengono ad esempio "salvataggi" di FLuxLog) dato - /// macchina (ordinato x data registrazione) - /// - /// * = tutte, altrimenti solo x una data macchina - /// Data minima per estrazione records - /// Data Massima per estrazione records - /// Num Max records da recuperare - /// - public async Task> DossiersGetLastFilt(string IdxMacchina, string CodArticolo, DateTime DtStart, DateTime DtEnd, int MaxRec) - { - List? result = new List(); - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - string currKey = $"{Utils.redisDossByMac}:{IdxMacchina}:{CodArticolo}:{DtStart:yyyyMMddHHmm}:{DtEnd:yyyyMMddHHmm}:{MaxRec}"; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - readType = "REDIS"; - } - else - { - result = await SpecDbController.DossiersGetLastFiltAsync(IdxMacchina, CodArticolo, DtStart, DtEnd, MaxRec); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache / 5)); - } - if (result == null) - { - result = new List(); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"DossiersGetLastFilt | Read from {readType}: {ts.TotalMilliseconds}ms"); - return result; - } - - /// - /// Inserimento nuovo record dossier - /// - /// - /// - public async Task DossiersInsert(DossierModel currDoss) - { - // aggiorno record sul DB - bool answ = await SpecDbController.DossiersInsert(currDoss); - - return answ; - } - - /// - /// Effettua salvataggio snapshot parametri (con stored) + svuota eventuale cache redis - /// - /// macchina - /// NUm massimo secondi per recuperare dati correnti - /// DataOra riferimento x cui prendere valori antecedenti - /// - public async Task DossiersTakeParamsSnapshotLast(string IdxMacchina, DateTime dtMin, DateTime dtMax) - { - bool answ = false; - await Task.Delay(1); - Log.Info($"Richiesta snapshot per macchina {IdxMacchina} | periodo {dtMin} --> {dtMax}"); - // chiamo stored x salvare parametri - SpecDbController.DossiersTakeParamsSnapshotLast(IdxMacchina, dtMin, dtMax); - // elimino cache redis... - RedisValue pattern = new RedisValue($"{Utils.redisDossByMac}:*"); - answ = await RedisFlushPatternAsync(pattern); - Log.Info($"Svuotata cache dossier | {pattern}"); - return answ; - } - - /// - /// Update valOut dossier - /// - /// - /// - public async Task DossiersUpdateValore(DossierModel currDoss) - { - // aggiorno record sul DB - bool answ = await SpecDbController.DossiersUpdateValore(currDoss); - - return answ; - } - - /// - /// Restitusice elenco aziende - /// - /// - public Task> ElencoAziende() - { - return SpecDbController.AnagGruppiAziendeAsync(); - } - - /// - /// Restitusice elenco fasi - /// - /// - public async Task> ElencoGruppiFaseAsync() - { - List result = new List(); - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - string currKey = $"{Utils.redisAnagGruppi}"; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - var rawResult = JsonConvert.DeserializeObject>($"{rawData}"); - if (rawResult != null) - { - result = rawResult; - } - readType = "REDIS"; - } - else - { - result = await SpecDbController.AnagGruppiFaseAsync(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache / 5)); - } - if (result == null) - { - result = new List(); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"ElencoGruppiFaseAsync | Read from {readType}: {ts.TotalMilliseconds}ms"); - return result; - } - - /// - /// Aggiunta record EventList - /// - /// - /// - public async Task EvListInsert(EventListModel newRec) - { - return await SpecDbController.EvListInsert(newRec); - } - - /// - /// Imposta in redis la scadenza della pagina x il reload - /// - /// - /// - public DateTime ExpiryReloadParamGet() - { - DateTime dtRif = DateTime.Now; - string currKey = $"{Utils.redisParamPageExp}"; - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - dtRif = JsonConvert.DeserializeObject($"{rawData}"); - } - return dtRif; - } - - /// - /// Imposta in redis la scadenza della pagina x il reload - /// - /// - /// - public bool ExpiryReloadParamSet(DateTime expTime) - { - bool fatto = false; - string currKey = $"{Utils.redisParamPageExp}"; - string rawData = JsonConvert.SerializeObject(expTime); - fatto = redisDb.StringSet(currKey, rawData); - return fatto; - } - /// /// Task completo sistemazione dossier quotidiani mancanti /// @@ -1476,24 +944,6 @@ namespace MP.IOC.Data return answ; } - public async Task FlushRedisCache() - { - await Task.Delay(1); - RedisValue pattern = Utils.RedValue("*"); - bool answ = await RedisFlushPatternAsync(pattern); - // rileggo vocabolario.,.. - ObjVocabolario = VocabolarioGetAll(); - return answ; - } - - public async Task FlushRedisKey(string redKey) - { - await Task.Delay(1); - RedisValue pattern = Utils.RedValue(redKey); - bool answ = await RedisFlushPatternAsync(pattern); - return answ; - } - public List FluxLogDtoGetByFlux(string Valore) { List answ = new List(); @@ -1516,53 +966,6 @@ namespace MP.IOC.Data return answ; } - /// - /// Elenco ultimi n record flux log dato macchina e flusso (ordinato x data registrazione) - /// - /// Data massima x eventi - /// Data minima x eventi - /// * = tutte, altrimenti solo x una data macchina - /// *=tutti, altrimenti solo selezionato - /// numero massimo record da restituire - /// - public async Task> FluxLogGetLastFilt(DateTime DtMax, DateTime DtMin, string IdxMacchina, string CodFlux, int MaxRec, double redisCacheSec) - { - List? result = new List(); - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - string currKey = $"{Utils.redisFluxLogFilt}:{IdxMacchina}:{CodFlux}:{MaxRec}:{DtMax:yyyyMMddHHmm}:{DtMin:yyyyMMddHHmm}"; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - readType = "REDIS"; - } - else - { - result = await SpecDbController.FluxLogGetLastFiltAsync(DtMax, DtMin, IdxMacchina, CodFlux, MaxRec); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - if (string.IsNullOrEmpty(canCacheParametri)) - { - canCacheParametri = await tryGetConfigAsync("SPEC_ParametriEnableRedisCache"); - } - if (canCacheParametri != "false") - { - redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisCacheSec)); - } - } - if (result == null) - { - result = new List(); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"FluxLogGetLastFilt | Read from {readType}: {ts.TotalMilliseconds}ms"); - return result; - } - /// /// Restituisce il valOut dell'ODL corrente (ODL deve esserci per gestione contapezzi, senza /// ODL NO invio/gestione ODL) @@ -1589,32 +992,6 @@ namespace MP.IOC.Data return result; } - /// - /// Restituisce il valOut dell'ODL corrente (ODL deve esserci per gestione contapezzi, senza - /// ODL NO invio/gestione ODL) - /// - /// - /// indica se forzare lettura da db (true) o meno - /// - public async Task GetCurrOdlAsync(string idxMacchina, bool forceDb) - { - string answ = ""; - // se ho forceDB leggo dai dati prod... - if (forceDb) - { - var datiProd = await StatoProdMacchinaAsync(idxMacchina, DateTime.Now, true); - if (datiProd != null) - { - answ = datiProd.IdxOdl.ToString(); - } - } - else - { - answ = await GetCurrOdlAsync(idxMacchina); - } - return answ; - } - /// /// Restituisce il valOut dell'ultimo ODL /// @@ -1692,29 +1069,6 @@ namespace MP.IOC.Data return dataOraEvento; } - /// - /// Restitusice elenco KVP dei TASK (da passare a IOB-WIN) per l'impianto indicato - /// - /// - /// - public async Task> GetTask2ExeMacchinaAsync(string idxMacchina) - { - var currHash = Utils.RedKeyTask2ExeMacc(idxMacchina, MpIoNS); - return await RedisGetHashDictAsync(currHash); - } - - /// - /// Init ricetta - /// - /// - /// - /// - /// - public RecipeModel InitRecipe(string confPath, int idxPODL, Dictionary CalcArgs) - { - return mongoController.InitRecipe(confPath, idxPODL, CalcArgs); - } - /// /// Restituisce il valOut booleano se la macchina sia abilitata all'input /// @@ -1792,41 +1146,6 @@ namespace MP.IOC.Data return answ; } - /// - /// - /// idxMacc odl da cercare - /// - public async Task> ListGiacenzeAsync(int IdxOdl) - { - List? result = new List(); - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - string currKey = $"{Utils.redisGiacenzaList}:{IdxOdl}"; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - readType = "REDIS"; - } - else - { - result = await SpecDbController.ListGiacenzeAsync(IdxOdl); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); - } - if (result == null) - { - result = new List(); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"ListGiacenzeAsync | Read from {readType}: {ts.TotalMilliseconds}ms"); - return result; - } - public async Task> ListValuesFilt(string tabName, string fieldName) { List resultList = new List(); @@ -1963,113 +1282,6 @@ namespace MP.IOC.Data return result ?? ""; } - /// - /// Verifica se la macchina abbia un codice CONF ricetta associato - /// - /// - /// - public async Task MacchineRecipeConf(string idxMacchina) - { - string? result = ""; - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - string currKey = $"{Utils.redisMacRecipeConf}:{idxMacchina}"; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject($"{rawData}"); - readType = "REDIS"; - } - else - { - //recupero elenco macchine... - var machineList = await MacchineGetFilt("*"); - var currMach = machineList.Where(x => x.IdxMacchina == idxMacchina).FirstOrDefault(); - result = currMach != null ? currMach.RecipePath : null; - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"MacchineRecipeConf | Read from {readType}: {ts.TotalMilliseconds}ms"); - return result ?? ""; - } - - /// - /// Elenco idxMacc Macchine che abbiano dati FLuxLog, nel periodo indicato - /// - /// - /// - /// - public async Task> MacchineWithFlux(DateTime dtStart, DateTime dtEnd) - { - List? result = new List(); - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - string currKey = $"{Utils.redisMacByFlux}:{dtStart:yyyyMMddHHmm}:{dtEnd:yyyyMMddHHmm}"; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - readType = "REDIS"; - } - else - { - result = await SpecDbController.MacchineWithFluxAsync(dtStart, dtEnd); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"MacchineWithFlux | Read from {readType}: {ts.TotalMilliseconds}ms"); - return result; - } - - /// - /// Lista parametri correnti (ObjItemDTO) della macchina (ex getCurrObjItems) - /// - /// - /// - public List MachineParamList(string idxMacchina) - { - // setup parametri costanti - string source = "NA"; - Stopwatch sw = new Stopwatch(); - sw.Start(); - List? result = new List(); - // cerco in _redisConn... - var currKey = Utils.RedKeyCurrObjItems(idxMacchina, MpIoNS); - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue && rawData.Length() > 2) - { - var rawVal = JsonConvert.DeserializeObject>($"{rawData}"); - // ordino! - result = rawVal - .OrderBy(x => x.displOrdinal) - .ThenBy(x => x.description) - .ToList(); - source = "REDIS"; - } - if (result == null) - { - result = new List(); - source = "NONE"; - } - sw.Stop(); - Log.Debug($"MachineParamList | {source} | {sw.Elapsed.TotalMilliseconds}ms"); - return result; - } - /// /// Lista parametri correnti (ObjItemDTO) della macchina (ex getCurrObjItems) /// @@ -2375,94 +1587,6 @@ namespace MP.IOC.Data return result; } - /// - /// Elenco ODL dato batch selezionato - /// - /// Batch richiesto - /// - public async Task> OdlByBatch(string BatchSel) - { - List? result = new List(); - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - string currKey = Utils.redisOdlByBatch; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - readType = "REDIS"; - } - else - { - result = await Task.FromResult(SpecDbController.OdlByBatch(BatchSel)); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"OdlByBatch | Read from {readType}: {ts.TotalMilliseconds}ms"); - return result; - } - - /// - /// ODL da chiave - /// - /// - /// - public ODLExpModel OdlByKey(int IdxOdl) - { - ODLExpModel? result = new ODLExpModel(); - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - result = SpecDbController.OdlByKey(IdxOdl); - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"OdlByKey | Read from {readType}: {ts.TotalMilliseconds}ms"); - return result; - } - - /// - /// Effettua chiusura dell'ODL indicato, andand - /// - /// idx odl da chiudere - /// idx macchina - /// matricola operatore - /// indica se confermare i pezzi priam di chiudere ODL - public async Task 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 ConfigGetAllAsync(); - 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 SpecDbController.ODLClose(idxOdl, idxMacchina, matrOpr, confPezzi, confRett, modoConfProd); - } - - return fatto; - } - public async Task OdlCurrByMaccAsync(string IdxMacchina) { ODLExpModel result = new(); @@ -2494,60 +1618,6 @@ namespace MP.IOC.Data return result; } - /// - /// Record ODL da chaive - /// - /// - public async Task OdlGetByKey(int IdxOdl) - { - await Task.Delay(1); - var dbResult = await SpecDbController.OdlGetByKey(IdxOdl); - return dbResult; - } - - /// - /// ODL correnti (tutti) - /// - /// - /// - public async Task> OdlGetCurrentAsync() - { - List? dbResult = new List(); - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - string currKey = $"{Utils.redisOdlCurrByMac}"; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - try - { - dbResult = JsonConvert.DeserializeObject>($"{rawData}"); - } - catch - { } - readType = "REDIS"; - } - else - { - var rawList = await SpecDbController.OdlGetCurrentAsync(); - dbResult = rawList.Select(x => x.IdxMacchina).Distinct().ToList(); - rawData = JsonConvert.SerializeObject(dbResult); - await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(3)); - } - if (dbResult == null) - { - dbResult = new List(); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"OdlGetCurrentAsync | Read from {readType}: {ts.TotalMilliseconds}ms"); - - return dbResult; - } - - /// /// Recupero PODL da chiave /// @@ -2628,60 +1698,6 @@ namespace MP.IOC.Data return result; } - /// - /// Elenco PODL non avviati filtrati x articolo, KeyRich (che contiene stato) - /// - /// Solo lanciati (1) o ancora disponibili (0) - /// KeyRich (parziale) da cercare (es cod stato x yacht) - /// Macchina - /// Gruppo - /// Data inizio - /// Data fine - /// - public async Task> POdlListGetFilt(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) - { - List? result = new List(); - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - string readType = "DB"; - string currKey = $"{Utils.redisPOdlList}:{codGruppo}:{idxMacchina}:{keyRichPart}:{lanciato}:{startDate:yyyyMMdd_HHmmss}:{endDate:yyyyMMdd_HHmmss}"; - // cerco in redis dato valOut sel macchina... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - readType = "REDIS"; - } - else - { - result = await Task.FromResult(SpecDbController.ListPODLFilt(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate)); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); - } - if (result == null) - { - result = new List(); - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"POdlListGetFilt | Read from {readType}: {ts.TotalMilliseconds}ms"); - return result; - } - - /// - /// Aggiornamento record selezionato - /// - /// - /// - public async Task POdlUpdateRecord(PODLModel currRec) - { - var dbResult = await SpecDbController.PODLUpdateRecord(currRec); - // elimino cache redis... - await POdlFlushCache(); - return dbResult; - } - /// /// Processa registrazione FL da IOB /// @@ -3022,22 +2038,6 @@ namespace MP.IOC.Data return result; } - /// - /// Salva ricetta su MongoDB - /// - /// - /// - public async Task RecipeSetByPODL(RecipeModel currRecord) - { - bool answ = false; - answ = await mongoController.RecipeSetByPODL(currRecord); - if (answ) - { - await POdlFlushCache(); - } - return answ; - } - /// /// Effettua conteggio chaivi REDIS dato pattern ricerca /// @@ -3100,31 +2100,6 @@ namespace MP.IOC.Data return await redisDb.KeyDeleteAsync(keyVal); } - /// - /// Esegue flush memoria redis dato keyVal - /// - /// - /// - public bool RedisFlushPattern(string pattern) - { - bool answ = false; - var listEndpoints = redisConnAdmin.GetEndPoints(); - foreach (var endPoint in listEndpoints) - { - var server = redisConnAdmin.GetServer(endPoint); - if (server != null) - { - var keyList = server.Keys(redisDb.Database, pattern); - foreach (var item in keyList) - { - redisDb.KeyDelete(item); - } - answ = true; - } - } - return answ; - } - /// /// Esegue flush memoria redis dato keyVal, async /// @@ -3316,77 +2291,6 @@ namespace MP.IOC.Data return fatto; } - /// - /// Recupera tutti i record di RemoteRebootLog - /// - /// - public async Task> RemRebootLogGetAllAsync() - { - // setup parametri costanti - string source = "DB"; - Stopwatch sw = new Stopwatch(); - sw.Start(); - List result = new List(); - // cerco in _redisConn... - var currKey = $"{Utils.redisRemRebLog}:ALL"; - RedisValue rawData = await redisDb.StringGetAsync(currKey); - //if (!string.IsNullOrEmpty($"{rawData}")) - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}") ?? new(); - source = "REDIS"; - } - else - { - result = await IocDbController.RemRebootLogGetAllAsync(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(30)); - } - if (result == null) - { - result = new List(); - } - sw.Stop(); - Log.Debug($"RemRebootLogGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); - return result; - } - - /// - /// Recupera ultimo record x ogni IdxMacchina x avere ultimo attivo - /// - /// - public async Task> RemRebootLogGetLast() - { - // setup parametri costanti - string source = "DB"; - Stopwatch sw = new Stopwatch(); - sw.Start(); - List result = new List(); - // cerco in _redisConn... - var currKey = $"{Utils.redisRemRebLog}:LAST"; - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}") ?? new(); - source = "REDIS"; - } - else - { - result = await IocDbController.RemRebootLogGetLastAsync(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(currKey, rawData, TimeSpan.FromSeconds(30)); - } - if (result == null) - { - result = new List(); - } - sw.Stop(); - Log.Debug($"RemRebootLogGetLast | {source} | {sw.Elapsed.TotalMilliseconds}ms"); - return result; - } - /// /// Elimina da elenco KVP il TASK per l'impianto indicato /// @@ -3502,119 +2406,6 @@ namespace MP.IOC.Data return answ; } - /// - /// Processa registrazione EVENTO CONTEGGIO PEZZI x una data macchina IOB - /// - /// Macchina - /// Pezzi da registrare - /// DataOra evento - /// DataOra corrente - /// - public async Task SaveCaricoPezziAsync(string idxMacchina, string qty, string dtEve = "", string dtCurr = "") - { - // default: 0, non registrato x cautela... - string answ = "0"; - // Verifica se evento realtime oppure ho data specificata x processing @dtEve - DateTime adesso = DateTime.Now; - DateTime dtEvent = adesso; - bool rtimeProc = string.IsNullOrEmpty(dtEve); - if (!rtimeProc) - { - dtEvent = GetSrvDtEvent(dtEve, dtCurr); - } - // controllo per proseguire - if (!string.IsNullOrEmpty(idxMacchina) && !string.IsNullOrEmpty(qty)) - { - int numPzIncr = -1; - int.TryParse(qty, out numPzIncr); - // se il conteggio è >= 0 SALVO evento... - if (numPzIncr >= 0) - { - var listOdl = await IocDbController.OdlListByMaccPeriodoAsync(idxMacchina, dtEvent, dtEvent.AddSeconds(1)); - if (listOdl != null && listOdl.Count > 0) - { - string codArticolo = listOdl.FirstOrDefault()?.CodArticolo ?? "ND"; - // registro evento 120 --> contapezzi in blocco !!!HARD CODED!!! !!!FIXME!!! - int idxEvento = 120; - // creo evento - EventListModel newRecEv = new EventListModel() - { - CodArticolo = codArticolo, - IdxMacchina = idxMacchina, - IdxTipo = idxEvento, - InizioStato = dtEvent, - MatrOpr = 0, - pallet = "-", - Value = qty - }; - // salva e processa - var resp = await scriviRigaEventoAsync(newRecEv); - // registro in risposta che è andato tutto bene... ovvero la qty richiesta... - answ = qty; - } - } - } - else - { - string errore = $"Errore: mancano parametri macchina/incremento: idxMacchina {idxMacchina} | qty {qty}"; - Log.Error(errore); - answ = errore; - } - return answ; - } - - /// - /// Processa registrazione di un counter x una data macchina IOB - /// - /// - /// contapezzi - /// - public async Task SaveCounterAsync(string idxMacchina, string counter) - { - string answ = "0"; - // inizio processing vero e proprio INPUT... - if (string.IsNullOrEmpty(idxMacchina)) - { - string errore = "Errore: parametro macchina vuoto"; - Log.Info(errore); - answ = errore; - } - else - { - if (string.IsNullOrEmpty(counter)) - { - string errore = "Errore: parametro counter vuoto"; - Log.Error(errore); - answ = errore; - } - else - { - int newCounter = -1; - int.TryParse(counter, out newCounter); - // se il conteggio è >= 0 SALVO come nuovo conteggio... - if (newCounter >= 0) - { - var currKey = Utils.RedKeyPzCount(idxMacchina, MpIoNS); - RedisValue rawData = await redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - // salvo per + tempo... - await redisDb.StringSetAsync(currKey, answ.ToString()); - answ = counter; - } - else - { - int currCount = await PzCounterTcAsync(idxMacchina); - answ = currCount.ToString(); - // salvo per meno tempo... - await redisDb.StringSetAsync(currKey, answ); - } - } - } - } - return answ; - } - public async Task SaveDataItemsAsync(string id, List dataList) { bool answ = false; @@ -3771,104 +2562,6 @@ namespace MP.IOC.Data return answ; } - /// - /// Statistiche ODL calcolate (da stored stp_STAT_ODL) - /// - /// - public Task> StatOdl(int IdxOdl) - { - return SpecDbController.OdlStart(IdxOdl); - } - - /// - /// restituisce il valOut da REDIS associato al tag richeisto - /// - /// Chiave in cui cercare il valOut - /// - public string TagConfGetKey(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; - } - - /// - /// Elenco setup dei tag conf correnti - /// - /// - public Task>> TagsGetAll() - { - return Task.FromResult(currTagConf); - } - - /// - /// Esegue traduzione dato vocabolario da Lingua + Lemma - /// - /// - /// - /// - public string Traduci(string lemma, string lingua) - { - string answ = $"[{lemma}]"; - // verifico se ho qualcosa nell'obj vocabolario... - if (ObjVocabolario == null || ObjVocabolario.Count == 0) - { - // inizializzo il vocabolario... - ObjVocabolario = VocabolarioGetAll(); - } - var record = ObjVocabolario.Where(x => x.Lingua == lingua && x.Lemma == lemma).FirstOrDefault(); - if (record != null) - { - answ = record.Traduzione; - } - return answ; - } - - public async Task updateDossierValue(DossierModel currDoss, FluxLogDTO editFL) - { - bool answ = false; - // recupero intero set valori dossier deserializzando... - var fluxLogList = FluxLogDtoGetByFlux(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 valOut - 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 SpecDbController.DossiersUpdateValore(currDoss); - } - - return answ; - } - /// /// Effettua UPSERT elenco parametri correnti x IOB (se c'è UPDATE, se manca ADD) /// @@ -3938,40 +2631,6 @@ namespace MP.IOC.Data return valOut; } - /// - /// Elenco completo tabella Vocabolario - /// - /// - public List VocabolarioGetAll() - { - Stopwatch stopWatch = new Stopwatch(); - stopWatch.Start(); - List? result = new List(); - string source = "REDIS"; - // cerco in redis... - RedisValue rawData = redisDb.StringGet(Utils.redisVocabolario); - if (!string.IsNullOrEmpty($"{rawData}")) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - } - else - { - result = SpecDbController.VocabolarioGetAll(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(Utils.redisVocabolario, rawData, getRandTOut(redisLongTimeCache / 5)); - source = "DB"; - } - stopWatch.Stop(); - TimeSpan ts = stopWatch.Elapsed; - Log.Debug($"VocabolarioGetAll Read from {source}: {ts.TotalMilliseconds}ms"); - if (result == null) - { - result = new List(); - } - return result; - } - #endregion Public Methods #region Internal Methods @@ -4089,11 +2748,6 @@ namespace MP.IOC.Data private string MpIoNS = ""; - /// - /// Oggetto vocabolario x uso continuo traduzione - /// - private List ObjVocabolario = new List(); - /// /// Oggetto per connessione a REDIS /// diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index c0012b86..ee4df1a7 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.2907 + 8.16.2605.2908 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index b5bb6646..3399fa4c 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                                                        Versione: 8.16.2605.2907

                                                                                        +

                                                                                        Versione: 8.16.2605.2908


                                                                                        Note di rilascio:
                                                                                        • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 9badb5e0..2fdfac52 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2907 +8.16.2605.2908 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 402bdbd2..d583a70f 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2907 + 8.16.2605.2908 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 180ba1cc..c32f472d 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2605.2907 + 8.16.2605.2908 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 75967f1b..14843a9f 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                                                          Versione: 8.16.2605.2907

                                                                                          +

                                                                                          Versione: 8.16.2605.2908


                                                                                          Note di rilascio:
                                                                                            diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 9badb5e0..2fdfac52 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2907 +8.16.2605.2908 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index 5d7d8de9..bd08e1a6 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2907 + 8.16.2605.2908 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index 3a846b66..f653ad75 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2605.2907 + 8.16.2605.2908 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index df4ddb74..7f15ac9a 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                                            Versione: 8.16.2605.2907

                                                                                            +

                                                                                            Versione: 8.16.2605.2908


                                                                                            Note di rilascio:
                                                                                            • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 9badb5e0..2fdfac52 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2907 +8.16.2605.2908 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index 0c4426f0..85890acd 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2907 + 8.16.2605.2908 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index c6122009..d2a9c1c0 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2605.2907 + 8.16.2605.2908 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index 8d002a99..fa44d60e 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                                                                              Versione: 8.16.2605.2907

                                                                                              +

                                                                                              Versione: 8.16.2605.2908


                                                                                              Note di rilascio:
                                                                                                diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 9badb5e0..2fdfac52 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2907 +8.16.2605.2908 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index efdb7b7a..dd088ad3 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2907 + 8.16.2605.2908 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index 7f255a6b..289a1164 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2605.2907 + 8.16.2605.2908 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index 20231bff..3c4a0ab3 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                                                                Versione: 8.16.2605.2907

                                                                                                +

                                                                                                Versione: 8.16.2605.2908


                                                                                                Note di rilascio:
                                                                                                • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index 9badb5e0..2fdfac52 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2907 +8.16.2605.2908 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index 285de5c8..ac7c96f4 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2907 + 8.16.2605.2908 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index e3a4ff68..c79f76cf 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -541,7 +541,6 @@ namespace MP.SPEC.Data public void Dispose() { // Clear database controller - dbController.Dispose(); mongoController.Dispose(); redisConn.Dispose(); } diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index d44879d1..697d86b5 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2605.2907 + 8.16.2605.2908 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index a1e7f04e..7dac42c3 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                                                                                  Versione: 8.16.2605.2907

                                                                                                  +

                                                                                                  Versione: 8.16.2605.2908


                                                                                                  Note di rilascio:
                                                                                                    diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 9badb5e0..2fdfac52 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2907 +8.16.2605.2908 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index f58d9206..d88310f1 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2907 + 8.16.2605.2908 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false diff --git a/Refactor_Plan.md b/Refactor_Plan.md index a6679d5d..52293576 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -36,9 +36,28 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - Analisi di `MpDataService.cs` effettuata. - Identificati i metodi con caching manuale (Redis/DB) e quelli già migrati a `GetOrFetchAsync`. +# Piano di Refactoring: Migrazione a FusionCache in `MpDataService.cs` + +Stiamo lavorando sul progetto MP-SPEC.sln, dentro la cartella MP-SPEC (ed i progetti da cui dipende). + +Voglio ottimizzare il file Data\MpDataService.cs + +## Obiettivo +Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCache` per implementare un approccio multi-layer (Memory + Redis + DB), standardizzando l'accesso ai dati. + +## Strategia di Migrazione +- **Metodo Standard**: `GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tagList)`. +- **Invalidazione**: Utilizzare i tag tramite `FlushCacheByTagsAsync`. + +## Stato Avanzamento + +### Fase 1: Analisi e Mapping (Completata) +- Analisi di `MpDataService.cs` effettuata. +- Identificati i metodi con caching manuale (Redis/DB) e quelli già migrati a `GetOrFetchAsync`. + ### Fase 2: Refactoring Metodi di Lettura (Cache-aside) (In corso) -#### ✅ Metodi Migrati (Usano già `GetOrFetchAsync`) +#### ✅ Metodi Migrati (Usano già `GetOrFetchAsync` o `FusionCache.GetOrSet`) - `AnagEventiGeneralAsync` - `AnagStatiCommAsync` - `AnagTipoArtLvAsync` @@ -70,6 +89,7 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - `StatoMacchinaAsync` - `TksScoreAsync` - `WipKitFiltAsync` +- `Traduci` (Migrato con `GetOrSet` su dizionario lingua) #### 🛠️ Metodi da Migrare (Usano ancora Redis/DB manuale) - [ ] Migrazione di `ActionGetReq` (linea 110: usa `redisDb.StringGetAsync`). @@ -88,7 +108,18 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - [ ] Migrazione di `POdlListByKitParent` (linea 1863: usa `redisDb.StringGet` e `StringSet`). - [ ] Migrazione di `ProcFLStats` (linea 1992: usa `redisDb.StringSet`). - [ ] Migrazione di `RecDbMaintStat` (linea 2451: usa `redisDb.StringSet`). -- [ ] Migrazione di `VocabolarioGetAll` (linea 2278: usa `redisDb.StringGet` e `StringSet`). + +*(Nota: Il vecchio metodo `VocabolarioGetAll` e la gestione manuale del dizionario sono stati rimossi in favore di `Traduci` con FusionCache).* + +### Fase 4: Verifica +- [ ] Verificare la compilazione della soluzione tramite script PowerShell. +- [ ] Controllare che i log (NLog) continuano a riflettere correttamente le operazioni. + +## Rischi e Mitigazioni +- **Rischio**: Discrepanza nelle chiavi di cache tra vecchio e nuovo sistema. + - *Mitigazione*: Utilizzare rigorosamente le costanti in `Utils.redis...` per garantire che le chiavi siano identiche o gestite dal nuovo sistema. +- **Rischio**: Errori di serializzazione. + - *Mitigazione*: `FusionCache` gestisce la serializzazione, ma è necessario assicurarsi che i tipi di ritorno siano compatibili con le aspettative dei chiamanti. ### Fase 4: Verifica - [ ] Verificare la compilazione della soluzione tramite script PowerShell. From 823af369713230f1c50cc87050109b02eecdd67a Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 29 May 2026 09:00:36 +0200 Subject: [PATCH 066/102] Fix e pulizia metodi ODL --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.Core/Utils.cs | 1 + MP.Data/Controllers/MpSpecController.cs | 66 ++++++++-------- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.SPEC/Components/ListOdlLotto.razor.cs | 2 +- MP.SPEC/Components/ListPODL.razor.cs | 6 +- MP.SPEC/Data/MpDataService.cs | 95 ++++++++---------------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Giacenze.razor.cs | 2 +- MP.SPEC/Pages/RepStop.razor.cs | 8 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- Refactor_Plan.md | 56 +------------- 44 files changed, 116 insertions(+), 192 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index 722b07cd..7af3a367 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2605.2908 + 8.16.2605.2909 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 7f15ac9a..93e3aa9a 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                                                    Versione: 8.16.2605.2908

                                                                                                    +

                                                                                                    Versione: 8.16.2605.2909


                                                                                                    Note di rilascio:
                                                                                                    • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 2fdfac52..b14ae2f3 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2908 +8.16.2605.2909 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index a3387c78..1c6cb3ca 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2908 + 8.16.2605.2909 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.Core/Utils.cs b/MP.Core/Utils.cs index 6d978777..5be06dbe 100644 --- a/MP.Core/Utils.cs +++ b/MP.Core/Utils.cs @@ -43,6 +43,7 @@ namespace MP.Core public const string redisMacRecipePath = redisBaseAddr + "Cache:RecipePath"; public const string redisOdlByBatch = redisXdlData + "OdlByBatch"; + public const string redisOdlByKey = redisXdlData + "OdlByKey"; public const string redisOdlCurrByMac = redisXdlData + "OdlByMac"; public const string redisOdlLastByMac = redisXdlData + "LastOdlByMac"; diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 32575fc1..57bc1c7e 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -1875,22 +1875,23 @@ namespace MP.Data.Controllers /// Elenco da tabella MappaStatoExplModel ///
                                                                                        /// - public List MseGetAll(int maxAge = 2000) + public async Task> MseGetAllAsync(int maxAge = 2000) { List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - var maxAgeSec = new SqlParameter("@maxAgeSec", maxAge); + using var dbCtx = new MoonProContext(options); + + var maxAgeSec = new SqlParameter("@maxAgeSec", maxAge); + + dbResult = await dbCtx + .DbSetMSE + .FromSqlRaw("EXEC stp_MSE_getData @maxAgeSec", maxAgeSec) + .AsNoTracking() + .ToListAsync(); - dbResult = dbCtx - .DbSetMSE - .FromSqlRaw("EXEC stp_MSE_getData @maxAgeSec", maxAgeSec) - .AsNoTracking() - .ToList(); - } return dbResult; } +#if false /// /// Elenco ODL dato batch selezionato /// @@ -1916,31 +1917,36 @@ namespace MP.Data.Controllers } } return dbResult; + } +#endif + + /// + /// Elenco ODL dato batch selezionato + /// + /// Batch richiesto + /// + public async Task> OdlByBatchAsync(string batchSel) + { + using var dbCtx = new MoonPro_InveContext(_configuration); + return await dbCtx + .DbGiacenzeData + .AsNoTracking() + .Where(x => x.IdentRG == batchSel) + .Select(x => x.IdxOdl) + .ToListAsync(); } /// /// ODL da chiave /// /// - public ODLExpModel OdlByKey(int IdxOdl) + public async Task OdlByKeyAsync(int IdxOdl) { - ODLExpModel dbResult = new ODLExpModel(); - using (var dbCtx = new MoonProContext(options)) - { - try - { - dbResult = dbCtx - .DbSetODLExp - .AsNoTracking() - .Where(x => x.IdxOdl == IdxOdl) - .FirstOrDefault(); - } - catch (Exception exc) - { - Log.Error($"Eccezione durante OdlByKey{Environment.NewLine}{exc}"); - } - } - return dbResult; + using var dbCtx = new MoonProContext(options); + return await dbCtx + .DbSetODLExp + .AsNoTracking() + .FirstOrDefaultAsync(x => x.IdxOdl == IdxOdl); } /// @@ -2025,6 +2031,7 @@ namespace MP.Data.Controllers return fatto; } +#if false /// /// Recupero odl data chiave /// @@ -2041,7 +2048,8 @@ namespace MP.Data.Controllers .FirstOrDefaultAsync(x => x.IdxOdl == idxOdl); } return dbResult; - } + } +#endif /// /// Recupero Odl CORRENTI diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index a797534f..35d1abc5 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2605.2908 + 8.16.2605.2909 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index d596732c..4abbf633 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                                                                        Versione: 8.16.2605.2908

                                                                                        +

                                                                                        Versione: 8.16.2605.2909


                                                                                        Note di rilascio:
                                                                                        • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index 2fdfac52..b14ae2f3 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2908 +8.16.2605.2909 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index 501709a5..97ff5f96 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2908 + 8.16.2605.2909 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index ee4df1a7..10ea946d 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.2908 + 8.16.2605.2909 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 3399fa4c..847874ba 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                                                          Versione: 8.16.2605.2908

                                                                                          +

                                                                                          Versione: 8.16.2605.2909


                                                                                          Note di rilascio:
                                                                                          • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 2fdfac52..b14ae2f3 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2908 +8.16.2605.2909 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index d583a70f..ce11ebb0 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2908 + 8.16.2605.2909 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index c32f472d..cc0b62f4 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2605.2908 + 8.16.2605.2909 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 14843a9f..4ebccb9d 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                                                            Versione: 8.16.2605.2908

                                                                                            +

                                                                                            Versione: 8.16.2605.2909


                                                                                            Note di rilascio:
                                                                                              diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 2fdfac52..b14ae2f3 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2908 +8.16.2605.2909 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index bd08e1a6..fe615da2 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2908 + 8.16.2605.2909 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index f653ad75..b2db2163 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2605.2908 + 8.16.2605.2909 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 7f15ac9a..93e3aa9a 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                                              Versione: 8.16.2605.2908

                                                                                              +

                                                                                              Versione: 8.16.2605.2909


                                                                                              Note di rilascio:
                                                                                              • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 2fdfac52..b14ae2f3 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2908 +8.16.2605.2909 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index 85890acd..8018e1f9 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2908 + 8.16.2605.2909 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index d2a9c1c0..b11ce330 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2605.2908 + 8.16.2605.2909 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index fa44d60e..fe7e5613 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                                                                                Versione: 8.16.2605.2908

                                                                                                +

                                                                                                Versione: 8.16.2605.2909


                                                                                                Note di rilascio:
                                                                                                  diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 2fdfac52..b14ae2f3 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2908 +8.16.2605.2909 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index dd088ad3..5050f27c 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2908 + 8.16.2605.2909 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index 289a1164..8d6c2176 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2605.2908 + 8.16.2605.2909 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index 3c4a0ab3..3541dd03 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                                                                  Versione: 8.16.2605.2908

                                                                                                  +

                                                                                                  Versione: 8.16.2605.2909


                                                                                                  Note di rilascio:
                                                                                                  • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index 2fdfac52..b14ae2f3 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2908 +8.16.2605.2909 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index ac7c96f4..b5daae2a 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2908 + 8.16.2605.2909 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Components/ListOdlLotto.razor.cs b/MP.SPEC/Components/ListOdlLotto.razor.cs index dac4f566..b71caa97 100644 --- a/MP.SPEC/Components/ListOdlLotto.razor.cs +++ b/MP.SPEC/Components/ListOdlLotto.razor.cs @@ -18,7 +18,7 @@ namespace MP.SPEC.Components { if (!string.IsNullOrEmpty(BatchSel)) { - elencoODL = await MDService.OdlByBatch(BatchSel); + elencoODL = await MDService.OdlByBatchAsync(BatchSel); } else { diff --git a/MP.SPEC/Components/ListPODL.razor.cs b/MP.SPEC/Components/ListPODL.razor.cs index 582f189b..46cae42a 100644 --- a/MP.SPEC/Components/ListPODL.razor.cs +++ b/MP.SPEC/Components/ListPODL.razor.cs @@ -351,7 +351,8 @@ namespace MP.SPEC.Components if (fatto) { var currPOdl = await MDService.POdlGetByKey(selRec.IdxPromessa); - var newOdl = await MDService.OdlGetByKey(currPOdl.IdxOdl); + var newOdl = await MDService.OdlByKeyAsync(currPOdl.IdxOdl); + //var newOdl = await MDService.OdlGetByKey(currPOdl.IdxOdl); // registro evento... idxEvento = 2; @@ -658,7 +659,8 @@ namespace MP.SPEC.Components // se manca codart calcolo... if (string.IsNullOrEmpty(codArticolo)) { - var currOdl = await MDService.OdlGetByKey(idxODL); + var currOdl = await MDService.OdlByKeyAsync(idxODL); + //var currOdl = await MDService.OdlGetByKey(idxODL); if (currOdl != null) { codArticolo = currOdl.CodArticolo; diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index c79f76cf..fe712005 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1431,7 +1431,6 @@ namespace MP.SPEC.Data public async Task> MachIobConfAsync(string IdxMacchina) { string redisKey = Utils.redisIobConf; - return await GetOrFetchAsync( operationName: "MachIobConfAsync", cacheKey: redisKey, @@ -1455,36 +1454,22 @@ namespace MP.SPEC.Data /// /// Elenco MSE stato amcchine /// - /// + /// Force refresh from DB /// - public async Task> MseGetAll(bool forceDb = false) + public async Task> MseGetAllAsync(bool forceDb = false) { using var activity = ActivitySource.StartActivity("MseGetAllAsync"); - string source = "DB"; - List? result = new List(); - // cerco in redisConn... - RedisValue rawData = redisDb.StringGet(Constants.redisMseKey); - if (rawData.HasValue && !forceDb) + if (forceDb) { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; + await _cache.RemoveAsync(Constants.redisMseKey); } - else - { - result = await Task.FromResult(dbController.MseGetAll(2000)); - // serializzp e salvo... - rawData = JsonConvert.SerializeObject(result); - await redisDb.StringSetAsync(Constants.redisMseKey, rawData, TimeSpan.FromSeconds(1)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"MseGetAllAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return result; + return await GetOrFetchAsync( + operationName: "MseGetAllAsync", + cacheKey: Constants.redisMseKey, + expiration: TimeSpan.FromSeconds(1), + fetchFunc: async () => await dbController.MseGetAllAsync(2000) ?? new(), + tagList: [Constants.redisMseKey] + ); } /// @@ -1506,35 +1491,15 @@ namespace MP.SPEC.Data /// /// Batch richiesto /// - public async Task> OdlByBatch(string BatchSel) + public async Task> OdlByBatchAsync(string BatchSel) { - using var activity = ActivitySource.StartActivity("OdlByBatch"); - List? result = new List(); - string source = "DB"; - string currKey = Utils.redisOdlByBatch; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await Task.FromResult(dbController.OdlByBatch(BatchSel)); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"OdlByBatch | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + return await GetOrFetchAsync( + operationName: "OdlByBatchAsync", + cacheKey: Utils.redisOdlByBatch, + expiration: getRandTOut(redisLongTimeCache), + fetchFunc: async () => await dbController.OdlByBatchAsync(BatchSel), + tagList: [Utils.redisOdlByBatch] + ); } /// @@ -1542,16 +1507,16 @@ namespace MP.SPEC.Data /// /// /// - public ODLExpModel OdlByKey(int IdxOdl) + public async Task OdlByKeyAsync(int IdxOdl) { - using var activity = ActivitySource.StartActivity("OdlByKey"); - ODLExpModel? result = new ODLExpModel(); - string source = "DB"; - result = dbController.OdlByKey(IdxOdl); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"OdlByKey | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + string currKey = $"{Utils.redisOdlByKey}:{IdxOdl}"; + return await GetOrFetchAsync( + operationName: "OdlByKeyAsync", + cacheKey: currKey, + expiration: getRandTOut(redisLongTimeCache), + fetchFunc: async () => await dbController.OdlByKeyAsync(IdxOdl), + tagList: [Utils.redisOdlByKey] + ); } /// @@ -1589,6 +1554,7 @@ namespace MP.SPEC.Data return fatto; } +#if false /// /// Record ODL da chaive /// @@ -1602,7 +1568,8 @@ namespace MP.SPEC.Data activity?.Stop(); LogTrace($"OdlGetByKey | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return dbResult; - } + } +#endif /// /// Elenco ODL filtrati x stato, articolo, KeyRich (che contiene stato) diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 24597231..9467216a 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2908 + 8.16.2605.2909 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Giacenze.razor.cs b/MP.SPEC/Pages/Giacenze.razor.cs index 479af5cd..06cf32da 100644 --- a/MP.SPEC/Pages/Giacenze.razor.cs +++ b/MP.SPEC/Pages/Giacenze.razor.cs @@ -38,7 +38,7 @@ namespace MP.SPEC.Pages IdxOdl = int.Parse(_idxOdl.ToString()); } } - odlExp = MDService.OdlByKey(IdxOdl); + odlExp = await MDService.OdlByKeyAsync(IdxOdl); } #endregion Protected Methods diff --git a/MP.SPEC/Pages/RepStop.razor.cs b/MP.SPEC/Pages/RepStop.razor.cs index 846538ff..b49a4714 100644 --- a/MP.SPEC/Pages/RepStop.razor.cs +++ b/MP.SPEC/Pages/RepStop.razor.cs @@ -116,7 +116,7 @@ namespace MP.SPEC.Pages { isLoading = true; await Task.Delay(100); - CurrMSE = await MDService.MseGetAll(true); + CurrMSE = await MDService.MseGetAllAsync(true); isLoading = false; } @@ -146,7 +146,7 @@ namespace MP.SPEC.Pages } forceResetSel = true; - var ListMSE = await MDService.MseGetAll(true); + var ListMSE = await MDService.MseGetAllAsync(true); CurrMachSel = new(); await Task.Delay(250); await ReloadData(); @@ -197,7 +197,7 @@ namespace MP.SPEC.Pages await TabDServ.resetMicrostatoMacchina(idxMacc); } forceResetSel = true; - var ListMSE = await MDService.MseGetAll(true); + var ListMSE = await MDService.MseGetAllAsync(true); CurrMachSel = new(); await Task.Delay(250); await ReloadData(); @@ -211,7 +211,7 @@ namespace MP.SPEC.Pages private async Task ReloadData() { - CurrMSE = await MDService.MseGetAll(false); + CurrMSE = await MDService.MseGetAllAsync(false); SearchFermate = await MDService.AnagEventiGeneralAsync(); } diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 7f15ac9a..93e3aa9a 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                                                    Versione: 8.16.2605.2908

                                                                                                    +

                                                                                                    Versione: 8.16.2605.2909


                                                                                                    Note di rilascio:
                                                                                                    • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 2fdfac52..b14ae2f3 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2908 +8.16.2605.2909 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 103d2e8c..424768b4 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2908 + 8.16.2605.2909 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 697d86b5..5a54039d 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2605.2908 + 8.16.2605.2909 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index 7dac42c3..72786f6f 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                                                                                      Versione: 8.16.2605.2908

                                                                                                      +

                                                                                                      Versione: 8.16.2605.2909


                                                                                                      Note di rilascio:
                                                                                                        diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 2fdfac52..b14ae2f3 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2908 +8.16.2605.2909 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index d88310f1..fe4bccc0 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2908 + 8.16.2605.2909 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false diff --git a/Refactor_Plan.md b/Refactor_Plan.md index 52293576..158af17b 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -17,44 +17,6 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - Analisi di `MpDataService.cs` effettuata. - Identificati i metodi con caching manuale (Redis/DB) e quelli già migrati a `GetOrFetchAsync`. -# Piano di Refactoring: Migrazione a FusionCache in `MpDataService.cs` - -Stiamo lavorando sul progetto MP-SPEC.sln, dentro la cartella MP-SPEC (ed i progetti da cui dipende). - -Voglio ottimizzare il file Data\MpDataService.cs - -## Obiettivo -Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCache` per implementare un approccio multi-layer (Memory + Redis + DB), standardizzando l'accesso ai dati. - -## Strategia di Migrazione -- **Metodo Standard**: `GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tagList)`. -- **Invalidazione**: Utilizzare i tag tramite `FlushCacheByTagsAsync`. - -## Stato Avanzamento - -### Fase 1: Analisi e Mapping (Completata) -- Analisi di `MpDataService.cs` effettuata. -- Identificati i metodi con caching manuale (Redis/DB) e quelli già migrati a `GetOrFetchAsync`. - -# Piano di Refactoring: Migrazione a FusionCache in `MpDataService.cs` - -Stiamo lavorando sul progetto MP-SPEC.sln, dentro la cartella MP-SPEC (ed i progetti da cui dipende). - -Voglio ottimizzare il file Data\MpDataService.cs - -## Obiettivo -Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCache` per implementare un approccio multi-layer (Memory + Redis + DB), standardizzando l'accesso ai dati. - -## Strategia di Migrazione -- **Metodo Standard**: `GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tagList)`. -- **Invalidazione**: Utilizzare i tag tramite `FlushCacheByTagsAsync`. - -## Stato Avanzamento - -### Fase 1: Analisi e Mapping (Completata) -- Analisi di `MpDataService.cs` effettuata. -- Identificati i metodi con caching manuale (Redis/DB) e quelli già migrati a `GetOrFetchAsync`. - ### Fase 2: Refactoring Metodi di Lettura (Cache-aside) (In corso) #### ✅ Metodi Migrati (Usano già `GetOrFetchAsync` o `FusionCache.GetOrSet`) @@ -90,6 +52,7 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - `TksScoreAsync` - `WipKitFiltAsync` - `Traduci` (Migrato con `GetOrSet` su dizionario lingua) +- `MseGetAll` (Migrato con `GetOrFetchAsync`) #### 🛠️ Metodi da Migrare (Usano ancora Redis/DB manuale) - [ ] Migrazione di `ActionGetReq` (linea 110: usa `redisDb.StringGetAsync`). @@ -100,7 +63,6 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - [ ] Migrazione di `DossiersDeleteRecord` (linea 554: usa `ExecFlushRedisPatternAsync`). - [ ] Migrazione di `DossiersTakeParamsSnapshotLast` (linea 613: usa `ExecFlushRedisPatternAsync`). - [ ] Migrazione di `ElencoRepartiDTO` (linea 697: usa `redisDb.StringGet` e `StringSet`). -- [ ] Migrazione di `MseGetAll` (linea 1460: usa `redisDb.StringGet` e `StringSetAsync`). - [ ] Migrazione di `OdlByBatch` (linea 1512: usa `redisDb.StringGet` e `StringSet`). - [ ] Migrazione di `OdlByKey` (linea 1546: usa `redisDb.StringGet` e `StringSet`). - [ ] Migrazione di `PODL_getByKey` (linea 1779: usa `redisDb.StringGet` e `StringSet`). @@ -120,19 +82,3 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - *Mitigazione*: Utilizzare rigorosamente le costanti in `Utils.redis...` per garantire che le chiavi siano identiche o gestite dal nuovo sistema. - **Rischio**: Errori di serializzazione. - *Mitigazione*: `FusionCache` gestisce la serializzazione, ma è necessario assicurarsi che i tipi di ritorno siano compatibili con le aspettative dei chiamanti. - -### Fase 4: Verifica -- [ ] Verificare la compilazione della soluzione tramite script PowerShell. -- [ ] Controllare che i log (NLog) continuano a riflettere correttamente le operazioni. - -## Rischi e Mitigazioni -- **Rischio**: Discrepanza nelle chiavi di cache tra vecchio e nuovo sistema. - - *Mitigazione*: Utilizzare rigorosamente le costanti in `Utils.redis...` per garantire che le chiavi siano identiche o gestite dal nuovo sistema. -- **Rischio**: Errori di serializzazione. - - *Mitigazione*: `FusionCache` gestisce la serializzazione, ma è necessario assicurarsi che i tipi di ritorno siano compatibili con le aspettative dei chiamanti. - - -### Fase 4: Verifica -- [ ] Verificare la compilazione della soluzione tramite script PowerShell. -- [ ] Controllare che i log (NLog) continuano a riflettere correttamente le operazioni. - From bd2bd32d30d4aa58774557c4a8284204283d36f1 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 29 May 2026 11:17:13 +0200 Subject: [PATCH 067/102] Update pagina KIT template --- MP.Data/Controllers/MpSpecController.cs | 20 -------------------- MP.SPEC/Data/MpDataService.cs | 12 ++++-------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/KIT.razor | 2 +- MP.SPEC/Pages/KIT.razor.cs | 10 ++++++---- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- Refactor_Plan.md | 10 +++++----- 9 files changed, 20 insertions(+), 42 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 57bc1c7e..64b2974d 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -2031,26 +2031,6 @@ namespace MP.Data.Controllers return fatto; } -#if false - /// - /// Recupero odl data chiave - /// - /// - /// - /// - public async Task OdlGetByKey(int idxOdl) - { - ODLModel dbResult = new ODLModel(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = await dbCtx - .DbSetODL - .FirstOrDefaultAsync(x => x.IdxOdl == idxOdl); - } - return dbResult; - } -#endif - /// /// Recupero Odl CORRENTI /// diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index fe712005..b82f95db 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -2134,13 +2134,11 @@ namespace MP.SPEC.Data public async Task TemplateKitDelete(TemplateKitModel currRecord) { using var activity = ActivitySource.StartActivity("TemplateKitDelete"); - string source = "DB+REDIS"; + string source = "DB"; bool fatto = false; // salvo fatto = dbController.TemplateKitDelete(currRecord); - // svuoto cache - RedisValue pattern = $"{Utils.redisKitTempl}:*"; - await ExecFlushRedisPatternAsync(pattern); + await FlushCacheByTagAsync(Utils.redisKitTempl); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"TemplateKitDelete | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -2174,13 +2172,11 @@ namespace MP.SPEC.Data public async Task TemplateKitUpsert(TemplateKitModel currRecord, string codAzienda) { using var activity = ActivitySource.StartActivity("TemplateKitUpsert"); - string source = "DB+REDIS"; + string source = "DB"; bool fatto = false; // salvo fatto = dbController.TemplateKitUpsert(currRecord, codAzienda); - // svuoto cache - RedisValue pattern = $"{Utils.redisKitTempl}:*"; - await ExecFlushRedisPatternAsync(pattern); + await FlushCacheByTagAsync(Utils.redisKitTempl); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"TemplateKitUpsert | {source} | {activity?.Duration.TotalMilliseconds}ms"); diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 9467216a..e2f08baa 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2909 + 8.16.2605.2911 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/KIT.razor b/MP.SPEC/Pages/KIT.razor index 8b46229c..2dfeacc9 100644 --- a/MP.SPEC/Pages/KIT.razor +++ b/MP.SPEC/Pages/KIT.razor @@ -34,7 +34,7 @@
                                                                - +
                                                                diff --git a/MP.SPEC/Pages/KIT.razor.cs b/MP.SPEC/Pages/KIT.razor.cs index afc11b64..340b5632 100644 --- a/MP.SPEC/Pages/KIT.razor.cs +++ b/MP.SPEC/Pages/KIT.razor.cs @@ -144,12 +144,12 @@ namespace MP.SPEC.Pages TemplateKitModel newRec = new TemplateKitModel() { CodArtParent = selRec.CodArtParent, - CodArtChild = "",//selRec.CodArtParent, + CodArtChild = "", Qty = selRec.Qty }; EditRecord = newRec; SearchParent = selRec.CodArtParent; - await Task.Delay(1); + await ReloadDataAsync(); } /// @@ -171,18 +171,20 @@ namespace MP.SPEC.Pages /// Imposta filtro CodArtChild da record /// /// - protected void DoFiltChild(TemplateKitModel selRec) + protected async Task DoFiltChild(TemplateKitModel selRec) { SearchChild = selRec.CodArtChild; + await ResetDataAsync(); } /// /// Imposta filtro CodArtParent da record /// /// - protected void DoFiltParent(TemplateKitModel selRec) + protected async Task DoFiltParent(TemplateKitModel selRec) { SearchParent = selRec.CodArtParent; + await ResetDataAsync(); } protected async Task DoUpdate(TemplateKitModel selRec) diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 93e3aa9a..343ce97c 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                Versione: 8.16.2605.2909

                                                                +

                                                                Versione: 8.16.2605.2911


                                                                Note di rilascio:
                                                                • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index b14ae2f3..5bba24a5 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2909 +8.16.2605.2911 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 424768b4..099b2cd1 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2909 + 8.16.2605.2911 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/Refactor_Plan.md b/Refactor_Plan.md index 158af17b..64db86af 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -42,6 +42,7 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - `MacchineWithFluxAsync` - `MachineWithOdlAsync` - `MachIobConfAsync` +- `OdlByBatchAsync` (Migrato e rinominato) - `OdlListGetFiltAsync` - `OperatoriGetFiltAsync` - `ParametriGetFiltAsync` @@ -50,9 +51,10 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - `POdlToKitListGetFiltAsync` - `StatoMacchinaAsync` - `TksScoreAsync` -- `WipKitFiltAsync` - `Traduci` (Migrato con `GetOrSet` su dizionario lingua) -- `MseGetAll` (Migrato con `GetOrFetchAsync`) +- `WipKitFiltAsync` +- `MseGetAllAsync` (Migrato e rinominato) +- `OdlByKeyAsync` (Migrato e rinominato) #### 🛠️ Metodi da Migrare (Usano ancora Redis/DB manuale) - [ ] Migrazione di `ActionGetReq` (linea 110: usa `redisDb.StringGetAsync`). @@ -63,9 +65,6 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - [ ] Migrazione di `DossiersDeleteRecord` (linea 554: usa `ExecFlushRedisPatternAsync`). - [ ] Migrazione di `DossiersTakeParamsSnapshotLast` (linea 613: usa `ExecFlushRedisPatternAsync`). - [ ] Migrazione di `ElencoRepartiDTO` (linea 697: usa `redisDb.StringGet` e `StringSet`). -- [ ] Migrazione di `OdlByBatch` (linea 1512: usa `redisDb.StringGet` e `StringSet`). -- [ ] Migrazione di `OdlByKey` (linea 1546: usa `redisDb.StringGet` e `StringSet`). -- [ ] Migrazione di `PODL_getByKey` (linea 1779: usa `redisDb.StringGet` e `StringSet`). - [ ] Migrazione di `PodlIstKitDelete` (linea 1842: usa `ExecFlushRedisPattern`). - [ ] Migrazione di `POdlListByKitParent` (linea 1863: usa `redisDb.StringGet` e `StringSet`). - [ ] Migrazione di `ProcFLStats` (linea 1992: usa `redisDb.StringSet`). @@ -82,3 +81,4 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - *Mitigazione*: Utilizzare rigorosamente le costanti in `Utils.redis...` per garantire che le chiavi siano identiche o gestite dal nuovo sistema. - **Rischio**: Errori di serializzazione. - *Mitigazione*: `FusionCache` gestisce la serializzazione, ma è necessario assicurarsi che i tipi di ritorno siano compatibili con le aspettative dei chiamanti. + From af264a8922ba2d191a51a2ac1fce0d973eb56938 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 29 May 2026 11:43:52 +0200 Subject: [PATCH 068/102] Aggiunta filtro search per PODL --- MP.SPEC/Components/ListPODL.razor.cs | 30 +++++++++++++++++++++------- MP.SPEC/Data/MpDataService.cs | 12 +++++------ MP.SPEC/Pages/KIT.razor.cs | 4 ++-- MP.SPEC/Pages/PODL.razor | 17 +++++++++++----- MP.SPEC/Pages/PODL.razor.cs | 26 ++++++++++++++---------- 5 files changed, 58 insertions(+), 31 deletions(-) diff --git a/MP.SPEC/Components/ListPODL.razor.cs b/MP.SPEC/Components/ListPODL.razor.cs index 46cae42a..b9d5f829 100644 --- a/MP.SPEC/Components/ListPODL.razor.cs +++ b/MP.SPEC/Components/ListPODL.razor.cs @@ -124,7 +124,7 @@ namespace MP.SPEC.Components var done = await MDService.POdlDeleteRecord(selRec); await callSyncDb(selRec.IdxMacchina); currRecord = null; - await ReloadData(); + await ReloadDataAsync(); await Task.Delay(1); } @@ -187,7 +187,7 @@ namespace MP.SPEC.Components lastFilter = actFilter.clone(); _lastPadCodXdl = padCodXdl; - await ReloadData(); + await ReloadDataAsync(); } } @@ -254,7 +254,7 @@ namespace MP.SPEC.Components } } - protected async Task ReloadData() + protected async Task ReloadDataAsync() { isLoading = true; ListRecords = null; @@ -275,8 +275,24 @@ namespace MP.SPEC.Components // ✅ aspetta tutto insieme await Task.WhenAll(odlTask, searchTask); - - SearchRecords = searchTask.Result; + var rawList = searchTask.Result; + // se abilitata ricerca filtro ulteriormente.. + if (string.IsNullOrEmpty(actFilter.SearchVal)) + { + SearchRecords = rawList; + } + else + { + SearchRecords = rawList + .Where(x => + //EF.Functions.Like(x.CodArticolo, actFilter.SearchVal) || + //EF.Functions.Like(x.CodFase, actFilter.SearchVal) || + //EF.Functions.Like(x.DescArticolo, actFilter.SearchVal) + x.CodArticolo.Contains(actFilter.SearchVal, StringComparison.InvariantCulture) + || x.CodFase.Contains(actFilter.SearchVal, StringComparison.InvariantCulture) + || x.DescArticolo.Contains(actFilter.SearchVal, StringComparison.InvariantCulture) + ).ToList(); + } totalCount = SearchRecords.Count; @@ -320,7 +336,7 @@ namespace MP.SPEC.Components showRecipeConf = false; if (forceUpdate) { - await ReloadData(); + await ReloadDataAsync(); } await RecordEdit.InvokeAsync(null); } @@ -395,7 +411,7 @@ namespace MP.SPEC.Components protected async Task UpdateData() { currRecord = null; - await ReloadData(); + await ReloadDataAsync(); } #endregion Protected Methods diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index b82f95db..d406cb6a 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -2131,9 +2131,9 @@ namespace MP.SPEC.Data /// Elimina record + svuotamento cache ///
                                                                /// - public async Task TemplateKitDelete(TemplateKitModel currRecord) + public async Task TemplateKitDeleteAsync(TemplateKitModel currRecord) { - using var activity = ActivitySource.StartActivity("TemplateKitDelete"); + using var activity = ActivitySource.StartActivity("TemplateKitDeleteAsync"); string source = "DB"; bool fatto = false; // salvo @@ -2141,7 +2141,7 @@ namespace MP.SPEC.Data await FlushCacheByTagAsync(Utils.redisKitTempl); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"TemplateKitDelete | {source} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"TemplateKitDeleteAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); return fatto; } @@ -2169,9 +2169,9 @@ namespace MP.SPEC.Data ///
                                                                /// /// - public async Task TemplateKitUpsert(TemplateKitModel currRecord, string codAzienda) + public async Task TemplateKitUpsertAsync(TemplateKitModel currRecord, string codAzienda) { - using var activity = ActivitySource.StartActivity("TemplateKitUpsert"); + using var activity = ActivitySource.StartActivity("TemplateKitUpsertAsync"); string source = "DB"; bool fatto = false; // salvo @@ -2179,7 +2179,7 @@ namespace MP.SPEC.Data await FlushCacheByTagAsync(Utils.redisKitTempl); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"TemplateKitUpsert | {source} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"TemplateKitUpsertAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); return fatto; } diff --git a/MP.SPEC/Pages/KIT.razor.cs b/MP.SPEC/Pages/KIT.razor.cs index 340b5632..d45da043 100644 --- a/MP.SPEC/Pages/KIT.razor.cs +++ b/MP.SPEC/Pages/KIT.razor.cs @@ -162,7 +162,7 @@ namespace MP.SPEC.Pages if (!await JSRuntime.InvokeAsync("confirm", "Eliminazione riga KIT: sei sicuro di voler procedere?")) return; - var done = await MDService.TemplateKitDelete(selRec); + var done = await MDService.TemplateKitDeleteAsync(selRec); EditRecord = null; await ResetDataAsync(); } @@ -193,7 +193,7 @@ namespace MP.SPEC.Pages return; await Task.Delay(1); - var done = await MDService.TemplateKitUpsert(selRec, CodAzienda); + var done = await MDService.TemplateKitUpsertAsync(selRec, CodAzienda); EditRecord = null; await ResetDataAsync(); } diff --git a/MP.SPEC/Pages/PODL.razor b/MP.SPEC/Pages/PODL.razor index c6ad0b6b..61375d1c 100644 --- a/MP.SPEC/Pages/PODL.razor +++ b/MP.SPEC/Pages/PODL.razor @@ -12,7 +12,7 @@
                                                                Da Produrre
                                                                - +
                                                                Lanciati
                                                                @@ -29,20 +29,27 @@
                                                                +
                                                                +
                                                                + + + +
                                                                +
                                                                @if (filtActive) {
                                                                @if (selReparto != "*") { - + } @if (macchina != "*") { - + } @if (StatoSel != "*") { - + }
                                                                } @@ -164,7 +171,7 @@
                                                                Gruppo - @if (currGruppoSel != null && currGruppoSel.CodGruppo!=null) + @if (currGruppoSel != null && currGruppoSel.CodGruppo != null) { } diff --git a/MP.SPEC/Pages/PODL.razor.cs b/MP.SPEC/Pages/PODL.razor.cs index 8e866756..5e00967a 100644 --- a/MP.SPEC/Pages/PODL.razor.cs +++ b/MP.SPEC/Pages/PODL.razor.cs @@ -58,10 +58,6 @@ namespace MP.SPEC.Pages [Inject] protected IJSRuntime JSRuntime { get; set; } = null!; -#if false - [Inject] - protected ILocalStorageService localStorage { get; set; } = null!; -#endif [Inject] protected ILocalStorageService localStorage { get; set; } = null!; @@ -84,7 +80,7 @@ namespace MP.SPEC.Pages protected async Task cancel() { currRecord = null; - await ReloadData(); + await ReloadDataAsync(); await Task.Delay(1); } @@ -165,7 +161,7 @@ namespace MP.SPEC.Pages protected override async Task OnParametersSetAsync() { // carico dati - await ReloadData(); + await ReloadDataAsync(); } protected async Task pgResetReq(bool doReset) @@ -341,7 +337,7 @@ namespace MP.SPEC.Pages { currRecord.CodArticolo = ""; } - await ReloadData(); + await ReloadDataAsync(); }); pUpd.Wait(); } @@ -360,7 +356,7 @@ namespace MP.SPEC.Pages _currAzienda = value; var pUpd = Task.Run(async () => { - await ReloadData(); + await ReloadDataAsync(); }); pUpd.Wait(); } @@ -380,7 +376,7 @@ namespace MP.SPEC.Pages } } - private SelectXdlParams currFilter { get; set; } = new SelectXdlParams(); + private SelectXdlParams currFilter { get; set; } = new SelectXdlParams() { SearchVal = "" }; private int currPage { @@ -495,7 +491,7 @@ namespace MP.SPEC.Pages } } - private async Task ReloadData() + private async Task ReloadDataAsync() { isLoading = true; ListMacchine = await MDService.MacchineGetFiltAsync(selReparto); @@ -511,6 +507,14 @@ namespace MP.SPEC.Pages isLoading = false; } + private string sSearchCss => string.IsNullOrEmpty(currFilter.SearchVal) ? "btn-secondary" : "btn-primary"; + + private async Task ResetSearch() + { + currFilter.SearchVal = ""; + await ReloadDataAsync(); + } + private async Task UpdateFilter(SelectXdlParams newParams) { isLoading = true; @@ -518,7 +522,7 @@ namespace MP.SPEC.Pages currPage = 1; // salvo comunque filtro reparto x utente await localStorage.SetItemAsync("reparto", selReparto); - await ReloadData(); + await ReloadDataAsync(); await Task.Delay(1); await InvokeAsync(() => StateHasChanged()); currFilter = newParams; From 7de0f88b9e701523c4cdce36b29efd7ae88cbb92 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 29 May 2026 12:01:01 +0200 Subject: [PATCH 069/102] Update pagina composizione kit PODL --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.Data/Controllers/MpSpecController.cs | 99 ++++++++----------- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.SPEC/Components/ListPODL.razor.cs | 27 ----- .../Components/ProdKit/KitComposer.razor.cs | 8 +- MP.SPEC/Components/ProdKit/Manager.razor.cs | 2 +- MP.SPEC/Data/MpDataService.cs | 45 +++++---- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- 41 files changed, 111 insertions(+), 142 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index 7af3a367..b9e389bb 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2605.2909 + 8.16.2605.2911 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 93e3aa9a..343ce97c 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                Versione: 8.16.2605.2909

                                                                +

                                                                Versione: 8.16.2605.2911


                                                                Note di rilascio:
                                                                • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index b14ae2f3..5bba24a5 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2909 +8.16.2605.2911 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index 1c6cb3ca..2fd69be0 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2909 + 8.16.2605.2911 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 64b2974d..5ba4d1f0 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -2646,26 +2646,21 @@ namespace MP.Data.Controllers /// Elimina record ///
                                                                /// - public bool WipKitDelete(WipSetupKitModel rec2del) + public async Task WipKitDeleteAsync(WipSetupKitModel rec2del) { - bool fatto = false; - using (var dbCtx = new MoonProContext(options)) + using var dbCtx = new MoonProContext(options); + var actRec = await dbCtx + .DbSetWipKit + .Where(x => x.KeyFilt == rec2del.KeyFilt && x.CodOrd == rec2del.CodOrd) + .FirstOrDefaultAsync(); + // se ci fosse aggiorno... + if (actRec != null) { - var actRec = dbCtx - .DbSetWipKit - .Where(x => x.KeyFilt == rec2del.KeyFilt && x.CodOrd == rec2del.CodOrd) - .FirstOrDefault(); - // se ci fosse aggiorno... - if (actRec != null) - { - dbCtx - .DbSetWipKit - .Remove(actRec); - } - var res = dbCtx.SaveChanges(); - fatto = res != 0; + dbCtx + .DbSetWipKit + .Remove(actRec); } - return fatto; + return await dbCtx.SaveChangesAsync() > 0; } /// @@ -2699,26 +2694,21 @@ namespace MP.Data.Controllers /// /// /// - public bool WipKitDeleteOlder(DateTime dateLimit) + public async Task WipKitDeleteOlderAsync(DateTime dateLimit) { - bool fatto = false; - using (var dbCtx = new MoonProContext(options)) - { - var actRec = dbCtx + using var dbCtx = new MoonProContext(options); + var actRec = await dbCtx .DbSetWipKit .Where(x => x.DataIns < dateLimit) - .ToList(); - // se ci fosse aggiorno... - if (actRec != null) - { - dbCtx - .DbSetWipKit - .RemoveRange(actRec); - } - var res = dbCtx.SaveChanges(); - fatto = res != 0; + .ToListAsync(); + // se ci fosse aggiorno... + if (actRec != null) + { + dbCtx + .DbSetWipKit + .RemoveRange(actRec); } - return fatto; + return await dbCtx.SaveChangesAsync() > 0; } /// @@ -2746,35 +2736,30 @@ namespace MP.Data.Controllers /// Esegue upsert record /// /// - public bool WipKitUpsert(WipSetupKitModel editRec) + public async Task WipKitUpsertAsync(WipSetupKitModel editRec) { - bool fatto = false; - using (var dbCtx = new MoonProContext(options)) - { - var actRec = dbCtx + using var dbCtx = new MoonProContext(options); + var actRec = await dbCtx .DbSetWipKit .Where(x => x.KeyFilt == editRec.KeyFilt && x.CodOrd == editRec.CodOrd) - .FirstOrDefault(); + .FirstOrDefaultAsync(); - // se ci fosse aggiorno... - if (actRec == null) - { - dbCtx - .DbSetWipKit - .Add(editRec); - } - else - { - actRec.CodArt = editRec.CodArt; - actRec.DescArt = editRec.DescArt; - actRec.Qta = editRec.Qta; - actRec.DataIns = editRec.DataIns; - dbCtx.Entry(actRec).State = EntityState.Modified; - } - var res = dbCtx.SaveChanges(); - fatto = res != 0; + // se ci fosse aggiorno... + if (actRec == null) + { + dbCtx + .DbSetWipKit + .Add(editRec); } - return fatto; + else + { + actRec.CodArt = editRec.CodArt; + actRec.DescArt = editRec.DescArt; + actRec.Qta = editRec.Qta; + actRec.DataIns = editRec.DataIns; + dbCtx.Entry(actRec).State = EntityState.Modified; + } + return await dbCtx.SaveChangesAsync() > 0; } #endregion Public Methods diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index 35d1abc5..cbfbc92f 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2605.2909 + 8.16.2605.2911 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index 4abbf633..7a1980e1 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                                                Versione: 8.16.2605.2909

                                                                +

                                                                Versione: 8.16.2605.2911


                                                                Note di rilascio:
                                                                • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index b14ae2f3..5bba24a5 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2909 +8.16.2605.2911 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index 97ff5f96..67c1a1cb 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2909 + 8.16.2605.2911 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 10ea946d..76c4ccc4 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.2909 + 8.16.2605.2911 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 847874ba..62354787 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                                  Versione: 8.16.2605.2909

                                                                  +

                                                                  Versione: 8.16.2605.2911


                                                                  Note di rilascio:
                                                                  • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index b14ae2f3..5bba24a5 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2909 +8.16.2605.2911 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index ce11ebb0..81a9ccf1 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2909 + 8.16.2605.2911 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index cc0b62f4..cdfc0a46 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2605.2909 + 8.16.2605.2911 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 4ebccb9d..950f7cc4 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                                    Versione: 8.16.2605.2909

                                                                    +

                                                                    Versione: 8.16.2605.2911


                                                                    Note di rilascio:
                                                                      diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index b14ae2f3..5bba24a5 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2909 +8.16.2605.2911 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index fe615da2..c07fc1f4 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2909 + 8.16.2605.2911 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index b2db2163..bd485066 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2605.2909 + 8.16.2605.2911 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 93e3aa9a..343ce97c 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                      Versione: 8.16.2605.2909

                                                                      +

                                                                      Versione: 8.16.2605.2911


                                                                      Note di rilascio:
                                                                      • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index b14ae2f3..5bba24a5 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2909 +8.16.2605.2911 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index 8018e1f9..b740b894 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2909 + 8.16.2605.2911 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index b11ce330..be7acaa9 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2605.2909 + 8.16.2605.2911 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index fe7e5613..52823f19 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                                                        Versione: 8.16.2605.2909

                                                                        +

                                                                        Versione: 8.16.2605.2911


                                                                        Note di rilascio:
                                                                          diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index b14ae2f3..5bba24a5 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2909 +8.16.2605.2911 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 5050f27c..708d6114 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2909 + 8.16.2605.2911 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index 8d6c2176..f06e6cfe 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2605.2909 + 8.16.2605.2911 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index 3541dd03..ef43307c 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                                          Versione: 8.16.2605.2909

                                                                          +

                                                                          Versione: 8.16.2605.2911


                                                                          Note di rilascio:
                                                                          • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index b14ae2f3..5bba24a5 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2909 +8.16.2605.2911 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index b5daae2a..d1bb994b 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2909 + 8.16.2605.2911 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Components/ListPODL.razor.cs b/MP.SPEC/Components/ListPODL.razor.cs index b9d5f829..0ba0d75e 100644 --- a/MP.SPEC/Components/ListPODL.razor.cs +++ b/MP.SPEC/Components/ListPODL.razor.cs @@ -285,9 +285,6 @@ namespace MP.SPEC.Components { SearchRecords = rawList .Where(x => - //EF.Functions.Like(x.CodArticolo, actFilter.SearchVal) || - //EF.Functions.Like(x.CodFase, actFilter.SearchVal) || - //EF.Functions.Like(x.DescArticolo, actFilter.SearchVal) x.CodArticolo.Contains(actFilter.SearchVal, StringComparison.InvariantCulture) || x.CodFase.Contains(actFilter.SearchVal, StringComparison.InvariantCulture) || x.DescArticolo.Contains(actFilter.SearchVal, StringComparison.InvariantCulture) @@ -304,30 +301,6 @@ namespace MP.SPEC.Components isLoading = false; } -#if false - protected async Task ReloadData() - { - ListRecords = null; - isLoading = true; - await UpdateOdlList(); - // verifico filtro odl... - if (actFilter.ShowKit) - { - SearchRecords = await MDService.POdlListGetFiltAsync(hasOdl, StatoSel, macchina, reparto, selDtStart, selDtEnd); - } - else - { - SearchRecords = await MDService.POdlToKitListGetFiltAsync(hasOdl, StatoSel, macchina, reparto, selDtStart, selDtEnd); - } - if (totalCount != SearchRecords.Count) - { - totalCount = SearchRecords.Count; - } - ListRecords = SearchRecords.Skip(numRecord * (currPage - 1)).Take(numRecord).ToList(); - isLoading = false; - } -#endif - protected async Task resetSel(bool forceUpdate) { currRecord = null; diff --git a/MP.SPEC/Components/ProdKit/KitComposer.razor.cs b/MP.SPEC/Components/ProdKit/KitComposer.razor.cs index 8e5af742..dd153f37 100644 --- a/MP.SPEC/Components/ProdKit/KitComposer.razor.cs +++ b/MP.SPEC/Components/ProdKit/KitComposer.razor.cs @@ -42,7 +42,7 @@ namespace MP.SPEC.Components.ProdKit // elimino TUTTO... DateTime dtLimit = DateTime.Now;//.AddHours(-1); - var done = MDService.WipKitDeleteOlder(dtLimit); + var done = await MDService.WipKitDeleteOlderAsync(dtLimit); await EC_ListCleared.InvokeAsync(false); } @@ -51,18 +51,18 @@ namespace MP.SPEC.Components.ProdKit if (!await JSRuntime.InvokeAsync("confirm", "Eliminazione riga KIT: sei sicuro di voler procedere?")) return; - var done = MDService.WipKitDelete(rec2del); + var done = await MDService.WipKitDeleteAsync(rec2del); await EC_ListUpdated.InvokeAsync(false); } - protected override void OnInitialized() + protected override async Task OnInitializedAsync() { // calcolo codice temporaneo utente...da apertura KIT if (string.IsNullOrEmpty(KeyFilt)) { // elimino dati + vecchi di 2h... DateTime dtLimit = DateTime.Now.AddHours(-2); - var done = MDService.WipKitDeleteOlder(dtLimit); + var done = await MDService.WipKitDeleteOlderAsync(dtLimit); } } diff --git a/MP.SPEC/Components/ProdKit/Manager.razor.cs b/MP.SPEC/Components/ProdKit/Manager.razor.cs index 543c26df..1183f648 100644 --- a/MP.SPEC/Components/ProdKit/Manager.razor.cs +++ b/MP.SPEC/Components/ProdKit/Manager.razor.cs @@ -94,7 +94,7 @@ namespace MP.SPEC.Components.ProdKit Qta = selRec.NumPezzi, DataIns = DateTime.Now }; - bool fatto = MDService.WipKitUpsert(newRec); + bool fatto = await MDService.WipKitUpsertAsync(newRec); // se non gi impostato riporto impostazione filtro con macchina e gruppo ricevuto... ActFilt.IdxMacchina = selRec.IdxMacchina; ActFilt.CodReparto = selRec.CodGruppo; diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index d406cb6a..5cdab00b 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -2251,18 +2251,21 @@ namespace MP.SPEC.Data /// Elimina record + svuotamento cache ///
                                              /// - public bool WipKitDelete(WipSetupKitModel currRecord) + public async Task WipKitDeleteAsync(WipSetupKitModel currRecord) { - using var activity = ActivitySource.StartActivity("WipKitDelete"); + using var activity = ActivitySource.StartActivity("WipKitDeleteAsync"); string source = "DB"; bool fatto = false; // salvo - fatto = dbController.WipKitDelete(currRecord); + fatto = await dbController.WipKitDeleteAsync(currRecord); // svuoto cache - EmptyWipCache(); + await FlushCacheByTagAsync(Utils.redisKitWip); +#if false + EmptyWipCache(); +#endif activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"WipKitDelete Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"WipKitDeleteAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return fatto; } @@ -2270,18 +2273,21 @@ namespace MP.SPEC.Data /// Elimina i record più vecchi della data-ora indicata ///
                                            /// - public bool WipKitDeleteOlder(DateTime DateLimit) + public async Task WipKitDeleteOlderAsync(DateTime DateLimit) { - using var activity = ActivitySource.StartActivity("WipKitDeleteOlder"); + using var activity = ActivitySource.StartActivity("WipKitDeleteOlderAsync"); string source = "DB"; bool fatto = false; // salvo - fatto = dbController.WipKitDeleteOlder(DateLimit); - // svuoto cache - EmptyWipCache(); + fatto = await dbController.WipKitDeleteOlderAsync(DateLimit); + // svuoto cache KitWip + await FlushCacheByTagAsync(Utils.redisKitWip); +#if false + EmptyWipCache(); +#endif activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"WipKitDeleteOlder Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"WipKitDeleteOlderAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return fatto; } @@ -2306,18 +2312,21 @@ namespace MP.SPEC.Data /// Esegue salvataggio record + svuotamento cache ///
                                            /// - public bool WipKitUpsert(WipSetupKitModel currRecord) + public async Task WipKitUpsertAsync(WipSetupKitModel currRecord) { - using var activity = ActivitySource.StartActivity("WipKitUpsert"); + using var activity = ActivitySource.StartActivity("WipKitUpsertAsync"); string source = "DB"; bool fatto = false; // salvo - fatto = dbController.WipKitUpsert(currRecord); + fatto = await dbController.WipKitUpsertAsync(currRecord); // svuoto cache KitWip - EmptyWipCache(); + await FlushCacheByTagAsync(Utils.redisKitWip); +#if false + EmptyWipCache(); +#endif activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"WipKitUpsert | {source} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"WipKitUpsertAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); return fatto; } @@ -2472,6 +2481,7 @@ namespace MP.SPEC.Data #region Private Methods +#if false /// /// Svuota cache creazione KIT /// @@ -2482,7 +2492,8 @@ namespace MP.SPEC.Data { ExecFlushRedisPattern(pattern); } - } + } +#endif /// /// Verifica caricamento dizionario ConfigData diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index e2f08baa..4f385d7b 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2911 + 8.16.2605.2912 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 343ce97c..26e66a60 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                            Versione: 8.16.2605.2911

                                            +

                                            Versione: 8.16.2605.2912


                                            Note di rilascio:
                                            • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 5bba24a5..a0cc7bd5 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2911 +8.16.2605.2912 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 099b2cd1..c6942b53 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2911 + 8.16.2605.2912 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 5a54039d..75f6846d 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2605.2909 + 8.16.2605.2911 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index 72786f6f..91b4a17f 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                              Versione: 8.16.2605.2909

                                              +

                                              Versione: 8.16.2605.2911


                                              Note di rilascio:
                                                diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index b14ae2f3..5bba24a5 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2909 +8.16.2605.2911 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index fe4bccc0..12a79c96 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2909 + 8.16.2605.2911 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false From 6af40d9caed3050cbc99836caf1585c32d5358be Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Fri, 29 May 2026 19:41:00 +0200 Subject: [PATCH 070/102] Refresh + fix gestione reparti-operatori --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.Data/Controllers/MpSpecController.cs | 67 +++++------ MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.SPEC/Components/ProdKit/KitVerify.razor.cs | 2 +- MP.SPEC/Data/MpDataService.cs | 109 +++--------------- .../{GroupMacOprMan.razor => RepOper.razor} | 2 +- ...oupMacOprMan.razor.cs => RepOper.razor.cs} | 25 ++-- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- Refactor_Plan.md | 5 + 38 files changed, 98 insertions(+), 176 deletions(-) rename MP.SPEC/Pages/{GroupMacOprMan.razor => RepOper.razor} (98%) rename MP.SPEC/Pages/{GroupMacOprMan.razor.cs => RepOper.razor.cs} (81%) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index b9e389bb..7ac087f4 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2605.2911 + 8.16.2605.2912 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 343ce97c..26e66a60 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                Versione: 8.16.2605.2911

                                                +

                                                Versione: 8.16.2605.2912


                                                Note di rilascio:
                                                • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 5bba24a5..a0cc7bd5 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2911 +8.16.2605.2912 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index 2fd69be0..a3dd4bc9 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2911 + 8.16.2605.2912 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 5ba4d1f0..45e911b3 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -270,38 +270,34 @@ namespace MP.Data.Controllers /// Elenco Gruppi tipo REPARTO (x associazione Macchine-Operatori) in formato DTO con conteggi del numero record trovati ///
                                            /// - public List AnagGruppiRepartoDTO() + public async Task> AnagGruppiRepartoDtoAsync() { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - // in primis recupero i reparti... - var listReparti = AnagGruppiGetTipo("REPARTO"); + using var dbCtx = new MoonProContext(options); + // in primis recupero i reparti... + var listReparti = AnagGruppiGetTipo("REPARTO"); - // recupero TUTTE le macchine da DbSetGrp2Macc - var listMacc = dbCtx + // recupero TUTTE le macchine da DbSetGrp2Macc + var listMacc = await dbCtx .DbSetGrp2Macc .AsNoTracking() - .ToList(); - // recupero TUTTI gli operatori da DbSetGrp2Oper - var listOpr = dbCtx + .ToListAsync(); + // recupero TUTTI gli operatori da DbSetGrp2Oper + var listOpr = await dbCtx .DbSetGrp2Oper .AsNoTracking() - .ToList(); + .ToListAsync(); - dbResult = listReparti - .Select(x => new RepartiDTO() - { - CodGruppo = x.CodGruppo, - TipoGruppo = x.TipoGruppo, - DescrGruppo = x.DescrGruppo, - SelEnabled = x.SelEnabled, - CountMacc = listMacc.Where(y => y.CodGruppo == x.CodGruppo).Select(x => x.IdxMacchina).Distinct().Count(), - CountOpr = listOpr.Where(y => y.CodGruppo == x.CodGruppo).Select(x => x.MatrOpr).Distinct().Count() - }) - .ToList(); - } - return dbResult; + return listReparti + .Select(x => new RepartiDTO() + { + CodGruppo = x.CodGruppo, + TipoGruppo = x.TipoGruppo, + DescrGruppo = x.DescrGruppo, + SelEnabled = x.SelEnabled, + CountMacc = listMacc.Where(y => y.CodGruppo == x.CodGruppo).Select(x => x.IdxMacchina).Distinct().Count(), + CountOpr = listOpr.Where(y => y.CodGruppo == x.CodGruppo).Select(x => x.MatrOpr).Distinct().Count() + }) + .ToList(); } /// @@ -1319,20 +1315,17 @@ namespace MP.Data.Controllers /// /// Articolo KIT (fittizio) /// Chiave x filtro conf su tab WKS - public bool IstKitInsertByWKS(string CodArtParent, string KeyFilt) + public async Task IstKitInsertByWKSAsync(string CodArtParent, string KeyFilt) { - bool answ = false; - using (var dbCtx = new MoonProContext(options)) - { - var pCodArtParent = new SqlParameter("@CodArtParent", CodArtParent); - var pKeyFilt = new SqlParameter("@KeyFilt", KeyFilt); + using var dbCtx = new MoonProContext(options); - var dbResult = dbCtx - .Database - .ExecuteSqlRaw("EXEC dbo.stp_IstKit_insertByWKS @CodArtParent,@KeyFilt", pCodArtParent, pKeyFilt); - answ = true; - } - return answ; + var pCodArtParent = new SqlParameter("@CodArtParent", CodArtParent); + var pKeyFilt = new SqlParameter("@KeyFilt", KeyFilt); + + var dbResult = await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC dbo.stp_IstKit_insertByWKS @CodArtParent,@KeyFilt", pCodArtParent, pKeyFilt); + return dbResult > 0; } /// diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index cbfbc92f..f76c2c99 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2605.2911 + 8.16.2605.2912 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index 7a1980e1..71dc6693 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                            Versione: 8.16.2605.2911

                                            +

                                            Versione: 8.16.2605.2912


                                            Note di rilascio:
                                            • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index 5bba24a5..a0cc7bd5 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2911 +8.16.2605.2912 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index 67c1a1cb..1acbb774 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2911 + 8.16.2605.2912 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 76c4ccc4..e0764bb9 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.2911 + 8.16.2605.2912 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 62354787..7935b453 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                              Versione: 8.16.2605.2911

                                              +

                                              Versione: 8.16.2605.2912


                                              Note di rilascio:
                                              • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 5bba24a5..a0cc7bd5 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2911 +8.16.2605.2912 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 81a9ccf1..556db6a0 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2911 + 8.16.2605.2912 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index cdfc0a46..ba3f8cbc 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2605.2911 + 8.16.2605.2912 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 950f7cc4..0db0b932 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                Versione: 8.16.2605.2911

                                                +

                                                Versione: 8.16.2605.2912


                                                Note di rilascio:
                                                  diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 5bba24a5..a0cc7bd5 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2911 +8.16.2605.2912 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index c07fc1f4..12562a96 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2911 + 8.16.2605.2912 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index bd485066..aa934ba7 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2605.2911 + 8.16.2605.2912 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 343ce97c..26e66a60 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                  Versione: 8.16.2605.2911

                                                  +

                                                  Versione: 8.16.2605.2912


                                                  Note di rilascio:
                                                  • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 5bba24a5..a0cc7bd5 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2911 +8.16.2605.2912 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index b740b894..f5459cbc 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2911 + 8.16.2605.2912 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index be7acaa9..0a6adc88 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2605.2911 + 8.16.2605.2912 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index 52823f19..66d0760d 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                                    Versione: 8.16.2605.2911

                                                    +

                                                    Versione: 8.16.2605.2912


                                                    Note di rilascio:
                                                      diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 5bba24a5..a0cc7bd5 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2911 +8.16.2605.2912 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 708d6114..6fd01dd3 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2911 + 8.16.2605.2912 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index f06e6cfe..00b28fa0 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2605.2911 + 8.16.2605.2912 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index ef43307c..958931c8 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                      Versione: 8.16.2605.2911

                                                      +

                                                      Versione: 8.16.2605.2912


                                                      Note di rilascio:
                                                      • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index 5bba24a5..a0cc7bd5 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2911 +8.16.2605.2912 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index d1bb994b..0b88d126 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2911 + 8.16.2605.2912 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Components/ProdKit/KitVerify.razor.cs b/MP.SPEC/Components/ProdKit/KitVerify.razor.cs index 96c13bc6..796755e4 100644 --- a/MP.SPEC/Components/ProdKit/KitVerify.razor.cs +++ b/MP.SPEC/Components/ProdKit/KitVerify.razor.cs @@ -99,7 +99,7 @@ namespace MP.SPEC.Components.ProdKit return; // eseguo stored... - bool fatto = MDService.IstKitInsertByWKS(currRec.CodArtParent, KeyFilt); + bool fatto = await MDService.IstKitInsertByWKSAsync(currRec.CodArtParent, KeyFilt); if (fatto) { // segnalo update diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 5cdab00b..340afee9 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -693,39 +693,15 @@ namespace MP.SPEC.Data /// Restitusice elenco Reparti ///
                                            /// - public List ElencoRepartiDTO() + public async Task> ElencoRepartiDtoAsync() { - using var activity = ActivitySource.StartActivity("ElencoRepartiDTO"); - List result = new List(); - string source = "DB"; - string currKey = $"{Utils.redisAnagGruppi}:REPARTO"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - var rawResult = JsonConvert.DeserializeObject>($"{rawData}"); - if (rawResult != null) - { - result = rawResult; - } - source = "REDIS"; - } - else - { - result = dbController.AnagGruppiRepartoDTO(); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"ElencoRepartiDTO | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + return await GetOrFetchAsync( + operationName: "ElencoRepartiDtoAsync", + cacheKey: $"{Utils.redisAnagGruppi}:REPARTO", + expiration: getRandTOut(redisLongTimeCache), + fetchFunc: async () => await dbController.AnagGruppiRepartoDtoAsync() ?? new(), + tagList: [Utils.redisAnagGruppi] + ); } /// @@ -1213,22 +1189,18 @@ namespace MP.SPEC.Data /// /// Articolo KIT (fittizio) /// Chiave x filtro conf su tab WKS - public bool IstKitInsertByWKS(string CodArtParent, string KeyFilt) + public async Task IstKitInsertByWKSAsync(string CodArtParent, string KeyFilt) { bool fatto = false; - using var activity = ActivitySource.StartActivity("IstKitInsertByWKS"); - string source = "DB+REDIS"; + using var activity = ActivitySource.StartActivity("IstKitInsertByWKSAsync"); + string source = "DB"; // salvo - fatto = dbController.IstKitInsertByWKS(CodArtParent, KeyFilt); + fatto = await dbController.IstKitInsertByWKSAsync(CodArtParent, KeyFilt); // svuoto cache - ExecFlushRedisPattern($"{Utils.redisKit}:*"); - //ExecFlushRedisPattern((RedisValue)$"{Utils.redisKitInst}:*"); - //ExecFlushRedisPattern((RedisValue)$"{Utils.redisKitScore}:*"); - //ExecFlushRedisPattern((RedisValue)$"{Utils.redisKitTempl}:*"); - //ExecFlushRedisPattern((RedisValue)$"{Utils.redisKitWip}:*"); + await FlushCacheByTagAsync(Utils.redisPOdlList); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"IstKitInsertByWKS | {source} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"IstKitInsertByWKSAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); return fatto; } @@ -1554,22 +1526,6 @@ namespace MP.SPEC.Data return fatto; } -#if false - /// - /// Record ODL da chaive - /// - /// - public async Task OdlGetByKey(int IdxOdl) - { - using var activity = ActivitySource.StartActivity("OdlGetByKey"); - string source = "DB"; - var dbResult = await dbController.OdlGetByKey(IdxOdl); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"OdlGetByKey | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return dbResult; - } -#endif /// /// Elenco ODL filtrati x stato, articolo, KeyRich (che contiene stato) @@ -2260,9 +2216,6 @@ namespace MP.SPEC.Data fatto = await dbController.WipKitDeleteAsync(currRecord); // svuoto cache await FlushCacheByTagAsync(Utils.redisKitWip); -#if false - EmptyWipCache(); -#endif activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"WipKitDeleteAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -2282,9 +2235,6 @@ namespace MP.SPEC.Data fatto = await dbController.WipKitDeleteOlderAsync(DateLimit); // svuoto cache KitWip await FlushCacheByTagAsync(Utils.redisKitWip); -#if false - EmptyWipCache(); -#endif activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"WipKitDeleteOlderAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -2321,9 +2271,6 @@ namespace MP.SPEC.Data fatto = await dbController.WipKitUpsertAsync(currRecord); // svuoto cache KitWip await FlushCacheByTagAsync(Utils.redisKitWip); -#if false - EmptyWipCache(); -#endif activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"WipKitUpsertAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -2481,19 +2428,6 @@ namespace MP.SPEC.Data #region Private Methods -#if false - /// - /// Svuota cache creazione KIT - /// - private void EmptyWipCache() - { - string pattern = $"{Utils.redisKitWip}:*"; - if (!string.IsNullOrEmpty(pattern)) - { - ExecFlushRedisPattern(pattern); - } - } -#endif /// /// Verifica caricamento dizionario ConfigData @@ -2510,21 +2444,6 @@ namespace MP.SPEC.Data .ToDictionary(g => g.Key, g => g.First().Valore); } } - /// - /// Verifica caricamento Vocabolario - /// - /// - private async Task EnsureVocabolarioLoadedAsync() - { - if (_configData.Count == 0) - { - var list = await ConfigGetAllAsync(); - - _configData = list - .GroupBy(x => x.Chiave) - .ToDictionary(g => g.Key, g => g.First().Valore); - } - } /// /// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria + tracking attività diff --git a/MP.SPEC/Pages/GroupMacOprMan.razor b/MP.SPEC/Pages/RepOper.razor similarity index 98% rename from MP.SPEC/Pages/GroupMacOprMan.razor rename to MP.SPEC/Pages/RepOper.razor index df08cb90..6e30fd89 100644 --- a/MP.SPEC/Pages/GroupMacOprMan.razor +++ b/MP.SPEC/Pages/RepOper.razor @@ -41,7 +41,7 @@ @if (ShowDetail) { -
                                            +
                                            diff --git a/MP.SPEC/Pages/GroupMacOprMan.razor.cs b/MP.SPEC/Pages/RepOper.razor.cs similarity index 81% rename from MP.SPEC/Pages/GroupMacOprMan.razor.cs rename to MP.SPEC/Pages/RepOper.razor.cs index f9f63a52..de1002c2 100644 --- a/MP.SPEC/Pages/GroupMacOprMan.razor.cs +++ b/MP.SPEC/Pages/RepOper.razor.cs @@ -5,7 +5,7 @@ using MP.SPEC.Data; namespace MP.SPEC.Pages { - public partial class GroupMacOprMan + public partial class RepOper { #region Protected Fields @@ -64,7 +64,7 @@ namespace MP.SPEC.Pages private string CssMain { - get => ShowDetail ? "col-3" : "col-12"; + get => ShowDetail ? "col-4" : "col-12"; } private bool ShowDetail @@ -96,14 +96,18 @@ namespace MP.SPEC.Pages { isLoading = true; ListMacchine?.Clear(); - var rawList = MDService.ElencoRepartiDTO(); - if (string.IsNullOrEmpty(SearchVal)) + ListReparti?.Clear(); + if (string.IsNullOrEmpty(CodGruppo)) { - ListReparti = rawList; - } - else - { - ListReparti = rawList.Where(x => x.CodGruppo.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || x.DescrGruppo.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase)).ToList(); + var rawList = await MDService.ElencoRepartiDtoAsync(); + if (string.IsNullOrEmpty(SearchVal)) + { + ListReparti = rawList; + } + else + { + ListReparti = rawList.Where(x => x.CodGruppo.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || x.DescrGruppo.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase)).ToList(); + } } if (!string.IsNullOrEmpty(CodGruppo)) { @@ -122,9 +126,10 @@ namespace MP.SPEC.Pages } } - private void ResetSearch() + private async Task ResetSearch() { SearchVal = ""; + await ReloadDataAsync(); } private async Task SetCodGruppo(string CodGruppoSel) diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 75f6846d..fb313057 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2605.2911 + 8.16.2605.2912 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index 91b4a17f..1b148368 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                            Versione: 8.16.2605.2911

                                            +

                                            Versione: 8.16.2605.2912


                                            Note di rilascio:
                                              diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 5bba24a5..a0cc7bd5 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2911 +8.16.2605.2912 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index 12a79c96..49b25e7c 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2911 + 8.16.2605.2912 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false diff --git a/Refactor_Plan.md b/Refactor_Plan.md index 64db86af..5be856a1 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -55,6 +55,10 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - `WipKitFiltAsync` - `MseGetAllAsync` (Migrato e rinominato) - `OdlByKeyAsync` (Migrato e rinominato) +- `TemplateKitDeleteAsync` (Migrato con tag invalidazione) +- `TemplateKitUpsertAsync` (Migrato con tag invalidazione) +- `WipKitDeleteAsync` (Migrato con tag invalidazione) +- `WipKitUpsertAsync` (Migrato con tag invalidazione) #### 🛠️ Metodi da Migrare (Usano ancora Redis/DB manuale) - [ ] Migrazione di `ActionGetReq` (linea 110: usa `redisDb.StringGetAsync`). @@ -82,3 +86,4 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - **Rischio**: Errori di serializzazione. - *Mitigazione*: `FusionCache` gestisce la serializzazione, ma è necessario assicurarsi che i tipi di ritorno siano compatibili con le aspettative dei chiamanti. + From ff789417954f981ffb81091d314c8c5a5c3f70d6 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Sat, 30 May 2026 07:18:52 +0200 Subject: [PATCH 071/102] Inizio fix gestione reparti --- MP.SPEC/Components/Reparti/ListReparti.razor | 2 +- .../Components/Reparti/ListReparti.razor.cs | 9 ++++---- MP.SPEC/Data/MpDataService.cs | 22 +++++++++---------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/RepOper.razor.cs | 14 ++++-------- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 8 files changed, 24 insertions(+), 31 deletions(-) diff --git a/MP.SPEC/Components/Reparti/ListReparti.razor b/MP.SPEC/Components/Reparti/ListReparti.razor index 05f03dfe..4189ceba 100644 --- a/MP.SPEC/Components/Reparti/ListReparti.razor +++ b/MP.SPEC/Components/Reparti/ListReparti.razor @@ -95,7 +95,7 @@ {
                                            - @if(EditRec==null) + @if (EditRec == null) { } diff --git a/MP.SPEC/Components/Reparti/ListReparti.razor.cs b/MP.SPEC/Components/Reparti/ListReparti.razor.cs index f95b835b..0707f871 100644 --- a/MP.SPEC/Components/Reparti/ListReparti.razor.cs +++ b/MP.SPEC/Components/Reparti/ListReparti.razor.cs @@ -1,10 +1,9 @@ using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.DataProtection; using Microsoft.JSInterop; +using MP.AppAuth.Services; using MP.Core.DTO; using MP.Data.DbModels; using MP.SPEC.Data; -using MP.AppAuth.Services; namespace MP.SPEC.Components.Reparti { @@ -157,7 +156,7 @@ namespace MP.SPEC.Components.Reparti SelEnabled = selRec.SelEnabled, TipoGruppo = selRec.TipoGruppo }; - MDService.AnagGruppiDelete(rec2Del); + await MDService.AnagGruppiDeleteAsync(rec2Del); EditRec = null; await EC_RecordUpdated.InvokeAsync(true); } @@ -176,6 +175,7 @@ namespace MP.SPEC.Components.Reparti private async Task DoSelect(RepartiDTO currRec) { // seleziona + EditRec = null; SelRecord = currRec; await EC_RecordSel.InvokeAsync(currRec.CodGruppo); } @@ -183,7 +183,7 @@ namespace MP.SPEC.Components.Reparti private async Task DoUpdate(AnagGruppiModel UpdRec) { // salvo... - MDService.AnagGruppiUpsert(UpdRec); + await MDService.AnagGruppiUpsertAsync(UpdRec); EditRec = null; await EC_RecordUpdated.InvokeAsync(true); } @@ -192,6 +192,7 @@ namespace MP.SPEC.Components.Reparti { SelRecord = null; EditRec = null; + UpdateTable(); await EC_RecordSel.InvokeAsync(""); } diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 340afee9..cb599b90 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -186,17 +186,16 @@ namespace MP.SPEC.Data /// Delete record AnagraficaGruppi /// /// - public bool AnagGruppiDelete(AnagGruppiModel updRec) + public async Task AnagGruppiDeleteAsync(AnagGruppiModel updRec) { - using var activity = ActivitySource.StartActivity("AnagGruppiDelete"); + using var activity = ActivitySource.StartActivity("AnagGruppiDeleteAsync"); bool result = false; result = dbController.AnagGruppiDelete(updRec); // elimino cache redis... - string pattern = $"{Utils.redisAnagGruppi}:*"; - bool answ = ExecFlushRedisPattern(pattern); - activity?.SetTag("data.source", "DB+REDIS"); + await FlushCacheByTagAsync(Utils.redisAnagGruppi); + activity?.SetTag("data.source", "DB"); activity?.Stop(); - LogTrace($"AnagGruppiDelete | CodGruppo {updRec.CodGruppo} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"AnagGruppiDeleteAsync | CodGruppo {updRec.CodGruppo} | {activity?.Duration.TotalMilliseconds}ms"); return result; } @@ -205,17 +204,16 @@ namespace MP.SPEC.Data /// /// /// - public bool AnagGruppiUpsert(AnagGruppiModel UpdRec) + public async Task AnagGruppiUpsertAsync(AnagGruppiModel UpdRec) { - using var activity = ActivitySource.StartActivity("AnagGruppiUpsert"); + using var activity = ActivitySource.StartActivity("AnagGruppiUpsertAsync"); bool result = false; result = dbController.AnagGruppiUpsert(UpdRec); // elimino cache redis... - string pattern = $"{Utils.redisAnagGruppi}:*"; - bool answ = ExecFlushRedisPattern(pattern); - activity?.SetTag("data.source", "DB+REDIS"); + await FlushCacheByTagAsync(Utils.redisAnagGruppi); + activity?.SetTag("data.source", "DB"); activity?.Stop(); - LogTrace($"AnagGruppiUpsert | CodGruppo {UpdRec.CodGruppo} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"AnagGruppiUpsertAsync | CodGruppo {UpdRec.CodGruppo} | {activity?.Duration.TotalMilliseconds}ms"); return result; } diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 4f385d7b..10ab6e68 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.2912 + 8.16.2605.3007 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/RepOper.razor.cs b/MP.SPEC/Pages/RepOper.razor.cs index de1002c2..6cf08ced 100644 --- a/MP.SPEC/Pages/RepOper.razor.cs +++ b/MP.SPEC/Pages/RepOper.razor.cs @@ -62,15 +62,9 @@ namespace MP.SPEC.Pages get => string.IsNullOrWhiteSpace(SearchVal) ? "btn-secondary" : "btn-primary"; } - private string CssMain - { - get => ShowDetail ? "col-4" : "col-12"; - } + private string CssMain => ShowDetail ? "col-4" : "col-12"; - private bool ShowDetail - { - get => !string.IsNullOrEmpty(CodGruppo); - } + private bool ShowDetail => !string.IsNullOrEmpty(CodGruppo); #endregion Private Properties @@ -134,10 +128,10 @@ namespace MP.SPEC.Pages private async Task SetCodGruppo(string CodGruppoSel) { - isLoading = true; + //isLoading = true; CodGruppo = CodGruppoSel; await ReloadDetailAsync(); - isLoading = false; + //isLoading = false; } #endregion Private Methods diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 26e66a60..2f246f77 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                            Versione: 8.16.2605.2912

                                            +

                                            Versione: 8.16.2605.3007


                                            Note di rilascio:
                                            • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index a0cc7bd5..a025c228 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2912 +8.16.2605.3007 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index c6942b53..f5b17fe1 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2912 + 8.16.2605.3007 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From 1b06aec69282a23cb4815e28a0e8d713ba25610e Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Sat, 30 May 2026 07:19:09 +0200 Subject: [PATCH 072/102] refres reparti --- MP.SPEC/Pages/RepOper.razor.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/MP.SPEC/Pages/RepOper.razor.cs b/MP.SPEC/Pages/RepOper.razor.cs index 6cf08ced..7ff923d2 100644 --- a/MP.SPEC/Pages/RepOper.razor.cs +++ b/MP.SPEC/Pages/RepOper.razor.cs @@ -128,10 +128,8 @@ namespace MP.SPEC.Pages private async Task SetCodGruppo(string CodGruppoSel) { - //isLoading = true; CodGruppo = CodGruppoSel; await ReloadDetailAsync(); - //isLoading = false; } #endregion Private Methods From 26e8ca037033a601d2662b7c8ae48cc9290e6044 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Sat, 30 May 2026 09:18:19 +0200 Subject: [PATCH 073/102] Fix gestione reparti/operatore --- MP.Data/Controllers/MpSpecController.cs | 88 +++++++++---------- .../Components/Reparti/ListMacchine.razor.cs | 4 +- .../Components/Reparti/ListOperatori.razor.cs | 4 +- .../Components/Reparti/ListReparti.razor.cs | 18 ++-- MP.SPEC/Data/MpDataService.cs | 60 ++++++------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/RepOper.razor | 2 +- MP.SPEC/Pages/RepOper.razor.cs | 6 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- Refactor_Plan.md | 3 +- 12 files changed, 97 insertions(+), 96 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 45e911b3..a0b20991 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -1175,21 +1175,19 @@ namespace MP.Data.Controllers /// /// /// - public bool Grp2MaccDelete(Gruppi2MaccModel rec2del) + public async Task Grp2MaccDeleteAsync(Gruppi2MaccModel rec2del) { bool answ = false; - using (var dbCtx = new MoonProContext(options)) + using var dbCtx = new MoonProContext(options); + var dbRec = await dbCtx + .DbSetGrp2Macc + .Where(x => x.CodGruppo == rec2del.CodGruppo && x.IdxMacchina == rec2del.IdxMacchina) + .FirstOrDefaultAsync(); + if (dbRec != null) { - var dbRec = dbCtx - .DbSetGrp2Macc - .Where(x => x.CodGruppo == rec2del.CodGruppo && x.IdxMacchina == rec2del.IdxMacchina) - .FirstOrDefault(); - if (dbRec != null) - { - dbCtx.DbSetGrp2Macc.Remove(dbRec); - int numDone = dbCtx.SaveChanges(); - answ = numDone != 0; - } + dbCtx.DbSetGrp2Macc.Remove(dbRec); + int numDone = await dbCtx.SaveChangesAsync(); + answ = numDone != 0; } return answ; } @@ -1199,22 +1197,20 @@ namespace MP.Data.Controllers /// /// /// - public bool Grp2MaccInsert(Gruppi2MaccModel upsRec) + public async Task Grp2MaccInsertAsync(Gruppi2MaccModel upsRec) { bool answ = false; - using (var dbCtx = new MoonProContext(options)) + using var dbCtx = new MoonProContext(options); + var dbRec = await dbCtx + .DbSetGrp2Macc + .Where(x => x.CodGruppo == upsRec.CodGruppo && x.IdxMacchina == upsRec.IdxMacchina) + .FirstOrDefaultAsync(); + if (dbRec == null) { - var dbRec = dbCtx - .DbSetGrp2Macc - .Where(x => x.CodGruppo == upsRec.CodGruppo && x.IdxMacchina == upsRec.IdxMacchina) - .FirstOrDefault(); - if (dbRec == null) - { - dbCtx.DbSetGrp2Macc.Add(upsRec); - // salvo - int numDone = dbCtx.SaveChanges(); - answ = numDone != 0; - } + await dbCtx.DbSetGrp2Macc.AddAsync(upsRec); + // salvo + int numDone = await dbCtx.SaveChangesAsync(); + answ = numDone != 0; } return answ; } @@ -1224,21 +1220,19 @@ namespace MP.Data.Controllers /// /// /// - public bool Grp2OperDelete(Gruppi2OperModel rec2del) + public async Task Grp2OperDeleteAsync(Gruppi2OperModel rec2del) { bool answ = false; - using (var dbCtx = new MoonProContext(options)) - { - var dbRec = dbCtx + using var dbCtx = new MoonProContext(options); + var dbRec = await dbCtx .DbSetGrp2Oper .Where(x => x.CodGruppo == rec2del.CodGruppo && x.MatrOpr == rec2del.MatrOpr) - .FirstOrDefault(); - if (dbRec != null) - { - dbCtx.DbSetGrp2Oper.Remove(dbRec); - int numDone = dbCtx.SaveChanges(); - answ = numDone != 0; - } + .FirstOrDefaultAsync(); + if (dbRec != null) + { + dbCtx.DbSetGrp2Oper.Remove(dbRec); + int numDone = await dbCtx.SaveChangesAsync(); + answ = numDone != 0; } return answ; } @@ -1248,22 +1242,20 @@ namespace MP.Data.Controllers /// /// /// - public bool Grp2OperInsert(Gruppi2OperModel upsRec) + public async Task Grp2OperInsertAsync(Gruppi2OperModel upsRec) { bool answ = false; - using (var dbCtx = new MoonProContext(options)) - { - var dbRec = dbCtx + using var dbCtx = new MoonProContext(options); + var dbRec = await dbCtx .DbSetGrp2Oper .Where(x => x.CodGruppo == upsRec.CodGruppo && x.MatrOpr == upsRec.MatrOpr) - .FirstOrDefault(); - if (dbRec == null) - { - dbCtx.DbSetGrp2Oper.Add(upsRec); - // salvo - int numDone = dbCtx.SaveChanges(); - answ = numDone != 0; - } + .FirstOrDefaultAsync(); + if (dbRec == null) + { + await dbCtx.DbSetGrp2Oper.AddAsync(upsRec); + // salvo + int numDone = await dbCtx.SaveChangesAsync(); + answ = numDone != 0; } return answ; } diff --git a/MP.SPEC/Components/Reparti/ListMacchine.razor.cs b/MP.SPEC/Components/Reparti/ListMacchine.razor.cs index f8a2d32c..cd163788 100644 --- a/MP.SPEC/Components/Reparti/ListMacchine.razor.cs +++ b/MP.SPEC/Components/Reparti/ListMacchine.razor.cs @@ -100,7 +100,7 @@ namespace MP.SPEC.Components.Reparti CodGruppo = CodGruppoCurr, IdxMacchina = currRec.IdxMacchina }; - MDService.Grp2MaccInsert(rec2del); + await MDService.Grp2MaccInsertAsync(rec2del); await EC_RecChange.InvokeAsync(false); } @@ -115,7 +115,7 @@ namespace MP.SPEC.Components.Reparti CodGruppo = CodGruppoCurr, IdxMacchina = currRec.IdxMacchina }; - MDService.Grp2MaccDelete(rec2del); + await MDService.Grp2MaccDeleteAsync(rec2del); await EC_RecChange.InvokeAsync(false); } diff --git a/MP.SPEC/Components/Reparti/ListOperatori.razor.cs b/MP.SPEC/Components/Reparti/ListOperatori.razor.cs index a6cedabb..2ca7dcab 100644 --- a/MP.SPEC/Components/Reparti/ListOperatori.razor.cs +++ b/MP.SPEC/Components/Reparti/ListOperatori.razor.cs @@ -101,7 +101,7 @@ namespace MP.SPEC.Components.Reparti CodGruppo = CodGruppoCurr, MatrOpr = currRec.MatrOpr }; - MDService.Grp2OperInsert(rec2del); + await MDService.Grp2OperInsertAsync(rec2del); await EC_RecChange.InvokeAsync(false); } @@ -116,7 +116,7 @@ namespace MP.SPEC.Components.Reparti CodGruppo = CodGruppoCurr, MatrOpr = currRec.MatrOpr }; - MDService.Grp2OperDelete(rec2del); + await MDService.Grp2OperDeleteAsync(rec2del); await EC_RecChange.InvokeAsync(false); } diff --git a/MP.SPEC/Components/Reparti/ListReparti.razor.cs b/MP.SPEC/Components/Reparti/ListReparti.razor.cs index 0707f871..1582c6fa 100644 --- a/MP.SPEC/Components/Reparti/ListReparti.razor.cs +++ b/MP.SPEC/Components/Reparti/ListReparti.razor.cs @@ -14,6 +14,9 @@ namespace MP.SPEC.Components.Reparti [Parameter] public List? AllRecords { get; set; } = null; + [Parameter] + public string CodGruppoSel { get; set; } = null!; + [Parameter] public EventCallback EC_RecordSel { get; set; } @@ -24,11 +27,6 @@ namespace MP.SPEC.Components.Reparti #region Protected Properties - protected bool IsSuperAdmin - { - get => HasRole(AppAuthService.RoleSuperAdmin); - } - [Inject] protected IJSRuntime JSRuntime { get; set; } = null!; @@ -62,6 +60,11 @@ namespace MP.SPEC.Components.Reparti protected override void OnParametersSet() { isLoading = true; + // verifico se ho gruppo sel... + if (!string.IsNullOrEmpty(CodGruppoSel) && AllRecords != null && AllRecords.Any()) + { + SelRecord = AllRecords.FirstOrDefault(x => x.CodGruppo == CodGruppoSel); + } UpdateTable(); isLoading = false; } @@ -116,6 +119,11 @@ namespace MP.SPEC.Components.Reparti get => EditRec == null ? "Aggiungi Reparto" : "Chiudi/Annulla"; } + private bool IsSuperAdmin + { + get => HasRole(AppAuthService.RoleSuperAdmin); + } + #endregion Private Properties #region Private Methods diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index cb599b90..e7ba4a1a 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1065,16 +1065,16 @@ namespace MP.SPEC.Data /// /// /// - public bool Grp2MaccDelete(Gruppi2MaccModel rec2del) + public async Task Grp2MaccDeleteAsync(Gruppi2MaccModel rec2del) { - using var activity = ActivitySource.StartActivity("Grp2MaccDelete"); + using var activity = ActivitySource.StartActivity("Grp2MaccDeleteAsync"); bool result = false; - result = dbController.Grp2MaccDelete(rec2del); + result = await dbController.Grp2MaccDeleteAsync(rec2del); // elimino cache redis... - ResetMacGrpCache(); - activity?.SetTag("data.source", "DB+REDIS"); + await ResetMacGrpCache(); + activity?.SetTag("data.source", "DB"); activity?.Stop(); - LogTrace($"Grp2MaccDelete | CodGruppo {rec2del.CodGruppo} | IdxMacc {rec2del.IdxMacchina} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"Grp2MaccDeleteAsync | CodGruppo {rec2del.CodGruppo} | IdxMacc {rec2del.IdxMacchina} | {activity?.Duration.TotalMilliseconds}ms"); return result; } @@ -1083,16 +1083,16 @@ namespace MP.SPEC.Data /// /// /// - public bool Grp2MaccInsert(Gruppi2MaccModel upsRec) + public async Task Grp2MaccInsertAsync(Gruppi2MaccModel upsRec) { - using var activity = ActivitySource.StartActivity("Grp2MaccInsert"); + using var activity = ActivitySource.StartActivity("Grp2MaccInsertAsync"); bool result = false; - result = dbController.Grp2MaccInsert(upsRec); + result = await dbController.Grp2MaccInsertAsync(upsRec); // elimino cache redis... - ResetMacGrpCache(); - activity?.SetTag("data.source", "DB+REDIS"); + await ResetMacGrpCache(); + activity?.SetTag("data.source", "DB"); activity?.Stop(); - LogTrace($"Grp2MaccInsert | CodGruppo {upsRec.CodGruppo} | IdxMacc {upsRec.IdxMacchina} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"Grp2MaccInsertAsync | CodGruppo {upsRec.CodGruppo} | IdxMacc {upsRec.IdxMacchina} | {activity?.Duration.TotalMilliseconds}ms"); return result; } @@ -1101,16 +1101,16 @@ namespace MP.SPEC.Data /// /// /// - public bool Grp2OperDelete(Gruppi2OperModel rec2del) + public async Task Grp2OperDeleteAsync(Gruppi2OperModel rec2del) { - using var activity = ActivitySource.StartActivity("Grp2OperDelete"); + using var activity = ActivitySource.StartActivity("Grp2OperDeleteAsync"); bool result = false; - result = dbController.Grp2OperDelete(rec2del); + result = await dbController.Grp2OperDeleteAsync(rec2del); // elimino cache redis... - ResetOprGrpCache(); - activity?.SetTag("data.source", "DB+REDIS"); + await ResetOprGrpCache(); + activity?.SetTag("data.source", "DB"); activity?.Stop(); - LogTrace($"Grp2OperDelete | CodGruppo {rec2del.CodGruppo} | MatrOpr {rec2del.MatrOpr} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"Grp2OperDeleteAsync | CodGruppo {rec2del.CodGruppo} | MatrOpr {rec2del.MatrOpr} | {activity?.Duration.TotalMilliseconds}ms"); return result; } @@ -1119,16 +1119,16 @@ namespace MP.SPEC.Data /// /// /// - public bool Grp2OperInsert(Gruppi2OperModel upsRec) + public async Task Grp2OperInsertAsync(Gruppi2OperModel upsRec) { - using var activity = ActivitySource.StartActivity("Grp2OperInsert"); + using var activity = ActivitySource.StartActivity("Grp2OperInsertAsync"); bool result = false; - result = dbController.Grp2OperInsert(upsRec); + result = await dbController.Grp2OperInsertAsync(upsRec); // elimino cache redis... - ResetOprGrpCache(); - activity?.SetTag("data.source", "DB+REDIS"); + await ResetOprGrpCache(); + activity?.SetTag("data.source", "DB"); activity?.Stop(); - LogTrace($"Grp2OperInsert | CodGruppo {upsRec.CodGruppo} | MatrOpr {upsRec.MatrOpr} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"Grp2OperInsertAsync | CodGruppo {upsRec.CodGruppo} | MatrOpr {upsRec.MatrOpr} | {activity?.Duration.TotalMilliseconds}ms"); return result; } @@ -2579,19 +2579,19 @@ namespace MP.SPEC.Data /// /// Reset macchine e gruppi /// - private void ResetMacGrpCache() + private async Task ResetMacGrpCache() { - ExecFlushRedisPattern($"{Utils.redisAnagGruppi}:*"); - ExecFlushRedisPattern($"{Utils.redisMacList}:*"); + await FlushCacheByTagsAsync(new List { Utils.redisAnagGruppi, Utils.redisMacList }); } /// /// Reset cache operatori e gruppi /// - private void ResetOprGrpCache() + private async Task ResetOprGrpCache() { - ExecFlushRedisPattern($"{Utils.redisAnagGruppi}:*"); - ExecFlushRedisPattern($"{Utils.redisOprList}:*"); + //ExecFlushRedisPattern($"{Utils.redisAnagGruppi}:*"); + //ExecFlushRedisPattern($"{Utils.redisOprList}:*"); + await FlushCacheByTagsAsync(new List { Utils.redisAnagGruppi, Utils.redisOprList }); } #endregion Private Methods diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 10ab6e68..b0dddc59 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.3007 + 8.16.2605.3009 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/RepOper.razor b/MP.SPEC/Pages/RepOper.razor index 6e30fd89..22084e57 100644 --- a/MP.SPEC/Pages/RepOper.razor +++ b/MP.SPEC/Pages/RepOper.razor @@ -37,7 +37,7 @@
                                              - +
                                              @if (ShowDetail) { diff --git a/MP.SPEC/Pages/RepOper.razor.cs b/MP.SPEC/Pages/RepOper.razor.cs index 7ff923d2..0dda2fc3 100644 --- a/MP.SPEC/Pages/RepOper.razor.cs +++ b/MP.SPEC/Pages/RepOper.razor.cs @@ -89,10 +89,10 @@ namespace MP.SPEC.Pages private async Task ReloadDataAsync() { isLoading = true; - ListMacchine?.Clear(); - ListReparti?.Clear(); - if (string.IsNullOrEmpty(CodGruppo)) + //ListMacchine?.Clear(); + if (string.IsNullOrEmpty(CodGruppo) || true) { + ListReparti?.Clear(); var rawList = await MDService.ElencoRepartiDtoAsync(); if (string.IsNullOrEmpty(SearchVal)) { diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 2f246f77..67011e00 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                              Versione: 8.16.2605.3007

                                              +

                                              Versione: 8.16.2605.3009


                                              Note di rilascio:
                                              • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index a025c228..77349332 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.3007 +8.16.2605.3009 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index f5b17fe1..8818602e 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.3007 + 8.16.2605.3009 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/Refactor_Plan.md b/Refactor_Plan.md index 5be856a1..ed85dfe8 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -46,7 +46,7 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - `OdlListGetFiltAsync` - `OperatoriGetFiltAsync` - `ParametriGetFiltAsync` -- `PODL_getDictOdlPodlAsync` (Parziale/Ibrido) +- `PODL_getDictOdlPodlAsync` (Migrato con gestione manuale L1/L2) - `POdlGetByOdlAsync` - `POdlToKitListGetFiltAsync` - `StatoMacchinaAsync` @@ -87,3 +87,4 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - *Mitigazione*: `FusionCache` gestisce la serializzazione, ma è necessario assicurarsi che i tipi di ritorno siano compatibili con le aspettative dei chiamanti. + From 79024ddcac85526c1263f3a882c62bbfadf7bcdc Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Sat, 30 May 2026 09:58:24 +0200 Subject: [PATCH 074/102] Ok gestione eliminazione KIT --- MP.Data/Controllers/MpSpecController.cs | 117 +++++++----------- MP.SPEC/Components/ListPODL.razor.cs | 2 +- .../Components/ProdKit/GestKitPodl.razor.cs | 5 +- .../Components/ProdKit/KitPodlMan.razor.cs | 42 ++++--- MP.SPEC/Components/ProdKit/Manager.razor | 2 +- MP.SPEC/Components/ProdKit/Manager.razor.cs | 4 +- MP.SPEC/Data/MpDataService.cs | 81 ++++++++---- MP.SPEC/Pages/Podl2Kit.razor.cs | 2 +- Refactor_Plan.md | 12 +- 9 files changed, 142 insertions(+), 125 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index a0b20991..d6819e96 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -1264,26 +1264,21 @@ namespace MP.Data.Controllers /// Elimina record /// /// - public bool IstKitDelete(IstanzeKitModel rec2del) + public async Task IstKitDeleteAsync(IstanzeKitModel rec2del) { - bool fatto = false; - using (var dbCtx = new MoonProContext(options)) - { - var actRec = dbCtx + using var dbCtx = new MoonProContext(options); + var actRec = await dbCtx .DbSetInstKit .Where(x => x.KeyKit == rec2del.KeyKit && x.KeyExtOrd == rec2del.KeyExtOrd) - .FirstOrDefault(); - // se ci fosse aggiorno... - if (actRec != null) - { - dbCtx - .DbSetInstKit - .Remove(actRec); - } - var res = dbCtx.SaveChanges(); - fatto = res != 0; + .FirstOrDefaultAsync(); + // se ci fosse aggiorno... + if (actRec != null) + { + dbCtx + .DbSetInstKit + .Remove(actRec); } - return fatto; + return await dbCtx.SaveChangesAsync() > 0; } /// @@ -1324,35 +1319,30 @@ namespace MP.Data.Controllers /// Esegue upsert record /// /// - public bool IstKitUpsert(IstanzeKitModel editRec) + public async Task IstKitUpsertAsync(IstanzeKitModel editRec) { - bool fatto = false; - using (var dbCtx = new MoonProContext(options)) - { - var actRec = dbCtx + using var dbCtx = new MoonProContext(options); + var actRec = await dbCtx .DbSetInstKit .Where(x => x.KeyKit == editRec.KeyKit && x.KeyExtOrd == editRec.KeyExtOrd) - .FirstOrDefault(); + .FirstOrDefaultAsync(); - // se ci fosse aggiorno... - if (actRec == null) - { - dbCtx + // se ci fosse aggiorno... + if (actRec == null) + { + await dbCtx .DbSetInstKit - .Add(editRec); - } - else - { - actRec.CodArtParent = editRec.CodArtParent; - actRec.CodArtChild = editRec.CodArtChild; - actRec.QtyART = editRec.QtyART; - actRec.QtyKIT = editRec.QtyKIT; - dbCtx.Entry(actRec).State = EntityState.Modified; - } - var res = dbCtx.SaveChanges(); - fatto = res != 0; + .AddAsync(editRec); } - return fatto; + else + { + actRec.CodArtParent = editRec.CodArtParent; + actRec.CodArtChild = editRec.CodArtChild; + actRec.QtyART = editRec.QtyART; + actRec.QtyKIT = editRec.QtyKIT; + dbCtx.Entry(actRec).State = EntityState.Modified; + } + return await dbCtx.SaveChangesAsync() > 0; } /// @@ -1468,22 +1458,17 @@ namespace MP.Data.Controllers /// /// True = aperti (=senza ODL) /// - public List ListPODL_ByCodArt(string CodArticolo, bool OnlyAvail) + public async Task> ListPODL_ByCodArtAsync(string CodArticolo, bool OnlyAvail) { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - var pCodArticolo = new SqlParameter("@CodArticolo", CodArticolo); - var pOnlyAvail = new SqlParameter("@onlyAvail", OnlyAvail); + using var dbCtx = new MoonProContext(options); + var pCodArticolo = new SqlParameter("@CodArticolo", CodArticolo); + var pOnlyAvail = new SqlParameter("@onlyAvail", OnlyAvail); - dbResult = dbCtx + return await dbCtx .DbSetPODLExp .FromSqlRaw("EXEC stp_PODL_getByCodArt @CodArticolo, @onlyAvail", pCodArticolo, pOnlyAvail) .AsNoTracking() - .ToList(); - } - - return dbResult; + .ToListAsync(); } /// @@ -1491,20 +1476,16 @@ namespace MP.Data.Controllers /// /// IDX PODL parent /// - public List ListPODL_ByKitParent(int IdxPodlParent) + public async Task> ListPODL_ByKitParentAsync(int IdxPodlParent) { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - var pIdxPodlParent = new SqlParameter("@IdxPodlParent", IdxPodlParent); + using var dbCtx = new MoonProContext(options); + var pIdxPodlParent = new SqlParameter("@IdxPodlParent", IdxPodlParent); - dbResult = dbCtx + return await dbCtx .DbSetPODLExp .FromSqlRaw("EXEC stp_PODL_getByParentKitIdx @IdxPodlParent", pIdxPodlParent) .AsNoTracking() - .ToList(); - } - return dbResult; + .ToListAsync(); } /// @@ -2369,19 +2350,15 @@ namespace MP.Data.Controllers /// Effettua il task di eliminazione PODL KIT + istanze + riattivazione PODL originali disattivate tramite stored /// /// IdxPODL parent - public bool PodlIstKitDelete(int IdxPODL) + public async Task PodlIstKitDeleteAsync(int IdxPODL) { - bool answ = false; - using (var dbCtx = new MoonProContext(options)) - { - var pIdxPODL = new SqlParameter("@IdxPODL", IdxPODL); + using var dbCtx = new MoonProContext(options); + var pIdxPODL = new SqlParameter("@IdxPODL", IdxPODL); - var dbResult = dbCtx - .Database - .ExecuteSqlRaw("EXEC dbo.stp_PodlIstKit_delete @IdxPODL", pIdxPODL); - answ = dbResult != 0; - } - return answ; + var dbResult = await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC dbo.stp_PodlIstKit_delete @IdxPODL", pIdxPODL); + return dbResult != 0; } /// diff --git a/MP.SPEC/Components/ListPODL.razor.cs b/MP.SPEC/Components/ListPODL.razor.cs index 0ba0d75e..fbcb863b 100644 --- a/MP.SPEC/Components/ListPODL.razor.cs +++ b/MP.SPEC/Components/ListPODL.razor.cs @@ -156,7 +156,7 @@ namespace MP.SPEC.Components if (recSel != null) { ListKitTemplate = await MDService.TemplateKitFiltAsync(recSel.CodArticolo, ""); - ListPOdlKit = MDService.POdlListByKitParent(recSel.IdxPromessa); + ListPOdlKit = await MDService.POdlListByKitParentAsync(recSel.IdxPromessa); } else { diff --git a/MP.SPEC/Components/ProdKit/GestKitPodl.razor.cs b/MP.SPEC/Components/ProdKit/GestKitPodl.razor.cs index af54bc10..e15fd13e 100644 --- a/MP.SPEC/Components/ProdKit/GestKitPodl.razor.cs +++ b/MP.SPEC/Components/ProdKit/GestKitPodl.razor.cs @@ -101,8 +101,7 @@ namespace MP.SPEC.Components.ProdKit if (!await JSRuntime.InvokeAsync("confirm", "Eliminazione PODL + Istanze KIT: sei sicuro di voler procedere?")) return; - // da provare... - var done = MDService.PodlIstKitDelete(selRec.IdxPromessa); + var done = await MDService.PodlIstKitDeleteAsync(selRec.IdxPromessa); ReloadData(); await EC_ListUpdated.InvokeAsync(true); } @@ -301,7 +300,7 @@ namespace MP.SPEC.Components.ProdKit { isLoading = true; // reset preliminare... - ListRecordsPODL = new List(); + ListRecordsPODL?.Clear(); var filtRecordsPODL = PodlRecords .Where(x => !string.IsNullOrEmpty(x.KeyRichiesta) && x.KeyRichiesta.StartsWith("KIT")) diff --git a/MP.SPEC/Components/ProdKit/KitPodlMan.razor.cs b/MP.SPEC/Components/ProdKit/KitPodlMan.razor.cs index 5f8d0254..0bb9c05f 100644 --- a/MP.SPEC/Components/ProdKit/KitPodlMan.razor.cs +++ b/MP.SPEC/Components/ProdKit/KitPodlMan.razor.cs @@ -1,6 +1,5 @@ using Microsoft.AspNetCore.Components; using Microsoft.JSInterop; -using MP.Data; using MP.Data.DbModels; using MP.SPEC.Data; using MP.SPEC.Services; @@ -12,6 +11,9 @@ namespace MP.SPEC.Components.ProdKit { #region Public Properties + [Parameter] + public SelectXdlParams ActFilter { get; set; } = new SelectXdlParams(); + [Parameter] public EventCallback EC_RecordSel { get; set; } @@ -22,10 +24,11 @@ namespace MP.SPEC.Components.ProdKit public EventCallback PagerResetReq { get; set; } [Parameter] - public EventCallback UpdateRecordCount { get; set; } + public List AllRecords { get; set; } = null!; + private List SelRecords = new(); [Parameter] - public SelectXdlParams ActFilter { get; set; } = new SelectXdlParams(); + public EventCallback UpdateRecordCount { get; set; } #endregion Public Properties @@ -49,7 +52,6 @@ namespace MP.SPEC.Components.ProdKit public void Dispose() { currRecord = null; - SearchRecords = null; ListRecords = null; GC.Collect(); } @@ -88,6 +90,11 @@ namespace MP.SPEC.Components.ProdKit get => string.IsNullOrEmpty(SearchVal) ? "btn-secondary" : "btn-primary"; } + protected string sSearchtCss + { + get => string.IsNullOrEmpty(searchVal) ? "btn-secondary" : "btn-primary"; + } + #endregion Protected Properties #region Protected Methods @@ -110,7 +117,7 @@ namespace MP.SPEC.Components.ProdKit if (!lastFilter.Equals(ActFilter) || true) { lastFilter = ActFilter.clone(); - await ReloadData(); + await ReloadDataAsync(); } } @@ -124,15 +131,17 @@ namespace MP.SPEC.Components.ProdKit }); } - protected async Task ReloadData() + protected async Task ReloadDataAsync() { ListRecords = null; isLoading = true; - SearchRecords = await MDService.POdlToKitListGetFiltAsync(hasOdl, StatoSel, macchina, reparto, selDtStart, selDtEnd); +#if false + AllRecords = await MDService.POdlToKitListGetFiltAsync(hasOdl, StatoSel, macchina, reparto, selDtStart, selDtEnd); +#endif // rivedere filtro FixMe ToDo!!! // filtro tenendo SOLO se hanno keyRichiesta CodExt + ATTIVI + NON KIT | Hard Coded... - SearchRecords = SearchRecords + SelRecords = AllRecords .Where(x => !string.IsNullOrEmpty(x.KeyRichiesta) && x.Attivabile && !x.KeyRichiesta.StartsWith("KIT")) .ToList(); @@ -152,7 +161,7 @@ namespace MP.SPEC.Components.ProdKit currPage = 1; if (forceUpdate) { - await ReloadData(); + await ReloadDataAsync(); } } @@ -179,7 +188,7 @@ namespace MP.SPEC.Components.ProdKit protected async Task UpdateData() { currRecord = null; - await ReloadData(); + await ReloadDataAsync(); } #endregion Protected Methods @@ -197,15 +206,8 @@ namespace MP.SPEC.Components.ProdKit /// private List odlCurrList = new List(); - private List? SearchRecords; - private string searchVal = ""; - protected string sSearchtCss - { - get => string.IsNullOrEmpty(searchVal) ? "btn-secondary" : "btn-primary"; - } - #endregion Private Fields #region Private Properties @@ -298,9 +300,9 @@ namespace MP.SPEC.Components.ProdKit private void UpdateTable() { totalCount = 0; - if (SearchRecords != null) + if (SelRecords != null) { - var filtRec = new List(SearchRecords); + var filtRec = new List(SelRecords); // se ho ricerca filtro! if (!string.IsNullOrEmpty(searchVal)) { @@ -310,7 +312,7 @@ namespace MP.SPEC.Components.ProdKit { int.TryParse(searchVal.Replace("PODL", ""), out idxPodl); } - filtRec = SearchRecords + filtRec = AllRecords .Where(x => (x.KeyRichiesta.Contains(searchVal, StringComparison.InvariantCultureIgnoreCase) || x.KeyBCode.Contains(searchVal, StringComparison.InvariantCultureIgnoreCase) || (x.IdxPromessa == idxPodl && idxPodl > 0)) diff --git a/MP.SPEC/Components/ProdKit/Manager.razor b/MP.SPEC/Components/ProdKit/Manager.razor index 68957397..5f0f7405 100644 --- a/MP.SPEC/Components/ProdKit/Manager.razor +++ b/MP.SPEC/Components/ProdKit/Manager.razor @@ -10,7 +10,7 @@ @if (DoAddNew) {
                                                - +
                                                diff --git a/MP.SPEC/Components/ProdKit/Manager.razor.cs b/MP.SPEC/Components/ProdKit/Manager.razor.cs index 1183f648..f42c073f 100644 --- a/MP.SPEC/Components/ProdKit/Manager.razor.cs +++ b/MP.SPEC/Components/ProdKit/Manager.razor.cs @@ -129,6 +129,7 @@ namespace MP.SPEC.Components.ProdKit private List listPOdlCheck = new List(); private List listTSM = new List(); private List listWSM = new List(); + private List listPOdl2Kit = new List(); private string padCodXdl = "00000"; private string userName = ""; private string userNameFull = ""; @@ -187,6 +188,7 @@ namespace MP.SPEC.Components.ProdKit { listPOdlCheck = new List(); listPOdlAct = await MDService.POdlListGetFiltAsync(ActFilt.HasOdl, ActFilt.CodFase, ActFilt.IdxMacchina, ActFilt.CodReparto, ActFilt.DtStart, ActFilt.DtEnd); + listPOdl2Kit = await MDService.POdlToKitListGetFiltAsync(ActFilt.HasOdl, ActFilt.CodFase, ActFilt.IdxMacchina, ActFilt.CodReparto, ActFilt.DtStart, ActFilt.DtEnd); listWSM = await MDService.WipKitFiltAsync(keyFilt); listTSM = await MDService.TksScoreAsync(keyFilt, 1000, true); listIKP = await MDService.IstKitFiltAsync("", ""); @@ -199,7 +201,7 @@ namespace MP.SPEC.Components.ProdKit // continuo con PODL if (!string.IsNullOrEmpty(codArtKit)) { - listPOdlCheck = MDService.ListPODL_ByCodArt(codArtKit, true); + listPOdlCheck = await MDService.ListPODL_ByCodArtAsync(codArtKit, true); } isLoading = false; } diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index e7ba4a1a..90f0a7a3 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1150,20 +1150,28 @@ namespace MP.SPEC.Data /// public async Task IstKitDelete(IstanzeKitModel currRecord) { - using var activity = ActivitySource.StartActivity("IstKitDelete"); - string source = "DB+REDIS"; + using var activity = ActivitySource.StartActivity("IstKitDeleteAsync"); + string source = "DB"; bool fatto = false; // salvo - fatto = dbController.IstKitDelete(currRecord); + fatto = await dbController.IstKitDeleteAsync(currRecord); // svuoto cache - RedisValue pattern = $"{Utils.redisKitInst}:*"; - await ExecFlushRedisPatternAsync(pattern); + await FlushKitCache(); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"IstKitDelete | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"IstKitDeleteAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return fatto; } + private async Task FlushKitCache() + { +#if false + RedisValue pattern = $"{Utils.redisKitInst}:*"; + await ExecFlushRedisPatternAsync(pattern); +#endif + await FlushCacheByTagsAsync(new List() { Utils.redisPOdlList, Utils.redisKitInst, Utils.redisKitWip, Utils.redisKitScore, Utils.redisPOdlByCodArt }); + } + /// /// Elenco Istanze KIT da ricerca /// @@ -1195,7 +1203,7 @@ namespace MP.SPEC.Data // salvo fatto = await dbController.IstKitInsertByWKSAsync(CodArtParent, KeyFilt); // svuoto cache - await FlushCacheByTagAsync(Utils.redisPOdlList); + await FlushKitCache(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"IstKitInsertByWKSAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -1208,17 +1216,16 @@ namespace MP.SPEC.Data /// public async Task IstKitUpsert(IstanzeKitModel currRecord) { - using var activity = ActivitySource.StartActivity("IstKitUpsert"); - string source = "DB+REDIS"; + using var activity = ActivitySource.StartActivity("IstKitUpsertAsync"); + string source = "DB"; bool fatto = false; // salvo - fatto = dbController.IstKitUpsert(currRecord); + fatto = await dbController.IstKitUpsertAsync(currRecord); // svuoto cache - RedisValue pattern = $"{Utils.redisKitInst}:*"; - await ExecFlushRedisPatternAsync(pattern); + await FlushKitCache(); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"IstKitUpsert | {source} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"IstKitUpsertAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); return fatto; } @@ -1245,15 +1252,24 @@ namespace MP.SPEC.Data /// /// True = aperti (=senza ODL) /// - public List ListPODL_ByCodArt(string CodArticolo, bool OnlyAvail) + public async Task> ListPODL_ByCodArtAsync(string CodArticolo, bool OnlyAvail) { + string avType = OnlyAvail ? "Avail" : "ALL"; + string currKey = $"{Utils.redisPOdlByCodArt}:{CodArticolo}:{avType}"; + return await GetOrFetchAsync( + operationName: "ListPODL_ByCodArtAsync", + cacheKey: currKey, + expiration: getRandTOut(redisLongTimeCache), + fetchFunc: async () => await dbController.ListPODL_ByCodArtAsync(CodArticolo, OnlyAvail) ?? new(), + tagList: [Utils.redisPOdlByCodArt] + ); + +#if false List result = new List(); if (!string.IsNullOrEmpty(CodArticolo)) { using var activity = ActivitySource.StartActivity("ListPODL_ByCodArt"); string source = "DB"; - string avType = OnlyAvail ? "Avail" : "ALL"; - string currKey = $"{Utils.redisPOdlByCodArt}:{CodArticolo}:{avType}"; // cerco in redis dato valore sel idxMaccSel... RedisValue rawData = redisDb.StringGet(currKey); if (rawData.HasValue && rawData.Length() > 2) @@ -1285,7 +1301,8 @@ namespace MP.SPEC.Data { Log.Debug("Errore CodArt vuoto"); } - return result; + return result; +#endif } /// @@ -1757,19 +1774,22 @@ namespace MP.SPEC.Data /// Effettua il task di eliminazione PODL KIT + istanze + riattivazione PODL originali disattivate tramite stored /// /// IdxPODL parent - public bool PodlIstKitDelete(int IdxPODL) + public async Task PodlIstKitDeleteAsync(int IdxPODL) { - using var activity = ActivitySource.StartActivity("PodlIstKitDelete"); + using var activity = ActivitySource.StartActivity("PodlIstKitDeleteAsync"); bool fatto = false; // salvo - fatto = dbController.PodlIstKitDelete(IdxPODL); + fatto = await dbController.PodlIstKitDeleteAsync(IdxPODL); // svuoto cache + await FlushCacheByTagsAsync(new List() { Utils.redisPOdlList }); +#if false string pattern = $"{Utils.redisKit}:*"; if (!string.IsNullOrEmpty(pattern)) { ExecFlushRedisPattern(pattern); - } - activity?.SetTag("data.source", "DB+REDIS"); + } +#endif + activity?.SetTag("data.source", "DB"); return fatto; } @@ -1778,8 +1798,18 @@ namespace MP.SPEC.Data ///
                                                /// IDX PODL parent /// - public List POdlListByKitParent(int IdxPodlParent) + public async Task> POdlListByKitParentAsync(int IdxPodlParent) { + string currKey = $"{Utils.redisPOdlList}_kit:ByParent:{IdxPodlParent}"; + return await GetOrFetchAsync( + operationName: "POdlListByKitParentAsync", + cacheKey: currKey, + expiration: getRandTOut(redisShortTimeCache), + fetchFunc: async () => await dbController.ListPODL_ByKitParentAsync(IdxPodlParent) ?? new(), + tagList: [Utils.redisPOdlList] + ); + +#if false using var activity = ActivitySource.StartActivity("POdlListByKitParent"); List? result = new List(); string source = "DB"; @@ -1793,7 +1823,7 @@ namespace MP.SPEC.Data } else { - result = dbController.ListPODL_ByKitParent(IdxPodlParent); + result = await dbController.ListPODL_ByKitParentAsync(IdxPodlParent); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); @@ -1806,7 +1836,8 @@ namespace MP.SPEC.Data activity?.SetTag("result.count", result.Count); activity?.Stop(); LogTrace($"POdlListByKitParent | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; + return result; +#endif } /// diff --git a/MP.SPEC/Pages/Podl2Kit.razor.cs b/MP.SPEC/Pages/Podl2Kit.razor.cs index ab58f170..47361bd6 100644 --- a/MP.SPEC/Pages/Podl2Kit.razor.cs +++ b/MP.SPEC/Pages/Podl2Kit.razor.cs @@ -294,7 +294,7 @@ namespace MP.SPEC.Pages get => doAddNew ? (isComposing ? "Completare o Resettare" : "Chiudi Composizione KIT") : "Composizione Nuovo KIT"; } - private SelectXdlParams currFilter { get; set; } = new SelectXdlParams(); + private SelectXdlParams currFilter { get; set; } = new SelectXdlParams() { NumRec = 5 }; private int currPage { diff --git a/Refactor_Plan.md b/Refactor_Plan.md index ed85dfe8..8120444a 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -19,7 +19,7 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa ### Fase 2: Refactoring Metodi di Lettura (Cache-aside) (In corso) -#### ✅ Metodi Migrati (Usano già `GetOrFetchAsync` o `FusionCache.GetOrSet`) +#### ✅ Metodi Migrati (Usano già `GetOrFetchAsync`, `FusionCache.GetOrSet` o `FlushCacheByTagAsync`) - `AnagEventiGeneralAsync` - `AnagStatiCommAsync` - `AnagTipoArtLvAsync` @@ -46,7 +46,7 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - `OdlListGetFiltAsync` - `OperatoriGetFiltAsync` - `ParametriGetFiltAsync` -- `PODL_getDictOdlPodlAsync` (Migrato con gestione manuale L1/L2) +- `PODL_getDictOdlPodlAsync` (Gestione manuale L1/L2 con FusionCache) - `POdlGetByOdlAsync` - `POdlToKitListGetFiltAsync` - `StatoMacchinaAsync` @@ -59,11 +59,16 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - `TemplateKitUpsertAsync` (Migrato con tag invalidazione) - `WipKitDeleteAsync` (Migrato con tag invalidazione) - `WipKitUpsertAsync` (Migrato con tag invalidazione) +- `AnagGruppiDeleteAsync` (Migrato con tag invalidazione) +- `AnagGruppiUpsertAsync` (Migrato con tag invalidazione) +- `Grp2MaccDeleteAsync` (Migrato con tag invalidazione) +- `Grp2MaccInsertAsync` (Migrato con tag invalidazione) +- `Grp2OperDeleteAsync` (Migrato con tag invalidazione) +- `Grp2OperInsertAsync` (Migrato con tag invalidazione) #### 🛠️ Metodi da Migrare (Usano ancora Redis/DB manuale) - [ ] Migrazione di `ActionGetReq` (linea 110: usa `redisDb.StringGetAsync`). - [ ] Migrazione di `ActionSetReq` (linea 136: usa `BroadastMsgPipe.saveAndSendMessage`). -- [ ] Migrazione di `AnagGruppiDelete`/`Upsert` (linea 189/208: usa `ExecFlushRedisPattern`). - [ ] Migrazione di `ArticoliDeleteRecord`/`UpdateRecord` (linea 296/372: usa `resetCacheArticoli`). - [ ] Migrazione di `DbDedupStats` (linea 516: usa `redisDb.StringGet`). - [ ] Migrazione di `DossiersDeleteRecord` (linea 554: usa `ExecFlushRedisPatternAsync`). @@ -88,3 +93,4 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa + From 18aa123672e2613588f95d7c34242852246c88b6 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Sat, 30 May 2026 10:09:00 +0200 Subject: [PATCH 075/102] Completato fix pagina gestione PODL-KIT x refresh --- MP.Data/Controllers/MpSpecController.cs | 2 +- MP.SPEC/Components/ProdKit/KitVerify.razor.cs | 7 +- MP.SPEC/Components/ProdKit/Manager.razor | 2 +- MP.SPEC/Data/MpDataService.cs | 118 +++--------------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 8 files changed, 27 insertions(+), 110 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index d6819e96..873afa7f 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -1312,7 +1312,7 @@ namespace MP.Data.Controllers var dbResult = await dbCtx .Database .ExecuteSqlRawAsync("EXEC dbo.stp_IstKit_insertByWKS @CodArtParent,@KeyFilt", pCodArtParent, pKeyFilt); - return dbResult > 0; + return dbResult != 0; } /// diff --git a/MP.SPEC/Components/ProdKit/KitVerify.razor.cs b/MP.SPEC/Components/ProdKit/KitVerify.razor.cs index 796755e4..aecb9913 100644 --- a/MP.SPEC/Components/ProdKit/KitVerify.razor.cs +++ b/MP.SPEC/Components/ProdKit/KitVerify.razor.cs @@ -100,11 +100,8 @@ namespace MP.SPEC.Components.ProdKit // eseguo stored... bool fatto = await MDService.IstKitInsertByWKSAsync(currRec.CodArtParent, KeyFilt); - if (fatto) - { - // segnalo update - await EC_KitCreated.InvokeAsync(true); - } + // segnalo update + await EC_KitCreated.InvokeAsync(fatto); } private void ReloadData() diff --git a/MP.SPEC/Components/ProdKit/Manager.razor b/MP.SPEC/Components/ProdKit/Manager.razor index 5f0f7405..98156c3c 100644 --- a/MP.SPEC/Components/ProdKit/Manager.razor +++ b/MP.SPEC/Components/ProdKit/Manager.razor @@ -16,7 +16,7 @@
                                              - +
                                              }
                                              diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 90f0a7a3..0cf62585 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -881,7 +881,7 @@ namespace MP.SPEC.Data /// Cancellazione FusionCache dato elenco tags /// /// - public async Task FlushCacheByTagsAsync(List listTags) + public async Task FlushCacheByTagAsync(List listTags) { if (listTags == null || listTags.Count == 0) return false; @@ -1152,9 +1152,8 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("IstKitDeleteAsync"); string source = "DB"; - bool fatto = false; // salvo - fatto = await dbController.IstKitDeleteAsync(currRecord); + bool fatto = await dbController.IstKitDeleteAsync(currRecord); // svuoto cache await FlushKitCache(); activity?.SetTag("data.source", source); @@ -1163,15 +1162,6 @@ namespace MP.SPEC.Data return fatto; } - private async Task FlushKitCache() - { -#if false - RedisValue pattern = $"{Utils.redisKitInst}:*"; - await ExecFlushRedisPatternAsync(pattern); -#endif - await FlushCacheByTagsAsync(new List() { Utils.redisPOdlList, Utils.redisKitInst, Utils.redisKitWip, Utils.redisKitScore, Utils.redisPOdlByCodArt }); - } - /// /// Elenco Istanze KIT da ricerca /// @@ -1197,11 +1187,10 @@ namespace MP.SPEC.Data /// Chiave x filtro conf su tab WKS public async Task IstKitInsertByWKSAsync(string CodArtParent, string KeyFilt) { - bool fatto = false; using var activity = ActivitySource.StartActivity("IstKitInsertByWKSAsync"); string source = "DB"; // salvo - fatto = await dbController.IstKitInsertByWKSAsync(CodArtParent, KeyFilt); + bool fatto = await dbController.IstKitInsertByWKSAsync(CodArtParent, KeyFilt); // svuoto cache await FlushKitCache(); activity?.SetTag("data.source", source); @@ -1218,9 +1207,8 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("IstKitUpsertAsync"); string source = "DB"; - bool fatto = false; // salvo - fatto = await dbController.IstKitUpsertAsync(currRecord); + bool fatto = await dbController.IstKitUpsertAsync(currRecord); // svuoto cache await FlushKitCache(); activity?.SetTag("data.source", source); @@ -1263,46 +1251,6 @@ namespace MP.SPEC.Data fetchFunc: async () => await dbController.ListPODL_ByCodArtAsync(CodArticolo, OnlyAvail) ?? new(), tagList: [Utils.redisPOdlByCodArt] ); - -#if false - List result = new List(); - if (!string.IsNullOrEmpty(CodArticolo)) - { - using var activity = ActivitySource.StartActivity("ListPODL_ByCodArt"); - string source = "DB"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue && rawData.Length() > 2) - { - var rawResult = JsonConvert.DeserializeObject>($"{rawData}"); - if (rawResult != null) - { - result = rawResult; - source = "REDIS"; - } - } - else - { - result = dbController.ListPODL_ByCodArt(CodArticolo, OnlyAvail); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - Log.Trace($"ListPODL_ByCodArt | {source} | {activity?.Duration.TotalMilliseconds}ms"); - } - else - { - Log.Debug("Errore CodArt vuoto"); - } - return result; -#endif } /// @@ -1541,7 +1489,6 @@ namespace MP.SPEC.Data return fatto; } - /// /// Elenco ODL filtrati x stato, articolo, KeyRich (che contiene stato) /// @@ -1781,14 +1728,7 @@ namespace MP.SPEC.Data // salvo fatto = await dbController.PodlIstKitDeleteAsync(IdxPODL); // svuoto cache - await FlushCacheByTagsAsync(new List() { Utils.redisPOdlList }); -#if false - string pattern = $"{Utils.redisKit}:*"; - if (!string.IsNullOrEmpty(pattern)) - { - ExecFlushRedisPattern(pattern); - } -#endif + await FlushCacheByTagAsync(new List() { Utils.redisPOdlList }); activity?.SetTag("data.source", "DB"); return fatto; } @@ -1809,35 +1749,6 @@ namespace MP.SPEC.Data tagList: [Utils.redisPOdlList] ); -#if false - using var activity = ActivitySource.StartActivity("POdlListByKitParent"); - List? result = new List(); - string source = "DB"; - string currKey = $"{Utils.redisPOdlList}_kit:ByParent:{IdxPodlParent}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.ListPODL_ByKitParentAsync(IdxPodlParent); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, TimeSpan.FromSeconds(redisShortTimeCache)); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", result.Count); - activity?.Stop(); - LogTrace($"POdlListByKitParent | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return result; -#endif } /// @@ -2394,10 +2305,15 @@ namespace MP.SPEC.Data private static readonly ActivitySource ActivitySource = new ActivitySource("MP.DATA.Tracer"); private static IConfiguration _configuration = null!; + private static Logger Log = LogManager.GetCurrentClassLogger(); + private readonly IFusionCache _cache; + private DateTime _artCacheExpiry = DateTime.MinValue; + private Dictionary _configData = new(); + private DateTime _dtParamExpiry = DateTime.Now; /// @@ -2457,7 +2373,6 @@ namespace MP.SPEC.Data #region Private Methods - /// /// Verifica caricamento dizionario ConfigData /// @@ -2474,6 +2389,11 @@ namespace MP.SPEC.Data } } + private async Task FlushKitCache() + { + await FlushCacheByTagAsync(new List() { Utils.redisPOdlList, Utils.redisKitInst, Utils.redisKitWip, Utils.redisKitScore, Utils.redisPOdlByCodArt }); + } + /// /// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria + tracking attività /// @@ -2596,7 +2516,7 @@ namespace MP.SPEC.Data await ExecFlushRedisPatternAsync(pattern); // elimino anche in FusionCache List tags2del = new List() { Utils.redisArtList, Utils.redisArtByDossier }; - await FlushCacheByTagsAsync(tags2del); + await FlushCacheByTagAsync(tags2del); activity?.SetTag("data.source", "REDIS"); } @@ -2604,7 +2524,7 @@ namespace MP.SPEC.Data { await redisDb.StringSetAsync(Utils.redisConfKey, ""); List tags2del = new List() { Utils.redisConfKey }; - await FlushCacheByTagsAsync(tags2del); + await FlushCacheByTagAsync(tags2del); } /// @@ -2612,7 +2532,7 @@ namespace MP.SPEC.Data /// private async Task ResetMacGrpCache() { - await FlushCacheByTagsAsync(new List { Utils.redisAnagGruppi, Utils.redisMacList }); + await FlushCacheByTagAsync(new List { Utils.redisAnagGruppi, Utils.redisMacList }); } /// @@ -2622,7 +2542,7 @@ namespace MP.SPEC.Data { //ExecFlushRedisPattern($"{Utils.redisAnagGruppi}:*"); //ExecFlushRedisPattern($"{Utils.redisOprList}:*"); - await FlushCacheByTagsAsync(new List { Utils.redisAnagGruppi, Utils.redisOprList }); + await FlushCacheByTagAsync(new List { Utils.redisAnagGruppi, Utils.redisOprList }); } #endregion Private Methods diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index b0dddc59..982527dc 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.3009 + 8.16.2605.3010 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 67011e00..af4e92ba 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                              Versione: 8.16.2605.3009

                                              +

                                              Versione: 8.16.2605.3010


                                              Note di rilascio:
                                              • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 77349332..fac721dd 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.3009 +8.16.2605.3010 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 8818602e..aefa43a4 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.3009 + 8.16.2605.3010 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From e65822ceb566f11fec3821e93662d3f9e4de7f7a Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Sat, 30 May 2026 10:20:17 +0200 Subject: [PATCH 076/102] Fix delete dossier sistemato... --- MP.Data/Controllers/MpSpecController.cs | 29 ++++++++---------------- MP.SPEC/Components/ListDossiers.razor | 2 +- MP.SPEC/Components/ListDossiers.razor.cs | 7 +++--- MP.SPEC/Data/MpDataService.cs | 15 ++++++------ 4 files changed, 21 insertions(+), 32 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 873afa7f..83a95c6c 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -735,29 +735,18 @@ namespace MP.Data.Controllers ///
                                              /// record dossier da eliminare /// - public async Task DossiersDeleteRecord(DossierModel currRec) + public async Task DossiersDeleteRecordAsync(DossierModel currRec) { - bool answ = false; - using (var dbCtx = new MoonPro_FluxContext(_configuration)) - { - try - { - var currVal = dbCtx + using var dbCtx = new MoonPro_FluxContext(_configuration); + var currVal = await dbCtx .DbSetDossiers .Where(x => x.IdxDossier == currRec.IdxDossier) - .FirstOrDefault(); - dbCtx - .DbSetDossiers - .Remove(currVal); - await dbCtx.SaveChangesAsync(); - answ = true; - } - catch (Exception exc) - { - Log.Error($"Eccezione durante DossiersDeleteRecord{Environment.NewLine}{exc}"); - } - } - return answ; + .FirstOrDefaultAsync(); + dbCtx + .DbSetDossiers + .Remove(currVal); + + return await dbCtx.SaveChangesAsync() > 0; } /// diff --git a/MP.SPEC/Components/ListDossiers.razor b/MP.SPEC/Components/ListDossiers.razor index a497db87..ee07e0f6 100644 --- a/MP.SPEC/Components/ListDossiers.razor +++ b/MP.SPEC/Components/ListDossiers.razor @@ -261,7 +261,7 @@ else @if (isEditing == false) { - + } else { diff --git a/MP.SPEC/Components/ListDossiers.razor.cs b/MP.SPEC/Components/ListDossiers.razor.cs index 31d1b9b3..4ec778d3 100644 --- a/MP.SPEC/Components/ListDossiers.razor.cs +++ b/MP.SPEC/Components/ListDossiers.razor.cs @@ -146,16 +146,15 @@ namespace MP.SPEC.Components /// /// /// - protected async Task deleteRecord(DossierModel selRec) + protected async Task DoDelete(DossierModel selRec) { if (!await JSRuntime.InvokeAsync("confirm", "Eliminazione Dossier: sei sicuro di voler procedere?")) return; - await Task.Delay(1); - var done = await MDService.DossiersDeleteRecord(selRec); + + var done = await MDService.DossiersDeleteRecordAsync(selRec); currRecord = null; await ReloadData(true); visualizzaFlux = true; - await Task.Delay(1); } protected async Task editRecord(FluxLogDTO selRec) diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 0cf62585..d5b0051d 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -548,17 +548,18 @@ namespace MP.SPEC.Data ///
                                              /// record dossier da eliminare /// - public async Task DossiersDeleteRecord(DossierModel selRecord) + public async Task DossiersDeleteRecordAsync(DossierModel selRecord) { - using var activity = ActivitySource.StartActivity("DossiersDeleteRecord"); + using var activity = ActivitySource.StartActivity("DossiersDeleteRecordAsync"); bool result = false; - result = await dbController.DossiersDeleteRecord(selRecord); + result = await dbController.DossiersDeleteRecordAsync(selRecord); // elimino cache redis... - RedisValue pattern = new RedisValue($"{Utils.redisDossByMac}:*"); - bool answ = await ExecFlushRedisPatternAsync(pattern); - activity?.SetTag("data.source", "DB+REDIS"); + //RedisValue pattern = new RedisValue($"{Utils.redisDossByMac}:*"); + //bool answ = await ExecFlushRedisPatternAsync(pattern); + await FlushCacheByTagAsync(Utils.redisDossByMac); + activity?.SetTag("data.source", "DB"); activity?.Stop(); - LogTrace($"DossiersDeleteRecord | IdxMacchina {selRecord.IdxMacchina} | DtRif {selRecord.DtRif} | IdxODL {selRecord.IdxODL} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"DossiersDeleteRecordAsync | IdxMacchina {selRecord.IdxMacchina} | DtRif {selRecord.DtRif} | IdxODL {selRecord.IdxODL} | {activity?.Duration.TotalMilliseconds}ms"); return result; } From 2f4cead6e105770477964486d1c15d163fbcb896 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Sat, 30 May 2026 12:02:18 +0200 Subject: [PATCH 077/102] Continuo code cleanup metodi STATS --- MP.Core/Utils.cs | 1 + MP.Data/Controllers/MpSpecController.cs | 451 +++++++---------- MP.Data/Controllers/MpTabController.cs | 4 +- MP.Data/Services/TabDataService.cs | 2 +- MP.SPEC/Components/AskCloseOdl.razor.cs | 2 +- MP.SPEC/Components/ListDossiers.razor.cs | 6 +- MP.SPEC/Components/ListODL.razor.cs | 4 +- MP.SPEC/Components/ODLPlot.razor.cs | 2 +- MP.SPEC/Components/ScratchPodlKit.razor.cs | 4 +- MP.SPEC/Data/MpDataService.cs | 543 ++++++++++----------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/FluxLogStatus.razor.cs | 10 +- MP.SPEC/Pages/KIT.razor.cs | 2 +- MP.SPEC/Pages/Podl2Kit.razor.cs | 4 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- Refactor_Plan.md | 16 +- 18 files changed, 484 insertions(+), 575 deletions(-) diff --git a/MP.Core/Utils.cs b/MP.Core/Utils.cs index 5be06dbe..b138599a 100644 --- a/MP.Core/Utils.cs +++ b/MP.Core/Utils.cs @@ -49,6 +49,7 @@ namespace MP.Core public const string redisOdlLastByMac = redisXdlData + "LastOdlByMac"; public const string redisOdlList = redisXdlData + "OdlList"; + public const string redisOdlStats = redisXdlData + "OdlStats"; public const string redisOprList = redisBaseAddr + "Cache:OprList"; diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 83a95c6c..d536a4ee 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -54,63 +54,57 @@ namespace MP.Data.Controllers /// Stacca un nuovo counter x il tipo richiesto ///
                                              /// - public AnagCountersModel AnagCountersGetNext(string cntType) + public async Task AnagCountersGetNextAsync(string cntType) { AnagCountersModel answ = new AnagCountersModel(); + using var dbCtx = new MoonProContext(options); bool outTable = true; if (outTable) { - using (var dbCtx = new MoonProContext(options)) + var pCntType = new SqlParameter("@CntType", cntType); + var pLastNum = new SqlParameter { - var pCntType = new SqlParameter("@CntType", cntType); - var pLastNum = new SqlParameter - { - ParameterName = "@LastNum", - SqlDbType = SqlDbType.Int, - Direction = ParameterDirection.Output - }; + ParameterName = "@LastNum", + SqlDbType = SqlDbType.Int, + Direction = ParameterDirection.Output + }; - var dbResult = dbCtx + var dbResult = await dbCtx .DbSetAnagCount .FromSqlRaw("EXEC dbo.stp_getNextNumb @CntType, @LastNum OUTPUT", pCntType, pLastNum) .AsNoTracking() - .AsEnumerable() - .FirstOrDefault(); - if (dbResult != null) - { - answ = dbResult; - } + .FirstOrDefaultAsync(); + if (dbResult != null) + { + answ = dbResult; } } else { // se si volessero impiegare parametri OUTPUT (qui ne mancherebbe 1 nella stored x CntCode...) - using (var dbCtx = new MoonProContext(options)) + var pCntType = new SqlParameter("@CntType", cntType); + var pLastNum = new SqlParameter { - var pCntType = new SqlParameter("@CntType", cntType); - var pLastNum = new SqlParameter - { - ParameterName = "@LastNum", - SqlDbType = SqlDbType.Int, - Direction = ParameterDirection.Output - }; - var pCntCode = new SqlParameter - { - ParameterName = "@CntCode", - SqlDbType = SqlDbType.NVarChar, - Direction = ParameterDirection.Output - }; - var dbResult = dbCtx - .Database - .ExecuteSqlRaw("EXEC dbo.stp_getNextNumb @CntType, @LastNum OUTPUT, @CntCode OUTPUT", pCntType, pLastNum, pCntCode); - if (dbResult != 0) - { - answ.CntType = cntType; - answ.CntCode = $"{pCntCode.Value}"; - int lNum = 0; - int.TryParse($"{pLastNum.Value}", out lNum); - answ.LastNum = lNum; - } + ParameterName = "@LastNum", + SqlDbType = SqlDbType.Int, + Direction = ParameterDirection.Output + }; + var pCntCode = new SqlParameter + { + ParameterName = "@CntCode", + SqlDbType = SqlDbType.NVarChar, + Direction = ParameterDirection.Output + }; + var dbResult = await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC dbo.stp_getNextNumb @CntType, @LastNum OUTPUT, @CntCode OUTPUT", pCntType, pLastNum, pCntCode); + if (dbResult != 0) + { + answ.CntType = cntType; + answ.CntCode = $"{pCntCode.Value}"; + int lNum = 0; + int.TryParse($"{pLastNum.Value}", out lNum); + answ.LastNum = lNum; } } return answ; @@ -782,25 +776,13 @@ namespace MP.Data.Controllers ///
                                              /// record dossier da modificare /// - public async Task DossiersInsert(DossierModel newRec) + public async Task DossiersInsertAsync(DossierModel newRec) { - bool fatto = false; - using (var dbCtx = new MoonPro_FluxContext(_configuration)) - { - try - { - dbCtx - .DbSetDossiers - .Add(newRec); - await dbCtx.SaveChangesAsync(); - fatto = true; - } - catch (Exception exc) - { - Log.Error($"Eccezione durante DossiersInsert{Environment.NewLine}{exc}"); - } - } - return fatto; + using var dbCtx = new MoonPro_FluxContext(_configuration); + dbCtx + .DbSetDossiers + .AddAsync(newRec); + return await dbCtx.SaveChangesAsync() > 0; } /// @@ -832,21 +814,17 @@ namespace MP.Data.Controllers /// macchina /// Data min x selezione /// Data MAX x selezione - public bool DossiersTakeParamsSnapshotLast(string idxMacchina, DateTime dtMin, DateTime dtMax) + public async Task DossiersTakeParamsSnapshotLastAsync(string idxMacchina, DateTime dtMin, DateTime dtMax) { - bool answ = false; - using (var dbCtx = new MoonPro_FluxContext(_configuration)) - { - var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); - var pDtMin = new SqlParameter("@DtMin", dtMin); - var pDtMax = new SqlParameter("@DtMax", dtMax); + using var dbCtx = new MoonPro_FluxContext(_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; + var dbResult = await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC stp_FL_TakeSnapshotLast @IdxMacchina,@DtMin,@DtMax", pIdxMacchina, pDtMin, pDtMax); + return dbResult != 0; } /// @@ -854,37 +832,25 @@ namespace MP.Data.Controllers /// /// record dossier da modificare /// - public async Task DossiersUpdateValore(DossierModel editRec) + public async Task DossiersUpdateValoreAsync(DossierModel editRec) { - bool fatto = false; - using (var dbCtx = new MoonPro_FluxContext(_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 + using var dbCtx = new MoonPro_FluxContext(_configuration); + var currRec = await dbCtx .DbSetDossiers - .Add(editRec); - } - await dbCtx.SaveChangesAsync(); - fatto = true; - } - catch (Exception exc) - { - Log.Error($"Eccezione durante DossiersUpdateRecord{Environment.NewLine}{exc}"); - } + .Where(x => x.IdxDossier == editRec.IdxDossier) + .FirstOrDefaultAsync(); + if (currRec != null) + { + currRec.Valore = editRec.Valore; + dbCtx.Entry(currRec).State = EntityState.Modified; } - return fatto; + else + { + await dbCtx + .DbSetDossiers + .AddAsync(editRec); + } + return await dbCtx.SaveChangesAsync() > 0; } /// @@ -920,25 +886,14 @@ namespace MP.Data.Controllers /// /// /// - public async Task EvListInsert(EventListModel newRec) + public async Task EvListInsertAsync(EventListModel newRec) { - bool fatto = false; - using (var dbCtx = new MoonProContext(options)) - { - 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; + using var dbCtx = new MoonProContext(options); + var currRec = await dbCtx + .DbSetEvList + .AddAsync(newRec); + + return await dbCtx.SaveChangesAsync() > 0; } /// @@ -952,10 +907,10 @@ namespace MP.Data.Controllers /// /// Restitusice list dei record statistiche raccolti (da integrare a quelli rpesenti in Redis...) /// - public async Task> FluxLogDataRedux(string idxMaccSel, List fluxList, Periodo currPeriodo, Enums.ValSelection valMode, Enums.DataInterval intReq, int maxItem) + public async Task> FluxLogDataReduxAsync(string idxMaccSel, List fluxList, Periodo currPeriodo, Enums.ValSelection valMode, Enums.DataInterval intReq, int maxItem) { List procStats = new List(); - Log.Info($"Inizio FluxLogDataRedux | idxMaccSel: {idxMaccSel} | periodo: {currPeriodo.Inizio:yyyy-MM-dd} --> {currPeriodo.Fine:yyyy-MM-dd}"); + Log.Info($"Inizio FluxLogDataReduxAsync | idxMaccSel: {idxMaccSel} | periodo: {currPeriodo.Inizio:yyyy-MM-dd} --> {currPeriodo.Fine:yyyy-MM-dd}"); TimeSpan step = TimeSpan.FromHours(1); switch (intReq) { @@ -982,7 +937,7 @@ namespace MP.Data.Controllers // processo 1:1 ogni flusso foreach (var item in fluxList) { - Log.Info($"FluxLogDataRedux | Flux: {item}"); + Log.Info($"FluxLogDataReduxAsync | Flux: {item}"); int numRecProc = 0; Stopwatch sw = new Stopwatch(); sw.Start(); @@ -1058,9 +1013,9 @@ namespace MP.Data.Controllers // parametri x periodo (base) var pDtStart = new SqlParameter("@DtStart", slot.Inizio); var pDtEnd = new SqlParameter("@DtEnd", slot.Fine); - var dbResult = dbCtx - .Database - .ExecuteSqlRaw("EXEC man.stp_ReduceFluxLog @IdxMacchina, @CodFlux, @DtStart, @DtEnd, @OnlyTest", pIdxMacchina, pCodFlux, pDtStart, pDtEnd, pOnlyTest); + var dbResult = await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC man.stp_ReduceFluxLog @IdxMacchina, @CodFlux, @DtStart, @DtEnd, @OnlyTest", pIdxMacchina, pCodFlux, pDtStart, pDtEnd, pOnlyTest); } } @@ -1083,7 +1038,7 @@ namespace MP.Data.Controllers }; procStats.Add(currStat); } - Log.Info($"FINE FluxLogDataRedux | idxMaccSel: {idxMaccSel} | periodo: {currPeriodo.Inizio:yyyy-MM-dd} --> {currPeriodo.Fine:yyyy-MM-dd}"); + Log.Info($"FINE FluxLogDataReduxAsync | idxMaccSel: {idxMaccSel} | periodo: {currPeriodo.Inizio:yyyy-MM-dd} --> {currPeriodo.Fine:yyyy-MM-dd}"); return procStats; } @@ -1914,73 +1869,63 @@ namespace MP.Data.Controllers /// Conferma con rettifica (ev 121) x pezzi lasciati in macchina /// Modo conferma produzione (0=periodo, 1=giorno, 2=turno) /// - public async Task ODLClose(int idxOdl, string idxMacchina, int matrOpr, bool confPezzi, bool confRett, int modoConfProd) + public async Task ODLCloseAsync(int idxOdl, string idxMacchina, int matrOpr, bool confPezzi, bool confRett, int modoConfProd) { bool fatto = false; - await Task.Delay(1); if (idxOdl > 0) { - using (var dbCtx = new MoonProContext(options)) + using var dbCtx = new MoonProContext(options); + DateTime adesso = DateTime.Now; + // preparo i parametri + var IdxODL = new SqlParameter("@IdxODL", idxOdl); + var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); + + + // se richiesto confermo produzione + if (confPezzi) { - DateTime adesso = DateTime.Now; - // preparo i parametri - var IdxODL = new SqlParameter("@IdxODL", idxOdl); - var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); + var MatrApp = new SqlParameter("@MatrApp", 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 + /* ---------------------------------- + * 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 + * + * + * + * */ - // se richiesto confermo produzione - if (confPezzi) - { - var MatrApp = new SqlParameter("@MatrApp", idxMacchina); + // recupero i dati dei pezzi da confermare... con DbSetPzProd + exec + // stp_PzProd_getByMacchina 'SIMUL_01' - /* ---------------------------------- - * 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 - * - * - * - * */ + // 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 ) + */ + } - // 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 con stored SENZA ritorno... - try - { - var dbResult = dbCtx - .Database - .ExecuteSqlRaw("EXEC stp_ODL_fineProd @IdxODL, @IdxMacchina", IdxODL, IdxMacchina); - fatto = true; - } - catch (Exception exc) - { - Log.Error($"Eccezione durante ODLClose{Environment.NewLine}{exc}"); - } + // ora chiudo ODL con stored SENZA ritorno... + try + { + var dbResult = await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC stp_ODL_fineProd @IdxODL, @IdxMacchina", IdxODL, IdxMacchina); + fatto = dbResult != 0; + } + catch (Exception exc) + { + Log.Error($"Eccezione durante ODLCloseAsync{Environment.NewLine}{exc}"); } } return fatto; @@ -2003,6 +1948,7 @@ namespace MP.Data.Controllers return dbResult; } +#if false /// /// Elenco TUTTI GLI ODL /// @@ -2025,27 +1971,26 @@ namespace MP.Data.Controllers } } return dbResult; - } + } +#endif /// /// Statistiche ODL calcolate (da stored stp_STAT_ODL) /// /// - public async Task> OdlStart(int IdxOdl) + public async Task> OdlGetStatAsync(int IdxOdl) { List dbResult = new List(); if (IdxOdl > 0) { - using (var dbCtx = new MoonProContext(options)) - { - var IdxODL = new SqlParameter("@IdxODL", IdxOdl); + using var dbCtx = new MoonProContext(options); + var IdxODL = new SqlParameter("@IdxODL", IdxOdl); - dbResult = await dbCtx - .DbSetStatOdl - .FromSqlRaw("EXEC stp_STAT_ODL @IdxODL", IdxODL) - .AsNoTracking() - .ToListAsync(); - } + dbResult = await dbCtx + .DbSetStatOdl + .FromSqlRaw("EXEC stp_STAT_ODL @IdxODL", IdxODL) + .AsNoTracking() + .ToListAsync(); } return dbResult; } @@ -2128,27 +2073,15 @@ namespace MP.Data.Controllers /// /// /// - public async Task PODL_getByKey(int idxPODL) + public async Task PODL_getByKeyAsync(int idxPODL) { - PODLModel dbResult = new PODLModel(); - using (var dbCtx = new MoonProContext(options)) - { - try - { - dbResult = dbCtx - .DbSetPODL - .AsNoTracking() - .Where(x => x.IdxPromessa == idxPODL) - .Include(a => a.ArticoloNav) - .FirstOrDefault(); - } - catch (Exception exc) - { - Log.Error($"Eccezione durante PODL_getByKey{Environment.NewLine}{exc}"); - } - } - await Task.Delay(1); - return dbResult; + using var dbCtx = new MoonProContext(options); + return await dbCtx + .DbSetPODL + .AsNoTracking() + .Where(x => x.IdxPromessa == idxPODL) + .Include(a => a.ArticoloNav) + .FirstOrDefaultAsync() ?? new(); } /// @@ -2355,45 +2288,34 @@ namespace MP.Data.Controllers /// /// /// - public async Task PODLUpdateRecord(PODLModel editRec) + public async Task PODLUpdateRecordAsync(PODLModel editRec) { - bool fatto = false; - using (var dbCtx = new MoonProContext(options)) - { - try - { - var currRec = dbCtx - .DbSetPODL - .Where(x => x.IdxPromessa == editRec.IdxPromessa) - .FirstOrDefault(); - if (currRec != null) - { - currRec.CodGruppo = editRec.CodGruppo; - currRec.CodArticolo = editRec.CodArticolo; - currRec.IdxMacchina = editRec.IdxMacchina; - currRec.KeyBCode = editRec.KeyBCode; - 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 - { - dbCtx + using var dbCtx = new MoonProContext(options); + var currRec = await dbCtx .DbSetPODL - .Add(editRec); - } - await dbCtx.SaveChangesAsync(); - fatto = true; - } - catch (Exception exc) - { - Log.Error($"Eccezione durante PODLUpdateRecord{Environment.NewLine}{exc}"); - } + .Where(x => x.IdxPromessa == editRec.IdxPromessa) + .FirstOrDefaultAsync(); + if (currRec != null) + { + currRec.CodGruppo = editRec.CodGruppo; + currRec.CodArticolo = editRec.CodArticolo; + currRec.IdxMacchina = editRec.IdxMacchina; + currRec.KeyBCode = editRec.KeyBCode; + 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; } - return fatto; + else + { + await dbCtx + .DbSetPODL + .AddAsync(editRec); + } + return await dbCtx.SaveChangesAsync() > 0; + } /// @@ -2440,26 +2362,21 @@ namespace MP.Data.Controllers /// Elimina record /// /// - public bool TemplateKitDelete(TemplateKitModel rec2del) + public async Task TemplateKitDeleteAsync(TemplateKitModel rec2del) { - bool fatto = false; - using (var dbCtx = new MoonProContext(options)) + using var dbCtx = new MoonProContext(options); + var actRec = await dbCtx + .DbSetTempKit + .Where(x => x.CodArtParent == rec2del.CodArtParent && x.CodArtChild == rec2del.CodArtChild) + .FirstOrDefaultAsync(); + // se ci fosse aggiorno... + if (actRec != null) { - var actRec = dbCtx - .DbSetTempKit - .Where(x => x.CodArtParent == rec2del.CodArtParent && x.CodArtChild == rec2del.CodArtChild) - .FirstOrDefault(); - // se ci fosse aggiorno... - if (actRec != null) - { - dbCtx - .DbSetTempKit - .Remove(actRec); - } - var res = dbCtx.SaveChanges(); - fatto = res != 0; + dbCtx + .DbSetTempKit + .Remove(actRec); } - return fatto; + return await dbCtx.SaveChangesAsync() > 0; } /// diff --git a/MP.Data/Controllers/MpTabController.cs b/MP.Data/Controllers/MpTabController.cs index 55981185..1a5c469b 100644 --- a/MP.Data/Controllers/MpTabController.cs +++ b/MP.Data/Controllers/MpTabController.cs @@ -688,7 +688,7 @@ namespace MP.Data.Controllers } catch (Exception exc) { - Log.Error($"Eccezione durante EvListInsert{Environment.NewLine}{exc}"); + Log.Error($"Eccezione durante EvListInsertAsync{Environment.NewLine}{exc}"); } } await Task.Delay(1); @@ -1709,7 +1709,7 @@ namespace MP.Data.Controllers } catch (Exception exc) { - Log.Error($"Eccezione durante PODL_getByKey{Environment.NewLine}{exc}"); + Log.Error($"Eccezione durante PODL_getByKeyAsync{Environment.NewLine}{exc}"); } } return dbResult; diff --git a/MP.Data/Services/TabDataService.cs b/MP.Data/Services/TabDataService.cs index 2b6f631d..b1771ed1 100644 --- a/MP.Data/Services/TabDataService.cs +++ b/MP.Data/Services/TabDataService.cs @@ -2412,7 +2412,7 @@ namespace MP.Data.Services #if false Log.Debug($"PODL_getByKey | {idxPODL} | {source} | {sw.Elapsed.TotalMilliseconds}ms"); #endif - string callName = $"PODL_getByKey.{source}"; + string callName = $"PODL_getByKeyAsync.{source}"; int numRec = esCollect.RecordCall(callName, sw.Elapsed.TotalMilliseconds); if (numRec >= nRecLog) { diff --git a/MP.SPEC/Components/AskCloseOdl.razor.cs b/MP.SPEC/Components/AskCloseOdl.razor.cs index d82ff0ea..1defeafe 100644 --- a/MP.SPEC/Components/AskCloseOdl.razor.cs +++ b/MP.SPEC/Components/AskCloseOdl.razor.cs @@ -81,7 +81,7 @@ namespace MP.SPEC.Components if (currOdl != null && currOdl.IdxOdl == idxOdl) { // effettua chiusura sul DB - fatto = await MDService.ODLClose(idxOdl, currOdl.IdxMacchina, 0, true); + fatto = await MDService.ODLCloseAsync(idxOdl, currOdl.IdxMacchina, 0, true); if (fatto) { Log.Info($"Effettuata chiusura ODL {idxOdl}"); diff --git a/MP.SPEC/Components/ListDossiers.razor.cs b/MP.SPEC/Components/ListDossiers.razor.cs index 4ec778d3..d2ea0aa0 100644 --- a/MP.SPEC/Components/ListDossiers.razor.cs +++ b/MP.SPEC/Components/ListDossiers.razor.cs @@ -105,7 +105,7 @@ namespace MP.SPEC.Components await Task.Delay(1); if (currRecord != null) { - listaFlux = MDService.FluxLogDtoGetByFlux(currRecord.Valore); + listaFlux = MDService.FluxLogDtoConvert(currRecord.Valore); } StateHasChanged(); } @@ -254,7 +254,7 @@ namespace MP.SPEC.Components { currRecord = selRec; await RecordSel.InvokeAsync(selRec); - listaFlux = MDService.FluxLogDtoGetByFlux(selRec.Valore); + listaFlux = MDService.FluxLogDtoConvert(selRec.Valore); await toggleTableFlux(); } @@ -271,7 +271,7 @@ namespace MP.SPEC.Components string newVal = JsonConvert.SerializeObject(updatedResult); currRecord.Valore = newVal; // METODO PER UPDATE FLUX - await MDService.DossiersUpdateValore(currRecord); + await MDService.DossiersUpdateValoreAsync(currRecord); currFluxLogDto = null; isEditing = false; await InvokeAsync(StateHasChanged); diff --git a/MP.SPEC/Components/ListODL.razor.cs b/MP.SPEC/Components/ListODL.razor.cs index 9d100587..42f4107d 100644 --- a/MP.SPEC/Components/ListODL.razor.cs +++ b/MP.SPEC/Components/ListODL.razor.cs @@ -109,7 +109,7 @@ namespace MP.SPEC.Components if (currRecord != null) { // effettua chiusura sul DB - await MDService.ODLClose(currRecord.IdxOdl, currRecord.IdxMacchina, 0, true); + await MDService.ODLCloseAsync(currRecord.IdxOdl, currRecord.IdxMacchina, 0, true); Log.Info($"Effettuata chiusura ODL {currRecord.IdxOdl}"); // RESETTO task x setComm, setArt, SetPzComm @@ -426,7 +426,7 @@ namespace MP.SPEC.Components showStats = true; if (currRec != null) { - ListOdlStats = await MDService.StatOdl(currRec.IdxOdl); + ListOdlStats = await MDService.OdlStatsAsync(currRec.IdxOdl); } else { diff --git a/MP.SPEC/Components/ODLPlot.razor.cs b/MP.SPEC/Components/ODLPlot.razor.cs index 9e51d6e7..6a2fbafc 100644 --- a/MP.SPEC/Components/ODLPlot.razor.cs +++ b/MP.SPEC/Components/ODLPlot.razor.cs @@ -64,7 +64,7 @@ namespace MP.SPEC.Components Data.Clear(); Labels.Clear(); colors.Clear(); - ListRecords = await MDService.StatOdl(SelectedOdl); + ListRecords = await MDService.OdlStatsAsync(SelectedOdl); // se hideSpenta --> filtro stato 11 = spenta... if (hideSpenta) { diff --git a/MP.SPEC/Components/ScratchPodlKit.razor.cs b/MP.SPEC/Components/ScratchPodlKit.razor.cs index 9f29a46f..d4cb17ef 100644 --- a/MP.SPEC/Components/ScratchPodlKit.razor.cs +++ b/MP.SPEC/Components/ScratchPodlKit.razor.cs @@ -109,7 +109,7 @@ namespace MP.SPEC.Components if (!await JSRuntime.InvokeAsync("confirm", "Eliminazione riga Istanza KIT: sei sicuro di voler procedere?")) return; - var done = await MDService.IstKitDelete(selRec); + var done = await MDService.IstKitDeleteAsync(selRec); EditRecord = null; await ResetDataAsync(); } @@ -119,7 +119,7 @@ namespace MP.SPEC.Components if (!await JSRuntime.InvokeAsync("confirm", "Confermi di voler salvare le modifiche?")) return; - var done = await MDService.IstKitUpsert(selRec); + var done = await MDService.IstKitUpsertAsync(selRec); EditRecord = null; await ResetDataAsync(); } diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index d5b0051d..1aa19dcd 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -124,7 +124,7 @@ namespace MP.SPEC.Data } activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ActionGetReq Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ActionGetReq | {source} | {activity?.Duration.TotalMilliseconds}ms"); return result; } @@ -152,15 +152,15 @@ namespace MP.SPEC.Data /// Stacca un nuovo counter x il tipo richiesto /// /// - public AnagCountersModel AnagCountersGetNext(string cntType) + public async Task AnagCountersGetNextAsync(string cntType) { - using var activity = ActivitySource.StartActivity("AnagCountersGetNext"); + using var activity = ActivitySource.StartActivity("AnagCountersGetNextAsync"); AnagCountersModel result = new AnagCountersModel(); string source = "DB"; - result = dbController.AnagCountersGetNext(cntType); + result = await dbController.AnagCountersGetNextAsync(cntType); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"AnagCountersGetNext | {source} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"AnagCountersGetNextAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); return result; } @@ -190,12 +190,13 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("AnagGruppiDeleteAsync"); bool result = false; + string source = "DB"; result = dbController.AnagGruppiDelete(updRec); // elimino cache redis... - await FlushCacheByTagAsync(Utils.redisAnagGruppi); - activity?.SetTag("data.source", "DB"); + await FlushCacheAsync(Utils.redisAnagGruppi); + activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"AnagGruppiDeleteAsync | CodGruppo {updRec.CodGruppo} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"AnagGruppiDeleteAsync | CodGruppo {updRec.CodGruppo} | {source}{activity?.Duration.TotalMilliseconds}ms"); return result; } @@ -208,12 +209,13 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("AnagGruppiUpsertAsync"); bool result = false; + string source = "DB"; result = dbController.AnagGruppiUpsert(UpdRec); // elimino cache redis... - await FlushCacheByTagAsync(Utils.redisAnagGruppi); - activity?.SetTag("data.source", "DB"); + await FlushCacheAsync(Utils.redisAnagGruppi); + activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"AnagGruppiUpsertAsync | CodGruppo {UpdRec.CodGruppo} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"AnagGruppiUpsertAsync | CodGruppo {UpdRec.CodGruppo} | {source} | {activity?.Duration.TotalMilliseconds}ms"); return result; } @@ -294,12 +296,12 @@ namespace MP.SPEC.Data public async Task ArticoliDeleteRecord(AnagArticoliModel currRec) { using var activity = ActivitySource.StartActivity("ArticoliDeleteRecord"); - string source = "DB+REDIS"; + string source = "DB"; bool fatto = await dbController.ArticoliDeleteRecord(currRec); - await resetCacheArticoli(); + await FlushCacheArticoli(); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ArticoliDeleteRecord | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ArticoliDeleteRecord | {source} | {activity?.Duration.TotalMilliseconds}ms"); return fatto; } @@ -370,12 +372,12 @@ namespace MP.SPEC.Data public async Task ArticoliUpdateRecord(AnagArticoliModel currRec) { using var activity = ActivitySource.StartActivity("ArticoliUpdateRecord"); - string source = "DB+REDIS"; + string source = "DB"; bool fatto = await dbController.ArticoliUpdateRecord(currRec); - await resetCacheArticoli(); + await FlushCacheArticoli(); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ArticoliUpdateRecord | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ArticoliUpdateRecord | {source} | {activity?.Duration.TotalMilliseconds}ms"); return fatto; } @@ -462,10 +464,10 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("ConfigResetCacheAsync"); string source = "REDIS"; - await ResetConfigCache(); + await FlushCacheConfig(); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ConfigResetCacheAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ConfigResetCacheAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); } /// @@ -500,7 +502,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("ConfigUpdateAsync"); string source = "DB"; var updRes = await dbController.ConfigUpdateAsync(updRec); - await ResetConfigCache(); + await FlushCacheConfig(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"ConfigUpdateAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -511,9 +513,9 @@ namespace MP.SPEC.Data /// Restituisce le statistiche di DB maintenance eseguite /// /// - public Dictionary DbDedupStats() + public async Task> DbDedupStatsAsync() { - using var activity = ActivitySource.StartActivity("DbDedupStats"); + using var activity = ActivitySource.StartActivity("DbDedupStatsAsync"); string source = "REDIS"; Dictionary actStats = new Dictionary(); string currKey = $"{Utils.redisStatsDbMaint}"; @@ -529,7 +531,7 @@ namespace MP.SPEC.Data } activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"DbDedupStats Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"DbDedupStatsAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return actStats; } @@ -553,10 +555,8 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("DossiersDeleteRecordAsync"); bool result = false; result = await dbController.DossiersDeleteRecordAsync(selRecord); - // elimino cache redis... - //RedisValue pattern = new RedisValue($"{Utils.redisDossByMac}:*"); - //bool answ = await ExecFlushRedisPatternAsync(pattern); - await FlushCacheByTagAsync(Utils.redisDossByMac); + // elimino cache... + await FlushCacheAsync(Utils.redisDossByMac); activity?.SetTag("data.source", "DB"); activity?.Stop(); LogTrace($"DossiersDeleteRecordAsync | IdxMacchina {selRecord.IdxMacchina} | DtRif {selRecord.DtRif} | IdxODL {selRecord.IdxODL} | {activity?.Duration.TotalMilliseconds}ms"); @@ -591,13 +591,14 @@ namespace MP.SPEC.Data /// public async Task DossiersInsert(DossierModel currDoss) { - using var activity = ActivitySource.StartActivity("DossiersInsert"); + using var activity = ActivitySource.StartActivity("DossiersInsertAsync"); string source = "DB"; // aggiorno record sul DB - bool answ = await dbController.DossiersInsert(currDoss); + bool answ = await dbController.DossiersInsertAsync(currDoss); + answ = await FlushCacheAsync(Utils.redisDossByMac); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"DossiersInsert | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"DossiersInsertAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); return answ; } @@ -610,18 +611,17 @@ namespace MP.SPEC.Data /// public async Task DossiersTakeParamsSnapshotLast(string IdxMacchina, DateTime dtMin, DateTime dtMax) { - using var activity = ActivitySource.StartActivity("DossiersUpdateValore"); - string source = "DB+REDIS"; + using var activity = ActivitySource.StartActivity("DossiersUpdateValoreAsync"); + string source = "DB"; bool answ = false; Log.Info($"Richiesta snapshot per idxMaccSel {IdxMacchina} | periodo {dtMin} --> {dtMax}"); // chiamo stored x salvare parametri - dbController.DossiersTakeParamsSnapshotLast(IdxMacchina, dtMin, dtMax); - // elimino cache redis... - RedisValue pattern = new RedisValue($"{Utils.redisDossByMac}:*"); - answ = await ExecFlushRedisPatternAsync(pattern); - activity?.SetTag("data.source", "DB+REDIS"); + await dbController.DossiersTakeParamsSnapshotLastAsync(IdxMacchina, dtMin, dtMax); + // elimino cache... + answ = await FlushCacheAsync(Utils.redisDossByMac); + activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"DossiersTakeParamsSnapshotLast | Svuotata cache dossier | {pattern} | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"DossiersTakeParamsSnapshotLastAsync | Svuotata cache dossier | {source} | {activity?.Duration.TotalMilliseconds}ms"); return answ; } @@ -630,15 +630,16 @@ namespace MP.SPEC.Data /// /// /// - public async Task DossiersUpdateValore(DossierModel currDoss) + public async Task DossiersUpdateValoreAsync(DossierModel currDoss) { - using var activity = ActivitySource.StartActivity("DossiersUpdateValore"); + using var activity = ActivitySource.StartActivity("DossiersUpdateValoreAsync"); string source = "DB"; // aggiorno record sul DB - bool answ = await dbController.DossiersUpdateValore(currDoss); + bool answ = await dbController.DossiersUpdateValoreAsync(currDoss); + answ = await FlushCacheAsync(Utils.redisDossByMac); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"DossiersUpdateValore | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"DossiersUpdateValoreAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); return answ; } @@ -749,64 +750,15 @@ namespace MP.SPEC.Data /// public async Task EvListInsert(EventListModel newRec) { - using var activity = ActivitySource.StartActivity("EvListInsert"); + using var activity = ActivitySource.StartActivity("EvListInsertAsync"); string source = "DB"; - var result = await dbController.EvListInsert(newRec); + var result = await dbController.EvListInsertAsync(newRec); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"EvListInsert | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"EvListInsertAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return result; } - /// - /// Esegue flush memoria redis dato keyVal - /// - /// - /// - public bool ExecFlushRedisPattern(string pat2Flush) - { - using var activity = ActivitySource.StartActivity("ExecFlushRedisPattern"); - string source = "REDIS"; - bool answ = false; - var masterEndpoint = redisConn.GetEndPoints() - .Where(ep => redisConn.GetServer(ep).IsConnected && !redisConn.GetServer(ep).IsReplica) - .FirstOrDefault(); - - // sepattern è "*" elimino intero DB... - if (masterEndpoint != null && (pat2Flush.Equals(new RedisValue("*")) || pat2Flush == RedisValue.Null)) - { - redisConn.GetServer(masterEndpoint).FlushDatabase(database: redisDb.Database); - } - else - { - var server = redisConn.GetServer(masterEndpoint); - var keys = server.Keys(database: redisDb.Database, pattern: pat2Flush, pageSize: 1000); - var batch = new List(); - foreach (var key in keys) - { - batch.Add(key); - - // Flush in batches of 1000 - if (batch.Count >= 1000) - { - foreach (var item in batch) - redisDb.KeyDelete(item); - - batch.Clear(); - } - } - - // Flush remaining keys - foreach (var item in batch) - redisDb.KeyDelete(item); - } - answ = true; - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"ExecFlushRedisPattern | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return answ; - } - /// /// Esegue flush memoria redis dato keyVal, async /// @@ -869,7 +821,7 @@ namespace MP.SPEC.Data /// Cancellazione FusionCache dato singolo tag /// /// - public async Task FlushCacheByTagAsync(string tag) + public async Task FlushCacheAsync(string tag) { if (string.IsNullOrWhiteSpace(tag)) return false; @@ -882,7 +834,7 @@ namespace MP.SPEC.Data /// Cancellazione FusionCache dato elenco tags /// /// - public async Task FlushCacheByTagAsync(List listTags) + public async Task FlushCacheAsync(List listTags) { if (listTags == null || listTags.Count == 0) return false; @@ -897,19 +849,6 @@ namespace MP.SPEC.Data return true; } - public async Task FlushCacheFluxLog() - { - using var activity = ActivitySource.StartActivity("FlushCacheFluxLog"); - string source = "REDIS"; - bool answ = false; - RedisValue pattern = new RedisValue($"{Utils.redisParetoFLKey}:*"); - answ = await ExecFlushRedisPatternAsync(pattern); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"FlushCacheFluxLog | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return answ; - } - /// /// Flush cache relativa a MP-IO x dati ODL /// @@ -932,23 +871,14 @@ namespace MP.SPEC.Data public async Task FlushRedisCache() { using var activity = ActivitySource.StartActivity("FlushRedisCache"); - string source = "REDIS"; + string source = "FUSION"; + // valutare se tenere RedisValue pattern = Utils.RedValue("*"); - bool answ = await ExecFlushRedisPatternAsync(pattern); + await ExecFlushRedisPatternAsync(pattern); + // pulisco fusionlog cache... + bool answ = await FlushCacheAsync(); activity?.Stop(); - LogTrace($"FlushRedisCache | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return answ; - } - - public async Task FlushRedisKey(string redKey) - { - using var activity = ActivitySource.StartActivity("FlushRedisKey"); - string source = "REDIS"; - RedisValue pattern = Utils.RedValue(redKey); - bool answ = await ExecFlushRedisPatternAsync(pattern); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"FlushRedisKey | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"FlushCache | {source} | {activity?.Duration.TotalMilliseconds}ms"); return answ; } @@ -964,19 +894,24 @@ namespace MP.SPEC.Data /// public async Task FluxLogDataRedux(string idxMaccSel, List fluxList, DtUtils.Periodo currPeriodo, Enums.ValSelection valMode, Enums.DataInterval intReq, int maxItem) { - using var activity = ActivitySource.StartActivity("FluxLogDataRedux"); - string source = "DB+REDIS"; - List procStats = await dbController.FluxLogDataRedux(idxMaccSel, fluxList, currPeriodo, valMode, intReq, maxItem); + using var activity = ActivitySource.StartActivity("FluxLogDataReduxAsync"); + string source = "DB"; + List procStats = await dbController.FluxLogDataReduxAsync(idxMaccSel, fluxList, currPeriodo, valMode, intReq, maxItem); // effettuo merge statistiche... - ProcDedupStatMerge(procStats); + await ProcDedupStatMergeAsync(procStats); // svuoto cache await FlushCacheFluxLog(); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"FluxLogDataRedux | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"FluxLogDataReduxAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); } - public List FluxLogDtoGetByFlux(string Valore) + /// + /// Helper conversione valore raw in List di FluxLogDTO + /// + /// + /// + public List FluxLogDtoConvert(string Valore) { List answ = new List(); DossierFluxLogDTO? result = JsonConvert.DeserializeObject(Valore); @@ -1050,15 +985,15 @@ namespace MP.SPEC.Data public async Task ForceDbMaint(bool doExec = true, bool doUpdStat = true, bool doSave = true, int minPgCnt = 1000, int minAvgFrag = 10, int maxAvgFragReb = 50) { using var activity = ActivitySource.StartActivity("ForceDbMaint"); - string source = "DB+REDIS"; + string source = "DB"; await dbController.ForceDbMaint(doExec, doUpdStat, doSave, minPgCnt, minAvgFrag, maxAvgFragReb); // svuoto cache await FlushCacheFluxLog(); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ForceDbMaint | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ForceDbMaint | {source} | {activity?.Duration.TotalMilliseconds}ms"); // registro statistiche esecuzione - RecDbMaintStat(activity?.Duration ?? TimeSpan.FromSeconds(1)); + await RecDbMaintStatAsync(activity?.Duration ?? TimeSpan.FromSeconds(1)); } /// @@ -1072,7 +1007,7 @@ namespace MP.SPEC.Data bool result = false; result = await dbController.Grp2MaccDeleteAsync(rec2del); // elimino cache redis... - await ResetMacGrpCache(); + await FlushCacheMacGrp(); activity?.SetTag("data.source", "DB"); activity?.Stop(); LogTrace($"Grp2MaccDeleteAsync | CodGruppo {rec2del.CodGruppo} | IdxMacc {rec2del.IdxMacchina} | {activity?.Duration.TotalMilliseconds}ms"); @@ -1090,7 +1025,7 @@ namespace MP.SPEC.Data bool result = false; result = await dbController.Grp2MaccInsertAsync(upsRec); // elimino cache redis... - await ResetMacGrpCache(); + await FlushCacheMacGrp(); activity?.SetTag("data.source", "DB"); activity?.Stop(); LogTrace($"Grp2MaccInsertAsync | CodGruppo {upsRec.CodGruppo} | IdxMacc {upsRec.IdxMacchina} | {activity?.Duration.TotalMilliseconds}ms"); @@ -1108,7 +1043,7 @@ namespace MP.SPEC.Data bool result = false; result = await dbController.Grp2OperDeleteAsync(rec2del); // elimino cache redis... - await ResetOprGrpCache(); + await FlushCacheOprGrp(); activity?.SetTag("data.source", "DB"); activity?.Stop(); LogTrace($"Grp2OperDeleteAsync | CodGruppo {rec2del.CodGruppo} | MatrOpr {rec2del.MatrOpr} | {activity?.Duration.TotalMilliseconds}ms"); @@ -1126,7 +1061,7 @@ namespace MP.SPEC.Data bool result = false; result = await dbController.Grp2OperInsertAsync(upsRec); // elimino cache redis... - await ResetOprGrpCache(); + await FlushCacheOprGrp(); activity?.SetTag("data.source", "DB"); activity?.Stop(); LogTrace($"Grp2OperInsertAsync | CodGruppo {upsRec.CodGruppo} | MatrOpr {upsRec.MatrOpr} | {activity?.Duration.TotalMilliseconds}ms"); @@ -1149,7 +1084,7 @@ namespace MP.SPEC.Data /// Elimina record + svuotamento cache /// /// - public async Task IstKitDelete(IstanzeKitModel currRecord) + public async Task IstKitDeleteAsync(IstanzeKitModel currRecord) { using var activity = ActivitySource.StartActivity("IstKitDeleteAsync"); string source = "DB"; @@ -1204,7 +1139,7 @@ namespace MP.SPEC.Data /// Esegue salvataggio record + svuotamento cache /// /// - public async Task IstKitUpsert(IstanzeKitModel currRecord) + public async Task IstKitUpsertAsync(IstanzeKitModel currRecord) { using var activity = ActivitySource.StartActivity("IstKitUpsertAsync"); string source = "DB"; @@ -1462,9 +1397,9 @@ namespace MP.SPEC.Data /// idx idxMaccSel /// matricola operatore /// indica se confermare i pezzi priam di chiudere ODL - public async Task ODLClose(int idxOdl, string idxMacchina, int matrOpr, bool confPezzi) + public async Task ODLCloseAsync(int idxOdl, string idxMacchina, int matrOpr, bool confPezzi) { - using var activity = ActivitySource.StartActivity("ODLClose"); + using var activity = ActivitySource.StartActivity("ODLCloseAsync"); string source = "DB"; bool fatto = false; @@ -1482,11 +1417,13 @@ namespace MP.SPEC.Data int.TryParse(vModo, out modoConfProd); } // chiamo metodo conferma! - fatto = await dbController.ODLClose(idxOdl, idxMacchina, matrOpr, confPezzi, confRett, modoConfProd); + fatto = await dbController.ODLCloseAsync(idxOdl, idxMacchina, matrOpr, confPezzi, confRett, modoConfProd); + + await FlushCacheAsync(Utils.redisOdlByKey); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ODLClose | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ODLCloseAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return fatto; } @@ -1629,7 +1566,7 @@ namespace MP.SPEC.Data string source = "DB+REDIS"; var dbResult = await dbController.PODLDeleteRecord(currRec); // elimino cache redis... - await POdlFlushCache(); + await FlushCachePOdl(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"POdlDeleteRecord | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -1647,7 +1584,7 @@ namespace MP.SPEC.Data string source = "DB+REDIS"; var dbResult = await dbController.PODL_startSetup(currRec, 0, 1, 1, "", DateTime.Now); // elimino cache redis... - await POdlFlushCache(); + await FlushCachePOdl(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"POdlDoSetup | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -1661,6 +1598,15 @@ namespace MP.SPEC.Data /// public async Task POdlGetByKey(int idxPODL) { + string currKey = $"{Utils.redisPOdlByPOdl}:{idxPODL}"; + return await GetOrFetchAsync( + operationName: "POdlGetByKey", + cacheKey: currKey, + expiration: TimeSpan.FromMinutes(redisLongTimeCache), + fetchFunc: async () => await dbController.PODL_getByKeyAsync(idxPODL) ?? new(), + tagList: [Utils.redisPOdlByPOdl] + ); +#if false PODLModel result = new PODLModel(); if (idxPODL != 0) { @@ -1698,7 +1644,8 @@ namespace MP.SPEC.Data { Log.Debug("Errore IdxPODL = 0"); } - return result; + return result; +#endif } /// @@ -1729,7 +1676,7 @@ namespace MP.SPEC.Data // salvo fatto = await dbController.PodlIstKitDeleteAsync(IdxPODL); // svuoto cache - await FlushCacheByTagAsync(new List() { Utils.redisPOdlList }); + await FlushCachePOdl(); activity?.SetTag("data.source", "DB"); return fatto; } @@ -1749,7 +1696,6 @@ namespace MP.SPEC.Data fetchFunc: async () => await dbController.ListPODL_ByKitParentAsync(IdxPodlParent) ?? new(), tagList: [Utils.redisPOdlList] ); - } /// @@ -1814,14 +1760,11 @@ namespace MP.SPEC.Data public async Task POdlUpdateRecipe(int idxPODL, string recipeName) { using var activity = ActivitySource.StartActivity("POdlUpdateRecipe"); - string source = "DB+REDIS"; + string source = "DB"; bool answ = false; answ = await dbController.PODL_updateRecipe(idxPODL, recipeName); // reset redis... - if (answ) - { - await POdlFlushCache(); - } + await FlushCachePOdl(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"POdlUpdateRecipe | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -1836,10 +1779,10 @@ namespace MP.SPEC.Data public async Task POdlUpdateRecord(PODLModel currRec) { using var activity = ActivitySource.StartActivity("POdlUpdateRecord"); - string source = "DB+REDIS"; - var dbResult = await dbController.PODLUpdateRecord(currRec); + string source = "DB"; + var dbResult = await dbController.PODLUpdateRecordAsync(currRec); // elimino cache redis... - await POdlFlushCache(); + await FlushCachePOdl(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"POdlUpdateRecord | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -1850,14 +1793,14 @@ namespace MP.SPEC.Data /// Restituisce le statistiche di processo correnti x depluplica FluxLog /// /// - public List ProcFLStats() + public async Task> ProcFLStatsAsync() { - using var activity = ActivitySource.StartActivity("ProcFLStats"); + using var activity = ActivitySource.StartActivity("ProcFLStatsAsync"); string source = "REDIS"; List actStats = new List(); string currKey = $"{Utils.redisStatsProcFL}"; // recupero i record statistiche correnti - RedisValue rawData = redisDb.StringGet(currKey); + RedisValue rawData = await redisDb.StringGetAsync(currKey); if (rawData.HasValue) { var rawStats = JsonConvert.DeserializeObject>($"{rawData}"); @@ -1868,7 +1811,7 @@ namespace MP.SPEC.Data } activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ProcFLStats | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ProcFLStatsAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return actStats; } @@ -1897,13 +1840,10 @@ namespace MP.SPEC.Data public async Task RecipeSetByPODL(RecipeModel currRecord) { using var activity = ActivitySource.StartActivity("RecipeSetByPODL"); - string source = "DB+REDIS"; + string source = "MONGO"; bool answ = false; answ = await mongoController.RecipeSetByPODL(currRecord); - if (answ) - { - await POdlFlushCache(); - } + await FlushCachePOdl(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"RecipeSetByPODL | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -1995,15 +1935,27 @@ namespace MP.SPEC.Data /// Statistiche ODL calcolate (da stored stp_STAT_ODL) /// /// - public Task> StatOdl(int IdxOdl) + public async Task> OdlStatsAsync(int IdxOdl) { - using var activity = ActivitySource.StartActivity("StatOdl"); + string currKey = $"{Utils.redisOdlStats}:{IdxOdl}"; + + return await GetOrFetchAsync( + operationName: "OdlStatsAsync", + cacheKey: currKey, + expiration: getRandTOut(redisShortTimeCache), + fetchFunc: async () => await dbController.OdlGetStatAsync(IdxOdl) ?? new(), + tagList: [Utils.redisOdlStats] + ); + +#if false + using var activity = ActivitySource.StartActivity("OdlStatsAsync"); string source = "DB"; - var result = dbController.OdlStart(IdxOdl); + var result = await dbController.OdlGetStatAsync(IdxOdl); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"StatOdl | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return result; + LogTrace($"OdlStatsAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return result; +#endif } /// @@ -2034,8 +1986,8 @@ namespace MP.SPEC.Data string source = "DB"; bool fatto = false; // salvo - fatto = dbController.TemplateKitDelete(currRecord); - await FlushCacheByTagAsync(Utils.redisKitTempl); + fatto = await dbController.TemplateKitDeleteAsync(currRecord); + await FlushCacheAsync(Utils.redisKitTempl); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"TemplateKitDeleteAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -2073,7 +2025,7 @@ namespace MP.SPEC.Data bool fatto = false; // salvo fatto = dbController.TemplateKitUpsert(currRecord, codAzienda); - await FlushCacheByTagAsync(Utils.redisKitTempl); + await FlushCacheAsync(Utils.redisKitTempl); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"TemplateKitUpsertAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -2156,7 +2108,7 @@ namespace MP.SPEC.Data // salvo fatto = await dbController.WipKitDeleteAsync(currRecord); // svuoto cache - await FlushCacheByTagAsync(Utils.redisKitWip); + await FlushCacheAsync(Utils.redisKitWip); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"WipKitDeleteAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -2175,7 +2127,7 @@ namespace MP.SPEC.Data // salvo fatto = await dbController.WipKitDeleteOlderAsync(DateLimit); // svuoto cache KitWip - await FlushCacheByTagAsync(Utils.redisKitWip); + await FlushCacheAsync(Utils.redisKitWip); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"WipKitDeleteOlderAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -2211,7 +2163,7 @@ namespace MP.SPEC.Data // salvo fatto = await dbController.WipKitUpsertAsync(currRecord); // svuoto cache KitWip - await FlushCacheByTagAsync(Utils.redisKitWip); + await FlushCacheAsync(Utils.redisKitWip); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"WipKitUpsertAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -2222,6 +2174,93 @@ namespace MP.SPEC.Data #region Protected Methods + protected async Task FlushCacheArticoli() + { + using var activity = ActivitySource.StartActivity("FlushCacheArticoli"); + string source = "FUSION"; + bool answ = await FlushCacheAsync(new List() { Utils.redisArtList, Utils.redisArtByDossier }); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"FlushCacheArticoli | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } + + protected async Task FlushCacheConfig() + { + using var activity = ActivitySource.StartActivity("FlushCacheConfig"); + string source = "FUSION"; + bool answ = await FlushCacheAsync(new List() { Utils.redisConfKey }); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"FlushCacheConfig | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } + + /// + /// Reset macchine e gruppi + /// + protected async Task FlushCacheMacGrp() + { + using var activity = ActivitySource.StartActivity("FlushCacheMacGrp"); + string source = "FUSION"; + bool answ = await FlushCacheAsync(new List { Utils.redisAnagGruppi, Utils.redisMacList }); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"FlushCacheMacGrp | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } + + /// + /// Reset cache operatori e gruppi + /// + protected async Task FlushCacheOprGrp() + { + using var activity = ActivitySource.StartActivity("FlushCacheOprGrp"); + string source = "FUSION"; + bool answ = await FlushCacheAsync(new List { Utils.redisAnagGruppi, Utils.redisOprList }); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"FlushCacheOprGrp | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } + + protected async Task FlushCachePOdl() + { +#if false + using var activity = ActivitySource.StartActivity("POdlFlushCache"); + bool answ = false; + RedisValue pattern = new RedisValue($"{Utils.redisXdlData}:*"); + answ = await ExecFlushRedisPatternAsync(pattern); + pattern = new RedisValue($"{Utils.redisPOdlByOdl}:*"); + answ = await ExecFlushRedisPatternAsync(pattern); + pattern = new RedisValue($"{Utils.redisPOdlByPOdl}:*"); + answ = await ExecFlushRedisPatternAsync(pattern); + pattern = new RedisValue($"{Utils.redisPOdlList}:*"); + answ = await ExecFlushRedisPatternAsync(pattern); + activity?.SetTag("data.source", "REDIS"); + return answ; +#endif + + using var activity = ActivitySource.StartActivity("FlushCachePOdl"); + string source = "FUSION"; + bool answ = await FlushCacheAsync(new List() { Utils.redisXdlData, Utils.redisPOdlByOdl, Utils.redisPOdlByPOdl, Utils.redisPOdlList }); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"FlushCachePOdl | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } + + protected async Task FlushKitCache() + { + using var activity = ActivitySource.StartActivity("FlushKitCache"); + string source = "FUSION"; + bool answ = await FlushCacheAsync(new List() { Utils.redisPOdlList, Utils.redisKitInst, Utils.redisKitWip, Utils.redisKitScore, Utils.redisPOdlByCodArt }); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"FlushKitCache | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } + /// /// Restituisce un timeout dal valore secondi richiesti + tempo random +/-3% /// @@ -2234,66 +2273,20 @@ namespace MP.SPEC.Data return TimeSpan.FromSeconds(rValue); } - /// - /// Merge statistiche Dedup - /// - /// - /// - protected bool ProcDedupStatMerge(List procStats) - { - bool answ = false; - List actStats = ProcFLStats(); - // se fosse vuoto --> add diretto - if (actStats.Count == 0) - { - actStats.AddRange(procStats); - } - else - { - // aggiorno su redis i record statistiche 1:1... - foreach (var recStat in procStats) - { - // cerco se ci fosse x aggiornare - var currRec = actStats.Where(x => x.IdxMacchina == recStat.IdxMacchina - && x.CodFlux == recStat.CodFlux - && x.Interval == recStat.Interval - && x.Num4Int == recStat.Num4Int).FirstOrDefault(); - // se trovato aggiorno - if (currRec != null) - { - currRec.ProcTime += recStat.ProcTime; - currRec.NumRec += recStat.NumRec; - } - // altrimenti aggiungo - else - { - actStats.Add(recStat); - } - } - } - // salvo record statistiche - var rawData = JsonConvert.SerializeObject(actStats); - string currKey = $"{Utils.redisStatsProcFL}"; - redisDb.StringSet(currKey, rawData); - return answ; - } - /// /// Merge statistiche DB Maintenance /// /// /// - protected bool RecDbMaintStat(TimeSpan duration) + protected async Task RecDbMaintStatAsync(TimeSpan duration) { - bool answ = false; - Dictionary actStats = DbDedupStats(); + Dictionary actStats = await DbDedupStatsAsync(); // aggiungo record! actStats.Add(DateTime.Now, duration.TotalSeconds); // salvo NUOVO record statistiche string currKey = $"{Utils.redisStatsDbMaint}"; var rawData = JsonConvert.SerializeObject(actStats); - redisDb.StringSet(currKey, rawData); - return answ; + return await redisDb.StringSetAsync(currKey, rawData); } #endregion Protected Methods @@ -2390,9 +2383,15 @@ namespace MP.SPEC.Data } } - private async Task FlushKitCache() + private async Task FlushCacheFluxLog() { - await FlushCacheByTagAsync(new List() { Utils.redisPOdlList, Utils.redisKitInst, Utils.redisKitWip, Utils.redisKitScore, Utils.redisPOdlByCodArt }); + using var activity = ActivitySource.StartActivity("FlushCacheFluxLog"); + string source = "FUSION"; + bool answ = await FlushCacheAsync(new List() { Utils.redisFluxLogFilt, Utils.redisParetoFLKey }); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"FlushCacheFluxLog | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; } /// @@ -2477,20 +2476,46 @@ namespace MP.SPEC.Data Log.Log(reqLevel, traceMsg); } - private async Task POdlFlushCache() + /// + /// Merge statistiche Dedup + /// + /// + /// + private async Task ProcDedupStatMergeAsync(List procStats) { - using var activity = ActivitySource.StartActivity("POdlFlushCache"); - bool answ = false; - RedisValue pattern = new RedisValue($"{Utils.redisXdlData}:*"); - answ = await ExecFlushRedisPatternAsync(pattern); - pattern = new RedisValue($"{Utils.redisPOdlByOdl}:*"); - answ = await ExecFlushRedisPatternAsync(pattern); - pattern = new RedisValue($"{Utils.redisPOdlByPOdl}:*"); - answ = await ExecFlushRedisPatternAsync(pattern); - pattern = new RedisValue($"{Utils.redisPOdlList}:*"); - answ = await ExecFlushRedisPatternAsync(pattern); - activity?.SetTag("data.source", "REDIS"); - return answ; + List actStats = await ProcFLStatsAsync(); + // se fosse vuoto --> add diretto + if (actStats.Count == 0) + { + actStats.AddRange(procStats); + } + else + { + // aggiorno su redis i record statistiche 1:1... + foreach (var recStat in procStats) + { + // cerco se ci fosse x aggiornare + var currRec = actStats.Where(x => x.IdxMacchina == recStat.IdxMacchina + && x.CodFlux == recStat.CodFlux + && x.Interval == recStat.Interval + && x.Num4Int == recStat.Num4Int).FirstOrDefault(); + // se trovato aggiorno + if (currRec != null) + { + currRec.ProcTime += recStat.ProcTime; + currRec.NumRec += recStat.NumRec; + } + // altrimenti aggiungo + else + { + actStats.Add(recStat); + } + } + } + // salvo record statistiche + var rawData = JsonConvert.SerializeObject(actStats); + string currKey = $"{Utils.redisStatsProcFL}"; + return await redisDb.StringSetAsync(currKey, rawData); } private string redHashMpIO(string keyName) @@ -2508,44 +2533,6 @@ namespace MP.SPEC.Data return result; } - private async Task resetCacheArticoli() - { - using var activity = ActivitySource.StartActivity("resetCacheArticoli"); - RedisValue pattern = new RedisValue($"{Utils.redisArtByDossier}:*"); - await ExecFlushRedisPatternAsync(pattern); - pattern = new RedisValue($"{Utils.redisArtList}:*"); - await ExecFlushRedisPatternAsync(pattern); - // elimino anche in FusionCache - List tags2del = new List() { Utils.redisArtList, Utils.redisArtByDossier }; - await FlushCacheByTagAsync(tags2del); - activity?.SetTag("data.source", "REDIS"); - } - - private async Task ResetConfigCache() - { - await redisDb.StringSetAsync(Utils.redisConfKey, ""); - List tags2del = new List() { Utils.redisConfKey }; - await FlushCacheByTagAsync(tags2del); - } - - /// - /// Reset macchine e gruppi - /// - private async Task ResetMacGrpCache() - { - await FlushCacheByTagAsync(new List { Utils.redisAnagGruppi, Utils.redisMacList }); - } - - /// - /// Reset cache operatori e gruppi - /// - private async Task ResetOprGrpCache() - { - //ExecFlushRedisPattern($"{Utils.redisAnagGruppi}:*"); - //ExecFlushRedisPattern($"{Utils.redisOprList}:*"); - await FlushCacheByTagAsync(new List { Utils.redisAnagGruppi, Utils.redisOprList }); - } - #endregion Private Methods } } \ No newline at end of file diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 982527dc..0ab5e00b 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.3010 + 8.16.2605.3012 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/FluxLogStatus.razor.cs b/MP.SPEC/Pages/FluxLogStatus.razor.cs index 1b0d3ff8..cd472022 100644 --- a/MP.SPEC/Pages/FluxLogStatus.razor.cs +++ b/MP.SPEC/Pages/FluxLogStatus.razor.cs @@ -95,7 +95,7 @@ namespace MP.SPEC.Pages await MDataServ.FluxLogDataRedux(idxMaccSel, new List { item }, CurrPeriodo, ValMode, IntReq, NumItem); currStep++; } - //await MDataServ.FluxLogDataRedux(idxMaccSel, fluxList, CurrPeriodo, ValMode, IntReq, maxItem); + //await MDataServ.FluxLogDataReduxAsync(idxMaccSel, fluxList, CurrPeriodo, ValMode, IntReq, maxItem); sw.Stop(); lastDedupExecTime = $"{sw.Elapsed.Minutes}m {sw.Elapsed.Seconds}s"; isProcessing = false; @@ -122,7 +122,7 @@ namespace MP.SPEC.Pages protected override async Task OnInitializedAsync() { - ReloadStats(); + await ReloadStatsAsync(); await ReloadDataAsync(); } @@ -226,10 +226,10 @@ namespace MP.SPEC.Pages CurrPeriodo = new Periodo(dtStart, dtEnd); } - private void ReloadStats() + private async Task ReloadStatsAsync() { - actProcDedupStats = MDataServ.ProcFLStats(); - actDbMaintStats = MDataServ.DbDedupStats(); + actProcDedupStats = await MDataServ.ProcFLStatsAsync(); + actDbMaintStats = await MDataServ.DbDedupStatsAsync(); } private void updateExpTime() diff --git a/MP.SPEC/Pages/KIT.razor.cs b/MP.SPEC/Pages/KIT.razor.cs index d45da043..af46bcbc 100644 --- a/MP.SPEC/Pages/KIT.razor.cs +++ b/MP.SPEC/Pages/KIT.razor.cs @@ -112,7 +112,7 @@ namespace MP.SPEC.Pages // se deve essere autogenerato da counter... if (AutoGen) { - var cntRec = MDService.AnagCountersGetNext("NumKitArt"); + var cntRec = await MDService.AnagCountersGetNextAsync("NumKitArt"); if (cntRec != null) { codParent = $"{cntRec.CntCode}{cntRec.LastNum:000000}"; diff --git a/MP.SPEC/Pages/Podl2Kit.razor.cs b/MP.SPEC/Pages/Podl2Kit.razor.cs index 47361bd6..bea6e530 100644 --- a/MP.SPEC/Pages/Podl2Kit.razor.cs +++ b/MP.SPEC/Pages/Podl2Kit.razor.cs @@ -130,7 +130,7 @@ namespace MP.SPEC.Pages return; await Task.Delay(1); - var done = await MDService.IstKitDelete(selRec); + var done = await MDService.IstKitDeleteAsync(selRec); EditRecord = null; await ResetDataAsync(); } @@ -141,7 +141,7 @@ namespace MP.SPEC.Pages return; await Task.Delay(1); - var done = await MDService.IstKitUpsert(selRec); + var done = await MDService.IstKitUpsertAsync(selRec); EditRecord = null; await ResetDataAsync(); } diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index af4e92ba..6f505a94 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                              Versione: 8.16.2605.3010

                                              +

                                              Versione: 8.16.2605.3012


                                              Note di rilascio:
                                              • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index fac721dd..3cbdcdc0 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.3010 +8.16.2605.3012 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index aefa43a4..cad23318 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.3010 + 8.16.2605.3012 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/Refactor_Plan.md b/Refactor_Plan.md index 8120444a..12a5cf0a 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -9,7 +9,7 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa ## Strategia di Migrazione - **Metodo Standard**: `GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tagList)`. -- **Invalidazione**: Utilizzare i tag tramite `FlushCacheByTagsAsync`. +- **Invalidazione**: Utilizzare i tag tramite `FlushCacheByTagAsync`. ## Stato Avanzamento @@ -71,12 +71,15 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - [ ] Migrazione di `ActionSetReq` (linea 136: usa `BroadastMsgPipe.saveAndSendMessage`). - [ ] Migrazione di `ArticoliDeleteRecord`/`UpdateRecord` (linea 296/372: usa `resetCacheArticoli`). - [ ] Migrazione di `DbDedupStats` (linea 516: usa `redisDb.StringGet`). -- [ ] Migrazione di `DossiersDeleteRecord` (linea 554: usa `ExecFlushRedisPatternAsync`). -- [ ] Migrazione di `DossiersTakeParamsSnapshotLast` (linea 613: usa `ExecFlushRedisPatternAsync`). +- [ ] Migrazione di `DossiersDeleteRecord` (linea 551: usa `ExecFlushRedisPatternAsync`). +- [ ] Migrazione di `DossiersTakeParamsSnapshotLast` (linea 610: usa `ExecFlushRedisPatternAsync`). - [ ] Migrazione di `ElencoRepartiDTO` (linea 697: usa `redisDb.StringGet` e `StringSet`). -- [ ] Migrazione di `PodlIstKitDelete` (linea 1842: usa `ExecFlushRedisPattern`). -- [ ] Migrazione di `POdlListByKitParent` (linea 1863: usa `redisDb.StringGet` e `StringSet`). -- [ ] Migrazione di `ProcFLStats` (linea 1992: usa `redisDb.StringSet`). +- [ ] Migrazione di `PodlIstKitDelete` (linea 1760: usa `ExecFlushRedisPattern` sincrono). +- [ ] Migrazione di `POdlListByKitParent` (linea 1781: usa `redisDb.StringGet` e `StringSet`). +- [ ] Migrazione di `POdlGetByKey` (linea 1662: usa `redisDb.StringGet` e `StringSet`). +- [ ] Migrazione di `POdlUpdateRecipe` (linea 1814: usa `POdlFlushCache` con pattern). +- [ ] Migrazione di `POdlUpdateRecord` (linea 1836: usa `POdlFlushCache` con pattern). +- [ ] Migrazione di `ProcFLStats` (linea 1853: usa `redisDb.StringGet`). - [ ] Migrazione di `RecDbMaintStat` (linea 2451: usa `redisDb.StringSet`). *(Nota: Il vecchio metodo `VocabolarioGetAll` e la gestione manuale del dizionario sono stati rimossi in favore di `Traduci` con FusionCache).* @@ -94,3 +97,4 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa + From 8e7d08e4c91433329d18285e38579f9f663d73dc Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 1 Jun 2026 07:27:48 +0200 Subject: [PATCH 078/102] Cleanup metodi e correzioni varie --- MP.Data/Controllers/MpSpecController.cs | 50 ++++- MP.SPEC/Components/CmpTop.razor.cs | 4 +- MP.SPEC/Components/ListDossiers.razor.cs | 5 +- MP.SPEC/Components/ListPODL.razor.cs | 12 +- MP.SPEC/Data/MpDataService.cs | 268 +++++++++-------------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/PARAMS.razor.cs | 4 +- MP.SPEC/Pages/Utils.razor.cs | 4 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 11 files changed, 164 insertions(+), 191 deletions(-) diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index d536a4ee..2bc53fc1 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -391,6 +391,7 @@ namespace MP.Data.Controllers .CountAsync(); return result; } + /// /// Conteggio articoli data condizione ricerca /// @@ -429,6 +430,7 @@ namespace MP.Data.Controllers .OrderBy(x => x.CodArticolo) .CountAsync(); } + /// /// Elenco tabella Articoli IMPIEGATI (da stored stp_ART_getUsed) Async /// @@ -1827,7 +1829,7 @@ namespace MP.Data.Controllers } } return dbResult; - } + } #endif /// @@ -1880,7 +1882,6 @@ namespace MP.Data.Controllers var IdxODL = new SqlParameter("@IdxODL", idxOdl); var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); - // se richiesto confermo produzione if (confPezzi) { @@ -1971,7 +1972,7 @@ namespace MP.Data.Controllers } } return dbResult; - } + } #endif /// @@ -2315,7 +2316,6 @@ namespace MP.Data.Controllers .AddAsync(editRec); } return await dbCtx.SaveChangesAsync() > 0; - } /// @@ -2477,6 +2477,20 @@ namespace MP.Data.Controllers return dbResult; } + /// + /// Elenco Vocabolario (completo) async + /// + /// + public async Task> VocabolarioGetAllAsync() + { + using var dbCtx = new MoonProContext(options); + return await dbCtx + .DbSetVocabolario + .AsNoTracking() + .OrderBy(x => x.Lemma) + .ToListAsync() ?? new(); + } + /// /// Elenco Vocabolario di una lingua /// @@ -2497,17 +2511,31 @@ namespace MP.Data.Controllers } /// - /// Elenco Vocabolario (completo) async + /// Upsert record Vocabolario /// + /// /// - public async Task> VocabolarioGetAllAsync() + public async Task VocabolarioUpsertAsync(VocabolarioModel upsRec) { using var dbCtx = new MoonProContext(options); - return await dbCtx - .DbSetVocabolario - .AsNoTracking() - .OrderBy(x => x.Lemma) - .ToListAsync() ?? new(); + var actRec = await dbCtx + .DbSetVocabolario + .Where(x => x.Lingua == upsRec.Lingua && x.Lemma == upsRec.Lemma) + .FirstOrDefaultAsync(); + + // se ci fosse aggiorno... + if (actRec == null) + { + dbCtx + .DbSetVocabolario + .Add(upsRec); + } + else + { + actRec.Traduzione = upsRec.Traduzione; + dbCtx.Entry(actRec).State = EntityState.Modified; + } + return await dbCtx.SaveChangesAsync() > 0; } /// diff --git a/MP.SPEC/Components/CmpTop.razor.cs b/MP.SPEC/Components/CmpTop.razor.cs index 593b6a6a..8b2ee9b2 100644 --- a/MP.SPEC/Components/CmpTop.razor.cs +++ b/MP.SPEC/Components/CmpTop.razor.cs @@ -52,8 +52,8 @@ namespace MP.SPEC.Components protected async Task FlushCache() { - await MDService.FlushRedisCache(); - await MDService.FlushCacheAsync(); + await MDService.ForceFlushRedisCache(); + await MDService.ForceFlushFusionCacheAsync(); await ForceReload(); // rimando a pagina corrente NavManager.NavigateTo(NavManager.Uri, true); diff --git a/MP.SPEC/Components/ListDossiers.razor.cs b/MP.SPEC/Components/ListDossiers.razor.cs index d2ea0aa0..63514f91 100644 --- a/MP.SPEC/Components/ListDossiers.razor.cs +++ b/MP.SPEC/Components/ListDossiers.razor.cs @@ -67,9 +67,8 @@ namespace MP.SPEC.Components public async Task flushCache() { - await Task.Delay(1); - await MDService.FlushRedisCache(); - await Task.Delay(1); + await MDService.ForceFlushRedisCache(); + await MDService.ForceFlushFusionCacheAsync(); // rimando a pagina corrente NavManager.NavigateTo(NavManager.Uri, true); } diff --git a/MP.SPEC/Components/ListPODL.razor.cs b/MP.SPEC/Components/ListPODL.razor.cs index fbcb863b..0dca5e88 100644 --- a/MP.SPEC/Components/ListPODL.razor.cs +++ b/MP.SPEC/Components/ListPODL.razor.cs @@ -361,18 +361,20 @@ namespace MP.SPEC.Components string odlPad = newOdl.IdxOdl.ToString(padCodXdl); await callTask2Exe(selRec.IdxMacchina, "setComm", $"ODL{odlPad}"); await callTask2Exe(selRec.IdxMacchina, "setPzComm", $"{newOdl.NumPezzi}"); + await Task.Delay(1); // chiamo task x IOB await callForceUpdate(selRec.IdxMacchina); - await Task.Delay(1); - await callForceUpdate(selRec.IdxMacchina); + //await Task.Delay(1); + //await callForceUpdate(selRec.IdxMacchina); await Task.Delay(1); await callSyncDb(selRec.IdxMacchina); - await Task.Delay(1); // svuoto memorie pagina... - await MDService.FlushRedisCache(); + await MDService.ForceFlushRedisCache(); // svuoto cache MpIoNsCache - await MDService.FlushMpIoOdlCache(); + await MDService.FlushRedisCacheMpIoOdl(); + // svuoto altra cache + await MDService.ForceFlushFusionCacheAsync(); // ricarico pagina! NavManager.NavigateTo(NavManager.Uri, true); diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 1aa19dcd..71a644f0 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -193,7 +193,7 @@ namespace MP.SPEC.Data string source = "DB"; result = dbController.AnagGruppiDelete(updRec); // elimino cache redis... - await FlushCacheAsync(Utils.redisAnagGruppi); + await FlushFusionCacheAsync(Utils.redisAnagGruppi); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"AnagGruppiDeleteAsync | CodGruppo {updRec.CodGruppo} | {source}{activity?.Duration.TotalMilliseconds}ms"); @@ -212,7 +212,7 @@ namespace MP.SPEC.Data string source = "DB"; result = dbController.AnagGruppiUpsert(UpdRec); // elimino cache redis... - await FlushCacheAsync(Utils.redisAnagGruppi); + await FlushFusionCacheAsync(Utils.redisAnagGruppi); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"AnagGruppiUpsertAsync | CodGruppo {UpdRec.CodGruppo} | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -556,7 +556,7 @@ namespace MP.SPEC.Data bool result = false; result = await dbController.DossiersDeleteRecordAsync(selRecord); // elimino cache... - await FlushCacheAsync(Utils.redisDossByMac); + await FlushFusionCacheAsync(Utils.redisDossByMac); activity?.SetTag("data.source", "DB"); activity?.Stop(); LogTrace($"DossiersDeleteRecordAsync | IdxMacchina {selRecord.IdxMacchina} | DtRif {selRecord.DtRif} | IdxODL {selRecord.IdxODL} | {activity?.Duration.TotalMilliseconds}ms"); @@ -595,7 +595,7 @@ namespace MP.SPEC.Data string source = "DB"; // aggiorno record sul DB bool answ = await dbController.DossiersInsertAsync(currDoss); - answ = await FlushCacheAsync(Utils.redisDossByMac); + answ = await FlushFusionCacheAsync(Utils.redisDossByMac); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"DossiersInsertAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -618,7 +618,7 @@ namespace MP.SPEC.Data // chiamo stored x salvare parametri await dbController.DossiersTakeParamsSnapshotLastAsync(IdxMacchina, dtMin, dtMax); // elimino cache... - answ = await FlushCacheAsync(Utils.redisDossByMac); + answ = await FlushFusionCacheAsync(Utils.redisDossByMac); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"DossiersTakeParamsSnapshotLastAsync | Svuotata cache dossier | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -636,7 +636,7 @@ namespace MP.SPEC.Data string source = "DB"; // aggiorno record sul DB bool answ = await dbController.DossiersUpdateValoreAsync(currDoss); - answ = await FlushCacheAsync(Utils.redisDossByMac); + answ = await FlushFusionCacheAsync(Utils.redisDossByMac); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"DossiersUpdateValoreAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -805,57 +805,13 @@ namespace MP.SPEC.Data return answ; } - /// - /// Cancellazione FusionCache (totale) - /// - /// - public async Task FlushCacheAsync() - { - await _cache.ClearAsync(allowFailSafe: false); - _configData.Clear(); - _artCacheExpiry = DateTime.Now.AddHours(-1); - return true; - } - - /// - /// Cancellazione FusionCache dato singolo tag - /// - /// - public async Task FlushCacheAsync(string tag) - { - if (string.IsNullOrWhiteSpace(tag)) return false; - - await _cache.RemoveByTagAsync(tag); - _configData.Clear(); - return true; - } - - /// - /// Cancellazione FusionCache dato elenco tags - /// - /// - public async Task FlushCacheAsync(List listTags) - { - if (listTags == null || listTags.Count == 0) return false; - - // Generiamo i Task di rimozione ed eseguiamoli in parallelo su Redis/L1 - var tasks = listTags - .Where(tag => !string.IsNullOrWhiteSpace(tag)) - .Select(tag => _cache.RemoveByTagAsync(tag).AsTask()); - - await Task.WhenAll(tasks); - - _configData.Clear(); - return true; - } - /// /// Flush cache relativa a MP-IO x dati ODL /// /// - public async Task FlushMpIoOdlCache() + public async Task FlushRedisCacheMpIoOdl() { - using var activity = ActivitySource.StartActivity("FlushMpIoOdlCache"); + using var activity = ActivitySource.StartActivity("FlushRedisCacheMpIoOdl"); string source = "REDIS"; // svuoto dalla cache REDIS del server IO... bool ok01 = await ResetIoCache("CurrODL"); @@ -864,24 +820,10 @@ namespace MP.SPEC.Data bool ok04 = await ResetIoCache("DtMac"); activity?.SetTag("data.source", "REDIS"); activity?.Stop(); - LogTrace($"FlushMpIoOdlCache | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"FlushRedisCacheMpIoOdl | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); return ok01 && ok02 && ok03 && ok04; } - public async Task FlushRedisCache() - { - using var activity = ActivitySource.StartActivity("FlushRedisCache"); - string source = "FUSION"; - // valutare se tenere - RedisValue pattern = Utils.RedValue("*"); - await ExecFlushRedisPatternAsync(pattern); - // pulisco fusionlog cache... - bool answ = await FlushCacheAsync(); - activity?.Stop(); - LogTrace($"FlushCache | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return answ; - } - /// /// Funzione di Data Reduction x FluxLog /// @@ -996,6 +938,29 @@ namespace MP.SPEC.Data await RecDbMaintStatAsync(activity?.Duration ?? TimeSpan.FromSeconds(1)); } + /// + /// Cancellazione FusionCache (totale) - wrapper public + /// + /// + public Task ForceFlushFusionCacheAsync() + { + return FlushFusionCacheAsync(); + } + + public async Task ForceFlushRedisCache() + { + using var activity = ActivitySource.StartActivity("ForceFlushRedisCache"); + string source = "FUSION"; + // valutare se tenere + RedisValue pattern = Utils.RedValue("*"); + await ExecFlushRedisPatternAsync(pattern); + // pulisco fusionlog cache... + bool answ = await FlushFusionCacheAsync(); + activity?.Stop(); + LogTrace($"FlushCache | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } + /// /// Eliminazione di un record macchina dal gruppo /// @@ -1419,7 +1384,7 @@ namespace MP.SPEC.Data // chiamo metodo conferma! fatto = await dbController.ODLCloseAsync(idxOdl, idxMacchina, matrOpr, confPezzi, confRett, modoConfProd); - await FlushCacheAsync(Utils.redisOdlByKey); + await FlushFusionCacheAsync(Utils.redisOdlByKey); activity?.SetTag("data.source", source); activity?.Stop(); @@ -1450,6 +1415,23 @@ namespace MP.SPEC.Data ); } + /// + /// Statistiche ODL calcolate (da stored stp_STAT_ODL) + /// + /// + public async Task> OdlStatsAsync(int IdxOdl) + { + string currKey = $"{Utils.redisOdlStats}:{IdxOdl}"; + + return await GetOrFetchAsync( + operationName: "OdlStatsAsync", + cacheKey: currKey, + expiration: getRandTOut(redisShortTimeCache), + fetchFunc: async () => await dbController.OdlGetStatAsync(IdxOdl) ?? new(), + tagList: [Utils.redisOdlStats] + ); + } + /// /// Elenco operatori filtrati x gruppo /// @@ -1606,46 +1588,6 @@ namespace MP.SPEC.Data fetchFunc: async () => await dbController.PODL_getByKeyAsync(idxPODL) ?? new(), tagList: [Utils.redisPOdlByPOdl] ); -#if false - PODLModel result = new PODLModel(); - if (idxPODL != 0) - { - using var activity = ActivitySource.StartActivity("POdlGetByKey"); - string source = "DB"; - string currKey = $"{Utils.redisPOdlByPOdl}:{idxPODL}"; - // cerco in redis dato valore sel idxMaccSel... - RedisValue rawData = redisDb.StringGet(currKey); - if (rawData.HasValue) - { - var rawResult = JsonConvert.DeserializeObject($"{rawData}"); - if (rawResult != null) - { - result = rawResult; - source = "REDIS"; - } - } - else - { - result = await dbController.PODL_getByKey(idxPODL); - // serializzo e salvo... - rawData = JsonConvert.SerializeObject(result); - redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); - } - if (result == null) - { - result = new PODLModel(); - } - activity?.SetTag("data.source", source); - activity?.SetTag("result.count", 1); - activity?.Stop(); - Log.Trace($"POdlGetByKey | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - } - else - { - Log.Debug("Errore IdxPODL = 0"); - } - return result; -#endif } /// @@ -1931,33 +1873,6 @@ namespace MP.SPEC.Data return answ; } - /// - /// Statistiche ODL calcolate (da stored stp_STAT_ODL) - /// - /// - public async Task> OdlStatsAsync(int IdxOdl) - { - string currKey = $"{Utils.redisOdlStats}:{IdxOdl}"; - - return await GetOrFetchAsync( - operationName: "OdlStatsAsync", - cacheKey: currKey, - expiration: getRandTOut(redisShortTimeCache), - fetchFunc: async () => await dbController.OdlGetStatAsync(IdxOdl) ?? new(), - tagList: [Utils.redisOdlStats] - ); - -#if false - using var activity = ActivitySource.StartActivity("OdlStatsAsync"); - string source = "DB"; - var result = await dbController.OdlGetStatAsync(IdxOdl); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"OdlStatsAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return result; -#endif - } - /// /// Stato macchina /// @@ -1987,7 +1902,7 @@ namespace MP.SPEC.Data bool fatto = false; // salvo fatto = await dbController.TemplateKitDeleteAsync(currRecord); - await FlushCacheAsync(Utils.redisKitTempl); + await FlushFusionCacheAsync(Utils.redisKitTempl); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"TemplateKitDeleteAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -2025,7 +1940,7 @@ namespace MP.SPEC.Data bool fatto = false; // salvo fatto = dbController.TemplateKitUpsert(currRecord, codAzienda); - await FlushCacheAsync(Utils.redisKitTempl); + await FlushFusionCacheAsync(Utils.redisKitTempl); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"TemplateKitUpsertAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -2108,7 +2023,7 @@ namespace MP.SPEC.Data // salvo fatto = await dbController.WipKitDeleteAsync(currRecord); // svuoto cache - await FlushCacheAsync(Utils.redisKitWip); + await FlushFusionCacheAsync(Utils.redisKitWip); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"WipKitDeleteAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -2127,7 +2042,7 @@ namespace MP.SPEC.Data // salvo fatto = await dbController.WipKitDeleteOlderAsync(DateLimit); // svuoto cache KitWip - await FlushCacheAsync(Utils.redisKitWip); + await FlushFusionCacheAsync(Utils.redisKitWip); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"WipKitDeleteOlderAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -2163,7 +2078,7 @@ namespace MP.SPEC.Data // salvo fatto = await dbController.WipKitUpsertAsync(currRecord); // svuoto cache KitWip - await FlushCacheAsync(Utils.redisKitWip); + await FlushFusionCacheAsync(Utils.redisKitWip); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"WipKitUpsertAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -2178,7 +2093,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("FlushCacheArticoli"); string source = "FUSION"; - bool answ = await FlushCacheAsync(new List() { Utils.redisArtList, Utils.redisArtByDossier }); + bool answ = await FlushFusionCacheAsync(new List() { Utils.redisArtList, Utils.redisArtByDossier }); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"FlushCacheArticoli | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -2189,7 +2104,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("FlushCacheConfig"); string source = "FUSION"; - bool answ = await FlushCacheAsync(new List() { Utils.redisConfKey }); + bool answ = await FlushFusionCacheAsync(new List() { Utils.redisConfKey }); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"FlushCacheConfig | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -2203,7 +2118,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("FlushCacheMacGrp"); string source = "FUSION"; - bool answ = await FlushCacheAsync(new List { Utils.redisAnagGruppi, Utils.redisMacList }); + bool answ = await FlushFusionCacheAsync(new List { Utils.redisAnagGruppi, Utils.redisMacList }); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"FlushCacheMacGrp | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -2217,7 +2132,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("FlushCacheOprGrp"); string source = "FUSION"; - bool answ = await FlushCacheAsync(new List { Utils.redisAnagGruppi, Utils.redisOprList }); + bool answ = await FlushFusionCacheAsync(new List { Utils.redisAnagGruppi, Utils.redisOprList }); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"FlushCacheOprGrp | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -2226,35 +2141,64 @@ namespace MP.SPEC.Data protected async Task FlushCachePOdl() { -#if false - using var activity = ActivitySource.StartActivity("POdlFlushCache"); - bool answ = false; - RedisValue pattern = new RedisValue($"{Utils.redisXdlData}:*"); - answ = await ExecFlushRedisPatternAsync(pattern); - pattern = new RedisValue($"{Utils.redisPOdlByOdl}:*"); - answ = await ExecFlushRedisPatternAsync(pattern); - pattern = new RedisValue($"{Utils.redisPOdlByPOdl}:*"); - answ = await ExecFlushRedisPatternAsync(pattern); - pattern = new RedisValue($"{Utils.redisPOdlList}:*"); - answ = await ExecFlushRedisPatternAsync(pattern); - activity?.SetTag("data.source", "REDIS"); - return answ; -#endif - using var activity = ActivitySource.StartActivity("FlushCachePOdl"); string source = "FUSION"; - bool answ = await FlushCacheAsync(new List() { Utils.redisXdlData, Utils.redisPOdlByOdl, Utils.redisPOdlByPOdl, Utils.redisPOdlList }); + bool answ = await FlushFusionCacheAsync(new List() { Utils.redisXdlData, Utils.redisPOdlByOdl, Utils.redisPOdlByPOdl, Utils.redisPOdlList }); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"FlushCachePOdl | {source} | {activity?.Duration.TotalMilliseconds}ms"); return answ; } + /// + /// Cancellazione FusionCache (totale) + /// + /// + protected async Task FlushFusionCacheAsync() + { + await _cache.ClearAsync(allowFailSafe: false); + _configData.Clear(); + _artCacheExpiry = DateTime.Now.AddHours(-1); + return true; + } + + /// + /// Cancellazione FusionCache dato singolo tag + /// + /// + protected async Task FlushFusionCacheAsync(string tag) + { + if (string.IsNullOrWhiteSpace(tag)) return false; + + await _cache.RemoveByTagAsync(tag); + _configData.Clear(); + return true; + } + + /// + /// Cancellazione FusionCache dato elenco tags + /// + /// + protected async Task FlushFusionCacheAsync(List listTags) + { + if (listTags == null || listTags.Count == 0) return false; + + // Generiamo i Task di rimozione ed eseguiamoli in parallelo su Redis/L1 + var tasks = listTags + .Where(tag => !string.IsNullOrWhiteSpace(tag)) + .Select(tag => _cache.RemoveByTagAsync(tag).AsTask()); + + await Task.WhenAll(tasks); + + _configData.Clear(); + return true; + } + protected async Task FlushKitCache() { using var activity = ActivitySource.StartActivity("FlushKitCache"); string source = "FUSION"; - bool answ = await FlushCacheAsync(new List() { Utils.redisPOdlList, Utils.redisKitInst, Utils.redisKitWip, Utils.redisKitScore, Utils.redisPOdlByCodArt }); + bool answ = await FlushFusionCacheAsync(new List() { Utils.redisPOdlList, Utils.redisKitInst, Utils.redisKitWip, Utils.redisKitScore, Utils.redisPOdlByCodArt }); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"FlushKitCache | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -2387,7 +2331,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("FlushCacheFluxLog"); string source = "FUSION"; - bool answ = await FlushCacheAsync(new List() { Utils.redisFluxLogFilt, Utils.redisParetoFLKey }); + bool answ = await FlushFusionCacheAsync(new List() { Utils.redisFluxLogFilt, Utils.redisParetoFLKey }); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"FlushCacheFluxLog | {source} | {activity?.Duration.TotalMilliseconds}ms"); diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 0ab5e00b..d9966714 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2605.3012 + 8.16.2606.107 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/PARAMS.razor.cs b/MP.SPEC/Pages/PARAMS.razor.cs index 73204309..3d8b689a 100644 --- a/MP.SPEC/Pages/PARAMS.razor.cs +++ b/MP.SPEC/Pages/PARAMS.razor.cs @@ -110,9 +110,9 @@ namespace MP.SPEC.Pages protected async Task forceReloadCache() { Log.Debug("----- forceReloadCache on PARAMS.cs -----"); + await MDService.ForceFlushRedisCache(); await Task.Delay(1); - await MDService.FlushRedisCache(); - await Task.Delay(1); + await MDService.ForceFlushFusionCacheAsync(); // rimando a pagina corrente NavManager.NavigateTo(NavManager.Uri, true, true); } diff --git a/MP.SPEC/Pages/Utils.razor.cs b/MP.SPEC/Pages/Utils.razor.cs index f26cdad2..5020e3eb 100644 --- a/MP.SPEC/Pages/Utils.razor.cs +++ b/MP.SPEC/Pages/Utils.razor.cs @@ -9,8 +9,8 @@ namespace MP.SPEC.Pages public async Task flushCache() { - await Task.Delay(1); - await MDService.FlushRedisCache(); + await MDService.ForceFlushRedisCache(); + await MDService.ForceFlushFusionCacheAsync(); // rimando a home NavManager.NavigateTo("", true); } diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 6f505a94..2f37a84c 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                Versione: 8.16.2605.3012

                                                +

                                                Versione: 8.16.2606.107


                                                Note di rilascio:
                                                • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 3cbdcdc0..23c4c2a2 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.3012 +8.16.2606.107 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index cad23318..1934059c 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.3012 + 8.16.2606.107 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From 4e632ff9f48e51b2a7504b7661a76b029a09b4ad Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 1 Jun 2026 07:59:10 +0200 Subject: [PATCH 079/102] Correzione compilazione progetti x spostamento altre classi in SPEC service method --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/Data/MpDataService.cs | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.SPEC/Data/MpDataService.cs | 542 +++++++++++++++--------------- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- Refactor_Plan.md | 22 +- 35 files changed, 315 insertions(+), 315 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index 7ac087f4..80f54f41 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2605.2912 + 8.16.2606.107 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 26e66a60..2f37a84c 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                  Versione: 8.16.2605.2912

                                                  +

                                                  Versione: 8.16.2606.107


                                                  Note di rilascio:
                                                  • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index a0cc7bd5..23c4c2a2 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2912 +8.16.2606.107 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index a3dd4bc9..7af13f75 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2912 + 8.16.2606.107 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index f76c2c99..c6af9b64 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2605.2912 + 8.16.2606.107 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index 71dc6693..f65472e3 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                                    Versione: 8.16.2605.2912

                                                    +

                                                    Versione: 8.16.2606.107


                                                    Note di rilascio:
                                                    • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index a0cc7bd5..23c4c2a2 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2912 +8.16.2606.107 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index 1acbb774..812608b3 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2912 + 8.16.2606.107 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs index f11e2a3c..7c431061 100644 --- a/MP.IOC/Data/MpDataService.cs +++ b/MP.IOC/Data/MpDataService.cs @@ -1645,7 +1645,7 @@ namespace MP.IOC.Data } else { - result = await SpecDbController.PODL_getByKey(idxPODL); + result = await SpecDbController.PODL_getByKeyAsync(idxPODL); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index e0764bb9..262d0290 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2605.2912 + 8.16.2606.107 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 7935b453..ace390ae 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                      Versione: 8.16.2605.2912

                                                      +

                                                      Versione: 8.16.2606.107


                                                      Note di rilascio:
                                                      • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index a0cc7bd5..23c4c2a2 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2912 +8.16.2606.107 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 556db6a0..4d5d949a 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2912 + 8.16.2606.107 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index ba3f8cbc..22696007 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2605.2912 + 8.16.2606.0107 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 0db0b932..b1d044b8 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                        Versione: 8.16.2605.2912

                                                        +

                                                        Versione: 8.16.2606.0107


                                                        Note di rilascio:
                                                          diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index a0cc7bd5..189d4f36 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2912 +8.16.2606.0107 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index 12562a96..ca810dd9 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2912 + 8.16.2606.0107 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index aa934ba7..fedcb911 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2605.2912 + 8.16.2606.107 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 26e66a60..2f37a84c 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                          Versione: 8.16.2605.2912

                                                          +

                                                          Versione: 8.16.2606.107


                                                          Note di rilascio:
                                                          • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index a0cc7bd5..23c4c2a2 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2912 +8.16.2606.107 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index f5459cbc..f996b216 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2912 + 8.16.2606.107 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 0a6adc88..335a8d97 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2605.2912 + 8.16.2606.0107 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index 66d0760d..f94200a8 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                                            Versione: 8.16.2605.2912

                                                            +

                                                            Versione: 8.16.2606.0107


                                                            Note di rilascio:
                                                              diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index a0cc7bd5..189d4f36 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2912 +8.16.2606.0107 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 6fd01dd3..7d49450e 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2912 + 8.16.2606.0107 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index 00b28fa0..1b35a199 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2605.2912 + 8.16.2606.107 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index 958931c8..b843ef52 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                              Versione: 8.16.2605.2912

                                                              +

                                                              Versione: 8.16.2606.107


                                                              Note di rilascio:
                                                              • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index a0cc7bd5..23c4c2a2 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2912 +8.16.2606.107 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index 0b88d126..15b83d5e 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2912 + 8.16.2606.107 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 71a644f0..f823395f 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -1,6 +1,5 @@ using EgwCoreLib.Utils; using Microsoft.EntityFrameworkCore; -using MP.Core.Conf; using MP.Core.DTO; using MP.Core.Objects; using MP.Data; @@ -85,10 +84,7 @@ namespace MP.SPEC.Data #region Public Properties - public static MpSpecController dbController { get; set; } = null!; - public static MpMongoController mongoController { get; set; } = null!; public MessagePipe BroadastMsgPipe { get; set; } = null!; - public Dictionary> currTagConf { get; set; } = new Dictionary>(); /// /// Expiry DateTime x refresh pagina parametri @@ -173,7 +169,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "AnagEventiGeneralAsync", cacheKey: $"{Utils.redisEventList}:VSEB:GENERAL", - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => { return await dbController.AnagEventiGeneralAsync() ?? new List(); @@ -224,7 +220,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "AnagStatiCommAsync", cacheKey: Utils.redisStatoCom, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.AnagStatiCommAsync() ?? new List(), tagList: [Utils.redisStatoCom] @@ -240,7 +236,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "AnagTipoArtLvAsync", cacheKey: Utils.redisTipoArt, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.AnagTipoArtLvAsync() ?? new List(), tagList: [Utils.redisTipoArt] ); @@ -255,25 +251,19 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ArticleWithDossierAsync", cacheKey: Utils.redisArtByDossier, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await Task.FromResult(dbController.ArticleWithDossier()) ?? new List(), tagList: [Utils.redisArtByDossier] ); } - public async Task ArticoliCountAsync() - { - string redisKey = $"{Utils.redisArtList}:Count"; - return await GetOrFetchAsync( - operationName: "ArticoliCountAsync", - cacheKey: redisKey, - expiration: getRandTOut(redisLongTimeCache), - fetchFunc: async () => - await dbController.ArticoliCountAsync(), - tagList: [Utils.redisArtList, $"{Utils.redisArtList}:CountAll"] - ); - } - + /// + /// Conteggio articoli data ricerca + /// + /// + /// + /// + /// public async Task ArticoliCountSearchAsync(string tipo = "*", string azienda = "*", string searchVal = "") { string sKey = string.IsNullOrWhiteSpace(tipo) ? "ALL" : tipo.Trim(); @@ -281,7 +271,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ArticoliCountSearchAsync", cacheKey: redisKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.ArticoliCountSearchAsync(tipo, azienda, searchVal), tagList: [Utils.redisArtList, $"{Utils.redisArtList}:CountSearch"] @@ -298,7 +288,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("ArticoliDeleteRecord"); string source = "DB"; bool fatto = await dbController.ArticoliDeleteRecord(currRec); - await FlushCacheArticoli(); + await FlushFusionCacheArticoli(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"ArticoliDeleteRecord | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -318,7 +308,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ArticoliGetByTipoAsync", cacheKey: redisKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.ArticoliGetByTipoAsync(tipo, azienda) ?? new List(), tagList: [Utils.redisArtList, $"{Utils.redisArtList}:Tipo"] @@ -340,7 +330,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ArticoliGetSearchAsync", cacheKey: redisKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal) ?? new List(), tagList: [Utils.redisArtList, $"{Utils.redisArtList}:Search"] @@ -357,7 +347,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ArticoliInKitAsync", cacheKey: redisKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.ArticoliInKitAsync() ?? new List(), tagList: [Utils.redisArtList, $"{Utils.redisArtList}:InKit"] @@ -374,7 +364,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("ArticoliUpdateRecord"); string source = "DB"; bool fatto = await dbController.ArticoliUpdateRecord(currRec); - await FlushCacheArticoli(); + await FlushFusionCacheArticoli(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"ArticoliUpdateRecord | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -450,7 +440,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ConfigGetAllAsync", cacheKey: Utils.redisConfAll, - expiration: getRandTOut(redisLongTimeCache * 2), + expiration: GetRandTOut(redisLongTimeCache * 2), fetchFunc: async () => await dbController.ConfigGetAllAsync() ?? new List(), tagList: [Utils.redisConfAll] ); @@ -464,7 +454,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("ConfigResetCacheAsync"); string source = "REDIS"; - await FlushCacheConfig(); + await FlushFusionCacheConfig(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"ConfigResetCacheAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -502,7 +492,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("ConfigUpdateAsync"); string source = "DB"; var updRes = await dbController.ConfigUpdateAsync(updRec); - await FlushCacheConfig(); + await FlushFusionCacheConfig(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"ConfigUpdateAsync Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -578,7 +568,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "DossiersGetLastFiltAsync", cacheKey: currKey, - expiration: getRandTOut(redisLongTimeCache * 5), + expiration: GetRandTOut(redisLongTimeCache * 5), fetchFunc: async () => await dbController.DossiersGetLastFiltAsync(IdxMacchina, CodArticolo, DtStart, DtEnd, MaxRec) ?? new List(), tagList: [Utils.redisDossByMac] ); @@ -652,7 +642,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ElencoAziendeAsync", cacheKey: $"{Utils.redisAnagGruppi}:Aziende", - expiration: getRandTOut(redisLongTimeCache * 2), + expiration: GetRandTOut(redisLongTimeCache * 2), fetchFunc: async () => await dbController.AnagGruppiAziendeAsync() ?? new List(), tagList: [Utils.redisAnagGruppi, $"{Utils.redisAnagGruppi}:Aziende"] @@ -668,7 +658,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ElencoGruppiFaseAsync", cacheKey: $"{Utils.redisAnagGruppi}:FASE", - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.AnagGruppiFaseAsync() ?? new List(), tagList: [Utils.redisAnagGruppi] ); @@ -683,7 +673,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ElencoLinkAsync", cacheKey: Utils.redisLinkMenu, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.ElencoLinkAsync() ?? new List(), tagList: [Utils.redisLinkMenu] ); @@ -698,7 +688,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ElencoRepartiDtoAsync", cacheKey: $"{Utils.redisAnagGruppi}:REPARTO", - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.AnagGruppiRepartoDtoAsync() ?? new(), tagList: [Utils.redisAnagGruppi] ); @@ -759,52 +749,6 @@ namespace MP.SPEC.Data return result; } - /// - /// Esegue flush memoria redis dato keyVal, async - /// - /// - /// - public async Task ExecFlushRedisPatternAsync(RedisValue pat2Flush) - { - bool answ = false; - using var activity = ActivitySource.StartActivity("ExecFlushRedisPatternAsync"); - string source = "REDIS"; - var masterEndpoint = redisConn.GetEndPoints() - .Where(ep => redisConn.GetServer(ep).IsConnected && !redisConn.GetServer(ep).IsReplica) - .FirstOrDefault(); - - // sepattern è "*" elimino intero DB... - if (masterEndpoint != null && (pat2Flush.Equals(new RedisValue("*")) || pat2Flush == RedisValue.Null)) - { - redisConn.GetServer(masterEndpoint).FlushDatabase(database: redisDb.Database); - } - else - { - var server = redisConn.GetServer(masterEndpoint); - var keys = server.Keys(database: redisDb.Database, pattern: pat2Flush, pageSize: 1000); - - var deleteTasks = new List(); - foreach (var key in keys) - { - deleteTasks.Add(redisDb.KeyDeleteAsync(key)); - if (deleteTasks.Count >= 1000) - { - await Task.WhenAll(deleteTasks); - deleteTasks.Clear(); - } - } - if (deleteTasks.Count > 0) - { - await Task.WhenAll(deleteTasks); - } - } - answ = true; - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"ExecFlushRedisPatternAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return answ; - } - /// /// Flush cache relativa a MP-IO x dati ODL /// @@ -842,7 +786,7 @@ namespace MP.SPEC.Data // effettuo merge statistiche... await ProcDedupStatMergeAsync(procStats); // svuoto cache - await FlushCacheFluxLog(); + await FlushFusionCacheFluxLog(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"FluxLogDataReduxAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -908,7 +852,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "FluxLogParetoAsync", cacheKey: redKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.FluxLogParetoAsync(idxMacchina, dtFrom, dtTo) ?? new List(), tagList: [Utils.redisParetoFLKey] ); @@ -930,7 +874,7 @@ namespace MP.SPEC.Data string source = "DB"; await dbController.ForceDbMaint(doExec, doUpdStat, doSave, minPgCnt, minAvgFrag, maxAvgFragReb); // svuoto cache - await FlushCacheFluxLog(); + await FlushFusionCacheFluxLog(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"ForceDbMaint | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -947,6 +891,10 @@ namespace MP.SPEC.Data return FlushFusionCacheAsync(); } + /// + /// Cancellazione RedisCache forzata + /// + /// public async Task ForceFlushRedisCache() { using var activity = ActivitySource.StartActivity("ForceFlushRedisCache"); @@ -972,7 +920,7 @@ namespace MP.SPEC.Data bool result = false; result = await dbController.Grp2MaccDeleteAsync(rec2del); // elimino cache redis... - await FlushCacheMacGrp(); + await FlushFusionCacheMacGrp(); activity?.SetTag("data.source", "DB"); activity?.Stop(); LogTrace($"Grp2MaccDeleteAsync | CodGruppo {rec2del.CodGruppo} | IdxMacc {rec2del.IdxMacchina} | {activity?.Duration.TotalMilliseconds}ms"); @@ -990,7 +938,7 @@ namespace MP.SPEC.Data bool result = false; result = await dbController.Grp2MaccInsertAsync(upsRec); // elimino cache redis... - await FlushCacheMacGrp(); + await FlushFusionCacheMacGrp(); activity?.SetTag("data.source", "DB"); activity?.Stop(); LogTrace($"Grp2MaccInsertAsync | CodGruppo {upsRec.CodGruppo} | IdxMacc {upsRec.IdxMacchina} | {activity?.Duration.TotalMilliseconds}ms"); @@ -1008,7 +956,7 @@ namespace MP.SPEC.Data bool result = false; result = await dbController.Grp2OperDeleteAsync(rec2del); // elimino cache redis... - await FlushCacheOprGrp(); + await FlushFusionCacheOprGrp(); activity?.SetTag("data.source", "DB"); activity?.Stop(); LogTrace($"Grp2OperDeleteAsync | CodGruppo {rec2del.CodGruppo} | MatrOpr {rec2del.MatrOpr} | {activity?.Duration.TotalMilliseconds}ms"); @@ -1026,7 +974,7 @@ namespace MP.SPEC.Data bool result = false; result = await dbController.Grp2OperInsertAsync(upsRec); // elimino cache redis... - await FlushCacheOprGrp(); + await FlushFusionCacheOprGrp(); activity?.SetTag("data.source", "DB"); activity?.Stop(); LogTrace($"Grp2OperInsertAsync | CodGruppo {upsRec.CodGruppo} | MatrOpr {upsRec.MatrOpr} | {activity?.Duration.TotalMilliseconds}ms"); @@ -1056,7 +1004,7 @@ namespace MP.SPEC.Data // salvo bool fatto = await dbController.IstKitDeleteAsync(currRecord); // svuoto cache - await FlushKitCache(); + await FlushFusionCacheKit(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"IstKitDeleteAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -1075,7 +1023,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "IstKitFiltAsync", cacheKey: currKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.IstKitFiltAsync(keyKit, keyExtOrd) ?? new List(), tagList: [Utils.redisKitInst] ); @@ -1093,7 +1041,7 @@ namespace MP.SPEC.Data // salvo bool fatto = await dbController.IstKitInsertByWKSAsync(CodArtParent, KeyFilt); // svuoto cache - await FlushKitCache(); + await FlushFusionCacheKit(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"IstKitInsertByWKSAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -1111,7 +1059,7 @@ namespace MP.SPEC.Data // salvo bool fatto = await dbController.IstKitUpsertAsync(currRecord); // svuoto cache - await FlushKitCache(); + await FlushFusionCacheKit(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"IstKitUpsertAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -1129,7 +1077,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ListGiacenzeAsync", cacheKey: currKey, - expiration: getRandTOut(redisShortTimeCache), + expiration: GetRandTOut(redisShortTimeCache), fetchFunc: async () => await dbController.ListGiacenzeAsync(IdxOdl) ?? new List(), tagList: [Utils.redisGiacenzaList] ); @@ -1148,7 +1096,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ListPODL_ByCodArtAsync", cacheKey: currKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.ListPODL_ByCodArtAsync(CodArticolo, OnlyAvail) ?? new(), tagList: [Utils.redisPOdlByCodArt] ); @@ -1167,7 +1115,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "MacchineGetFiltAsync", cacheKey: redisKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.MacchineGetFiltAsync(codGruppo) ?? new List(), @@ -1186,7 +1134,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "MacchineRecipeArchiveAsync", cacheKey: currKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => { var machineList = await MacchineGetFiltAsync("*"); @@ -1208,7 +1156,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "MacchineRecipeConfAsync", cacheKey: currKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => { var machineList = await MacchineGetFiltAsync("*"); @@ -1231,7 +1179,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "MacchineWithFluxAsync", cacheKey: currKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.MacchineWithFluxAsync(dtStart, dtEnd) ?? new List(), tagList: [Utils.redisMacByFlux] ); @@ -1244,7 +1192,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "MachineWithOdlAsync", cacheKey: redisKey, - expiration: getRandTOut(redisShortTimeCache), + expiration: GetRandTOut(redisShortTimeCache), fetchFunc: async () => { var rawData = await dbController.OdlGetCurrentAsync(); @@ -1270,12 +1218,12 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "MachIobConfAsync", cacheKey: redisKey, - expiration: getRandTOut(redisShortTimeCache), + expiration: GetRandTOut(redisShortTimeCache), fetchFunc: async () => { Dictionary result = new Dictionary(); // cerco in redis... - string currKey = redHashMpIO($"IOB:{IdxMacchina}:MachIobConfAsync"); + string currKey = RedHashMpIO($"IOB:{IdxMacchina}:MachIobConfAsync"); if (await redisDb.KeyExistsAsync(currKey)) { result = (await redisDb.HashGetAllAsync(currKey)) @@ -1332,7 +1280,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "OdlByBatchAsync", cacheKey: Utils.redisOdlByBatch, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.OdlByBatchAsync(BatchSel), tagList: [Utils.redisOdlByBatch] ); @@ -1349,7 +1297,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "OdlByKeyAsync", cacheKey: currKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.OdlByKeyAsync(IdxOdl), tagList: [Utils.redisOdlByKey] ); @@ -1409,7 +1357,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "OdlListGetFiltAsync", cacheKey: currKey, - expiration: getRandTOut(redisShortTimeCache), + expiration: GetRandTOut(redisShortTimeCache), fetchFunc: async () => await dbController.ListODLFiltAsync(inCorso, codArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate) ?? new(), tagList: [Utils.redisOdlList] ); @@ -1426,7 +1374,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "OdlStatsAsync", cacheKey: currKey, - expiration: getRandTOut(redisShortTimeCache), + expiration: GetRandTOut(redisShortTimeCache), fetchFunc: async () => await dbController.OdlGetStatAsync(IdxOdl) ?? new(), tagList: [Utils.redisOdlStats] ); @@ -1445,7 +1393,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "OperatoriGetFiltAsync", cacheKey: currKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.OperatoriGetFiltAsync(codGruppo) ?? new List(), tagList: [Utils.redisOprList] ); @@ -1462,7 +1410,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "ParametriGetFiltAsync", cacheKey: currKey, - expiration: getRandTOut(redisShortTimeCache), + expiration: GetRandTOut(redisShortTimeCache), fetchFunc: async () => await dbController.ParametriGetFiltAsync(IdxMacchina) ?? new(), tagList: [Utils.redisFluxByMac] ); @@ -1548,7 +1496,7 @@ namespace MP.SPEC.Data string source = "DB+REDIS"; var dbResult = await dbController.PODLDeleteRecord(currRec); // elimino cache redis... - await FlushCachePOdl(); + await FlushFusionCachePOdl(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"POdlDeleteRecord | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -1566,7 +1514,7 @@ namespace MP.SPEC.Data string source = "DB+REDIS"; var dbResult = await dbController.PODL_startSetup(currRec, 0, 1, 1, "", DateTime.Now); // elimino cache redis... - await FlushCachePOdl(); + await FlushFusionCachePOdl(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"POdlDoSetup | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -1618,7 +1566,7 @@ namespace MP.SPEC.Data // salvo fatto = await dbController.PodlIstKitDeleteAsync(IdxPODL); // svuoto cache - await FlushCachePOdl(); + await FlushFusionCachePOdl(); activity?.SetTag("data.source", "DB"); return fatto; } @@ -1634,7 +1582,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "POdlListByKitParentAsync", cacheKey: currKey, - expiration: getRandTOut(redisShortTimeCache), + expiration: GetRandTOut(redisShortTimeCache), fetchFunc: async () => await dbController.ListPODL_ByKitParentAsync(IdxPodlParent) ?? new(), tagList: [Utils.redisPOdlList] ); @@ -1656,7 +1604,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "POdlListGetFiltAsync", cacheKey: currKey, - expiration: getRandTOut(redisShortTimeCache), + expiration: GetRandTOut(redisShortTimeCache), fetchFunc: async () => await dbController.ListPODLFiltAsync(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate) ?? new List(), tagList: [Utils.redisPOdlList] ); @@ -1679,7 +1627,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "POdlToKitListGetFiltAsync", cacheKey: redisKey, - expiration: getRandTOut(redisShortTimeCache * 5), + expiration: GetRandTOut(redisShortTimeCache * 5), fetchFunc: async () => await dbController.ListPODL_KitFiltAsync( lanciato, @@ -1706,7 +1654,7 @@ namespace MP.SPEC.Data bool answ = false; answ = await dbController.PODL_updateRecipe(idxPODL, recipeName); // reset redis... - await FlushCachePOdl(); + await FlushFusionCachePOdl(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"POdlUpdateRecipe | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -1724,7 +1672,7 @@ namespace MP.SPEC.Data string source = "DB"; var dbResult = await dbController.PODLUpdateRecordAsync(currRec); // elimino cache redis... - await FlushCachePOdl(); + await FlushFusionCachePOdl(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"POdlUpdateRecord | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -1785,7 +1733,7 @@ namespace MP.SPEC.Data string source = "MONGO"; bool answ = false; answ = await mongoController.RecipeSetByPODL(currRecord); - await FlushCachePOdl(); + await FlushFusionCachePOdl(); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"RecipeSetByPODL | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -1885,7 +1833,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "StatoMacchinaAsync", cacheKey: currKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.StatoMacchinaAsync(idxMacchina) ?? new(), tagList: [Utils.redisStatoMacch] ); @@ -1922,7 +1870,7 @@ namespace MP.SPEC.Data return await GetOrFetchAsync( operationName: "TemplateKitFiltAsync", cacheKey: currKey, - expiration: getRandTOut(redisLongTimeCache), + expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await dbController.TemplateKitFiltAsync(codParent, codChild) ?? new List(), tagList: [Utils.redisKitTempl] ); @@ -2087,154 +2035,6 @@ namespace MP.SPEC.Data #endregion Public Methods - #region Protected Methods - - protected async Task FlushCacheArticoli() - { - using var activity = ActivitySource.StartActivity("FlushCacheArticoli"); - string source = "FUSION"; - bool answ = await FlushFusionCacheAsync(new List() { Utils.redisArtList, Utils.redisArtByDossier }); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"FlushCacheArticoli | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return answ; - } - - protected async Task FlushCacheConfig() - { - using var activity = ActivitySource.StartActivity("FlushCacheConfig"); - string source = "FUSION"; - bool answ = await FlushFusionCacheAsync(new List() { Utils.redisConfKey }); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"FlushCacheConfig | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return answ; - } - - /// - /// Reset macchine e gruppi - /// - protected async Task FlushCacheMacGrp() - { - using var activity = ActivitySource.StartActivity("FlushCacheMacGrp"); - string source = "FUSION"; - bool answ = await FlushFusionCacheAsync(new List { Utils.redisAnagGruppi, Utils.redisMacList }); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"FlushCacheMacGrp | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return answ; - } - - /// - /// Reset cache operatori e gruppi - /// - protected async Task FlushCacheOprGrp() - { - using var activity = ActivitySource.StartActivity("FlushCacheOprGrp"); - string source = "FUSION"; - bool answ = await FlushFusionCacheAsync(new List { Utils.redisAnagGruppi, Utils.redisOprList }); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"FlushCacheOprGrp | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return answ; - } - - protected async Task FlushCachePOdl() - { - using var activity = ActivitySource.StartActivity("FlushCachePOdl"); - string source = "FUSION"; - bool answ = await FlushFusionCacheAsync(new List() { Utils.redisXdlData, Utils.redisPOdlByOdl, Utils.redisPOdlByPOdl, Utils.redisPOdlList }); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"FlushCachePOdl | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return answ; - } - - /// - /// Cancellazione FusionCache (totale) - /// - /// - protected async Task FlushFusionCacheAsync() - { - await _cache.ClearAsync(allowFailSafe: false); - _configData.Clear(); - _artCacheExpiry = DateTime.Now.AddHours(-1); - return true; - } - - /// - /// Cancellazione FusionCache dato singolo tag - /// - /// - protected async Task FlushFusionCacheAsync(string tag) - { - if (string.IsNullOrWhiteSpace(tag)) return false; - - await _cache.RemoveByTagAsync(tag); - _configData.Clear(); - return true; - } - - /// - /// Cancellazione FusionCache dato elenco tags - /// - /// - protected async Task FlushFusionCacheAsync(List listTags) - { - if (listTags == null || listTags.Count == 0) return false; - - // Generiamo i Task di rimozione ed eseguiamoli in parallelo su Redis/L1 - var tasks = listTags - .Where(tag => !string.IsNullOrWhiteSpace(tag)) - .Select(tag => _cache.RemoveByTagAsync(tag).AsTask()); - - await Task.WhenAll(tasks); - - _configData.Clear(); - return true; - } - - protected async Task FlushKitCache() - { - using var activity = ActivitySource.StartActivity("FlushKitCache"); - string source = "FUSION"; - bool answ = await FlushFusionCacheAsync(new List() { Utils.redisPOdlList, Utils.redisKitInst, Utils.redisKitWip, Utils.redisKitScore, Utils.redisPOdlByCodArt }); - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"FlushKitCache | {source} | {activity?.Duration.TotalMilliseconds}ms"); - return answ; - } - - /// - /// Restituisce un timeout dal valore secondi richiesti + tempo random +/-3% - /// - /// - /// - protected TimeSpan getRandTOut(double durationSec) - { - double noise = (rand.NextDouble() * 0.06) - 0.03; - double rValue = durationSec * (1 + noise); - return TimeSpan.FromSeconds(rValue); - } - - /// - /// Merge statistiche DB Maintenance - /// - /// - /// - protected async Task RecDbMaintStatAsync(TimeSpan duration) - { - Dictionary actStats = await DbDedupStatsAsync(); - // aggiungo record! - actStats.Add(DateTime.Now, duration.TotalSeconds); - // salvo NUOVO record statistiche - string currKey = $"{Utils.redisStatsDbMaint}"; - var rawData = JsonConvert.SerializeObject(actStats); - return await redisDb.StringSetAsync(currKey, rawData); - } - - #endregion Protected Methods - #region Private Fields /// @@ -2269,8 +2069,6 @@ namespace MP.SPEC.Data /// private HashSet _listCodArtUsed = new(); - private string canCacheParametri = ""; - private string MpIoNS = ""; private Random rand = new Random(); @@ -2309,6 +2107,14 @@ namespace MP.SPEC.Data #endregion Private Fields + #region Private Properties + + private static MpSpecController dbController { get; set; } = null!; + + private static MpMongoController mongoController { get; set; } = null!; + + #endregion Private Properties + #region Private Methods /// @@ -2327,14 +2133,176 @@ namespace MP.SPEC.Data } } - private async Task FlushCacheFluxLog() + /// + /// Esegue flush memoria redis dato keyVal, async + /// + /// + /// + private async Task ExecFlushRedisPatternAsync(RedisValue pat2Flush) { - using var activity = ActivitySource.StartActivity("FlushCacheFluxLog"); + bool answ = false; + using var activity = ActivitySource.StartActivity("ExecFlushRedisPatternAsync"); + string source = "REDIS"; + var masterEndpoint = redisConn.GetEndPoints() + .Where(ep => redisConn.GetServer(ep).IsConnected && !redisConn.GetServer(ep).IsReplica) + .FirstOrDefault(); + + // sepattern è "*" elimino intero DB... + if (masterEndpoint != null && (pat2Flush.Equals(new RedisValue("*")) || pat2Flush == RedisValue.Null)) + { + redisConn.GetServer(masterEndpoint).FlushDatabase(database: redisDb.Database); + } + else + { + var server = redisConn.GetServer(masterEndpoint); + var keys = server.Keys(database: redisDb.Database, pattern: pat2Flush, pageSize: 1000); + + var deleteTasks = new List(); + foreach (var key in keys) + { + deleteTasks.Add(redisDb.KeyDeleteAsync(key)); + if (deleteTasks.Count >= 1000) + { + await Task.WhenAll(deleteTasks); + deleteTasks.Clear(); + } + } + if (deleteTasks.Count > 0) + { + await Task.WhenAll(deleteTasks); + } + } + answ = true; + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"ExecFlushRedisPatternAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } + + private async Task FlushFusionCacheArticoli() + { + using var activity = ActivitySource.StartActivity("FlushFusionCacheArticoli"); + string source = "FUSION"; + bool answ = await FlushFusionCacheAsync(new List() { Utils.redisArtList, Utils.redisArtByDossier }); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"FlushFusionCacheArticoli | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } + + /// + /// Cancellazione FusionCache (totale) + /// + /// + private async Task FlushFusionCacheAsync() + { + await _cache.ClearAsync(allowFailSafe: false); + _configData.Clear(); + _artCacheExpiry = DateTime.Now.AddHours(-1); + return true; + } + + /// + /// Cancellazione FusionCache dato singolo tag + /// + /// + private async Task FlushFusionCacheAsync(string tag) + { + if (string.IsNullOrWhiteSpace(tag)) return false; + + await _cache.RemoveByTagAsync(tag); + _configData.Clear(); + return true; + } + + /// + /// Cancellazione FusionCache dato elenco tags + /// + /// + private async Task FlushFusionCacheAsync(List listTags) + { + if (listTags == null || listTags.Count == 0) return false; + + // Generiamo i Task di rimozione ed eseguiamoli in parallelo su Redis/L1 + var tasks = listTags + .Where(tag => !string.IsNullOrWhiteSpace(tag)) + .Select(tag => _cache.RemoveByTagAsync(tag).AsTask()); + + await Task.WhenAll(tasks); + + _configData.Clear(); + return true; + } + + private async Task FlushFusionCacheConfig() + { + using var activity = ActivitySource.StartActivity("FlushFusionCacheConfig"); + string source = "FUSION"; + bool answ = await FlushFusionCacheAsync(new List() { Utils.redisConfKey }); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"FlushFusionCacheConfig | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } + + private async Task FlushFusionCacheFluxLog() + { + using var activity = ActivitySource.StartActivity("FlushFusionCacheFluxLog"); string source = "FUSION"; bool answ = await FlushFusionCacheAsync(new List() { Utils.redisFluxLogFilt, Utils.redisParetoFLKey }); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"FlushCacheFluxLog | {source} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"FlushFusionCacheFluxLog | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } + + private async Task FlushFusionCacheKit() + { + using var activity = ActivitySource.StartActivity("FlushFusionCacheKit"); + string source = "FUSION"; + bool answ = await FlushFusionCacheAsync(new List() { Utils.redisPOdlList, Utils.redisKitInst, Utils.redisKitWip, Utils.redisKitScore, Utils.redisPOdlByCodArt }); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"FlushFusionCacheKit | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } + + /// + /// Reset macchine e gruppi + /// + private async Task FlushFusionCacheMacGrp() + { + using var activity = ActivitySource.StartActivity("FlushFusionCacheMacGrp"); + string source = "FUSION"; + bool answ = await FlushFusionCacheAsync(new List { Utils.redisAnagGruppi, Utils.redisMacList }); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"FlushFusionCacheMacGrp | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } + + /// + /// Reset cache operatori e gruppi + /// + private async Task FlushFusionCacheOprGrp() + { + using var activity = ActivitySource.StartActivity("FlushFusionCacheOprGrp"); + string source = "FUSION"; + bool answ = await FlushFusionCacheAsync(new List { Utils.redisAnagGruppi, Utils.redisOprList }); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"FlushFusionCacheOprGrp | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return answ; + } + + private async Task FlushFusionCachePOdl() + { + using var activity = ActivitySource.StartActivity("FlushFusionCachePOdl"); + string source = "FUSION"; + bool answ = await FlushFusionCacheAsync(new List() { Utils.redisXdlData, Utils.redisPOdlByOdl, Utils.redisPOdlByPOdl, Utils.redisPOdlList }); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"FlushFusionCachePOdl | {source} | {activity?.Duration.TotalMilliseconds}ms"); return answ; } @@ -2405,6 +2373,18 @@ namespace MP.SPEC.Data return final!; } + /// + /// Restituisce un timeout dal valore secondi richiesti + tempo random +/-3% + /// + /// + /// + private TimeSpan GetRandTOut(double durationSec) + { + double noise = (rand.NextDouble() * 0.06) - 0.03; + double rValue = durationSec * (1 + noise); + return TimeSpan.FromSeconds(rValue); + } + /// /// Helper trace messaggio log (SE abilitato) /// @@ -2462,7 +2442,23 @@ namespace MP.SPEC.Data return await redisDb.StringSetAsync(currKey, rawData); } - private string redHashMpIO(string keyName) + /// + /// Merge statistiche DB Maintenance + /// + /// + /// + private async Task RecDbMaintStatAsync(TimeSpan duration) + { + Dictionary actStats = await DbDedupStatsAsync(); + // aggiungo record! + actStats.Add(DateTime.Now, duration.TotalSeconds); + // salvo NUOVO record statistiche + string currKey = $"{Utils.redisStatsDbMaint}"; + var rawData = JsonConvert.SerializeObject(actStats); + return await redisDb.StringSetAsync(currKey, rawData); + } + + private string RedHashMpIO(string keyName) { string result = keyName; try @@ -2471,7 +2467,7 @@ namespace MP.SPEC.Data } catch (Exception exc) { - Log.Error($"Errore in redHashMpIO{Environment.NewLine}{exc}"); + Log.Error($"Errore in RedHashMpIO{Environment.NewLine}{exc}"); } return result; diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index fb313057..55f50d46 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2605.2912 + 8.16.2606.0107 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index 1b148368..995d1a5a 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                                                Versione: 8.16.2605.2912

                                                                +

                                                                Versione: 8.16.2606.0107


                                                                Note di rilascio:
                                                                  diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index a0cc7bd5..189d4f36 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2605.2912 +8.16.2606.0107 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index 49b25e7c..939d6d59 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2605.2912 + 8.16.2606.0107 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false diff --git a/Refactor_Plan.md b/Refactor_Plan.md index 12a5cf0a..034e4602 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -9,7 +9,7 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa ## Strategia di Migrazione - **Metodo Standard**: `GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tagList)`. -- **Invalidazione**: Utilizzare i tag tramite `FlushCacheByTagAsync`. +- **Invalidazione**: Utilizzare i tag tramite `FlushFusionCacheByTagAsync`. ## Stato Avanzamento @@ -19,7 +19,7 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa ### Fase 2: Refactoring Metodi di Lettura (Cache-aside) (In corso) -#### ✅ Metodi Migrati (Usano già `GetOrFetchAsync`, `FusionCache.GetOrSet` o `FlushCacheByTagAsync`) +#### ✅ Metodi Migrati (Usano già `GetOrFetchAsync`, `FusionCache.GetOrSet` o `FlushFusionCacheByTagAsync`) - `AnagEventiGeneralAsync` - `AnagStatiCommAsync` - `AnagTipoArtLvAsync` @@ -65,15 +65,17 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - `Grp2MaccInsertAsync` (Migrato con tag invalidazione) - `Grp2OperDeleteAsync` (Migrato con tag invalidazione) - `Grp2OperInsertAsync` (Migrato con tag invalidazione) +- `ArticoliDeleteRecord` (Migrato con `FlushCacheArticoli`) +- `ArticoliUpdateRecord` (Migrato con `FlushCacheArticoli`) +- `DossiersDeleteRecordAsync` (Migrato con tag invalidazione) +- `DossiersTakeParamsSnapshotLast` (Migrato con tag invalidazione) +- `DossiersInsert` (Migrato con tag invalidazione) +- `DossiersUpdateValoreAsync` (Migrato con tag invalidazione) +- `ElencoRepartiDTO` (Migrato) -#### 🛠️ Metodi da Migrare (Usano ancora Redis/DB manuale) +#### 🛠️ Metodi da Migrare (Usano ancora Redis/DB manuale o pattern non standard per Fusion) - [ ] Migrazione di `ActionGetReq` (linea 110: usa `redisDb.StringGetAsync`). - [ ] Migrazione di `ActionSetReq` (linea 136: usa `BroadastMsgPipe.saveAndSendMessage`). -- [ ] Migrazione di `ArticoliDeleteRecord`/`UpdateRecord` (linea 296/372: usa `resetCacheArticoli`). -- [ ] Migrazione di `DbDedupStats` (linea 516: usa `redisDb.StringGet`). -- [ ] Migrazione di `DossiersDeleteRecord` (linea 551: usa `ExecFlushRedisPatternAsync`). -- [ ] Migrazione di `DossiersTakeParamsSnapshotLast` (linea 610: usa `ExecFlushRedisPatternAsync`). -- [ ] Migrazione di `ElencoRepartiDTO` (linea 697: usa `redisDb.StringGet` e `StringSet`). - [ ] Migrazione di `PodlIstKitDelete` (linea 1760: usa `ExecFlushRedisPattern` sincrono). - [ ] Migrazione di `POdlListByKitParent` (linea 1781: usa `redisDb.StringGet` e `StringSet`). - [ ] Migrazione di `POdlGetByKey` (linea 1662: usa `redisDb.StringGet` e `StringSet`). @@ -82,7 +84,7 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - [ ] Migrazione di `ProcFLStats` (linea 1853: usa `redisDb.StringGet`). - [ ] Migrazione di `RecDbMaintStat` (linea 2451: usa `redisDb.StringSet`). -*(Nota: Il vecchio metodo `VocabolarioGetAll` e la gestione manuale del dizionario sono stati rimossi in favore di `Traduci` con FusionCache).* +*(Nota: I metodi `DbDedupStatsAsync` e `RecDbMaintStatAsync` sono gestiti direttamente su Redis in modo persistente e non sono target della migrazione a FusionCache).* ### Fase 4: Verifica - [ ] Verificare la compilazione della soluzione tramite script PowerShell. @@ -98,3 +100,5 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa + + From b19f21fdffd15f0df8350799779d3d2f52bdaf37 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 1 Jun 2026 08:25:28 +0200 Subject: [PATCH 080/102] Trasformazione async metodi SaveSendMessages --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.Data/MessagePipe.cs | 14 +++++++------- MP.Data/Services/MonDataFeeder.cs | 6 +++--- MP.Data/Services/TabDataFeeder.cs | 6 +++--- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.SPEC/Components/AskCloseOdl.razor.cs | 4 ++-- MP.SPEC/Data/MpDataService.cs | 12 +++++++----- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Test.razor.cs | 4 ++-- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- Refactor_Plan.md | 17 ++++++++++------- 43 files changed, 70 insertions(+), 65 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index 80f54f41..108f2d0c 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2606.107 + 8.16.2606.108 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 2f37a84c..87c10ba8 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                  Versione: 8.16.2606.107

                                                                  +

                                                                  Versione: 8.16.2606.108


                                                                  Note di rilascio:
                                                                  • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 23c4c2a2..39fc2c3d 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.107 +8.16.2606.108 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index 7af13f75..baac9408 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.107 + 8.16.2606.108 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.Data/MessagePipe.cs b/MP.Data/MessagePipe.cs index 1094cc72..e306f874 100644 --- a/MP.Data/MessagePipe.cs +++ b/MP.Data/MessagePipe.cs @@ -3,7 +3,7 @@ using StackExchange.Redis; using System; using System.Collections.Generic; using System.Diagnostics; -using System.Threading.Channels; +using System.Threading.Tasks; namespace MP.Data { @@ -44,17 +44,17 @@ namespace MP.Data ///
                                                                /// Chiave REDIS x salvare valore /// Messaggio serializzato da inviare - public bool saveAndSendMessage(string memKey, string message) + public async Task SaveAndSendMessageAsync(string memKey, string message) { bool answ = false; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); // invio notifica tramite il canale richiesto - answ = sendMessage(message); + answ = await SendMessageAsync(message); if (redisDb != null) { - redisDb.StringSetAsync(memKey, message); + await redisDb.StringSetAsync(memKey, message); } stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; @@ -68,7 +68,7 @@ namespace MP.Data } if (enableLog || numSent[memKey] > 30) { - Log.Info($"saveAndSendMessage| mKey {memKey} x {numSent[memKey]} | {message.Length} size | {ts.TotalMilliseconds} ms"); + Log.Info($"SaveAndSendMessageAsync| mKey {memKey} x {numSent[memKey]} | {message.Length} size | {ts.TotalMilliseconds} ms"); numSent[memKey] = 0; } @@ -80,7 +80,7 @@ namespace MP.Data ///
                                                                /// /// - public bool sendMessage(string newMess) + public async Task SendMessageAsync(string newMess) { bool answ = false; if (!string.IsNullOrEmpty(_channel)) @@ -89,7 +89,7 @@ namespace MP.Data ISubscriber sub = redis.GetSubscriber(); sub.Publish(_channel, newMess); #endif - var numCli = redisSub.Publish(rChannel, newMess); + var numCli = await redisSub.PublishAsync(rChannel, newMess); answ = numCli > 0; } return answ; diff --git a/MP.Data/Services/MonDataFeeder.cs b/MP.Data/Services/MonDataFeeder.cs index 15c151a9..697c0d69 100644 --- a/MP.Data/Services/MonDataFeeder.cs +++ b/MP.Data/Services/MonDataFeeder.cs @@ -113,17 +113,17 @@ namespace MP.Data.Services if (resto == 0) { // invio in channel blink il segnale - blinkPipe.sendMessage("true"); + blinkPipe.SendMessageAsync("true"); Log.Debug("Elapsed Fast Timer Blink"); } else { // invio in channel blink segnale false - blinkPipe.sendMessage("false"); + blinkPipe.SendMessageAsync("false"); // rileggo dati... var newData = await MseGetAll(); // invio tramite la pipe... - dataPipe.sendMessage(JsonConvert.SerializeObject(newData)); + dataPipe.SendMessageAsync(JsonConvert.SerializeObject(newData)); Log.Debug("Elapsed Fast Timer reload"); } }); diff --git a/MP.Data/Services/TabDataFeeder.cs b/MP.Data/Services/TabDataFeeder.cs index 8d4c00a2..f91090de 100644 --- a/MP.Data/Services/TabDataFeeder.cs +++ b/MP.Data/Services/TabDataFeeder.cs @@ -133,17 +133,17 @@ namespace MP.Data.Services if (resto == 0) { // invio in channel blink il segnale - blinkPipe.sendMessage("true"); + blinkPipe.SendMessageAsync("true"); Log.Trace("Elapsed Fast Timer Blink"); } else { // invio in channel blink segnale false - blinkPipe.sendMessage("false"); + blinkPipe.SendMessageAsync("false"); // rileggo dati... var newData = await MseGetAll(); // invio tramite la pipe... - dataPipe.sendMessage(JsonConvert.SerializeObject(newData)); + dataPipe.SendMessageAsync(JsonConvert.SerializeObject(newData)); Log.Trace("Elapsed Fast Timer reload"); } }); diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index c6af9b64..c417100a 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2606.107 + 8.16.2606.108 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index f65472e3..b1927062 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                                                Versione: 8.16.2606.107

                                                                +

                                                                Versione: 8.16.2606.108


                                                                Note di rilascio:
                                                                • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index 23c4c2a2..39fc2c3d 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.107 +8.16.2606.108 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index 812608b3..b202c947 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.107 + 8.16.2606.108 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 262d0290..b8ee4b5e 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2606.107 + 8.16.2606.108 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index ace390ae..45f2d9dc 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                                  Versione: 8.16.2606.107

                                                                  +

                                                                  Versione: 8.16.2606.108


                                                                  Note di rilascio:
                                                                  • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 23c4c2a2..39fc2c3d 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.107 +8.16.2606.108 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 4d5d949a..11eeec80 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.107 + 8.16.2606.108 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 22696007..7c486e88 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2606.0107 + 8.16.2606.0108 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index b1d044b8..293c48e3 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                                    Versione: 8.16.2606.0107

                                                                    +

                                                                    Versione: 8.16.2606.0108


                                                                    Note di rilascio:
                                                                      diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 189d4f36..83bdfcd4 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0107 +8.16.2606.0108 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index ca810dd9..1ac7b2c6 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0107 + 8.16.2606.0108 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index fedcb911..9f766193 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2606.107 + 8.16.2606.108 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 2f37a84c..87c10ba8 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                      Versione: 8.16.2606.107

                                                                      +

                                                                      Versione: 8.16.2606.108


                                                                      Note di rilascio:
                                                                      • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 23c4c2a2..39fc2c3d 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.107 +8.16.2606.108 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index f996b216..fd37fd54 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.107 + 8.16.2606.108 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 335a8d97..9e3d5d0a 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2606.0107 + 8.16.2606.0108 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index f94200a8..62e7c681 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                                                        Versione: 8.16.2606.0107

                                                                        +

                                                                        Versione: 8.16.2606.0108


                                                                        Note di rilascio:
                                                                          diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 189d4f36..83bdfcd4 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0107 +8.16.2606.0108 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 7d49450e..2cd09b01 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0107 + 8.16.2606.0108 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index 1b35a199..0740f8fc 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2606.107 + 8.16.2606.108 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index b843ef52..ea962f3b 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                                          Versione: 8.16.2606.107

                                                                          +

                                                                          Versione: 8.16.2606.108


                                                                          Note di rilascio:
                                                                          • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index 23c4c2a2..39fc2c3d 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.107 +8.16.2606.108 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index 15b83d5e..b67b2eaa 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.107 + 8.16.2606.108 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Components/AskCloseOdl.razor.cs b/MP.SPEC/Components/AskCloseOdl.razor.cs index 1defeafe..85fe627e 100644 --- a/MP.SPEC/Components/AskCloseOdl.razor.cs +++ b/MP.SPEC/Components/AskCloseOdl.razor.cs @@ -55,7 +55,7 @@ namespace MP.SPEC.Components } // eseguo chiusura finale CurrAction.IsActive = false; - MDService.ActionSetReq(CurrAction); + MDService.ActionSetReqAsync(CurrAction); await Task.Delay(1); } @@ -103,7 +103,7 @@ namespace MP.SPEC.Components } } - MDService.ActionSetReq(CurrAction); + MDService.ActionSetReqAsync(CurrAction); await Task.Delay(1); // se fatto --> ricarico! if (fatto) diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index f823395f..077b7e26 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -129,18 +129,18 @@ namespace MP.SPEC.Data ///
                                                /// /// - public bool ActionSetReq(DisplayAction? act2save) + public async Task ActionSetReqAsync(DisplayAction? act2save) { - using var activity = ActivitySource.StartActivity("ActionSetReq"); + using var activity = ActivitySource.StartActivity("ActionSetReqAsync"); string source = "REDIS"; bool fatto = false; // cerco in redis... string rawData = JsonConvert.SerializeObject(act2save); // invio broadcast + salvo in redis - BroadastMsgPipe.saveAndSendMessage(Utils.redisActionReq, rawData); + await BroadastMsgPipe.SaveAndSendMessageAsync(Utils.redisActionReq, rawData); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ActionSetReq {source} send to broadcast + Write cache: {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ActionSetReqAsync {source} send to broadcast + Write cache: {activity?.Duration.TotalMilliseconds}ms"); return fatto; } @@ -2307,7 +2307,9 @@ namespace MP.SPEC.Data } /// - /// Implementa gestione recupero cache da memoria o da obj esterno + cache memoria + tracking attività + /// Implementa gestione FusionCache+ tracking attività + /// - recupero cache da memoria o da obj esterno + cache memoria + /// - recupero da fetchFunc se mancasse + store in cache L1/L2 /// /// /// diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index d9966714..01d64cb9 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2606.107 + 8.16.2606.108 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Test.razor.cs b/MP.SPEC/Pages/Test.razor.cs index 9d489526..7f2957a3 100644 --- a/MP.SPEC/Pages/Test.razor.cs +++ b/MP.SPEC/Pages/Test.razor.cs @@ -38,7 +38,7 @@ namespace MP.SPEC.Pages CurrAction.IsActive = false; CurrAction.Topic = "Chiusura ODL"; CurrAction.Message = "Rilevato possibile fine operazioni, Vuoi chiudere la commessa?"; - MMDataService.ActionSetReq(CurrAction); + MMDataService.ActionSetReqAsync(CurrAction); await Task.Delay(1); } @@ -72,7 +72,7 @@ namespace MP.SPEC.Pages { CurrAction.DtReq = DateTime.Now; CurrAction.IsActive = true; - MMDataService.ActionSetReq(CurrAction); + MMDataService.ActionSetReqAsync(CurrAction); } #endregion Protected Methods diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 2f37a84c..87c10ba8 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                Versione: 8.16.2606.107

                                                +

                                                Versione: 8.16.2606.108


                                                Note di rilascio:
                                                • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 23c4c2a2..39fc2c3d 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.107 +8.16.2606.108 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 1934059c..60fbae64 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.107 + 8.16.2606.108 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 55f50d46..37a76526 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2606.0107 + 8.16.2606.0108 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index 995d1a5a..6363d87f 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                                  Versione: 8.16.2606.0107

                                                  +

                                                  Versione: 8.16.2606.0108


                                                  Note di rilascio:
                                                    diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 189d4f36..83bdfcd4 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0107 +8.16.2606.0108 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index 939d6d59..4e89cd4f 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0107 + 8.16.2606.0108 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false diff --git a/Refactor_Plan.md b/Refactor_Plan.md index 034e4602..89c93421 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -72,19 +72,20 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - `DossiersInsert` (Migrato con tag invalidazione) - `DossiersUpdateValoreAsync` (Migrato con tag invalidazione) - `ElencoRepartiDTO` (Migrato) +- `PodlIstKitDeleteAsync` (Migrato con tag invalidazione) +- `POdlUpdateRecipe` (Migrato con tag invalidazione) +- `POdlUpdateRecord` (Migrato con tag invalidazione) +- `POdlGetByKey` (Migrato con FusionCache) +- `POdlListByKitParentAsync` (Migrato con FusionCache) #### 🛠️ Metodi da Migrare (Usano ancora Redis/DB manuale o pattern non standard per Fusion) - [ ] Migrazione di `ActionGetReq` (linea 110: usa `redisDb.StringGetAsync`). - [ ] Migrazione di `ActionSetReq` (linea 136: usa `BroadastMsgPipe.saveAndSendMessage`). -- [ ] Migrazione di `PodlIstKitDelete` (linea 1760: usa `ExecFlushRedisPattern` sincrono). -- [ ] Migrazione di `POdlListByKitParent` (linea 1781: usa `redisDb.StringGet` e `StringSet`). -- [ ] Migrazione di `POdlGetByKey` (linea 1662: usa `redisDb.StringGet` e `StringSet`). -- [ ] Migrazione di `POdlUpdateRecipe` (linea 1814: usa `POdlFlushCache` con pattern). -- [ ] Migrazione di `POdlUpdateRecord` (linea 1836: usa `POdlFlushCache` con pattern). +- [ ] Migrazione di `DbDedupStatsAsync` (linea 516: gestione persistente su Redis, valutare se mantenere o cambiare pattern). - [ ] Migrazione di `ProcFLStats` (linea 1853: usa `redisDb.StringGet`). -- [ ] Migrazione di `RecDbMaintStat` (linea 2451: usa `redisDb.StringSet`). +- [ ] Migrazione di `RecDbMaintStatAsync` (linea 2451: gestione persistente su Redis, valutare se mantenere o cambiare pattern). -*(Nota: I metodi `DbDedupStatsAsync` e `RecDbMaintStatAsync` sono gestiti direttamente su Redis in modo persistente e non sono target della migrazione a FusionCache).* +*(Nota: I metodi `ActionGetReq`, `ActionSetReq`, `DbDedupStatsAsync`, `ProcFLStats` e `RecDbMaintStatAsync` sono stati analizzati e, dove appropriato, confermati nel loro attuale pattern di gestione Redis/DB).* ### Fase 4: Verifica - [ ] Verificare la compilazione della soluzione tramite script PowerShell. @@ -102,3 +103,5 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa + + From bd2b35b2e6c99cc008eb5a028e94688a822a7104 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 1 Jun 2026 09:37:10 +0200 Subject: [PATCH 081/102] =?UTF-8?q?Completata=20p=C3=A8ulizia=20SPEC!!!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.Data/Controllers/MpSpecController.cs | 1323 ++++++----------------- MP.Data/Controllers/MpTabController.cs | 2 +- MP.Data/Services/ListSelectDataSrv.cs | 12 +- MP.Data/Services/MonDataFeeder.cs | 6 +- MP.Data/Services/OrderDataSrv.cs | 4 +- MP.Data/Services/StatusData.cs | 2 +- MP.Data/Services/TabDataFeeder.cs | 6 +- MP.Data/Services/TabDataService.cs | 4 +- MP.Data/Services/TranslateSrv.cs | 2 +- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/Data/MpDataService.cs | 25 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.SPEC/Data/MpDataService.cs | 83 +- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/FluxLogStatus.razor.cs | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- Refactor_Plan.md | 27 +- 49 files changed, 413 insertions(+), 1157 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index 108f2d0c..104cd909 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2606.108 + 8.16.2606.109 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 87c10ba8..9d115dbc 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                    Versione: 8.16.2606.108

                                                    +

                                                    Versione: 8.16.2606.109


                                                    Note di rilascio:
                                                    • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 39fc2c3d..ce4acb58 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.108 +8.16.2606.109 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index baac9408..819108c5 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.108 + 8.16.2606.109 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecController.cs index 2bc53fc1..7e42b2f1 100644 --- a/MP.Data/Controllers/MpSpecController.cs +++ b/MP.Data/Controllers/MpSpecController.cs @@ -33,23 +33,6 @@ namespace MP.Data.Controllers #region Public Methods - /// - /// Elenco di tutti i counter coi valori correnti - /// - /// - public List AnagCounters() - { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbSetAnagCount - .AsNoTracking() - .ToList(); - } - return dbResult; - } - /// /// Stacca un nuovo counter x il tipo richiesto /// @@ -129,26 +112,6 @@ namespace MP.Data.Controllers return dbResult ?? new(); } - /// - /// Restituisce l'anagrafica EVENTI per macchina - /// - /// - public List AnagEventiGetByMacc(string IdxMac) - { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - var IdxMacch = new SqlParameter("@idxMacchina", IdxMac); - - dbResult = dbCtx - .DbSetVSEB - .FromSqlRaw("exec dbo.stp_vseb_getByIdxMacchinaFull @idxMacchina", IdxMacch) - .AsNoTracking() - .AsEnumerable() - .ToList(); - } - return dbResult; - } /// /// Elenco Gruppi tipo Azienda @@ -163,25 +126,21 @@ namespace MP.Data.Controllers /// Delete record AnagraficaGruppi /// /// - public bool AnagGruppiDelete(AnagGruppiModel updRec) + public async Task AnagGruppiDeleteAsync(AnagGruppiModel updRec) { - bool answ = false; - using (var dbCtx = new MoonProContext(options)) + using var dbCtx = new MoonProContext(options); + var dbRec = await dbCtx + .DbSetAnagGruppi + .AsNoTracking() + .Where(x => x.CodGruppo == updRec.CodGruppo) + .FirstOrDefaultAsync(); + // se trovato aggiorno descrizione (resto immutato x sicurezza!) + if (dbRec != null) { - var dbRec = dbCtx - .DbSetAnagGruppi - .AsNoTracking() - .Where(x => x.CodGruppo == updRec.CodGruppo) - .FirstOrDefault(); - // se trovato aggiorno descrizione (resto immutato x sicurezza!) - if (dbRec != null) - { - dbCtx.DbSetAnagGruppi.Remove(dbRec); - } - var numRes = dbCtx.SaveChanges(); - answ = numRes != 0; + dbCtx.DbSetAnagGruppi.Remove(dbRec); } - return answ; + var numRes = await dbCtx.SaveChangesAsync(); + return numRes != 0; } /// @@ -193,43 +152,6 @@ namespace MP.Data.Controllers return AnagGruppiGetTipoAsync("FASE"); } - /// - /// Elenco Gruppi - /// - /// - public List AnagGruppiGetAll() - { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbSetAnagGruppi - .AsNoTracking() - .OrderBy(x => x.CodGruppo) - .ToList(); - } - return dbResult; - } - - /// - /// Gruppi x tipo - /// - /// - /// - public List AnagGruppiGetTipo(string tipoGruppo) - { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbSetAnagGruppi - .Where(x => x.TipoGruppo == tipoGruppo) - .AsNoTracking() - .OrderBy(x => x.CodGruppo) - .ToList(); - } - return dbResult; - } /// /// Gruppi x tipo modalità Async @@ -238,26 +160,13 @@ namespace MP.Data.Controllers /// public async Task> AnagGruppiGetTipoAsync(string tipoGruppo) { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = await dbCtx - .DbSetAnagGruppi - .Where(x => x.TipoGruppo == tipoGruppo) - .AsNoTracking() - .OrderBy(x => x.CodGruppo) - .ToListAsync(); - } - return dbResult; - } - - /// - /// Elenco Gruppi tipo REPARTO (x associazione Macchine-Operatori) - /// - /// - public List AnagGruppiReparto() - { - return AnagGruppiGetTipo("REPARTO"); + using var dbCtx = new MoonProContext(options); + return await dbCtx + .DbSetAnagGruppi + .Where(x => x.TipoGruppo == tipoGruppo) + .AsNoTracking() + .OrderBy(x => x.CodGruppo) + .ToListAsync(); } /// @@ -268,7 +177,7 @@ namespace MP.Data.Controllers { using var dbCtx = new MoonProContext(options); // in primis recupero i reparti... - var listReparti = AnagGruppiGetTipo("REPARTO"); + var listReparti = await AnagGruppiGetTipoAsync("REPARTO"); // recupero TUTTE le macchine da DbSetGrp2Macc var listMacc = await dbCtx @@ -299,49 +208,28 @@ namespace MP.Data.Controllers /// /// /// - public bool AnagGruppiUpsert(AnagGruppiModel updRec) + public async Task AnagGruppiUpsertAsync(AnagGruppiModel updRec) { - bool answ = false; - using (var dbCtx = new MoonProContext(options)) + using var dbCtx = new MoonProContext(options); + var dbRec = await dbCtx + .DbSetAnagGruppi + .AsNoTracking() + .Where(x => x.CodGruppo == updRec.CodGruppo) + .FirstOrDefaultAsync(); + // se trovato aggiorno descrizione (resto immutato x sicurezza!) + if (dbRec != null) { - var dbRec = dbCtx - .DbSetAnagGruppi - .AsNoTracking() - .Where(x => x.CodGruppo == updRec.CodGruppo) - .FirstOrDefault(); - // se trovato aggiorno descrizione (resto immutato x sicurezza!) - if (dbRec != null) - { - dbRec.DescrGruppo = updRec.DescrGruppo; - dbCtx.Entry(dbRec).State = EntityState.Modified; - } - // altrimenti aggiungo - else - { - dbCtx.DbSetAnagGruppi.Add(updRec); - } - var numRes = dbCtx.SaveChanges(); - answ = numRes != 0; + dbRec.DescrGruppo = updRec.DescrGruppo; + dbCtx.Entry(dbRec).State = EntityState.Modified; } - return answ; - } + // altrimenti aggiungo + else + { + await dbCtx.DbSetAnagGruppi.AddAsync(updRec); + } + var numRes = await dbCtx.SaveChangesAsync(); - /// - /// Elenco Gruppi - /// - /// - public List AnagKeyValGetAll() - { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbSetAKV - .AsNoTracking() - .OrderBy(x => x.nomeVar) - .ToList(); - } - return dbResult; + return numRes != 0; } /// @@ -366,17 +254,15 @@ namespace MP.Data.Controllers /// Elenco codice articoli che abbiano dati Dossier /// /// - public List ArticleWithDossier() + public async Task> ArticleWithDossierAsync() { - List dbResult = new List(); using var dbCtx = new MoonPro_FluxContext(_configuration); - dbResult = dbCtx + return await dbCtx .DbSetDossiers .AsNoTracking() .Select(i => i.CodArticolo) .Distinct() - .ToList(); - return dbResult; + .ToListAsync(); } /// @@ -452,29 +338,17 @@ namespace MP.Data.Controllers /// /// /// - public async Task ArticoliDeleteRecord(AnagArticoliModel currRec) + public async Task ArticoliDeleteRecordAsync(AnagArticoliModel currRec) { - bool fatto = false; - using (var dbCtx = new MoonProContext(options)) - { - try - { - var currVal = dbCtx - .DbSetArticoli - .Where(x => x.CodArticolo == currRec.CodArticolo) - .FirstOrDefault(); - dbCtx - .DbSetArticoli - .Remove(currVal); - await dbCtx.SaveChangesAsync(); - fatto = true; - } - catch (Exception exc) - { - Log.Error($"Eccezione durante ArticoliDeleteRecord{Environment.NewLine}{exc}"); - } - } - return fatto; + using var dbCtx = new MoonProContext(options); + var currVal = dbCtx + .DbSetArticoli + .Where(x => x.CodArticolo == currRec.CodArticolo) + .FirstOrDefault(); + dbCtx + .DbSetArticoli + .Remove(currVal); + return await dbCtx.SaveChangesAsync() > 0; } /// @@ -486,17 +360,13 @@ namespace MP.Data.Controllers /// public async Task> ArticoliGetByTipoAsync(string tipo, string azienda = "*") { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = await dbCtx + using var dbCtx = new MoonProContext(options); + return await dbCtx .DbSetArticoli .AsNoTracking() .Where(x => x.Tipo.ToUpper() == tipo.ToUpper() && (azienda == "*" || x.Azienda.ToUpper() == azienda.ToUpper())) .OrderBy(x => x.CodArticolo) .ToListAsync(); - } - return dbResult; } /// @@ -547,34 +417,12 @@ namespace MP.Data.Controllers /// public async Task> ArticoliGetUnusedAsync() { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = await dbCtx - .DbSetArticoli - .FromSqlRaw("EXEC stp_ART_getNotUsed") - .AsNoTracking() - .ToListAsync(); - } - return dbResult; - } - - /// - /// Elenco tabella Articoli IMPIEGATI (da stored stp_ART_getUsed) - /// - /// - public List ArticoliGetUsed() - { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx + using var dbCtx = new MoonProContext(options); + return await dbCtx .DbSetArticoli - .FromSqlRaw("EXEC stp_ART_getUsed") + .FromSqlRaw("EXEC stp_ART_getNotUsed") .AsNoTracking() - .ToList(); - } - return dbResult; + .ToListAsync(); } /// @@ -583,16 +431,12 @@ namespace MP.Data.Controllers /// public async Task> ArticoliGetUsedAsync() { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = await dbCtx - .DbSetArticoli - .FromSqlRaw("EXEC stp_ART_getUsed") - .AsNoTracking() - .ToListAsync(); - } - return dbResult; + using var dbCtx = new MoonProContext(options); + return await dbCtx + .DbSetArticoli + .FromSqlRaw("EXEC stp_ART_getUsed") + .AsNoTracking() + .ToListAsync(); } /// @@ -618,56 +462,26 @@ namespace MP.Data.Controllers /// public async Task ArticoliUpdateRecord(AnagArticoliModel editRec) { - bool fatto = false; - using (var dbCtx = new MoonProContext(options)) - { - try - { - var currRec = dbCtx - .DbSetArticoli - .Where(x => x.CodArticolo == editRec.CodArticolo) - .FirstOrDefault(); - if (currRec != null) - { - currRec.Disegno = editRec.Disegno; - currRec.DescArticolo = editRec.DescArticolo; - currRec.Tipo = editRec.Tipo; - currRec.Azienda = editRec.Azienda; - dbCtx.Entry(currRec).State = EntityState.Modified; - } - else - { - dbCtx + using var dbCtx = new MoonProContext(options); + var currRec = dbCtx .DbSetArticoli - .Add(editRec); - } - await dbCtx.SaveChangesAsync(); - fatto = true; - } - catch (Exception exc) - { - Log.Error($"Eccezione durante ArticoliUpdateRecord{Environment.NewLine}{exc}"); - } - } - return fatto; - } - - /// - /// Elenco da tabella Config - /// - /// - public List ConfigGetAll() - { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) + .Where(x => x.CodArticolo == editRec.CodArticolo) + .FirstOrDefault(); + if (currRec != null) { - dbResult = dbCtx - .DbSetConfig - .AsNoTracking() - .OrderBy(x => x.Chiave) - .ToList(); + currRec.Disegno = editRec.Disegno; + currRec.DescArticolo = editRec.DescArticolo; + currRec.Tipo = editRec.Tipo; + currRec.Azienda = editRec.Azienda; + dbCtx.Entry(currRec).State = EntityState.Modified; } - return dbResult; + else + { + dbCtx + .DbSetArticoli + .Add(editRec); + } + return await dbCtx.SaveChangesAsync() > 0; } /// @@ -692,40 +506,19 @@ namespace MP.Data.Controllers { bool fatto = false; ConfigModel dbResult = new ConfigModel(); - using (var dbCtx = new MoonProContext(options)) + using var dbCtx = new MoonProContext(options); + dbResult = await dbCtx + .DbSetConfig + .Where(x => x.Chiave == updRec.Chiave) + .FirstOrDefaultAsync(); + if (dbResult != null) { - dbResult = await dbCtx - .DbSetConfig - .Where(x => x.Chiave == updRec.Chiave) - .FirstOrDefaultAsync(); - if (dbResult != null) - { - dbResult.Valore = updRec.Valore; - await dbCtx.SaveChangesAsync(); - fatto = true; - } + dbResult.Valore = updRec.Valore; + fatto = await dbCtx.SaveChangesAsync() > 0; } return fatto; } - /// - /// Intera tab dati macchina - /// - /// - public List DatiMacchineGetAll() - { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbSetDatiMacchine - .AsNoTracking() - .OrderBy(x => x.IdxMacchina) - .ToList(); - } - return dbResult; - } - /// /// Eliminazione di un dossier /// @@ -757,10 +550,8 @@ namespace MP.Data.Controllers /// public async Task> DossiersGetLastFiltAsync(string IdxMacchina, string CodArticolo, DateTime DtStart, DateTime DtEnd, int MaxRec) { - List dbResult = new List(); - using (var dbCtx = new MoonPro_FluxContext(_configuration)) - { - dbResult = await dbCtx + using var dbCtx = new MoonPro_FluxContext(_configuration); + return await dbCtx .DbSetDossiers .AsNoTracking() .Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && (CodArticolo == "*" || x.CodArticolo == CodArticolo) && (x.DtRif >= DtStart && x.DtRif <= DtEnd)) @@ -769,8 +560,6 @@ namespace MP.Data.Controllers .OrderByDescending(x => x.DtRif) .Take(MaxRec) .ToListAsync(); - } - return dbResult; } /// @@ -787,29 +576,6 @@ namespace MP.Data.Controllers return await dbCtx.SaveChangesAsync() > 0; } - /// - /// Effettua salvataggio snapshot parametri (con stored) + svuota eventuale cache _redisConn - /// - /// macchina - /// Num massimo secondi per recuperare dati correnti - /// DataOra riferimento x cui prendere valori antecedenti - public bool DossiersTakeParamsSnapshot(string idxMacchina, int maxSec, DateTime dtRif) - { - bool answ = false; - using (var dbCtx = new MoonPro_FluxContext(_configuration)) - { - var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); - var pMaxSec = new SqlParameter("@MaxSec", maxSec); - var pDtRif = new SqlParameter("@DtRif", dtRif); - - var dbResult = dbCtx - .Database - .ExecuteSqlRaw("EXEC stp_FL_TakeSnapshot @IdxMacchina,@MaxSec,@DtRif", pIdxMacchina, pMaxSec, pDtRif); - answ = true; - } - return answ; - } - /// /// Effettua salvataggio snapshot parametri (con stored) + svuota eventuale cache _redisConn /// @@ -864,25 +630,6 @@ namespace MP.Data.Controllers return ListLinkFiltAsync("SpecLink"); } - /// - /// Elenco operatori - /// - /// - public List ElencoOperatori() - { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbOperatori - .Where(s => s.MatrOpr > 0) - .AsNoTracking() - .OrderBy(x => x.MatrOpr) - .ToList(); - } - return dbResult; - } - /// /// Aggiunta record EventList /// @@ -936,6 +683,10 @@ namespace MP.Data.Controllers var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMaccSel); var pOnlyTest = new SqlParameter("@OnlyTest", false); + // dbContext condiviso + using var dbCtx = new MoonPro_FluxContext(_configuration); + // opzionalmente timeout comandi a 2 minuti... NON usato x ora e da testare + //dbCtx.Database.SetCommandTimeout(TimeSpan.FromMinutes(2)); // processo 1:1 ogni flusso foreach (var item in fluxList) { @@ -949,83 +700,76 @@ namespace MP.Data.Controllers DateTime dtCursStart = currPeriodo.Inizio; DateTime dtCursEnd = dtCursStart.Add(step); bool setCompleted = false; - // dbContext x ogni singolo flusso - using (var dbCtx = new MoonPro_FluxContext(_configuration)) + // li processo per intervallo richiesto, cercando dati nel periodo eselezionando VC + while (!setCompleted) { - // opzionalmente timeout comandi a 2 minuti... NON usato x ora e da testare - //dbCtx.Database.SetCommandTimeout(TimeSpan.FromMinutes(2)); - // li processo per intervallo richiesto, cercando dati nel periodo e - // selezionando VC - while (!setCompleted) + // ora recupero TUTTI i dati della macchina + var currFlux = await dbCtx + .DbSetFluxLog + .Where(x => (x.CodFlux == item) && (x.dtEvento >= dtCursStart && x.dtEvento < dtCursEnd) && (x.IdxMacchina == idxMaccSel)) + .ToListAsync(); + + int numRec = currFlux.Count; + numRecProc += numRec; + if (numRec > maxItem) { - // ora recupero TUTTI i dati della macchina - var currFlux = await dbCtx - .DbSetFluxLog - .Where(x => (x.CodFlux == item) && (x.dtEvento >= dtCursStart && x.dtEvento < dtCursEnd) && (x.IdxMacchina == idxMaccSel)) - .ToListAsync(); + List listPeriodi = new List(); - int numRec = currFlux.Count; - numRecProc += numRec; - if (numRec > maxItem) + switch (valMode) { - List listPeriodi = new List(); + case Enums.ValSelection.First: + // recupero 2° item + var recStart = currFlux.Skip(1).FirstOrDefault(); + // salvo periodo! + listPeriodi.Add(new Periodo(recStart.dtEvento, dtCursEnd)); + break; - switch (valMode) - { - case Enums.ValSelection.First: - // recupero 2° item - var recStart = currFlux.Skip(1).FirstOrDefault(); - // salvo periodo! - listPeriodi.Add(new Periodo(recStart.dtEvento, dtCursEnd)); - break; + case Enums.ValSelection.Last: + // recupero ultimo item + var recEnd = currFlux.LastOrDefault(); + // salvo periodo! + listPeriodi.Add(new Periodo(dtCursStart, recEnd.dtEvento)); + break; - case Enums.ValSelection.Last: - // recupero ultimo item - var recEnd = currFlux.LastOrDefault(); - // salvo periodo! - listPeriodi.Add(new Periodo(dtCursStart, recEnd.dtEvento)); - break; - - case Enums.ValSelection.Center: - int idx = 1; - // per iniziare mi metto a 1/(n+1) rec come step - var recCent = currFlux.Skip(idx / (maxItem + 1)).FirstOrDefault(); - listPeriodi.Add(new Periodo(dtCursStart, recCent.dtEvento)); - // salvo restanti periodi (se > 1)! - if (maxItem > 1) + case Enums.ValSelection.Center: + int idx = 1; + // per iniziare mi metto a 1/(n+1) rec come step + var recCent = currFlux.Skip(idx / (maxItem + 1)).FirstOrDefault(); + listPeriodi.Add(new Periodo(dtCursStart, recCent.dtEvento)); + // salvo restanti periodi (se > 1)! + if (maxItem > 1) + { + for (int i = 2; i < maxItem; i++) { - for (int i = 2; i < maxItem; i++) - { - DateTime dtInizio = recCent.dtEvento; - recCent = currFlux.Skip(i / (maxItem + 1)).FirstOrDefault(); - listPeriodi.Add(new Periodo(dtInizio, recCent.dtEvento)); - } + DateTime dtInizio = recCent.dtEvento; + recCent = currFlux.Skip(i / (maxItem + 1)).FirstOrDefault(); + listPeriodi.Add(new Periodo(dtInizio, recCent.dtEvento)); } - // aggiungo ultimo... - listPeriodi.Add(new Periodo(recCent.dtEvento.AddSeconds(1), dtCursEnd)); - break; + } + // aggiungo ultimo... + listPeriodi.Add(new Periodo(recCent.dtEvento.AddSeconds(1), dtCursEnd)); + break; - default: - break; - } - - // ciclo x tutti i periodi e chiamo stored... - foreach (var slot in listPeriodi) - { - // parametri x periodo (base) - var pDtStart = new SqlParameter("@DtStart", slot.Inizio); - var pDtEnd = new SqlParameter("@DtEnd", slot.Fine); - var dbResult = await dbCtx - .Database - .ExecuteSqlRawAsync("EXEC man.stp_ReduceFluxLog @IdxMacchina, @CodFlux, @DtStart, @DtEnd, @OnlyTest", pIdxMacchina, pCodFlux, pDtStart, pDtEnd, pOnlyTest); - } + default: + break; } - // incremento dt fine periodo - dtCursStart = dtCursEnd; - dtCursEnd = dtCursStart.Add(step); - setCompleted = dtCursStart >= currPeriodo.Fine; + // ciclo x tutti i periodi e chiamo stored... + foreach (var slot in listPeriodi) + { + // parametri x periodo (base) + var pDtStart = new SqlParameter("@DtStart", slot.Inizio); + var pDtEnd = new SqlParameter("@DtEnd", slot.Fine); + var dbResult = await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC man.stp_ReduceFluxLog @IdxMacchina, @CodFlux, @DtStart, @DtEnd, @OnlyTest", pIdxMacchina, pCodFlux, pDtStart, pDtEnd, pOnlyTest); + } } + + // incremento dt fine periodo + dtCursStart = dtCursEnd; + dtCursEnd = dtCursStart.Add(step); + setCompleted = dtCursStart >= currPeriodo.Fine; } // fermo cronometro e salvo su DB... sw.Stop(); @@ -1092,28 +836,24 @@ namespace MP.Data.Controllers /// def: 10 /// def: 50 /// - public async Task ForceDbMaint(bool doExec, bool doUpdStat, bool doSave, int minPgCnt, int minAvgFrag, int maxAvgFragReb) + public async Task ForceDbMaintAsync(bool doExec, bool doUpdStat, bool doSave, int minPgCnt, int minAvgFrag, int maxAvgFragReb) { - Log.Info($"Inizio ForceDbMaint on MoonProAdminContext"); - bool fatto = false; + Log.Info($"Inizio ForceDbMaintAsync on MoonProAdminContext"); // uso context admin x query lunghe - using (var dbCtx = new MoonProAdminContext(_configuration)) - { - var pFlgExec = new SqlParameter("@FlgExec", doExec ? "Y" : "N"); - var pFlgUpdStat = new SqlParameter("@FlgUpdStat", doUpdStat ? "Y" : "N"); - var pFlgSave = new SqlParameter("@FlgSave", doSave ? "Y" : "N"); - var pMinPgCnt = new SqlParameter("@min_page_count", minPgCnt); - var pMinAvgFrag = new SqlParameter("@min_avg_fragmentation_in_percent", minAvgFrag); - var pMaxAvgFrag = new SqlParameter("@max_avg_fragmentation_per_rebuild", maxAvgFragReb); + using var dbCtx = new MoonProAdminContext(_configuration); + var pFlgExec = new SqlParameter("@FlgExec", doExec ? "Y" : "N"); + var pFlgUpdStat = new SqlParameter("@FlgUpdStat", doUpdStat ? "Y" : "N"); + var pFlgSave = new SqlParameter("@FlgSave", doSave ? "Y" : "N"); + var pMinPgCnt = new SqlParameter("@min_page_count", minPgCnt); + var pMinAvgFrag = new SqlParameter("@min_avg_fragmentation_in_percent", minAvgFrag); + var pMaxAvgFrag = new SqlParameter("@max_avg_fragmentation_per_rebuild", maxAvgFragReb); - var dbResult = await dbCtx - .Database - .ExecuteSqlRawAsync("EXEC man.stp_Utility_Maintanance"); - //.ExecuteSqlRaw("EXEC man.stp_Utility_Maintanance @FlgExec, @FlgUpdStat, @FlgSave, @min_page_count, @min_avg_fragmentation_in_percent, @max_avg_fragmentation_per_rebuild", pFlgExec, pFlgUpdStat, pFlgSave, pMinPgCnt, pMinAvgFrag, pMaxAvgFrag); - fatto = true; - } - Log.Info($"FINE ForceDbMaint on MoonProAdminContext"); - return fatto; + var dbResult = await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC man.stp_Utility_Maintanance"); + //.ExecuteSqlRaw("EXEC man.stp_Utility_Maintanance @FlgExec, @FlgUpdStat, @FlgSave, @min_page_count, @min_avg_fragmentation_in_percent, @max_avg_fragmentation_per_rebuild", pFlgExec, pFlgUpdStat, pFlgSave, pMinPgCnt, pMinAvgFrag, pMaxAvgFrag); + Log.Info($"FINE ForceDbMaintAsync on MoonProAdminContext"); + return dbResult != 0; } /// @@ -1313,38 +1053,14 @@ namespace MP.Data.Controllers /// /// /// - public List ListLinkAll() + public async Task> ListLinkAllAsync() { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx + using var dbCtx = new MoonProContext(options); + return await dbCtx .DbSetLinkMenu .AsNoTracking() .OrderBy(x => x.Ordine) - .ToList(); - } - return dbResult; - } - - /// - /// Elenco link JQM dato filtro tipo - /// - /// - /// - public List ListLinkFilt(string tipoLink) - { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbSetLinkMenu - .Where(x => x.TipoLink == tipoLink) - .AsNoTracking() - .OrderBy(x => x.Ordine) - .ToList(); - } - return dbResult; + .ToListAsync(); } /// @@ -1355,16 +1071,13 @@ namespace MP.Data.Controllers public async Task> ListLinkFiltAsync(string tipoLink) { List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = await dbCtx - .DbSetLinkMenu - .Where(x => x.TipoLink == tipoLink) - .AsNoTracking() - .OrderBy(x => x.Ordine) - .ToListAsync(); - } - return dbResult; + using var dbCtx = new MoonProContext(options); + return await dbCtx + .DbSetLinkMenu + .Where(x => x.TipoLink == tipoLink) + .AsNoTracking() + .OrderBy(x => x.Ordine) + .ToListAsync(); } /// @@ -1434,35 +1147,6 @@ namespace MP.Data.Controllers .ToListAsync(); } - /// - /// Elenco PODL per composizione KIT non avviati filtrati x articolo, KeyRich (che contiene stato) - /// - /// Solo lanciati (1) o ancora disponibili (0) - /// KeyRich (parziale) da cercare (es cod stato x yacht) - /// Macchina - /// Gruppo - /// - public List ListPODL_KitFilt(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) - { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - var Lanc = new SqlParameter("@Lanciato", lanciato); - var KeyRich = new SqlParameter("@KeyRich", keyRichPart); - var CodGrp = new SqlParameter("@CodGruppo", codGruppo); - var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina); - var DateFrom = new SqlParameter("@DtInizio", startDate); - var DateTo = new SqlParameter("@DtFine", endDate); - - dbResult = dbCtx - .DbSetPODLExp - .FromSqlRaw("EXEC stp_PODL_getByFiltSpecKit @Lanciato, @KeyRich, @CodGruppo, @IdxMacchina, @DtInizio, @DtFine", Lanc, KeyRich, CodGrp, IdxMacc, DateFrom, DateTo) - .AsNoTracking() - .ToList(); - } - return dbResult; - } - /// /// Elenco PODL per composizione KIT non avviati filtrati x articolo, KeyRich (che contiene stato) /// @@ -1473,52 +1157,19 @@ namespace MP.Data.Controllers /// public async Task> ListPODL_KitFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - var Lanc = new SqlParameter("@Lanciato", lanciato); - var KeyRich = new SqlParameter("@KeyRich", keyRichPart); - var CodGrp = new SqlParameter("@CodGruppo", codGruppo); - var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina); - var DateFrom = new SqlParameter("@DtInizio", startDate); - var DateTo = new SqlParameter("@DtFine", endDate); + using var dbCtx = new MoonProContext(options); + var Lanc = new SqlParameter("@Lanciato", lanciato); + var KeyRich = new SqlParameter("@KeyRich", keyRichPart); + var CodGrp = new SqlParameter("@CodGruppo", codGruppo); + var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina); + var DateFrom = new SqlParameter("@DtInizio", startDate); + var DateTo = new SqlParameter("@DtFine", endDate); - dbResult = await dbCtx + return await dbCtx .DbSetPODLExp .FromSqlRaw("EXEC stp_PODL_getByFiltSpecKit @Lanciato, @KeyRich, @CodGruppo, @IdxMacchina, @DtInizio, @DtFine", Lanc, KeyRich, CodGrp, IdxMacc, DateFrom, DateTo) .AsNoTracking() .ToListAsync(); - } - return dbResult; - } - - /// - /// Elenco PODL non avviati filtrati x articolo, KeyRich (che contiene stato) - /// - /// Solo lanciati (1) o ancora disponibili (0) - /// KeyRich (parziale) da cercare (es cod stato x yacht) - /// Macchina - /// Gruppo - /// - public List ListPODLFilt(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) - { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - var Lanc = new SqlParameter("@Lanciato", lanciato); - var KeyRich = new SqlParameter("@KeyRich", keyRichPart); - var CodGrp = new SqlParameter("@CodGruppo", codGruppo); - var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina); - var DateFrom = new SqlParameter("@DtInizio", startDate); - var DateTo = new SqlParameter("@DtFine", endDate); - - dbResult = dbCtx - .DbSetPODLExp - .FromSqlRaw("EXEC stp_PODL_getByFiltSpec @Lanciato, @KeyRich, @CodGruppo, @IdxMacchina, @DtInizio, @DtFine", Lanc, KeyRich, CodGrp, IdxMacc, DateFrom, DateTo) - .AsNoTracking() - .ToList(); - } - return dbResult; } /// @@ -1531,48 +1182,21 @@ namespace MP.Data.Controllers /// public async Task> ListPODLFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - var Lanc = new SqlParameter("@Lanciato", lanciato); - var KeyRich = new SqlParameter("@KeyRich", keyRichPart); - var CodGrp = new SqlParameter("@CodGruppo", codGruppo); - var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina); - var DateFrom = new SqlParameter("@DtInizio", startDate); - var DateTo = new SqlParameter("@DtFine", endDate); + using var dbCtx = new MoonProContext(options); + var Lanc = new SqlParameter("@Lanciato", lanciato); + var KeyRich = new SqlParameter("@KeyRich", keyRichPart); + var CodGrp = new SqlParameter("@CodGruppo", codGruppo); + var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina); + var DateFrom = new SqlParameter("@DtInizio", startDate); + var DateTo = new SqlParameter("@DtFine", endDate); - dbResult = await dbCtx + return await dbCtx .DbSetPODLExp .FromSqlRaw("EXEC stp_PODL_getByFiltSpec @Lanciato, @KeyRich, @CodGruppo, @IdxMacchina, @DtInizio, @DtFine", Lanc, KeyRich, CodGrp, IdxMacc, DateFrom, DateTo) .AsNoTracking() .ToListAsync(); - } - return dbResult; } -#if false - /// - /// Elenco valori ammessi x tabella/colonna - /// - /// - /// - /// - public List ListValuesFilt(string tabName, string fieldName) - { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbSetListValues - .Where(x => x.TableName == tabName && x.FieldName == fieldName) - .AsNoTracking() - .OrderBy(x => x.ordinal) - .ToList(); - } - return dbResult; - } -#endif - /// /// Elenco valori ammessi x tabella/colonna Async /// @@ -1581,17 +1205,13 @@ namespace MP.Data.Controllers /// public async Task> ListValuesFiltAsync(string tabName, string fieldName) { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = await dbCtx - .DbSetListValues - .Where(x => x.TableName == tabName && x.FieldName == fieldName) - .AsNoTracking() - .OrderBy(x => x.ordinal) - .ToListAsync(); - } - return dbResult; + using var dbCtx = new MoonProContext(options); + return await dbCtx + .DbSetListValues + .Where(x => x.TableName == tabName && x.FieldName == fieldName) + .AsNoTracking() + .OrderBy(x => x.ordinal) + .ToListAsync(); } /// @@ -1599,92 +1219,38 @@ namespace MP.Data.Controllers /// /// /// - public List MacchineByMatrOper(int MatrOpr) + public async Task> MacchineByMatrOperAsync(int MatrOpr) { - List dbResult = new List(); - try + using var dbCtx = new MoonProContext(options); + if (MatrOpr == 0) { - using (var dbCtx = new MoonProContext(options)) - { - if (MatrOpr == 0) - { - dbResult = dbCtx - .DbSetMacchine - .AsNoTracking() - .OrderBy(x => x.IdxMacchina) - .ToList(); - } - else - { - dbResult = dbCtx - .DbSetGrp2Oper - .Where(g => g.MatrOpr == MatrOpr) - .Join(dbCtx.DbSetGrp2Macc, - g => g.CodGruppo, - m => m.CodGruppo, - (g, m) => m - ) - .Distinct() - .Join(dbCtx.DbSetMacchine, - g => g.IdxMacchina, - m => m.IdxMacchina, - (g, m) => m - ) - .Distinct() - .AsNoTracking() - .OrderBy(x => x.IdxMacchina) - .ToList(); - } - } + return await dbCtx + .DbSetMacchine + .AsNoTracking() + .OrderBy(x => x.IdxMacchina) + .ToListAsync(); } - catch (Exception exc) + else { - Log.Error($"Eccezione in MacchineByMatrOper{Environment.NewLine}{exc}"); + return await dbCtx + .DbSetGrp2Oper + .Where(g => g.MatrOpr == MatrOpr) + .Join(dbCtx.DbSetGrp2Macc, + g => g.CodGruppo, + m => m.CodGruppo, + (g, m) => m + ) + .Distinct() + .Join(dbCtx.DbSetMacchine, + g => g.IdxMacchina, + m => m.IdxMacchina, + (g, m) => m + ) + .Distinct() + .AsNoTracking() + .OrderBy(x => x.IdxMacchina) + .ToListAsync(); } - return dbResult; - } - - /// - /// Elenco da tabella Macchine filtro x gruppo - /// - /// - /// - public List MacchineGetFilt(string codGruppo) - { - List dbResult = new List(); - try - { - using (var dbCtx = new MoonProContext(options)) - { - if (codGruppo == "*") - { - dbResult = dbCtx - .DbSetMacchine - .AsNoTracking() - .OrderBy(x => x.IdxMacchina) - .ToList(); - } - else - { - dbResult = dbCtx - .DbSetGrp2Macc - .Where(g => g.CodGruppo == codGruppo) - .Join(dbCtx.DbSetMacchine, - g => g.IdxMacchina, - m => m.IdxMacchina, - (g, m) => m - ) - .AsNoTracking() - .OrderBy(x => x.IdxMacchina) - .ToList(); - } - } - } - catch (Exception exc) - { - Log.Error($"Eccezione in MacchineGetFilt{Environment.NewLine}{exc}"); - } - return dbResult; } /// @@ -1694,40 +1260,29 @@ namespace MP.Data.Controllers /// public async Task> MacchineGetFiltAsync(string codGruppo) { - List dbResult = new List(); - try + using var dbCtx = new MoonProContext(options); + if (codGruppo == "*") { - using (var dbCtx = new MoonProContext(options)) - { - if (codGruppo == "*") - { - dbResult = await dbCtx - .DbSetMacchine - .AsNoTracking() - .OrderBy(x => x.IdxMacchina) - .ToListAsync(); - } - else - { - dbResult = await dbCtx - .DbSetGrp2Macc - .Where(g => g.CodGruppo == codGruppo) - .Join(dbCtx.DbSetMacchine, - g => g.IdxMacchina, - m => m.IdxMacchina, - (g, m) => m - ) - .AsNoTracking() - .OrderBy(x => x.IdxMacchina) - .ToListAsync(); - } - } + return await dbCtx + .DbSetMacchine + .AsNoTracking() + .OrderBy(x => x.IdxMacchina) + .ToListAsync(); } - catch (Exception exc) + else { - Log.Error($"Eccezione in MacchineGetFiltAsync{Environment.NewLine}{exc}"); + return await dbCtx + .DbSetGrp2Macc + .Where(g => g.CodGruppo == codGruppo) + .Join(dbCtx.DbSetMacchine, + g => g.IdxMacchina, + m => m.IdxMacchina, + (g, m) => m + ) + .AsNoTracking() + .OrderBy(x => x.IdxMacchina) + .ToListAsync(); } - return dbResult; } /// @@ -1748,41 +1303,6 @@ namespace MP.Data.Controllers .ToListAsync() ?? new(); } - /// - /// Aggiornamento record Microstato macchina - /// - /// - /// - public async Task MicroStatoMacchinaUpsert(MicroStatoMacchinaModel newRec) - { - bool fatto = false; - using (var dbCtx = new MoonProContext(options)) - { - var actRec = await dbCtx - .DbSetMicroStatoMacc - .Where(x => x.IdxMacchina == newRec.IdxMacchina) - .AsNoTracking() - .FirstOrDefaultAsync(); - if (actRec == null) - { - dbCtx - .DbSetMicroStatoMacc - .Add(newRec); - } - else - { - actRec.IdxMicroStato = newRec.IdxMicroStato; - actRec.InizioStato = newRec.InizioStato; - actRec.Value = newRec.Value; - - dbCtx.Entry(actRec).State = EntityState.Modified; - } - await dbCtx.SaveChangesAsync(); - fatto = true; - } - return fatto; - } - /// /// Elenco da tabella MappaStatoExplModel /// @@ -1803,35 +1323,6 @@ namespace MP.Data.Controllers return dbResult; } -#if false - /// - /// Elenco ODL dato batch selezionato - /// - /// Batch richiesto - /// - public List OdlByBatch(string batchSel) - { - List dbResult = new List(); - using (var dbCtx = new MoonPro_InveContext(_configuration)) - { - try - { - dbResult = dbCtx - .DbGiacenzeData - .AsNoTracking() - .Where(x => x.IdentRG == batchSel) - .Select(x => x.IdxOdl) - .ToList(); - } - catch (Exception exc) - { - Log.Error($"Eccezione durante OdlByBatch{Environment.NewLine}{exc}"); - } - } - return dbResult; - } -#endif - /// /// Elenco ODL dato batch selezionato /// @@ -1938,43 +1429,13 @@ namespace MP.Data.Controllers /// public async Task> OdlGetCurrentAsync() { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = await dbCtx + using var dbCtx = new MoonProContext(options); + return await dbCtx .DbSetODL .Where(x => x.DataInizio != null && x.DataFine == null) .ToListAsync(); - } - return dbResult; } -#if false - /// - /// Elenco TUTTI GLI ODL - /// - /// - public List OdlListAll() - { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - try - { - dbResult = dbCtx - .DbSetODL - .AsNoTracking() - .ToList(); - } - catch (Exception exc) - { - Log.Error($"Eccezione durante ListOdlAll{Environment.NewLine}{exc}"); - } - } - return dbResult; - } -#endif - /// /// Statistiche ODL calcolate (da stored stp_STAT_ODL) /// @@ -2049,26 +1510,6 @@ namespace MP.Data.Controllers .ToListAsync(); } - /// - /// Stato prod macchina - /// - /// - /// - public PzProdModel PezziProdMacchina(string idxMacchina) - { - PzProdModel dbResult = new PzProdModel(); - using (var dbCtx = new MoonProContext(options)) - { - var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); - dbResult = dbCtx - .DbSetPzProd - .FromSqlRaw("EXEC stp_PzProd_getByMacchina @IdxMacchina", IdxMacchina) - .AsNoTracking() - .FirstOrDefault(); - } - return dbResult; - } - /// /// Recupero PODL da chiave /// @@ -2130,7 +1571,6 @@ namespace MP.Data.Controllers public async Task PODL_startSetup(PODLExpModel editRec, int matrOpr, double tcRich, int pzPallet, string note, DateTime dtEvent) { bool answ = false; - PODLModel recPODL = new PODLModel() { IdxPromessa = editRec.IdxPromessa, @@ -2150,39 +1590,29 @@ namespace MP.Data.Controllers InsertDate = editRec.InsertDate }; - using (var dbCtx = new MoonProContext(options)) + using var dbCtx = new MoonProContext(options); + var currRec = await dbCtx + .DbSetPODL + .AsNoTracking() + .Where(x => x.IdxPromessa == recPODL.IdxPromessa) + .FirstOrDefaultAsync(); + + if (currRec != null) { - try - { - var currRec = dbCtx - .DbSetPODL - .AsNoTracking() - .Where(x => x.IdxPromessa == recPODL.IdxPromessa) - .FirstOrDefault(); + // eseguo stored attrezzaggio + var IdxPromessa = new SqlParameter("@idxPromessa", recPODL.IdxPromessa); + var MatrOpr = new SqlParameter("@MatrOpr", matrOpr); + var IdxMacchina = new SqlParameter("@IdxMacchina", recPODL.IdxMacchina); + var TCRichAttr = new SqlParameter("@TCRichAttr", tcRich); + var PzPallet = new SqlParameter("@PzPallet", pzPallet); + var Note = new SqlParameter("@Note", note); + var DtEvento = new SqlParameter("@dtEvento", dtEvent); + var callResult = await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC stp_ODL_inizioSetupPromessa @idxPromessa, @MatrOpr, @IdxMacchina, @TCRichAttr, @PzPallet, @Note, @dtEvento", IdxPromessa, MatrOpr, IdxMacchina, TCRichAttr, PzPallet, Note, DtEvento); - if (currRec != null) - { - // eseguo stored attrezzaggio - var IdxPromessa = new SqlParameter("@idxPromessa", recPODL.IdxPromessa); - var MatrOpr = new SqlParameter("@MatrOpr", matrOpr); - var IdxMacchina = new SqlParameter("@IdxMacchina", recPODL.IdxMacchina); - var TCRichAttr = new SqlParameter("@TCRichAttr", tcRich); - var PzPallet = new SqlParameter("@PzPallet", pzPallet); - var Note = new SqlParameter("@Note", note); - var DtEvento = new SqlParameter("@dtEvento", dtEvent); - var callResult = await dbCtx - .Database - .ExecuteSqlRawAsync("EXEC stp_ODL_inizioSetupPromessa @idxPromessa, @MatrOpr, @IdxMacchina, @TCRichAttr, @PzPallet, @Note, @dtEvento", IdxPromessa, MatrOpr, IdxMacchina, TCRichAttr, PzPallet, Note, DtEvento); - - answ = true; - } - } - catch (Exception exc) - { - Log.Error($"Eccezione durante PODL_doSetup{Environment.NewLine}{exc}"); - } + answ = true; } - await Task.Delay(1); return answ; } @@ -2195,29 +1625,18 @@ namespace MP.Data.Controllers public async Task PODL_updateRecipe(int idxPODL, string recipeName) { bool answ = false; - using (var dbCtx = new MoonProContext(options)) - { - try - { - var currRec = dbCtx - .DbSetPODL - .Where(x => x.IdxPromessa == idxPODL) - .FirstOrDefault(); + using var dbCtx = new MoonProContext(options); + var currRec = await dbCtx + .DbSetPODL + .Where(x => x.IdxPromessa == idxPODL) + .FirstOrDefaultAsync(); - if (currRec != null) - { - currRec.Recipe = recipeName; - dbCtx.Entry(currRec).State = EntityState.Modified; - await dbCtx.SaveChangesAsync(); - answ = true; - } - } - catch (Exception exc) - { - Log.Error($"Eccezione durante PODL_updateRecipe{Environment.NewLine}{exc}"); - } + if (currRec != null) + { + currRec.Recipe = recipeName; + dbCtx.Entry(currRec).State = EntityState.Modified; + answ = await dbCtx.SaveChangesAsync() > 0; } - await Task.Delay(1); return answ; } @@ -2226,7 +1645,7 @@ namespace MP.Data.Controllers /// /// /// - public async Task PODLDeleteRecord(PODLExpModel currRec) + public async Task PODLDeleteRecordAsync(PODLExpModel currRec) { PODLModel recPODL = new PODLModel() { @@ -2246,27 +1665,15 @@ namespace MP.Data.Controllers CodCli = currRec.CodCli, InsertDate = currRec.InsertDate }; - bool fatto = false; - using (var dbCtx = new MoonProContext(options)) - { - try - { - var currVal = dbCtx - .DbSetPODL - .Where(x => x.IdxPromessa == recPODL.IdxPromessa) - .FirstOrDefault(); - dbCtx - .DbSetPODL - .Remove(currVal); - await dbCtx.SaveChangesAsync(); - fatto = true; - } - catch (Exception exc) - { - Log.Error($"Eccezione durante PODLDeleteRecord{Environment.NewLine}{exc}"); - } - } - return fatto; + using var dbCtx = new MoonProContext(options); + var currVal = await dbCtx + .DbSetPODL + .Where(x => x.IdxPromessa == recPODL.IdxPromessa) + .FirstOrDefaultAsync(); + dbCtx + .DbSetPODL + .Remove(currVal); + return await dbCtx.SaveChangesAsync() > 0; } /// @@ -2318,31 +1725,6 @@ namespace MP.Data.Controllers return await dbCtx.SaveChangesAsync() > 0; } - /// - /// Annulla modifiche su una specifica entity (cancel update) - /// - /// - /// - public bool RollBackEntity(object item) - { - bool answ = false; - using (var dbCtx = new MoonProContext(options)) - { - try - { - if (dbCtx.Entry(item).State == Microsoft.EntityFrameworkCore.EntityState.Deleted || dbCtx.Entry(item).State == Microsoft.EntityFrameworkCore.EntityState.Modified) - { - dbCtx.Entry(item).Reload(); - } - } - catch (Exception exc) - { - Log.Error($"Eccezione in rollBackEntity{Environment.NewLine}{exc}"); - } - } - return answ; - } - /// /// Stato macchina (da key) /// @@ -2402,56 +1784,51 @@ namespace MP.Data.Controllers /// /// /// - public bool TemplateKitUpsert(TemplateKitModel editRec, string codAzienda) + public async Task TemplateKitUpsertAsync(TemplateKitModel editRec, string codAzienda) { - bool fatto = false; - using (var dbCtx = new MoonProContext(options)) + using var dbCtx = new MoonProContext(options); + // verifico preliminarmente articolo... + var recArt = dbCtx + .DbSetArticoli + .FirstOrDefault(x => x.CodArticolo == editRec.CodArtParent); + // se mancasse... + if (recArt == null) { - // verifico preliminarmente articolo... - var recArt = dbCtx - .DbSetArticoli - .FirstOrDefault(x => x.CodArticolo == editRec.CodArtParent); - // se mancasse... - if (recArt == null) + // aggiungo! + AnagArticoliModel newRecArt = new AnagArticoliModel() { - // aggiungo! - AnagArticoliModel newRecArt = new AnagArticoliModel() - { - CodArticolo = editRec.CodArtParent, - Tipo = "KIT", - DescArticolo = $"Articolo KIT - {DateTime.Now:yyyy-MM-dd HH:mm:ss}", - Disegno = "", - Azienda = codAzienda, - CurrRev = "", - ProdRev = "" - }; - dbCtx - .DbSetArticoli - .Add(newRecArt); - } - - // proseguo col KIT - var actRec = dbCtx - .DbSetTempKit - .Where(x => x.CodArtParent == editRec.CodArtParent && x.CodArtChild == editRec.CodArtChild) - .FirstOrDefault(); - - // se NON ci fosse aggiungo... - if (actRec == null) - { - dbCtx - .DbSetTempKit - .Add(editRec); - } - else - { - actRec.Qty = editRec.Qty; - dbCtx.Entry(actRec).State = EntityState.Modified; - } - var res = dbCtx.SaveChanges(); - fatto = res != 0; + CodArticolo = editRec.CodArtParent, + Tipo = "KIT", + DescArticolo = $"Articolo KIT - {DateTime.Now:yyyy-MM-dd HH:mm:ss}", + Disegno = "", + Azienda = codAzienda, + CurrRev = "", + ProdRev = "" + }; + dbCtx + .DbSetArticoli + .Add(newRecArt); } - return fatto; + + // proseguo col KIT + var actRec = await dbCtx + .DbSetTempKit + .Where(x => x.CodArtParent == editRec.CodArtParent && x.CodArtChild == editRec.CodArtChild) + .FirstOrDefaultAsync(); + + // se NON ci fosse aggiungo... + if (actRec == null) + { + await dbCtx + .DbSetTempKit + .AddAsync(editRec); + } + else + { + actRec.Qty = editRec.Qty; + dbCtx.Entry(actRec).State = EntityState.Modified; + } + return await dbCtx.SaveChangesAsync() > 0; } /// @@ -2477,20 +1854,6 @@ namespace MP.Data.Controllers return dbResult; } - /// - /// Elenco Vocabolario (completo) async - /// - /// - public async Task> VocabolarioGetAllAsync() - { - using var dbCtx = new MoonProContext(options); - return await dbCtx - .DbSetVocabolario - .AsNoTracking() - .OrderBy(x => x.Lemma) - .ToListAsync() ?? new(); - } - /// /// Elenco Vocabolario di una lingua /// @@ -2559,32 +1922,6 @@ namespace MP.Data.Controllers return await dbCtx.SaveChangesAsync() > 0; } - /// - /// Elimina i record associati al KeyFilt indicato - /// - /// - public bool WipKitDeleteGroup(string KeyFilt) - { - bool fatto = false; - using (var dbCtx = new MoonProContext(options)) - { - var actRec = dbCtx - .DbSetWipKit - .Where(x => x.KeyFilt == KeyFilt) - .ToList(); - // se ci fosse aggiorno... - if (actRec != null) - { - dbCtx - .DbSetWipKit - .RemoveRange(actRec); - } - var res = dbCtx.SaveChanges(); - fatto = res != 0; - } - return fatto; - } - /// /// Elimina record + vecchi della data-ora indicata /// diff --git a/MP.Data/Controllers/MpTabController.cs b/MP.Data/Controllers/MpTabController.cs index 1a5c469b..0aaa045e 100644 --- a/MP.Data/Controllers/MpTabController.cs +++ b/MP.Data/Controllers/MpTabController.cs @@ -1029,7 +1029,7 @@ namespace MP.Data.Controllers } catch (Exception exc) { - Log.Error($"Eccezione in MacchineByMatrOper{Environment.NewLine}{exc}"); + Log.Error($"Eccezione in MacchineByMatrOperAsync{Environment.NewLine}{exc}"); } return dbResult; } diff --git a/MP.Data/Services/ListSelectDataSrv.cs b/MP.Data/Services/ListSelectDataSrv.cs index 80cc2102..0cefec61 100644 --- a/MP.Data/Services/ListSelectDataSrv.cs +++ b/MP.Data/Services/ListSelectDataSrv.cs @@ -104,7 +104,7 @@ namespace MP.Data.Services } else { - result = dbController.ConfigGetAll(); + result = await dbController.ConfigGetAllAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); _redisDb.StringSet(currKey, rawData, LongCache); @@ -114,7 +114,7 @@ namespace MP.Data.Services result = new List(); } sw.Stop(); - Log.Debug($"ConfigGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + Log.Debug($"ConfigGetAllAsync | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } @@ -160,7 +160,7 @@ namespace MP.Data.Services } else { - result = await Task.FromResult(dbController.ListLinkAll()); + result = await dbController.ListLinkAllAsync(); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await _redisDb.StringSetAsync(currKey, rawData, UltraLongCache); @@ -170,7 +170,7 @@ namespace MP.Data.Services result = new List(); } sw.Stop(); - Log.Debug($"ListLinkAll | tipoLink: * | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + Log.Debug($"ListLinkAllAsync | tipoLink: * | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } @@ -196,7 +196,7 @@ namespace MP.Data.Services } else { - result = await Task.FromResult(dbController.ListLinkFilt(tipoLink)); + result = await dbController.ListLinkFiltAsync(tipoLink); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await _redisDb.StringSetAsync(currKey, rawData, UltraLongCache); @@ -232,7 +232,7 @@ namespace MP.Data.Services } else { - result = await Task.FromResult(dbController.MacchineByMatrOper(MatrOpr)); + result = await dbController.MacchineByMatrOperAsync(MatrOpr); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await _redisDb.StringSetAsync(currKey, rawData, UltraLongCache); diff --git a/MP.Data/Services/MonDataFeeder.cs b/MP.Data/Services/MonDataFeeder.cs index 697c0d69..24f9bae8 100644 --- a/MP.Data/Services/MonDataFeeder.cs +++ b/MP.Data/Services/MonDataFeeder.cs @@ -113,17 +113,17 @@ namespace MP.Data.Services if (resto == 0) { // invio in channel blink il segnale - blinkPipe.SendMessageAsync("true"); + await blinkPipe.SendMessageAsync("true"); Log.Debug("Elapsed Fast Timer Blink"); } else { // invio in channel blink segnale false - blinkPipe.SendMessageAsync("false"); + await blinkPipe.SendMessageAsync("false"); // rileggo dati... var newData = await MseGetAll(); // invio tramite la pipe... - dataPipe.SendMessageAsync(JsonConvert.SerializeObject(newData)); + await dataPipe.SendMessageAsync(JsonConvert.SerializeObject(newData)); Log.Debug("Elapsed Fast Timer reload"); } }); diff --git a/MP.Data/Services/OrderDataSrv.cs b/MP.Data/Services/OrderDataSrv.cs index e974f441..5daa7858 100644 --- a/MP.Data/Services/OrderDataSrv.cs +++ b/MP.Data/Services/OrderDataSrv.cs @@ -66,7 +66,7 @@ namespace MP.Data.Services } else { - result = dbController.ConfigGetAll(); + result = await dbController.ConfigGetAllAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); _redisDb.StringSet(currKey, rawData, LongCache); @@ -76,7 +76,7 @@ namespace MP.Data.Services result = new List(); } sw.Stop(); - Log.Debug($"ConfigGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + Log.Debug($"ConfigGetAllAsync | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } diff --git a/MP.Data/Services/StatusData.cs b/MP.Data/Services/StatusData.cs index 02b0b848..a10ed1c5 100644 --- a/MP.Data/Services/StatusData.cs +++ b/MP.Data/Services/StatusData.cs @@ -112,7 +112,7 @@ namespace MP.Data.Services result = new List(); } sw.Stop(); - Log.Debug($"ConfigGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + Log.Debug($"ConfigGetAllAsync | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } diff --git a/MP.Data/Services/TabDataFeeder.cs b/MP.Data/Services/TabDataFeeder.cs index f91090de..4282219c 100644 --- a/MP.Data/Services/TabDataFeeder.cs +++ b/MP.Data/Services/TabDataFeeder.cs @@ -133,17 +133,17 @@ namespace MP.Data.Services if (resto == 0) { // invio in channel blink il segnale - blinkPipe.SendMessageAsync("true"); + await blinkPipe.SendMessageAsync("true"); Log.Trace("Elapsed Fast Timer Blink"); } else { // invio in channel blink segnale false - blinkPipe.SendMessageAsync("false"); + await blinkPipe.SendMessageAsync("false"); // rileggo dati... var newData = await MseGetAll(); // invio tramite la pipe... - dataPipe.SendMessageAsync(JsonConvert.SerializeObject(newData)); + await dataPipe.SendMessageAsync(JsonConvert.SerializeObject(newData)); Log.Trace("Elapsed Fast Timer reload"); } }); diff --git a/MP.Data/Services/TabDataService.cs b/MP.Data/Services/TabDataService.cs index b1771ed1..948ee410 100644 --- a/MP.Data/Services/TabDataService.cs +++ b/MP.Data/Services/TabDataService.cs @@ -505,7 +505,7 @@ namespace MP.Data.Services result = new List(); } sw.Stop(); - Log.Debug($"ConfigGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + Log.Debug($"ConfigGetAllAsync | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } @@ -1485,7 +1485,7 @@ namespace MP.Data.Services } sw.Stop(); - string callName = $"MacchineByMatrOper.{source}"; + string callName = $"MacchineByMatrOperAsync.{source}"; int numRec = esCollect.RecordCall(callName, sw.Elapsed.TotalMilliseconds); if (numRec >= nRecLog) { diff --git a/MP.Data/Services/TranslateSrv.cs b/MP.Data/Services/TranslateSrv.cs index 10af4614..d3d37010 100644 --- a/MP.Data/Services/TranslateSrv.cs +++ b/MP.Data/Services/TranslateSrv.cs @@ -83,7 +83,7 @@ namespace MP.Data.Services result = new List(); } sw.Stop(); - Log.Debug($"ConfigGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + Log.Debug($"ConfigGetAllAsync | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index c417100a..6df2a809 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2606.108 + 8.16.2606.109 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index b1927062..b3fac9ec 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                                      Versione: 8.16.2606.108

                                                      +

                                                      Versione: 8.16.2606.109


                                                      Note di rilascio:
                                                      • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index 39fc2c3d..ce4acb58 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.108 +8.16.2606.109 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index b202c947..bbab37fe 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.108 + 8.16.2606.109 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs index 7c431061..fed66bf3 100644 --- a/MP.IOC/Data/MpDataService.cs +++ b/MP.IOC/Data/MpDataService.cs @@ -797,7 +797,6 @@ namespace MP.IOC.Data else { result = await IocDbController.ConfigGetAllAsync(); - //result = await Task.FromResult(SpecDbController.ConfigGetAllAsync()); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(Utils.redisConfKey, rawData, getRandTOut(redisLongTimeCache)); @@ -944,28 +943,6 @@ namespace MP.IOC.Data return answ; } - public List FluxLogDtoGetByFlux(string Valore) - { - List answ = new List(); - DossierFluxLogDTO? result = JsonConvert.DeserializeObject(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; - } - /// /// Restituisce il valOut dell'ODL corrente (ODL deve esserci per gestione contapezzi, senza /// ODL NO invio/gestione ODL) @@ -1232,7 +1209,7 @@ namespace MP.IOC.Data } else { - result = await Task.FromResult(SpecDbController.MacchineGetFilt(codGruppo)); + result = await SpecDbController.MacchineGetFiltAsync(codGruppo); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index b8ee4b5e..5936ddb9 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2606.108 + 8.16.2606.109 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 45f2d9dc..d2952a57 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                        Versione: 8.16.2606.108

                                                        +

                                                        Versione: 8.16.2606.109


                                                        Note di rilascio:
                                                        • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 39fc2c3d..ce4acb58 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.108 +8.16.2606.109 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 11eeec80..b2b0ea2a 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.108 + 8.16.2606.109 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 7c486e88..ee1d9d49 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2606.0108 + 8.16.2606.0109 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 293c48e3..43b65f99 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                          Versione: 8.16.2606.0108

                                                          +

                                                          Versione: 8.16.2606.0109


                                                          Note di rilascio:
                                                            diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 83bdfcd4..5304e764 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0108 +8.16.2606.0109 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index 1ac7b2c6..f5944105 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0108 + 8.16.2606.0109 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index 9f766193..b94904bf 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2606.108 + 8.16.2606.109 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 87c10ba8..9d115dbc 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                            Versione: 8.16.2606.108

                                                            +

                                                            Versione: 8.16.2606.109


                                                            Note di rilascio:
                                                            • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 39fc2c3d..ce4acb58 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.108 +8.16.2606.109 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index fd37fd54..8ed448e0 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.108 + 8.16.2606.109 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 9e3d5d0a..cf4430a5 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2606.0108 + 8.16.2606.0109 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index 62e7c681..2a8036c7 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                                              Versione: 8.16.2606.0108

                                                              +

                                                              Versione: 8.16.2606.0109


                                                              Note di rilascio:
                                                                diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 83bdfcd4..5304e764 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0108 +8.16.2606.0109 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 2cd09b01..a8e8f624 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0108 + 8.16.2606.0109 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index 0740f8fc..7bdd107f 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2606.108 + 8.16.2606.109 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index ea962f3b..95f5086b 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                                Versione: 8.16.2606.108

                                                                +

                                                                Versione: 8.16.2606.109


                                                                Note di rilascio:
                                                                • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index 39fc2c3d..ce4acb58 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.108 +8.16.2606.109 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index b67b2eaa..dbf88ce9 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.108 + 8.16.2606.109 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 077b7e26..c95bce5c 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -187,7 +187,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("AnagGruppiDeleteAsync"); bool result = false; string source = "DB"; - result = dbController.AnagGruppiDelete(updRec); + result = await dbController.AnagGruppiDeleteAsync(updRec); // elimino cache redis... await FlushFusionCacheAsync(Utils.redisAnagGruppi); activity?.SetTag("data.source", source); @@ -206,7 +206,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("AnagGruppiUpsertAsync"); bool result = false; string source = "DB"; - result = dbController.AnagGruppiUpsert(UpdRec); + result = await dbController.AnagGruppiUpsertAsync(UpdRec); // elimino cache redis... await FlushFusionCacheAsync(Utils.redisAnagGruppi); activity?.SetTag("data.source", source); @@ -252,7 +252,7 @@ namespace MP.SPEC.Data operationName: "ArticleWithDossierAsync", cacheKey: Utils.redisArtByDossier, expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => await Task.FromResult(dbController.ArticleWithDossier()) ?? new List(), + fetchFunc: async () => await dbController.ArticleWithDossierAsync() ?? new List(), tagList: [Utils.redisArtByDossier] ); } @@ -285,13 +285,13 @@ namespace MP.SPEC.Data /// public async Task ArticoliDeleteRecord(AnagArticoliModel currRec) { - using var activity = ActivitySource.StartActivity("ArticoliDeleteRecord"); + using var activity = ActivitySource.StartActivity("ArticoliDeleteRecordAsync"); string source = "DB"; - bool fatto = await dbController.ArticoliDeleteRecord(currRec); + bool fatto = await dbController.ArticoliDeleteRecordAsync(currRec); await FlushFusionCacheArticoli(); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ArticoliDeleteRecord | {source} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ArticoliDeleteRecordAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); return fatto; } @@ -868,16 +868,16 @@ namespace MP.SPEC.Data /// def: 10 /// def: 50 /// - public async Task ForceDbMaint(bool doExec = true, bool doUpdStat = true, bool doSave = true, int minPgCnt = 1000, int minAvgFrag = 10, int maxAvgFragReb = 50) + public async Task ForceDbMaintAsync(bool doExec = true, bool doUpdStat = true, bool doSave = true, int minPgCnt = 1000, int minAvgFrag = 10, int maxAvgFragReb = 50) { - using var activity = ActivitySource.StartActivity("ForceDbMaint"); + using var activity = ActivitySource.StartActivity("ForceDbMaintAsync"); string source = "DB"; - await dbController.ForceDbMaint(doExec, doUpdStat, doSave, minPgCnt, minAvgFrag, maxAvgFragReb); + await dbController.ForceDbMaintAsync(doExec, doUpdStat, doSave, minPgCnt, minAvgFrag, maxAvgFragReb); // svuoto cache await FlushFusionCacheFluxLog(); activity?.SetTag("data.source", source); activity?.Stop(); - LogTrace($"ForceDbMaint | {source} | {activity?.Duration.TotalMilliseconds}ms"); + LogTrace($"ForceDbMaintAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); // registro statistiche esecuzione await RecDbMaintStatAsync(activity?.Duration ?? TimeSpan.FromSeconds(1)); } @@ -1494,7 +1494,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("POdlDeleteRecord"); string source = "DB+REDIS"; - var dbResult = await dbController.PODLDeleteRecord(currRec); + var dbResult = await dbController.PODLDeleteRecordAsync(currRec); // elimino cache redis... await FlushFusionCachePOdl(); activity?.SetTag("data.source", source); @@ -1740,65 +1740,6 @@ namespace MP.SPEC.Data return answ; } - /// - /// Effettua conteggio chaivi REDIS dato pat2Flush ricerca - /// - /// - /// - public int RedisCountKey(string keyPattern) - { - using var activity = ActivitySource.StartActivity("RedisCountKey"); - string source = "REDIS"; - int num = 0; - keyPattern = (string.IsNullOrEmpty(keyPattern) ? "**" : keyPattern); - try - { - var listEndpoints = redisConnAdmin.GetEndPoints(); - foreach (var endPoint in listEndpoints) - { - var server = redisConnAdmin.GetServer(endPoint); - foreach (RedisKey item in server.Keys(pattern: keyPattern, database: redisDb.Database, pageSize: 250, cursor: 0L)) - { - num++; - } - } - } - catch (Exception arg) - { - Log.Error($"Eccezione in RedisCountKey{Environment.NewLine}{arg}"); - } - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"RedisCountKey | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return num; - } - - /// - /// Esegue eliminazione memoria redis keyVal - /// - /// - /// - public bool RedisDelKey(string keyVal) - { - using var activity = ActivitySource.StartActivity("RedisDelKey"); - string source = "REDIS"; - bool answ = false; - var listEndpoints = redisConnAdmin.GetEndPoints(); - foreach (var endPoint in listEndpoints) - { - var server = redisConnAdmin.GetServer(endPoint); - if (server != null) - { - redisDb.KeyDelete((RedisKey)keyVal); - answ = true; - } - } - activity?.SetTag("data.source", source); - activity?.Stop(); - LogTrace($"RedisDelKey | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); - return answ; - } - /// /// Reset della cache IO post operazioni come setup ODL... /// @@ -1887,7 +1828,7 @@ namespace MP.SPEC.Data string source = "DB"; bool fatto = false; // salvo - fatto = dbController.TemplateKitUpsert(currRecord, codAzienda); + fatto = await dbController.TemplateKitUpsertAsync(currRecord, codAzienda); await FlushFusionCacheAsync(Utils.redisKitTempl); activity?.SetTag("data.source", source); activity?.Stop(); diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 01d64cb9..2d0f50e7 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2606.108 + 8.16.2606.109 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/FluxLogStatus.razor.cs b/MP.SPEC/Pages/FluxLogStatus.razor.cs index cd472022..3f758d89 100644 --- a/MP.SPEC/Pages/FluxLogStatus.razor.cs +++ b/MP.SPEC/Pages/FluxLogStatus.razor.cs @@ -114,7 +114,7 @@ namespace MP.SPEC.Pages Stopwatch sw = Stopwatch.StartNew(); lastDbMaintTime = "..."; await InvokeAsync(StateHasChanged); - await MDataServ.ForceDbMaint(true, true, true, 1000, 10, 50); + await MDataServ.ForceDbMaintAsync(true, true, true, 1000, 10, 50); sw.Stop(); lastDbMaintTime = $"{sw.Elapsed.Minutes}m {sw.Elapsed.Seconds}s"; isReindexing = false; diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 87c10ba8..9d115dbc 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                  Versione: 8.16.2606.108

                                                                  +

                                                                  Versione: 8.16.2606.109


                                                                  Note di rilascio:
                                                                  • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 39fc2c3d..ce4acb58 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.108 +8.16.2606.109 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 60fbae64..1c7d6282 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.108 + 8.16.2606.109 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 37a76526..33c7bf24 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2606.0108 + 8.16.2606.0109 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index 6363d87f..019ad772 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                                                    Versione: 8.16.2606.0108

                                                                    +

                                                                    Versione: 8.16.2606.0109


                                                                    Note di rilascio:
                                                                      diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 83bdfcd4..5304e764 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0108 +8.16.2606.0109 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index 4e89cd4f..15109b0d 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0108 + 8.16.2606.0109 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false diff --git a/Refactor_Plan.md b/Refactor_Plan.md index 89c93421..1aa90a24 100644 --- a/Refactor_Plan.md +++ b/Refactor_Plan.md @@ -17,9 +17,9 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - Analisi di `MpDataService.cs` effettuata. - Identificati i metodi con caching manuale (Redis/DB) e quelli già migrati a `GetOrFetchAsync`. -### Fase 2: Refactoring Metodi di Lettura (Cache-aside) (In corso) +### Fase 2: Refactoring Metodi di Lettura (Cache-aside) (Completata) -#### ✅ Metodi Migrati (Usano già `GetOrFetchAsync`, `FusionCache.GetOrSet` o `FlushFusionCacheByTagAsync`) +#### ✅ Metodi Migrati o Confermati (Pattern corretto per l'uso previsto) - `AnagEventiGeneralAsync` - `AnagStatiCommAsync` - `AnagTipoArtLvAsync` @@ -77,19 +77,19 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa - `POdlUpdateRecord` (Migrato con tag invalidazione) - `POdlGetByKey` (Migrato con FusionCache) - `POdlListByKitParentAsync` (Migrato con FusionCache) +- `ActionGetReq` (Pattern Redis/Channels corretto) +- `ActionSetReq` (Pattern Redis/Channels corretto) +- `DbDedupStatsAsync` (Pattern Redis persistente corretto) +- `ProcFLStats` (Pattern Redis persistente corretto) +- `RecDbMaintStatAsync` (Pattern Redis persistente corretto) -#### 🛠️ Metodi da Migrare (Usano ancora Redis/DB manuale o pattern non standard per Fusion) -- [ ] Migrazione di `ActionGetReq` (linea 110: usa `redisDb.StringGetAsync`). -- [ ] Migrazione di `ActionSetReq` (linea 136: usa `BroadastMsgPipe.saveAndSendMessage`). -- [ ] Migrazione di `DbDedupStatsAsync` (linea 516: gestione persistente su Redis, valutare se mantenere o cambiare pattern). -- [ ] Migrazione di `ProcFLStats` (linea 1853: usa `redisDb.StringGet`). -- [ ] Migrazione di `RecDbMaintStatAsync` (linea 2451: gestione persistente su Redis, valutare se mantenere o cambiare pattern). +#### 🛠️ Metodi da Migrare (Nessuno) +- *Nessun metodo residuo richiede migrazione a FusionCache.* -*(Nota: I metodi `ActionGetReq`, `ActionSetReq`, `DbDedupStatsAsync`, `ProcFLStats` e `RecDbMaintStatAsync` sono stati analizzati e, dove appropriato, confermati nel loro attuale pattern di gestione Redis/DB).* - -### Fase 4: Verifica -- [ ] Verificare la compilazione della soluzione tramite script PowerShell. -- [ ] Controllare che i log (NLog) continuano a riflettere correttamente le operazioni. +### Fase 4: Verifica (Completata) +- [x] Verificare la compilazione della soluzione tramite script PowerShell. +- [x] Controllare che i log (NLog) continuano a riflettere correttamente le operazioni. +- [x] Verifica coerenza signature (async/task/sync). ## Rischi e Mitigazioni - **Rischio**: Discrepanza nelle chiavi di cache tra vecchio e nuovo sistema. @@ -105,3 +105,4 @@ Migrare la logica di caching manuale (Redis + DB) verso l'utilizzo di `IFusionCa + From 7c9e6010102c2669e87b60553df8e061390d9f21 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 1 Jun 2026 09:44:10 +0200 Subject: [PATCH 082/102] Spostamento refactor plan x metodi SPEC --- Refactor_Plan.md => MP.SPEC/Data/Refactor_Plan.md | 0 Refactor_Plan.pdf => MP.SPEC/Data/Refactor_Plan.pdf | Bin 2 files changed, 0 insertions(+), 0 deletions(-) rename Refactor_Plan.md => MP.SPEC/Data/Refactor_Plan.md (100%) rename Refactor_Plan.pdf => MP.SPEC/Data/Refactor_Plan.pdf (100%) diff --git a/Refactor_Plan.md b/MP.SPEC/Data/Refactor_Plan.md similarity index 100% rename from Refactor_Plan.md rename to MP.SPEC/Data/Refactor_Plan.md diff --git a/Refactor_Plan.pdf b/MP.SPEC/Data/Refactor_Plan.pdf similarity index 100% rename from Refactor_Plan.pdf rename to MP.SPEC/Data/Refactor_Plan.pdf From 213eb35be186da6bf63c6b159c514a90055e6770 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 1 Jun 2026 13:54:21 +0200 Subject: [PATCH 083/102] Refresh compilazioni --- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index 6df2a809..c5a7f331 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2606.109 + 8.16.2606.113 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index b3fac9ec..19fc2e90 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                                                      Versione: 8.16.2606.109

                                                                      +

                                                                      Versione: 8.16.2606.113


                                                                      Note di rilascio:
                                                                      • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index ce4acb58..142014de 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.109 +8.16.2606.113 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index bbab37fe..4c8d4a7e 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.109 + 8.16.2606.113 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 5936ddb9..4b13e62b 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2606.109 + 8.16.2606.113 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index d2952a57..386f99ae 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                                        Versione: 8.16.2606.109

                                                                        +

                                                                        Versione: 8.16.2606.113


                                                                        Note di rilascio:
                                                                        • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index ce4acb58..142014de 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.109 +8.16.2606.113 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index b2b0ea2a..62319e01 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.109 + 8.16.2606.113 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index ee1d9d49..fa1991a8 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2606.0109 + 8.16.2606.0113 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 43b65f99..fa3e2870 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                                          Versione: 8.16.2606.0109

                                                                          +

                                                                          Versione: 8.16.2606.0113


                                                                          Note di rilascio:
                                                                            diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 5304e764..5e53158e 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0109 +8.16.2606.0113 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index f5944105..44a961c6 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0109 + 8.16.2606.0113 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index b94904bf..7c5b2eeb 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2606.109 + 8.16.2606.113 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 9d115dbc..91e3fb3c 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                            Versione: 8.16.2606.109

                                                                            +

                                                                            Versione: 8.16.2606.113


                                                                            Note di rilascio:
                                                                            • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index ce4acb58..142014de 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.109 +8.16.2606.113 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index 8ed448e0..ab4aa2e7 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.109 + 8.16.2606.113 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index cf4430a5..91c9f10d 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2606.0109 + 8.16.2606.0113 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index 2a8036c7..4dfd359b 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                                                              Versione: 8.16.2606.0109

                                                                              +

                                                                              Versione: 8.16.2606.0113


                                                                              Note di rilascio:
                                                                                diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 5304e764..5e53158e 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0109 +8.16.2606.0113 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index a8e8f624..6325cd45 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0109 + 8.16.2606.0113 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index 7bdd107f..1f7aa719 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2606.109 + 8.16.2606.113 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index 95f5086b..e367897f 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                                                Versione: 8.16.2606.109

                                                                                +

                                                                                Versione: 8.16.2606.113


                                                                                Note di rilascio:
                                                                                • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index ce4acb58..142014de 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.109 +8.16.2606.113 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index dbf88ce9..c0386092 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.109 + 8.16.2606.113 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 33c7bf24..37fb2ac3 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2606.0109 + 8.16.2606.0113 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index 019ad772..31157f85 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                                                                  Versione: 8.16.2606.0109

                                                                                  +

                                                                                  Versione: 8.16.2606.0113


                                                                                  Note di rilascio:
                                                                                    diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 5304e764..5e53158e 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0109 +8.16.2606.0113 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index 15109b0d..487a23f2 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0109 + 8.16.2606.0113 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false From d2e82d720966aeaf2a2f4e5c86c3e00f4c913949 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 1 Jun 2026 13:55:27 +0200 Subject: [PATCH 084/102] Rename controller --> repositori x spec --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- .../Controllers/{MpSpecController.cs => MpSpecRepository.cs} | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename MP.Data/Controllers/{MpSpecController.cs => MpSpecRepository.cs} (100%) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index 104cd909..b4b8e6e8 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2606.109 + 8.16.2606.113 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 9d115dbc..91e3fb3c 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                                    Versione: 8.16.2606.109

                                                                                    +

                                                                                    Versione: 8.16.2606.113


                                                                                    Note di rilascio:
                                                                                    • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index ce4acb58..142014de 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.109 +8.16.2606.113 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index 819108c5..9170deab 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.109 + 8.16.2606.113 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.Data/Controllers/MpSpecController.cs b/MP.Data/Controllers/MpSpecRepository.cs similarity index 100% rename from MP.Data/Controllers/MpSpecController.cs rename to MP.Data/Controllers/MpSpecRepository.cs From 3ea4b778279e2a83ec6159d8902e17e378d626cf Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 1 Jun 2026 13:56:14 +0200 Subject: [PATCH 085/102] pre-update descrizioni --- MP.Data/Repositories/IAnagRepository.cs | 37 +++++++++++++++++++ MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- MP.SPEC/refactor_repository.md | 47 ++++++++++++++++++++++++ MP.SPEC/refactor_repository.pdf | Bin 0 -> 91727 bytes 7 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 MP.Data/Repositories/IAnagRepository.cs create mode 100644 MP.SPEC/refactor_repository.md create mode 100644 MP.SPEC/refactor_repository.pdf diff --git a/MP.Data/Repositories/IAnagRepository.cs b/MP.Data/Repositories/IAnagRepository.cs new file mode 100644 index 00000000..8cbbbc98 --- /dev/null +++ b/MP.Data/Repositories/IAnagRepository.cs @@ -0,0 +1,37 @@ +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using MP.Core.DTO; +using MP.Core.Objects; +using MP.Data.DbModels; +using NLog; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace MP.Data.Repositories +{ + public interface IAnagRepository + { + Task AnagCountersGetNextAsync(string cntType); + Task> AnagEventiGeneralAsync(); + Task AnagGruppiDeleteAsync(AnagGruppiModel updRec); + Task AnagGruppiUpsertAsync(AnagGruppiModel UpdRec); + Task> AnagStatiCommAsync(); + Task> AnagTipoArtLvAsync(); + Task> ArticleWithDossierAsync(); + Task ArticoliCountSearchAsync(string tipo = "*", string azienda = "*", string searchVal = ""); + Task> ArticoliGetByTipoAsync(string tipo, string azienda = "*"); + Task> ArticoliGetSearchAsync(int numRecord, string tipoArt, string azienda, string searchVal); + Task> ArticoliInKitAsync(); + Task ArticoliDeleteRecord(AnagArticoliModel currRec); + Task ArticoliUpdateRecord(AnagArticoliModel currRec); + Task> ListValuesFiltAsync(string tabName, string fieldName); + Task> MacchineByMatrOper(int MatrOpr); + Task> MacchineGetFiltAsync(string codGruppo); + Task> VocabolarioGetLang(string lingua); + Task VocabolarioUpsertAsync(VocabolarioModel upsRec); + } +} diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 2d0f50e7..7dc37fbb 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2606.109 + 8.16.2606.113 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 9d115dbc..91e3fb3c 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                                      Versione: 8.16.2606.109

                                                                                      +

                                                                                      Versione: 8.16.2606.113


                                                                                      Note di rilascio:
                                                                                      • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index ce4acb58..142014de 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.109 +8.16.2606.113 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 1c7d6282..1f1a8e1b 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.109 + 8.16.2606.113 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/refactor_repository.md b/MP.SPEC/refactor_repository.md new file mode 100644 index 00000000..e804649b --- /dev/null +++ b/MP.SPEC/refactor_repository.md @@ -0,0 +1,47 @@ +# ?? Proposta di Refactoring: Decomposizione MpSpecController + +## 1. Situazione Attuale (AS-IS) +* **Componente**: MpSpecController (situato in MP.Data\Controllers\). +* **Pattern**: "God Object" / Monolithic Repository. +* **Problemi identificati**: + * **Violazione SRP**: Gestisce entità eterogenee (Anagrafiche, Produzione, Dossier, Configurazione, Log). + * **Naming**: Il suffisso Controller è fuorviante (indica un livello API, mentre il ruolo è di Repository). + * **Manutenibilità**: Elevato rischio di regressioni durante le modifiche a causa dell'accorpamento di logiche diverse. + * **Testabilità**: Difficoltà estrema nel mockare le dipendenze (molteplici DbContext e parametri di configurazione) in un unico oggetto. + * **Accoppiamento**: MpDataService dipende da un unico, enorme oggetto per ogni operazione di persistenza. + +## 2. Situazione Proposta (TO-BE) +* **Trasformazione**: MpSpecController viene rinominato in MpSpecRepository (come fallback o hub centrale temporaneo) e poi progressivamente svuotato. +* **Nuova Architettura**: Introduzione di Repository specializzati per **Domini Logici**, ognuno con la propria interfaccia (I...Repository). +* **Iniezione delle Dipendenze**: MpDataService smetterà di iniettare un unico repository e inizierà a iniettare solo i moduli di cui ha realmente bisogno (es. IAnagRepository, IProductionRepository, ecc.). +* **Standardizzazione**: Ogni repository gestirà esclusivamente il proprio DbContext di riferimento. + +## 3. Elenco Repository da Creare (Domain Grouping) + +| Repository | Responsabilità (entità/Modelli) | Context Target | +| :--- | :--- | :--- | +| **IAnagRepository** | AnagGruppi, AnagArticoli, AnagOperatori, AnagStatiComm, AnagTipoArtLv, Vocabolario, Parametri | MoonProContext | +| **IProductionRepository** | ODL, PODL, IstanzeKit, TemplateKit, WipKit, Macchine, Gruppi2Macc/Oper | MoonProContext | +| **IDossierRepository** | Dossier, DossierFluxLog | MoonProContext | +| **IFluxLogRepository** | FluxLog, StatDedupDTO, ParetoFluxLog | MoonPro_FluxContext | +| **ISystemRepository** | LinkMenu, Config, Manutenzione DB | MoonProContext / MoonProAdminContext | + +## 4. Checklist Avanzamento Modifiche + +### Fase 1: Preparazione (Infrastruttura) +- [ ] Creazione file +efactor_repository.md. +- [ ] Analisi delle interfacce necessarie per ogni dominio. +- [ ] Rinomina MpSpecController $\rightarrow$ MpSpecRepository (per allineamento naming). + +### Fase 2: Estrazione Modulare (Iterativa) +- [ ] **Modulo Anagrafica**: Creazione AnagRepository $\rightarrow$ Spostamento metodi $\rightarrow$ Aggiornamento MpDataService. +- [ ] **Modulo Produzione**: Creazione ProductionRepository $\rightarrow$ Spostamento metodi $\rightarrow$ Aggiornamento MpDataService. +- [ ] **Modulo Dossier**: Creazione DossierRepository $\rightarrow$ Spostamento metodi $\rightarrow$ Aggiornamento MpDataService. +- [ ] **Modulo FluxLog**: Creazione FluxLogRepository $\rightarrow$ Spostamento metodi $\rightarrow$ Aggiornamento MpDataService. +- [ ] **Modulo Sistema**: Creazione SystemRepository $\rightarrow$ Spostamento metodi $\rightarrow$ Aggiornamento MpDataService. + +### Fase 3: Pulizia e Verifica +- [ ] Rimozione del codice residuo da MpSpecRepository. +- [ ] Verifica della compilazione della soluzione (./build_all_par.ps1 --agent). +- [ ] Verifica della coerenza dei log e della persistenza dei dati. diff --git a/MP.SPEC/refactor_repository.pdf b/MP.SPEC/refactor_repository.pdf new file mode 100644 index 0000000000000000000000000000000000000000..806fa38d45a4b12778b690b29fe1fa25ca59b86b GIT binary patch literal 91727 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 literal 0 HcmV?d00001 From 5c20387e1da4c4f8fdcced58e0e223741b8ec37a Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 1 Jun 2026 16:43:40 +0200 Subject: [PATCH 086/102] Inizio setup repository --- MP.Data/DataServiceCollectionExtensions.cs | 50 +++ MP.Data/Repositories/IAnagRepository.cs | 37 -- MP.Data/Repository/Anag/AnagRepository.cs | 417 +++++++++++++++++++++ MP.Data/Repository/Anag/BaseRepository.cs | 31 ++ MP.Data/Repository/Anag/IAnagRepository.cs | 186 +++++++++ MP.Data/Repository/Anag/IBaseRepository.cs | 8 + MP.Data/Repository/IOC/BaseRepository.cs | 21 +- MP.Data/Repository/Utils/BaseRepository.cs | 20 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.SPEC/Components/AskCloseOdl.razor.cs | 3 +- MP.SPEC/Data/MpDataService.cs | 6 +- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Test.razor | 2 +- MP.SPEC/Pages/Test.razor.cs | 8 +- MP.SPEC/Program.cs | 29 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 21 files changed, 738 insertions(+), 96 deletions(-) delete mode 100644 MP.Data/Repositories/IAnagRepository.cs create mode 100644 MP.Data/Repository/Anag/AnagRepository.cs create mode 100644 MP.Data/Repository/Anag/BaseRepository.cs create mode 100644 MP.Data/Repository/Anag/IAnagRepository.cs create mode 100644 MP.Data/Repository/Anag/IBaseRepository.cs diff --git a/MP.Data/DataServiceCollectionExtensions.cs b/MP.Data/DataServiceCollectionExtensions.cs index 2ff337b3..f649a7a0 100644 --- a/MP.Data/DataServiceCollectionExtensions.cs +++ b/MP.Data/DataServiceCollectionExtensions.cs @@ -1,9 +1,12 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using MP.AppAuth.Services; using MP.Data.Controllers; +using MP.Data.Repository.Anag; using MP.Data.Repository.IOC; using MP.Data.Repository.Mtc; using MP.Data.Repository.Utils; +using MP.Data.Services; using MP.Data.Services.IOC; using MP.Data.Services.Mtc; using MP.Data.Services.Utils; @@ -12,6 +15,11 @@ namespace MP.Data { public static class DataServiceCollectionExtensions { + /// + /// Aggiunta repository/servizi specifici per IOC + /// + /// + /// public static IServiceCollection AddIocDataLayer(this IServiceCollection services) { // Repository Singleton @@ -31,6 +39,48 @@ namespace MP.Data services.TryAddScoped(); services.TryAddScoped(); + return services; + } + /// + /// Aggiunta repository/servizi specifici per SPEC + /// + /// + /// + public static IServiceCollection AddSpecDataLayer(this IServiceCollection services) + { + // ---------- Start Repository ---------- + // Singleton + services.TryAddSingleton(); + + // Scoped + + + // ---------- End Repository ---------- + + + // ---------- Start Servizi ---------- + + // Singleton + + // Scoped + + // ---------- End Servizi ---------- + + + // ---------- Start Altro ---------- + // Singleton + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + + // Scoped + services.AddScoped(); + services.AddScoped(); + + // ---------- End Altro ---------- + return services; } } diff --git a/MP.Data/Repositories/IAnagRepository.cs b/MP.Data/Repositories/IAnagRepository.cs deleted file mode 100644 index 8cbbbc98..00000000 --- a/MP.Data/Repositories/IAnagRepository.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Microsoft.Data.SqlClient; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; -using MP.Core.DTO; -using MP.Core.Objects; -using MP.Data.DbModels; -using NLog; -using System; -using System.Collections.Generic; -using System.Data; -using System.Linq; -using System.Threading.Tasks; - -namespace MP.Data.Repositories -{ - public interface IAnagRepository - { - Task AnagCountersGetNextAsync(string cntType); - Task> AnagEventiGeneralAsync(); - Task AnagGruppiDeleteAsync(AnagGruppiModel updRec); - Task AnagGruppiUpsertAsync(AnagGruppiModel UpdRec); - Task> AnagStatiCommAsync(); - Task> AnagTipoArtLvAsync(); - Task> ArticleWithDossierAsync(); - Task ArticoliCountSearchAsync(string tipo = "*", string azienda = "*", string searchVal = ""); - Task> ArticoliGetByTipoAsync(string tipo, string azienda = "*"); - Task> ArticoliGetSearchAsync(int numRecord, string tipoArt, string azienda, string searchVal); - Task> ArticoliInKitAsync(); - Task ArticoliDeleteRecord(AnagArticoliModel currRec); - Task ArticoliUpdateRecord(AnagArticoliModel currRec); - Task> ListValuesFiltAsync(string tabName, string fieldName); - Task> MacchineByMatrOper(int MatrOpr); - Task> MacchineGetFiltAsync(string codGruppo); - Task> VocabolarioGetLang(string lingua); - Task VocabolarioUpsertAsync(VocabolarioModel upsRec); - } -} diff --git a/MP.Data/Repository/Anag/AnagRepository.cs b/MP.Data/Repository/Anag/AnagRepository.cs new file mode 100644 index 00000000..c68cd626 --- /dev/null +++ b/MP.Data/Repository/Anag/AnagRepository.cs @@ -0,0 +1,417 @@ +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; +using MP.Core.DTO; +using MP.Data.DbModels; +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace MP.Data.Repository.Anag +{ + public class AnagRepository : BaseRepository, IAnagRepository + { + public AnagRepository(IDbContextFactory ctxFactory) : base(ctxFactory) + { + } + + /// + public async Task AnagCountersGetNextAsync(string cntType) + { + AnagCountersModel answ = new AnagCountersModel(); + await using var dbCtx = await CreateContextAsync(); + bool outTable = true; + if (outTable) + { + var pCntType = new SqlParameter("@CntType", cntType); + var pLastNum = new SqlParameter + { + ParameterName = "@LastNum", + SqlDbType = SqlDbType.Int, + Direction = ParameterDirection.Output + }; + + var dbResult = await dbCtx + .DbSetAnagCount + .FromSqlRaw("EXEC dbo.stp_getNextNumb @CntType, @LastNum OUTPUT", pCntType, pLastNum) + .AsNoTracking() + .FirstOrDefaultAsync(); + if (dbResult != null) + { + answ = dbResult; + } + } + else + { + var pCntType = new SqlParameter("@CntType", cntType); + var pLastNum = new SqlParameter + { + ParameterName = "@LastNum", + SqlDbType = SqlDbType.Int, + Direction = ParameterDirection.Output + }; + var pCntCode = new SqlParameter + { + ParameterName = "@CntCode", + SqlDbType = SqlDbType.NVarChar, + Direction = ParameterDirection.Output + }; + var dbResult = await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC dbo.stp_getNextNumb @CntType, @LastNum OUTPUT, @CntCode OUTPUT", pCntType, pLastNum, pCntCode); + if (dbResult != 0) + { + answ.CntType = cntType; + answ.CntCode = $"{pCntCode.Value}"; + int lNum = 0; + int.TryParse($"{pLastNum.Value}", out lNum); + answ.LastNum = lNum; + } + } + return answ; + } + + /// + public async Task> AnagEventiGeneralAsync(string TableName = "EvList", string FieldName = "Common") + { + await using var dbCtx = await CreateContextAsync(); + var pTableName = new SqlParameter("@TableName", TableName); + var pFieldName = new SqlParameter("@FieldName", FieldName); + var dbResult = await dbCtx + .DbSetVSEB + .FromSqlRaw("exec dbo.stp_vseb_getGenerallyAvailable @TableName, @FieldName", pTableName, pFieldName) + .AsNoTracking() + .ToListAsync(); + return dbResult ?? new(); + } + + /// + public async Task> AnagGruppiAziendeAsync() + { + return await AnagGruppiGetTipoAsync("AZIENDA"); + } + + /// + public async Task AnagGruppiDeleteAsync(AnagGruppiModel updRec) + { + await using var dbCtx = await CreateContextAsync(); + var dbRec = await dbCtx + .DbSetAnagGruppi + .AsNoTracking() + .Where(x => x.CodGruppo == updRec.CodGruppo) + .FirstOrDefaultAsync(); + if (dbRec != null) + { + dbCtx.DbSetAnagGruppi.Remove(dbRec); + } + var numRes = await dbCtx.SaveChangesAsync(); + return numRes != 0; + } + + /// + public async Task> AnagGruppiFaseAsync() + { + return await AnagGruppiGetTipoAsync("FASE"); + } + + /// + public async Task> AnagGruppiGetTipoAsync(string tipoGruppo) + { + await using var dbCtx = await CreateContextAsync(); + return await dbCtx + .DbSetAnagGruppi + .Where(x => x.TipoGruppo == tipoGruppo) + .AsNoTracking() + .OrderBy(x => x.CodGruppo) + .ToListAsync(); + } + + /// + public async Task> AnagGruppiRepartoDtoAsync() + { + await using var dbCtx = await CreateContextAsync(); + var listReparti = await AnagGruppiGetTipoAsync("REPARTO"); + + var listMacc = await dbCtx + .DbSetGrp2Macc + .AsNoTracking() + .ToListAsync(); + var listOpr = await dbCtx + .DbSetGrp2Oper + .AsNoTracking() + .ToListAsync(); + + return listReparti + .Select(x => new RepartiDTO() + { + CodGruppo = x.CodGruppo, + TipoGruppo = x.TipoGruppo, + DescrGruppo = x.DescrGruppo, + SelEnabled = x.SelEnabled, + CountMacc = listMacc.Where(y => y.CodGruppo == x.CodGruppo).Select(y => y.IdxMacchina).Distinct().Count(), + CountOpr = listOpr.Where(y => y.CodGruppo == x.CodGruppo).Select(y => y.MatrOpr).Distinct().Count() + }) + .ToList(); + } + + /// + public async Task AnagGruppiUpsertAsync(AnagGruppiModel updRec) + { + await using var dbCtx = await CreateContextAsync(); + var dbRec = await dbCtx + .DbSetAnagGruppi + .AsNoTracking() + .Where(x => x.CodGruppo == updRec.CodGruppo) + .FirstOrDefaultAsync(); + if (dbRec != null) + { + dbRec.DescrGruppo = updRec.DescrGruppo; + dbCtx.Entry(dbRec).State = EntityState.Modified; + } + else + { + await dbCtx.DbSetAnagGruppi.AddAsync(updRec); + } + var numRes = await dbCtx.SaveChangesAsync(); + return numRes != 0; + } + + /// + public async Task> AnagStatiCommAsync() + { + return await ListValuesFiltAsync("PODL", "StatoComm"); + } + + /// + public async Task> AnagTipoArtLvAsync() + { + return await ListValuesFiltAsync("AnagArticoli", "Tipo"); + } + +#if false + /// + public async Task> ArticleWithDossierAsync() + { + using var dbCtx = new MoonPro_FluxContext(_configuration); + return await dbCtx + .DbSetDossiers + .AsNoTracking() + .Select(i => i.CodArticolo) + .Distinct() + .ToListAsync(); + } +#endif + + /// + public async Task ArticoliCountAsync() + { + await using var dbCtx = await CreateContextAsync(); + return await dbCtx.DbSetArticoli.CountAsync(); + } + + /// + public async Task ArticoliCountSearchAsync(string tipoArt = "*", string azienda = "*", string searchVal = "") + { + await using var dbCtx = await CreateContextAsync(); + IQueryable query = dbCtx.DbSetArticoli.AsNoTracking(); + + if (tipoArt != "*") + { + query = query.Where(x => EF.Functions.Like(x.Tipo, tipoArt)); + } + if (azienda != "*") + { + query = query.Where(x => EF.Functions.Like(x.Azienda, azienda)); + } + if (!string.IsNullOrWhiteSpace(searchVal)) + { + string pattern = $"%{searchVal}%"; + query = query.Where(x => + EF.Functions.Like(x.CodArticolo, pattern) || + EF.Functions.Like(x.DescArticolo, pattern) || + EF.Functions.Like(x.Disegno, pattern)); + } + + return await query.OrderBy(x => x.CodArticolo).CountAsync(); + } + + /// + public async Task ArticoliDeleteRecordAsync(AnagArticoliModel currRec) + { + await using var dbCtx = await CreateContextAsync(); + var currVal = await dbCtx + .DbSetArticoli + .Where(x => x.CodArticolo == currRec.CodArticolo) + .FirstOrDefaultAsync(); + if (currVal != null) + { + dbCtx.DbSetArticoli.Remove(currVal); + return await dbCtx.SaveChangesAsync() > 0; + } + return false; + } + + /// + public async Task> ArticoliGetByTipoAsync(string tipo, string azienda = "*") + { + await using var dbCtx = await CreateContextAsync(); + return await dbCtx + .DbSetArticoli + .AsNoTracking() + .Where(x => x.Tipo.ToUpper() == tipo.ToUpper() && (azienda == "*" || x.Azienda.ToUpper() == azienda.ToUpper())) + .OrderBy(x => x.CodArticolo) + .ToListAsync(); + } + + /// + public async Task> ArticoliGetSearchAsync(int numRecord, string tipoArt = "*", string azienda = "*", string searchVal = "") + { + await using var dbCtx = await CreateContextAsync(); + IQueryable query = dbCtx.DbSetArticoli.AsNoTracking(); + + if (tipoArt != "*") + { + query = query.Where(x => EF.Functions.Like(x.Tipo, tipoArt)); + } + if (azienda != "*") + { + query = query.Where(x => EF.Functions.Like(x.Azienda, azienda)); + } + if (!string.IsNullOrWhiteSpace(searchVal)) + { + string pattern = $"%{searchVal}%"; + query = query.Where(x => + EF.Functions.Like(x.CodArticolo, pattern) || + EF.Functions.Like(x.DescArticolo, pattern) || + EF.Functions.Like(x.Disegno, pattern)); + } + + return await query.OrderBy(x => x.CodArticolo).Take(numRecord).ToListAsync(); + } + + /// + public async Task> ArticoliGetUnusedAsync() + { + await using var dbCtx = await CreateContextAsync(); + return await dbCtx.DbSetArticoli.FromSqlRaw("EXEC stp_ART_getNotUsed").AsNoTracking().ToListAsync(); + } + + /// + public async Task> ArticoliGetUsedAsync() + { + await using var dbCtx = await CreateContextAsync(); + return await dbCtx.DbSetArticoli.FromSqlRaw("EXEC stp_ART_getUsed").AsNoTracking().ToListAsync(); + } + + /// + public async Task> ArticoliInKitAsync() + { + await using var dbCtx = await CreateContextAsync(); + return await dbCtx.DbSetArticoli.FromSqlRaw("EXEC stp_TempKIT_getArtChild").AsNoTracking().ToListAsync(); + } + + /// + public async Task ArticoliUpdateRecord(AnagArticoliModel editRec) + { + await using var dbCtx = await CreateContextAsync(); + var currRec = await dbCtx.DbSetArticoli.FirstOrDefaultAsync(x => x.CodArticolo == editRec.CodArticolo); + if (currRec != null) + { + currRec.Disegno = editRec.Disegno; + currRec.DescArticolo = editRec.DescArticolo; + currRec.Tipo = editRec.Tipo; + currRec.Azienda = editRec.Azienda; + dbCtx.Entry(currRec).State = EntityState.Modified; + return await dbCtx.SaveChangesAsync() > 0; + } + return false; + } + + /// + public async Task> ListValuesFiltAsync(string tabName, string fieldName) + { + await using var dbCtx = await CreateContextAsync(); + return await dbCtx.DbSetListValues + .Where(x => x.TableName == tabName && x.FieldName == fieldName) + .AsNoTracking() + .OrderBy(x => x.ordinal) + .ToListAsync(); + } + + /// + public async Task> MacchineByMatrOperAsync(int MatrOpr) + { + await using var dbCtx = await CreateContextAsync(); + if (MatrOpr == 0) + { + return await dbCtx.DbSetMacchine.AsNoTracking().OrderBy(x => x.IdxMacchina).ToListAsync(); + } + else + { + return await dbCtx.DbSetGrp2Oper + .Where(g => g.MatrOpr == MatrOpr) + .Join(dbCtx.DbSetGrp2Macc, g => g.CodGruppo, m => m.CodGruppo, (g, m) => m) + .Distinct() + .Join(dbCtx.DbSetMacchine, g => g.IdxMacchina, m => m.IdxMacchina, (g, m) => m) + .Distinct() + .AsNoTracking() + .OrderBy(x => x.IdxMacchina) + .ToListAsync(); + } + } + + /// + public async Task> MacchineGetFiltAsync(string codGruppo) + { + await using var dbCtx = await CreateContextAsync(); + if (codGruppo == "*") + { + return await dbCtx.DbSetMacchine.AsNoTracking().OrderBy(x => x.IdxMacchina).ToListAsync(); + } + else + { + return await dbCtx.DbSetGrp2Macc + .Where(g => g.CodGruppo == codGruppo) + .Join(dbCtx.DbSetMacchine, g => g.IdxMacchina, m => m.IdxMacchina, (g, m) => m) + .AsNoTracking() + .OrderBy(x => x.IdxMacchina) + .ToListAsync(); + } + } + + /// + public async Task> PODL_getDictOdlPodlAsync(List missingIds) + { + if (missingIds == null || !missingIds.Any()) + return new Dictionary(); + + await using var dbCtx = await CreateContextAsync(); + return await dbCtx + .DbSetPODL + .AsNoTracking() + .Where(x => missingIds.Contains(x.IdxOdl)) + .ToDictionaryAsync(x => x.IdxOdl, x => x.IdxPromessa); + } + + /// + /// Recupero dizionario traduzioni da cache o DB + /// + /// Codice lingua + /// Dizionario di traduzioni + public async Task> VocabolarioGetLangAsync(string lingua) + { + await using var dbCtx = await CreateContextAsync(); + var rawList = dbCtx + .DbSetVocabolario + .AsNoTracking() + .Where(x => x.Lingua.ToLower() == lingua.ToLower()) + .OrderBy(x => x.Lemma) + .ToList(); + // Proietto in dizionario + return rawList + .DistinctBy(t => t.Lemma, StringComparer.OrdinalIgnoreCase) + .ToDictionary(t => t.Lemma, t => t.Traduzione, StringComparer.OrdinalIgnoreCase); + } + } +} diff --git a/MP.Data/Repository/Anag/BaseRepository.cs b/MP.Data/Repository/Anag/BaseRepository.cs new file mode 100644 index 00000000..bc26dc68 --- /dev/null +++ b/MP.Data/Repository/Anag/BaseRepository.cs @@ -0,0 +1,31 @@ +using Microsoft.EntityFrameworkCore; +using System.Threading.Tasks; + +namespace MP.Data.Repository.Anag +{ + public abstract class BaseRepository : IBaseRepository + { + #region Protected Fields + + protected readonly IDbContextFactory _ctxFactory; + + #endregion Protected Fields + + #region Protected Constructors + + protected BaseRepository(IDbContextFactory ctxFactory) => _ctxFactory = ctxFactory; + + #endregion Protected Constructors + + #region Protected Methods + + /// + /// Creazione dbcontext per singola transazione + /// + /// + protected async Task CreateContextAsync() => await _ctxFactory.CreateDbContextAsync(); + + #endregion Protected Methods + + } +} \ No newline at end of file diff --git a/MP.Data/Repository/Anag/IAnagRepository.cs b/MP.Data/Repository/Anag/IAnagRepository.cs new file mode 100644 index 00000000..e817d469 --- /dev/null +++ b/MP.Data/Repository/Anag/IAnagRepository.cs @@ -0,0 +1,186 @@ +using MP.Core.DTO; +using MP.Data.DbModels; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace MP.Data.Repository.Anag +{ + public interface IAnagRepository + { + /// + /// Stacca un nuovo counter x il tipo richiesto + /// + /// Tipo di contatore + /// Modello del contatore aggiornato + Task AnagCountersGetNextAsync(string cntType); + + /// + /// Restituisce l'anagrafica EVENTI generalmente disponibile per OGNI macchina + /// + /// Nome Table x filtro (std: EvList) + /// Nome Field x filtro (std: Common) + /// Lista di eventi generali + Task> AnagEventiGeneralAsync(string TableName = "EvList", string FieldName = "Common"); + + /// + /// Elenco Gruppi tipo Azienda + /// + /// Lista di modelli anagrafica gruppi + Task> AnagGruppiAziendeAsync(); + + /// + /// Delete record AnagraficaGruppi + /// + /// Record da eliminare + /// True se l'eliminazione avvenuta + Task AnagGruppiDeleteAsync(AnagGruppiModel updRec); + + /// + /// Elenco Gruppi tipo Fasi + /// + /// Lista di modelli anagrafica gruppi + Task> AnagGruppiFaseAsync(); + + /// + /// Gruppi x tipo modalit Async + /// + /// Tipo di gruppo (es. REPARTO, FASE, AZIENDA) + /// Lista di modelli anagrafica gruppi + Task> AnagGruppiGetTipoAsync(string tipoGruppo); + + /// + /// Elenco Gruppi tipo REPARTO (x associazione Macchine-Operatori) in formato DTO con conteggi del numero record trovati + /// + /// Lista di DTO reparti con conteggio macchine e operatori + Task> AnagGruppiRepartoDtoAsync(); + + /// + /// Upsert record AnagraficaGruppi (solo codice/descrizione) + /// + /// Record da inserire o aggiornare + /// True se l'operazione riuscita + Task AnagGruppiUpsertAsync(AnagGruppiModel updRec); + + /// + /// Elenco valori ammessi x Stati commessa (es Yacht Baglietto) + /// + /// Lista di valori ammessi + Task> AnagStatiCommAsync(); + + /// + /// Elenco valori ammessi x Tipo articoli + /// + /// Lista di valori ammessi + Task> AnagTipoArtLvAsync(); + +#if false + /// + /// Elenco codice articoli che abbiano dati Dossier + /// + /// Lista di codici articolo + Task> ArticleWithDossierAsync(); +#endif + + /// + /// Conteggio num articoli Async + /// + /// Conteggio totale articoli + Task ArticoliCountAsync(); + + /// + /// Conteggio articoli data condizione ricerca + /// + /// Tipo articolo + /// Azienda + /// Valore di ricerca + /// Conteggio risultati ricerca + Task ArticoliCountSearchAsync(string tipoArt = "*", string azienda = "*", string searchVal = ""); + + /// + /// Eliminazione Record Articolo + /// + /// Record da eliminare + /// True se eliminato + Task ArticoliDeleteRecordAsync(AnagArticoliModel currRec); + + /// + /// Restituisce elenco articoli dato tipo (es KIT) + /// + /// Tipo articolo (es. KIT) + /// Azienda (opzionale) + /// Lista di articoli per tipo + Task> ArticoliGetByTipoAsync(string tipo, string azienda = "*"); + + /// + /// Elenco tabella Articoli da filtro + /// + /// Numero massimo di record + /// Tipo articolo + /// Azienda + /// Valore di ricerca + /// Lista di articoli cercati + Task> ArticoliGetSearchAsync(int numRecord, string tipoArt = "*", string azienda = "*", string searchVal = ""); + + /// + /// Elenco tabella Articoli NON IMPIEGATI (da stored stp_ART_getUsed) Async + /// + /// Lista di articoli non impiegati + Task> ArticoliGetUnusedAsync(); + + /// + /// Elenco tabella Articoli IMPIEGATI (da stored stp_ART_getUsed) Async + /// + /// Lista di articoli impiegati + Task> ArticoliGetUsedAsync(); + + /// + /// Elenco Articoli che sono in KIT Child + /// + /// Lista di articoli in kit + Task> ArticoliInKitAsync(); + + /// + /// Update Record Articolo + /// + /// Record da aggiornare + /// True se aggiornato + Task ArticoliUpdateRecord(AnagArticoliModel editRec); + + /// + /// Elenco valori ammessi x tabella/colonna Async + /// + /// Nome tabella + /// Nome colonna + /// Lista di valori ammessi + Task> ListValuesFiltAsync(string tabName, string fieldName); + + /// + /// Elenco Macchine dato operatore secondo gruppi (macchine/operatore) + /// + /// Matricola operatore + /// Lista di macchine + Task> MacchineByMatrOperAsync(int MatrOpr); + + /// + /// Elenco da tabella Macchine filtro x gruppo + /// + /// Codice gruppo + /// Lista di macchine + Task> MacchineGetFiltAsync(string codGruppo); + + /// + /// Dizionario associazione ODL/PODL + /// + /// Lista di ID mancanti + /// Dizionario di associazione + Task> PODL_getDictOdlPodlAsync(List missingIds); + + /// + /// Recupero dizionario traduzioni da cache o DB + /// + /// Codice lingua + /// Dizionario di traduzioni + Task> VocabolarioGetLangAsync(string lingua); + + } +} diff --git a/MP.Data/Repository/Anag/IBaseRepository.cs b/MP.Data/Repository/Anag/IBaseRepository.cs new file mode 100644 index 00000000..246d20f6 --- /dev/null +++ b/MP.Data/Repository/Anag/IBaseRepository.cs @@ -0,0 +1,8 @@ +namespace MP.Data.Repository.Anag +{ + public interface IBaseRepository + { + //Task CreateContextAsync(); + //Task SaveChangesAsync(DataLayerContext ctx); + } +} diff --git a/MP.Data/Repository/IOC/BaseRepository.cs b/MP.Data/Repository/IOC/BaseRepository.cs index 7814ee85..50877a21 100644 --- a/MP.Data/Repository/IOC/BaseRepository.cs +++ b/MP.Data/Repository/IOC/BaseRepository.cs @@ -13,8 +13,7 @@ namespace MP.Data.Repository.IOC #region Protected Constructors - protected BaseRepository(IDbContextFactory ctxFactory) - => _ctxFactory = ctxFactory; + protected BaseRepository(IDbContextFactory ctxFactory) => _ctxFactory = ctxFactory; #endregion Protected Constructors @@ -24,24 +23,8 @@ namespace MP.Data.Repository.IOC /// Creazione dbcontext per singola transazione ///
                                                        /// - protected async Task CreateContextAsync() - => await _ctxFactory.CreateDbContextAsync(); + protected async Task CreateContextAsync() => await _ctxFactory.CreateDbContextAsync(); #endregion Protected Methods - -#if false - /// - /// Salvataggio dati asincrono - /// - /// - protected async Task SaveChangesAsync(DataLayerContext ctx) - => await ctx.SaveChangesAsync() > 0; -#endif - -#if false - protected readonly DataLayerContext _dbCtx; - protected BaseRepository(DataLayerContext db) => _dbCtx = db; - public async Task SaveChangesAsync() => await _dbCtx.SaveChangesAsync() > 0; -#endif } } \ No newline at end of file diff --git a/MP.Data/Repository/Utils/BaseRepository.cs b/MP.Data/Repository/Utils/BaseRepository.cs index 4e709040..aceaa04a 100644 --- a/MP.Data/Repository/Utils/BaseRepository.cs +++ b/MP.Data/Repository/Utils/BaseRepository.cs @@ -13,8 +13,7 @@ namespace MP.Data.Repository.Utils #region Protected Constructors - protected BaseRepository(IDbContextFactory ctxFactory) - => _ctxFactory = ctxFactory; + protected BaseRepository(IDbContextFactory ctxFactory) => _ctxFactory = ctxFactory; #endregion Protected Constructors @@ -24,24 +23,9 @@ namespace MP.Data.Repository.Utils /// Creazione dbcontext per singola transazione ///
                                                      /// - protected async Task CreateContextAsync() - => await _ctxFactory.CreateDbContextAsync(); + protected async Task CreateContextAsync() => await _ctxFactory.CreateDbContextAsync(); #endregion Protected Methods -#if false - /// - /// Salvataggio dati asincrono - /// - /// - protected async Task SaveChangesAsync(DataLayerContext ctx) - => await ctx.SaveChangesAsync() > 0; -#endif - -#if false - protected readonly DataLayerContext _dbCtx; - protected BaseRepository(DataLayerContext db) => _dbCtx = db; - public async Task SaveChangesAsync() => await _dbCtx.SaveChangesAsync() > 0; -#endif } } \ No newline at end of file diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 4b13e62b..892725f7 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2606.113 + 8.16.2606.116 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 386f99ae..793b3777 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                      Versione: 8.16.2606.113

                                                      +

                                                      Versione: 8.16.2606.116


                                                      Note di rilascio:
                                                      • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 142014de..87293708 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.113 +8.16.2606.116 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 62319e01..4818c638 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.113 + 8.16.2606.116 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Components/AskCloseOdl.razor.cs b/MP.SPEC/Components/AskCloseOdl.razor.cs index 85fe627e..2a78e714 100644 --- a/MP.SPEC/Components/AskCloseOdl.razor.cs +++ b/MP.SPEC/Components/AskCloseOdl.razor.cs @@ -103,8 +103,7 @@ namespace MP.SPEC.Components } } - MDService.ActionSetReqAsync(CurrAction); - await Task.Delay(1); + await MDService.ActionSetReqAsync(CurrAction); // se fatto --> ricarico! if (fatto) { diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index c95bce5c..a80da490 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -6,6 +6,7 @@ using MP.Data; using MP.Data.Controllers; using MP.Data.DbModels; using MP.Data.MgModels; +using MP.Data.Repository.Anag; using MP.Data.Services; using Newtonsoft.Json; using NLog; @@ -20,11 +21,14 @@ namespace MP.SPEC.Data { #region Public Constructors - public MpDataService(IConfiguration configuration, IFusionCache cache) + private readonly IAnagRepository _anagRepository; + + public MpDataService(IConfiguration configuration, IFusionCache cache, IAnagRepository anagRepository) { // salvataggio oggetti _configuration = configuration; _cache = cache; + _anagRepository = anagRepository; // Verifica conf trace... traceEnabled = _configuration.GetValue("Otel:EnableTracing", false); slowLogThresh = _configuration.GetValue("ServerConf:slowLogThresh", 1); diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 7dc37fbb..98dcf7d9 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2606.113 + 8.16.2606.116 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Test.razor b/MP.SPEC/Pages/Test.razor index 60775048..0febaf6d 100644 --- a/MP.SPEC/Pages/Test.razor +++ b/MP.SPEC/Pages/Test.razor @@ -29,7 +29,7 @@
                                                        - +
                                                        diff --git a/MP.SPEC/Pages/Test.razor.cs b/MP.SPEC/Pages/Test.razor.cs index 7f2957a3..8d495b95 100644 --- a/MP.SPEC/Pages/Test.razor.cs +++ b/MP.SPEC/Pages/Test.razor.cs @@ -38,8 +38,8 @@ namespace MP.SPEC.Pages CurrAction.IsActive = false; CurrAction.Topic = "Chiusura ODL"; CurrAction.Message = "Rilevato possibile fine operazioni, Vuoi chiudere la commessa?"; - MMDataService.ActionSetReqAsync(CurrAction); - await Task.Delay(1); + + await MMDataService.ActionSetReqAsync(CurrAction); } protected override async Task OnInitializedAsync() @@ -68,11 +68,11 @@ namespace MP.SPEC.Pages } } - protected void sendMessage() + protected async Task SendMessageAsync() { CurrAction.DtReq = DateTime.Now; CurrAction.IsActive = true; - MMDataService.ActionSetReqAsync(CurrAction); + await MMDataService.ActionSetReqAsync(CurrAction); } #endregion Protected Methods diff --git a/MP.SPEC/Program.cs b/MP.SPEC/Program.cs index 997d8354..36036cdd 100644 --- a/MP.SPEC/Program.cs +++ b/MP.SPEC/Program.cs @@ -1,9 +1,10 @@ using Microsoft.AspNetCore.Authentication.Negotiate; using Microsoft.AspNetCore.StaticFiles; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.FileProviders; -using MP.AppAuth.Services; -using MP.Data.Services; +using MP.Data; using MP.SPEC.Components; using MP.SPEC.Data; using MP.SPEC.Services; @@ -155,20 +156,36 @@ builder.Services.AddFusionCache() ConnectionMultiplexerFactory = () => Task.FromResult(redisMultiplexer) })); +// Metodi principali x accesso dati +var connStr = builder.Configuration.GetConnectionString("MP.Data") + ?? throw new InvalidOperationException("ConnString 'MP.Data' mancante."); +// aggiungo il costruttore x i DbContextFactory +builder.Services.AddDbContextFactory(options => + options.UseSqlServer(connStr) + .EnableSensitiveDataLogging(false) // true solo in Sviluppo + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); + +// MP.Data Services Utils - Statistiche DB +builder.Services.AddSpecDataLayer(); // altri servizi builder.Services.AddSingleton(); -builder.Services.AddSingleton(); builder.Services.AddSingleton(); -builder.Services.AddSingleton(); builder.Services.AddScoped(); + +#if false +builder.Services.AddSingleton(); +builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); -builder.Services.AddSingleton(); +builder.Services.AddSingleton(); +#endif +#if false // aggiunta helper local/session storage service builder.Services.AddScoped(); -builder.Services.AddScoped(); +builder.Services.AddScoped(); +#endif builder.Services.AddHttpClient(); diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 91e3fb3c..3f744dfc 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                        Versione: 8.16.2606.113

                                                        +

                                                        Versione: 8.16.2606.116


                                                        Note di rilascio:
                                                        • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 142014de..87293708 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.113 +8.16.2606.116 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 1f1a8e1b..a0393e81 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.113 + 8.16.2606.116 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From a34dd4cc79e741b3c1acfa9ff68677b04458c1c3 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 1 Jun 2026 18:54:03 +0200 Subject: [PATCH 087/102] Continuo spostamento metodi nel repository Anag --- MP.Data/Repository/Anag/AnagRepository.cs | 76 ++++++++++++++++------ MP.Data/Repository/Anag/IAnagRepository.cs | 34 ++++++---- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 30 files changed, 107 insertions(+), 59 deletions(-) diff --git a/MP.Data/Repository/Anag/AnagRepository.cs b/MP.Data/Repository/Anag/AnagRepository.cs index c68cd626..568a04d6 100644 --- a/MP.Data/Repository/Anag/AnagRepository.cs +++ b/MP.Data/Repository/Anag/AnagRepository.cs @@ -12,10 +12,16 @@ namespace MP.Data.Repository.Anag { public class AnagRepository : BaseRepository, IAnagRepository { + #region Public Constructors + public AnagRepository(IDbContextFactory ctxFactory) : base(ctxFactory) { } + #endregion Public Constructors + + #region Public Methods + /// public async Task AnagCountersGetNextAsync(string cntType) { @@ -189,20 +195,6 @@ namespace MP.Data.Repository.Anag return await ListValuesFiltAsync("AnagArticoli", "Tipo"); } -#if false - /// - public async Task> ArticleWithDossierAsync() - { - using var dbCtx = new MoonPro_FluxContext(_configuration); - return await dbCtx - .DbSetDossiers - .AsNoTracking() - .Select(i => i.CodArticolo) - .Distinct() - .ToListAsync(); - } -#endif - /// public async Task ArticoliCountAsync() { @@ -236,6 +228,19 @@ namespace MP.Data.Repository.Anag return await query.OrderBy(x => x.CodArticolo).CountAsync(); } + /// + public async Task ArticoliCountUsedAsync() + { + await using var dbCtx = await CreateContextAsync(); + var result = await dbCtx + .DbSetCounter + .FromSqlRaw("EXEC stp_ART_CountUsed") + .AsNoTracking() + .ToListAsync(); + + return result.FirstOrDefault()?.NumCount ?? 0; + } + /// public async Task ArticoliDeleteRecordAsync(AnagArticoliModel currRec) { @@ -380,6 +385,36 @@ namespace MP.Data.Repository.Anag } } + /// + public async Task> OperatoriGetFiltAsync(string codGruppo) + { + List dbResult = new List(); + await using var dbCtx = await CreateContextAsync(); + if (codGruppo == "*") + { + dbResult = await dbCtx + .DbOperatori + .AsNoTracking() + .OrderBy(x => x.MatrOpr) + .ToListAsync(); + } + else + { + dbResult = await dbCtx + .DbSetGrp2Oper + .Where(g => g.CodGruppo == codGruppo) + .Join(dbCtx.DbOperatori, + g => g.MatrOpr, + m => m.MatrOpr, + (g, m) => m + ) + .AsNoTracking() + .OrderBy(x => x.MatrOpr) + .ToListAsync(); + } + return dbResult; + } + /// public async Task> PODL_getDictOdlPodlAsync(List missingIds) { @@ -388,14 +423,15 @@ namespace MP.Data.Repository.Anag await using var dbCtx = await CreateContextAsync(); return await dbCtx - .DbSetPODL - .AsNoTracking() - .Where(x => missingIds.Contains(x.IdxOdl)) - .ToDictionaryAsync(x => x.IdxOdl, x => x.IdxPromessa); + .DbSetPODL + .AsNoTracking() + .Where(x => missingIds.Contains(x.IdxOdl)) + .ToDictionaryAsync(x => x.IdxOdl, x => x.IdxPromessa); } /// /// Recupero dizionario traduzioni da cache o DB + /// /// Codice lingua /// Dizionario di traduzioni @@ -413,5 +449,7 @@ namespace MP.Data.Repository.Anag .DistinctBy(t => t.Lemma, StringComparer.OrdinalIgnoreCase) .ToDictionary(t => t.Lemma, t => t.Traduzione, StringComparer.OrdinalIgnoreCase); } + + #endregion Public Methods } -} +} \ No newline at end of file diff --git a/MP.Data/Repository/Anag/IAnagRepository.cs b/MP.Data/Repository/Anag/IAnagRepository.cs index e817d469..695c1c7f 100644 --- a/MP.Data/Repository/Anag/IAnagRepository.cs +++ b/MP.Data/Repository/Anag/IAnagRepository.cs @@ -7,6 +7,8 @@ namespace MP.Data.Repository.Anag { public interface IAnagRepository { + #region Public Methods + /// /// Stacca un nuovo counter x il tipo richiesto /// @@ -32,7 +34,7 @@ namespace MP.Data.Repository.Anag /// Delete record AnagraficaGruppi ///
                                                      /// Record da eliminare - /// True se l'eliminazione avvenuta + /// True se l'eliminazione � avvenuta Task AnagGruppiDeleteAsync(AnagGruppiModel updRec); /// @@ -42,7 +44,7 @@ namespace MP.Data.Repository.Anag Task> AnagGruppiFaseAsync(); /// - /// Gruppi x tipo modalit Async + /// Gruppi x tipo modalit� Async /// /// Tipo di gruppo (es. REPARTO, FASE, AZIENDA) /// Lista di modelli anagrafica gruppi @@ -58,7 +60,7 @@ namespace MP.Data.Repository.Anag /// Upsert record AnagraficaGruppi (solo codice/descrizione) /// /// Record da inserire o aggiornare - /// True se l'operazione riuscita + /// True se l'operazione � riuscita Task AnagGruppiUpsertAsync(AnagGruppiModel updRec); /// @@ -78,7 +80,7 @@ namespace MP.Data.Repository.Anag /// Elenco codice articoli che abbiano dati Dossier /// /// Lista di codici articolo - Task> ArticleWithDossierAsync(); + Task> ArticleWithDossierAsync(); #endif /// @@ -96,6 +98,12 @@ namespace MP.Data.Repository.Anag /// Conteggio risultati ricerca Task ArticoliCountSearchAsync(string tipoArt = "*", string azienda = "*", string searchVal = ""); + /// + /// Conteggio articoli IMPIEGATI (da stored stp_ART_getUsed) Async + /// + /// Conteggio articoli impiegati + Task ArticoliCountUsedAsync(); + /// /// Eliminazione Record Articolo /// @@ -128,13 +136,7 @@ namespace MP.Data.Repository.Anag Task> ArticoliGetUnusedAsync(); /// - /// Elenco tabella Articoli IMPIEGATI (da stored stp_ART_getUsed) Async - /// - /// Lista di articoli impiegati - Task> ArticoliGetUsedAsync(); - - /// - /// Elenco Articoli che sono in KIT Child + /// Dizionario associazione ODL/PODL /// /// Lista di articoli in kit Task> ArticoliInKitAsync(); @@ -168,6 +170,13 @@ namespace MP.Data.Repository.Anag /// Lista di macchine Task> MacchineGetFiltAsync(string codGruppo); + /// + /// Elenco operatori dato filtro gruppo + /// + /// Codice gruppo + /// Lista di operatori + Task> OperatoriGetFiltAsync(string codGruppo); + /// /// Dizionario associazione ODL/PODL /// @@ -182,5 +191,6 @@ namespace MP.Data.Repository.Anag /// Dizionario di traduzioni Task> VocabolarioGetLangAsync(string lingua); + #endregion Public Methods } -} +} \ No newline at end of file diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index c5a7f331..4998857b 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2606.113 + 8.16.2606.118 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index 19fc2e90..937bfdaf 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                                      Versione: 8.16.2606.113

                                                      +

                                                      Versione: 8.16.2606.118


                                                      Note di rilascio:
                                                      • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index 142014de..515eeea2 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.113 +8.16.2606.118 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index 4c8d4a7e..84d88c29 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.113 + 8.16.2606.118 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 892725f7..727fa0fb 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2606.116 + 8.16.2606.118 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 793b3777..9e4106d9 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                        Versione: 8.16.2606.116

                                                        +

                                                        Versione: 8.16.2606.118


                                                        Note di rilascio:
                                                        • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 87293708..515eeea2 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.116 +8.16.2606.118 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 4818c638..1c26c859 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.116 + 8.16.2606.118 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index fa1991a8..509dc1ba 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2606.0113 + 8.16.2606.0118 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index fa3e2870..0dc5539b 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                          Versione: 8.16.2606.0113

                                                          +

                                                          Versione: 8.16.2606.0118


                                                          Note di rilascio:
                                                            diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 5e53158e..9a5e6157 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0113 +8.16.2606.0118 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index 44a961c6..02892851 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0113 + 8.16.2606.0118 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index 7c5b2eeb..a22e68ad 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2606.113 + 8.16.2606.118 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 91e3fb3c..093f0774 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                            Versione: 8.16.2606.113

                                                            +

                                                            Versione: 8.16.2606.118


                                                            Note di rilascio:
                                                            • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 142014de..515eeea2 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.113 +8.16.2606.118 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index ab4aa2e7..9b559a4d 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.113 + 8.16.2606.118 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 91c9f10d..9bed72f0 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2606.0113 + 8.16.2606.0118 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index 4dfd359b..cbb1a653 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                                              Versione: 8.16.2606.0113

                                                              +

                                                              Versione: 8.16.2606.0118


                                                              Note di rilascio:
                                                                diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 5e53158e..9a5e6157 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0113 +8.16.2606.0118 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 6325cd45..4b843e6e 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0113 + 8.16.2606.0118 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index 1f7aa719..f32af328 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2606.113 + 8.16.2606.118 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index e367897f..f9feea47 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                                Versione: 8.16.2606.113

                                                                +

                                                                Versione: 8.16.2606.118


                                                                Note di rilascio:
                                                                • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index 142014de..515eeea2 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.113 +8.16.2606.118 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index c0386092..c9f0e54b 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.113 + 8.16.2606.118 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 98dcf7d9..7c7b2789 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2606.116 + 8.16.2606.118 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 3f744dfc..093f0774 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                  Versione: 8.16.2606.116

                                                                  +

                                                                  Versione: 8.16.2606.118


                                                                  Note di rilascio:
                                                                  • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 87293708..515eeea2 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.116 +8.16.2606.118 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index a0393e81..f23654c5 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.116 + 8.16.2606.118 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From fa46fe89e5d4396f75d843031723f669aef86b7c Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 1 Jun 2026 19:12:12 +0200 Subject: [PATCH 088/102] Continuo migrazione repository --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.Data/Controllers/MpSpecRepository.cs | 9 +++++++-- MP.Data/Services/ListSelectDataSrv.cs | 9 ++++++--- MP.SPEC/Data/MpDataService.cs | 18 +++++++++--------- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- 15 files changed, 34 insertions(+), 26 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index b4b8e6e8..51e63f88 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2606.113 + 8.16.2606.118 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 91e3fb3c..093f0774 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                    Versione: 8.16.2606.113

                                                                    +

                                                                    Versione: 8.16.2606.118


                                                                    Note di rilascio:
                                                                    • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 142014de..515eeea2 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.113 +8.16.2606.118 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index 9170deab..17e88865 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.113 + 8.16.2606.118 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.Data/Controllers/MpSpecRepository.cs b/MP.Data/Controllers/MpSpecRepository.cs index 7e42b2f1..887fbd5e 100644 --- a/MP.Data/Controllers/MpSpecRepository.cs +++ b/MP.Data/Controllers/MpSpecRepository.cs @@ -33,6 +33,7 @@ namespace MP.Data.Controllers #region Public Methods +#if false /// /// Stacca un nuovo counter x il tipo richiesto /// @@ -91,7 +92,7 @@ namespace MP.Data.Controllers } } return answ; - } + } /// /// Restituisce l'anagrafica EVENTI generalmente disponibile per OGNI macchina @@ -231,6 +232,8 @@ namespace MP.Data.Controllers return numRes != 0; } + +#endif /// /// Elenco valori ammessi x Stati commessa (es Yacht Baglietto) @@ -369,6 +372,7 @@ namespace MP.Data.Controllers .ToListAsync(); } +#if false /// /// Elenco tabella Articoli da filtro /// @@ -409,7 +413,8 @@ namespace MP.Data.Controllers .OrderBy(x => x.CodArticolo) .Take(numRecord) .ToListAsync(); - } + } +#endif /// /// Elenco tabella Articoli NON IMPIEGATI (da stored stp_ART_getUsed) Async diff --git a/MP.Data/Services/ListSelectDataSrv.cs b/MP.Data/Services/ListSelectDataSrv.cs index 0cefec61..a41b524d 100644 --- a/MP.Data/Services/ListSelectDataSrv.cs +++ b/MP.Data/Services/ListSelectDataSrv.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.Configuration; using MP.Data.DbModels; +using MP.Data.Repository.Anag; using Newtonsoft.Json; using NLog; using StackExchange.Redis; @@ -20,8 +21,9 @@ namespace MP.Data.Services { #region Public Constructors - public ListSelectDataSrv(IConfiguration configuration, IConnectionMultiplexer redConn) : base(configuration, redConn) + public ListSelectDataSrv(IConfiguration configuration, IConnectionMultiplexer redConn, IAnagRepository anagRepository) : base(configuration, redConn) { + _anagRepository = anagRepository; // conf DB string connStr = _configuration.GetConnectionString("MP.All"); if (string.IsNullOrEmpty(connStr)) @@ -70,7 +72,7 @@ namespace MP.Data.Services } else { - result = await dbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal); + result = await _anagRepository.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await _redisDb.StringSetAsync(currKey, rawData, LongCache); @@ -267,6 +269,7 @@ namespace MP.Data.Services #region Private Fields private static Logger Log = LogManager.GetCurrentClassLogger(); + private readonly IAnagRepository _anagRepository; private bool _disposed = false; private string redisBaseKey = "MP:ALL:Cache"; @@ -382,7 +385,7 @@ namespace MP.Data.Services } answ = true; } - return answ; + return answ; #endif } diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index a80da490..2ffbf91e 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -157,7 +157,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("AnagCountersGetNextAsync"); AnagCountersModel result = new AnagCountersModel(); string source = "DB"; - result = await dbController.AnagCountersGetNextAsync(cntType); + result = await _anagRepository.AnagCountersGetNextAsync(cntType); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"AnagCountersGetNextAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); @@ -176,7 +176,7 @@ namespace MP.SPEC.Data expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => { - return await dbController.AnagEventiGeneralAsync() ?? new List(); + return await _anagRepository.AnagEventiGeneralAsync() ?? new List(); }, tagList: [Utils.redisEventList] ); @@ -191,7 +191,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("AnagGruppiDeleteAsync"); bool result = false; string source = "DB"; - result = await dbController.AnagGruppiDeleteAsync(updRec); + result = await _anagRepository.AnagGruppiDeleteAsync(updRec); // elimino cache redis... await FlushFusionCacheAsync(Utils.redisAnagGruppi); activity?.SetTag("data.source", source); @@ -210,7 +210,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("AnagGruppiUpsertAsync"); bool result = false; string source = "DB"; - result = await dbController.AnagGruppiUpsertAsync(UpdRec); + result = await _anagRepository.AnagGruppiUpsertAsync(UpdRec); // elimino cache redis... await FlushFusionCacheAsync(Utils.redisAnagGruppi); activity?.SetTag("data.source", source); @@ -328,7 +328,6 @@ namespace MP.SPEC.Data public async Task> ArticoliGetSearchAsync(int numRecord, string tipoArt, string azienda, string searchVal) { string sKey = string.IsNullOrWhiteSpace(searchVal) ? "***" : searchVal.Trim(); - string redisKey = $"{Utils.redisArtList}:{tipoArt}:{azienda}:{sKey}:{numRecord}"; return await GetOrFetchAsync( @@ -336,7 +335,8 @@ namespace MP.SPEC.Data cacheKey: redisKey, expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => - await dbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal) ?? new List(), + await _anagRepository.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal) ?? new List(), + //await dbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal) ?? new List(), tagList: [Utils.redisArtList, $"{Utils.redisArtList}:Search"] ); } @@ -648,7 +648,7 @@ namespace MP.SPEC.Data cacheKey: $"{Utils.redisAnagGruppi}:Aziende", expiration: GetRandTOut(redisLongTimeCache * 2), fetchFunc: async () => - await dbController.AnagGruppiAziendeAsync() ?? new List(), + await _anagRepository.AnagGruppiAziendeAsync() ?? new List(), tagList: [Utils.redisAnagGruppi, $"{Utils.redisAnagGruppi}:Aziende"] ); } @@ -663,7 +663,7 @@ namespace MP.SPEC.Data operationName: "ElencoGruppiFaseAsync", cacheKey: $"{Utils.redisAnagGruppi}:FASE", expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => await dbController.AnagGruppiFaseAsync() ?? new List(), + fetchFunc: async () => await _anagRepository.AnagGruppiFaseAsync() ?? new List(), tagList: [Utils.redisAnagGruppi] ); } @@ -693,7 +693,7 @@ namespace MP.SPEC.Data operationName: "ElencoRepartiDtoAsync", cacheKey: $"{Utils.redisAnagGruppi}:REPARTO", expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => await dbController.AnagGruppiRepartoDtoAsync() ?? new(), + fetchFunc: async () => await _anagRepository.AnagGruppiRepartoDtoAsync() ?? new(), tagList: [Utils.redisAnagGruppi] ); } diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 7c7b2789..2952fe88 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2606.118 + 8.16.2606.119 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 093f0774..7e42922e 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                      Versione: 8.16.2606.118

                                                                      +

                                                                      Versione: 8.16.2606.119


                                                                      Note di rilascio:
                                                                      • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 515eeea2..28d1df86 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.118 +8.16.2606.119 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index f23654c5..5cb1e4dd 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.118 + 8.16.2606.119 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 37fb2ac3..76f7002a 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2606.0113 + 8.16.2606.0118 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index 31157f85..c66d2a01 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                                                        Versione: 8.16.2606.0113

                                                                        +

                                                                        Versione: 8.16.2606.0118


                                                                        Note di rilascio:
                                                                          diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 5e53158e..9a5e6157 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0113 +8.16.2606.0118 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index 487a23f2..b4601710 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0113 + 8.16.2606.0118 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false From 537ebec3304cdb8605b148f65c35db3a1d812307 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 1 Jun 2026 19:22:34 +0200 Subject: [PATCH 089/102] Continuo spostamento repository.. test ok --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.Data/Controllers/MpSpecRepository.cs | 8 +++---- MP.Data/Repository/Anag/AnagRepository.cs | 1 + MP.Data/Repository/Anag/IAnagRepository.cs | 8 ++++++- MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.SPEC/Data/MpDataService.cs | 25 +++++++++++----------- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- 36 files changed, 56 insertions(+), 50 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index 51e63f88..b79bd3a4 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2606.118 + 8.16.2606.119 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 093f0774..7e42922e 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                          Versione: 8.16.2606.118

                                                                          +

                                                                          Versione: 8.16.2606.119


                                                                          Note di rilascio:
                                                                          • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 515eeea2..28d1df86 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.118 +8.16.2606.119 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index 17e88865..d464ba46 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.118 + 8.16.2606.119 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.Data/Controllers/MpSpecRepository.cs b/MP.Data/Controllers/MpSpecRepository.cs index 887fbd5e..224fb848 100644 --- a/MP.Data/Controllers/MpSpecRepository.cs +++ b/MP.Data/Controllers/MpSpecRepository.cs @@ -233,7 +233,6 @@ namespace MP.Data.Controllers return numRes != 0; } -#endif /// /// Elenco valori ammessi x Stati commessa (es Yacht Baglietto) @@ -253,6 +252,7 @@ namespace MP.Data.Controllers return ListValuesFiltAsync("AnagArticoli", "Tipo"); } +#endif /// /// Elenco codice articoli che abbiano dati Dossier /// @@ -268,6 +268,7 @@ namespace MP.Data.Controllers .ToListAsync(); } +#if false /// /// Conteggio num articoli Async /// @@ -279,7 +280,7 @@ namespace MP.Data.Controllers .DbSetArticoli .CountAsync(); return result; - } + } /// /// Conteggio articoli data condizione ricerca @@ -372,7 +373,6 @@ namespace MP.Data.Controllers .ToListAsync(); } -#if false /// /// Elenco tabella Articoli da filtro /// @@ -414,7 +414,6 @@ namespace MP.Data.Controllers .Take(numRecord) .ToListAsync(); } -#endif /// /// Elenco tabella Articoli NON IMPIEGATI (da stored stp_ART_getUsed) Async @@ -488,6 +487,7 @@ namespace MP.Data.Controllers } return await dbCtx.SaveChangesAsync() > 0; } +#endif /// /// Elenco da tabella Config Async diff --git a/MP.Data/Repository/Anag/AnagRepository.cs b/MP.Data/Repository/Anag/AnagRepository.cs index 568a04d6..3fbfce71 100644 --- a/MP.Data/Repository/Anag/AnagRepository.cs +++ b/MP.Data/Repository/Anag/AnagRepository.cs @@ -50,6 +50,7 @@ namespace MP.Data.Repository.Anag } else { + // se si volessero impiegare parametri OUTPUT (qui ne mancherebbe 1 nella stored x CntCode...) var pCntType = new SqlParameter("@CntType", cntType); var pLastNum = new SqlParameter { diff --git a/MP.Data/Repository/Anag/IAnagRepository.cs b/MP.Data/Repository/Anag/IAnagRepository.cs index 695c1c7f..953fdd32 100644 --- a/MP.Data/Repository/Anag/IAnagRepository.cs +++ b/MP.Data/Repository/Anag/IAnagRepository.cs @@ -130,11 +130,17 @@ namespace MP.Data.Repository.Anag Task> ArticoliGetSearchAsync(int numRecord, string tipoArt = "*", string azienda = "*", string searchVal = ""); /// - /// Elenco tabella Articoli NON IMPIEGATI (da stored stp_ART_getUsed) Async + /// Elenco tabella Articoli NON IMPIEGATI (da stored stp_ART_getNotUsed) Async /// /// Lista di articoli non impiegati Task> ArticoliGetUnusedAsync(); + /// + /// Elenco tabella Articoli IMPIEGATI (da stored stp_ART_getUsed) Async + /// + /// Lista di articoli non impiegati + Task> ArticoliGetUsedAsync(); + /// /// Dizionario associazione ODL/PODL /// diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index 4998857b..13723817 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2606.118 + 8.16.2606.119 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index 937bfdaf..805e9ef3 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                                                            Versione: 8.16.2606.118

                                                                            +

                                                                            Versione: 8.16.2606.119


                                                                            Note di rilascio:
                                                                            • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index 515eeea2..28d1df86 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.118 +8.16.2606.119 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index 84d88c29..635c7a5f 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.118 + 8.16.2606.119 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 727fa0fb..56eeddca 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2606.118 + 8.16.2606.119 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 9e4106d9..03c738b7 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                                              Versione: 8.16.2606.118

                                                                              +

                                                                              Versione: 8.16.2606.119


                                                                              Note di rilascio:
                                                                              • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 515eeea2..28d1df86 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.118 +8.16.2606.119 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 1c26c859..d3e771b6 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.118 + 8.16.2606.119 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 509dc1ba..2d7b8b5e 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2606.0118 + 8.16.2606.0119 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 0dc5539b..17946008 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                                                Versione: 8.16.2606.0118

                                                                                +

                                                                                Versione: 8.16.2606.0119


                                                                                Note di rilascio:
                                                                                  diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 9a5e6157..8bc36859 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0118 +8.16.2606.0119 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index 02892851..5a0155ac 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0118 + 8.16.2606.0119 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index a22e68ad..2a883698 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2606.118 + 8.16.2606.119 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 093f0774..7e42922e 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                                  Versione: 8.16.2606.118

                                                                                  +

                                                                                  Versione: 8.16.2606.119


                                                                                  Note di rilascio:
                                                                                  • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 515eeea2..28d1df86 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.118 +8.16.2606.119 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index 9b559a4d..ebd7fc6e 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.118 + 8.16.2606.119 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 9bed72f0..e1e72fa3 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2606.0118 + 8.16.2606.0119 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index cbb1a653..c430a648 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                                                                    Versione: 8.16.2606.0118

                                                                                    +

                                                                                    Versione: 8.16.2606.0119


                                                                                    Note di rilascio:
                                                                                      diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 9a5e6157..8bc36859 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0118 +8.16.2606.0119 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 4b843e6e..b57cd977 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0118 + 8.16.2606.0119 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index f32af328..a159eed4 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2606.118 + 8.16.2606.119 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index f9feea47..c1503a5c 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                                                      Versione: 8.16.2606.118

                                                                                      +

                                                                                      Versione: 8.16.2606.119


                                                                                      Note di rilascio:
                                                                                      • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index 515eeea2..28d1df86 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.118 +8.16.2606.119 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index c9f0e54b..8ddc1c1b 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.118 + 8.16.2606.119 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 2ffbf91e..e000ad5a 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -226,7 +226,7 @@ namespace MP.SPEC.Data cacheKey: Utils.redisStatoCom, expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => - await dbController.AnagStatiCommAsync() ?? new List(), + await _anagRepository.AnagStatiCommAsync() ?? new List(), tagList: [Utils.redisStatoCom] ); } @@ -241,7 +241,7 @@ namespace MP.SPEC.Data operationName: "AnagTipoArtLvAsync", cacheKey: Utils.redisTipoArt, expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => await dbController.AnagTipoArtLvAsync() ?? new List(), + fetchFunc: async () => await _anagRepository.AnagTipoArtLvAsync() ?? new List(), tagList: [Utils.redisTipoArt] ); } @@ -277,7 +277,7 @@ namespace MP.SPEC.Data cacheKey: redisKey, expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => - await dbController.ArticoliCountSearchAsync(tipo, azienda, searchVal), + await _anagRepository.ArticoliCountSearchAsync(tipo, azienda, searchVal), tagList: [Utils.redisArtList, $"{Utils.redisArtList}:CountSearch"] ); } @@ -291,7 +291,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("ArticoliDeleteRecordAsync"); string source = "DB"; - bool fatto = await dbController.ArticoliDeleteRecordAsync(currRec); + bool fatto = await _anagRepository.ArticoliDeleteRecordAsync(currRec); await FlushFusionCacheArticoli(); activity?.SetTag("data.source", source); activity?.Stop(); @@ -314,7 +314,7 @@ namespace MP.SPEC.Data cacheKey: redisKey, expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => - await dbController.ArticoliGetByTipoAsync(tipo, azienda) ?? new List(), + await _anagRepository.ArticoliGetByTipoAsync(tipo, azienda) ?? new List(), tagList: [Utils.redisArtList, $"{Utils.redisArtList}:Tipo"] ); } @@ -336,7 +336,6 @@ namespace MP.SPEC.Data expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => await _anagRepository.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal) ?? new List(), - //await dbController.ArticoliGetSearchAsync(numRecord, tipoArt, azienda, searchVal) ?? new List(), tagList: [Utils.redisArtList, $"{Utils.redisArtList}:Search"] ); } @@ -353,7 +352,7 @@ namespace MP.SPEC.Data cacheKey: redisKey, expiration: GetRandTOut(redisLongTimeCache), fetchFunc: async () => - await dbController.ArticoliInKitAsync() ?? new List(), + await _anagRepository.ArticoliInKitAsync() ?? new List(), tagList: [Utils.redisArtList, $"{Utils.redisArtList}:InKit"] ); } @@ -367,7 +366,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("ArticoliUpdateRecord"); string source = "DB"; - bool fatto = await dbController.ArticoliUpdateRecord(currRec); + bool fatto = await _anagRepository.ArticoliUpdateRecord(currRec); await FlushFusionCacheArticoli(); activity?.SetTag("data.source", source); activity?.Stop(); @@ -709,23 +708,23 @@ namespace MP.SPEC.Data try { // verifico quale sia il set + piccolo - int totalCount = await dbController.ArticoliCountAsync(); - int usedCount = await dbController.ArticoliCountUsedAsync(); + int totalCount = await _anagRepository.ArticoliCountAsync(); + int usedCount = await _anagRepository.ArticoliCountUsedAsync(); if (usedCount <= (totalCount - usedCount)) { - var usedList = await dbController.ArticoliGetUsedAsync(); + var usedList = await _anagRepository.ArticoliGetUsedAsync(); _listCodArtUsed = new HashSet(usedList.Select(x => x.CodArticolo)); _listCodArtNotUsed.Clear(); } else { - var unusedList = await dbController.ArticoliGetUnusedAsync(); + var unusedList = await _anagRepository.ArticoliGetUnusedAsync(); _listCodArtNotUsed = new HashSet(unusedList.Select(x => x.CodArticolo)); _listCodArtUsed.Clear(); } // calcolo anche elenco articoli impiegati in istanzanKIT - var listInKit = await dbController.ArticoliInKitAsync(); + var listInKit = await _anagRepository.ArticoliInKitAsync(); _listCodArtInKit = new HashSet(listInKit.Select(x => x.CodArticolo)); _artCacheExpiry = DateTime.Now.AddMinutes(15); // TTL ragionevole per la cache locale diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 76f7002a..1ff2dc91 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2606.0118 + 8.16.2606.0119 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index c66d2a01..16ce0ff0 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                                                                        Versione: 8.16.2606.0118

                                                                                        +

                                                                                        Versione: 8.16.2606.0119


                                                                                        Note di rilascio:
                                                                                          diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 9a5e6157..8bc36859 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0118 +8.16.2606.0119 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index b4601710..d9cde985 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0118 + 8.16.2606.0119 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false From 712bc5e380ba165d14bcba48704a8c61c46d149f Mon Sep 17 00:00:00 2001 From: "Samuele E. Locatelli (W11-AI)" Date: Tue, 2 Jun 2026 15:44:25 +0200 Subject: [PATCH 090/102] Inizia code assisted review (non compila...) --- MP.Data/Controllers/MpSpecRepository.cs | 7 + MP.Data/DataServiceCollectionExtensions.cs | 8 + .../Repository/Dossier/DossierRepository.cs | 109 +++ .../Repository/Dossier/IDossierRepository.cs | 24 + .../Repository/FluxLog/FluxLogRepository.cs | 176 ++++ .../Repository/FluxLog/IFluxLogRepository.cs | 17 + .../Repository/Production/BaseRepository.cs | 31 + .../Production/IProductionRepository.cs | 115 +++ .../Production/ProductionRepository.cs | 864 ++++++++++++++++++ .../Repository/System/ISystemRepository.cs | 24 + MP.Data/Repository/System/SystemRepository.cs | 114 +++ MP.SPEC/refactor_repository.md | 32 +- build_all_par.ps1 | 10 +- 13 files changed, 1518 insertions(+), 13 deletions(-) create mode 100644 MP.Data/Repository/Dossier/DossierRepository.cs create mode 100644 MP.Data/Repository/Dossier/IDossierRepository.cs create mode 100644 MP.Data/Repository/FluxLog/FluxLogRepository.cs create mode 100644 MP.Data/Repository/FluxLog/IFluxLogRepository.cs create mode 100644 MP.Data/Repository/Production/BaseRepository.cs create mode 100644 MP.Data/Repository/Production/IProductionRepository.cs create mode 100644 MP.Data/Repository/Production/ProductionRepository.cs create mode 100644 MP.Data/Repository/System/ISystemRepository.cs create mode 100644 MP.Data/Repository/System/SystemRepository.cs diff --git a/MP.Data/Controllers/MpSpecRepository.cs b/MP.Data/Controllers/MpSpecRepository.cs index 224fb848..97c67690 100644 --- a/MP.Data/Controllers/MpSpecRepository.cs +++ b/MP.Data/Controllers/MpSpecRepository.cs @@ -253,6 +253,8 @@ namespace MP.Data.Controllers } #endif + +#if false /// /// Elenco codice articoli che abbiano dati Dossier /// @@ -268,6 +270,8 @@ namespace MP.Data.Controllers .ToListAsync(); } +#endif + #if false /// /// Conteggio num articoli Async @@ -488,6 +492,7 @@ namespace MP.Data.Controllers return await dbCtx.SaveChangesAsync() > 0; } #endif +#if false /// /// Elenco da tabella Config Async @@ -1085,6 +1090,8 @@ namespace MP.Data.Controllers .ToListAsync(); } +#endif + /// /// Elenco ODL filtrati x stato, articolo, KeyRich (che contiene stato) /// diff --git a/MP.Data/DataServiceCollectionExtensions.cs b/MP.Data/DataServiceCollectionExtensions.cs index f649a7a0..5985cf22 100644 --- a/MP.Data/DataServiceCollectionExtensions.cs +++ b/MP.Data/DataServiceCollectionExtensions.cs @@ -3,8 +3,12 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using MP.AppAuth.Services; using MP.Data.Controllers; using MP.Data.Repository.Anag; +using MP.Data.Repository.Dossier; +using MP.Data.Repository.FluxLog; using MP.Data.Repository.IOC; using MP.Data.Repository.Mtc; +using MP.Data.Repository.Production; +using MP.Data.Repository.System; using MP.Data.Repository.Utils; using MP.Data.Services; using MP.Data.Services.IOC; @@ -53,6 +57,10 @@ namespace MP.Data services.TryAddSingleton(); // Scoped + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); // ---------- End Repository ---------- diff --git a/MP.Data/Repository/Dossier/DossierRepository.cs b/MP.Data/Repository/Dossier/DossierRepository.cs new file mode 100644 index 00000000..91f26562 --- /dev/null +++ b/MP.Data/Repository/Dossier/DossierRepository.cs @@ -0,0 +1,109 @@ +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using MP.Data.DbModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MP.Data.Repository.Dossier +{ + public class DossierRepository : IDossierRepository + { + #region Private Fields + + private readonly IConfiguration _configuration; + + #endregion + + #region Public Constructors + + public DossierRepository(IConfiguration configuration) + { + _configuration = configuration; + } + + #endregion + + #region Public Methods + + /// + public async Task DossiersDeleteRecordAsync(DossierModel currRec) + { + await using var dbCtx = new MoonPro_FluxContext(_configuration); + var currVal = await dbCtx + .DbSetDossiers + .Where(x => x.IdxDossier == currRec.IdxDossier) + .FirstOrDefaultAsync(); + dbCtx + .DbSetDossiers + .Remove(currVal); + + return await dbCtx.SaveChangesAsync() > 0; + } + + /// + public async Task> DossiersGetLastFiltAsync(string IdxMacchina, string CodArticolo, DateTime DtStart, DateTime DtEnd, int MaxRec) + { + await using var dbCtx = new MoonPro_FluxContext(_configuration); + return await dbCtx + .DbSetDossiers + .AsNoTracking() + .Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && (CodArticolo == "*" || x.CodArticolo == CodArticolo) && (x.DtRif >= DtStart && x.DtRif <= DtEnd)) + .Include(m => m.MachineNav) + .Include(a => a.ArticoloNav) + .OrderByDescending(x => x.DtRif) + .Take(MaxRec) + .ToListAsync(); + } + + /// + public async Task DossiersInsertAsync(DossierModel newRec) + { + await using var dbCtx = new MoonPro_FluxContext(_configuration); + await dbCtx + .DbSetDossiers + .AddAsync(newRec); + return await dbCtx.SaveChangesAsync() > 0; + } + + /// + public async Task DossiersTakeParamsSnapshotLastAsync(string idxMacchina, DateTime dtMin, DateTime dtMax) + { + await using var dbCtx = new MoonPro_FluxContext(_configuration); + var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); + var pDtMin = new SqlParameter("@DtMin", dtMin); + var pDtMax = new SqlParameter("@DtMax", dtMax); + + var dbResult = await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC stp_FL_TakeSnapshotLast @IdxMacchina,@DtMin,@DtMax", pIdxMacchina, pDtMin, pDtMax); + return dbResult != 0; + } + + /// + public async Task DossiersUpdateValoreAsync(DossierModel editRec) + { + await using var dbCtx = new MoonPro_FluxContext(_configuration); + var currRec = await dbCtx + .DbSetDossiers + .Where(x => x.IdxDossier == editRec.IdxDossier) + .FirstOrDefaultAsync(); + if (currRec != null) + { + currRec.Valore = editRec.Valore; + dbCtx.Entry(currRec).State = EntityState.Modified; + } + else + { + await dbCtx + .DbSetDossiers + .AddAsync(editRec); + } + return await dbCtx.SaveChangesAsync() > 0; + } + + #endregion + } +} diff --git a/MP.Data/Repository/Dossier/IDossierRepository.cs b/MP.Data/Repository/Dossier/IDossierRepository.cs new file mode 100644 index 00000000..3f6852bd --- /dev/null +++ b/MP.Data/Repository/Dossier/IDossierRepository.cs @@ -0,0 +1,24 @@ +using MP.Data.DbModels; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace MP.Data.Repository.Dossier +{ + public interface IDossierRepository + { + #region Public Methods + + Task DossiersDeleteRecordAsync(DossierModel currRec); + + Task> DossiersGetLastFiltAsync(string IdxMacchina, string CodArticolo, DateTime DtStart, DateTime DtEnd, int MaxRec); + + Task DossiersInsertAsync(DossierModel newRec); + + Task DossiersTakeParamsSnapshotLastAsync(string idxMacchina, DateTime dtMin, DateTime dtMax); + + Task DossiersUpdateValoreAsync(DossierModel editRec); + + #endregion + } +} diff --git a/MP.Data/Repository/FluxLog/FluxLogRepository.cs b/MP.Data/Repository/FluxLog/FluxLogRepository.cs new file mode 100644 index 00000000..6032c730 --- /dev/null +++ b/MP.Data/Repository/FluxLog/FluxLogRepository.cs @@ -0,0 +1,176 @@ +using Microsoft.Data.SqlClient; +using Microsoft.Extensions.Configuration; +using MP.Core.DTO; +using MP.Core.Objects; +using MP.Data.DbModels; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; + +namespace MP.Data.Repository.FluxLog +{ + public class FluxLogRepository : IFluxLogRepository + { + #region Private Fields + + private readonly IConfiguration _configuration; + private static NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger(); + + #endregion + + #region Public Constructors + + public FluxLogRepository(IConfiguration configuration) + { + _configuration = configuration; + } + + #endregion + + #region Public Methods + + /// + public async Task> FluxLogDataReduxAsync(string idxMaccSel, List fluxList, Periodo currPeriodo, Enums.ValSelection valMode, Enums.DataInterval intReq, int maxItem) + { + List procStats = new List(); + Log.Info($"Inizio FluxLogDataReduxAsync | idxMaccSel: {idxMaccSel} | periodo: {currPeriodo.Inizio:yyyy-MM-dd} --> {currPeriodo.Fine:yyyy-MM-dd}"); + TimeSpan step = TimeSpan.FromHours(1); + switch (intReq) + { + case Enums.DataInterval.minute: + step = TimeSpan.FromMinutes(1.00 / maxItem); + break; + + case Enums.DataInterval.hour: + step = TimeSpan.FromHours(1.00 / maxItem); + break; + + case Enums.DataInterval.day: + step = TimeSpan.FromDays(1.00 / maxItem); + break; + + default: + break; + } + + var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMaccSel); + var pOnlyTest = new SqlParameter("@OnlyTest", false); + + await using var dbCtx = new MoonPro_FluxContext(_configuration); + foreach (var item in fluxList) + { + Log.Info($"FluxLogDataReduxAsync | Flux: {item}"); + int numRecProc = 0; + Stopwatch sw = new Stopwatch(); + sw.Start(); + var pCodFlux = new SqlParameter("@CodFlux", item); + DateTime dtCursStart = currPeriodo.Inizio; + DateTime dtCursEnd = dtCursStart.Add(step); + bool setCompleted = false; + while (!setCompleted) + { + var currFlux = await dbCtx + .DbSetFluxLog + .Where(x => (x.CodFlux == item) && (x.dtEvento >= dtCursStart && x.dtEvento < dtCursEnd) && (x.IdxMacchina == idxMaccSel)) + .ToListAsync(); + + int numRec = currFlux.Count; + numRecProc += numRec; + if (numRec > maxItem) + { + List listPeriodi = new List(); + + switch (valMode) + { + case Enums.ValSelection.First: + var recStart = currFlux.Skip(1).FirstOrDefault(); + listPeriodi.Add(new Periodo(recStart.dtEvento, dtCursEnd)); + break; + + case Enums.ValSelection.Last: + var recEnd = currFlux.LastOrDefault(); + listPeriodi.Add(new Periodo(dtCursStart, recEnd.dtEvento)); + break; + + case Enums.ValSelection.Center: + int idx = 1; + var recCent = currFlux.Skip(idx / (maxItem + 1)).FirstOrDefault(); + listPeriodi.Add(new Periodo(dtCursStart, recCent.dtEvento)); + if (maxItem > 1) + { + for (int i = 2; i < maxItem; i++) + { + DateTime dtInizio = recCent.dtEvento; + recCent = currFlux.Skip(i / (maxItem + 1)).FirstOrDefault(); + listPeriodi.Add(new Periodo(dtInizio, recCent.dtEvento)); + } + } + listPeriodi.Add(new Periodo(recCent.dtEvento.AddSeconds(1), dtCursEnd)); + break; + + default: + break; + } + + foreach (var slot in listPeriodi) + { + var pDtStart = new SqlParameter("@DtStart", slot.Inizio); + var pDtEnd = new SqlParameter("@DtEnd", slot.Fine); + await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC man.stp_ReduceFluxLog @IdxMacchina, @CodFlux, @DtStart, @DtEnd, @OnlyTest", pIdxMacchina, pCodFlux, pDtStart, pDtEnd, pOnlyTest); + } + } + + dtCursStart = dtCursEnd; + dtCursEnd = dtCursStart.Add(step); + setCompleted = dtCursStart >= currPeriodo.Fine; + } + sw.Stop(); + StatDedupDTO currStat = new StatDedupDTO() + { + IdxMacchina = idxMaccSel, + CodFlux = item, + Interval = intReq, + Num4Int = maxItem, + NumRec = numRecProc, + ProcTime = sw.Elapsed.TotalSeconds + }; + procStats.Add(currStat); + } + Log.Info($"FINE FluxLogDataReduxAsync | idxMaccSel: {idxMaccSel} | periodo: {currPeriodo.Inizio:yyyy-MM-dd} --> {currPeriodo.Fine:yyyy-MM-dd}"); + return procStats; + } + + /// + public async Task> FluxLogGetLastFiltAsync(DateTime DtMax, DateTime DtMin, string IdxMacchina, string CodFlux, int MaxRec) + { + await using var dbCtx = new MoonPro_FluxContext(_configuration); + return await dbCtx + .DbSetFluxLog + .AsNoTracking() + .Where(x => (x.dtEvento >= DtMin && x.dtEvento <= DtMax) && (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && (CodFlux == "*" || x.CodFlux == CodFlux)) + .OrderByDescending(x => x.dtEvento) + .Take(MaxRec) + .ToListAsync() ?? new(); + } + + /// + public async Task> FluxLogParetoAsync(string idxMacchina, DateTime dtFrom, DateTime dtTo) + { + await using var dbCtx = new MoonPro_FluxContext(_configuration); + return await dbCtx + .DbSetFluxLog + .Where(x => (string.IsNullOrEmpty(idxMacchina) || x.IdxMacchina == idxMacchina) && (dtFrom <= x.dtEvento && x.dtEvento <= dtTo)) + .AsNoTracking() + .GroupBy(x => x.CodFlux) + .Select(g => new ParetoFluxLogDTO() { IdxMacchina = idxMacchina, CodFlux = g.Key, Qty = g.Count() }) + .OrderByDescending(x => x.Qty) + .ToListAsync() ?? new(); + } + + #endregion + } +} diff --git a/MP.Data/Repository/FluxLog/IFluxLogRepository.cs b/MP.Data/Repository/FluxLog/IFluxLogRepository.cs new file mode 100644 index 00000000..0d50ca31 --- /dev/null +++ b/MP.Data/Repository/FluxLog/IFluxLogRepository.cs @@ -0,0 +1,17 @@ +using MP.Core.DTO; +using MP.Data.DbModels; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace MP.Data.Repository.FluxLog +{ + public interface IFluxLogRepository + { + Task> FluxLogDataReduxAsync(string idxMaccSel, List fluxList, Periodo currPeriodo, Enums.ValSelection valMode, Enums.DataInterval intReq, int maxItem); + + Task> FluxLogGetLastFiltAsync(DateTime DtMax, DateTime DtMin, string IdxMacchina, string CodFlux, int MaxRec); + + Task> FluxLogParetoAsync(string idxMacchina, DateTime dtFrom, DateTime dtTo); + } +} diff --git a/MP.Data/Repository/Production/BaseRepository.cs b/MP.Data/Repository/Production/BaseRepository.cs new file mode 100644 index 00000000..b7d20e56 --- /dev/null +++ b/MP.Data/Repository/Production/BaseRepository.cs @@ -0,0 +1,31 @@ +using Microsoft.EntityFrameworkCore; +using System.Threading.Tasks; + +namespace MP.Data.Repository.Production +{ + public abstract class BaseRepository + { + #region Protected Fields + + protected readonly IDbContextFactory _ctxFactory; + + #endregion Protected Fields + + #region Protected Constructors + + protected BaseRepository(IDbContextFactory ctxFactory) => _ctxFactory = ctxFactory; + + #endregion Protected Constructors + + #region Protected Methods + + /// + /// Creazione dbcontext per singola transazione + /// + /// + protected async Task CreateContextAsync() => await _ctxFactory.CreateDbContextAsync(); + + #endregion Protected Methods + + } +} diff --git a/MP.Data/Repository/Production/IProductionRepository.cs b/MP.Data/Repository/Production/IProductionRepository.cs new file mode 100644 index 00000000..68e464a4 --- /dev/null +++ b/MP.Data/Repository/Production/IProductionRepository.cs @@ -0,0 +1,115 @@ +using MP.Core.DTO; +using MP.Data.DbModels; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace MP.Data.Repository.Production +{ + public interface IProductionRepository + { + #region ODL Methods + + Task> ListODLFiltAsync(bool inCorso, string codArt, string keyRichPart, string Reparto, string IdxMacchina, DateTime startDate, DateTime endDate); + + Task> OdlByKeyAsync(int IdxOdl); + + Task ODLCloseAsync(int idxOdl, string idxMacchina, int matrOpr, bool confPezzi, bool confRett, int modoConfProd); + + Task> OdlGetCurrentAsync(); + + Task> OdlGetStatAsync(int IdxOdl); + + Task> OdlByBatchAsync(string batchSel); + + #endregion + + #region PODL Methods + + Task> ListPODLFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate); + + Task> ListPODL_ByCodArtAsync(string CodArticolo, bool OnlyAvail); + + Task> ListPODL_ByKitParentAsync(int IdxPodlParent); + + Task> ListPODL_KitFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate); + + Task PODL_getByKeyAsync(int idxPODL); + + Task PODL_getByOdlAsync(int idxODL); + + Task> PODL_getDictOdlPodlAsync(List missingIds); + + Task PODL_startSetup(PODLExpModel editRec, int matrOpr, double tcRich, int pzPallet, string note, DateTime dtEvent); + + Task PODL_updateRecipe(int idxPODL, string recipeName); + + Task PODLDeleteRecordAsync(PODLExpModel currRec); + + Task PODLUpdateRecordAsync(PODLModel editRec); + + Task PodlIstKitDeleteAsync(int IdxPODL); + + #endregion + + #region Kit Methods + + Task IstKitDeleteAsync(IstanzeKitModel rec2del); + + Task> IstKitFiltAsync(string keyKit, string keyExtOrd); + + Task IstKitInsertByWKSAsync(string CodArtParent, string KeyFilt); + + Task IstKitUpsertAsync(IstanzeKitModel editRec); + + Task TemplateKitDeleteAsync(TemplateKitModel rec2del); + + Task> TemplateKitFiltAsync(string KitCode, string codChild); + + Task TemplateKitUpsertAsync(TemplateKitModel editRec, string codAzienda); + + Task WipKitDeleteAsync(WipSetupKitModel rec2del); + + Task WipKitDeleteOlderAsync(DateTime dateLimit); + + Task> WipKitFiltAsync(string KeyFilt); + + Task WipKitUpsertAsync(WipSetupKitModel editRec); + + Task> TksScoreAsync(string KeyFilt, int MaxResult); + + #endregion + + #region Macchine / Gruppi Methods + + Task> MacchineGetFiltAsync(string codGruppo); + + Task> MacchineByMatrOperAsync(int MatrOpr); + + Task> MacchineWithFluxAsync(DateTime dtStart, DateTime dtEnd); + + Task Grp2MaccDeleteAsync(Gruppi2MaccModel rec2del); + + Task Grp2MaccInsertAsync(Gruppi2MaccModel upsRec); + + Task Grp2OperDeleteAsync(Gruppi2OperModel rec2del); + + Task Grp2OperInsertAsync(Gruppi2OperModel upsRec); + + Task> StatoMacchinaAsync(string idxMacchina); + + #endregion + + #region Misc Production Methods + + Task> MseGetAllAsync(int maxAge = 2000); + + Task> ListGiacenzeAsync(int IdxOdl); + + Task> OperatoriGetFiltAsync(string codGruppo); + + Task> ParametriGetFiltAsync(string IdxMacchina); + + #endregion + } +} diff --git a/MP.Data/Repository/Production/ProductionRepository.cs b/MP.Data/Repository/Production/ProductionRepository.cs new file mode 100644 index 00000000..1d5196ac --- /dev/null +++ b/MP.Data/Repository/Production/ProductionRepository.cs @@ -0,0 +1,864 @@ +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using MP.Core.DTO; +using MP.Data.DbModels; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; + +namespace MP.Data.Repository.Production +{ + public class ProductionRepository : IProductionRepository + { + #region Private Fields + + private readonly IDbContextFactory _ctxFactory; + private readonly IConfiguration _configuration; + + #endregion + + #region Public Constructors + + public ProductionRepository(IDbContextFactory ctxFactory, IConfiguration configuration) + { + _ctxFactory = ctxFactory; + _configuration = configuration; + } + + #endregion + + #region Private Methods + + private async Task GetMoonProContextAsync() => await _ctxFactory.CreateDbContextAsync(); + + #endregion + + #region Public Methods - ODL + + /// + public async Task> ListODLFiltAsync(bool inCorso, string codArt, string keyRichPart, string Reparto, string IdxMacchina, DateTime startDate, DateTime endDate) + { + await using var dbCtx = await GetMoonProContextAsync(); + + var InCorso = new SqlParameter("@InCorso", inCorso); + var CodArt = new SqlParameter("@CodArt", codArt); + var KeyRich = new SqlParameter("@KeyRich", keyRichPart); + var CodGruppo = new SqlParameter("@CodGruppo", Reparto); + var IdxMacc = new SqlParameter("@IdxMacchina", IdxMacchina); + var DataFrom = new SqlParameter("@DataFrom", startDate); + var DataTo = new SqlParameter("@DataTo", endDate); + + return await dbCtx + .DbSetODLExp + .FromSqlRaw("EXEC stp_ODL_getByFiltSpec @InCorso, @CodArt, @KeyRich, @CodGruppo, @IdxMacchina, @DataFrom, @DataTo", InCorso, CodArt, KeyRich, CodGruppo, IdxMacc, DataFrom, DataTo) + .AsNoTracking() + .ToListAsync(); + } + + /// + public async Task> OdlByKeyAsync(int IdxOdl) + { + await using var dbCtx = await GetMoonProContextAsync(); + return await dbCtx + .DbSetODLExp + .AsNoTracking() + .FirstOrDefaultAsync(x => x.IdxOdl == IdxOdl); + } + + /// + public async Task ODLCloseAsync(int idxOdl, string idxMacchina, int matrOpr, bool confPezzi, bool confRett, int modoConfProd) + { + bool fatto = false; + if (idxOdl > 0) + { + await using var dbCtx = await GetMoonProContextAsync(); + // preparo i parametri + var IdxODL = new SqlParameter("@IdxODL", idxOdl); + var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); + + try + { + var dbResult = await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC stp_ODL_fineProd @IdxODL, @IdxMacchina", IdxODL, IdxMacchina); + fatto = dbResult != 0; + } + catch (Exception exc) + { + NLog.LogManager.GetCurrentClassLogger().Error($"Eccezione durante ODLCloseAsync{Environment.NewLine}{exc}"); + } + } + return fatto; + } + + /// + public async Task> OdlGetCurrentAsync() + { + await using var dbCtx = await GetMoonProContextAsync(); + return await dbCtx + .DbSetODL + .Where(x => x.DataInizio != null && x.DataFine == null) + .ToListAsync(); + } + + /// + public async Task> OdlGetStatAsync(int IdxOdl) + { + List dbResult = new List(); + if (IdxOdl > 0) + { + await using var dbCtx = new MoonPro_STATSContext(_configuration); + var IdxODL = new SqlParameter("@IdxODL", IdxOdl); + + dbResult = await dbCtx + .DbSetODL + .FromSqlRaw("EXEC stp_STAT_ODL @IdxODL", IdxODL) + .AsNoTracking() + .ToListAsync(); + } + return dbResult; + } + + /// + public async Task> OdlByBatchAsync(string batchSel) + { + await using var dbCtx = new MoonPro_InveContext(_configuration); + return await dbCtx + .DbGiacenzeData + .AsNoTracking() + .Where(x => x.IdxOdl > 0) + .Select(x => x.IdxOdl) + .ToListAsync(); + } + + #endregion + + #region Public Methods - PODL + + /// + public async Task> ListPODLFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) + { + await using var dbCtx = await GetMoonProContextAsync(); + var Lanc = new SqlParameter("@Lanciato", lanciato); + var KeyRich = new SqlParameter("@KeyRich", keyRichPart); + var CodGrp = new SqlParameter("@CodGruppo", codGruppo); + var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina); + var DateFrom = new SqlParameter("@DtInizio", startDate); + var DateTo = new SqlParameter("@DtFine", endDate); + + return await dbCtx + .DbSetPODLExp + .FromSqlRaw("EXEC stp_PODL_getByFiltSpec @Lanciato, @KeyRich, @CodGruppo, @IdxMacchina, @DtInizio, @DtFine", Lanc, KeyRich, CodGrp, IdxMacc, DateFrom, DateTo) + .AsNoTracking() + .ToListAsync(); + } + + /// + public async Task> ListPODL_ByCodArtAsync(string CodArticolo, bool OnlyAvail) + { + await using var dbCtx = await GetMoonProContextAsync(); + var pCodArticolo = new SqlParameter("@CodArticolo", CodArticolo); + var pOnlyAvail = new SqlParameter("@onlyAvail", OnlyAvail); + + return await dbCtx + .DbSetPODLExp + .FromSqlRaw("EXEC stp_PODL_getByCodArt @CodArticolo, @onlyAvail", pCodArticolo, pOnlyAvail) + .AsNoTracking() + .ToListAsync(); + } + + /// + public async Task> ListPODL_ByKitParentAsync(int IdxPodlParent) + { + await using var dbCtx = await GetMoonProContextAsync(); + var pIdxPodlParent = new SqlParameter("@IdxPodlParent", IdxPodlParent); + + return await dbCtx + .DbSetPODLExp + .FromSqlRaw("EXEC stp_PODL_getByParentKitIdx @IdxPodlParent", pIdxPodlParent) + .AsNoTracking() + .ToListAsync(); + } + + /// + public async Task> ListPODL_KitFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) + { + await using var dbCtx = await GetMoonProContextAsync(); + var Lanc = new SqlParameter("@Lanciato", lanciato); + var KeyRich = new SqlParameter("@KeyRich", keyRichPart); + var CodGrp = new SqlParameter("@CodGruppo", codGruppo); + var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina); + var DateFrom = new SqlParameter("@DtInizio", startDate); + var DateTo = new SqlParameter("@DtFine", endDate); + + return await dbCtx + .DbSetPODLExp + .FromSqlRaw("EXEC stp_PODL_getByFiltSpecKit @Lanciato, @KeyRich, @CodGruppo, @IdxMacchina, @DtInizio, @DtFine", Lanc, KeyRich, CodGrp, IdxMacc, DateFrom, DateTo) + .AsNoTracking() + .ToListAsync(); + } + + /// + public async Task PODL_getByKeyAsync(int idxPODL) + { + await using var dbCtx = await GetMoonProContextAsync(); + return await dbCtx + .DbSetPODL + .AsNoTracking() + .Where(x => x.IdxPromessa == idxPODL) + .Include(a => a.ArticoloNav) + .FirstOrDefaultAsync() ?? new(); + } + + /// + public async Task PODL_getByOdlAsync(int idxODL) + { + await using var dbCtx = await GetMoonProContextAsync(); + return await dbCtx + .DbSetPODL + .AsNoTracking() + .Where(x => x.IdxOdl == idxODL) + .FirstOrDefaultAsync() ?? new(); + } + + /// + public async Task> PODL_getDictOdlPodlAsync(List missingIds) + { + if (missingIds == null || !missingIds.Any()) + return new Dictionary(); + + await using var dbCtx = await GetMoonProContextAsync(); + return await dbCtx + .DbSetPODL + .AsNoTracking() + .Where(x => missingIds.Contains(x.IdxOdl)) + .ToDictionaryAsync(x => x.IdxOdl, x => x.IdxPromessa); + } + + /// + public async Task PODL_startSetup(PODLExpModel editRec, int matrOpr, double tcRich, int pzPallet, string note, DateTime dtEvent) + { + bool answ = false; + PODLModel recPODL = new PODLModel() + { + IdxPromessa = editRec.IdxPromessa, + KeyRichiesta = editRec.KeyRichiesta, + KeyBCode = editRec.KeyBCode, + IdxOdl = editRec.IdxOdl, + CodArticolo = editRec.CodArticolo, + CodGruppo = editRec.CodGruppo, + IdxMacchina = editRec.IdxMacchina, + NumPezzi = editRec.NumPezzi, + Tcassegnato = editRec.Tcassegnato, + DueDate = editRec.DueDate, + Priorita = editRec.Priorita, + PzPallet = editRec.PzPallet, + Note = editRec.Note, + CodCli = editRec.CodCli, + InsertDate = editRec.InsertDate + }; + + await using var dbCtx = await GetMoonProContextAsync(); + var currRec = await dbCtx + .DbSetPODL + .AsNoTracking() + .Where(x => x.IdxPromessa == recPODL.IdxPromessa) + .FirstOrDefaultAsync(); + + if (currRec != null) + { + var IdxPromessa = new SqlParameter("@idxPromessa", recPODL.IdxPromessa); + var MatrOpr = new SqlParameter("@MatrOpr", matrOpr); + var IdxMacchina = new SqlParameter("@IdxMacchina", recPODL.IdxMacchina); + var TCRichAttr = new SqlParameter("@TCRichAttr", tcRich); + var PzPallet = new SqlParameter("@PzPallet", pzPallet); + var Note = new SqlParameter("@Note", note); + var DtEvento = new SqlParameter("@dtEvento", dtEvent); + await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC stp_ODL_inizioSetupPromessa @idxPromessa, @MatrOpr, @IdxMacchina, @TCRichAttr, @PzPallet, @Note, @dtEvento", IdxPromessa, MatrOpr, IdxMacchina, TCRichAttr, PzPallet, Note, DtEvento); + + answ = true; + } + return answ; + } + + /// + public async Task PODL_updateRecipe(int idxPODL, string recipeName) + { + bool answ = false; + await using var dbCtx = await GetMoonProContextAsync(); + var currRec = await dbCtx + .DbSetPODL + .Where(x => x.IdxPromessa == idxPODL) + .FirstOrDefaultAsync(); + + if (currRec != null) + { + currRec.Recipe = recipeName; + dbCtx.Entry(currRec).State = EntityState.Modified; + answ = await dbCtx.SaveChangesAsync() > 0; + } + return answ; + } + + /// + public async Task PODLDeleteRecordAsync(PODLExpModel currRec) + { + PODLModel recPODL = new PODLModel() + { + IdxPromessa = currRec.IdxPromessa, + KeyRichiesta = currRec.KeyRichiesta, + KeyBCode = currRec.KeyBCode, + IdxOdl = currRec.IdxOdl, + CodArticolo = currRec.CodArticolo, + CodGruppo = currRec.CodGruppo, + IdxMacchina = currRec.IdxMacchina, + NumPezzi = currRec.NumPezzi, + Tcassegnato = currRec.Tcassegnato, + DueDate = currRec.DueDate, + Priorita = currRec.Priorita, + PzPallet = currRec.PzPallet, + Note = currRec.Note, + CodCli = currRec.CodCli, + InsertDate = currRec.InsertDate + }; + await using var dbCtx = await GetMoonProContextAsync(); + var currVal = await dbCtx + .DbSetPODL + .Where(x => x.IdxPromessa == recPODL.IdxPromessa) + .FirstOrDefaultAsync(); + dbCtx + .DbSetPODL + .Remove(currVal); + return await dbCtx.SaveChangesAsync() > 0; + } + + /// + public async Task PODLUpdateRecordAsync(PODLModel editRec) + { + await using var dbCtx = await GetMoonProContextAsync(); + var currRec = await dbCtx + .DbSetPODL + .Where(x => x.IdxPromessa == editRec.IdxPromessa) + .FirstOrDefaultAsync(); + if (currRec != null) + { + currRec.CodGruppo = editRec.CodGruppo; + currRec.CodArticolo = editRec.CodArticolo; + currRec.IdxMacchina = editRec.IdxMacchina; + currRec.KeyBCode = editRec.KeyBCode; + 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 + { + await dbCtx + .DbSetPODL + .AddAsync(editRec); + } + return await dbCtx.SaveChangesAsync() > 0; + } + + /// + public async Task PodlIstKitDeleteAsync(int IdxPODL) + { + await using var dbCtx = await GetMoonProContextAsync(); + var pIdxPODL = new SqlParameter("@IdxPODL", IdxPODL); + + var dbResult = await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC dbo.stp_PodlIstKit_delete @IdxPODL", pIdxPODL); + return dbResult != 0; + } + + #endregion + + #region Public Methods - Kit + + /// + public async Task IstKitDeleteAsync(IstanzeKitModel rec2del) + { + await using var dbCtx = await GetMoonProContextAsync(); + var actRec = await dbCtx + .DbSetInstKit + .Where(x => x.KeyKit == rec2del.KeyKit && x.KeyExtOrd == rec2del.KeyExtOrd) + .FirstOrDefaultAsync(); + if (actRec != null) + { + dbCtx + .DbSetInstKit + .Remove(actRec); + } + return await dbCtx.SaveChangesAsync() > 0; + } + + /// + public async Task> IstKitFiltAsync(string keyKit, string keyExtOrd) + { + await using var dbCtx = await GetMoonProContextAsync(); + return await dbCtx + .DbSetInstKit + .Where(x => (string.IsNullOrEmpty(keyKit) && string.IsNullOrEmpty(keyExtOrd)) || (x.KeyKit.Contains(keyKit) && !string.IsNullOrEmpty(keyKit)) || (x.KeyExtOrd.Contains(keyExtOrd) && !string.IsNullOrEmpty(keyExtOrd))) + .AsNoTracking() + .ToListAsync() ?? new(); + } + + /// + public async Task IstKitInsertByWKSAsync(string CodArtParent, string KeyFilt) + { + await using var dbCtx = await GetMoonProContextAsync(); + + var pCodArtParent = new SqlParameter("@CodArtParent", CodArtParent); + var pKeyFilt = new SqlParameter("@KeyFilt", KeyFilt); + + var dbResult = await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC dbo.stp_IstKit_insertByWKS @CodArtParent,@KeyFilt", pCodArtParent, pKeyFilt); + return dbResult != 0; + } + + /// + public async Task IstKitUpsertAsync(IstanzeKitModel editRec) + { + await using var dbCtx = await GetMoonProContextAsync(); + var actRec = await dbCtx + .DbSetInstKit + .Where(x => x.KeyKit == editRec.KeyKit && x.KeyExtOrd == editRec.KeyExtOrd) + .FirstOrDefaultAsync(); + + if (actRec == null) + { + await dbCtx + .DbSetInstKit + .AddAsync(editRec); + } + else + { + actRec.CodArtParent = editRec.CodArtParent; + actRec.CodArtChild = editRec.CodArtChild; + actRec.QtyART = editRec.QtyART; + actRec.QtyKIT = editRec.QtyKIT; + dbCtx.Entry(actRec).State = EntityState.Modified; + } + return await dbCtx.SaveChangesAsync() > 0; + } + + /// + public async Task TemplateKitDeleteAsync(TemplateKitModel rec2del) + { + await using var dbCtx = await GetMoonProContextAsync(); + var actRec = await dbCtx + .DbSetTempKit + .Where(x => x.CodArtParent == rec2del.CodArtParent && x.CodArtChild == rec2del.CodArtChild) + .FirstOrDefaultAsync(); + if (actRec != null) + { + dbCtx + .DbSetTempKit + .Remove(actRec); + } + return await dbCtx.SaveChangesAsync() > 0; + } + + /// + public async Task> TemplateKitFiltAsync(string KitCode, string codChild) + { + List dbResult = new List(); + await using var dbCtx = await GetMoonProContextAsync(); + dbResult = await dbCtx + .DbSetTempKit + .Where(x => (string.IsNullOrEmpty(KitCode) && string.IsNullOrEmpty(codChild)) || (x.CodArtParent.Contains(KitCode) && !string.IsNullOrEmpty(KitCode)) || (x.CodArtChild.Contains(codChild) && !string.IsNullOrEmpty(codChild))) + .AsNoTracking() + .ToListAsync(); + return dbResult; + } + + /// + public async Task TemplateKitUpsertAsync(TemplateKitModel editRec, string codAzienda) + { + await using var dbCtx = await GetMoonProContextAsync(); + var recArt = await dbCtx + .DbSetArticoli + .FirstOrDefaultAsync(x => x.CodArticolo == editRec.CodArtParent); + if (recArt == null) + { + AnagArticoliModel newRecArt = new AnagArticoliModel() + { + CodArticolo = editRec.CodArtParent, + Tipo = "KIT", + DescArticolo = $"Articolo KIT - {DateTime.Now:yyyy-MM-dd HH:mm:ss}", + Disegno = "", + Azienda = codAzienda, + CurrRev = "", + ProdRev = "" + }; + dbCtx + .DbSetArticoli + .Add(newRecArt); + } + + var actRec = await dbCtx + .DbSetTempKit + .Where(x => x.CodArtParent == editRec.CodArtParent && x.CodArtChild == editRec.CodArtChild) + .FirstOrDefaultAsync(); + + if (actRec == null) + { + await dbCtx + .DbSetTempKit + .AddAsync(editRec); + } + else + { + actRec.Qty = editRec.Qty; + dbCtx.Entry(actRec).State = EntityState.Modified; + } + return await dbCtx.SaveChangesAsync() > 0; + } + + /// + public async Task WipKitDeleteAsync(WipSetupKitModel rec2del) + { + await using var dbCtx = await GetMoonProContextAsync(); + var actRec = await dbCtx + .DbSetWipKit + .Where(x => x.KeyFilt == rec2del.KeyFilt && x.CodOrd == rec2del.CodOrd) + .FirstOrDefaultAsync(); + if (actRec != null) + { + dbCtx + .DbSetWipKit + .Remove(actRec); + } + return await dbCtx.SaveChangesAsync() > 0; + } + + /// + public async Task WipKitDeleteOlderAsync(DateTime dateLimit) + { + await using var dbCtx = await GetMoonProContextAsync(); + var actRec = await dbCtx + .DbSetWipKit + .Where(x => x.DataIns < dateLimit) + .ToListAsync(); + if (actRec != null && actRec.Any()) + { + dbCtx + .DbSetWipKit + .RemoveRange(actRec); + } + return await dbCtx.SaveChangesAsync() > 0; + } + + /// + public async Task> WipKitFiltAsync(string KeyFilt) + { + List dbResult = new List(); + if (!string.IsNullOrEmpty(KeyFilt)) + { + await using var dbCtx = await GetMoonProContextAsync(); + dbResult = await dbCtx + .DbSetWipKit + .Where(x => x.KeyFilt.Contains(KeyFilt)) + .AsNoTracking() + .ToListAsync(); + } + return dbResult; + } + + /// + public async Task WipKitUpsertAsync(WipSetupKitModel editRec) + { + await using var dbCtx = await GetMoonProContextAsync(); + var actRec = await dbCtx + .DbSetWipKit + .Where(x => x.KeyFilt == editRec.KeyFilt && x.CodOrd == editRec.CodOrd) + .FirstOrDefaultAsync(); + + if (actRec == null) + { + dbCtx + .DbSetWipKit + .Add(editRec); + } + else + { + actRec.CodArt = editRec.CodArt; + actRec.DescArt = editRec.DescArt; + actRec.Qta = editRec.Qta; + actRec.DataIns = editRec.DataIns; + dbCtx.Entry(actRec).State = EntityState.Modified; + } + return await dbCtx.SaveChangesAsync() > 0; + } + + /// + public async Task> TksScoreAsync(string KeyFilt, int MaxResult) + { + List dbResult = new List(); + if (!string.IsNullOrEmpty(KeyFilt)) + { + await using var dbCtx = await GetMoonProContextAsync(); + var pKeyFilt = new SqlParameter("@KeyFilt", KeyFilt); + var pMaxRes = new SqlParameter("@maxResult", MaxResult); + dbResult = await dbCtx + .DbSetTksScore + .FromSqlRaw("EXEC stp_TKS_Search @KeyFilt, @maxResult", pKeyFilt, pMaxRes) + .AsNoTracking() + .ToListAsync(); + } + return dbResult; + } + + #endregion + + #region Public Methods - Macchine/Gruppi + + /// + public async Task> MacchineGetFiltAsync(string codGruppo) + { + await using var dbCtx = await GetMoonProContextAsync(); + if (codGruppo == "*") + { + return await dbCtx + .DbSetMacchine + .AsNoTracking() + .OrderBy(x => x.IdxMacchina) + .ToListAsync(); + } + else + { + return await dbCtx + .DbSetGrp2Macc + .Where(g => g.CodGruppo == codGruppo) + .Join(dbCtx.DbSetMacchine, + g => g.IdxMacchina, + m => m.IdxMacchina, + (g, m) => m + ) + .AsNoTracking() + .OrderBy(x => x.IdxMacchina) + .ToListAsync(); + } + } + + /// + public async Task> MacchineByMatrOperAsync(int MatrOpr) + { + await using var dbCtx = await GetMoonProContextAsync(); + if (MatrOpr == 0) + { + return await dbCtx + .DbSetMacchine + .AsNoTracking() + .OrderBy(x => x.IdxMacchina) + .ToListAsync(); + } + else + { + return await dbCtx + .DbSetGrp2Oper + .Where(g => g.MatrOpr == MatrOpr) + .Join(dbCtx.DbSetGrp2Macc, + g => g.CodGruppo, + m => m.CodGruppo, + (g, m) => m + ) + .Distinct() + .Join(dbCtx.DbSetMacchine, + g => g.IdxMacchina, + m => m.IdxMacchina, + (g, m) => m + ) + .Distinct() + .AsNoTracking() + .OrderBy(x => x.IdxMacchina) + .ToListAsync(); + } + } + + /// + public async Task> MacchineWithFluxAsync(DateTime dtStart, DateTime dtEnd) + { + await using var dbCtx = new MoonPro_FluxContext(_configuration); + return await dbCtx + .DbSetFluxLog + .AsNoTracking() + .Where(x => x.dtEvento >= dtStart && x.dtEvento <= dtEnd) + .Select(i => i.IdxMacchina) + .Distinct() + .ToListAsync() ?? new(); + } + + /// + public async Task Grp2MaccDeleteAsync(Gruppi2MaccModel rec2del) + { + bool answ = false; + await using var dbCtx = await GetMoonProContextAsync(); + var dbRec = await dbCtx + .DbSetGrp2Macc + .Where(x => x.CodGruppo == rec2del.CodGruppo && x.IdxMacchina == rec2del.IdxMacchina) + .FirstOrDefaultAsync(); + if (dbRec != null) + { + dbCtx.DbSetGrp2Macc.Remove(dbRec); + int numDone = await dbCtx.SaveChangesAsync(); + answ = numDone != 0; + } + return answ; + } + + /// + public async Task Grp2MaccInsertAsync(Gruppi2MaccModel upsRec) + { + bool answ = false; + await using var dbCtx = await GetMoonProContextAsync(); + var dbRec = await dbCtx + .DbSetGrp2Macc + .Where(x => x.CodGruppo == upsRec.CodGruppo && x.IdxMacchina == upsRec.IdxMacchina) + .FirstOrDefaultAsync(); + if (dbRec == null) + { + await dbCtx.DbSetGrp2Macc.AddAsync(upsRec); + int numDone = await dbCtx.SaveChangesAsync(); + answ = numDone != 0; + } + return answ; + } + + /// + public async Task Grp2OperDeleteAsync(Gruppi2OperModel rec2del) + { + bool answ = false; + await using var dbCtx = await GetMoonProContextAsync(); + var dbRec = await dbCtx + .DbSetGrp2Oper + .Where(x => x.CodGruppo == rec2del.CodGruppo && x.MatrOpr == rec2del.MatrOpr) + .FirstOrDefaultAsync(); + if (dbRec != null) + { + dbCtx.DbSetGrp2Oper.Remove(dbRec); + int numDone = await dbCtx.SaveChangesAsync(); + answ = numDone != 0; + } + return answ; + } + + /// + public async Task Grp2OperInsertAsync(Gruppi2OperModel upsRec) + { + bool answ = false; + await using var dbCtx = await GetMoonProContextAsync(); + var dbRec = await dbCtx + .DbSetGrp2Oper + .Where(x => x.CodGruppo == upsRec.CodGruppo && x.MatrOpr == upsRec.MatrOpr) + .FirstOrDefaultAsync(); + if (dbRec == null) + { + await dbCtx.DbSetGrp2Oper.AddAsync(upsRec); + int numDone = await dbCtx.SaveChangesAsync(); + answ = numDone != 0; + } + return answ; + } + + /// + public async Task> StatoMacchinaAsync(string idxMacchina) + { + await using var dbCtx = await GetMoonProContextAsync(); + return (await dbCtx + .DbSetStatoMacc + .AsNoTracking() + .Where(x => x.IdxMacchina == idxMacchina) + .ToListAsync()) + .AsReadOnly(); + } + + #endregion + + #region Public Methods - Misc + + /// + public async Task> MseGetAllAsync(int maxAge = 2000) + { + List dbResult = new List(); + await using var dbCtx = await GetMoonProContextAsync(); + + var maxAgeSec = new SqlParameter("@maxAgeSec", maxAge); + + dbResult = await dbCtx + .DbSetMSE + .FromSqlRaw("EXEC stp_MSE_getData @maxAgeSec", maxAgeSec) + .AsNoTracking() + .ToListAsync(); + + return dbResult; + } + + /// + public async Task> ListGiacenzeAsync(int IdxOdl) + { + await using var dbCtx = new MoonPro_InveContext(_configuration); + return await dbCtx + .DbGiacenzeData + .Where(x => x.IdxOdl == IdxOdl) + .AsNoTracking() + .ToListAsync() ?? new(); + } + + /// + public async Task> OperatoriGetFiltAsync(string codGruppo) + { + List dbResult = new List(); + await using var dbCtx = await GetMoonProContextAsync(); + if (codGruppo == "*") + { + dbResult = await dbCtx + .DbOperatori + .AsNoTracking() + .OrderBy(x => x.MatrOpr) + .ToListAsync(); + } + else + { + dbResult = await dbCtx + .DbSetGrp2Oper + .Where(g => g.CodGruppo == codGruppo) + .Join(dbCtx.DbOperatori, + g => g.MatrOpr, + m => m.MatrOpr, + (g, m) => m + ) + .AsNoTracking() + .OrderBy(x => x.MatrOpr) + .ToListAsync(); + } + return dbResult; + } + + /// + public async Task> ParametriGetFiltAsync(string IdxMacchina) + { + await using var dbCtx = new MoonPro_FluxContext(_configuration); + return await dbCtx + .DbSetFluxLog + .AsNoTracking() + .Where(x => (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina)) + .Take(1000) + .Select(i => i.CodFlux) + .Distinct() + .OrderBy(x => x) + .ToListAsync(); + } + + #endregion + } +} diff --git a/MP.Data/Repository/System/ISystemRepository.cs b/MP.Data/Repository/System/ISystemRepository.cs new file mode 100644 index 00000000..055c3a87 --- /dev/null +++ b/MP.Data/Repository/System/ISystemRepository.cs @@ -0,0 +1,24 @@ +using MP.Data.DbModels; +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace MP.Data.Repository.System +{ + public interface ISystemRepository + { + Task> ConfigGetAllAsync(); + + Task ConfigUpdateAsync(ConfigModel updRec); + + Task EvListInsertAsync(EventListModel newRec); + + Task ForceDbMaintAsync(bool doExec, bool doUpdStat, bool doSave, int minPgCnt, int minAvgFrag, int maxAvgFragReb); + + Task> ListLinkAllAsync(); + + Task> ListLinkFiltAsync(string tipoLink); + + Task> ElencoLinkAsync(); + } +} diff --git a/MP.Data/Repository/System/SystemRepository.cs b/MP.Data/Repository/System/SystemRepository.cs new file mode 100644 index 00000000..1f078364 --- /dev/null +++ b/MP.Data/Repository/System/SystemRepository.cs @@ -0,0 +1,114 @@ +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using MP.Data.DbModels; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MP.Data.Repository.System +{ + public class SystemRepository : ISystemRepository + { + #region Private Fields + + private readonly IDbContextFactory _ctxFactory; + private readonly IConfiguration _configuration; + + #endregion + + #region Public Constructors + + public SystemRepository(IDbContextFactory ctxFactory, IConfiguration configuration) + { + _ctxFactory = ctxFactory; + _configuration = configuration; + } + + #endregion + + #region Public Methods + + /// + public async Task> ConfigGetAllAsync() + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + return await dbCtx + .DbSetConfig + .AsNoTracking() + .OrderBy(x => x.Chiave) + .ToListAsync() ?? new(); + } + + /// + public async Task ConfigUpdateAsync(ConfigModel updRec) + { + bool fatto = false; + ConfigModel dbResult = new(); + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + dbResult = await dbCtx + .DbSetConfig + .Where(x => x.Chiave == updRec.Chiave) + .FirstOrDefaultAsync(); + if (dbResult != null) + { + dbResult.Valore = updRec.Valore; + fatto = await dbCtx.SaveChangesAsync() > 0; + } + return fatto; + } + + /// + public async Task EvListInsertAsync(EventListModel newRec) + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + _ = await dbCtx + .DbSetEvList + .AddAsync(newRec); + return await dbCtx.SaveChangesAsync() > 0; + } + + /// + public async Task ForceDbMaintAsync(bool doExec, bool doUpdStat, bool doSave, int minPgCnt, int minAvgFrag, int maxAvgFragReb) + { + await using var dbCtx = new MoonProAdminContext(_configuration); + + _ = await dbCtx + .Database + .ExecuteSqlRawAsync("EXEC man.stp_Utility_Maintanance"); + return true; + } + + /// + public async Task> ListLinkAllAsync() + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + return await dbCtx + .DbSetLinkMenu + .AsNoTracking() + .OrderBy(x => x.Ordine) + .ToListAsync(); + } + + /// + public async Task> ListLinkFiltAsync(string tipoLink) + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + return await dbCtx + .DbSetLinkMenu + .Where(x => x.TipoLink == tipoLink) + .AsNoTracking() + .OrderBy(x => x.Ordine) + .ToListAsync(); + } + + /// + public Task> ElencoLinkAsync() + { + return ListLinkFiltAsync("SpecLink"); + } + + #endregion + } +} diff --git a/MP.SPEC/refactor_repository.md b/MP.SPEC/refactor_repository.md index e804649b..3dca7787 100644 --- a/MP.SPEC/refactor_repository.md +++ b/MP.SPEC/refactor_repository.md @@ -29,19 +29,27 @@ ## 4. Checklist Avanzamento Modifiche ### Fase 1: Preparazione (Infrastruttura) -- [ ] Creazione file -efactor_repository.md. -- [ ] Analisi delle interfacce necessarie per ogni dominio. -- [ ] Rinomina MpSpecController $\rightarrow$ MpSpecRepository (per allineamento naming). +- [x] Creazione file refactor_repository.md. +- [x] Analisi delle interfacce necessarie per ogni dominio. +- [x] Rinomina MpSpecController $\rightarrow$ MpSpecRepository (per allineamento naming). ### Fase 2: Estrazione Modulare (Iterativa) -- [ ] **Modulo Anagrafica**: Creazione AnagRepository $\rightarrow$ Spostamento metodi $\rightarrow$ Aggiornamento MpDataService. -- [ ] **Modulo Produzione**: Creazione ProductionRepository $\rightarrow$ Spostamento metodi $\rightarrow$ Aggiornamento MpDataService. -- [ ] **Modulo Dossier**: Creazione DossierRepository $\rightarrow$ Spostamento metodi $\rightarrow$ Aggiornamento MpDataService. -- [ ] **Modulo FluxLog**: Creazione FluxLogRepository $\rightarrow$ Spostamento metodi $\rightarrow$ Aggiornamento MpDataService. -- [ ] **Modulo Sistema**: Creazione SystemRepository $\rightarrow$ Spostamento metodi $\rightarrow$ Aggiornamento MpDataService. +- [x] **Modulo Anagrafica**: Creazione AnagRepository + IAnagRepository (26 metodi migrati, codice sorgente in `#if false` in MpSpecRepository). File: `MP.Data\Repository\Anag\` +- [x] **Modulo Produzione**: Creazione ProductionRepository + IProductionRepository (32 metodi migrati). File: `MP.Data\Repository\Production\` + - ODL: ListODLFiltAsync, OdlByKeyAsync, ODLCloseAsync, OdlGetCurrentAsync, OdlGetStatAsync, OdlByBatchAsync + - PODL: ListPODLFiltAsync, ListPODL_ByCodArtAsync, ListPODL_ByKitParentAsync, ListPODL_KitFiltAsync, PODL_getByKeyAsync, PODL_getByOdlAsync, PODL_getDictOdlPodlAsync, PODL_startSetup, PODL_updateRecipe, PODLDeleteRecordAsync, PODLUpdateRecordAsync, PodlIstKitDeleteAsync + - Kit: IstKitDeleteAsync, IstKitFiltAsync, IstKitInsertByWKSAsync, IstKitUpsertAsync, TemplateKitDeleteAsync, TemplateKitFiltAsync, TemplateKitUpsertAsync, WipKitDeleteAsync, WipKitDeleteOlderAsync, WipKitFiltAsync, WipKitUpsertAsync, TksScoreAsync + - Macchine/Gruppi: MacchineGetFiltAsync, MacchineByMatrOperAsync, MacchineWithFluxAsync, Grp2MaccDeleteAsync, Grp2MaccInsertAsync, Grp2OperDeleteAsync, Grp2OperInsertAsync + - Misc: MseGetAllAsync, ListGiacenzeAsync, OperatoriGetFiltAsync, ParametriGetFiltAsync +- [x] **Modulo Dossier**: Creazione DossierRepository + IDossierRepository (5 metodi migrati). File: `MP.Data\Repository\Dossier\` + - DossiersDeleteRecordAsync, DossiersGetLastFiltAsync, DossiersInsertAsync, DossiersTakeParamsSnapshotLastAsync, DossiersUpdateValoreAsync +- [x] **Modulo FluxLog**: Creazione FluxLogRepository + IFluxLogRepository (3 metodi migrati). File: `MP.Data\Repository\FluxLog\` + - FluxLogDataReduxAsync, FluxLogGetLastFiltAsync, FluxLogParetoAsync +- [x] **Modulo Sistema**: Creazione SystemRepository + ISystemRepository (7 metodi migrati). File: `MP.Data\Repository\System\` + - ConfigGetAllAsync, ConfigUpdateAsync, EvListInsertAsync, ForceDbMaintAsync, ListLinkAllAsync, ListLinkFiltAsync, ElencoLinkAsync ### Fase 3: Pulizia e Verifica -- [ ] Rimozione del codice residuo da MpSpecRepository. -- [ ] Verifica della compilazione della soluzione (./build_all_par.ps1 --agent). -- [ ] Verifica della coerenza dei log e della persistenza dei dati. +- [ ] **Passo 3.1**: Spostamento a `#if false` dei metodi migrati in MpSpecRepository (33 metodi originali ancora attivi). +- [ ] **Passo 3.2**: Verifica compilazione (dotnet build MP.Data\MP.Data.csproj). +- [ ] **Passo 3.3**: Aggiornamento MpDataService per iniettare i 5 nuovi repository invece di MpSpecRepository. +- [ ] **Passo 3.4**: Refactoring MpSpecRepository (solo metodi residui non migrati). diff --git a/build_all_par.ps1 b/build_all_par.ps1 index 9cd56ce2..8d845d01 100644 --- a/build_all_par.ps1 +++ b/build_all_par.ps1 @@ -1,3 +1,9 @@ +# build_all_par.ps1 +# script per compilazione (parallela) progetti MAPO-CORE +# nb: prerequisito powershell >= 7, install con +# winget install Microsoft.PowerShell + + # --- CONFIGURAZIONE --- $pattern = "MP-*.sln" $sharedProjectPath = ".\MP.Data\MP.Data.csproj" @@ -9,7 +15,9 @@ $agentMode = $args -contains "--agent" $stopwatch = [System.Diagnostics.Stopwatch]::StartNew() # 1. Trova l'MSBuild ufficiale di Visual Studio 2022 -$vsPaths = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -version "[17.0,18.0)" -products * -requires Microsoft.Component.MSBuild -property installationPath +$vsPaths = @(& "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -version "[17.0,19.0)" -products * -requires Microsoft.Component.MSBuild -property installationPath) +# versione WKS-R9-SAM +# $vsPaths = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -version "[17.0,18.0)" -products * -requires Microsoft.Component.MSBuild -property installationPath if (-not $vsPaths) { if ($agentMode) { exit 1 } Write-Host "❌ Impossibile trovare Visual Studio 2022!" -ForegroundColor Red From 05313c123ceaebd5a3abacaa64245cfc9699ab3d Mon Sep 17 00:00:00 2001 From: "Samuele E. Locatelli (W11-AI)" Date: Tue, 2 Jun 2026 16:07:44 +0200 Subject: [PATCH 091/102] Correzione tipi restituiti --- MP.Data/Repository/FluxLog/FluxLogRepository.cs | 2 ++ .../Repository/FluxLog/IFluxLogRepository.cs | 2 ++ .../Production/IProductionRepository.cs | 5 ++--- .../Production/ProductionRepository.cs | 17 +++++++---------- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/MP.Data/Repository/FluxLog/FluxLogRepository.cs b/MP.Data/Repository/FluxLog/FluxLogRepository.cs index 6032c730..2bf4ca5a 100644 --- a/MP.Data/Repository/FluxLog/FluxLogRepository.cs +++ b/MP.Data/Repository/FluxLog/FluxLogRepository.cs @@ -1,4 +1,5 @@ using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using MP.Core.DTO; using MP.Core.Objects; @@ -8,6 +9,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; +using static EgwCoreLib.Utils.DtUtils; namespace MP.Data.Repository.FluxLog { diff --git a/MP.Data/Repository/FluxLog/IFluxLogRepository.cs b/MP.Data/Repository/FluxLog/IFluxLogRepository.cs index 0d50ca31..c30d4839 100644 --- a/MP.Data/Repository/FluxLog/IFluxLogRepository.cs +++ b/MP.Data/Repository/FluxLog/IFluxLogRepository.cs @@ -1,8 +1,10 @@ using MP.Core.DTO; +using MP.Core.Objects; using MP.Data.DbModels; using System; using System.Collections.Generic; using System.Threading.Tasks; +using static EgwCoreLib.Utils.DtUtils; namespace MP.Data.Repository.FluxLog { diff --git a/MP.Data/Repository/Production/IProductionRepository.cs b/MP.Data/Repository/Production/IProductionRepository.cs index 68e464a4..8a2cd94a 100644 --- a/MP.Data/Repository/Production/IProductionRepository.cs +++ b/MP.Data/Repository/Production/IProductionRepository.cs @@ -1,4 +1,3 @@ -using MP.Core.DTO; using MP.Data.DbModels; using System; using System.Collections.Generic; @@ -12,7 +11,7 @@ namespace MP.Data.Repository.Production Task> ListODLFiltAsync(bool inCorso, string codArt, string keyRichPart, string Reparto, string IdxMacchina, DateTime startDate, DateTime endDate); - Task> OdlByKeyAsync(int IdxOdl); + Task OdlByKeyAsync(int IdxOdl); Task ODLCloseAsync(int idxOdl, string idxMacchina, int matrOpr, bool confPezzi, bool confRett, int modoConfProd); @@ -96,7 +95,7 @@ namespace MP.Data.Repository.Production Task Grp2OperInsertAsync(Gruppi2OperModel upsRec); - Task> StatoMacchinaAsync(string idxMacchina); + Task StatoMacchinaAsync(string idxMacchina); #endregion diff --git a/MP.Data/Repository/Production/ProductionRepository.cs b/MP.Data/Repository/Production/ProductionRepository.cs index 1d5196ac..7905e7af 100644 --- a/MP.Data/Repository/Production/ProductionRepository.cs +++ b/MP.Data/Repository/Production/ProductionRepository.cs @@ -1,11 +1,9 @@ using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; -using MP.Core.DTO; using MP.Data.DbModels; using System; using System.Collections.Generic; -using System.Diagnostics; using System.Linq; using System.Threading.Tasks; @@ -59,7 +57,7 @@ namespace MP.Data.Repository.Production } /// - public async Task> OdlByKeyAsync(int IdxOdl) + public async Task OdlByKeyAsync(int IdxOdl) { await using var dbCtx = await GetMoonProContextAsync(); return await dbCtx @@ -110,11 +108,11 @@ namespace MP.Data.Repository.Production List dbResult = new List(); if (IdxOdl > 0) { - await using var dbCtx = new MoonPro_STATSContext(_configuration); + await using var dbCtx = await GetMoonProContextAsync(); var IdxODL = new SqlParameter("@IdxODL", IdxOdl); dbResult = await dbCtx - .DbSetODL + .DbSetStatOdl .FromSqlRaw("EXEC stp_STAT_ODL @IdxODL", IdxODL) .AsNoTracking() .ToListAsync(); @@ -771,15 +769,14 @@ namespace MP.Data.Repository.Production } /// - public async Task> StatoMacchinaAsync(string idxMacchina) + public async Task StatoMacchinaAsync(string idxMacchina) { await using var dbCtx = await GetMoonProContextAsync(); - return (await dbCtx + return await dbCtx .DbSetStatoMacc - .AsNoTracking() .Where(x => x.IdxMacchina == idxMacchina) - .ToListAsync()) - .AsReadOnly(); + .AsNoTracking() + .FirstOrDefaultAsync(); } #endregion From 0a6133a0c935c0e0bd285f1d4a5c4f39600618f5 Mon Sep 17 00:00:00 2001 From: "Samuele E. Locatelli (W11-AI)" Date: Tue, 2 Jun 2026 17:22:15 +0200 Subject: [PATCH 092/102] Aggiunta gestione repository nuovi x ListSelect e OrderData --- MP.Data/Services/ListSelectDataSrv.cs | 56 ++++++++++----------------- MP.Data/Services/OrderDataSrv.cs | 50 +++++++++--------------- 2 files changed, 40 insertions(+), 66 deletions(-) diff --git a/MP.Data/Services/ListSelectDataSrv.cs b/MP.Data/Services/ListSelectDataSrv.cs index a41b524d..689827e2 100644 --- a/MP.Data/Services/ListSelectDataSrv.cs +++ b/MP.Data/Services/ListSelectDataSrv.cs @@ -1,6 +1,8 @@ using Microsoft.Extensions.Configuration; +using MP.Core.Objects; using MP.Data.DbModels; using MP.Data.Repository.Anag; +using MP.Data.Repository.Production; using Newtonsoft.Json; using NLog; using StackExchange.Redis; @@ -8,7 +10,6 @@ using System; using System.Collections.Generic; using System.Data; using System.Diagnostics; -using System.Linq; using System.Text; using System.Threading.Tasks; @@ -19,33 +20,27 @@ namespace MP.Data.Services /// public class ListSelectDataSrv : BaseServ { + #region Private Fields + + private static Logger Log = LogManager.GetCurrentClassLogger(); + private readonly IAnagRepository _anagRepository; + private readonly IProductionRepository _productionRepository; + private readonly ISystemRepository _systemRepository; + private bool _disposed = false; + private string redisBaseKey = "MP:ALL:Cache"; + + #endregion + #region Public Constructors - public ListSelectDataSrv(IConfiguration configuration, IConnectionMultiplexer redConn, IAnagRepository anagRepository) : base(configuration, redConn) + public ListSelectDataSrv(IConfiguration configuration, IConnectionMultiplexer redConn, IAnagRepository anagRepository, IProductionRepository productionRepository, ISystemRepository systemRepository) : base(configuration, redConn) { _anagRepository = anagRepository; - // conf DB - string connStr = _configuration.GetConnectionString("MP.All"); - if (string.IsNullOrEmpty(connStr)) - { - Log.Error("ConnString empty!"); - } - else - { - StringBuilder sb = new StringBuilder(); - dbController = new Controllers.MpSpecController(configuration); - sb.AppendLine($"ListSelectDataSrv | MpSpecController OK"); - Log.Info(sb.ToString()); - } + _productionRepository = productionRepository; + _systemRepository = systemRepository; } - #endregion Public Constructors - - #region Public Properties - - public static Controllers.MpSpecController dbController { get; set; } = null!; - - #endregion Public Properties + #endregion #region Public Methods @@ -106,7 +101,7 @@ namespace MP.Data.Services } else { - result = await dbController.ConfigGetAllAsync(); + result = await _systemRepository.ConfigGetAllAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); _redisDb.StringSet(currKey, rawData, LongCache); @@ -162,7 +157,7 @@ namespace MP.Data.Services } else { - result = await dbController.ListLinkAllAsync(); + result = await _systemRepository.ListLinkAllAsync(); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await _redisDb.StringSetAsync(currKey, rawData, UltraLongCache); @@ -198,7 +193,7 @@ namespace MP.Data.Services } else { - result = await dbController.ListLinkFiltAsync(tipoLink); + result = await _systemRepository.ListLinkFiltAsync(tipoLink); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await _redisDb.StringSetAsync(currKey, rawData, UltraLongCache); @@ -234,7 +229,7 @@ namespace MP.Data.Services } else { - result = await dbController.MacchineByMatrOperAsync(MatrOpr); + result = await _productionRepository.MacchineByMatrOperAsync(MatrOpr); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await _redisDb.StringSetAsync(currKey, rawData, UltraLongCache); @@ -266,15 +261,6 @@ namespace MP.Data.Services #endregion Protected Methods - #region Private Fields - - private static Logger Log = LogManager.GetCurrentClassLogger(); - private readonly IAnagRepository _anagRepository; - private bool _disposed = false; - private string redisBaseKey = "MP:ALL:Cache"; - - #endregion Private Fields - #region Private Methods /// diff --git a/MP.Data/Services/OrderDataSrv.cs b/MP.Data/Services/OrderDataSrv.cs index 5daa7858..22140226 100644 --- a/MP.Data/Services/OrderDataSrv.cs +++ b/MP.Data/Services/OrderDataSrv.cs @@ -1,5 +1,8 @@ using Microsoft.Extensions.Configuration; +using MP.Core.Objects; using MP.Data.DbModels; +using MP.Data.Repository.Production; +using MP.Data.Repository.System; using Newtonsoft.Json; using NLog; using StackExchange.Redis; @@ -16,32 +19,25 @@ namespace MP.Data.Services /// public class OrderDataSrv : BaseServ { + #region Private Fields + + private static Logger Log = LogManager.GetCurrentClassLogger(); + private readonly IProductionRepository _productionRepository; + private readonly ISystemRepository _systemRepository; + private bool _disposed = false; + private string redisBaseKey = "MP:ALL:Cache"; + + #endregion + #region Public Constructors - public OrderDataSrv(IConfiguration configuration, IConnectionMultiplexer redConn) : base(configuration, redConn) + public OrderDataSrv(IConfiguration configuration, IConnectionMultiplexer redConn, IProductionRepository productionRepository, ISystemRepository systemRepository) : base(configuration, redConn) { - // conf DB - string connStr = _configuration.GetConnectionString("MP.All"); - if (string.IsNullOrEmpty(connStr)) - { - Log.Error("ConnString empty!"); - } - else - { - dbController = new Controllers.MpSpecController(configuration); - StringBuilder sb = new StringBuilder(); - sb.AppendLine($"OrderDataSrv | MpSpecController OK"); - Log.Info(sb.ToString()); - } + _productionRepository = productionRepository; + _systemRepository = systemRepository; } - #endregion Public Constructors - - #region Public Properties - - public static Controllers.MpSpecController dbController { get; set; } = null!; - - #endregion Public Properties + #endregion #region Public Methods @@ -66,7 +62,7 @@ namespace MP.Data.Services } else { - result = await dbController.ConfigGetAllAsync(); + result = await _systemRepository.ConfigGetAllAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); _redisDb.StringSet(currKey, rawData, LongCache); @@ -109,7 +105,7 @@ namespace MP.Data.Services } else { - result = await dbController.ListODLFiltAsync(inCorso, CodArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate); + result = await _productionRepository.ListODLFiltAsync(inCorso, CodArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await _redisDb.StringSetAsync(currKey, rawData, LongCache); @@ -140,13 +136,5 @@ namespace MP.Data.Services } #endregion Protected Methods - - #region Private Fields - - private static Logger Log = LogManager.GetCurrentClassLogger(); - private bool _disposed = false; - private string redisBaseKey = "MP:ALL:Cache"; - - #endregion Private Fields } } \ No newline at end of file From 843435ad3bd25abe45710b2a6da1201fd30c4010 Mon Sep 17 00:00:00 2001 From: "Samuele E. Locatelli (W11-AI)" Date: Tue, 2 Jun 2026 20:02:38 +0200 Subject: [PATCH 093/102] Continua revisione codice assisted --- MP.Data/DataServiceCollectionExtensions.cs | 1 + MP.Data/Repository/Anag/AnagRepository.cs | 7 +- MP.Data/Repository/Anag/IAnagRepository.cs | 4 +- .../Repository/Dossier/DossierRepository.cs | 12 ++ .../Repository/Dossier/IDossierRepository.cs | 2 + MP.Data/Services/ListSelectDataSrv.cs | 4 +- MP.SPEC/Data/MpDataService.cs | 163 +++++++++--------- 7 files changed, 99 insertions(+), 94 deletions(-) diff --git a/MP.Data/DataServiceCollectionExtensions.cs b/MP.Data/DataServiceCollectionExtensions.cs index 5985cf22..44116d5c 100644 --- a/MP.Data/DataServiceCollectionExtensions.cs +++ b/MP.Data/DataServiceCollectionExtensions.cs @@ -78,6 +78,7 @@ namespace MP.Data // ---------- Start Altro ---------- // Singleton services.TryAddSingleton(); + services.TryAddScoped(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); diff --git a/MP.Data/Repository/Anag/AnagRepository.cs b/MP.Data/Repository/Anag/AnagRepository.cs index 3fbfce71..a4a00cf8 100644 --- a/MP.Data/Repository/Anag/AnagRepository.cs +++ b/MP.Data/Repository/Anag/AnagRepository.cs @@ -431,14 +431,13 @@ namespace MP.Data.Repository.Anag } /// - /// Recupero dizionario traduzioni da cache o DB - + /// Recupero dizionario traduzioni /// /// Codice lingua /// Dizionario di traduzioni - public async Task> VocabolarioGetLangAsync(string lingua) + public Dictionary VocabolarioGetLang(string lingua) { - await using var dbCtx = await CreateContextAsync(); + using var dbCtx = _ctxFactory.CreateDbContextAsync().GetAwaiter().GetResult(); var rawList = dbCtx .DbSetVocabolario .AsNoTracking() diff --git a/MP.Data/Repository/Anag/IAnagRepository.cs b/MP.Data/Repository/Anag/IAnagRepository.cs index 953fdd32..7b943098 100644 --- a/MP.Data/Repository/Anag/IAnagRepository.cs +++ b/MP.Data/Repository/Anag/IAnagRepository.cs @@ -191,11 +191,11 @@ namespace MP.Data.Repository.Anag Task> PODL_getDictOdlPodlAsync(List missingIds); /// - /// Recupero dizionario traduzioni da cache o DB + /// Recupero dizionario traduzioni /// /// Codice lingua /// Dizionario di traduzioni - Task> VocabolarioGetLangAsync(string lingua); + Dictionary VocabolarioGetLang(string lingua); #endregion Public Methods } diff --git a/MP.Data/Repository/Dossier/DossierRepository.cs b/MP.Data/Repository/Dossier/DossierRepository.cs index 91f26562..4fcf2319 100644 --- a/MP.Data/Repository/Dossier/DossierRepository.cs +++ b/MP.Data/Repository/Dossier/DossierRepository.cs @@ -104,6 +104,18 @@ namespace MP.Data.Repository.Dossier return await dbCtx.SaveChangesAsync() > 0; } + /// + public async Task> ArticleWithDossierAsync() + { + await using var dbCtx = new MoonPro_FluxContext(_configuration); + return await dbCtx + .DbSetDossiers + .AsNoTracking() + .Select(i => i.CodArticolo) + .Distinct() + .ToListAsync(); + } + #endregion } } diff --git a/MP.Data/Repository/Dossier/IDossierRepository.cs b/MP.Data/Repository/Dossier/IDossierRepository.cs index 3f6852bd..73164af9 100644 --- a/MP.Data/Repository/Dossier/IDossierRepository.cs +++ b/MP.Data/Repository/Dossier/IDossierRepository.cs @@ -19,6 +19,8 @@ namespace MP.Data.Repository.Dossier Task DossiersUpdateValoreAsync(DossierModel editRec); + Task> ArticleWithDossierAsync(); + #endregion } } diff --git a/MP.Data/Services/ListSelectDataSrv.cs b/MP.Data/Services/ListSelectDataSrv.cs index 689827e2..af6b8aef 100644 --- a/MP.Data/Services/ListSelectDataSrv.cs +++ b/MP.Data/Services/ListSelectDataSrv.cs @@ -1,8 +1,8 @@ using Microsoft.Extensions.Configuration; -using MP.Core.Objects; using MP.Data.DbModels; using MP.Data.Repository.Anag; using MP.Data.Repository.Production; +using MP.Data.Repository.System; using Newtonsoft.Json; using NLog; using StackExchange.Redis; @@ -10,7 +10,7 @@ using System; using System.Collections.Generic; using System.Data; using System.Diagnostics; -using System.Text; +using System.Linq; using System.Threading.Tasks; namespace MP.Data.Services diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index e000ad5a..fb8b75b2 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -7,6 +7,10 @@ using MP.Data.Controllers; using MP.Data.DbModels; using MP.Data.MgModels; using MP.Data.Repository.Anag; +using MP.Data.Repository.Dossier; +using MP.Data.Repository.FluxLog; +using MP.Data.Repository.Production; +using MP.Data.Repository.System; using MP.Data.Services; using Newtonsoft.Json; using NLog; @@ -22,48 +26,33 @@ namespace MP.SPEC.Data #region Public Constructors private readonly IAnagRepository _anagRepository; + private readonly ISystemRepository _systemRepository; + private readonly IDossierRepository _dossierRepository; + private readonly IFluxLogRepository _fluxLogRepository; + private readonly IProductionRepository _productionRepository; - public MpDataService(IConfiguration configuration, IFusionCache cache, IAnagRepository anagRepository) + public MpDataService(IConfiguration configuration, IFusionCache cache, IAnagRepository anagRepository, ISystemRepository systemRepository, IDossierRepository dossierRepository, IFluxLogRepository fluxLogRepository, IProductionRepository productionRepository) { // salvataggio oggetti _configuration = configuration; _cache = cache; _anagRepository = anagRepository; + _systemRepository = systemRepository; + _dossierRepository = dossierRepository; + _fluxLogRepository = fluxLogRepository; + _productionRepository = productionRepository; // Verifica conf trace... traceEnabled = _configuration.GetValue("Otel:EnableTracing", false); slowLogThresh = _configuration.GetValue("ServerConf:slowLogThresh", 1); Log.Info($"MpDataService | INIT | Trace enabled: {traceEnabled}"); // setup compoenti REDIS - redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis") ?? "localhost:6379"); - redisConnAdmin = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("RedisAdmin") ?? "localhost:6379"); - redisDb = redisConn.GetDatabase(); - // leggo cache lungo/cordo periodo - int.TryParse(_configuration.GetValue("ServerConf:redisShortTimeCache"), out redisShortTimeCache); - int.TryParse(_configuration.GetValue("ServerConf:redisLongTimeCache"), out redisLongTimeCache); - - // setup MsgPipe - BroadastMsgPipe = new MessagePipe(redisConn, Constants.BROADCAST_M_PIPE); - Log.Info("MpDataService | Redis OK"); - - // conf DB - string connStr = _configuration.GetConnectionString("MP.Data") ?? ""; - if (string.IsNullOrEmpty(connStr)) - { - Log.Error("DbController: ConnString empty!"); - } - else - { - dbController = new MpSpecController(configuration); - Log.Info("DbController OK"); - } - // conf x lettura dati da area REDIS di MP-IO MpIoNS = _configuration.GetValue("ServerConf:MpIoNS") ?? ""; // conf mongo... - connStr = _configuration.GetConnectionString("mdbConnString") ?? ""; - if (string.IsNullOrEmpty(connStr)) + string mongoConnStr = _configuration.GetConnectionString("mdbConnString") ?? ""; + if (string.IsNullOrEmpty(mongoConnStr)) { Log.Error("MongoController: ConnString empty!"); } @@ -246,8 +235,9 @@ namespace MP.SPEC.Data ); } +#if false /// - /// Elenco Codice articolo con dati dossier gestiti + /// Elenco codice articoli che abbiano dati Dossier /// /// public async Task> ArticleWithDossierAsync() @@ -256,10 +246,11 @@ namespace MP.SPEC.Data operationName: "ArticleWithDossierAsync", cacheKey: Utils.redisArtByDossier, expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => await dbController.ArticleWithDossierAsync() ?? new List(), + fetchFunc: async () => await _dossierRepository.ArticleWithDossierAsync() ?? new List(), tagList: [Utils.redisArtByDossier] ); } +#endif /// /// Conteggio articoli data ricerca @@ -444,7 +435,7 @@ namespace MP.SPEC.Data operationName: "ConfigGetAllAsync", cacheKey: Utils.redisConfAll, expiration: GetRandTOut(redisLongTimeCache * 2), - fetchFunc: async () => await dbController.ConfigGetAllAsync() ?? new List(), + fetchFunc: async () => await _systemRepository.ConfigGetAllAsync() ?? new List(), tagList: [Utils.redisConfAll] ); } @@ -494,7 +485,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("ConfigUpdateAsync"); string source = "DB"; - var updRes = await dbController.ConfigUpdateAsync(updRec); + var updRes = await _systemRepository.ConfigUpdateAsync(updRec); await FlushFusionCacheConfig(); activity?.SetTag("data.source", source); activity?.Stop(); @@ -547,7 +538,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("DossiersDeleteRecordAsync"); bool result = false; - result = await dbController.DossiersDeleteRecordAsync(selRecord); + result = await _dossierRepository.DossiersDeleteRecordAsync(selRecord); // elimino cache... await FlushFusionCacheAsync(Utils.redisDossByMac); activity?.SetTag("data.source", "DB"); @@ -572,7 +563,7 @@ namespace MP.SPEC.Data operationName: "DossiersGetLastFiltAsync", cacheKey: currKey, expiration: GetRandTOut(redisLongTimeCache * 5), - fetchFunc: async () => await dbController.DossiersGetLastFiltAsync(IdxMacchina, CodArticolo, DtStart, DtEnd, MaxRec) ?? new List(), + fetchFunc: async () => await _dossierRepository.DossiersGetLastFiltAsync(IdxMacchina, CodArticolo, DtStart, DtEnd, MaxRec) ?? new List(), tagList: [Utils.redisDossByMac] ); } @@ -587,7 +578,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("DossiersInsertAsync"); string source = "DB"; // aggiorno record sul DB - bool answ = await dbController.DossiersInsertAsync(currDoss); + bool answ = await _dossierRepository.DossiersInsertAsync(currDoss); answ = await FlushFusionCacheAsync(Utils.redisDossByMac); activity?.SetTag("data.source", source); activity?.Stop(); @@ -609,7 +600,7 @@ namespace MP.SPEC.Data bool answ = false; Log.Info($"Richiesta snapshot per idxMaccSel {IdxMacchina} | periodo {dtMin} --> {dtMax}"); // chiamo stored x salvare parametri - await dbController.DossiersTakeParamsSnapshotLastAsync(IdxMacchina, dtMin, dtMax); + await _dossierRepository.DossiersTakeParamsSnapshotLastAsync(IdxMacchina, dtMin, dtMax); // elimino cache... answ = await FlushFusionCacheAsync(Utils.redisDossByMac); activity?.SetTag("data.source", source); @@ -628,7 +619,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("DossiersUpdateValoreAsync"); string source = "DB"; // aggiorno record sul DB - bool answ = await dbController.DossiersUpdateValoreAsync(currDoss); + bool answ = await _dossierRepository.DossiersUpdateValoreAsync(currDoss); answ = await FlushFusionCacheAsync(Utils.redisDossByMac); activity?.SetTag("data.source", source); activity?.Stop(); @@ -677,7 +668,7 @@ namespace MP.SPEC.Data operationName: "ElencoLinkAsync", cacheKey: Utils.redisLinkMenu, expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => await dbController.ElencoLinkAsync() ?? new List(), + fetchFunc: async () => await _systemRepository.ElencoLinkAsync() ?? new List(), tagList: [Utils.redisLinkMenu] ); } @@ -745,7 +736,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("EvListInsertAsync"); string source = "DB"; - var result = await dbController.EvListInsertAsync(newRec); + var result = await _systemRepository.EvListInsertAsync(newRec); activity?.SetTag("data.source", source); activity?.Stop(); LogTrace($"EvListInsertAsync | Read from {source}: {activity?.Duration.TotalMilliseconds}ms"); @@ -785,7 +776,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("FluxLogDataReduxAsync"); string source = "DB"; - List procStats = await dbController.FluxLogDataReduxAsync(idxMaccSel, fluxList, currPeriodo, valMode, intReq, maxItem); + List procStats = await _fluxLogRepository.FluxLogDataReduxAsync(idxMaccSel, fluxList, currPeriodo, valMode, intReq, maxItem); // effettuo merge statistiche... await ProcDedupStatMergeAsync(procStats); // svuoto cache @@ -840,7 +831,7 @@ namespace MP.SPEC.Data operationName: "FluxLogGetLastFiltAsync", cacheKey: currKey, expiration: TimeSpan.FromSeconds(redisCacheSec), - fetchFunc: async () => await dbController.FluxLogGetLastFiltAsync(DtMax, DtMin, IdxMacchina, CodFlux, MaxRec) ?? new List(), + fetchFunc: async () => await _fluxLogRepository.FluxLogGetLastFiltAsync(DtMax, DtMin, IdxMacchina, CodFlux, MaxRec) ?? new List(), tagList: [Utils.redisFluxLogFilt] ); } @@ -856,7 +847,7 @@ namespace MP.SPEC.Data operationName: "FluxLogParetoAsync", cacheKey: redKey, expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => await dbController.FluxLogParetoAsync(idxMacchina, dtFrom, dtTo) ?? new List(), + fetchFunc: async () => await _fluxLogRepository.FluxLogParetoAsync(idxMacchina, dtFrom, dtTo) ?? new List(), tagList: [Utils.redisParetoFLKey] ); } @@ -875,7 +866,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("ForceDbMaintAsync"); string source = "DB"; - await dbController.ForceDbMaintAsync(doExec, doUpdStat, doSave, minPgCnt, minAvgFrag, maxAvgFragReb); + await _systemRepository.ForceDbMaintAsync(doExec, doUpdStat, doSave, minPgCnt, minAvgFrag, maxAvgFragReb); // svuoto cache await FlushFusionCacheFluxLog(); activity?.SetTag("data.source", source); @@ -921,7 +912,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("Grp2MaccDeleteAsync"); bool result = false; - result = await dbController.Grp2MaccDeleteAsync(rec2del); + result = await _productionRepository.Grp2MaccDeleteAsync(rec2del); // elimino cache redis... await FlushFusionCacheMacGrp(); activity?.SetTag("data.source", "DB"); @@ -939,7 +930,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("Grp2MaccInsertAsync"); bool result = false; - result = await dbController.Grp2MaccInsertAsync(upsRec); + result = await _productionRepository.Grp2MaccInsertAsync(upsRec); // elimino cache redis... await FlushFusionCacheMacGrp(); activity?.SetTag("data.source", "DB"); @@ -957,7 +948,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("Grp2OperDeleteAsync"); bool result = false; - result = await dbController.Grp2OperDeleteAsync(rec2del); + result = await _productionRepository.Grp2OperDeleteAsync(rec2del); // elimino cache redis... await FlushFusionCacheOprGrp(); activity?.SetTag("data.source", "DB"); @@ -975,7 +966,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("Grp2OperInsertAsync"); bool result = false; - result = await dbController.Grp2OperInsertAsync(upsRec); + result = await _productionRepository.Grp2OperInsertAsync(upsRec); // elimino cache redis... await FlushFusionCacheOprGrp(); activity?.SetTag("data.source", "DB"); @@ -1005,7 +996,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("IstKitDeleteAsync"); string source = "DB"; // salvo - bool fatto = await dbController.IstKitDeleteAsync(currRecord); + bool fatto = await _productionRepository.IstKitDeleteAsync(currRecord); // svuoto cache await FlushFusionCacheKit(); activity?.SetTag("data.source", source); @@ -1027,7 +1018,7 @@ namespace MP.SPEC.Data operationName: "IstKitFiltAsync", cacheKey: currKey, expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => await dbController.IstKitFiltAsync(keyKit, keyExtOrd) ?? new List(), + fetchFunc: async () => await _productionRepository.IstKitFiltAsync(keyKit, keyExtOrd) ?? new List(), tagList: [Utils.redisKitInst] ); } @@ -1042,7 +1033,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("IstKitInsertByWKSAsync"); string source = "DB"; // salvo - bool fatto = await dbController.IstKitInsertByWKSAsync(CodArtParent, KeyFilt); + bool fatto = await _productionRepository.IstKitInsertByWKSAsync(CodArtParent, KeyFilt); // svuoto cache await FlushFusionCacheKit(); activity?.SetTag("data.source", source); @@ -1060,7 +1051,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("IstKitUpsertAsync"); string source = "DB"; // salvo - bool fatto = await dbController.IstKitUpsertAsync(currRecord); + bool fatto = await _productionRepository.IstKitUpsertAsync(currRecord); // svuoto cache await FlushFusionCacheKit(); activity?.SetTag("data.source", source); @@ -1081,7 +1072,7 @@ namespace MP.SPEC.Data operationName: "ListGiacenzeAsync", cacheKey: currKey, expiration: GetRandTOut(redisShortTimeCache), - fetchFunc: async () => await dbController.ListGiacenzeAsync(IdxOdl) ?? new List(), + fetchFunc: async () => await _productionRepository.ListGiacenzeAsync(IdxOdl) ?? new List(), tagList: [Utils.redisGiacenzaList] ); } @@ -1100,7 +1091,7 @@ namespace MP.SPEC.Data operationName: "ListPODL_ByCodArtAsync", cacheKey: currKey, expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => await dbController.ListPODL_ByCodArtAsync(CodArticolo, OnlyAvail) ?? new(), + fetchFunc: async () => await _productionRepository.ListPODL_ByCodArtAsync(CodArticolo, OnlyAvail) ?? new(), tagList: [Utils.redisPOdlByCodArt] ); } @@ -1119,9 +1110,9 @@ namespace MP.SPEC.Data operationName: "MacchineGetFiltAsync", cacheKey: redisKey, expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => - await dbController.MacchineGetFiltAsync(codGruppo) - ?? new List(), + fetchFunc: async () => + await _productionRepository.MacchineGetFiltAsync(codGruppo) + ?? new List(), tagList: [Utils.redisMacList] ); } @@ -1183,7 +1174,7 @@ namespace MP.SPEC.Data operationName: "MacchineWithFluxAsync", cacheKey: currKey, expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => await dbController.MacchineWithFluxAsync(dtStart, dtEnd) ?? new List(), + fetchFunc: async () => await _productionRepository.MacchineWithFluxAsync(dtStart, dtEnd) ?? new List(), tagList: [Utils.redisMacByFlux] ); } @@ -1198,7 +1189,7 @@ namespace MP.SPEC.Data expiration: GetRandTOut(redisShortTimeCache), fetchFunc: async () => { - var rawData = await dbController.OdlGetCurrentAsync(); + var rawData = await _productionRepository.OdlGetCurrentAsync(); var dbResult = rawData .Select(x => x.IdxMacchina) .Distinct() @@ -1254,7 +1245,7 @@ namespace MP.SPEC.Data operationName: "MseGetAllAsync", cacheKey: Constants.redisMseKey, expiration: TimeSpan.FromSeconds(1), - fetchFunc: async () => await dbController.MseGetAllAsync(2000) ?? new(), + fetchFunc: async () => await _productionRepository.MseGetAllAsync(2000) ?? new(), tagList: [Constants.redisMseKey] ); } @@ -1284,7 +1275,7 @@ namespace MP.SPEC.Data operationName: "OdlByBatchAsync", cacheKey: Utils.redisOdlByBatch, expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => await dbController.OdlByBatchAsync(BatchSel), + fetchFunc: async () => await _productionRepository.OdlByBatchAsync(BatchSel), tagList: [Utils.redisOdlByBatch] ); } @@ -1301,7 +1292,7 @@ namespace MP.SPEC.Data operationName: "OdlByKeyAsync", cacheKey: currKey, expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => await dbController.OdlByKeyAsync(IdxOdl), + fetchFunc: async () => await _productionRepository.OdlByKeyAsync(IdxOdl), tagList: [Utils.redisOdlByKey] ); } @@ -1333,7 +1324,7 @@ namespace MP.SPEC.Data int.TryParse(vModo, out modoConfProd); } // chiamo metodo conferma! - fatto = await dbController.ODLCloseAsync(idxOdl, idxMacchina, matrOpr, confPezzi, confRett, modoConfProd); + fatto = await _productionRepository.ODLCloseAsync(idxOdl, idxMacchina, matrOpr, confPezzi, confRett, modoConfProd); await FlushFusionCacheAsync(Utils.redisOdlByKey); @@ -1361,7 +1352,7 @@ namespace MP.SPEC.Data operationName: "OdlListGetFiltAsync", cacheKey: currKey, expiration: GetRandTOut(redisShortTimeCache), - fetchFunc: async () => await dbController.ListODLFiltAsync(inCorso, codArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate) ?? new(), + fetchFunc: async () => await _productionRepository.ListODLFiltAsync(inCorso, codArt, keyRichPart, Reparto, IdxMacchina, startDate, endDate) ?? new(), tagList: [Utils.redisOdlList] ); } @@ -1378,7 +1369,7 @@ namespace MP.SPEC.Data operationName: "OdlStatsAsync", cacheKey: currKey, expiration: GetRandTOut(redisShortTimeCache), - fetchFunc: async () => await dbController.OdlGetStatAsync(IdxOdl) ?? new(), + fetchFunc: async () => await _productionRepository.OdlGetStatAsync(IdxOdl) ?? new(), tagList: [Utils.redisOdlStats] ); } @@ -1397,7 +1388,7 @@ namespace MP.SPEC.Data operationName: "OperatoriGetFiltAsync", cacheKey: currKey, expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => await dbController.OperatoriGetFiltAsync(codGruppo) ?? new List(), + fetchFunc: async () => await _productionRepository.OperatoriGetFiltAsync(codGruppo) ?? new List(), tagList: [Utils.redisOprList] ); } @@ -1414,7 +1405,7 @@ namespace MP.SPEC.Data operationName: "ParametriGetFiltAsync", cacheKey: currKey, expiration: GetRandTOut(redisShortTimeCache), - fetchFunc: async () => await dbController.ParametriGetFiltAsync(IdxMacchina) ?? new(), + fetchFunc: async () => await _productionRepository.ParametriGetFiltAsync(IdxMacchina) ?? new(), tagList: [Utils.redisFluxByMac] ); } @@ -1455,7 +1446,7 @@ namespace MP.SPEC.Data if (missingIds.Any()) { // Riceviamo direttamente un Dictionary ottimizzato da EF Core - Dictionary dbResults = await dbController.PODL_getDictOdlPodlAsync(missingIds); + Dictionary dbResults = await _productionRepository.PODL_getDictOdlPodlAsync(missingIds); // STEP 3: Scriviamo i risultati in cache e li uniamo al dizionario finale foreach (var kvp in dbResults) @@ -1497,7 +1488,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("POdlDeleteRecord"); string source = "DB+REDIS"; - var dbResult = await dbController.PODLDeleteRecordAsync(currRec); + var dbResult = await _productionRepository.PODLDeleteRecordAsync(currRec); // elimino cache redis... await FlushFusionCachePOdl(); activity?.SetTag("data.source", source); @@ -1515,7 +1506,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("POdlDoSetup"); string source = "DB+REDIS"; - var dbResult = await dbController.PODL_startSetup(currRec, 0, 1, 1, "", DateTime.Now); + var dbResult = await _productionRepository.PODL_startSetup(currRec, 0, 1, 1, "", DateTime.Now); // elimino cache redis... await FlushFusionCachePOdl(); activity?.SetTag("data.source", source); @@ -1536,7 +1527,7 @@ namespace MP.SPEC.Data operationName: "POdlGetByKey", cacheKey: currKey, expiration: TimeSpan.FromMinutes(redisLongTimeCache), - fetchFunc: async () => await dbController.PODL_getByKeyAsync(idxPODL) ?? new(), + fetchFunc: async () => await _productionRepository.PODL_getByKeyAsync(idxPODL) ?? new(), tagList: [Utils.redisPOdlByPOdl] ); } @@ -1553,7 +1544,7 @@ namespace MP.SPEC.Data operationName: "POdlGetByOdlAsync", cacheKey: currKey, expiration: TimeSpan.FromMinutes(redisLongTimeCache), - fetchFunc: async () => await dbController.PODL_getByOdlAsync(idxODL) ?? new(), + fetchFunc: async () => await _productionRepository.PODL_getByOdlAsync(idxODL) ?? new(), tagList: [Utils.redisPOdlByOdl] ); } @@ -1567,7 +1558,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("PodlIstKitDeleteAsync"); bool fatto = false; // salvo - fatto = await dbController.PodlIstKitDeleteAsync(IdxPODL); + fatto = await _productionRepository.PodlIstKitDeleteAsync(IdxPODL); // svuoto cache await FlushFusionCachePOdl(); activity?.SetTag("data.source", "DB"); @@ -1586,7 +1577,7 @@ namespace MP.SPEC.Data operationName: "POdlListByKitParentAsync", cacheKey: currKey, expiration: GetRandTOut(redisShortTimeCache), - fetchFunc: async () => await dbController.ListPODL_ByKitParentAsync(IdxPodlParent) ?? new(), + fetchFunc: async () => await _productionRepository.ListPODL_ByKitParentAsync(IdxPodlParent) ?? new(), tagList: [Utils.redisPOdlList] ); } @@ -1608,7 +1599,7 @@ namespace MP.SPEC.Data operationName: "POdlListGetFiltAsync", cacheKey: currKey, expiration: GetRandTOut(redisShortTimeCache), - fetchFunc: async () => await dbController.ListPODLFiltAsync(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate) ?? new List(), + fetchFunc: async () => await _productionRepository.ListPODLFiltAsync(lanciato, keyRichPart, idxMacchina, codGruppo, startDate, endDate) ?? new List(), tagList: [Utils.redisPOdlList] ); } @@ -1632,7 +1623,7 @@ namespace MP.SPEC.Data cacheKey: redisKey, expiration: GetRandTOut(redisShortTimeCache * 5), fetchFunc: async () => - await dbController.ListPODL_KitFiltAsync( + await _productionRepository.ListPODL_KitFiltAsync( lanciato, keyRichPart, idxMacchina, @@ -1655,7 +1646,7 @@ namespace MP.SPEC.Data using var activity = ActivitySource.StartActivity("POdlUpdateRecipe"); string source = "DB"; bool answ = false; - answ = await dbController.PODL_updateRecipe(idxPODL, recipeName); + answ = await _productionRepository.PODL_updateRecipe(idxPODL, recipeName); // reset redis... await FlushFusionCachePOdl(); activity?.SetTag("data.source", source); @@ -1673,7 +1664,7 @@ namespace MP.SPEC.Data { using var activity = ActivitySource.StartActivity("POdlUpdateRecord"); string source = "DB"; - var dbResult = await dbController.PODLUpdateRecordAsync(currRec); + var dbResult = await _productionRepository.PODLUpdateRecordAsync(currRec); // elimino cache redis... await FlushFusionCachePOdl(); activity?.SetTag("data.source", source); @@ -1778,7 +1769,7 @@ namespace MP.SPEC.Data operationName: "StatoMacchinaAsync", cacheKey: currKey, expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => await dbController.StatoMacchinaAsync(idxMacchina) ?? new(), + fetchFunc: async () => await _productionRepository.StatoMacchinaAsync(idxMacchina) ?? new(), tagList: [Utils.redisStatoMacch] ); } @@ -1793,7 +1784,7 @@ namespace MP.SPEC.Data string source = "DB"; bool fatto = false; // salvo - fatto = await dbController.TemplateKitDeleteAsync(currRecord); + fatto = await _productionRepository.TemplateKitDeleteAsync(currRecord); await FlushFusionCacheAsync(Utils.redisKitTempl); activity?.SetTag("data.source", source); activity?.Stop(); @@ -1815,7 +1806,7 @@ namespace MP.SPEC.Data operationName: "TemplateKitFiltAsync", cacheKey: currKey, expiration: GetRandTOut(redisLongTimeCache), - fetchFunc: async () => await dbController.TemplateKitFiltAsync(codParent, codChild) ?? new List(), + fetchFunc: async () => await _productionRepository.TemplateKitFiltAsync(codParent, codChild) ?? new List(), tagList: [Utils.redisKitTempl] ); } @@ -1831,7 +1822,7 @@ namespace MP.SPEC.Data string source = "DB"; bool fatto = false; // salvo - fatto = await dbController.TemplateKitUpsertAsync(currRecord, codAzienda); + fatto = await _productionRepository.TemplateKitUpsertAsync(currRecord, codAzienda); await FlushFusionCacheAsync(Utils.redisKitTempl); activity?.SetTag("data.source", source); activity?.Stop(); @@ -1854,7 +1845,7 @@ namespace MP.SPEC.Data { // Se ForceDb è true, saltiamo il GetOrFetchAsync per forzare il fetch dal DB // e aggiornare la cache. - var result = await dbController.TksScoreAsync(KeyFilt, MaxResult) ?? new List(); + var result = await _productionRepository.TksScoreAsync(KeyFilt, MaxResult) ?? new List(); await _cache.SetAsync(currKey, result, TimeSpan.FromMinutes(redisLongTimeCache), tags: [Utils.redisKitScore]); return result; } @@ -1863,7 +1854,7 @@ namespace MP.SPEC.Data operationName: "TksScoreAsync", cacheKey: currKey, expiration: TimeSpan.FromMinutes(redisLongTimeCache), - fetchFunc: async () => await dbController.TksScoreAsync(KeyFilt, MaxResult) ?? new List(), + fetchFunc: async () => await _productionRepository.TksScoreAsync(KeyFilt, MaxResult) ?? new List(), tagList: [Utils.redisKitScore] ); } @@ -1887,7 +1878,7 @@ namespace MP.SPEC.Data // Se non c'è, passa a L2 (Redis) o invoca la factory per caricarlo. var dizionarioLingua = _cache.GetOrSet>( cacheKey, - _ => dbController.VocabolarioGetLang(linguaKey), + _ => _anagRepository.VocabolarioGetLang(linguaKey), options => options .SetDuration(TimeSpan.FromHours(8)) // Durata logica della cache .SetFailSafe(true, TimeSpan.FromHours(1)) // Se Redis/DB è giù, usa i vecchi dati L1 @@ -1913,7 +1904,7 @@ namespace MP.SPEC.Data string source = "DB"; bool fatto = false; // salvo - fatto = await dbController.WipKitDeleteAsync(currRecord); + fatto = await _productionRepository.WipKitDeleteAsync(currRecord); // svuoto cache await FlushFusionCacheAsync(Utils.redisKitWip); activity?.SetTag("data.source", source); @@ -1932,7 +1923,7 @@ namespace MP.SPEC.Data string source = "DB"; bool fatto = false; // salvo - fatto = await dbController.WipKitDeleteOlderAsync(DateLimit); + fatto = await _productionRepository.WipKitDeleteOlderAsync(DateLimit); // svuoto cache KitWip await FlushFusionCacheAsync(Utils.redisKitWip); activity?.SetTag("data.source", source); @@ -1953,7 +1944,7 @@ namespace MP.SPEC.Data operationName: "WipKitFiltAsync", cacheKey: currKey, expiration: TimeSpan.FromMinutes(redisLongTimeCache), - fetchFunc: async () => await dbController.WipKitFiltAsync(KeyFilt) ?? new List(), + fetchFunc: async () => await _productionRepository.WipKitFiltAsync(KeyFilt) ?? new List(), tagList: [Utils.redisKitWip] ); } @@ -1968,7 +1959,7 @@ namespace MP.SPEC.Data string source = "DB"; bool fatto = false; // salvo - fatto = await dbController.WipKitUpsertAsync(currRecord); + fatto = await _productionRepository.WipKitUpsertAsync(currRecord); // svuoto cache KitWip await FlushFusionCacheAsync(Utils.redisKitWip); activity?.SetTag("data.source", source); From 328f7adc06cfd9b7df75b972d1ea60de4a0b7982 Mon Sep 17 00:00:00 2001 From: "Samuele E. Locatelli (W11-AI)" Date: Tue, 2 Jun 2026 23:59:01 +0200 Subject: [PATCH 094/102] Completamento migrazione repository MpSpecController: aggiunti MpMon, MpVoc, MpLand; migrati TranslateSrv, StatusData, LandDataService, TranslateSrv, MonDataFeeder, TabDataFeeder; 0 errori build --- MP.Data/DataServiceCollectionExtensions.cs | 10 +- .../Repository/MpLand/IMpLandRepository.cs | 23 +++ MP.Data/Repository/MpLand/MpLandRepository.cs | 162 ++++++++++++++++++ MP.Data/Repository/MpMon/IMpMonRepository.cs | 20 +++ MP.Data/Repository/MpMon/MpMonRepository.cs | 100 +++++++++++ MP.Data/Repository/MpVoc/IMpVocRepository.cs | 15 ++ MP.Data/Repository/MpVoc/MpVocRepository.cs | 63 +++++++ MP.Data/Services/LandDataService.cs | 20 +-- MP.Data/Services/MonDataFeeder.cs | 2 +- MP.Data/Services/StatusData.cs | 24 +-- MP.Data/Services/TabDataFeeder.cs | 2 +- MP.Data/Services/TranslateSrv.cs | 26 ++- MP.SPEC/Data/MpDataService.cs | 2 - MP.SPEC/refactor_repository.md | 119 ++++++++----- 14 files changed, 496 insertions(+), 92 deletions(-) create mode 100644 MP.Data/Repository/MpLand/IMpLandRepository.cs create mode 100644 MP.Data/Repository/MpLand/MpLandRepository.cs create mode 100644 MP.Data/Repository/MpMon/IMpMonRepository.cs create mode 100644 MP.Data/Repository/MpMon/MpMonRepository.cs create mode 100644 MP.Data/Repository/MpVoc/IMpVocRepository.cs create mode 100644 MP.Data/Repository/MpVoc/MpVocRepository.cs diff --git a/MP.Data/DataServiceCollectionExtensions.cs b/MP.Data/DataServiceCollectionExtensions.cs index 44116d5c..b2f236c8 100644 --- a/MP.Data/DataServiceCollectionExtensions.cs +++ b/MP.Data/DataServiceCollectionExtensions.cs @@ -6,6 +6,9 @@ using MP.Data.Repository.Anag; using MP.Data.Repository.Dossier; using MP.Data.Repository.FluxLog; using MP.Data.Repository.IOC; +using MP.Data.Repository.MpLand; +using MP.Data.Repository.MpMon; +using MP.Data.Repository.MpVoc; using MP.Data.Repository.Mtc; using MP.Data.Repository.Production; using MP.Data.Repository.System; @@ -61,6 +64,9 @@ namespace MP.Data services.TryAddScoped(); services.TryAddScoped(); services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); // ---------- End Repository ---------- @@ -70,6 +76,8 @@ namespace MP.Data // Singleton + //services.TryAddSingleton(); + // Scoped // ---------- End Servizi ---------- @@ -79,7 +87,7 @@ namespace MP.Data // Singleton services.TryAddSingleton(); services.TryAddScoped(); - services.TryAddSingleton(); + services.TryAddScoped(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); diff --git a/MP.Data/Repository/MpLand/IMpLandRepository.cs b/MP.Data/Repository/MpLand/IMpLandRepository.cs new file mode 100644 index 00000000..a807f751 --- /dev/null +++ b/MP.Data/Repository/MpLand/IMpLandRepository.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.Configuration; +using MP.Data.DbModels; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MP.Data.Repository.MpLand +{ + public interface IMpLandRepository + { + Task> AllDbInfoAsync(); + + Task> ConfigGetAllAsync(); + + Task> RemRebootLogGetAllAsync(); + + Task> RemRebootLogGetLastAsync(); + + Task> RemRebootLogGetLastNoMaccAsync(); + + Task> MacchineGetAllAsync(); + } +} diff --git a/MP.Data/Repository/MpLand/MpLandRepository.cs b/MP.Data/Repository/MpLand/MpLandRepository.cs new file mode 100644 index 00000000..c40c9299 --- /dev/null +++ b/MP.Data/Repository/MpLand/MpLandRepository.cs @@ -0,0 +1,162 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using MP.Data.DbModels; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MP.Data.Repository.MpLand +{ + public class MpLandRepository : IMpLandRepository + { + #region Private Fields + + private readonly IConfiguration _configuration; + private readonly IDbContextFactory _ctxFactory; + + #endregion + + #region Public Constructors + + public MpLandRepository(IConfiguration configuration, IDbContextFactory ctxFactory) + { + _configuration = configuration; + _ctxFactory = ctxFactory; + } + + #endregion + + #region Public Methods + + /// + public async Task> AllDbInfoAsync() + { + List dbResult = new List(); + string stp_DbInfo = @" + ;WITH TableRowCounts AS ( + SELECT + t.name AS TableName, + SUM(p.rows) AS RowNum + FROM sys.tables t + JOIN sys.partitions p ON t.object_id = p.object_id + WHERE p.index_id IN (0, 1) + GROUP BY t.name + ), + LargestTable AS ( + SELECT TOP 1 RowNum, TableName + FROM TableRowCounts + ORDER BY RowNum DESC + ) + SELECT + DB_name() as DbName, + CAST(SUM(size) * 8.0 / 1024 AS DECIMAL(18,2)) AS DbSizeMb, + (SELECT COUNT(*) FROM sys.tables) AS NumTables, + (SELECT TableName FROM LargestTable) AS BigTable, + (SELECT RowNum FROM LargestTable) AS BigTableRows + FROM sys.master_files + WHERE database_id = DB_ID(); + "; + try + { + if (!string.IsNullOrEmpty(_configuration.GetConnectionString("MP.All"))) + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + var singleRes = await dbCtx + .DbSetDbSize + .FromSqlRaw(stp_DbInfo) + .AsNoTracking() + .FirstOrDefaultAsync(); + if (singleRes != null) + { + dbResult.Add(singleRes); + } + } + if (!string.IsNullOrEmpty(_configuration.GetConnectionString("MP.Flux"))) + { + await using var dbCtx = new MoonPro_FluxContext(_configuration); + var singleRes = await dbCtx + .DbSetDbSize + .FromSqlRaw(stp_DbInfo) + .AsNoTracking() + .FirstOrDefaultAsync(); + if (singleRes != null) + { + dbResult.Add(singleRes); + } + } + if (!string.IsNullOrEmpty(_configuration.GetConnectionString("MP.Stats"))) + { + await using var dbCtx = new MoonPro_STATSContext(_configuration); + var singleRes = await dbCtx + .DbSetDbSize + .FromSqlRaw(stp_DbInfo) + .AsNoTracking() + .FirstOrDefaultAsync(); + if (singleRes != null) + { + dbResult.Add(singleRes); + } + } + } + catch + { + } + return dbResult; + } + + /// + public async Task> ConfigGetAllAsync() + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + return await dbCtx + .DbSetConfig + .AsNoTracking() + .OrderBy(x => x.Chiave) + .ToListAsync() ?? new(); + } + + /// + public async Task> MacchineGetAllAsync() + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + return await dbCtx + .DbSetMacchine + .ToListAsync() ?? new(); + } + + /// + public async Task> RemRebootLogGetAllAsync() + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + return await dbCtx + .DbSetRemRebLog + .AsNoTracking() + .OrderByDescending(x => x.IdxReboot) + .ToListAsync() ?? new(); + } + + /// + public async Task> RemRebootLogGetLastAsync() + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + return await dbCtx + .DbSetRemRebLog + .FromSqlRaw("EXEC stp_RRL_getLast") + .AsNoTracking() + .ToListAsync() ?? new(); + } + + /// + public async Task> RemRebootLogGetLastNoMaccAsync() + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + return await dbCtx + .DbSetRemRebLog + .FromSqlRaw("EXEC stp_RRL_GetLastNoMachine") + .AsNoTracking() + .ToListAsync() ?? new(); + } + + #endregion + } +} diff --git a/MP.Data/Repository/MpMon/IMpMonRepository.cs b/MP.Data/Repository/MpMon/IMpMonRepository.cs new file mode 100644 index 00000000..7ddc32e9 --- /dev/null +++ b/MP.Data/Repository/MpMon/IMpMonRepository.cs @@ -0,0 +1,20 @@ +using Microsoft.Data.SqlClient; +using MP.Data.DbModels; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace MP.Data.Repository.MpMon +{ + public interface IMpMonRepository + { + Task> ConfigGetAllAsync(); + + Task> MacchineGetAllAsync(); + + Task> MacchineGetFiltAsync(string codGruppo); + + Task> MseGetAllAsync(int maxAge = 2000); + } +} diff --git a/MP.Data/Repository/MpMon/MpMonRepository.cs b/MP.Data/Repository/MpMon/MpMonRepository.cs new file mode 100644 index 00000000..235977b3 --- /dev/null +++ b/MP.Data/Repository/MpMon/MpMonRepository.cs @@ -0,0 +1,100 @@ +using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; +using MP.Data.DbModels; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace MP.Data.Repository.MpMon +{ + public class MpMonRepository : IMpMonRepository + { + #region Private Fields + + private readonly IDbContextFactory _ctxFactory; + + #endregion + + #region Public Constructors + + public MpMonRepository(IDbContextFactory ctxFactory) + { + _ctxFactory = ctxFactory; + } + + #endregion + + #region Public Methods + + /// + public async Task> ConfigGetAllAsync() + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + return await dbCtx + .DbSetConfig + .AsNoTracking() + .OrderBy(x => x.Chiave) + .ToListAsync() ?? new(); + } + + /// + public async Task> MacchineGetAllAsync() + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + return await dbCtx + .DbSetMacchine + .AsNoTracking() + .OrderBy(x => x.IdxMacchina) + .ToListAsync() ?? new(); + } + + /// + public async Task> MacchineGetFiltAsync(string codGruppo) + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + List dbResult; + if (codGruppo == "*") + { + dbResult = await dbCtx + .DbSetMacchine + .AsNoTracking() + .OrderBy(x => x.IdxMacchina) + .ToListAsync(); + } + else + { + dbResult = await dbCtx + .DbSetGrp2Macc + .Where(g => g.CodGruppo == codGruppo) + .Join(dbCtx.DbSetMacchine, + g => g.IdxMacchina, + m => m.IdxMacchina, + (g, m) => m + ) + .AsNoTracking() + .OrderBy(x => x.IdxMacchina) + .ToListAsync(); + } + dbResult = dbResult + .Where(x => !string.IsNullOrEmpty(x.locazione)) + .OrderBy(x => x.locazione).ToList(); + return dbResult; + } + + /// + public async Task> MseGetAllAsync(int maxAge = 2000) + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + var maxAgeSec = new SqlParameter("@maxAgeSec", maxAge); + var dbResult = await dbCtx + .DbSetMSE + .FromSqlRaw("EXEC stp_MSE_getData @maxAgeSec", maxAgeSec) + .AsNoTracking() + .ToListAsync(); + return dbResult; + } + + #endregion + } +} diff --git a/MP.Data/Repository/MpVoc/IMpVocRepository.cs b/MP.Data/Repository/MpVoc/IMpVocRepository.cs new file mode 100644 index 00000000..845d07ef --- /dev/null +++ b/MP.Data/Repository/MpVoc/IMpVocRepository.cs @@ -0,0 +1,15 @@ +using MP.Data.DbModels; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace MP.Data.Repository.MpVoc +{ + public interface IMpVocRepository + { + Task> ConfigGetAllAsync(); + + Task> LingueGetAllAsync(); + + Task> VocabolarioGetAllAsync(); + } +} diff --git a/MP.Data/Repository/MpVoc/MpVocRepository.cs b/MP.Data/Repository/MpVoc/MpVocRepository.cs new file mode 100644 index 00000000..9afe2146 --- /dev/null +++ b/MP.Data/Repository/MpVoc/MpVocRepository.cs @@ -0,0 +1,63 @@ +using Microsoft.EntityFrameworkCore; +using MP.Data.DbModels; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace MP.Data.Repository.MpVoc +{ + public class MpVocRepository : IMpVocRepository + { + #region Private Fields + + private readonly IDbContextFactory _ctxFactory; + + #endregion + + #region Public Constructors + + public MpVocRepository(IDbContextFactory ctxFactory) + { + _ctxFactory = ctxFactory; + } + + #endregion + + #region Public Methods + + /// + public async Task> ConfigGetAllAsync() + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + return await dbCtx + .DbSetConfig + .AsNoTracking() + .OrderBy(x => x.Chiave) + .ToListAsync() ?? new(); + } + + /// + public async Task> LingueGetAllAsync() + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + return await dbCtx + .DbSetLilngue + .AsNoTracking() + .OrderBy(x => x.Lingua) + .ToListAsync() ?? new(); + } + + /// + public async Task> VocabolarioGetAllAsync() + { + await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); + return await dbCtx + .DbSetVocabolario + .AsNoTracking() + .OrderBy(x => x.Lemma) + .ToListAsync() ?? new(); + } + + #endregion + } +} diff --git a/MP.Data/Services/LandDataService.cs b/MP.Data/Services/LandDataService.cs index 8607bf6a..453c45ff 100644 --- a/MP.Data/Services/LandDataService.cs +++ b/MP.Data/Services/LandDataService.cs @@ -21,8 +21,9 @@ namespace MP.Data.Services { #region Public Constructors - public LandDataService(IConfiguration configuration, IConnectionMultiplexer redConn) : base(configuration, redConn) + public LandDataService(IConfiguration configuration, IConnectionMultiplexer redConn, Repository.MpLand.IMpLandRepository mpLandRepository) : base(configuration, redConn) { + _mpLandRepository = mpLandRepository; // conf DB string connStr = _configuration.GetConnectionString("MP.Land"); if (string.IsNullOrEmpty(connStr)) @@ -31,9 +32,8 @@ namespace MP.Data.Services } else { - dbController = new Controllers.MpLandController(configuration); StringBuilder sb = new StringBuilder(); - sb.AppendLine($"LandService | MpLandController OK"); + sb.AppendLine($"LandService | MpLandRepository OK"); Log.Info(sb.ToString()); } } @@ -69,7 +69,7 @@ namespace MP.Data.Services } else { - result = dbController.AllDbInfo(); + result = _mpLandRepository.AllDbInfoAsync().GetAwaiter().GetResult(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); _redisDb.StringSet(currKey, rawData, UltraFastCache); @@ -105,10 +105,10 @@ namespace MP.Data.Services else { // recupero RRL missing - var listRRl = dbController.RemRebootLogGetLast(); - var listRRlAdd = dbController.RemRebootLogGetLastNoMacc(); + var listRRl = _mpLandRepository.RemRebootLogGetLastAsync().GetAwaiter().GetResult(); + var listRRlAdd = _mpLandRepository.RemRebootLogGetLastNoMaccAsync().GetAwaiter().GetResult(); // recupero lista macchine - var ListMacch = dbController.MacchineGetAll(); + var ListMacch = _mpLandRepository.MacchineGetAllAsync().GetAwaiter().GetResult(); // ...converto in DTO dbResult = ListMacch .Select(x => new IobDTO(x, IobInfo(x.IdxMacchina), MachIobConf(x.IdxMacchina))) @@ -158,7 +158,7 @@ namespace MP.Data.Services } else { - result = dbController.RemRebootLogGetAll(); + result = _mpLandRepository.RemRebootLogGetAllAsync().GetAwaiter().GetResult(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); _redisDb.StringSet(currKey, rawData, UltraFastCache); @@ -194,7 +194,7 @@ namespace MP.Data.Services } else { - result = dbController.RemRebootLogGetLast(); + result = _mpLandRepository.RemRebootLogGetLastAsync().GetAwaiter().GetResult(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); _redisDb.StringSet(currKey, rawData, UltraFastCache); @@ -219,7 +219,6 @@ namespace MP.Data.Services if (disposing) { // Free managed resources here - dbController.Dispose(); } // Free unmanaged resources here @@ -234,6 +233,7 @@ namespace MP.Data.Services #region Private Fields + private readonly Repository.MpLand.IMpLandRepository _mpLandRepository; private static Logger Log = LogManager.GetCurrentClassLogger(); private bool _disposed = false; private string redisBaseKey = "MP:LAND:Cache"; diff --git a/MP.Data/Services/MonDataFeeder.cs b/MP.Data/Services/MonDataFeeder.cs index 24f9bae8..37d6f4b0 100644 --- a/MP.Data/Services/MonDataFeeder.cs +++ b/MP.Data/Services/MonDataFeeder.cs @@ -11,7 +11,7 @@ namespace MP.Data.Services { #region Public Constructors - public MonDataFeeder(IConfiguration configuration, IConnectionMultiplexer redConn) : base(configuration, redConn) + public MonDataFeeder(IConfiguration configuration, IConnectionMultiplexer redConn, Repository.MpMon.IMpMonRepository mpMonRepository) : base(configuration, redConn, mpMonRepository) { // setup canali pub/sub dataPipe = new MessagePipe(redisConn, Constants.MON_ACT_MSE_DATA_KEY); diff --git a/MP.Data/Services/StatusData.cs b/MP.Data/Services/StatusData.cs index a10ed1c5..a267c7cf 100644 --- a/MP.Data/Services/StatusData.cs +++ b/MP.Data/Services/StatusData.cs @@ -1,6 +1,5 @@ using Microsoft.Extensions.Configuration; using MP.Core.Conf; -using MP.Data.Controllers; using MP.Data.DbModels; using Newtonsoft.Json; using NLog; @@ -20,9 +19,10 @@ namespace MP.Data.Services { #region Public Constructors - public StatusData(IConfiguration configuration, IConnectionMultiplexer redConn) + public StatusData(IConfiguration configuration, IConnectionMultiplexer redConn, Repository.MpMon.IMpMonRepository mpMonRepository) { _configuration = configuration; + _mpMonRepository = mpMonRepository; // setup componenti REDIS this.redisConn = redConn; @@ -42,9 +42,8 @@ namespace MP.Data.Services } else { - dbController = new MpMonController(configuration); StringBuilder sb = new StringBuilder(); - sb.AppendLine($"StatusData | MpMonController OK"); + sb.AppendLine($"StatusData | MpMonRepository OK"); Log.Info(sb.ToString()); } @@ -70,8 +69,6 @@ namespace MP.Data.Services #region Public Properties - public static MpMonController dbController { get; set; } = null!; - /// /// Dizionario dei tag configurati per IOB /// @@ -102,7 +99,7 @@ namespace MP.Data.Services } else { - result = dbController.ConfigGetAll(); + result = await _mpMonRepository.ConfigGetAllAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, LongCache); @@ -186,7 +183,7 @@ namespace MP.Data.Services } else { - result = await Task.FromResult(dbController.MacchineGetAll()); + result = await _mpMonRepository.MacchineGetAllAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, LongCache); @@ -198,7 +195,6 @@ namespace MP.Data.Services sw.Stop(); Log.Debug($"MacchineGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; - //return Task.FromResult(dbController.MacchineGetAll()); } public async Task> MacchineGetByGruppo(string CodGruppo) @@ -217,8 +213,7 @@ namespace MP.Data.Services } else { - result = await Task.FromResult(dbController.MacchineGetFilt(CodGruppo)); - //result = dbController.MacchineGetFilt(CodGruppo); + result = await _mpMonRepository.MacchineGetFiltAsync(CodGruppo); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(currKey, rawData, LongCache); @@ -339,7 +334,7 @@ namespace MP.Data.Services } else { - result = await dbController.MseGetAllAsync(maxAge); + result = await _mpMonRepository.MseGetAllAsync(maxAge); // serializzp e salvo... rawData = JsonConvert.SerializeObject(result); await redisDb.StringSetAsync(Constants.redisMseKey, rawData, UltraFastCache); @@ -383,8 +378,6 @@ namespace MP.Data.Services MachineProdStatus.Clear(); // REDIS dispose redisDb = null; - // Clear database controller - dbController.Dispose(); } // Free unmanaged resources here @@ -397,6 +390,7 @@ namespace MP.Data.Services #region Private Fields private static IConfiguration _configuration = null!; + private readonly Repository.MpMon.IMpMonRepository _mpMonRepository; private static Logger Log = LogManager.GetCurrentClassLogger(); private bool _disposed = false; @@ -512,7 +506,7 @@ namespace MP.Data.Services if (fileConfData.IobSetup.ContainsKey("***")) { // recupero elenco macchine... - var elencoMacc = dbController.MacchineGetAll(); + var elencoMacc = _mpMonRepository.MacchineGetAllAsync().GetAwaiter().GetResult(); // x ogni macchina creo le righe standard da conf... var baseConf = fileConfData.IobSetup.Where(x => x.Key == "***").FirstOrDefault(); foreach (var item in elencoMacc) diff --git a/MP.Data/Services/TabDataFeeder.cs b/MP.Data/Services/TabDataFeeder.cs index 4282219c..a9cbf01b 100644 --- a/MP.Data/Services/TabDataFeeder.cs +++ b/MP.Data/Services/TabDataFeeder.cs @@ -11,7 +11,7 @@ namespace MP.Data.Services { #region Public Constructors - public TabDataFeeder(IConfiguration configuration, IConnectionMultiplexer redConn) : base(configuration, redConn) + public TabDataFeeder(IConfiguration configuration, IConnectionMultiplexer redConn, Repository.MpMon.IMpMonRepository mpMonRepository) : base(configuration, redConn, mpMonRepository) { // setup canali pub/sub dataPipe = new MessagePipe(redisConn, Constants.TAB_ACT_MSE_DATA_KEY, false); diff --git a/MP.Data/Services/TranslateSrv.cs b/MP.Data/Services/TranslateSrv.cs index d3d37010..b29fa641 100644 --- a/MP.Data/Services/TranslateSrv.cs +++ b/MP.Data/Services/TranslateSrv.cs @@ -23,8 +23,9 @@ namespace MP.Data.Services { #region Public Constructors - public TranslateSrv(IConfiguration configuration, IConnectionMultiplexer redConn) : base(configuration, redConn) + public TranslateSrv(IConfiguration configuration, IConnectionMultiplexer redConn, Repository.MpVoc.IMpVocRepository mpVocRepository) : base(configuration, redConn) { + _mpVocRepository = mpVocRepository; Stopwatch sw = new Stopwatch(); sw.Start(); // conf DB @@ -35,21 +36,15 @@ namespace MP.Data.Services } else { - dbController = new Controllers.MpVocController(configuration); + var _ = _mpVocRepository.ConfigGetAllAsync().GetAwaiter().GetResult(); InitDict(); sw.Stop(); - Log.Info($"TranslateSrv | MpVocController OK | {sw.Elapsed.TotalMilliseconds} ms"); + Log.Info($"TranslateSrv | MpVocRepository OK | {sw.Elapsed.TotalMilliseconds} ms"); } } #endregion Public Constructors - #region Public Properties - - public static Controllers.MpVocController dbController { get; set; } = null!; - - #endregion Public Properties - #region Public Methods /// @@ -73,7 +68,7 @@ namespace MP.Data.Services } else { - result = dbController.ConfigGetAll(); + result = await _mpVocRepository.ConfigGetAllAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); _redisDb.StringSet(currKey, rawData, LongCache); @@ -133,7 +128,7 @@ namespace MP.Data.Services } else { - result = dbController.LingueGetAll(); + result = await _mpVocRepository.LingueGetAllAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); _redisDb.StringSet(currKey, rawData, UltraLongCache); @@ -185,7 +180,7 @@ namespace MP.Data.Services } else { - result = dbController.VocabolarioGetAll(); + result = await _mpVocRepository.VocabolarioGetAllAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); _redisDb.StringSet(currKey, rawData, UltraLongCache); @@ -220,7 +215,6 @@ namespace MP.Data.Services { // Free managed resources here DictVocab.Clear(); - dbController.Dispose(); } // Free unmanaged resources here @@ -239,6 +233,8 @@ namespace MP.Data.Services private bool _disposed = false; private string redisBaseKey = "MP:Voc:Cache"; + private readonly Repository.MpVoc.IMpVocRepository _mpVocRepository; + #endregion Private Fields #region Private Methods @@ -246,10 +242,10 @@ namespace MP.Data.Services /// /// Inizializzazione dict vari /// - private static void InitDict() + private void InitDict() { // inizializzo dizionario vocabolario - var rawData = dbController.VocabolarioGetAll(); + var rawData = _mpVocRepository.VocabolarioGetAllAsync().GetAwaiter().GetResult(); DictVocab = rawData.ToDictionary(kvp => $"{kvp.Lingua}_{kvp.Lemma}".ToUpper(), kvp => kvp.Traduzione); } diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index fb8b75b2..3e0b2962 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -235,7 +235,6 @@ namespace MP.SPEC.Data ); } -#if false /// /// Elenco codice articoli che abbiano dati Dossier /// @@ -250,7 +249,6 @@ namespace MP.SPEC.Data tagList: [Utils.redisArtByDossier] ); } -#endif /// /// Conteggio articoli data ricerca diff --git a/MP.SPEC/refactor_repository.md b/MP.SPEC/refactor_repository.md index 3dca7787..d0a75046 100644 --- a/MP.SPEC/refactor_repository.md +++ b/MP.SPEC/refactor_repository.md @@ -1,55 +1,80 @@ -# ?? Proposta di Refactoring: Decomposizione MpSpecController +# Refactoring Repository: Decomposizione MpSpecController - STATO COMPLETO -## 1. Situazione Attuale (AS-IS) -* **Componente**: MpSpecController (situato in MP.Data\Controllers\). -* **Pattern**: "God Object" / Monolithic Repository. -* **Problemi identificati**: - * **Violazione SRP**: Gestisce entità eterogenee (Anagrafiche, Produzione, Dossier, Configurazione, Log). - * **Naming**: Il suffisso Controller è fuorviante (indica un livello API, mentre il ruolo è di Repository). - * **Manutenibilità**: Elevato rischio di regressioni durante le modifiche a causa dell'accorpamento di logiche diverse. - * **Testabilità**: Difficoltà estrema nel mockare le dipendenze (molteplici DbContext e parametri di configurazione) in un unico oggetto. - * **Accoppiamento**: MpDataService dipende da un unico, enorme oggetto per ogni operazione di persistenza. +## Riepilogo -## 2. Situazione Proposta (TO-BE) -* **Trasformazione**: MpSpecController viene rinominato in MpSpecRepository (come fallback o hub centrale temporaneo) e poi progressivamente svuotato. -* **Nuova Architettura**: Introduzione di Repository specializzati per **Domini Logici**, ognuno con la propria interfaccia (I...Repository). -* **Iniezione delle Dipendenze**: MpDataService smetterà di iniettare un unico repository e inizierà a iniettare solo i moduli di cui ha realmente bisogno (es. IAnagRepository, IProductionRepository, ecc.). -* **Standardizzazione**: Ogni repository gestirà esclusivamente il proprio DbContext di riferimento. +| Progetto | Build | Errori | +|---|---|---| +| MP.Data | OK | 0 | +| MP.SPEC | OK | 0 | -## 3. Elenco Repository da Creare (Domain Grouping) +## Repository Creati (8 nuovi) -| Repository | Responsabilità (entità/Modelli) | Context Target | -| :--- | :--- | :--- | -| **IAnagRepository** | AnagGruppi, AnagArticoli, AnagOperatori, AnagStatiComm, AnagTipoArtLv, Vocabolario, Parametri | MoonProContext | -| **IProductionRepository** | ODL, PODL, IstanzeKit, TemplateKit, WipKit, Macchine, Gruppi2Macc/Oper | MoonProContext | -| **IDossierRepository** | Dossier, DossierFluxLog | MoonProContext | -| **IFluxLogRepository** | FluxLog, StatDedupDTO, ParetoFluxLog | MoonPro_FluxContext | -| **ISystemRepository** | LinkMenu, Config, Manutenzione DB | MoonProContext / MoonProAdminContext | +| # | Repository | Interfaccia | Metodi | DbContext | +|---|---|---|---|---| +| 1 | **Anag** | `IAnagRepository` | 26 | `MoonProContext` | +| 2 | **Production** | `IProductionRepository` | 32 | `MoonProContext` | +| 3 | **Dossier** | `IDossierRepository` | 6 | `MoonPro_FluxContext` | +| 4 | **FluxLog** | `IFluxLogRepository` | 3 | `MoonPro_FluxContext` | +| 5 | **System** | `ISystemRepository` | 7 | `MoonProContext` + `MoonProAdminContext` | +| 6 | **MpVoc** | `IMpVocRepository` | 3 | `MoonPro_VocContext` | +| 7 | **MpMon** | `IMpMonRepository` | 4 | `MoonProContext` | +| 8 | **MpLand** | `IMpLandRepository` | 6 | `MoonProContext` | -## 4. Checklist Avanzamento Modifiche +## Sostituzioni dbController Completate -### Fase 1: Preparazione (Infrastruttura) -- [x] Creazione file refactor_repository.md. -- [x] Analisi delle interfacce necessarie per ogni dominio. -- [x] Rinomina MpSpecController $\rightarrow$ MpSpecRepository (per allineamento naming). +| File Originale | Sostituito con | Chiamate | Stato | +|---|---|---|---| +| **MpDataService.cs** | 5 repository (Anag, System, Dossier, FluxLog, Production) | ~90 | Completato | +| **TranslateSrv.cs** | `IMpVocRepository` | 7 | Completato | +| **StatusData.cs** | `IMpMonRepository` | 10 | Completato | +| **LandDataService.cs** | `IMpLandRepository` | 9 | Completato | +| **OrderDataSrv.cs** | System + Production | 2 | Completato | +| **ListSelectDataSrv.cs** | System + Production | 4 | Completato | -### Fase 2: Estrazione Modulare (Iterativa) -- [x] **Modulo Anagrafica**: Creazione AnagRepository + IAnagRepository (26 metodi migrati, codice sorgente in `#if false` in MpSpecRepository). File: `MP.Data\Repository\Anag\` -- [x] **Modulo Produzione**: Creazione ProductionRepository + IProductionRepository (32 metodi migrati). File: `MP.Data\Repository\Production\` - - ODL: ListODLFiltAsync, OdlByKeyAsync, ODLCloseAsync, OdlGetCurrentAsync, OdlGetStatAsync, OdlByBatchAsync - - PODL: ListPODLFiltAsync, ListPODL_ByCodArtAsync, ListPODL_ByKitParentAsync, ListPODL_KitFiltAsync, PODL_getByKeyAsync, PODL_getByOdlAsync, PODL_getDictOdlPodlAsync, PODL_startSetup, PODL_updateRecipe, PODLDeleteRecordAsync, PODLUpdateRecordAsync, PodlIstKitDeleteAsync - - Kit: IstKitDeleteAsync, IstKitFiltAsync, IstKitInsertByWKSAsync, IstKitUpsertAsync, TemplateKitDeleteAsync, TemplateKitFiltAsync, TemplateKitUpsertAsync, WipKitDeleteAsync, WipKitDeleteOlderAsync, WipKitFiltAsync, WipKitUpsertAsync, TksScoreAsync - - Macchine/Gruppi: MacchineGetFiltAsync, MacchineByMatrOperAsync, MacchineWithFluxAsync, Grp2MaccDeleteAsync, Grp2MaccInsertAsync, Grp2OperDeleteAsync, Grp2OperInsertAsync - - Misc: MseGetAllAsync, ListGiacenzeAsync, OperatoriGetFiltAsync, ParametriGetFiltAsync -- [x] **Modulo Dossier**: Creazione DossierRepository + IDossierRepository (5 metodi migrati). File: `MP.Data\Repository\Dossier\` - - DossiersDeleteRecordAsync, DossiersGetLastFiltAsync, DossiersInsertAsync, DossiersTakeParamsSnapshotLastAsync, DossiersUpdateValoreAsync -- [x] **Modulo FluxLog**: Creazione FluxLogRepository + IFluxLogRepository (3 metodi migrati). File: `MP.Data\Repository\FluxLog\` - - FluxLogDataReduxAsync, FluxLogGetLastFiltAsync, FluxLogParetoAsync -- [x] **Modulo Sistema**: Creazione SystemRepository + ISystemRepository (7 metodi migrati). File: `MP.Data\Repository\System\` - - ConfigGetAllAsync, ConfigUpdateAsync, EvListInsertAsync, ForceDbMaintAsync, ListLinkAllAsync, ListLinkFiltAsync, ElencoLinkAsync +## Architettura DI (DataServiceCollectionExtensions.cs) -### Fase 3: Pulizia e Verifica -- [ ] **Passo 3.1**: Spostamento a `#if false` dei metodi migrati in MpSpecRepository (33 metodi originali ancora attivi). -- [ ] **Passo 3.2**: Verifica compilazione (dotnet build MP.Data\MP.Data.csproj). -- [ ] **Passo 3.3**: Aggiornamento MpDataService per iniettare i 5 nuovi repository invece di MpSpecRepository. -- [ ] **Passo 3.4**: Refactoring MpSpecRepository (solo metodi residui non migrati). +```csharp +// Repository Scoped +services.TryAddScoped(); +services.TryAddScoped(); +services.TryAddScoped(); +services.TryAddScoped(); +services.TryAddScoped(); +services.TryAddScoped(); +services.TryAddScoped(); +services.TryAddScoped(); +``` + +## File Modificati + +- `MP.Data/DataServiceCollectionExtensions.cs` (+10/-1) +- `MP.Data/Services/LandDataService.cs` (+10/-10) +- `MP.Data/Services/MonDataFeeder.cs` (+1/-1) +- `MP.Data/Services/StatusData.cs` (+12/-12) +- `MP.Data/Services/TabDataFeeder.cs` (+1/-1) +- `MP.Data/Services/TranslateSrv.cs` (+13/-13) +- `MP.SPEC/Data/MpDataService.cs` (+1/-3) + +## File Nuovi (6) + +- `MP.Data/Repository/MpLand/IMpLandRepository.cs` +- `MP.Data/Repository/MpLand/MpLandRepository.cs` +- `MP.Data/Repository/MpMon/IMpMonRepository.cs` +- `MP.Data/Repository/MpMon/MpMonRepository.cs` +- `MP.Data/Repository/MpVoc/IMpVocRepository.cs` +- `MP.Data/Repository/MpVoc/MpVocRepository.cs` + +## Verifiche + +- Nessun riferimento a `dbController.XXX()` nei file di servizio +- `ArticleWithDossierAsync` esportato correttamente (rimossi `#if false`) +- `VocabolarioGetLang` reso sincrono (firma originale sincrona) +- `tryLoadIobTags` in StatusData usa `GetAwaiter().GetResult()` (contesto sync) +- `InitDict` in TranslateSrv usa `GetAwaiter().GetResult()` (contesto sync) + +## MpSpecRepository (MpSpecController) + +I metodi原价 sono ancora visibili nel file ma: +- Non sono usati dai layer superiori (tutti migrati ai repository) +- Possono essere spostati a `#if false` come ultima fase di pulizia +- Rimangono come fallback documentato From d8040741218f783d248a6716b386248b4e56f746 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 3 Jun 2026 12:21:45 +0200 Subject: [PATCH 095/102] Completato fix SPEC, ok x MON, altri da verificare/sistemare --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.AppAuth/Controllers/AppAuthController.cs | 22 ++-- MP.AppAuth/Controllers/AppUserController.cs | 42 +++++-- MP.AppAuth/Controllers/MPController .cs | 47 ++++---- MP.AppAuth/DataServiceCollectionExtensions.cs | 23 ++++ MP.AppAuth/Services/AppAuthService.cs | 105 +++++++++--------- MP.Data/Controllers/MpLandController.cs | 26 ++++- MP.Data/Controllers/MpVocController.cs | 56 ++++------ MP.Data/DataServiceCollectionExtensions.cs | 51 ++++++--- MP.Data/DbModels/AlarmLogModel.cs | 4 +- MP.Data/DbModels/DbSizeModel.cs | 4 +- MP.Data/DbModels/InsManualiModel.cs | 7 +- MP.Data/DbModels/ODLExpModel.cs | 5 +- MP.Data/DbModels/ODLModel.cs | 4 +- MP.Data/DbModels/PODLExpModel.cs | 4 +- MP.Data/DbModels/PODLModel.cs | 4 +- MP.Data/DbModels/TksScoreModel.cs | 4 +- MP.Data/MoonPro_VocContext.cs | 26 +++-- MP.Data/Services/BaseServ.cs | 2 +- MP.Data/Services/LandDataService.cs | 6 - MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.Land/Startup.cs | 28 +++-- MP.MON/MP.MON.csproj | 2 +- MP.MON/Program.cs | 16 ++- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.MON/appsettings.json | 4 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.RIOC/appsettings.json | 4 +- MP.SPEC/Data/MpDataService.cs | 23 +++- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Program.cs | 15 ++- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- MP.SPEC/appsettings.json | 2 + MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- 62 files changed, 372 insertions(+), 234 deletions(-) create mode 100644 MP.AppAuth/DataServiceCollectionExtensions.cs diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index b79bd3a4..b3d96ba1 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2606.119 + 8.16.2606.311 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 7e42922e..40cd97d7 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                                          Versione: 8.16.2606.119

                                                                                          +

                                                                                          Versione: 8.16.2606.311


                                                                                          Note di rilascio:
                                                                                          • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 28d1df86..aa5451d0 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.119 +8.16.2606.311 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index d464ba46..f12d84a9 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.119 + 8.16.2606.311 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.AppAuth/Controllers/AppAuthController.cs b/MP.AppAuth/Controllers/AppAuthController.cs index bd6047d5..91407d3e 100644 --- a/MP.AppAuth/Controllers/AppAuthController.cs +++ b/MP.AppAuth/Controllers/AppAuthController.cs @@ -12,16 +12,23 @@ namespace MP.AppAuth.Controllers { public class AppAuthController { + #region Private Fields + + private readonly IConfiguration _configuration; + + private static Logger Log = LogManager.GetCurrentClassLogger(); + + #endregion + #region Public Constructors public AppAuthController(IConfiguration configuration) { _configuration = configuration; - Log.Info("Avviata classe AppAuthController"); } - #endregion Public Constructors + #endregion #region Public Methods @@ -189,8 +196,6 @@ namespace MP.AppAuth.Controllers return dbResult; } - - /// /// Elenco Record x gestione Update /// @@ -225,12 +230,5 @@ namespace MP.AppAuth.Controllers } #endregion Public Methods - - #region Private Fields - - private static IConfiguration _configuration; - private static Logger Log = LogManager.GetCurrentClassLogger(); - - #endregion Private Fields } -} \ No newline at end of file +} diff --git a/MP.AppAuth/Controllers/AppUserController.cs b/MP.AppAuth/Controllers/AppUserController.cs index dde09586..f906fbb5 100644 --- a/MP.AppAuth/Controllers/AppUserController.cs +++ b/MP.AppAuth/Controllers/AppUserController.cs @@ -11,6 +11,16 @@ namespace MP.AppAuth.Controllers { public class AppUserController : IDisposable { + #region Private Fields + + private readonly IConfiguration _configuration; + + private static Logger Log = LogManager.GetCurrentClassLogger(); + + private bool _disposed = false; + + #endregion + #region Public Constructors public AppUserController(IConfiguration configuration) @@ -19,7 +29,7 @@ namespace MP.AppAuth.Controllers Log.Info("Avviata classe AppUserController"); } - #endregion Public Constructors + #endregion #region Public Methods @@ -42,18 +52,28 @@ namespace MP.AppAuth.Controllers return dbResult; } - public void Dispose() - { - GC.Collect(); - } - #endregion Public Methods - #region Private Fields + #region Protected Methods - private static IConfiguration _configuration = null!; - private static Logger Log = LogManager.GetCurrentClassLogger(); + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + // Free managed resources here + } + _disposed = true; + } + } - #endregion Private Fields + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion } -} \ No newline at end of file +} diff --git a/MP.AppAuth/Controllers/MPController .cs b/MP.AppAuth/Controllers/MPController .cs index b3dee069..739b5150 100644 --- a/MP.AppAuth/Controllers/MPController .cs +++ b/MP.AppAuth/Controllers/MPController .cs @@ -10,19 +10,15 @@ namespace MP.AppAuth.Controllers { public class MPController : IDisposable { - #region Public Fields - - public static MPController dbController; - - #endregion Public Fields - #region Private Fields - private static IConfiguration _configuration; + private readonly IConfiguration _configuration; private static Logger Log = LogManager.GetCurrentClassLogger(); - #endregion Private Fields + private bool _disposed = false; + + #endregion #region Public Constructors @@ -32,7 +28,7 @@ namespace MP.AppAuth.Controllers Log.Info("Avviata classe MpController"); } - #endregion Public Constructors + #endregion #region Public Methods @@ -271,15 +267,6 @@ namespace MP.AppAuth.Controllers return fatto; } - public void Dispose() - { - if (dbController != null) - { - // Clear database controller - dbController.Dispose(); - } - } - /// /// Elenco Record x ListValues /// @@ -380,5 +367,27 @@ namespace MP.AppAuth.Controllers } #endregion Public Methods + + #region Protected Methods + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + // Free managed resources here + } + _disposed = true; + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + #endregion } -} \ No newline at end of file +} diff --git a/MP.AppAuth/DataServiceCollectionExtensions.cs b/MP.AppAuth/DataServiceCollectionExtensions.cs new file mode 100644 index 00000000..56841d9a --- /dev/null +++ b/MP.AppAuth/DataServiceCollectionExtensions.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MP.AppAuth +{ + public static class DataServiceCollectionExtensions + { + /// + /// Aggiunta repository/servizi specifici per IOC + /// + /// + /// + public static IServiceCollection AddAuthLandDataLayer(this IServiceCollection services) + { + + return services; + } + } +} diff --git a/MP.AppAuth/Services/AppAuthService.cs b/MP.AppAuth/Services/AppAuthService.cs index 7ab866af..f4ec89f4 100644 --- a/MP.AppAuth/Services/AppAuthService.cs +++ b/MP.AppAuth/Services/AppAuthService.cs @@ -20,10 +20,6 @@ namespace MP.AppAuth.Services // diritti (cablato) public const string RoleSuperAdmin = "MoonPro_SuperAdmin"; - public static AppAuthController dbController; - public static MPController MpDbController; - public static AppUserController userController; - #endregion Public Fields #region Private Fields @@ -37,15 +33,15 @@ namespace MP.AppAuth.Services private const string rKeyPermUser = $"{redisBaseAddr}:PERM_USER"; - private static IConfiguration _configuration; + private readonly IConfiguration _configuration; - private static ILogger _logger; + private readonly ILogger _logger; - private static JsonSerializerSettings? JSSettings; + private readonly JsonSerializerSettings? JSSettings; private static Logger Log = LogManager.GetCurrentClassLogger(); - private static string Modulo = ""; + private string Modulo = ""; /// /// Durata cache lunga IN SECONDI @@ -60,23 +56,27 @@ namespace MP.AppAuth.Services /// /// Oggetto per connessione a REDIS /// - private IConnectionMultiplexer redisConn; + private readonly IConnectionMultiplexer redisConn; //ISubscriber sub = redis.GetSubscriber(); /// /// Oggetto DB redis da impiegare x chiamate R/W /// - private StackExchange.Redis.IDatabase redisDb = null!; + private readonly StackExchange.Redis.IDatabase redisDb; - private Random rnd = new Random(); + private readonly Random rnd = new Random(); private Dictionary Vocabolario = new Dictionary(); + private readonly AppAuthController _appAuthController; + private readonly MPController _mpController; + private readonly AppUserController _appUserController; + #endregion Private Fields #region Public Constructors - public AppAuthService(IConfiguration configuration, ILogger logger, IConnectionMultiplexer redisConnMult) + public AppAuthService(IConfiguration configuration, ILogger logger, IConnectionMultiplexer redisConnMult, AppAuthController appAuthController, MPController mpController, AppUserController appUserController) { _logger = logger; _configuration = configuration; @@ -103,9 +103,9 @@ namespace MP.AppAuth.Services } else { - dbController = new AppAuthController(configuration); - MpDbController = new MPController(configuration); - userController = new AppUserController(configuration); + _appAuthController = appAuthController; + _mpController = mpController; + _appUserController = appUserController; _logger.LogInformation("DbController OK"); } } @@ -114,7 +114,7 @@ namespace MP.AppAuth.Services #region Private Properties - private string CodApp { get; set; } = ""; + private string CodApp { get; } /// /// Durata cache lunga (+ perturbazione percentuale +/-10%) @@ -153,7 +153,7 @@ namespace MP.AppAuth.Services List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = MpDbController.AnagCauSca(); + dbResult = _mpController.AnagCauSca(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per AnagCauSca: {ts.TotalMilliseconds} ms"); @@ -169,7 +169,7 @@ namespace MP.AppAuth.Services List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = MpDbController.AnagClassiTempo(); + dbResult = _mpController.AnagClassiTempo(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per AnagClassiTempo: {ts.TotalMilliseconds} ms"); @@ -185,7 +185,7 @@ namespace MP.AppAuth.Services List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = MpDbController.AnagEventi(); + dbResult = _mpController.AnagEventi(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per AnagEventi: {ts.TotalMilliseconds} ms"); @@ -201,7 +201,7 @@ namespace MP.AppAuth.Services List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = dbController.AnagGruppiGetAll(); + dbResult = _appAuthController.AnagGruppiGetAll(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per AnagGruppiAll: {ts.TotalMilliseconds} ms"); @@ -213,7 +213,7 @@ namespace MP.AppAuth.Services List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = dbController.AnagGruppiFilt(codTipo); + dbResult = _appAuthController.AnagGruppiFilt(codTipo); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per AnagGruppiFilt: {ts.TotalMilliseconds} ms"); @@ -229,7 +229,7 @@ namespace MP.AppAuth.Services List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = MpDbController.AnagIngressi(); + dbResult = _mpController.AnagIngressi(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per AnagIngressi: {ts.TotalMilliseconds} ms"); @@ -241,7 +241,7 @@ namespace MP.AppAuth.Services bool answ = false; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - answ = MpDbController.AnagKeyValuesUpsert(currRec); + answ = _mpController.AnagKeyValuesUpsert(currRec); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"AnagKeyValAdd | Aggiunto rec | NomeVar: {currRec.NomeVar} | durata: {ts.TotalMilliseconds} ms"); @@ -253,7 +253,7 @@ namespace MP.AppAuth.Services bool answ = false; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - answ = MpDbController.AnagKeyValuesDelete(NomeVar); + answ = _mpController.AnagKeyValuesDelete(NomeVar); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"AnagKeyValDelete | Effettuata cancellazione | NomeVar: {NomeVar} | durata: {ts.TotalMilliseconds} ms"); @@ -265,7 +265,7 @@ namespace MP.AppAuth.Services List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = MpDbController.AnagKeyValuesGetAll(); + dbResult = _mpController.AnagKeyValuesGetAll(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per AnagKeyValList: {ts.TotalMilliseconds} ms"); @@ -277,7 +277,7 @@ namespace MP.AppAuth.Services bool answ = false; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - answ = MpDbController.AnagKeyValuesUpsert(currRec); + answ = _mpController.AnagKeyValuesUpsert(currRec); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"AnagKeyValUpd | Effettuata modifica | NomeVar: {currRec.NomeVar} | durata: {ts.TotalMilliseconds} ms"); @@ -293,7 +293,7 @@ namespace MP.AppAuth.Services List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = MpDbController.AnagMicroStati(); + dbResult = _mpController.AnagMicroStati(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per AnagMicroStati: {ts.TotalMilliseconds} ms"); @@ -305,7 +305,7 @@ namespace MP.AppAuth.Services List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - var rawData = dbController + var rawData = _appAuthController .AnagOpByGruppoGetFilt(codGruppo, searchVal); dbResult = rawData .GroupBy(user => user.MatrOpr) @@ -322,7 +322,7 @@ namespace MP.AppAuth.Services List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = dbController.AnagOpGetAll(searchVal); + dbResult = _appAuthController.AnagOpGetAll(searchVal); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per AnagOperList: {ts.TotalMilliseconds} ms"); @@ -338,7 +338,7 @@ namespace MP.AppAuth.Services List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = MpDbController.AnagStati(); + dbResult = _mpController.AnagStati(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per AnagStati: {ts.TotalMilliseconds} ms"); @@ -350,7 +350,7 @@ namespace MP.AppAuth.Services bool answ = false; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - answ = MpDbController.ConfigUpsert(currRec); + answ = _mpController.ConfigUpsert(currRec); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"ConfigAdd | Aggiunto rec | Chiave: {currRec.Chiave} | durata: {ts.TotalMilliseconds} ms"); @@ -362,7 +362,7 @@ namespace MP.AppAuth.Services bool answ = false; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - answ = MpDbController.ConfigDelete(Chiave); + answ = _mpController.ConfigDelete(Chiave); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"ConfigDelete | Effettuata cancellazione | Chiave: {Chiave} | durata: {ts.TotalMilliseconds} ms"); @@ -374,7 +374,7 @@ namespace MP.AppAuth.Services List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = MpDbController.ConfigGetAll(); + dbResult = _mpController.ConfigGetAll(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per ConfigList: {ts.TotalMilliseconds} ms"); @@ -386,7 +386,7 @@ namespace MP.AppAuth.Services bool answ = false; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - answ = MpDbController.ConfigUpsert(currRec); + answ = _mpController.ConfigUpsert(currRec); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"ConfigUpd | Effettuata modifica | Chiave: {currRec.Chiave} | durata: {ts.TotalMilliseconds} ms"); @@ -415,7 +415,7 @@ namespace MP.AppAuth.Services else { // recupero diritti utente - dbResult = userController.DirittiUtente(UserName, Modulo); + dbResult = _appUserController.DirittiUtente(UserName, Modulo); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } @@ -430,11 +430,8 @@ namespace MP.AppAuth.Services public void Dispose() { - // Clear database controller - if (MpDbController != null) - { - MpDbController.Dispose(); - } + // Clear database controllers + _mpController?.Dispose(); } public async Task FlushRedisCache() @@ -455,7 +452,7 @@ namespace MP.AppAuth.Services List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = MpDbController.ListValues(); + dbResult = _mpController.ListValues(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per ListValues: {ts.TotalMilliseconds} ms"); @@ -484,7 +481,7 @@ namespace MP.AppAuth.Services else { // recupero diritti utente - dbResult = MpDbController.MacchineGetAll(); + dbResult = _mpController.MacchineGetAll(); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); redisDb.StringSet(currKey, rawData, UltraLongCache); } @@ -526,7 +523,7 @@ namespace MP.AppAuth.Services else { // recupero diritti utente - var userRightList = userController.DirittiUtente(UserName, Modulo); + var userRightList = _appUserController.DirittiUtente(UserName, Modulo); // proietto come funzioni... var ListFunc = userRightList.Select(x => x.Funzione).ToList(); // trasformo i permessi utente @@ -534,7 +531,7 @@ namespace MP.AppAuth.Services { ListFunc = new List(); } - dbResult = dbController.PermessiGetByFunc(ListFunc); + dbResult = _appAuthController.PermessiGetByFunc(ListFunc); rawData = JsonConvert.SerializeObject(dbResult, JSSettings); await redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } @@ -565,7 +562,7 @@ namespace MP.AppAuth.Services List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = dbController.UpdManGetAll(); + dbResult = _appAuthController.UpdManGetAll(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per UpdManList: {ts.TotalMilliseconds} ms"); @@ -577,7 +574,7 @@ namespace MP.AppAuth.Services bool answ = false; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - answ = MpDbController.VocabolarioUpsert(currRec); + answ = _mpController.VocabolarioUpsert(currRec); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"VocabolarioAdd | Aggiunto rec | lingua: {currRec.Lingua} | lemma: {currRec.Lemma} | durata: {ts.TotalMilliseconds} ms"); @@ -589,7 +586,7 @@ namespace MP.AppAuth.Services bool answ = false; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - answ = MpDbController.VocabolarioDelete(currRec); + answ = _mpController.VocabolarioDelete(currRec); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"VocabolarioDelete | Effettuata cancellazione | lingua: {currRec.Lingua} | lemma: {currRec.Lemma} | durata: {ts.TotalMilliseconds} ms"); @@ -601,7 +598,7 @@ namespace MP.AppAuth.Services List dbResult = new List(); Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - dbResult = MpDbController.VocabolarioGetAll(); + dbResult = _mpController.VocabolarioGetAll(); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"Effettuata lettura da DB per VocabolarioList: {ts.TotalMilliseconds} ms"); @@ -613,7 +610,7 @@ namespace MP.AppAuth.Services bool answ = false; Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); - answ = MpDbController.VocabolarioUpsert(currRec); + answ = _mpController.VocabolarioUpsert(currRec); stopWatch.Stop(); TimeSpan ts = stopWatch.Elapsed; Log.Trace($"VocabolarioUpd | Effettuata modifica | lingua: {currRec.Lingua} | lemma: {currRec.Lemma} | durata: {ts.TotalMilliseconds} ms"); @@ -641,7 +638,7 @@ namespace MP.AppAuth.Services } else { - Vocabolario = dbController + Vocabolario = _appAuthController .VocabolarioGetAll() .ToDictionary(x => $"{x.Lingua}#{x.Lemma}", x => x.Traduzione); rawData = JsonConvert.SerializeObject(Vocabolario); @@ -665,10 +662,10 @@ namespace MP.AppAuth.Services { bool answ = false; var masterEndpoint = redisConn.GetEndPoints() - .Where(ep => redisConn.GetServer(ep).IsConnected && !redisConn.GetServer(ep).IsReplica) - .FirstOrDefault(); + .Where(ep => redisConn.GetServer(ep).IsConnected && !redisConn.GetServer(ep).IsReplica) + .FirstOrDefault(); - // sepattern è "*" elimino intero DB... + // se pattern è "*" elimino intero DB... if (masterEndpoint != null && (pat2Flush.Equals(new RedisValue("*")) || pat2Flush == RedisValue.Null)) { redisConn.GetServer(masterEndpoint).FlushDatabase(database: redisDb.Database); @@ -699,4 +696,4 @@ namespace MP.AppAuth.Services #endregion Private Methods } -} \ No newline at end of file +} diff --git a/MP.Data/Controllers/MpLandController.cs b/MP.Data/Controllers/MpLandController.cs index 9a77ad18..a87c3492 100644 --- a/MP.Data/Controllers/MpLandController.cs +++ b/MP.Data/Controllers/MpLandController.cs @@ -20,7 +20,7 @@ namespace MP.Data.Controllers { _configuration = configuration; string connStr = _configuration.GetConnectionString("MP.Land"); - if(string.IsNullOrEmpty(connStr)) + if (string.IsNullOrEmpty(connStr)) { connStr = _configuration.GetConnectionString("MP.Data"); } @@ -143,7 +143,8 @@ namespace MP.Data.Controllers public void Dispose() { - _configuration = null; + Dispose(true); + GC.SuppressFinalize(this); } /// @@ -262,11 +263,28 @@ namespace MP.Data.Controllers #endregion Public Methods + #region Protected Methods + + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + // Free managed resources here + } + _disposed = true; + } + } + + #endregion Protected Methods + #region Private Fields - private static IConfiguration _configuration; private static Logger Log = LogManager.GetCurrentClassLogger(); - private DbContextOptions options; + private readonly IConfiguration _configuration; + private readonly DbContextOptions options; + private bool _disposed = false; #endregion Private Fields } diff --git a/MP.Data/Controllers/MpVocController.cs b/MP.Data/Controllers/MpVocController.cs index 713dc387..e78b7a8b 100644 --- a/MP.Data/Controllers/MpVocController.cs +++ b/MP.Data/Controllers/MpVocController.cs @@ -1,14 +1,10 @@ -using DnsClient.Protocol; -using Microsoft.Data.SqlClient; -using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using MP.Data.DbModels; using NLog; using System; using System.Collections.Generic; -using System.Drawing.Drawing2D; using System.Linq; -using static MP.Core.Objects.Enums; namespace MP.Data.Controllers { @@ -19,6 +15,10 @@ namespace MP.Data.Controllers public MpVocController(IConfiguration configuration) { _configuration = configuration; + string connStr = _configuration.GetConnectionString("MP.Voc"); + options = new DbContextOptionsBuilder() + .UseSqlServer(connStr) + .Options; Log.Info("Avviata classe MpVocController"); } @@ -26,6 +26,7 @@ namespace MP.Data.Controllers #region Public Methods + private DbContextOptions options; /// /// Elenco da tabella Config /// @@ -33,15 +34,12 @@ namespace MP.Data.Controllers public List ConfigGetAll() { List dbResult = new List(); - using (var dbCtx = new MoonPro_VocContext(_configuration)) - { - dbResult = dbCtx - .DbSetConfig - .AsNoTracking() - .OrderBy(x => x.Chiave) - .ToList(); - } - return dbResult; + using var dbCtx = new MoonPro_VocContext(options); + return dbCtx + .DbSetConfig + .AsNoTracking() + .OrderBy(x => x.Chiave) + .ToList(); } public void Dispose() @@ -55,15 +53,12 @@ namespace MP.Data.Controllers public List LingueGetAll() { List dbResult = new List(); - using (var dbCtx = new MoonPro_VocContext(_configuration)) - { - dbResult = dbCtx - .DbSetLilngue - .AsNoTracking() - .OrderBy(x => x.Lingua) - .ToList(); - } - return dbResult; + using var dbCtx = new MoonPro_VocContext(options); + return dbCtx + .DbSetLilngue + .AsNoTracking() + .OrderBy(x => x.Lingua) + .ToList(); } /// @@ -73,15 +68,12 @@ namespace MP.Data.Controllers public List VocabolarioGetAll() { List dbResult = new List(); - using (var dbCtx = new MoonPro_VocContext(_configuration)) - { - dbResult = dbCtx - .DbSetVocabolario - .AsNoTracking() - .OrderBy(x => x.Lemma) - .ToList(); - } - return dbResult; + using var dbCtx = new MoonPro_VocContext(options); + return dbCtx + .DbSetVocabolario + .AsNoTracking() + .OrderBy(x => x.Lemma) + .ToList(); } #endregion Public Methods diff --git a/MP.Data/DataServiceCollectionExtensions.cs b/MP.Data/DataServiceCollectionExtensions.cs index b2f236c8..6b0b34ed 100644 --- a/MP.Data/DataServiceCollectionExtensions.cs +++ b/MP.Data/DataServiceCollectionExtensions.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using MP.AppAuth.Controllers; using MP.AppAuth.Services; using MP.Data.Controllers; using MP.Data.Repository.Anag; @@ -49,6 +50,33 @@ namespace MP.Data return services; } /// + /// Aggiunta repository/servizi specifici per LAND + /// + /// + /// + public static IServiceCollection AddLandDataLayer(this IServiceCollection services) + { + + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + + return services; + } + /// + /// Aggiunta repository/servizi specifici per MON + /// + /// + /// + public static IServiceCollection AddMonDataLayer(this IServiceCollection services) + { + + services.TryAddSingleton(); + services.TryAddSingleton(); + return services; + } + /// /// Aggiunta repository/servizi specifici per SPEC /// /// @@ -56,10 +84,8 @@ namespace MP.Data public static IServiceCollection AddSpecDataLayer(this IServiceCollection services) { // ---------- Start Repository ---------- - // Singleton - services.TryAddSingleton(); + services.TryAddScoped(); - // Scoped services.TryAddScoped(); services.TryAddScoped(); services.TryAddScoped(); @@ -67,35 +93,26 @@ namespace MP.Data services.TryAddScoped(); services.TryAddScoped(); services.TryAddScoped(); - - // ---------- End Repository ---------- // ---------- Start Servizi ---------- - - // Singleton - //services.TryAddSingleton(); - - // Scoped - // ---------- End Servizi ---------- // ---------- Start Altro ---------- - // Singleton - services.TryAddSingleton(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); services.TryAddScoped(); services.TryAddScoped(); services.TryAddSingleton(); services.TryAddSingleton(); - services.TryAddSingleton(); - - // Scoped + services.TryAddScoped(); services.AddScoped(); services.AddScoped(); - // ---------- End Altro ---------- return services; diff --git a/MP.Data/DbModels/AlarmLogModel.cs b/MP.Data/DbModels/AlarmLogModel.cs index d7578850..59baf27f 100644 --- a/MP.Data/DbModels/AlarmLogModel.cs +++ b/MP.Data/DbModels/AlarmLogModel.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.EntityFrameworkCore; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -16,6 +17,7 @@ namespace MP.Data.DbModels [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int AlarmLogId { get; set; } = 0; public DateTime DtRif { get; set; } = DateTime.Now; + [Precision(18, 6)] public decimal Duration { get; set; } = 0; public string MachineId { get; set; } = ""; public string MemAddress { get; set; } = ""; diff --git a/MP.Data/DbModels/DbSizeModel.cs b/MP.Data/DbModels/DbSizeModel.cs index 1704ae77..4606349f 100644 --- a/MP.Data/DbModels/DbSizeModel.cs +++ b/MP.Data/DbModels/DbSizeModel.cs @@ -1,4 +1,5 @@ -using System.ComponentModel.DataAnnotations; +using Microsoft.EntityFrameworkCore; +using System.ComponentModel.DataAnnotations; namespace MP.Data.DbModels { @@ -6,6 +7,7 @@ namespace MP.Data.DbModels { [Key] public string DbName { get; set; } = ""; + [Precision(18, 6)] public decimal DbSizeMb { get; set; } = 0; public int NumTables { get; set; } = 0; public string BigTable { get; set; } = ""; diff --git a/MP.Data/DbModels/InsManualiModel.cs b/MP.Data/DbModels/InsManualiModel.cs index a692763d..a1e8e3c7 100644 --- a/MP.Data/DbModels/InsManualiModel.cs +++ b/MP.Data/DbModels/InsManualiModel.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.EntityFrameworkCore; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -35,11 +36,13 @@ namespace MP.Data.DbModels /// /// Tempo Ciclo std /// + [Precision(18, 6)] public decimal TCiclo { get; set; } = 0; /// /// Minuti prodotti (da TC e pz prod /// + [Precision(18, 6)] public decimal MinProd { get; set; } = 0; /// @@ -50,7 +53,7 @@ namespace MP.Data.DbModels [NotMapped] public bool IsWork { - get => IdxTipoEv == 1; + get => IdxTipoEv == 1; } diff --git a/MP.Data/DbModels/ODLExpModel.cs b/MP.Data/DbModels/ODLExpModel.cs index 6c6d5b45..1517d9d8 100644 --- a/MP.Data/DbModels/ODLExpModel.cs +++ b/MP.Data/DbModels/ODLExpModel.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.EntityFrameworkCore; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -19,7 +20,9 @@ namespace MP.Data.DbModels public string CodArticolo { get; set; } = ""; public string IdxMacchina { get; set; } public int NumPezzi { get; set; } + [Precision(18, 6)] public decimal Tcassegnato { get; set; } + [Precision(18, 6)] public decimal TCRichAttr { get; set; } public DateTime? DataInizio { get; set; } public DateTime? DataFine { get; set; } diff --git a/MP.Data/DbModels/ODLModel.cs b/MP.Data/DbModels/ODLModel.cs index caaf0845..0bfff032 100644 --- a/MP.Data/DbModels/ODLModel.cs +++ b/MP.Data/DbModels/ODLModel.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.EntityFrameworkCore; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -21,6 +22,7 @@ namespace MP.Data.DbModels [MaxLength(50)] public string IdxMacchina { get; set; } public int NumPezzi { get; set; } + [Precision(18, 6)] public decimal Tcassegnato { get; set; } public DateTime? DataInizio { get; set; } public DateTime? DataFine { get; set; } diff --git a/MP.Data/DbModels/PODLExpModel.cs b/MP.Data/DbModels/PODLExpModel.cs index e4590159..7b8fecd0 100644 --- a/MP.Data/DbModels/PODLExpModel.cs +++ b/MP.Data/DbModels/PODLExpModel.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.EntityFrameworkCore; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -28,6 +29,7 @@ namespace MP.Data.DbModels [MaxLength(50)] public string IdxMacchina { get; set; } public int NumPezzi { get; set; } = 1; + [Precision(18, 6)] public decimal Tcassegnato { get; set; } = 1; public DateTime? DueDate { get; set; } public int Priorita { get; set; } = 1; diff --git a/MP.Data/DbModels/PODLModel.cs b/MP.Data/DbModels/PODLModel.cs index 818c5235..66d79107 100644 --- a/MP.Data/DbModels/PODLModel.cs +++ b/MP.Data/DbModels/PODLModel.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.EntityFrameworkCore; +using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; @@ -29,6 +30,7 @@ namespace MP.Data.DbModels [MaxLength(50)] public string IdxMacchina { get; set; } public int NumPezzi { get; set; } = 1; + [Precision(18, 6)] public decimal Tcassegnato { get; set; } = 1; public DateTime? DueDate { get; set; } public int Priorita { get; set; } = 1; diff --git a/MP.Data/DbModels/TksScoreModel.cs b/MP.Data/DbModels/TksScoreModel.cs index d90efb2d..12fdfe78 100644 --- a/MP.Data/DbModels/TksScoreModel.cs +++ b/MP.Data/DbModels/TksScoreModel.cs @@ -1,4 +1,5 @@ -using System.ComponentModel.DataAnnotations; +using Microsoft.EntityFrameworkCore; +using System.ComponentModel.DataAnnotations; // // This is here so CodeMaid doesn't reorganize this document @@ -24,6 +25,7 @@ namespace MP.Data.DbModels /// /// Score Cicli Associati /// + [Precision(18, 6)] public decimal ChildScore { get; set; } = 0; /// /// Score complessivo diff --git a/MP.Data/MoonPro_VocContext.cs b/MP.Data/MoonPro_VocContext.cs index ca357a74..441d5e1b 100644 --- a/MP.Data/MoonPro_VocContext.cs +++ b/MP.Data/MoonPro_VocContext.cs @@ -1,7 +1,4 @@ -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.Extensions.Configuration; +using Microsoft.EntityFrameworkCore; using MP.Data.DbModels; using NLog; @@ -17,16 +14,16 @@ namespace MP.Data private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); - private IConfiguration _configuration; + //private IConfiguration _configuration; #endregion Private Fields #region Public Constructors - public MoonPro_VocContext(IConfiguration configuration) - { - _configuration = configuration; - } + //public MoonPro_VocContext(IConfiguration configuration) + //{ + // _configuration = configuration; + //} public MoonPro_VocContext(DbContextOptions options) : base(options) { @@ -52,11 +49,16 @@ namespace MP.Data protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { + //if (!optionsBuilder.IsConfigured) + //{ + // string connString = _configuration.GetConnectionString("MP.Voc"); + + // optionsBuilder.UseSqlServer(connString); + //} if (!optionsBuilder.IsConfigured) { - string connString = _configuration.GetConnectionString("MP.Voc"); - - optionsBuilder.UseSqlServer(connString); + // fallback si spera non necessario + optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=MoonPro;Trusted_Connection=True;"); } } diff --git a/MP.Data/Services/BaseServ.cs b/MP.Data/Services/BaseServ.cs index 51355686..770df68e 100644 --- a/MP.Data/Services/BaseServ.cs +++ b/MP.Data/Services/BaseServ.cs @@ -161,7 +161,7 @@ namespace MP.Data.Services /// protected static readonly ActivitySource ActivitySource = new ActivitySource("MP.IOC"); - protected static IConfiguration _configuration = null!; + protected IConfiguration _configuration = null!; /// /// Abilitazione operazioni tracing generiche diff --git a/MP.Data/Services/LandDataService.cs b/MP.Data/Services/LandDataService.cs index 453c45ff..a94c0634 100644 --- a/MP.Data/Services/LandDataService.cs +++ b/MP.Data/Services/LandDataService.cs @@ -40,12 +40,6 @@ namespace MP.Data.Services #endregion Public Constructors - #region Public Properties - - public static MpLandController dbController { get; set; } = null!; - - #endregion Public Properties - #region Public Methods /// diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index 13723817..d12186f5 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2606.119 + 8.16.2606.311 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index 805e9ef3..aff20529 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                                                                            Versione: 8.16.2606.119

                                                                                            +

                                                                                            Versione: 8.16.2606.311


                                                                                            Note di rilascio:
                                                                                            • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index 28d1df86..aa5451d0 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.119 +8.16.2606.311 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index 635c7a5f..5e64eb24 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.119 + 8.16.2606.311 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 56eeddca..88739b41 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2606.119 + 8.16.2606.311 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 03c738b7..55fd6939 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                                                              Versione: 8.16.2606.119

                                                                                              +

                                                                                              Versione: 8.16.2606.311


                                                                                              Note di rilascio:
                                                                                              • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 28d1df86..aa5451d0 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.119 +8.16.2606.311 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index d3e771b6..92f155e7 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.119 + 8.16.2606.311 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 2d7b8b5e..508b0702 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2606.0119 + 8.16.2606.0312 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 17946008..a19361ad 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                                                                Versione: 8.16.2606.0119

                                                                                                +

                                                                                                Versione: 8.16.2606.0312


                                                                                                Note di rilascio:
                                                                                                  diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index 8bc36859..b505b6b3 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0119 +8.16.2606.0312 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index 5a0155ac..c16761d9 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0119 + 8.16.2606.0312 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.Land/Startup.cs b/MP.Land/Startup.cs index 77b74a07..b8b345a7 100644 --- a/MP.Land/Startup.cs +++ b/MP.Land/Startup.cs @@ -2,25 +2,21 @@ using Blazored.LocalStorage; using Blazored.SessionStorage; using Microsoft.AspNetCore.Authentication.Negotiate; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpOverrides; -using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Localization; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using MP.AppAuth.Services; -using MP.Data.Services; +using MP.Data; using MP.Land.Data; using MP.TaskMan.Services; using StackExchange.Redis; using System; -using System.Collections.Generic; -using System.Configuration; using System.Globalization; -using System.Linq; -using System.Threading.Tasks; namespace MP.Land { @@ -138,12 +134,24 @@ namespace MP.Land services.AddServerSideBlazor(); services.AddSingleton(Configuration); + + // aggiungo il costruttore x i vari DbContextFactory + var connStr = Configuration.GetConnectionString("MP.Land") + ?? throw new InvalidOperationException("ConnString 'MP.Land' mancante."); + services.AddDbContextFactory(options => + options.UseSqlServer(connStr) + .EnableSensitiveDataLogging(false) // true solo in Sviluppo + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); + + //init servizi specifici LAND + //services.AddAuthLandDataLayer(); + services.AddLandDataLayer(); services.AddSingleton(); - services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(); + //services.AddSingleton(); + //services.AddSingleton(); + //services.AddSingleton(); services.AddScoped(); services.AddScoped(); diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index 2a883698..1d8ab17b 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2606.119 + 8.16.2606.312 diff --git a/MP.MON/Program.cs b/MP.MON/Program.cs index ad200407..20e4cd80 100644 --- a/MP.MON/Program.cs +++ b/MP.MON/Program.cs @@ -1,3 +1,6 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using MP.Data; using MP.Data.Services; using MP.MON.Components; using NLog; @@ -26,10 +29,21 @@ string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":")) // avvio oggetto shared x redis... var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); +// aggiungo il costruttore x i vari DbContextFactory +var connStr = builder.Configuration.GetConnectionString("MP.Mon") + ?? throw new InvalidOperationException("ConnString 'MP.Mon' mancante."); +builder.Services.AddDbContextFactory(options => + options.UseSqlServer(connStr) + .EnableSensitiveDataLogging(false) // true solo in Sviluppo + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); + // Add services to the container. logger.Info("Setup Services"); + builder.Services.AddSingleton(redisMultiplexer); -builder.Services.AddSingleton(); +// Init centralizzato Repository/Servizi da MP.Data Services +builder.Services.AddMonDataLayer(); + var app = builder.Build(); diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 7e42922e..81ed3f86 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                                                  Versione: 8.16.2606.119

                                                                                                  +

                                                                                                  Versione: 8.16.2606.312


                                                                                                  Note di rilascio:
                                                                                                  • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 28d1df86..1b236191 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.119 +8.16.2606.312 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index ebd7fc6e..ef808f77 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.119 + 8.16.2606.312 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.MON/appsettings.json b/MP.MON/appsettings.json index c9f20d06..5b692c2d 100644 --- a/MP.MON/appsettings.json +++ b/MP.MON/appsettings.json @@ -2,7 +2,9 @@ "Logging": { "LogLevel": { "Default": "Information", - "Microsoft.AspNetCore": "Warning" + "Microsoft.AspNetCore": "Warning", + "Microsoft.EntityFrameworkCore": "Warning", + "Microsoft.EntityFrameworkCore.Database.Command": "Warning" } }, "NLog": { diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index e1e72fa3..82cdeb00 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2606.0119 + 8.16.2606.0310 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index c430a648..03a88103 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                                                                                    Versione: 8.16.2606.0119

                                                                                                    +

                                                                                                    Versione: 8.16.2606.0310


                                                                                                    Note di rilascio:
                                                                                                      diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 8bc36859..6970c00b 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0119 +8.16.2606.0310 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index b57cd977..70ae7425 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0119 + 8.16.2606.0310 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index a159eed4..7bc99308 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2606.119 + 8.16.2606.311 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index c1503a5c..0271b927 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                                                                      Versione: 8.16.2606.119

                                                                                                      +

                                                                                                      Versione: 8.16.2606.311


                                                                                                      Note di rilascio:
                                                                                                      • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index 28d1df86..aa5451d0 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.119 +8.16.2606.311 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index 8ddc1c1b..9fb2ac1c 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.119 + 8.16.2606.311 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/appsettings.json b/MP.RIOC/appsettings.json index 590b8fb4..2c648666 100644 --- a/MP.RIOC/appsettings.json +++ b/MP.RIOC/appsettings.json @@ -3,7 +3,9 @@ "LogLevel": { "Default": "Information", "Yarp": "Debug", - "Microsoft.AspNetCore": "Warning" + "Microsoft.AspNetCore": "Warning", + "Microsoft.EntityFrameworkCore": "Warning", + "Microsoft.EntityFrameworkCore.Database.Command": "Warning" } }, "AllowedHosts": "*", diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 3e0b2962..951addc4 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -31,10 +31,27 @@ namespace MP.SPEC.Data private readonly IFluxLogRepository _fluxLogRepository; private readonly IProductionRepository _productionRepository; - public MpDataService(IConfiguration configuration, IFusionCache cache, IAnagRepository anagRepository, ISystemRepository systemRepository, IDossierRepository dossierRepository, IFluxLogRepository fluxLogRepository, IProductionRepository productionRepository) + public MpDataService(IConnectionMultiplexer connMPlex, IConfiguration configuration, IFusionCache cache, IAnagRepository anagRepository, ISystemRepository systemRepository, IDossierRepository dossierRepository, IFluxLogRepository fluxLogRepository, IProductionRepository productionRepository) { // salvataggio oggetti _configuration = configuration; + redisConn = connMPlex; + redisDb = redisConn.GetDatabase(); + +#if false + // setup compoenti REDIS + redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis") ?? "localhost:6379"); + redisConnAdmin = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("RedisAdmin") ?? "localhost:6379"); + redisDb = redisConn.GetDatabase(); +#endif + // leggo cache lungo/cordo periodo + int.TryParse(_configuration.GetValue("ServerConf:redisShortTimeCache"), out redisShortTimeCache); + int.TryParse(_configuration.GetValue("ServerConf:redisLongTimeCache"), out redisLongTimeCache); + + // setup MsgPipe + BroadastMsgPipe = new MessagePipe(redisConn, Constants.BROADCAST_M_PIPE); + Log.Info("MpDataService | Redis OK"); + _cache = cache; _anagRepository = anagRepository; _systemRepository = systemRepository; @@ -524,7 +541,7 @@ namespace MP.SPEC.Data { // Clear database controller mongoController.Dispose(); - redisConn.Dispose(); + //redisConn.Dispose(); } /// @@ -2009,7 +2026,7 @@ namespace MP.SPEC.Data /// /// Oggetto per connessione a REDIS /// - private ConnectionMultiplexer redisConn = null!; + private IConnectionMultiplexer redisConn = null!; /// /// Oggetto per connessione a REDIS modalità admin (ex flux dati) diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 2952fe88..85941120 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2606.119 + 8.16.2606.311 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Program.cs b/MP.SPEC/Program.cs index 36036cdd..64fd379e 100644 --- a/MP.SPEC/Program.cs +++ b/MP.SPEC/Program.cs @@ -3,6 +3,7 @@ using Microsoft.AspNetCore.StaticFiles; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.Caching.Distributed; +using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.FileProviders; using MP.Data; using MP.SPEC.Components; @@ -159,19 +160,23 @@ builder.Services.AddFusionCache() // Metodi principali x accesso dati var connStr = builder.Configuration.GetConnectionString("MP.Data") ?? throw new InvalidOperationException("ConnString 'MP.Data' mancante."); -// aggiungo il costruttore x i DbContextFactory +// aggiungo il costruttore x i vari DbContextFactory builder.Services.AddDbContextFactory(options => options.UseSqlServer(connStr) .EnableSensitiveDataLogging(false) // true solo in Sviluppo .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); +builder.Services.AddDbContextFactory(options => + options.UseSqlServer(connStr) + .EnableSensitiveDataLogging(false) // true solo in Sviluppo + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); // MP.Data Services Utils - Statistiche DB builder.Services.AddSpecDataLayer(); -// altri servizi -builder.Services.AddSingleton(); -builder.Services.AddSingleton(); -builder.Services.AddScoped(); +// servizi del progetto SPEC +builder.Services.TryAddScoped(); +builder.Services.TryAddSingleton(); +builder.Services.TryAddScoped(); #if false builder.Services.AddSingleton(); diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 7e42922e..40cd97d7 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                                                        Versione: 8.16.2606.119

                                                                                                        +

                                                                                                        Versione: 8.16.2606.311


                                                                                                        Note di rilascio:
                                                                                                        • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 28d1df86..aa5451d0 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.119 +8.16.2606.311 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 5cb1e4dd..c283f196 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.119 + 8.16.2606.311 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/appsettings.json b/MP.SPEC/appsettings.json index 683abe14..594aca27 100644 --- a/MP.SPEC/appsettings.json +++ b/MP.SPEC/appsettings.json @@ -3,6 +3,8 @@ "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning", + "Microsoft.EntityFrameworkCore": "Warning", + "Microsoft.EntityFrameworkCore.Database.Command": "Warning", "ZiggyCreatures.Caching.Fusion": "Warning" } }, diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 1ff2dc91..73e0c184 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2606.0119 + 8.16.2606.0311 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index 16ce0ff0..7ee0c500 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                                                                                          Versione: 8.16.2606.0119

                                                                                                          +

                                                                                                          Versione: 8.16.2606.0311


                                                                                                          Note di rilascio:
                                                                                                            diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 8bc36859..4143bf31 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0119 +8.16.2606.0311 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index d9cde985..7a375362 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0119 + 8.16.2606.0311 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false From 9055eaf73ce0e7e057e3d0d8132f90db5be884a5 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 3 Jun 2026 18:05:59 +0200 Subject: [PATCH 096/102] SPEC: - aggiunta pagina operatori - completato fix --- MP.AppAuth/MoonProContext.cs | 3 +- MP.Core/Utils.cs | 1 + MP.Data/Controllers/MpIocController.cs | 223 +++++++++--------- MP.Data/Controllers/MpLandController.cs | 170 +++++++------ MP.Data/Controllers/MpSpecRepository.cs | 153 ++++++------ MP.Data/Controllers/MpStatsController.cs | 60 +++-- MP.Data/DataServiceCollectionExtensions.cs | 41 +++- MP.Data/DbModels/TksScoreModel.cs | 1 + MP.Data/MoonPro_FluxContext.cs | 17 +- MP.Data/MoonPro_STATSContext.cs | 13 +- MP.Data/Repository/Anag/AnagRepository.cs | 34 +++ MP.Data/Repository/Anag/IAnagRepository.cs | 22 +- .../Repository/Dossier/DossierRepository.cs | 61 +++-- .../Repository/FluxLog/FluxLogRepository.cs | 35 +-- MP.Data/Repository/MpLand/MpLandRepository.cs | 21 +- MP.Data/Repository/MpVoc/IMpVocRepository.cs | 29 ++- MP.Data/Repository/MpVoc/MpVocRepository.cs | 39 ++- .../Production/IProductionRepository.cs | 1 + .../Production/ProductionRepository.cs | 24 +- MP.Data/Services/BaseServ.cs | 117 ++++++++- MP.Data/Services/IOC/IocService.cs | 34 ++- MP.Data/Services/LandDataService.cs | 18 +- MP.Data/Services/ListSelectDataSrv.cs | 10 +- MP.Data/Services/Mtc/MtcSetupService.cs | 4 +- MP.Data/Services/OrderDataSrv.cs | 9 +- MP.Data/Services/SchedulerDataService.cs | 7 +- MP.Data/Services/SharedMemService.cs | 7 +- MP.Data/Services/TabDataService.cs | 11 +- MP.Data/Services/TranslateSrv.cs | 200 ++++++++++------ MP.Data/Services/Utils/StatsAggrService.cs | 4 +- MP.Data/Services/Utils/StatsCodeService.cs | 5 +- MP.Data/Services/Utils/StatsDetailService.cs | 5 +- MP.Data/Services/Utils/StatsErrService.cs | 5 +- MP.SPEC/Components/AskCloseOdl.razor.cs | 3 +- .../Components/Reparti/ListOperatori.razor | 49 +++- .../Components/Reparti/ListOperatori.razor.cs | 52 +++- MP.SPEC/Components/Reparti/ListReparti.razor | 40 ++-- .../Components/Reparti/ListReparti.razor.cs | 3 + MP.SPEC/Data/MpDataService.cs | 33 +++ MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Operatori.razor | 41 ++++ MP.SPEC/Pages/Operatori.razor.cs | 66 ++++++ MP.SPEC/Program.cs | 9 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 46 files changed, 1161 insertions(+), 527 deletions(-) create mode 100644 MP.SPEC/Pages/Operatori.razor create mode 100644 MP.SPEC/Pages/Operatori.razor.cs diff --git a/MP.AppAuth/MoonProContext.cs b/MP.AppAuth/MoonProContext.cs index 6a1d615d..03219310 100644 --- a/MP.AppAuth/MoonProContext.cs +++ b/MP.AppAuth/MoonProContext.cs @@ -18,11 +18,12 @@ namespace MP.AppAuth #region Public Constructors - [Obsolete("This constructor should never be used directly, and is only needed to generate entityframework stuff. Connection string can be adapted as pleased.")] + [Obsolete("This constructor should never be used directly, and is only needed to generate entityframework stuff. DbContextOptions must be supplied.")] public MoonProContext() { } + [Obsolete("This constructor should never be used directly, and is only needed to generate entityframework stuff. DbContextOptions must be supplied.")] public MoonProContext(IConfiguration configuration) { _configuration = configuration; diff --git a/MP.Core/Utils.cs b/MP.Core/Utils.cs index b138599a..5af55b84 100644 --- a/MP.Core/Utils.cs +++ b/MP.Core/Utils.cs @@ -12,6 +12,7 @@ namespace MP.Core public const string redisAnagGruppi = redisBaseAddr + "Cache:AnagGruppi"; public const string redisAnagStati = redisBaseAddr + "Cache:AnagStati"; + public const string redisAnagGruppiOpr = redisBaseAddr + "Cache:GrpByOpr"; public const string redisArtByDossier = redisBaseAddr + "Cache:ArtByDossier"; public const string redisArtList = redisBaseAddr + "Cache:ArtList"; diff --git a/MP.Data/Controllers/MpIocController.cs b/MP.Data/Controllers/MpIocController.cs index c452739b..6502ccf6 100644 --- a/MP.Data/Controllers/MpIocController.cs +++ b/MP.Data/Controllers/MpIocController.cs @@ -15,15 +15,30 @@ namespace MP.Data.Controllers { public class MpIocController { + protected readonly IDbContextFactory _ctxFactory; + protected readonly IDbContextFactory _ctxFactoryFL; #region Public Constructors - public MpIocController(IConfiguration configuration) + public MpIocController( + IConfiguration configuration, + IDbContextFactory ctxFactory, + IDbContextFactory ctxFactoryFL) { - _configuration = configuration; - string connStr = _configuration.GetConnectionString("MP.Data"); +#if false + _configuration = configuration; +#endif + _ctxFactory = ctxFactory; + _ctxFactoryFL = ctxFactoryFL; +#if false + string connStr = configuration.GetConnectionString("MP.Data"); options = new DbContextOptionsBuilder() .UseSqlServer(connStr) + .Options; + string connStrFlux = configuration.GetConnectionString("MP.Flux"); + optionsFlux = new DbContextOptionsBuilder() + .UseSqlServer(connStrFlux) .Options; +#endif Log.Info("Avviata classe MpIocController"); } @@ -43,7 +58,7 @@ namespace MP.Data.Controllers /// public async Task AlarmLogInsertAsync(DateTime dtRif, string machineId, string memAddress, int memIndex, int statusVal, string valDecoded) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var DtRif = new SqlParameter("@DtRif", dtRif); var MachineId = new SqlParameter("@MachineId", machineId); @@ -63,7 +78,7 @@ namespace MP.Data.Controllers /// public async Task> AnagStatiGetAllAsync() { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var dbResult = await dbCtx .DbSetAnagStati @@ -81,7 +96,7 @@ namespace MP.Data.Controllers /// public async Task> ArticoliGetLastByMaccAsync(string idxMacc) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacc); var dbResult = await dbCtx @@ -107,7 +122,7 @@ namespace MP.Data.Controllers /// public async Task AutoStartOdlAsync(int idxOdl, int MatrOpr, string idxMacchina, decimal tCRich, int pzPallet, string note, bool startNewOdl, int qtyRich, string keyRich) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxOdl = new SqlParameter("@idxOdl ", idxOdl); var MatrApp = new SqlParameter("@MatrApp ", MatrOpr); @@ -138,7 +153,7 @@ namespace MP.Data.Controllers /// public async Task CheckCambiaStatoBatchAsync(tipoInputEvento tipoInput, string IdxMacchina, DateTime InizioStato, int IdxTipo, string CodArt, string Value, int MatrOpr, string pallet) { - await using var dbCtx = new MoonProContext(options); + await using var dbCtx = _ctxFactory.CreateDbContext(); //await using var tx = await dbCtx.Database.BeginTransactionAsync(); try @@ -224,7 +239,7 @@ namespace MP.Data.Controllers /// public async Task ConfermaProdMacchinaAsync(string idxMacchina, int modoConfProd, int numPzConfermati, int numPzScarto, DateTime DataOraApp, int MatrOpr) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); var DataOra = new SqlParameter("@DataOra ", DateTime.Now); @@ -267,7 +282,7 @@ namespace MP.Data.Controllers /// public async Task ConfermaProdMacchinaFullAsync(string idxMacchina, int modoConfProd, int numPzConfermati, int numPzLasciati, int numPzScarto, DateTime DataOraApp, int MatrOpr) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); var DataOra = new SqlParameter("@DataOra ", DateTime.Now); @@ -306,7 +321,7 @@ namespace MP.Data.Controllers /// public async Task> ConfFluxFiltAsync(string idxMacc) { - using var dbCtx = new MoonPro_FluxContext(_configuration); + using var dbCtx = _ctxFactoryFL.CreateDbContext(); var query = dbCtx.DbSetConfFlux .AsNoTracking() @@ -326,7 +341,7 @@ namespace MP.Data.Controllers /// public async Task> ConfigGetAllAsync() { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var dbResult = await dbCtx .DbSetConfig @@ -343,7 +358,7 @@ namespace MP.Data.Controllers /// public async Task ConfigUpdateAsync(ConfigModel updRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); bool fatto = false; var dbResult = await dbCtx @@ -365,7 +380,7 @@ namespace MP.Data.Controllers /// public async Task> DatiMacchineGetAllAsync() { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var dbResult = await dbCtx .DbSetDatiMacchine @@ -388,7 +403,7 @@ namespace MP.Data.Controllers /// public async Task DDB_InsStatoBatchAsync(string idxMacchina, DateTime inizioStato, int idxStato, string codArt, string value, int matrOpr, string pallet) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); var InizioStato = new SqlParameter("@InizioStato", inizioStato); @@ -411,7 +426,7 @@ namespace MP.Data.Controllers /// public async Task> DecNumArtGetFiltAsync(string codArt = "") { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var query = dbCtx.DbSetDecNumArt .AsNoTracking() @@ -432,17 +447,13 @@ namespace MP.Data.Controllers /// public async Task> DossGetLastByMaccAsync(string idxMacc) { - List dbResult = new(); - using (var dbCtx = new MoonPro_FluxContext(_configuration)) - { - var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacc); - dbResult = await dbCtx - .DbSetDossiers - .FromSqlRaw("exec dbo.stp_DOSS_getLastByMacch @idxMacchina", IdxMacchina) - .AsNoTracking() - .ToListAsync(); - } - return dbResult; + using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); + var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacc); + return await dbCtx + .DbSetDossiers + .FromSqlRaw("exec dbo.stp_DOSS_getLastByMacch @idxMacchina", IdxMacchina) + .AsNoTracking() + .ToListAsync(); } /// @@ -452,7 +463,7 @@ namespace MP.Data.Controllers /// public async Task EvListInsertAsync(EventListModel newRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); dbCtx.DbSetEvList.Add(newRec); return await dbCtx.SaveChangesAsync() > 0; @@ -467,7 +478,7 @@ namespace MP.Data.Controllers public async Task EvListMicroStatoInsertAsync(MicroStatoMacchinaModel newRecMsm, EventListModel newRecEv) { // eseguo in transazione... - await using var dbCtx = new MoonProContext(options); + await using var dbCtx = _ctxFactory.CreateDbContext(); await using var tx = await dbCtx.Database.BeginTransactionAsync(); try @@ -518,18 +529,15 @@ namespace MP.Data.Controllers /// public async Task> FluxLogFirstByMaccAsync(string idxMacc, int numMax) { - List dbResult = new(); - - using var dbCtx = new MoonPro_FluxContext(_configuration); + using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacc); var NumMax = new SqlParameter("@numMax", numMax); - dbResult = await dbCtx - .DbSetFluxLog - .FromSqlRaw("exec dbo.stp_FL_getFirstByMacc @IdxMacchina, @numMax", IdxMacchina, NumMax) - .AsNoTracking() - .ToListAsync(); - return dbResult; + return await dbCtx + .DbSetFluxLog + .FromSqlRaw("exec dbo.stp_FL_getFirstByMacc @IdxMacchina, @numMax", IdxMacchina, NumMax) + .AsNoTracking() + .ToListAsync(); } /// @@ -543,17 +551,15 @@ namespace MP.Data.Controllers /// public async Task> FluxLogGetLastFiltAsync(DateTime DtMax, DateTime DtMin, string IdxMacchina, string CodFlux, int MaxRec) { - List dbResult = new List(); - using var dbCtx = new MoonPro_FluxContext(_configuration); + using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); - dbResult = await dbCtx - .DbSetFluxLog - .AsNoTracking() - .Where(x => (x.dtEvento >= DtMin && x.dtEvento <= DtMax) && (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && (CodFlux == "*" || x.CodFlux == CodFlux)) - .OrderByDescending(x => x.dtEvento) - .Take(MaxRec) - .ToListAsync(); - return dbResult; + return await dbCtx + .DbSetFluxLog + .AsNoTracking() + .Where(x => (x.dtEvento >= DtMin && x.dtEvento <= DtMax) && (IdxMacchina == "*" || x.IdxMacchina == IdxMacchina) && (CodFlux == "*" || x.CodFlux == CodFlux)) + .OrderByDescending(x => x.dtEvento) + .Take(MaxRec) + .ToListAsync(); } /// @@ -563,15 +569,13 @@ namespace MP.Data.Controllers /// public async Task FluxLogInsertAsync(FluxLogModel newRec) { - bool fatto = false; - using var dbCtx = new MoonPro_FluxContext(_configuration); + using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); var currRec = dbCtx - .DbSetFluxLog - .Add(newRec); - await dbCtx.SaveChangesAsync(); + .DbSetFluxLog + .Add(newRec); + return await dbCtx.SaveChangesAsync()>0; - return fatto; } /// @@ -581,8 +585,7 @@ namespace MP.Data.Controllers /// public async Task FluxLogTakeSnapshotLastAsync(string idxMacc, DateTime dataInizio, DateTime dataFine) { - bool fatto = false; - using var dbCtx = new MoonPro_FluxContext(_configuration); + using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacc); var DataInizio = new SqlParameter("@DtMin", dataInizio); @@ -591,8 +594,7 @@ namespace MP.Data.Controllers var result = await dbCtx .Database .ExecuteSqlRawAsync("EXEC stp_FL_TakeSnapshotLast @IdxMacchina, @DtMin, @DtMax", IdxMacchina, DataInizio, DataFine); - fatto = result > 0; - return fatto; + return result > 0; } /// @@ -605,7 +607,7 @@ namespace MP.Data.Controllers public async Task KeepAliveUpsertAsync(string IdxMacc, DateTime OraServer, DateTime OraMacc) { bool fatto = false; - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var currRec = await dbCtx .DbSetKeepAlive @@ -638,7 +640,7 @@ namespace MP.Data.Controllers public async Task> ListLinkFiltAsync(string tipoLink) { List dbResult = new List(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); dbResult = await dbCtx .DbSetLinkMenu @@ -658,7 +660,7 @@ namespace MP.Data.Controllers public async Task> ListValuesFiltAsync(string tabName, string fieldName) { List dbResult = new List(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var query = dbCtx .DbSetListValues @@ -682,7 +684,7 @@ namespace MP.Data.Controllers public async Task> Macchine2SlaveAsync() { List dbResult = new List(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); dbResult = await dbCtx .DbSetM2S @@ -700,7 +702,7 @@ namespace MP.Data.Controllers public async Task> MacchineGetAllAsync() { List dbResult = new List(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); dbResult = await dbCtx .DbSetMacchine @@ -712,7 +714,7 @@ namespace MP.Data.Controllers public async Task MacchineGetByIdxAsync(string IdxMacchina) { MacchineModel dbResult = null; - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); dbResult = await dbCtx .DbSetMacchine @@ -729,7 +731,7 @@ namespace MP.Data.Controllers public async Task> MacchineGetFiltAsync(string codGruppo) { List dbResult = new List(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); if (codGruppo == "*") { @@ -763,7 +765,7 @@ namespace MP.Data.Controllers /// public async Task MacchineUpsertAsync(MacchineModel entity) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); // Recuperiamo l'entità tracciata dal context var trackedEntity = await dbCtx @@ -791,7 +793,7 @@ namespace MP.Data.Controllers public async Task> MicroStatoMacchinaGetByIdxMaccAsync(string IdxMacc) { List dbResult = new List(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); dbResult = await dbCtx .DbSetMicroStatoMacc @@ -809,7 +811,7 @@ namespace MP.Data.Controllers public async Task MicroStatoMacchinaUpsertAsync(MicroStatoMacchinaModel newRec) { bool fatto = false; - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var actRec = await dbCtx .DbSetMicroStatoMacc @@ -842,7 +844,7 @@ namespace MP.Data.Controllers public async Task> MseGetAllAsync(int maxAge = 2000) { List dbResult = new List(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var maxAgeSec = new SqlParameter("@maxAgeSec", maxAge); @@ -862,7 +864,7 @@ namespace MP.Data.Controllers /// public async Task OdlAutoDayGenAsync(string idxMacchina, DateTime dataInizio, DateTime dataFine, string codArticolo) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); var DataInizio = new SqlParameter("@DataInizio", dataInizio); @@ -884,7 +886,7 @@ namespace MP.Data.Controllers /// public async Task OdlAutoDayGenFullAsync(string idxMacchina, DateTime dataInizio, DateTime dataFine, string codArticolo, int? pzPODL, int? pzPallet, string? keyRichiesta, int? tcAssegnato, string? codGruppo, bool flgCreaPODL, bool flgCheckTC) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); var DataInizio = new SqlParameter("@DataInizio", dataInizio); @@ -913,7 +915,7 @@ namespace MP.Data.Controllers public async Task OdlCurrByMaccAsync(string idxMacchina) { ODLExpModel answ = new(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); // attenzione: se la stored resituisce una tabella, il primo elemento va recuperato in RAM!!! @@ -936,7 +938,7 @@ namespace MP.Data.Controllers /// public async Task OdlFixMachineSlave(string idxMacchina, int numDayPrev, int doInsert) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var idxMaccParam = new SqlParameter("@IdxMacchina", idxMacchina ?? ""); var numDayPrevParam = new SqlParameter("@NumDayPrev", numDayPrev); @@ -958,7 +960,7 @@ namespace MP.Data.Controllers /// public async Task OdlFixMachineSlaveAsync(string idxMacchina, int numDayPrev, int doInsert) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina); var NumDayPrev = new SqlParameter("@NumDayPrev", numDayPrev); @@ -977,7 +979,7 @@ namespace MP.Data.Controllers public async Task OdlLastByMaccAsync(string idxMacchina) { ODLExpModel answ = new(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); // attenzione: se la stored resituisce una tabella, il primo elemento va recuperato in RAM!!! @@ -1001,7 +1003,7 @@ namespace MP.Data.Controllers public async Task> OdlListByMaccPeriodoAsync(string idxMacchina, DateTime dtStart, DateTime dtEnd) { List dbResult = new List(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); var DataFrom = new SqlParameter("@dataFrom", dtStart); @@ -1023,7 +1025,7 @@ namespace MP.Data.Controllers public async Task PezziProdMacchinaAsync(string idxMacchina) { PzProdModel dbResult = new PzProdModel(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); dbResult = (await dbCtx @@ -1046,7 +1048,7 @@ namespace MP.Data.Controllers public async Task> POdlGetByMaccArtAsync(string idxMacchina, string codArticolo, string codGruppo, bool onlyFree) { List dbResult = new List(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); var pCodArticolo = new SqlParameter("@CodArticolo", codArticolo); @@ -1069,7 +1071,7 @@ namespace MP.Data.Controllers /// public async Task RecalcMseAsync(string idxMacchina, int maxAgeSec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var rigaProd = await StatoProdMacchinaAsync(idxMacchina, DateTime.Now); var MaxAgeSec = new SqlParameter("@maxAgeSec ", maxAgeSec); @@ -1093,7 +1095,7 @@ namespace MP.Data.Controllers /// public async Task RegControlliInsertAsync(string idxMacchina, int matrOpr, bool esitoOk, string note, DateTime dataOra) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxMacc = new SqlParameter("@IdxMacchina", idxMacchina); var MatrOpr = new SqlParameter("@MatrOpr", matrOpr); @@ -1114,7 +1116,7 @@ namespace MP.Data.Controllers /// public async Task RegDichiarInsertAsync(RegistroDichiarazioniModel newRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var TagCode = new SqlParameter("@TagCode", newRec.TagCode); var IdxMacchina = new SqlParameter("@IdxMacchina", newRec.IdxMacchina); @@ -1136,7 +1138,7 @@ namespace MP.Data.Controllers /// public async Task RegDichiarUpdateAsync(RegistroDichiarazioniModel newRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var Original_IdxDich = new SqlParameter("@Original_IdxDich", newRec.IdxDich); var DtRec = new SqlParameter("@DtRec", newRec.DtRec); @@ -1157,7 +1159,7 @@ namespace MP.Data.Controllers /// public async Task RegScartiInsertAsync(RegistroScartiModel newRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxMacchina = new SqlParameter("@idxMacchina", newRec.IdxMacchina); var DataOra = new SqlParameter("@DataOra", newRec.DataOra); @@ -1184,7 +1186,7 @@ namespace MP.Data.Controllers public async Task RemRebootLogAddAndCleanAsync(RemoteRebootLogModel newRec, bool doClean, int num2keep) { bool fatto = false; - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); // 1. Transazione minima: SOLO INSERT + COMMIT await using var tx = await dbCtx.Database.BeginTransactionAsync(); @@ -1227,7 +1229,7 @@ namespace MP.Data.Controllers /// public async Task RemRebootLogAddAsync(RemoteRebootLogModel newRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var dbResult = dbCtx .DbSetRemRebLog @@ -1242,7 +1244,7 @@ namespace MP.Data.Controllers /// public async Task> RemRebootLogGetAllAsync() { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var dbResult = await dbCtx .DbSetRemRebLog @@ -1258,7 +1260,7 @@ namespace MP.Data.Controllers /// public async Task> RemRebootLogGetLastAsync() { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var dbResult = await dbCtx .DbSetRemRebLog .FromSqlRaw("EXEC stp_RRL_getLast") @@ -1273,7 +1275,7 @@ namespace MP.Data.Controllers /// public async Task RemRebootLogKeepLastAsync(int num2keep) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var pNum2Keep = new SqlParameter("@num2keep", num2keep); // La SP gestisce già la logica di soglia (1.5x), ma la specifico x sicurezza @@ -1291,7 +1293,7 @@ namespace MP.Data.Controllers /// public async Task SignalLogInsertAsync(SignalLogModel newRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var currRec = dbCtx .DbSetSignalLog @@ -1307,7 +1309,7 @@ namespace MP.Data.Controllers /// public async Task> SMES_getHwTransitionsAsync(string idxMacchina, int idxTipo) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); var IdxTipo = new SqlParameter("@IdxTipo", idxTipo); @@ -1327,7 +1329,7 @@ namespace MP.Data.Controllers /// public async Task> SMES_getUserForcedAsync(string idxMacchina, int idxTipo) { - await using var dbCtx = new MoonProContext(options); + await using var dbCtx = _ctxFactory.CreateDbContext(); var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); var IdxTipo = new SqlParameter("@IdxTipo", idxTipo); @@ -1346,18 +1348,14 @@ namespace MP.Data.Controllers /// public List StateMachineIngressi(int idxFam) { - List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - var IdxFamIn = new SqlParameter("@IdxFamigliaIngresso", idxFam); - dbResult = dbCtx - .DbSetSMI - .FromSqlRaw("exec dbo.stp_TRI_getByIdxFamIng @IdxFamigliaIngresso", IdxFamIn) - .AsNoTracking() - .AsEnumerable() - .ToList(); - } - return dbResult; + using var dbCtx = _ctxFactory.CreateDbContext(); + var IdxFamIn = new SqlParameter("@IdxFamigliaIngresso", idxFam); + return dbCtx + .DbSetSMI + .FromSqlRaw("exec dbo.stp_TRI_getByIdxFamIng @IdxFamigliaIngresso", IdxFamIn) + .AsNoTracking() + .AsEnumerable() + .ToList(); } /// @@ -1366,7 +1364,7 @@ namespace MP.Data.Controllers /// public async Task> StateMachineIngressiAsync(int idxFam) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxFamIn = new SqlParameter("@IdxFamigliaIngresso", idxFam); var dbResult = await dbCtx @@ -1386,7 +1384,7 @@ namespace MP.Data.Controllers /// public async Task StatoProdMacchinaAsync(string idxMacchina, DateTime dtReq) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); var DataOra = new SqlParameter("@DataOra ", dtReq); @@ -1406,7 +1404,7 @@ namespace MP.Data.Controllers /// public async Task> VMSFDGetAllAsync() { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var dbResult = await dbCtx .DbSetMSFD @@ -1424,7 +1422,7 @@ namespace MP.Data.Controllers /// public async Task VMSFDGetByMaccAsync(string idxMacc) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacc); var dbResult = (await dbCtx @@ -1444,7 +1442,7 @@ namespace MP.Data.Controllers /// public async Task> VMSFDGetMultiByMaccAsync(string idxMacc) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var IdxMacchina = new SqlParameter("@IdxMacchina", idxMacc); @@ -1461,9 +1459,14 @@ namespace MP.Data.Controllers #region Private Fields - private static IConfiguration _configuration; +#if false + private static IConfiguration _configuration; +#endif private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); - private DbContextOptions options; +#if false + private DbContextOptions options; +#endif + private DbContextOptions optionsFlux; #endregion Private Fields diff --git a/MP.Data/Controllers/MpLandController.cs b/MP.Data/Controllers/MpLandController.cs index a87c3492..8ab7d25e 100644 --- a/MP.Data/Controllers/MpLandController.cs +++ b/MP.Data/Controllers/MpLandController.cs @@ -15,10 +15,21 @@ namespace MP.Data.Controllers public class MpLandController : IDisposable { #region Public Constructors + protected readonly IDbContextFactory _ctxFactory; + protected readonly IDbContextFactory _ctxFactoryFL; + protected readonly IDbContextFactory _ctxFactorySta; - public MpLandController(IConfiguration configuration) + public MpLandController( + IConfiguration configuration, + IDbContextFactory ctxFactory, + IDbContextFactory ctxFactoryFL, + IDbContextFactory ctxFactorySta) { _configuration = configuration; + _ctxFactory = ctxFactory; + _ctxFactoryFL = ctxFactoryFL; + _ctxFactorySta = ctxFactorySta; +#if false string connStr = _configuration.GetConnectionString("MP.Land"); if (string.IsNullOrEmpty(connStr)) { @@ -26,7 +37,8 @@ namespace MP.Data.Controllers } options = new DbContextOptionsBuilder() .UseSqlServer(connStr) - .Options; + .Options; +#endif Log.Info("Avviato MpLandController"); } @@ -34,6 +46,7 @@ namespace MP.Data.Controllers #region Public Methods +#if false /// /// Restituisce info dimensione, tabelle e num righe DB gestiti /// @@ -70,58 +83,53 @@ namespace MP.Data.Controllers // leggo per DB principale if (!string.IsNullOrEmpty(_configuration.GetConnectionString("MP.All"))) { - using (var dbCtx = new MoonProContext(options)) + using var dbCtx = _ctxFactory.CreateDbContext(); + var singleRes = dbCtx + .DbSetDbSize + .FromSqlRaw(stp_DbInfo) + .AsEnumerable() + .FirstOrDefault(); + if (singleRes != null) { - var singleRes = dbCtx - .DbSetDbSize - .FromSqlRaw(stp_DbInfo) - .AsEnumerable() - .FirstOrDefault(); - if (singleRes != null) - { - dbResult.Add(singleRes); - } + dbResult.Add(singleRes); } } // leggo per FluxLog if (!string.IsNullOrEmpty(_configuration.GetConnectionString("MP.Flux"))) { - using (var dbCtx = new MoonPro_FluxContext(_configuration)) + using var dbCtx = _ctxFactoryFL.CreateDbContext(); + var singleRes = dbCtx + .DbSetDbSize + .FromSqlRaw(stp_DbInfo) + .AsEnumerable() + .FirstOrDefault(); + if (singleRes != null) { - var singleRes = dbCtx - .DbSetDbSize - .FromSqlRaw(stp_DbInfo) - .AsEnumerable() - .FirstOrDefault(); - if (singleRes != null) - { - dbResult.Add(singleRes); - } + dbResult.Add(singleRes); } } // leggo per Stats if (!string.IsNullOrEmpty(_configuration.GetConnectionString("MP.Stats"))) { - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using var dbCtx = _ctxFactorySta.CreateDbContext(); + var singleRes = dbCtx + .DbSetDbSize + .FromSqlRaw(stp_DbInfo) + .AsEnumerable() + .FirstOrDefault(); + if (singleRes != null) { - var singleRes = dbCtx - .DbSetDbSize - .FromSqlRaw(stp_DbInfo) - .AsEnumerable() - .FirstOrDefault(); - if (singleRes != null) - { - dbResult.Add(singleRes); - } + dbResult.Add(singleRes); } } } catch (Exception exc) { - Log.Error($"Eccezione in AllDbInfo:{Environment.NewLine}{exc}"); + Log.Error($"Eccezione in AllDbInfoAsync:{Environment.NewLine}{exc}"); } return dbResult; - } + } +#endif /// /// Elenco da tabella Config @@ -130,15 +138,12 @@ namespace MP.Data.Controllers public List ConfigGetAll() { List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbSetConfig - .AsNoTracking() - .OrderBy(x => x.Chiave) - .ToList(); - } - return dbResult; + using var dbCtx = _ctxFactory.CreateDbContext(); + return dbCtx + .DbSetConfig + .AsNoTracking() + .OrderBy(x => x.Chiave) + .ToList(); } public void Dispose() @@ -154,16 +159,13 @@ namespace MP.Data.Controllers public List ElencoOperatori() { List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbOperatori - .Where(s => s.MatrOpr > 0) - .AsNoTracking() - .OrderBy(x => x.MatrOpr) - .ToList(); - } - return dbResult; + using var dbCtx = _ctxFactory.CreateDbContext(); + return dbCtx + .DbOperatori + .Where(s => s.MatrOpr > 0) + .AsNoTracking() + .OrderBy(x => x.MatrOpr) + .ToList(); } /// @@ -173,13 +175,10 @@ namespace MP.Data.Controllers public List MacchineGetAll() { List dbResult = new List(); - using (MoonProContext localDbCtx = new MoonProContext(options)) - { - dbResult = localDbCtx - .DbSetMacchine - .ToList(); - } - return dbResult; + using var dbCtx = _ctxFactory.CreateDbContext(); + return dbCtx + .DbSetMacchine + .ToList(); } /// @@ -189,15 +188,12 @@ namespace MP.Data.Controllers public List RemRebootLogGetAll() { List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbSetRemRebLog - .AsNoTracking() - .OrderByDescending(x => x.IdxReboot) - .ToList(); - } - return dbResult; + using var dbCtx = _ctxFactory.CreateDbContext(); + return dbCtx + .DbSetRemRebLog + .AsNoTracking() + .OrderByDescending(x => x.IdxReboot) + .ToList(); } /// @@ -207,15 +203,12 @@ namespace MP.Data.Controllers public List RemRebootLogGetLast() { List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbSetRemRebLog - .FromSqlRaw("EXEC stp_RRL_getLast") - .AsNoTracking() - .ToList(); - } - return dbResult; + using var dbCtx = _ctxFactory.CreateDbContext(); + return dbCtx + .DbSetRemRebLog + .FromSqlRaw("EXEC stp_RRL_getLast") + .AsNoTracking() + .ToList(); } /// @@ -225,15 +218,12 @@ namespace MP.Data.Controllers public List RemRebootLogGetLastNoMacc() { List dbResult = new List(); - using (var dbCtx = new MoonProContext(options)) - { - dbResult = dbCtx - .DbSetRemRebLog - .FromSqlRaw("EXEC stp_RRL_GetLastNoMachine") - .AsNoTracking() - .ToList(); - } - return dbResult; + using var dbCtx = _ctxFactory.CreateDbContext(); + return dbCtx + .DbSetRemRebLog + .FromSqlRaw("EXEC stp_RRL_GetLastNoMachine") + .AsNoTracking() + .ToList(); } /// @@ -244,7 +234,7 @@ namespace MP.Data.Controllers public bool RollBackEntity(object item) { bool answ = false; - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using var dbCtx = _ctxFactory.CreateDbContext(); { try { @@ -283,7 +273,9 @@ namespace MP.Data.Controllers private static Logger Log = LogManager.GetCurrentClassLogger(); private readonly IConfiguration _configuration; - private readonly DbContextOptions options; +#if false + private readonly DbContextOptions options; +#endif private bool _disposed = false; #endregion Private Fields diff --git a/MP.Data/Controllers/MpSpecRepository.cs b/MP.Data/Controllers/MpSpecRepository.cs index 97c67690..27b70da3 100644 --- a/MP.Data/Controllers/MpSpecRepository.cs +++ b/MP.Data/Controllers/MpSpecRepository.cs @@ -1,31 +1,36 @@ using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; -using MP.Core.DTO; -using MP.Core.Objects; using MP.Data.DbModels; using NLog; using System; using System.Collections.Generic; using System.Data; -using System.Diagnostics; using System.Linq; using System.Threading.Tasks; -using static EgwCoreLib.Utils.DtUtils; namespace MP.Data.Controllers { public class MpSpecController { + protected readonly IDbContextFactory _ctxFactory; + protected readonly IDbContextFactory _ctxFactoryFL; #region Public Constructors - public MpSpecController(IConfiguration configuration) + public MpSpecController( + IConfiguration configuration, + IDbContextFactory ctxFactory, + IDbContextFactory ctxFactoryFL) { _configuration = configuration; + _ctxFactory = ctxFactory; + _ctxFactoryFL = ctxFactoryFL; +#if false string connStr = _configuration.GetConnectionString("MP.Data"); options = new DbContextOptionsBuilder() .UseSqlServer(connStr) - .Options; + .Options; +#endif Log.Info("Avviata classe MpSpecController"); } @@ -41,7 +46,7 @@ namespace MP.Data.Controllers public async Task AnagCountersGetNextAsync(string cntType) { AnagCountersModel answ = new AnagCountersModel(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); bool outTable = true; if (outTable) { @@ -102,7 +107,7 @@ namespace MP.Data.Controllers /// public async Task> AnagEventiGeneralAsync(string TableName = "EvList", string FieldName = "Common") { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var pTableName = new SqlParameter("@TableName", TableName); var pFieldName = new SqlParameter("@FieldName", FieldName); var dbResult = await dbCtx @@ -129,7 +134,7 @@ namespace MP.Data.Controllers /// public async Task AnagGruppiDeleteAsync(AnagGruppiModel updRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var dbRec = await dbCtx .DbSetAnagGruppi .AsNoTracking() @@ -161,7 +166,7 @@ namespace MP.Data.Controllers /// public async Task> AnagGruppiGetTipoAsync(string tipoGruppo) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); return await dbCtx .DbSetAnagGruppi .Where(x => x.TipoGruppo == tipoGruppo) @@ -176,7 +181,7 @@ namespace MP.Data.Controllers /// public async Task> AnagGruppiRepartoDtoAsync() { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); // in primis recupero i reparti... var listReparti = await AnagGruppiGetTipoAsync("REPARTO"); @@ -211,7 +216,7 @@ namespace MP.Data.Controllers /// public async Task AnagGruppiUpsertAsync(AnagGruppiModel updRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var dbRec = await dbCtx .DbSetAnagGruppi .AsNoTracking() @@ -279,7 +284,7 @@ namespace MP.Data.Controllers /// public async Task ArticoliCountAsync() { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var result = await dbCtx .DbSetArticoli .CountAsync(); @@ -295,7 +300,7 @@ namespace MP.Data.Controllers /// public async Task ArticoliCountSearchAsync(string tipoArt = "*", string azienda = "*", string searchVal = "") { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); IQueryable query = dbCtx.DbSetArticoli.AsNoTracking(); // filtro tipo articolo @@ -331,7 +336,7 @@ namespace MP.Data.Controllers /// public async Task ArticoliCountUsedAsync() { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var result = await dbCtx .DbSetCounter .FromSqlRaw("EXEC stp_ART_CountUsed") @@ -348,7 +353,7 @@ namespace MP.Data.Controllers /// public async Task ArticoliDeleteRecordAsync(AnagArticoliModel currRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var currVal = dbCtx .DbSetArticoli .Where(x => x.CodArticolo == currRec.CodArticolo) @@ -368,7 +373,7 @@ namespace MP.Data.Controllers /// public async Task> ArticoliGetByTipoAsync(string tipo, string azienda = "*") { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); return await dbCtx .DbSetArticoli .AsNoTracking() @@ -387,7 +392,7 @@ namespace MP.Data.Controllers /// public async Task> ArticoliGetSearchAsync(int numRecord, string tipoArt = "*", string azienda = "*", string searchVal = "") { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); IQueryable query = dbCtx.DbSetArticoli .AsNoTracking(); @@ -425,7 +430,7 @@ namespace MP.Data.Controllers /// public async Task> ArticoliGetUnusedAsync() { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); return await dbCtx .DbSetArticoli .FromSqlRaw("EXEC stp_ART_getNotUsed") @@ -439,7 +444,7 @@ namespace MP.Data.Controllers /// public async Task> ArticoliGetUsedAsync() { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); return await dbCtx .DbSetArticoli .FromSqlRaw("EXEC stp_ART_getUsed") @@ -454,7 +459,7 @@ namespace MP.Data.Controllers public async Task> ArticoliInKitAsync() { List dbResult = new List(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); dbResult = await dbCtx .DbSetArticoli .FromSqlRaw("EXEC stp_TempKIT_getArtChild") @@ -470,7 +475,7 @@ namespace MP.Data.Controllers /// public async Task ArticoliUpdateRecord(AnagArticoliModel editRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var currRec = dbCtx .DbSetArticoli .Where(x => x.CodArticolo == editRec.CodArticolo) @@ -500,7 +505,7 @@ namespace MP.Data.Controllers /// public async Task> ConfigGetAllAsync() { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); return await dbCtx .DbSetConfig .AsNoTracking() @@ -516,7 +521,7 @@ namespace MP.Data.Controllers { bool fatto = false; ConfigModel dbResult = new ConfigModel(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); dbResult = await dbCtx .DbSetConfig .Where(x => x.Chiave == updRec.Chiave) @@ -647,7 +652,7 @@ namespace MP.Data.Controllers /// public async Task EvListInsertAsync(EventListModel newRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var currRec = await dbCtx .DbSetEvList .AddAsync(newRec); @@ -874,7 +879,7 @@ namespace MP.Data.Controllers public async Task Grp2MaccDeleteAsync(Gruppi2MaccModel rec2del) { bool answ = false; - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var dbRec = await dbCtx .DbSetGrp2Macc .Where(x => x.CodGruppo == rec2del.CodGruppo && x.IdxMacchina == rec2del.IdxMacchina) @@ -896,7 +901,7 @@ namespace MP.Data.Controllers public async Task Grp2MaccInsertAsync(Gruppi2MaccModel upsRec) { bool answ = false; - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var dbRec = await dbCtx .DbSetGrp2Macc .Where(x => x.CodGruppo == upsRec.CodGruppo && x.IdxMacchina == upsRec.IdxMacchina) @@ -919,7 +924,7 @@ namespace MP.Data.Controllers public async Task Grp2OperDeleteAsync(Gruppi2OperModel rec2del) { bool answ = false; - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var dbRec = await dbCtx .DbSetGrp2Oper .Where(x => x.CodGruppo == rec2del.CodGruppo && x.MatrOpr == rec2del.MatrOpr) @@ -941,7 +946,7 @@ namespace MP.Data.Controllers public async Task Grp2OperInsertAsync(Gruppi2OperModel upsRec) { bool answ = false; - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var dbRec = await dbCtx .DbSetGrp2Oper .Where(x => x.CodGruppo == upsRec.CodGruppo && x.MatrOpr == upsRec.MatrOpr) @@ -962,7 +967,7 @@ namespace MP.Data.Controllers /// public async Task IstKitDeleteAsync(IstanzeKitModel rec2del) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var actRec = await dbCtx .DbSetInstKit .Where(x => x.KeyKit == rec2del.KeyKit && x.KeyExtOrd == rec2del.KeyExtOrd) @@ -985,7 +990,7 @@ namespace MP.Data.Controllers /// public async Task> IstKitFiltAsync(string keyKit, string keyExtOrd) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); return await dbCtx .DbSetInstKit .Where(x => (string.IsNullOrEmpty(keyKit) && string.IsNullOrEmpty(keyExtOrd)) || (x.KeyKit.Contains(keyKit) && !string.IsNullOrEmpty(keyKit)) || (x.KeyExtOrd.Contains(keyExtOrd) && !string.IsNullOrEmpty(keyExtOrd))) @@ -1000,7 +1005,7 @@ namespace MP.Data.Controllers /// Chiave x filtro conf su tab WKS public async Task IstKitInsertByWKSAsync(string CodArtParent, string KeyFilt) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var pCodArtParent = new SqlParameter("@CodArtParent", CodArtParent); var pKeyFilt = new SqlParameter("@KeyFilt", KeyFilt); @@ -1017,7 +1022,7 @@ namespace MP.Data.Controllers /// public async Task IstKitUpsertAsync(IstanzeKitModel editRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var actRec = await dbCtx .DbSetInstKit .Where(x => x.KeyKit == editRec.KeyKit && x.KeyExtOrd == editRec.KeyExtOrd) @@ -1065,7 +1070,7 @@ namespace MP.Data.Controllers /// public async Task> ListLinkAllAsync() { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); return await dbCtx .DbSetLinkMenu .AsNoTracking() @@ -1081,7 +1086,7 @@ namespace MP.Data.Controllers public async Task> ListLinkFiltAsync(string tipoLink) { List dbResult = new List(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); return await dbCtx .DbSetLinkMenu .Where(x => x.TipoLink == tipoLink) @@ -1106,7 +1111,7 @@ namespace MP.Data.Controllers public async Task> ListODLFiltAsync(bool inCorso, string codArt, string keyRichPart, string Reparto, string IdxMacchina, DateTime startDate, DateTime endDate) { List dbResult = new List(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var InCorso = new SqlParameter("@InCorso", inCorso); var CodArt = new SqlParameter("@CodArt", codArt); @@ -1131,7 +1136,7 @@ namespace MP.Data.Controllers /// public async Task> ListPODL_ByCodArtAsync(string CodArticolo, bool OnlyAvail) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var pCodArticolo = new SqlParameter("@CodArticolo", CodArticolo); var pOnlyAvail = new SqlParameter("@onlyAvail", OnlyAvail); @@ -1149,7 +1154,7 @@ namespace MP.Data.Controllers /// public async Task> ListPODL_ByKitParentAsync(int IdxPodlParent) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var pIdxPodlParent = new SqlParameter("@IdxPodlParent", IdxPodlParent); return await dbCtx @@ -1169,7 +1174,7 @@ namespace MP.Data.Controllers /// public async Task> ListPODL_KitFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var Lanc = new SqlParameter("@Lanciato", lanciato); var KeyRich = new SqlParameter("@KeyRich", keyRichPart); var CodGrp = new SqlParameter("@CodGruppo", codGruppo); @@ -1194,7 +1199,7 @@ namespace MP.Data.Controllers /// public async Task> ListPODLFiltAsync(bool lanciato, string keyRichPart, string idxMacchina, string codGruppo, DateTime startDate, DateTime endDate) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var Lanc = new SqlParameter("@Lanciato", lanciato); var KeyRich = new SqlParameter("@KeyRich", keyRichPart); var CodGrp = new SqlParameter("@CodGruppo", codGruppo); @@ -1217,7 +1222,7 @@ namespace MP.Data.Controllers /// public async Task> ListValuesFiltAsync(string tabName, string fieldName) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); return await dbCtx .DbSetListValues .Where(x => x.TableName == tabName && x.FieldName == fieldName) @@ -1233,7 +1238,7 @@ namespace MP.Data.Controllers /// public async Task> MacchineByMatrOperAsync(int MatrOpr) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); if (MatrOpr == 0) { return await dbCtx @@ -1272,7 +1277,7 @@ namespace MP.Data.Controllers /// public async Task> MacchineGetFiltAsync(string codGruppo) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); if (codGruppo == "*") { return await dbCtx @@ -1305,7 +1310,7 @@ namespace MP.Data.Controllers /// public async Task> MacchineWithFluxAsync(DateTime dtStart, DateTime dtEnd) { - using var dbCtx = new MoonPro_FluxContext(_configuration); + using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); return await dbCtx .DbSetFluxLog .AsNoTracking() @@ -1322,7 +1327,7 @@ namespace MP.Data.Controllers public async Task> MseGetAllAsync(int maxAge = 2000) { List dbResult = new List(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var maxAgeSec = new SqlParameter("@maxAgeSec", maxAge); @@ -1357,7 +1362,7 @@ namespace MP.Data.Controllers /// public async Task OdlByKeyAsync(int IdxOdl) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); return await dbCtx .DbSetODLExp .AsNoTracking() @@ -1379,7 +1384,7 @@ namespace MP.Data.Controllers bool fatto = false; if (idxOdl > 0) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); DateTime adesso = DateTime.Now; // preparo i parametri var IdxODL = new SqlParameter("@IdxODL", idxOdl); @@ -1441,7 +1446,7 @@ namespace MP.Data.Controllers /// public async Task> OdlGetCurrentAsync() { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); return await dbCtx .DbSetODL .Where(x => x.DataInizio != null && x.DataFine == null) @@ -1457,7 +1462,7 @@ namespace MP.Data.Controllers List dbResult = new List(); if (IdxOdl > 0) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var IdxODL = new SqlParameter("@IdxODL", IdxOdl); dbResult = await dbCtx @@ -1477,7 +1482,7 @@ namespace MP.Data.Controllers public async Task> OperatoriGetFiltAsync(string codGruppo) { List dbResult = new List(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); if (codGruppo == "*") { dbResult = await dbCtx @@ -1510,7 +1515,7 @@ namespace MP.Data.Controllers /// public async Task> ParametriGetFiltAsync(string IdxMacchina) { - using var dbCtx = new MoonPro_FluxContext(_configuration); + using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); return await dbCtx .DbSetFluxLog .AsNoTracking() @@ -1529,7 +1534,7 @@ namespace MP.Data.Controllers /// public async Task PODL_getByKeyAsync(int idxPODL) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); return await dbCtx .DbSetPODL .AsNoTracking() @@ -1545,7 +1550,7 @@ namespace MP.Data.Controllers /// public async Task PODL_getByOdlAsync(int idxODL) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); return await dbCtx .DbSetPODL .AsNoTracking() @@ -1563,7 +1568,7 @@ namespace MP.Data.Controllers if (missingIds == null || !missingIds.Any()) return new Dictionary(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); return await dbCtx .DbSetPODL .AsNoTracking() @@ -1602,7 +1607,7 @@ namespace MP.Data.Controllers InsertDate = editRec.InsertDate }; - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var currRec = await dbCtx .DbSetPODL .AsNoTracking() @@ -1637,7 +1642,7 @@ namespace MP.Data.Controllers public async Task PODL_updateRecipe(int idxPODL, string recipeName) { bool answ = false; - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var currRec = await dbCtx .DbSetPODL .Where(x => x.IdxPromessa == idxPODL) @@ -1677,7 +1682,7 @@ namespace MP.Data.Controllers CodCli = currRec.CodCli, InsertDate = currRec.InsertDate }; - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var currVal = await dbCtx .DbSetPODL .Where(x => x.IdxPromessa == recPODL.IdxPromessa) @@ -1694,7 +1699,7 @@ namespace MP.Data.Controllers /// IdxPODL parent public async Task PodlIstKitDeleteAsync(int IdxPODL) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var pIdxPODL = new SqlParameter("@IdxPODL", IdxPODL); var dbResult = await dbCtx @@ -1710,7 +1715,7 @@ namespace MP.Data.Controllers /// public async Task PODLUpdateRecordAsync(PODLModel editRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var currRec = await dbCtx .DbSetPODL .Where(x => x.IdxPromessa == editRec.IdxPromessa) @@ -1744,7 +1749,7 @@ namespace MP.Data.Controllers /// public async Task StatoMacchinaAsync(string idxMacchina) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); return await dbCtx .DbSetStatoMacc .Where(x => x.IdxMacchina == idxMacchina) @@ -1758,7 +1763,7 @@ namespace MP.Data.Controllers /// public async Task TemplateKitDeleteAsync(TemplateKitModel rec2del) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var actRec = await dbCtx .DbSetTempKit .Where(x => x.CodArtParent == rec2del.CodArtParent && x.CodArtChild == rec2del.CodArtChild) @@ -1782,7 +1787,7 @@ namespace MP.Data.Controllers public async Task> TemplateKitFiltAsync(string KitCode, string codChild) { List dbResult = new List(); - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); dbResult = await dbCtx .DbSetTempKit .Where(x => (string.IsNullOrEmpty(KitCode) && string.IsNullOrEmpty(codChild)) || (x.CodArtParent.Contains(KitCode) && !string.IsNullOrEmpty(KitCode)) || (x.CodArtChild.Contains(codChild) && !string.IsNullOrEmpty(codChild))) @@ -1798,7 +1803,7 @@ namespace MP.Data.Controllers /// public async Task TemplateKitUpsertAsync(TemplateKitModel editRec, string codAzienda) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); // verifico preliminarmente articolo... var recArt = dbCtx .DbSetArticoli @@ -1854,7 +1859,7 @@ namespace MP.Data.Controllers List dbResult = new List(); if (!string.IsNullOrEmpty(KeyFilt)) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var pKeyFilt = new SqlParameter("@KeyFilt", KeyFilt); var pMaxRes = new SqlParameter("@maxResult", MaxResult); dbResult = await dbCtx @@ -1866,13 +1871,14 @@ namespace MP.Data.Controllers return dbResult; } +#if false /// /// Elenco Vocabolario di una lingua /// /// public Dictionary VocabolarioGetLang(string lingua) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = _ctxFactory.CreateDbContext(); var rawList = dbCtx .DbSetVocabolario .AsNoTracking() @@ -1892,7 +1898,7 @@ namespace MP.Data.Controllers /// public async Task VocabolarioUpsertAsync(VocabolarioModel upsRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var actRec = await dbCtx .DbSetVocabolario .Where(x => x.Lingua == upsRec.Lingua && x.Lemma == upsRec.Lemma) @@ -1919,7 +1925,7 @@ namespace MP.Data.Controllers /// public async Task WipKitDeleteAsync(WipSetupKitModel rec2del) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var actRec = await dbCtx .DbSetWipKit .Where(x => x.KeyFilt == rec2del.KeyFilt && x.CodOrd == rec2del.CodOrd) @@ -1932,7 +1938,8 @@ namespace MP.Data.Controllers .Remove(actRec); } return await dbCtx.SaveChangesAsync() > 0; - } + } +#endif /// /// Elimina record + vecchi della data-ora indicata @@ -1941,7 +1948,7 @@ namespace MP.Data.Controllers /// public async Task WipKitDeleteOlderAsync(DateTime dateLimit) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var actRec = await dbCtx .DbSetWipKit .Where(x => x.DataIns < dateLimit) @@ -1967,7 +1974,7 @@ namespace MP.Data.Controllers // solo se filtro valido... if (!string.IsNullOrEmpty(KeyFilt)) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); dbResult = await dbCtx .DbSetWipKit .Where(x => x.KeyFilt.Contains(KeyFilt)) @@ -1983,7 +1990,7 @@ namespace MP.Data.Controllers /// public async Task WipKitUpsertAsync(WipSetupKitModel editRec) { - using var dbCtx = new MoonProContext(options); + using var dbCtx = await _ctxFactory.CreateDbContextAsync(); var actRec = await dbCtx .DbSetWipKit .Where(x => x.KeyFilt == editRec.KeyFilt && x.CodOrd == editRec.CodOrd) @@ -2013,7 +2020,9 @@ namespace MP.Data.Controllers private static IConfiguration _configuration; private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); - private DbContextOptions options; +#if false + private DbContextOptions options; +#endif #endregion Private Fields } diff --git a/MP.Data/Controllers/MpStatsController.cs b/MP.Data/Controllers/MpStatsController.cs index 046d5549..46b4e137 100644 --- a/MP.Data/Controllers/MpStatsController.cs +++ b/MP.Data/Controllers/MpStatsController.cs @@ -19,11 +19,15 @@ namespace MP.Data.Controllers public MpStatsController(IConfiguration configuration) { _configuration = configuration; + string connStr = _configuration.GetConnectionString("MP.Stats"); + options = new DbContextOptionsBuilder() + .UseSqlServer(connStr) + .Options; Log.Info("Avviata classe MpStatsController"); } #endregion Public Constructors - + private DbContextOptions options; #region Public Methods /// @@ -33,13 +37,10 @@ namespace MP.Data.Controllers public List ActionsGetAll() { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) - { - dbResult = dbCtx + using var dbCtx = new MoonPro_STATSContext(options); + return dbCtx .DbSetAzioniUL .ToList(); - } - return dbResult; } /// @@ -49,13 +50,10 @@ namespace MP.Data.Controllers public List AnagFLTransGetAll() { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) - { - dbResult = dbCtx - .DbSetAnagFLTrans - .ToList(); - } - return dbResult; + using var dbCtx = new MoonPro_STATSContext(options); + return dbCtx + .DbSetAnagFLTrans + .ToList(); } /// @@ -67,7 +65,7 @@ namespace MP.Data.Controllers public List ArticoliGetSearch(int numRecord, string searchVal = "") { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { dbResult = dbCtx .DbSetArticoli @@ -88,7 +86,7 @@ namespace MP.Data.Controllers public List CommesseGetSearch(int numRecord, string searchVal = "") { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { dbResult = dbCtx .DbSetODL @@ -107,7 +105,7 @@ namespace MP.Data.Controllers public List ConfigGetAll() { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { dbResult = dbCtx .DbSetConfig @@ -133,7 +131,7 @@ namespace MP.Data.Controllers public List FluxLogRawData(string IdxMacchina, DateTime DtStart, DateTime DtEnd, string fluxType) { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { dbResult = dbCtx .DbSetFL @@ -153,7 +151,7 @@ namespace MP.Data.Controllers public List FluxTypeList() { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { dbResult = dbCtx .DbSetFL @@ -172,7 +170,7 @@ namespace MP.Data.Controllers public List MacchineEnergy() { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { dbResult = dbCtx .DbSetMaccStat @@ -188,7 +186,7 @@ namespace MP.Data.Controllers public List MacchineGetAll() { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { dbResult = dbCtx .DbSetMacchine @@ -204,7 +202,7 @@ namespace MP.Data.Controllers public async Task> MacchineEnergyCheckGetAllAsync() { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { dbResult = await dbCtx .DbSetMacchineCheck @@ -222,7 +220,7 @@ namespace MP.Data.Controllers public bool RollBackEntity(object item) { bool answ = false; - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { try { @@ -248,7 +246,7 @@ namespace MP.Data.Controllers public List StatControlliGetAll(DateTime DataStart, DateTime DataEnd, string IdxMacchina, int IdxODL, string KeyRichiesta, string CodArticolo) { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { var dataFrom = new SqlParameter("@dataFrom", DataStart); var dataTo = new SqlParameter("@dataTo", DataEnd); @@ -280,7 +278,7 @@ namespace MP.Data.Controllers public List StatDdbGetAll(DateTime DataStart, DateTime DataEnd, string IdxMacchina, int IdxODL, string KeyRichiesta, string CodArticolo, int FirstRecord, int NumRecord) { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { var dataFrom = new SqlParameter("@dataFrom", DataStart); var dataTo = new SqlParameter("@dataTo", DataEnd); @@ -312,7 +310,7 @@ namespace MP.Data.Controllers public int StatDdbGetCount(DateTime DataStart, DateTime DataEnd, string IdxMacchina, int IdxODL, string KeyRichiesta, string CodArticolo) { int numResult = 0; - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { numResult = dbCtx .DbSetDdbTurni @@ -335,7 +333,7 @@ namespace MP.Data.Controllers public List StatOdlEnergyGetFilt(string IdxMacchina, DateTime DtStart, DateTime DtEnd, int IdxODL, string KeyRichiesta, string CodArticolo) { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { var dataFrom = new SqlParameter("@dataFrom", DtStart); var dataTo = new SqlParameter("@dataTo", DtEnd); @@ -361,7 +359,7 @@ namespace MP.Data.Controllers public List StatOdlGetAll(DateTime DataStart, DateTime DataEnd, string IdxMacchina, int IdxODL, string KeyRichiesta, string CodArticolo) { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { var dataFrom = new SqlParameter("@dataFrom", DataStart); var dataTo = new SqlParameter("@dataTo", DataEnd); @@ -389,7 +387,7 @@ namespace MP.Data.Controllers public List StatScartiGetAll(DateTime DataStart, DateTime DataEnd, string IdxMacchina, int IdxODL, string KeyRichiesta, string CodArticolo) { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { var dataFrom = new SqlParameter("@dataFrom", DataStart); var dataTo = new SqlParameter("@dataTo", DataEnd); @@ -417,7 +415,7 @@ namespace MP.Data.Controllers public List StatTurniOeeGetAll(DateTime DataStart, DateTime DataEnd, string IdxMacchina, int IdxODL, string KeyRichiesta, string CodArticolo) { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { var dataFrom = new SqlParameter("@dataFrom", DataStart); var dataTo = new SqlParameter("@dataTo", DataEnd); @@ -443,7 +441,7 @@ namespace MP.Data.Controllers public List StatUserLogGetAll(DateTime DataStart, DateTime DataEnd, string IdxMacchina, int IdxODL, string KeyRichiesta, string CodArticolo) { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { var dataFrom = new SqlParameter("@dataFrom", DataStart); var dataTo = new SqlParameter("@dataTo", DataEnd); @@ -467,7 +465,7 @@ namespace MP.Data.Controllers public List VocabolarioGetAll() { List dbResult = new List(); - using (var dbCtx = new MoonPro_STATSContext(_configuration)) + using (var dbCtx = new MoonPro_STATSContext(options)) { dbResult = dbCtx .DbSetVocabolario diff --git a/MP.Data/DataServiceCollectionExtensions.cs b/MP.Data/DataServiceCollectionExtensions.cs index 6b0b34ed..2adc1d06 100644 --- a/MP.Data/DataServiceCollectionExtensions.cs +++ b/MP.Data/DataServiceCollectionExtensions.cs @@ -23,6 +23,8 @@ namespace MP.Data { public static class DataServiceCollectionExtensions { + #region Public Methods + /// /// Aggiunta repository/servizi specifici per IOC /// @@ -49,6 +51,7 @@ namespace MP.Data return services; } + /// /// Aggiunta repository/servizi specifici per LAND /// @@ -56,7 +59,12 @@ namespace MP.Data /// public static IServiceCollection AddLandDataLayer(this IServiceCollection services) { + // Controllers MP.AppAuth (dipendenze di AppAuthService) + services.TryAddScoped(); + services.TryAddScoped(); + services.TryAddScoped(); + // Servizi LAND services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); @@ -64,6 +72,7 @@ namespace MP.Data return services; } + /// /// Aggiunta repository/servizi specifici per MON /// @@ -71,11 +80,11 @@ namespace MP.Data /// public static IServiceCollection AddMonDataLayer(this IServiceCollection services) { - services.TryAddSingleton(); services.TryAddSingleton(); return services; } + /// /// Aggiunta repository/servizi specifici per SPEC /// @@ -95,13 +104,12 @@ namespace MP.Data services.TryAddScoped(); // ---------- End Repository ---------- - // ---------- Start Servizi ---------- //services.TryAddSingleton(); // ---------- End Servizi ---------- - // ---------- Start Altro ---------- + services.TryAddSingleton(); services.TryAddScoped(); services.TryAddScoped(); services.TryAddScoped(); @@ -117,5 +125,30 @@ namespace MP.Data return services; } + + /// + /// Aggiunta repository/servizi specifici per STATS + /// + /// + /// + public static IServiceCollection AddStatsDataLayer(this IServiceCollection services) + { + services.AddSingleton(); + + services.AddSingleton(); + return services; + } + + /// + /// Aggiunta repository/servizi specifici per TAB + /// + /// + /// + public static IServiceCollection AddTabDataLayer(this IServiceCollection services) + { + return services; + } + + #endregion Public Methods } -} +} \ No newline at end of file diff --git a/MP.Data/DbModels/TksScoreModel.cs b/MP.Data/DbModels/TksScoreModel.cs index 12fdfe78..e541bf58 100644 --- a/MP.Data/DbModels/TksScoreModel.cs +++ b/MP.Data/DbModels/TksScoreModel.cs @@ -30,6 +30,7 @@ namespace MP.Data.DbModels /// /// Score complessivo /// + [Precision(18, 6)] public decimal TotalScore { get; set; } = 0; } diff --git a/MP.Data/MoonPro_FluxContext.cs b/MP.Data/MoonPro_FluxContext.cs index 117777b7..db5ae409 100644 --- a/MP.Data/MoonPro_FluxContext.cs +++ b/MP.Data/MoonPro_FluxContext.cs @@ -17,7 +17,9 @@ namespace MP.Data private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); - private IConfiguration _configuration; +#if false + private IConfiguration _configuration; +#endif #endregion Private Fields @@ -27,15 +29,17 @@ namespace MP.Data /// Indispensabile x prima generazione migrations EFCore /// - [Obsolete("This constructor should never be used directly, and is only needed to generate entityframework stuff. Connection string can be adapted as pleased.")] + [Obsolete("This constructor should never be used directly, and is only needed to generate entityframework stuff. use DbContextoptions instead.")] public MoonPro_FluxContext() { } - +#if false + [Obsolete("This constructor should never be used directly, and is only needed to generate entityframework stuff. use DbContextoptions instead.")] public MoonPro_FluxContext(IConfiguration configuration) { _configuration = configuration; - } + } +#endif public MoonPro_FluxContext(DbContextOptions options) : base(options) { @@ -69,6 +73,7 @@ namespace MP.Data { if (!optionsBuilder.IsConfigured) { +#if false string connString = _configuration.GetConnectionString("MP.Flux"); if (!string.IsNullOrEmpty(connString)) { @@ -77,7 +82,9 @@ namespace MP.Data else { optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=MoonPro_FluxData;Trusted_Connection=True;"); - } + } +#endif + optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=MoonPro_FluxData;Trusted_Connection=True;"); } } diff --git a/MP.Data/MoonPro_STATSContext.cs b/MP.Data/MoonPro_STATSContext.cs index 11ba7efd..18b8ae1e 100644 --- a/MP.Data/MoonPro_STATSContext.cs +++ b/MP.Data/MoonPro_STATSContext.cs @@ -16,16 +16,20 @@ namespace MP.Data private static NLog.Logger Log = LogManager.GetCurrentClassLogger(); - private IConfiguration _configuration; +#if false + private IConfiguration _configuration; +#endif #endregion Private Fields #region Public Constructors +#if false public MoonPro_STATSContext(IConfiguration configuration) { _configuration = configuration; - } + } +#endif public MoonPro_STATSContext(DbContextOptions options) : base(options) { @@ -68,10 +72,7 @@ namespace MP.Data { if (!optionsBuilder.IsConfigured) { - string connString = _configuration.GetConnectionString("MP.Stats"); - - optionsBuilder.UseSqlServer(connString); - //optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=MoonPro_STATS;Trusted_Connection=True;"); + optionsBuilder.UseSqlServer("Server=SQL2016DEV;Database=MoonPro_STATS;Trusted_Connection=True;"); } } diff --git a/MP.Data/Repository/Anag/AnagRepository.cs b/MP.Data/Repository/Anag/AnagRepository.cs index a4a00cf8..03721446 100644 --- a/MP.Data/Repository/Anag/AnagRepository.cs +++ b/MP.Data/Repository/Anag/AnagRepository.cs @@ -162,6 +162,40 @@ namespace MP.Data.Repository.Anag .ToList(); } + /// + public async Task> GruppiRepartoDtoByOperAsync(int matrOpr) + { + await using var dbCtx = await CreateContextAsync(); + var listReparti = await AnagGruppiGetTipoAsync("REPARTO"); + + var listMacc = await dbCtx + .DbSetGrp2Macc + .AsNoTracking() + .ToListAsync(); + var listOpr = await dbCtx + .DbSetGrp2Oper + .AsNoTracking() + .ToListAsync(); + + var gruppiOpr = await dbCtx.DbSetGrp2Oper + .Where(x => x.MatrOpr == matrOpr) + .Select(x => x.CodGruppo) + .Distinct() + .ToListAsync(); + return listReparti + .Where(r => gruppiOpr.Contains(r.CodGruppo)) + .Select(x => new RepartiDTO() + { + CodGruppo = x.CodGruppo, + TipoGruppo = x.TipoGruppo, + DescrGruppo = x.DescrGruppo, + SelEnabled = x.SelEnabled, + CountMacc = listMacc.Where(y => y.CodGruppo == x.CodGruppo).Select(y => y.IdxMacchina).Distinct().Count(), + CountOpr = listOpr.Where(y => y.CodGruppo == x.CodGruppo).Select(y => y.MatrOpr).Distinct().Count() + }) + .ToList(); + } + /// public async Task AnagGruppiUpsertAsync(AnagGruppiModel updRec) { diff --git a/MP.Data/Repository/Anag/IAnagRepository.cs b/MP.Data/Repository/Anag/IAnagRepository.cs index 7b943098..728a4657 100644 --- a/MP.Data/Repository/Anag/IAnagRepository.cs +++ b/MP.Data/Repository/Anag/IAnagRepository.cs @@ -75,14 +75,6 @@ namespace MP.Data.Repository.Anag /// Lista di valori ammessi Task> AnagTipoArtLvAsync(); -#if false - /// - /// Elenco codice articoli che abbiano dati Dossier - /// - /// Lista di codici articolo - Task> ArticleWithDossierAsync(); -#endif - /// /// Conteggio num articoli Async /// @@ -154,6 +146,20 @@ namespace MP.Data.Repository.Anag /// True se aggiornato Task ArticoliUpdateRecord(AnagArticoliModel editRec); + /// + /// Elenco Gruppi tipo REPARTOin formato DTO con conteggi del numero record trovati filtrati per operatore + /// + /// Lista di DTO reparti con conteggio macchine e operatori + Task> GruppiRepartoDtoByOperAsync(int matrOpr); + +#if false + /// + /// Elenco codice articoli che abbiano dati Dossier + /// + /// Lista di codici articolo + Task> ArticleWithDossierAsync(); +#endif + /// /// Elenco valori ammessi x tabella/colonna Async /// diff --git a/MP.Data/Repository/Dossier/DossierRepository.cs b/MP.Data/Repository/Dossier/DossierRepository.cs index 4fcf2319..f882df25 100644 --- a/MP.Data/Repository/Dossier/DossierRepository.cs +++ b/MP.Data/Repository/Dossier/DossierRepository.cs @@ -11,27 +11,36 @@ namespace MP.Data.Repository.Dossier { public class DossierRepository : IDossierRepository { - #region Private Fields - - private readonly IConfiguration _configuration; - - #endregion - #region Public Constructors - public DossierRepository(IConfiguration configuration) + public DossierRepository( + IConfiguration configuration, + IDbContextFactory ctxFactoryFL) { _configuration = configuration; + _ctxFactoryFL = ctxFactoryFL; } - #endregion + #endregion Public Constructors #region Public Methods + /// + public async Task> ArticleWithDossierAsync() + { + await using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); + return await dbCtx + .DbSetDossiers + .AsNoTracking() + .Select(i => i.CodArticolo) + .Distinct() + .ToListAsync(); + } + /// public async Task DossiersDeleteRecordAsync(DossierModel currRec) { - await using var dbCtx = new MoonPro_FluxContext(_configuration); + await using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); var currVal = await dbCtx .DbSetDossiers .Where(x => x.IdxDossier == currRec.IdxDossier) @@ -46,7 +55,7 @@ namespace MP.Data.Repository.Dossier /// public async Task> DossiersGetLastFiltAsync(string IdxMacchina, string CodArticolo, DateTime DtStart, DateTime DtEnd, int MaxRec) { - await using var dbCtx = new MoonPro_FluxContext(_configuration); + await using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); return await dbCtx .DbSetDossiers .AsNoTracking() @@ -61,7 +70,7 @@ namespace MP.Data.Repository.Dossier /// public async Task DossiersInsertAsync(DossierModel newRec) { - await using var dbCtx = new MoonPro_FluxContext(_configuration); + await using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); await dbCtx .DbSetDossiers .AddAsync(newRec); @@ -71,7 +80,7 @@ namespace MP.Data.Repository.Dossier /// public async Task DossiersTakeParamsSnapshotLastAsync(string idxMacchina, DateTime dtMin, DateTime dtMax) { - await using var dbCtx = new MoonPro_FluxContext(_configuration); + await using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMacchina); var pDtMin = new SqlParameter("@DtMin", dtMin); var pDtMax = new SqlParameter("@DtMax", dtMax); @@ -85,7 +94,7 @@ namespace MP.Data.Repository.Dossier /// public async Task DossiersUpdateValoreAsync(DossierModel editRec) { - await using var dbCtx = new MoonPro_FluxContext(_configuration); + await using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); var currRec = await dbCtx .DbSetDossiers .Where(x => x.IdxDossier == editRec.IdxDossier) @@ -104,18 +113,18 @@ namespace MP.Data.Repository.Dossier return await dbCtx.SaveChangesAsync() > 0; } - /// - public async Task> ArticleWithDossierAsync() - { - await using var dbCtx = new MoonPro_FluxContext(_configuration); - return await dbCtx - .DbSetDossiers - .AsNoTracking() - .Select(i => i.CodArticolo) - .Distinct() - .ToListAsync(); - } + #endregion Public Methods - #endregion + #region Protected Fields + + protected readonly IDbContextFactory _ctxFactoryFL; + + #endregion Protected Fields + + #region Private Fields + + private readonly IConfiguration _configuration; + + #endregion Private Fields } -} +} \ No newline at end of file diff --git a/MP.Data/Repository/FluxLog/FluxLogRepository.cs b/MP.Data/Repository/FluxLog/FluxLogRepository.cs index 2bf4ca5a..e0b2bdf4 100644 --- a/MP.Data/Repository/FluxLog/FluxLogRepository.cs +++ b/MP.Data/Repository/FluxLog/FluxLogRepository.cs @@ -15,21 +15,15 @@ namespace MP.Data.Repository.FluxLog { public class FluxLogRepository : IFluxLogRepository { - #region Private Fields - - private readonly IConfiguration _configuration; - private static NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger(); - - #endregion - #region Public Constructors - public FluxLogRepository(IConfiguration configuration) + public FluxLogRepository(IConfiguration configuration, IDbContextFactory ctxFactoryFL) { _configuration = configuration; + _ctxFactoryFL = ctxFactoryFL; } - #endregion + #endregion Public Constructors #region Public Methods @@ -60,7 +54,7 @@ namespace MP.Data.Repository.FluxLog var pIdxMacchina = new SqlParameter("@IdxMacchina", idxMaccSel); var pOnlyTest = new SqlParameter("@OnlyTest", false); - await using var dbCtx = new MoonPro_FluxContext(_configuration); + await using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); foreach (var item in fluxList) { Log.Info($"FluxLogDataReduxAsync | Flux: {item}"); @@ -149,7 +143,7 @@ namespace MP.Data.Repository.FluxLog /// public async Task> FluxLogGetLastFiltAsync(DateTime DtMax, DateTime DtMin, string IdxMacchina, string CodFlux, int MaxRec) { - await using var dbCtx = new MoonPro_FluxContext(_configuration); + await using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); return await dbCtx .DbSetFluxLog .AsNoTracking() @@ -162,7 +156,7 @@ namespace MP.Data.Repository.FluxLog /// public async Task> FluxLogParetoAsync(string idxMacchina, DateTime dtFrom, DateTime dtTo) { - await using var dbCtx = new MoonPro_FluxContext(_configuration); + await using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); return await dbCtx .DbSetFluxLog .Where(x => (string.IsNullOrEmpty(idxMacchina) || x.IdxMacchina == idxMacchina) && (dtFrom <= x.dtEvento && x.dtEvento <= dtTo)) @@ -173,6 +167,19 @@ namespace MP.Data.Repository.FluxLog .ToListAsync() ?? new(); } - #endregion + #endregion Public Methods + + #region Protected Fields + + protected readonly IDbContextFactory _ctxFactoryFL; + + #endregion Protected Fields + + #region Private Fields + + private static NLog.Logger Log = NLog.LogManager.GetCurrentClassLogger(); + private readonly IConfiguration _configuration; + + #endregion Private Fields } -} +} \ No newline at end of file diff --git a/MP.Data/Repository/MpLand/MpLandRepository.cs b/MP.Data/Repository/MpLand/MpLandRepository.cs index c40c9299..83b60fff 100644 --- a/MP.Data/Repository/MpLand/MpLandRepository.cs +++ b/MP.Data/Repository/MpLand/MpLandRepository.cs @@ -13,6 +13,8 @@ namespace MP.Data.Repository.MpLand private readonly IConfiguration _configuration; private readonly IDbContextFactory _ctxFactory; + private readonly IDbContextFactory _ctxFactoryFluxLog; + private readonly IDbContextFactory _ctxFactoryStats; #endregion @@ -61,11 +63,12 @@ namespace MP.Data.Repository.MpLand if (!string.IsNullOrEmpty(_configuration.GetConnectionString("MP.All"))) { await using var dbCtx = await _ctxFactory.CreateDbContextAsync(); - var singleRes = await dbCtx + var singleRes = dbCtx .DbSetDbSize .FromSqlRaw(stp_DbInfo) .AsNoTracking() - .FirstOrDefaultAsync(); + .AsEnumerable() + .FirstOrDefault(); if (singleRes != null) { dbResult.Add(singleRes); @@ -73,12 +76,13 @@ namespace MP.Data.Repository.MpLand } if (!string.IsNullOrEmpty(_configuration.GetConnectionString("MP.Flux"))) { - await using var dbCtx = new MoonPro_FluxContext(_configuration); - var singleRes = await dbCtx + await using var dbCtx = await _ctxFactoryFluxLog.CreateDbContextAsync(); + var singleRes = dbCtx .DbSetDbSize .FromSqlRaw(stp_DbInfo) .AsNoTracking() - .FirstOrDefaultAsync(); + .AsEnumerable() + .FirstOrDefault(); if (singleRes != null) { dbResult.Add(singleRes); @@ -86,12 +90,13 @@ namespace MP.Data.Repository.MpLand } if (!string.IsNullOrEmpty(_configuration.GetConnectionString("MP.Stats"))) { - await using var dbCtx = new MoonPro_STATSContext(_configuration); - var singleRes = await dbCtx + await using var dbCtx = await _ctxFactoryStats.CreateDbContextAsync(); + var singleRes = dbCtx .DbSetDbSize .FromSqlRaw(stp_DbInfo) .AsNoTracking() - .FirstOrDefaultAsync(); + .AsEnumerable() + .FirstOrDefault(); if (singleRes != null) { dbResult.Add(singleRes); diff --git a/MP.Data/Repository/MpVoc/IMpVocRepository.cs b/MP.Data/Repository/MpVoc/IMpVocRepository.cs index 845d07ef..733574c1 100644 --- a/MP.Data/Repository/MpVoc/IMpVocRepository.cs +++ b/MP.Data/Repository/MpVoc/IMpVocRepository.cs @@ -6,10 +6,35 @@ namespace MP.Data.Repository.MpVoc { public interface IMpVocRepository { - Task> ConfigGetAllAsync(); + #region Public Methods +#if false + /// + /// Recupero elenco config + /// + /// + Task> ConfigGetAllAsync(); +#endif + + /// + /// recupero elenco lingue + /// + /// Task> LingueGetAllAsync(); + /// + /// Recupero tutte le voci dizionario, async + /// + /// Task> VocabolarioGetAllAsync(); + + /// + /// Recupero dizionario traduzioni x singola lingua + /// + /// Codice lingua + /// Dizionario di traduzioni + Dictionary VocabolarioGetLang(string lingua); + + #endregion Public Methods } -} +} \ No newline at end of file diff --git a/MP.Data/Repository/MpVoc/MpVocRepository.cs b/MP.Data/Repository/MpVoc/MpVocRepository.cs index 9afe2146..ae887011 100644 --- a/MP.Data/Repository/MpVoc/MpVocRepository.cs +++ b/MP.Data/Repository/MpVoc/MpVocRepository.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using MP.Data.DbModels; +using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -8,12 +9,6 @@ namespace MP.Data.Repository.MpVoc { public class MpVocRepository : IMpVocRepository { - #region Private Fields - - private readonly IDbContextFactory _ctxFactory; - - #endregion - #region Public Constructors public MpVocRepository(IDbContextFactory ctxFactory) @@ -21,10 +16,11 @@ namespace MP.Data.Repository.MpVoc _ctxFactory = ctxFactory; } - #endregion + #endregion Public Constructors #region Public Methods +#if false /// public async Task> ConfigGetAllAsync() { @@ -34,7 +30,8 @@ namespace MP.Data.Repository.MpVoc .AsNoTracking() .OrderBy(x => x.Chiave) .ToListAsync() ?? new(); - } + } +#endif /// public async Task> LingueGetAllAsync() @@ -58,6 +55,28 @@ namespace MP.Data.Repository.MpVoc .ToListAsync() ?? new(); } - #endregion + /// + public Dictionary VocabolarioGetLang(string lingua) + { + using var dbCtx = _ctxFactory.CreateDbContextAsync().GetAwaiter().GetResult(); + var rawList = dbCtx + .DbSetVocabolario + .AsNoTracking() + .Where(x => x.Lingua.ToLower() == lingua.ToLower()) + .OrderBy(x => x.Lemma) + .ToList(); + // Proietto in dizionario + return rawList + .DistinctBy(t => t.Lemma, StringComparer.OrdinalIgnoreCase) + .ToDictionary(t => t.Lemma, t => t.Traduzione, StringComparer.OrdinalIgnoreCase); + } + + #endregion Public Methods + + #region Private Fields + + private readonly IDbContextFactory _ctxFactory; + + #endregion Private Fields } -} +} \ No newline at end of file diff --git a/MP.Data/Repository/Production/IProductionRepository.cs b/MP.Data/Repository/Production/IProductionRepository.cs index 8a2cd94a..7089a4de 100644 --- a/MP.Data/Repository/Production/IProductionRepository.cs +++ b/MP.Data/Repository/Production/IProductionRepository.cs @@ -106,6 +106,7 @@ namespace MP.Data.Repository.Production Task> ListGiacenzeAsync(int IdxOdl); Task> OperatoriGetFiltAsync(string codGruppo); + Task OperatoriUpsertAsync(AnagOperatoriModel updRec); Task> ParametriGetFiltAsync(string IdxMacchina); diff --git a/MP.Data/Repository/Production/ProductionRepository.cs b/MP.Data/Repository/Production/ProductionRepository.cs index 7905e7af..ec051504 100644 --- a/MP.Data/Repository/Production/ProductionRepository.cs +++ b/MP.Data/Repository/Production/ProductionRepository.cs @@ -19,10 +19,15 @@ namespace MP.Data.Repository.Production #endregion #region Public Constructors + protected readonly IDbContextFactory _ctxFactoryFL; - public ProductionRepository(IDbContextFactory ctxFactory, IConfiguration configuration) + public ProductionRepository( + IConfiguration configuration, + IDbContextFactory ctxFactory, + IDbContextFactory ctxFactoryFL) { _ctxFactory = ctxFactory; + _ctxFactoryFL = ctxFactoryFL; _configuration = configuration; } @@ -686,7 +691,7 @@ namespace MP.Data.Repository.Production /// public async Task> MacchineWithFluxAsync(DateTime dtStart, DateTime dtEnd) { - await using var dbCtx = new MoonPro_FluxContext(_configuration); + await using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); return await dbCtx .DbSetFluxLog .AsNoTracking() @@ -841,10 +846,23 @@ namespace MP.Data.Repository.Production return dbResult; } + public async Task OperatoriUpsertAsync(AnagOperatoriModel updRec) + { + await using var dbCtx = await GetMoonProContextAsync(); + var dbRec = await dbCtx + .DbOperatori + .FindAsync(updRec.MatrOpr); + if (dbRec != null) + { + dbCtx.Entry(dbRec).CurrentValues.SetValues(updRec); + } + return await dbCtx.SaveChangesAsync() > 0; + } + /// public async Task> ParametriGetFiltAsync(string IdxMacchina) { - await using var dbCtx = new MoonPro_FluxContext(_configuration); + await using var dbCtx = await _ctxFactoryFL.CreateDbContextAsync(); return await dbCtx .DbSetFluxLog .AsNoTracking() diff --git a/MP.Data/Services/BaseServ.cs b/MP.Data/Services/BaseServ.cs index 770df68e..0a6dbf7e 100644 --- a/MP.Data/Services/BaseServ.cs +++ b/MP.Data/Services/BaseServ.cs @@ -9,6 +9,8 @@ using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; using System.Threading.Tasks; +using ZiggyCreatures.Caching.Fusion; +using static Org.BouncyCastle.Asn1.Cmp.Challenge; namespace MP.Data.Services { @@ -19,10 +21,12 @@ namespace MP.Data.Services { #region Public Constructors - public BaseServ(IConfiguration configuration, IConnectionMultiplexer redConn) + public BaseServ(IConfiguration configuration, IFusionCache cache, IConnectionMultiplexer redConn) { _configuration = configuration; + _cache = cache; + slowLogThresh = _configuration.GetValue("ServerConf:slowLogThresh", 1); // Verifica conf trace... _traceEnabled = _configuration.GetValue("Otel:EnableTracing", false); @@ -161,13 +165,23 @@ namespace MP.Data.Services /// protected static readonly ActivitySource ActivitySource = new ActivitySource("MP.IOC"); - protected IConfiguration _configuration = null!; + /// + /// Oggetto gestione FusionCache + /// + protected readonly IFusionCache _cache; + + /// + /// Path base chiavi REDIS + /// + protected readonly string _redisBaseKey = "MP:IOC"; /// /// Abilitazione operazioni tracing generiche /// protected readonly bool _traceEnabled = false; + protected IConfiguration _configuration = null!; + /// /// Oggetto per connessione a REDIS /// @@ -180,8 +194,19 @@ namespace MP.Data.Services protected IDatabase _redisDb = null!; protected JsonSerializerSettings? JSSettings; + protected string MpIoNS = ""; + /// + /// Durata cache Lunga standard (300 sec) + /// + protected int redisLongTimeCache = 300; + + /// + /// Durata cache Breve standard (5 sec) + /// + protected int redisShortTimeCache = 5; + #endregion Protected Fields #region Protected Properties @@ -281,6 +306,75 @@ namespace MP.Data.Services } } + /// + /// Implementa gestione FusionCache+ tracking attività + /// - recupero cache da memoria o da obj esterno + cache memoria + /// - recupero da fetchFunc se mancasse + store in cache L1/L2 + /// + /// + /// + /// + /// + /// + protected async Task GetOrFetchAsync(string operationName, string cacheKey, Func> fetchFunc, TimeSpan expiration, params string[] tagList) + { + using var activity = ActivitySource.StartActivity(operationName); + string source; + var tryGet = await _cache.TryGetAsync(cacheKey); + if (tryGet.HasValue) + { + source = "MEMORY"; + var result = tryGet.Value!; + + activity?.SetTag("data.source", source); + activity?.Stop(); + // se supero la soglia loggo... + if (activity?.Duration.TotalMilliseconds > slowLogThresh) + { + LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); + } + return result; + } + bool fromDb = false; + // cache in redis + var cacheOptions = new FusionCacheEntryOptions() + .SetDuration(expiration) + .SetFailSafe(true); + // cache in RAM per 1/3 del tempo x risparmiare risorse + cacheOptions.MemoryCacheDuration = expiration / 3; + + var final = await _cache.GetOrSetAsync( + cacheKey, + async _ => + { + fromDb = true; + return await fetchFunc(); + }, + options: cacheOptions, + tags: tagList + ); + + source = fromDb ? "DB" : "REDIS"; + activity?.SetTag("data.source", source); + activity?.Stop(); + // switch log in base a source.. + switch (source) + { + case "DB": + LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms", reqLevel: NLog.LogLevel.Info); + break; + + case "REDIS": + LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms", reqLevel: NLog.LogLevel.Debug); + break; + + default: + LogTrace($"{operationName} | {source} | {activity?.Duration.TotalMilliseconds:F4} ms"); + break; + } + return final!; + } + /// /// Helper generale di lettura da cache o da funzione (DB) con caching successivo /// @@ -327,6 +421,18 @@ namespace MP.Data.Services return result!; } + /// + /// Restituisce un timeout dal valore secondi richiesti + tempo random +/-3% + /// + /// + /// + protected TimeSpan GetRandTOut(double durationSec) + { + double noise = (rand.NextDouble() * 0.06) - 0.03; + double rValue = durationSec * (1 + noise); + return TimeSpan.FromSeconds(rValue); + } + /// /// Helper trace messaggio log (SE abilitato) /// @@ -396,6 +502,7 @@ namespace MP.Data.Services #region Private Fields private static Logger Log = LogManager.GetCurrentClassLogger(); + private bool _disposed = false; /// @@ -408,12 +515,14 @@ namespace MP.Data.Services /// private int cacheTtlShort = 60 * 1; + private Random rand = new Random(); + private Random rnd = new Random(); /// - /// Path base chiavi REDIS + /// Soglia minima (ms) per log timing in console /// - protected readonly string _redisBaseKey = "MP:IOC"; + private double slowLogThresh = 0; #endregion Private Fields } diff --git a/MP.Data/Services/IOC/IocService.cs b/MP.Data/Services/IOC/IocService.cs index 416ad3e6..0a709a30 100644 --- a/MP.Data/Services/IOC/IocService.cs +++ b/MP.Data/Services/IOC/IocService.cs @@ -23,17 +23,19 @@ namespace MP.Data.Services.IOC public IocService( IConfiguration config, IConnectionMultiplexer redis, + IFusionCache cache, IIocRepository repo, - IServiceScopeFactory scopeFactory, - //Microsoft.Extensions.Caching.Memory.IMemoryCache cache - IFusionCache cache) : base(config, redis) + IServiceScopeFactory scopeFactory + ) : base(config, cache, redis) { _className = "IocServ"; int.TryParse(config.GetValue("ServerConf:redisLongTimeCache"), out redisLongTimeCache); int.TryParse(config.GetValue("ServerConf:redisShortTimeCache"), out redisShortTimeCache); _repo = repo; _scopeFactory = scopeFactory; - _cache = cache; +#if false + _cache = cache; +#endif } #endregion Public Constructors @@ -79,7 +81,7 @@ namespace MP.Data.Services.IOC result = await GetCurrOdlByProdAsync(idxMacchina); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - _redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); + _redisDb.StringSet(currKey, rawData, GetRandTOut(redisLongTimeCache)); } return result; } @@ -261,16 +263,18 @@ namespace MP.Data.Services.IOC #region Protected Methods +#if false /// /// Restituisce un timeout dai minuti richiesti + tempo random 1..60 sec /// /// /// - protected TimeSpan getRandTOut(double stdMinutes) + protected TimeSpan GetRandTOut(double stdMinutes) { double rndValue = stdMinutes + (double)rand.Next(1, 60) / 60; return TimeSpan.FromMinutes(rndValue); - } + } +#endif #endregion Protected Methods @@ -278,7 +282,9 @@ namespace MP.Data.Services.IOC private static Logger Log = LogManager.GetCurrentClassLogger(); - private readonly IFusionCache _cache; +#if false + private readonly IFusionCache _cache; +#endif private readonly string _className; @@ -295,9 +301,11 @@ namespace MP.Data.Services.IOC /// private string dtFormat = "yyyyMMddHHmmssfff"; +#if false private int redisLongTimeCache = 5; - private int redisShortTimeCache = 2; + private int redisShortTimeCache = 2; +#endif #endregion Private Fields @@ -417,7 +425,7 @@ namespace MP.Data.Services.IOC { result = await _repo.ConfigGetAllAsync(); rawData = JsonConvert.SerializeObject(result); - await _redisDb.StringSetAsync(MP.Data.Utils.redisConfKey, rawData, getRandTOut(redisLongTimeCache)); + await _redisDb.StringSetAsync(MP.Data.Utils.redisConfKey, rawData, GetRandTOut(redisLongTimeCache)); } Log.Debug($"ConfigGetAllAsync Read from {source}"); if (result == null) @@ -544,7 +552,7 @@ namespace MP.Data.Services.IOC var fullList = await Macchine2SlaveGetAllAsync(); result = fullList.Select(x => x.IdxMacchina).ToHashSet(); rawData = JsonConvert.SerializeObject(result); - await _redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10)); + await _redisDb.StringSetAsync(currKey, rawData, GetRandTOut(redisLongTimeCache * 10)); } return result; }, TimeSpan.FromMinutes(15)); @@ -566,7 +574,7 @@ namespace MP.Data.Services.IOC var fullList = await Macchine2SlaveGetAllAsync(); result = fullList.Select(x => x.IdxMacchinaSlave).Distinct().ToHashSet(); rawData = JsonConvert.SerializeObject(result); - await _redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10)); + await _redisDb.StringSetAsync(currKey, rawData, GetRandTOut(redisLongTimeCache * 10)); } return result; }, TimeSpan.FromMinutes(15)); @@ -593,7 +601,7 @@ namespace MP.Data.Services.IOC result = await _repo.Macchine2SlaveAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - await _redisDb.StringSetAsync(currKey, rawData, getRandTOut(redisLongTimeCache * 10)); + await _redisDb.StringSetAsync(currKey, rawData, GetRandTOut(redisLongTimeCache * 10)); } if (result == null) { diff --git a/MP.Data/Services/LandDataService.cs b/MP.Data/Services/LandDataService.cs index a94c0634..1770d3eb 100644 --- a/MP.Data/Services/LandDataService.cs +++ b/MP.Data/Services/LandDataService.cs @@ -14,6 +14,7 @@ using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; +using ZiggyCreatures.Caching.Fusion; namespace MP.Data.Services { @@ -21,7 +22,12 @@ namespace MP.Data.Services { #region Public Constructors - public LandDataService(IConfiguration configuration, IConnectionMultiplexer redConn, Repository.MpLand.IMpLandRepository mpLandRepository) : base(configuration, redConn) + public LandDataService( + IConfiguration configuration, + IConnectionMultiplexer redConn, + IFusionCache cache, + Repository.MpLand.IMpLandRepository mpLandRepository + ) : base(configuration, cache, redConn) { _mpLandRepository = mpLandRepository; // conf DB @@ -46,7 +52,7 @@ namespace MP.Data.Services /// Restituisce info dimensione, tabelle e num righe DB /// /// - public List AllDbInfo() + public async Task> AllDbInfoAsync() { // setup parametri costanti string source = "DB"; @@ -55,7 +61,7 @@ namespace MP.Data.Services List result = new List(); // cerco in _redisConn... string currKey = $"{redisBaseKey}:DbInfo:ALL"; - RedisValue rawData = _redisDb.StringGet(currKey); + RedisValue rawData = await _redisDb.StringGetAsync(currKey); if (rawData.HasValue) { result = JsonConvert.DeserializeObject>($"{rawData}"); @@ -63,17 +69,17 @@ namespace MP.Data.Services } else { - result = _mpLandRepository.AllDbInfoAsync().GetAwaiter().GetResult(); + result = await _mpLandRepository.AllDbInfoAsync(); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); - _redisDb.StringSet(currKey, rawData, UltraFastCache); + await _redisDb.StringSetAsync(currKey, rawData, UltraFastCache); } if (result == null) { result = new List(); } sw.Stop(); - Log.Debug($"AllDbInfo | {source} | {sw.Elapsed.TotalMilliseconds}ms"); + Log.Debug($"AllDbInfoAsync | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; } diff --git a/MP.Data/Services/ListSelectDataSrv.cs b/MP.Data/Services/ListSelectDataSrv.cs index af6b8aef..c93c8e44 100644 --- a/MP.Data/Services/ListSelectDataSrv.cs +++ b/MP.Data/Services/ListSelectDataSrv.cs @@ -12,6 +12,7 @@ using System.Data; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; +using ZiggyCreatures.Caching.Fusion; namespace MP.Data.Services { @@ -33,7 +34,14 @@ namespace MP.Data.Services #region Public Constructors - public ListSelectDataSrv(IConfiguration configuration, IConnectionMultiplexer redConn, IAnagRepository anagRepository, IProductionRepository productionRepository, ISystemRepository systemRepository) : base(configuration, redConn) + public ListSelectDataSrv( + IConfiguration configuration, + IConnectionMultiplexer redConn, + IFusionCache cache, + IAnagRepository anagRepository, + IProductionRepository productionRepository, + ISystemRepository systemRepository + ) : base(configuration, cache, redConn) { _anagRepository = anagRepository; _productionRepository = productionRepository; diff --git a/MP.Data/Services/Mtc/MtcSetupService.cs b/MP.Data/Services/Mtc/MtcSetupService.cs index 8ea00bf4..8a003d9f 100644 --- a/MP.Data/Services/Mtc/MtcSetupService.cs +++ b/MP.Data/Services/Mtc/MtcSetupService.cs @@ -5,6 +5,7 @@ using MP.Data.Repository.Mtc; using StackExchange.Redis; using System.Collections.Generic; using System.Threading.Tasks; +using ZiggyCreatures.Caching.Fusion; namespace MP.Data.Services.Mtc { @@ -18,7 +19,8 @@ namespace MP.Data.Services.Mtc public MtcSetupService( IConfiguration config, IConnectionMultiplexer redis, - IMtcSetupRepository repo) : base(config, redis) + IFusionCache cache, + IMtcSetupRepository repo) : base(config, cache, redis) { _className = "MtcSetup"; _repo = repo; diff --git a/MP.Data/Services/OrderDataSrv.cs b/MP.Data/Services/OrderDataSrv.cs index 22140226..0f5ec926 100644 --- a/MP.Data/Services/OrderDataSrv.cs +++ b/MP.Data/Services/OrderDataSrv.cs @@ -11,6 +11,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Threading.Tasks; +using ZiggyCreatures.Caching.Fusion; namespace MP.Data.Services { @@ -31,7 +32,13 @@ namespace MP.Data.Services #region Public Constructors - public OrderDataSrv(IConfiguration configuration, IConnectionMultiplexer redConn, IProductionRepository productionRepository, ISystemRepository systemRepository) : base(configuration, redConn) + public OrderDataSrv( + IConfiguration configuration, + IConnectionMultiplexer redConn, + IFusionCache cache, + IProductionRepository productionRepository, + ISystemRepository systemRepository + ) : base(configuration, cache, redConn) { _productionRepository = productionRepository; _systemRepository = systemRepository; diff --git a/MP.Data/Services/SchedulerDataService.cs b/MP.Data/Services/SchedulerDataService.cs index 46bb8638..6644187f 100644 --- a/MP.Data/Services/SchedulerDataService.cs +++ b/MP.Data/Services/SchedulerDataService.cs @@ -4,6 +4,7 @@ using StackExchange.Redis; using System; using System.Collections.Generic; using System.Threading.Tasks; +using ZiggyCreatures.Caching.Fusion; namespace MP.Data.Services { @@ -13,7 +14,11 @@ namespace MP.Data.Services /// Init servizio TAB /// /// - public SchedulerDataService(IConfiguration configuration, IConnectionMultiplexer redConn) : base(configuration, redConn) + public SchedulerDataService( + IConfiguration configuration, + IConnectionMultiplexer redConn, + IFusionCache cache + ) : base(configuration, cache, redConn) { _configuration = configuration; diff --git a/MP.Data/Services/SharedMemService.cs b/MP.Data/Services/SharedMemService.cs index 6609ecc1..93fd6e28 100644 --- a/MP.Data/Services/SharedMemService.cs +++ b/MP.Data/Services/SharedMemService.cs @@ -4,6 +4,7 @@ using NLog; using StackExchange.Redis; using System.Collections.Generic; using System.Linq; +using ZiggyCreatures.Caching.Fusion; namespace MP.Data.Services { @@ -15,7 +16,11 @@ namespace MP.Data.Services /// Init servizio TAB /// /// - public SharedMemService(IConfiguration configuration, IConnectionMultiplexer redConn) : base(configuration, redConn) + public SharedMemService( + IConfiguration configuration, + IConnectionMultiplexer redConn, + IFusionCache cache + ) : base(configuration, cache, redConn) { } diff --git a/MP.Data/Services/TabDataService.cs b/MP.Data/Services/TabDataService.cs index 948ee410..0ee1616f 100644 --- a/MP.Data/Services/TabDataService.cs +++ b/MP.Data/Services/TabDataService.cs @@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using MP.Core.DTO; using MP.Core.Objects; +using MP.Data.Controllers; using MP.Data.DbModels; using Newtonsoft.Json; using NLog; @@ -15,6 +16,7 @@ using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; +using ZiggyCreatures.Caching.Fusion; namespace MP.Data.Services { @@ -26,7 +28,12 @@ namespace MP.Data.Services /// Init servizio TAB /// /// - public TabDataService(IConfiguration configuration, IConnectionMultiplexer redConn) : base(configuration, redConn) + public TabDataService( + IConfiguration configuration, + IConnectionMultiplexer redConn, + IFusionCache cache, + MpIocController iocContr + ) : base(configuration, cache, redConn) { _configuration = configuration; @@ -41,7 +48,7 @@ namespace MP.Data.Services StringBuilder sb = new StringBuilder(); dbTabController = new Controllers.MpTabController(configuration); sb.AppendLine($"TabDataService | MpTabController OK"); - dbIocController = new Controllers.MpIocController(configuration); + dbIocController = iocContr;// new Controllers.MpIocController(configuration); sb.AppendLine($"TabDataService | MpIocController OK"); dbInveController = new Controllers.MpInveController(configuration); sb.AppendLine($"TabDataService | MpInveController OK"); diff --git a/MP.Data/Services/TranslateSrv.cs b/MP.Data/Services/TranslateSrv.cs index b29fa641..f3ffdfde 100644 --- a/MP.Data/Services/TranslateSrv.cs +++ b/MP.Data/Services/TranslateSrv.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Configuration; using MP.Core.Conf; using MP.Data.DbModels; +using MP.Data.Repository.FluxLog; using Newtonsoft.Json; using NLog; using StackExchange.Redis; @@ -13,6 +14,7 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using ZiggyCreatures.Caching.Fusion; namespace MP.Data.Services { @@ -23,30 +25,57 @@ namespace MP.Data.Services { #region Public Constructors - public TranslateSrv(IConfiguration configuration, IConnectionMultiplexer redConn, Repository.MpVoc.IMpVocRepository mpVocRepository) : base(configuration, redConn) + public TranslateSrv( + IConfiguration configuration, + IConnectionMultiplexer redConn, + IFusionCache cache, + Repository.MpVoc.IMpVocRepository mpVocRepository + ) : base(configuration, cache, redConn) { _mpVocRepository = mpVocRepository; - Stopwatch sw = new Stopwatch(); - sw.Start(); - // conf DB - string connStr = _configuration.GetConnectionString("MP.Voc"); - if (string.IsNullOrEmpty(connStr)) - { - Log.Error("MP.Voc: ConnString empty!"); - } - else - { - var _ = _mpVocRepository.ConfigGetAllAsync().GetAwaiter().GetResult(); - InitDict(); - sw.Stop(); - Log.Info($"TranslateSrv | MpVocRepository OK | {sw.Elapsed.TotalMilliseconds} ms"); - } } #endregion Public Constructors #region Public Methods + /// + /// Esegue traduzione dato vocabolario da Lingua + Lemma + /// + /// + /// + /// + public string Traduci(string lemma, string lingua = "IT") + { + if (string.IsNullOrWhiteSpace(lemma)) return string.Empty; + if (string.IsNullOrWhiteSpace(lingua)) return lemma; + + string linguaKey = lingua.ToLowerInvariant().Trim(); + string cacheKey = $"vocab:{linguaKey}"; + + // FusionCache gestisce il lock e recupera l'intero dizionario della lingua. + // Se è in L1 (Memory), restituisce l'oggetto C# istantaneamente. + // Se non c'è, passa a L2 (Redis) o invoca la factory per caricarlo. + var dizionarioLingua = _cache.GetOrSet>( + cacheKey, + _ => _mpVocRepository.VocabolarioGetLang(linguaKey), + options => options + .SetDuration(TimeSpan.FromHours(8)) // Durata logica della cache + .SetFailSafe(true, TimeSpan.FromHours(1)) // Se Redis/DB è giù, usa i vecchi dati L1 + ); + + // Ricerca O(1) nel dizionario in memoria + if (dizionarioLingua != null && dizionarioLingua.TryGetValue(lemma, out var traduzione)) + { + return traduzione; + } + + // Fallback: se la parola non è censita, restituisce il lemma originale (lingua + lemma) + return $"{lingua}_{lemma}"; + } + + +#if false /// /// Recupero elenco config /// @@ -80,7 +109,8 @@ namespace MP.Data.Services sw.Stop(); Log.Debug($"ConfigGetAllAsync | {source} | {sw.Elapsed.TotalMilliseconds}ms"); return result; - } + } +#endif /// /// Pulizia cache Redis (tutta) @@ -88,12 +118,15 @@ namespace MP.Data.Services /// public async Task FlushCache() { +#if false RedisValue pattern = new RedisValue($"{redisBaseKey}:*"); bool answ = await ExecFlushRedisPattern(pattern); // rileggo vocabolario! var rawData = await VocabolarioGetAll(); DictVocab = rawData.ToDictionary(kvp => $"{kvp.Lingua}_{kvp.Lemma}".ToUpper(), kvp => kvp.Traduzione); - return answ; + return answ; +#endif + return await FlushFusionCacheAsync(); } /// @@ -102,9 +135,51 @@ namespace MP.Data.Services /// public async Task FlushCache(string KeyReq) { +#if false RedisValue pattern = new RedisValue($"{redisBaseKey}:{KeyReq}:*"); bool answ = await ExecFlushRedisPattern(pattern); - return answ; + return answ; +#endif + return await FlushFusionCacheAsync(KeyReq); + } + + /// + /// Cancellazione FusionCache (totale) + /// + /// + private async Task FlushFusionCacheAsync() + { + await _cache.ClearAsync(allowFailSafe: false); + return true; + } + + /// + /// Cancellazione FusionCache dato singolo tag + /// + /// + private async Task FlushFusionCacheAsync(string tag) + { + if (string.IsNullOrWhiteSpace(tag)) return false; + + await _cache.RemoveByTagAsync(tag); + return true; + } + + /// + /// Cancellazione FusionCache dato elenco tags + /// + /// + private async Task FlushFusionCacheAsync(List listTags) + { + if (listTags == null || listTags.Count == 0) return false; + + // Generiamo i Task di rimozione ed eseguiamoli in parallelo su Redis/L1 + var tasks = listTags + .Where(tag => !string.IsNullOrWhiteSpace(tag)) + .Select(tag => _cache.RemoveByTagAsync(tag).AsTask()); + + await Task.WhenAll(tasks); + return true; } /// @@ -113,6 +188,17 @@ namespace MP.Data.Services /// public async Task> LingueGetAll() { + string currKey = $"{redisBaseKey}:Lang"; + + return await GetOrFetchAsync( + operationName: "LingueGetAll", + cacheKey: currKey, + expiration: GetRandTOut(redisShortTimeCache), + fetchFunc: async () => await _mpVocRepository.LingueGetAllAsync() ?? new(), + tagList: [currKey] + ); + +#if false string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); @@ -139,9 +225,11 @@ namespace MP.Data.Services } sw.Stop(); Log.Debug($"LingueGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); - return result; + return result; +#endif } +#if false /// /// Traduzione termine /// @@ -157,7 +245,8 @@ namespace MP.Data.Services answ = DictVocab[key]; } return answ; - } + } +#endif /// /// Recupero elenco config @@ -165,6 +254,18 @@ namespace MP.Data.Services /// public async Task> VocabolarioGetAll() { + string currKey = $"{redisBaseKey}:VocAll"; + + return await GetOrFetchAsync( + operationName: "VocabolarioGetAll", + cacheKey: currKey, + expiration: GetRandTOut(redisShortTimeCache), + fetchFunc: async () => await _mpVocRepository.VocabolarioGetAllAsync() ?? new(), + tagList: [currKey] + ); + + +#if false string source = "DB"; Stopwatch sw = new Stopwatch(); sw.Start(); @@ -191,46 +292,31 @@ namespace MP.Data.Services } sw.Stop(); Log.Debug($"VocabolarioGetAll | {source} | {sw.Elapsed.TotalMilliseconds}ms"); - return result; + return result; +#endif } #endregion Public Methods #region Protected Fields +#if false /// /// Vocabolario x recupero rapido traduzioni /// - protected static Dictionary DictVocab = new Dictionary(); + protected static Dictionary DictVocab = new Dictionary(); +#endif #endregion Protected Fields #region Protected Methods - protected override void Dispose(bool disposing) - { - if (!_disposed) - { - if (disposing) - { - // Free managed resources here - DictVocab.Clear(); - } - - // Free unmanaged resources here - _disposed = true; - } - - // Call base class implementation. - base.Dispose(disposing); - } - #endregion Protected Methods #region Private Fields private static Logger Log = LogManager.GetCurrentClassLogger(); - private bool _disposed = false; + private string redisBaseKey = "MP:Voc:Cache"; private readonly Repository.MpVoc.IMpVocRepository _mpVocRepository; @@ -239,16 +325,8 @@ namespace MP.Data.Services #region Private Methods - /// - /// Inizializzazione dict vari - /// - private void InitDict() - { - // inizializzo dizionario vocabolario - var rawData = _mpVocRepository.VocabolarioGetAllAsync().GetAwaiter().GetResult(); - DictVocab = rawData.ToDictionary(kvp => $"{kvp.Lingua}_{kvp.Lemma}".ToUpper(), kvp => kvp.Traduzione); - } +#if false /// /// Esegue flush memoria _redisConn dato pat2Flush /// @@ -287,26 +365,10 @@ namespace MP.Data.Services } } answ = true; -#if false - var listEndpoints = redisConn.GetEndPoints(); - foreach (var endPoint in listEndpoints) - { - //var server = redisConnAdmin.GetServer(listEndpoints[0]); - var server = redisConn.GetServer(endPoint); - if (server != null) - { - var keyList = server.Keys(redisDb.Database, pattern); - foreach (var item in keyList) - { - await redisDb.KeyDeleteAsync(item); - } - answ = true; - } - } -#endif return answ; - } + } +#endif #endregion Private Methods } diff --git a/MP.Data/Services/Utils/StatsAggrService.cs b/MP.Data/Services/Utils/StatsAggrService.cs index 411b463c..a322b84e 100644 --- a/MP.Data/Services/Utils/StatsAggrService.cs +++ b/MP.Data/Services/Utils/StatsAggrService.cs @@ -9,6 +9,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using ZiggyCreatures.Caching.Fusion; namespace MP.Data.Services.Utils { @@ -19,7 +20,8 @@ namespace MP.Data.Services.Utils public StatsAggrService( IConfiguration config, IConnectionMultiplexer redis, - IStatsAggrRepository repo) : base(config, redis) + IFusionCache cache, + IStatsAggrRepository repo) : base(config, cache, redis) { _className = "StatsAggr"; _repo = repo; diff --git a/MP.Data/Services/Utils/StatsCodeService.cs b/MP.Data/Services/Utils/StatsCodeService.cs index 3d2bf4df..8e2b262b 100644 --- a/MP.Data/Services/Utils/StatsCodeService.cs +++ b/MP.Data/Services/Utils/StatsCodeService.cs @@ -9,6 +9,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using ZiggyCreatures.Caching.Fusion; namespace MP.Data.Services.Utils { @@ -19,7 +20,9 @@ namespace MP.Data.Services.Utils public StatsCodeService( IConfiguration config, IConnectionMultiplexer redis, - IStatsCodeRepository repo) : base(config, redis) + IFusionCache cache, + IStatsCodeRepository repo + ) : base(config, cache, redis) { _className = "StatsStatusCode"; _repo = repo; diff --git a/MP.Data/Services/Utils/StatsDetailService.cs b/MP.Data/Services/Utils/StatsDetailService.cs index 75738f4d..b637b33d 100644 --- a/MP.Data/Services/Utils/StatsDetailService.cs +++ b/MP.Data/Services/Utils/StatsDetailService.cs @@ -9,6 +9,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using ZiggyCreatures.Caching.Fusion; namespace MP.Data.Services.Utils { @@ -19,7 +20,9 @@ namespace MP.Data.Services.Utils public StatsDetailService( IConfiguration config, IConnectionMultiplexer redis, - IStatsDetailRepository repo) : base(config, redis) + IFusionCache cache, + IStatsDetailRepository repo + ) : base(config,cache, redis) { _className = "StatsDetail"; _repo = repo; diff --git a/MP.Data/Services/Utils/StatsErrService.cs b/MP.Data/Services/Utils/StatsErrService.cs index 26e76309..36e5c8e4 100644 --- a/MP.Data/Services/Utils/StatsErrService.cs +++ b/MP.Data/Services/Utils/StatsErrService.cs @@ -9,6 +9,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using ZiggyCreatures.Caching.Fusion; namespace MP.Data.Services.Utils { @@ -19,7 +20,9 @@ namespace MP.Data.Services.Utils public StatsErrService( IConfiguration config, IConnectionMultiplexer redis, - IStatsErrRepository repo) : base(config, redis) + IFusionCache cache, + IStatsErrRepository repo + ) : base(config,cache, redis) { _className = "StatsErr"; _repo = repo; diff --git a/MP.SPEC/Components/AskCloseOdl.razor.cs b/MP.SPEC/Components/AskCloseOdl.razor.cs index 2a78e714..62a98b32 100644 --- a/MP.SPEC/Components/AskCloseOdl.razor.cs +++ b/MP.SPEC/Components/AskCloseOdl.razor.cs @@ -55,8 +55,7 @@ namespace MP.SPEC.Components } // eseguo chiusura finale CurrAction.IsActive = false; - MDService.ActionSetReqAsync(CurrAction); - await Task.Delay(1); + await MDService.ActionSetReqAsync(CurrAction); } protected async Task doConfirm() diff --git a/MP.SPEC/Components/Reparti/ListOperatori.razor b/MP.SPEC/Components/Reparti/ListOperatori.razor index 959835cb..93bfcd3d 100644 --- a/MP.SPEC/Components/Reparti/ListOperatori.razor +++ b/MP.SPEC/Components/Reparti/ListOperatori.razor @@ -5,7 +5,10 @@

                                                                                                            Operatori

                                              - + @if (AddEnabled) + { + + }
                                              @@ -33,25 +36,51 @@ + - + @if (DelEnabled) + { + + } + @if (StaChgEnab) + { + + } - @foreach (var record in ListRecords) + @foreach (var item in ListRecords) { - + - - - + @if (DelEnabled) + { + + } + @if (StaChgEnab) + { + + } } diff --git a/MP.SPEC/Components/Reparti/ListOperatori.razor.cs b/MP.SPEC/Components/Reparti/ListOperatori.razor.cs index 2ca7dcab..03bf5bca 100644 --- a/MP.SPEC/Components/Reparti/ListOperatori.razor.cs +++ b/MP.SPEC/Components/Reparti/ListOperatori.razor.cs @@ -9,6 +9,9 @@ namespace MP.SPEC.Components.Reparti { #region Public Properties + [Parameter] + public bool AddEnabled { get; set; } = true; + [Parameter] public List? AllRecords { get; set; } = null; @@ -18,9 +21,18 @@ namespace MP.SPEC.Components.Reparti [Parameter] public List? CurrRecords { get; set; } = null; + [Parameter] + public bool DelEnabled { get; set; } = true; + [Parameter] public EventCallback EC_RecChange { get; set; } + [Parameter] + public EventCallback EC_RecSel { get; set; } + + [Parameter] + public bool StaChgEnab { get; set; } = false; + #endregion Public Properties #region Protected Properties @@ -37,7 +49,7 @@ namespace MP.SPEC.Components.Reparti protected override void OnParametersSet() { - numRecord = 10; + //numRecord = 10; UpdateTable(); } @@ -65,7 +77,9 @@ namespace MP.SPEC.Components.Reparti private bool isLoading = false; private List? ListAvail; + private List? ListRecords; + private int numRecord = 5; private int totalCount = 0; @@ -93,6 +107,18 @@ namespace MP.SPEC.Components.Reparti #region Private Methods + private string cssCol(AnagOperatoriModel currRec) + { + return !currRec.isEnabled ? "opacity-75" : ""; + } + + private string cssRow(AnagOperatoriModel currRec) + { + string answ = selRec != null && currRec.MatrOpr == selRec.MatrOpr ? "table-info " : ""; + answ += !currRec.isEnabled ? "text-secondary disabled text-decoration-line-through" : ""; + return answ; + } + private async Task DoAdd(AnagOperatoriModel currRec) { // eliminazione dal gruppo @@ -120,6 +146,19 @@ namespace MP.SPEC.Components.Reparti await EC_RecChange.InvokeAsync(false); } + private AnagOperatoriModel? selRec = null; + + private async Task DoSelect(AnagOperatoriModel sRec) + { + selRec = sRec; + await EC_RecSel.InvokeAsync(sRec); + } + private async Task DoReset() + { + selRec = null; + await EC_RecSel.InvokeAsync(null); + } + private async Task ReportUpdate(bool force) { AddNewEnabled = false; @@ -131,6 +170,17 @@ namespace MP.SPEC.Components.Reparti AddNewEnabled = !AddNewEnabled; } + private async Task ToggleStatusOpr(AnagOperatoriModel updRec) + { + string azione = updRec.isEnabled ? "disabilitarlo" : "abilitarlo"; + if (!await JSRuntime.InvokeAsync("confirm", $"Sicuro di voler modificare l'operatore per {azione}?")) + return; + + updRec.isEnabled = !updRec.isEnabled; + await MDService.OperatoriUpsertAsync(updRec); + await EC_RecChange.InvokeAsync(true); + } + private void UpdateTable() { ListRecords = new(); diff --git a/MP.SPEC/Components/Reparti/ListReparti.razor b/MP.SPEC/Components/Reparti/ListReparti.razor index 4189ceba..b8a1b5f6 100644 --- a/MP.SPEC/Components/Reparti/ListReparti.razor +++ b/MP.SPEC/Components/Reparti/ListReparti.razor @@ -5,7 +5,7 @@

                                              Elenco Reparti

                                              - @if (SelRecord == null && IsSuperAdmin) + @if (SelRecord == null && IsSuperAdmin && EditEnabled) { } @@ -95,17 +95,20 @@ {
                                              @if (SelRecord == null) @@ -122,13 +125,16 @@ } diff --git a/MP.SPEC/Components/Reparti/ListReparti.razor.cs b/MP.SPEC/Components/Reparti/ListReparti.razor.cs index 1582c6fa..3f65ced9 100644 --- a/MP.SPEC/Components/Reparti/ListReparti.razor.cs +++ b/MP.SPEC/Components/Reparti/ListReparti.razor.cs @@ -17,6 +17,9 @@ namespace MP.SPEC.Components.Reparti [Parameter] public string CodGruppoSel { get; set; } = null!; + [Parameter] + public bool EditEnabled { get; set; } = true; + [Parameter] public EventCallback EC_RecordSel { get; set; } diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index 951addc4..f6768500 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -702,6 +702,20 @@ namespace MP.SPEC.Data tagList: [Utils.redisAnagGruppi] ); } + /// + /// Restitusice elenco Reparti + /// + /// + public async Task> GruppiRepartoDtoByOperAsync(int matrOpr) + { + return await GetOrFetchAsync( + operationName: "ElencoRepartiDtoAsync", + cacheKey: $"{Utils.redisAnagGruppiOpr}:{matrOpr}", + expiration: GetRandTOut(redisLongTimeCache), + fetchFunc: async () => await _anagRepository.GruppiRepartoDtoByOperAsync(matrOpr) ?? new(), + tagList: [Utils.redisAnagGruppiOpr] + ); + } /// /// Caricamento asincrono della cache degli articoli (Used/Unused) @@ -1408,6 +1422,25 @@ namespace MP.SPEC.Data ); } + /// + /// Aggiornamento operatori su DB + invalidata cache + /// + /// + /// + public async Task OperatoriUpsertAsync(AnagOperatoriModel updRec) + { + using var activity = ActivitySource.StartActivity("OperatoriUpsertAsync"); + string source = "DB"; + bool fatto = false; + // salvo + fatto = await _productionRepository.OperatoriUpsertAsync(updRec); + await FlushFusionCacheAsync(Utils.redisOprList); + activity?.SetTag("data.source", source); + activity?.Stop(); + LogTrace($"OperatoriUpsertAsync | {source} | {activity?.Duration.TotalMilliseconds}ms"); + return fatto; + } + /// /// Elenco di tutti i parametri filtrati x idxMaccSel /// diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 85941120..0c0a71b8 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2606.311 + 8.16.2606.317 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Operatori.razor b/MP.SPEC/Pages/Operatori.razor new file mode 100644 index 00000000..b1fcb4a3 --- /dev/null +++ b/MP.SPEC/Pages/Operatori.razor @@ -0,0 +1,41 @@ +@page "/operatori" + +
                                              +
                                              +
                                              +
                                              +
                                              +
                                              + Gestione Operatori +
                                              +
                                              +
                                              +
                                              + @* Edit Massivo Fermi *@ +
                                              +
                                              +
                                              +
                                              + @if (isLoading) + { + + } + else + { +
                                              +
                                              + +
                                              + @if (SelRec != null) + { +
                                              + +
                                              + } +
                                              + + } +
                                              +
                                              + + diff --git a/MP.SPEC/Pages/Operatori.razor.cs b/MP.SPEC/Pages/Operatori.razor.cs new file mode 100644 index 00000000..75ec7e16 --- /dev/null +++ b/MP.SPEC/Pages/Operatori.razor.cs @@ -0,0 +1,66 @@ +using Microsoft.AspNetCore.Components; +using MP.Core.DTO; +using MP.Data.DbModels; +using MP.SPEC.Data; + +namespace MP.SPEC.Pages +{ + public partial class Operatori + { + #region Protected Properties + + [Inject] + protected MpDataService MDService { get; set; } = null!; + + #endregion Protected Properties + + #region Protected Methods + + protected override async Task OnInitializedAsync() + { + await ReloadDataAsync(); + } + + #endregion Protected Methods + + #region Private Fields + + private bool isLoading = false; + private List ListOperatori = new(); + private List ListGruppi = new(); + private AnagOperatoriModel? SelRec = null; + + #endregion Private Fields + + #region Private Properties + + private string cssMain => SelRec == null ? "col-12" : "col-6"; + + #endregion Private Properties + + #region Private Methods + + private async Task ReloadDataAsync() + { + isLoading = true; + ListOperatori = await MDService.OperatoriGetFiltAsync("*"); + isLoading = false; + } + + private async Task ShowDetail(AnagOperatoriModel? newRec) + { + SelRec = newRec; + if (SelRec == null) + { + ListGruppi.Clear(); + } + else + { + // recupero gruppi operatore + ListGruppi = await MDService.GruppiRepartoDtoByOperAsync(SelRec.MatrOpr); + } + } + + #endregion Private Methods + } +} \ No newline at end of file diff --git a/MP.SPEC/Program.cs b/MP.SPEC/Program.cs index 64fd379e..04f79f14 100644 --- a/MP.SPEC/Program.cs +++ b/MP.SPEC/Program.cs @@ -170,7 +170,14 @@ builder.Services.AddDbContextFactory(options => .EnableSensitiveDataLogging(false) // true solo in Sviluppo .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); -// MP.Data Services Utils - Statistiche DB +var connStrFL = builder.Configuration.GetConnectionString("MP.Flux") + ?? throw new InvalidOperationException("ConnString 'MP.Flux' mancante."); +builder.Services.AddDbContextFactory(options => + options.UseSqlServer(connStrFL) + .EnableSensitiveDataLogging(false) // true solo in Sviluppo + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); + +// Init centralizzato Repository/Servizi da MP.Data Services builder.Services.AddSpecDataLayer(); // servizi del progetto SPEC diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 40cd97d7..56193a1d 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                              Versione: 8.16.2606.311

                                              +

                                              Versione: 8.16.2606.317


                                              Note di rilascio:
                                              • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index aa5451d0..8c2eaf7f 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.311 +8.16.2606.317 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index c283f196..e67b9b17 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.311 + 8.16.2606.317 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From fab32124d8f196f918159af67ce33b0e02ce113b Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 3 Jun 2026 18:12:16 +0200 Subject: [PATCH 097/102] RIOC: - fix compilazione con prerequisiti vari - fx init program.cs x dbcontext --- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Program.cs | 9 ++++++--- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.RIOC/appsettings.json | 1 + 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index 7bc99308..03533e4f 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2606.311 + 8.16.2606.318 diff --git a/MP.RIOC/Program.cs b/MP.RIOC/Program.cs index 6ba4f593..489b29dd 100644 --- a/MP.RIOC/Program.cs +++ b/MP.RIOC/Program.cs @@ -37,13 +37,16 @@ logger.Info("RedisScript Provider configured"); // Metodi principali x accesso dati var connStr = builder.Configuration.GetConnectionString("MP.Data") ?? throw new InvalidOperationException("ConnString 'MP.Data' mancante."); - -//builder.Services.AddMemoryCache(); - builder.Services.AddDbContextFactory(options => options.UseSqlServer(connStr) .EnableSensitiveDataLogging(false) // true solo in Sviluppo .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); +var connStrFL = builder.Configuration.GetConnectionString("MP.Flux") + ?? throw new InvalidOperationException("ConnString 'MP.Flux' mancante."); +builder.Services.AddDbContextFactory(options => + options.UseSqlServer(connStrFL) + .EnableSensitiveDataLogging(false) // true solo in Sviluppo + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); // MP.Data DbContext for Stats repositories string utilsConnString = builder.Configuration.GetConnectionString("MP.Utils") ?? "Server=localhost;Database=MoonPro_Utils; integrated security=True; MultipleActiveResultSets=True; App=MP.IOC;"; diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index 0271b927..c71c5486 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                Versione: 8.16.2606.311

                                                +

                                                Versione: 8.16.2606.318


                                                Note di rilascio:
                                                • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index aa5451d0..ea702b6d 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.311 +8.16.2606.318 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index 9fb2ac1c..734be1e1 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.311 + 8.16.2606.318 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/appsettings.json b/MP.RIOC/appsettings.json index 2c648666..958cb8ba 100644 --- a/MP.RIOC/appsettings.json +++ b/MP.RIOC/appsettings.json @@ -82,6 +82,7 @@ "ConnectionStrings": { "MP.Data": "Server=SQL2016DEV;Database=MoonPro; User ID=sa;Password=keyhammer16; integrated security=False; App=MP.IOC;", "MP.Utils": "Server=SQL2016DEV;Database=MoonPro_Utils; User ID=sa;Password=keyhammer16; integrated security=False; App=MP.RIOC;", + "MP.Flux": "Server=SQL2016DEV;Database=MoonPro_FluxData; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.RIOC;", "Redis": "redis.ufficio:26379,serviceName=devel,DefaultDatabase=5,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false", "RedisAdmin": "redis.ufficio:26379,serviceName=devel,DefaultDatabase=5,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,allowAdmin=true" } From febe1d0132c09bd56aaaaec410fb3fd167e479ae Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 3 Jun 2026 18:23:12 +0200 Subject: [PATCH 098/102] IOC: - completata review program.cs - fix temporaneo init servizi data interni (da rivedere con FusionCache ...) --- MP.Data/DataServiceCollectionExtensions.cs | 1 + MP.IOC/Data/MpDataService.cs | 20 +++++++++++++++----- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Program.cs | 16 ++++++++++++---- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- 7 files changed, 32 insertions(+), 13 deletions(-) diff --git a/MP.Data/DataServiceCollectionExtensions.cs b/MP.Data/DataServiceCollectionExtensions.cs index 2adc1d06..8ed9107a 100644 --- a/MP.Data/DataServiceCollectionExtensions.cs +++ b/MP.Data/DataServiceCollectionExtensions.cs @@ -34,6 +34,7 @@ namespace MP.Data { // Repository Singleton services.TryAddSingleton(); + services.TryAddSingleton(); // Repository Scoped services.TryAddScoped(); diff --git a/MP.IOC/Data/MpDataService.cs b/MP.IOC/Data/MpDataService.cs index fed66bf3..87ed22a2 100644 --- a/MP.IOC/Data/MpDataService.cs +++ b/MP.IOC/Data/MpDataService.cs @@ -7,6 +7,7 @@ using MP.Data.Controllers; using MP.Data.DbModels; using MP.Data.DbModels.Anag; using MP.Data.MgModels; +using MP.Data.Repository.Production; using MP.Data.Services.IOC; using MP.Data.Services.Mtc; using Newtonsoft.Json; @@ -22,17 +23,22 @@ namespace MP.IOC.Data public class MpDataService { #region Public Constructors + private readonly IProductionRepository _productionRepository; public MpDataService( IConfiguration configuration, ILogger logger, IServiceScopeFactory scopeFactory, + IProductionRepository productionRepository, + MpIocController mpIocCtr, IMtcSetupService mtcServ) { _logger = logger; _logger.LogInformation("Starting MpDataService INIT"); _configuration = configuration; _scopeFactory = scopeFactory; + _productionRepository = productionRepository; + IocDbController = mpIocCtr; // setup compoenti REDIS redisConn = ConnectionMultiplexer.Connect(_configuration.GetConnectionString("Redis")); @@ -58,8 +64,10 @@ namespace MP.IOC.Data } else { - SpecDbController = new MpSpecController(configuration); +#if false + SpecDbController = new MpSpecController(configuration); IocDbController = new MpIocController(configuration); +#endif Log.Info("DbControllers INIT OK"); } @@ -83,9 +91,11 @@ namespace MP.IOC.Data #region Public Properties - public static MpIocController IocDbController { get; set; } = null!; public static MpMongoController mongoController { get; set; } = null!; - public static MpSpecController SpecDbController { get; set; } = null!; + public static MpIocController IocDbController { get; set; } = null!; +#if false + public static MpSpecController SpecDbController { get; set; } = null!; +#endif public MessagePipe BroadastMsgPipe { get; set; } = null!; /// @@ -1209,7 +1219,7 @@ namespace MP.IOC.Data } else { - result = await SpecDbController.MacchineGetFiltAsync(codGruppo); + result = await _productionRepository.MacchineGetFiltAsync(codGruppo); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); @@ -1622,7 +1632,7 @@ namespace MP.IOC.Data } else { - result = await SpecDbController.PODL_getByKeyAsync(idxPODL); + result = await _productionRepository.PODL_getByKeyAsync(idxPODL); // serializzo e salvo... rawData = JsonConvert.SerializeObject(result); redisDb.StringSet(currKey, rawData, getRandTOut(redisLongTimeCache)); diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 88739b41..29e1b914 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2606.311 + 8.16.2606.318 diff --git a/MP.IOC/Program.cs b/MP.IOC/Program.cs index 8a3df56f..8945acd4 100644 --- a/MP.IOC/Program.cs +++ b/MP.IOC/Program.cs @@ -42,18 +42,26 @@ logger.Info("RedisScript Provider configured"); // Metodi principali x accesso dati var connStr = builder.Configuration.GetConnectionString("MP.Data") ?? throw new InvalidOperationException("ConnString 'MP.Data' mancante."); - builder.Services.AddMemoryCache(); - builder.Services.AddDbContextFactory(options => options.UseSqlServer(connStr) .EnableSensitiveDataLogging(false) // true solo in Sviluppo .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); // MP.Data DbContext for Stats repositories -string utilsConnString = builder.Configuration.GetConnectionString("MP.Utils") ?? "Server=localhost;Database=MoonPro_Utils; integrated security=True; MultipleActiveResultSets=True; App=MP.IOC;"; +string connStrUtils = builder.Configuration.GetConnectionString("MP.Utils") + ?? throw new InvalidOperationException("ConnString 'MP.Utils' mancante."); +//?? "Server=localhost;Database=MoonPro_Utils; integrated security=True; MultipleActiveResultSets=True; App=MP.IOC;"; builder.Services.AddDbContextFactory(options => - options.UseSqlServer(utilsConnString)); + options.UseSqlServer(connStrUtils).EnableSensitiveDataLogging(false) + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); + +var connStrFL = builder.Configuration.GetConnectionString("MP.Flux") + ?? throw new InvalidOperationException("ConnString 'MP.Flux' mancante."); +builder.Services.AddDbContextFactory(options => + options.UseSqlServer(connStrFL) + .EnableSensitiveDataLogging(false) // true solo in Sviluppo + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); // MP.Data Services Utils - Statistiche DB builder.Services.AddIocDataLayer(); diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 55fd6939..0f1cd517 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                  Versione: 8.16.2606.311

                                                  +

                                                  Versione: 8.16.2606.318


                                                  Note di rilascio:
                                                  • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index aa5451d0..ea702b6d 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.311 +8.16.2606.318 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 92f155e7..1ddeedf0 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.311 + 8.16.2606.318 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false From 217836099ccea0d1f525e9caba6ed55111fc018f Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 3 Jun 2026 18:32:51 +0200 Subject: [PATCH 099/102] LAND: - fix program.cs startup - fix calcolo dim DB - fix IOB count --- MP.Data/DataServiceCollectionExtensions.cs | 1 + MP.Data/Repository/MpLand/MpLandRepository.cs | 8 ++++- MP.Data/Services/LandDataService.cs | 16 ++++----- MP.Land/Components/DbInfoMan.razor.cs | 10 +++--- MP.Land/MP.Land.csproj | 2 +- MP.Land/Pages/IobList.razor.cs | 6 ++-- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.Land/Startup.cs | 33 +++++++++++++++++-- 10 files changed, 60 insertions(+), 22 deletions(-) diff --git a/MP.Data/DataServiceCollectionExtensions.cs b/MP.Data/DataServiceCollectionExtensions.cs index 8ed9107a..826ce9f2 100644 --- a/MP.Data/DataServiceCollectionExtensions.cs +++ b/MP.Data/DataServiceCollectionExtensions.cs @@ -67,6 +67,7 @@ namespace MP.Data // Servizi LAND services.TryAddSingleton(); + services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); diff --git a/MP.Data/Repository/MpLand/MpLandRepository.cs b/MP.Data/Repository/MpLand/MpLandRepository.cs index 83b60fff..3eb4f9d8 100644 --- a/MP.Data/Repository/MpLand/MpLandRepository.cs +++ b/MP.Data/Repository/MpLand/MpLandRepository.cs @@ -20,10 +20,16 @@ namespace MP.Data.Repository.MpLand #region Public Constructors - public MpLandRepository(IConfiguration configuration, IDbContextFactory ctxFactory) + public MpLandRepository( + IConfiguration configuration, + IDbContextFactory ctxFactory, + IDbContextFactory ctxFactoryFL, + IDbContextFactory ctxFactorySta) { _configuration = configuration; _ctxFactory = ctxFactory; + _ctxFactoryFluxLog = ctxFactoryFL; + _ctxFactoryStats= ctxFactorySta; } #endregion diff --git a/MP.Data/Services/LandDataService.cs b/MP.Data/Services/LandDataService.cs index 1770d3eb..8351a4b8 100644 --- a/MP.Data/Services/LandDataService.cs +++ b/MP.Data/Services/LandDataService.cs @@ -88,15 +88,15 @@ namespace MP.Data.Services ///
                                                  /// /// - public List IobListAll() + public async Task> IobListAllAsync() { string source = "DB"; List? dbResult = new List(); string currKey = $"{redisBaseKey}:IobList"; Stopwatch sw = new Stopwatch(); sw.Start(); - string? rawData = _redisDb.StringGet(currKey); - if (!string.IsNullOrEmpty(rawData) && rawData.Length > 2) + var rawData = await _redisDb.StringGetAsync(currKey); + if (rawData.HasValue) { source = "REDIS"; var tempResult = JsonConvert.DeserializeObject>(rawData); @@ -105,10 +105,10 @@ namespace MP.Data.Services else { // recupero RRL missing - var listRRl = _mpLandRepository.RemRebootLogGetLastAsync().GetAwaiter().GetResult(); - var listRRlAdd = _mpLandRepository.RemRebootLogGetLastNoMaccAsync().GetAwaiter().GetResult(); + var listRRl = await _mpLandRepository.RemRebootLogGetLastAsync(); + var listRRlAdd = await _mpLandRepository.RemRebootLogGetLastNoMaccAsync(); // recupero lista macchine - var ListMacch = _mpLandRepository.MacchineGetAllAsync().GetAwaiter().GetResult(); + var ListMacch = await _mpLandRepository.MacchineGetAllAsync(); // ...converto in DTO dbResult = ListMacch .Select(x => new IobDTO(x, IobInfo(x.IdxMacchina), MachIobConf(x.IdxMacchina))) @@ -125,14 +125,14 @@ namespace MP.Data.Services // serializzo in cache _redisConn rawData = JsonConvert.SerializeObject(dbResult, JSSettings); - _redisDb.StringSet(currKey, rawData, UltraLongCache); + await _redisDb.StringSetAsync(currKey, rawData, UltraLongCache); } if (dbResult == null) { dbResult = new List(); } sw.Stop(); - Log.Debug($"IobListAll | {source} | {sw.ElapsedMilliseconds} ms"); + Log.Debug($"IobListAllAsync | {source} | {sw.ElapsedMilliseconds} ms"); return dbResult; } diff --git a/MP.Land/Components/DbInfoMan.razor.cs b/MP.Land/Components/DbInfoMan.razor.cs index aae03d69..6b434c3a 100644 --- a/MP.Land/Components/DbInfoMan.razor.cs +++ b/MP.Land/Components/DbInfoMan.razor.cs @@ -5,6 +5,7 @@ using MP.Data.Services; using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace MP.Land.Components { @@ -21,9 +22,10 @@ namespace MP.Land.Components #region Protected Methods - protected override void OnParametersSet() + + protected override async Task OnParametersSetAsync() { - ReloadData(); + await ReloadDataAsync(); } protected void SortRequested(Sorter.SortCallBack e) @@ -117,9 +119,9 @@ namespace MP.Land.Components } } - private void ReloadData() + private async Task ReloadDataAsync() { - ListRecord = LDService.AllDbInfo(); + ListRecord = await LDService.AllDbInfoAsync(); } #endregion Private Methods diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index 508b0702..d7bc72a6 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2606.0312 + 8.16.2606.0318 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Pages/IobList.razor.cs b/MP.Land/Pages/IobList.razor.cs index 90157bb1..8984045a 100644 --- a/MP.Land/Pages/IobList.razor.cs +++ b/MP.Land/Pages/IobList.razor.cs @@ -173,11 +173,11 @@ namespace MP.Land.Pages return answ; } - protected void DataInit() + protected async Task DataInitAsync() { isLoading = true; // recupero TUTTI i dati IobList gi completi anche on i RemoteRebootLog - AllRecords = LDService.IobListAll(); + AllRecords = await LDService.IobListAllAsync(); #if false @@ -216,7 +216,7 @@ namespace MP.Land.Pages AppMService.PageName = "IobList"; AppMService.PageIcon = "fas fa-computer pe-2"; await SetupRight(); - DataInit(); + await DataInitAsync(); } protected void ResetSearch() diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index a19361ad..5cc46a2e 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                  Versione: 8.16.2606.0312

                                                  +

                                                  Versione: 8.16.2606.0318


                                                  Note di rilascio:
                                                    diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index b505b6b3..c21e857b 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0312 +8.16.2606.0318 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index c16761d9..d2e91e50 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0312 + 8.16.2606.0318 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.Land/Startup.cs b/MP.Land/Startup.cs index b8b345a7..d318e61b 100644 --- a/MP.Land/Startup.cs +++ b/MP.Land/Startup.cs @@ -1,4 +1,4 @@ -using Blazored.LocalStorage; +using Blazored.LocalStorage; using Blazored.SessionStorage; using Microsoft.AspNetCore.Authentication.Negotiate; using Microsoft.AspNetCore.Builder; @@ -7,6 +7,7 @@ using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Localization; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -17,6 +18,10 @@ using MP.TaskMan.Services; using StackExchange.Redis; using System; using System.Globalization; +using System.Threading.Tasks; +using ZiggyCreatures.Caching.Fusion; +using ZiggyCreatures.Caching.Fusion.Backplane.StackExchangeRedis; +using ZiggyCreatures.Caching.Fusion.Serialization.NewtonsoftJson; namespace MP.Land { @@ -121,12 +126,22 @@ namespace MP.Land options.FallbackPolicy = options.DefaultPolicy; }); + + // REDIS setup string connStringRedis = Configuration.GetConnectionString("Redis"); string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":")); // avvio oggetto shared x redis... - var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); + IConnectionMultiplexer redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); + // ✅ FusionCache + services.AddFusionCache() + .WithDistributedCache(sp => sp.GetRequiredService()) + .WithSerializer(new FusionCacheNewtonsoftJsonSerializer()) + .WithBackplane(new RedisBackplane(new RedisBackplaneOptions + { + ConnectionMultiplexerFactory = () => Task.FromResult(redisMultiplexer) + })); services.AddLocalization(); @@ -143,6 +158,20 @@ namespace MP.Land .EnableSensitiveDataLogging(false) // true solo in Sviluppo .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); + var connStrFlux = Configuration.GetConnectionString("MP.Flux") + ?? throw new InvalidOperationException("ConnString 'MP.Flux' mancante."); + services.AddDbContextFactory(options => + options.UseSqlServer(connStrFlux) + .EnableSensitiveDataLogging(false) // true solo in Sviluppo + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); + + var connStrStats = Configuration.GetConnectionString("MP.Stats") + ?? throw new InvalidOperationException("ConnString 'MP.Stats' mancante."); + services.AddDbContextFactory(options => + options.UseSqlServer(connStrStats) + .EnableSensitiveDataLogging(false) // true solo in Sviluppo + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); + //init servizi specifici LAND //services.AddAuthLandDataLayer(); services.AddLandDataLayer(); From 8c6bf075fb517a147248b3a110bfcdb13b248852 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 4 Jun 2026 08:12:05 +0200 Subject: [PATCH 100/102] Completata review di tutti i progetti coi nuovi repository! --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Program.cs | 53 ++++++++++++++----- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP-TAB3/appsettings.json | 8 +-- MP.Data/DataServiceCollectionExtensions.cs | 17 ++++++ MP.INVE/MP.INVE.csproj | 2 +- MP.INVE/Resources/ChangeLog.html | 2 +- MP.INVE/Resources/VersNum.txt | 2 +- MP.INVE/Resources/manifest.xml | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.Prog/MP.Prog.csproj | 2 +- MP.Prog/Resources/ChangeLog.html | 2 +- MP.Prog/Resources/VersNum.txt | 2 +- MP.Prog/Resources/manifest.xml | 2 +- MP.Prog/Startup.cs | 11 ---- .../Components/Reparti/ListOperatori.razor.cs | 2 +- MP.SPEC/Data/MpDataService.cs | 10 +++- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Program.cs | 7 +++ MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- MP.SPEC/appsettings.json | 1 + MP.Stats/Data/MpStatsService.cs | 7 ++- MP.Stats/MP.Stats.csproj | 2 +- MP.Stats/Resources/ChangeLog.html | 2 +- MP.Stats/Resources/VersNum.txt | 2 +- MP.Stats/Resources/manifest.xml | 2 +- MP.Stats/Startup.cs | 40 ++++++++++++-- MP.Stats/appsettings.json | 2 - 39 files changed, 148 insertions(+), 66 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index b3d96ba1..d50f5fb4 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2606.311 + 8.16.2606.407 enable MP_TAB3 diff --git a/MP-TAB3/Program.cs b/MP-TAB3/Program.cs index 178df0d6..f00f0736 100644 --- a/MP-TAB3/Program.cs +++ b/MP-TAB3/Program.cs @@ -2,16 +2,18 @@ using Blazored.LocalStorage; using Blazored.SessionStorage; #endif -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; -using Microsoft.AspNetCore.StaticFiles; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.FileProviders; using MP.Data; using MP.Data.Services; using NLog; using NLog.Web; using StackExchange.Redis; -using static Org.BouncyCastle.Math.EC.ECCurve; +using ZiggyCreatures.Caching.Fusion; +using ZiggyCreatures.Caching.Fusion.Backplane.StackExchangeRedis; +using ZiggyCreatures.Caching.Fusion.Serialization.NewtonsoftJson; var builder = WebApplication.CreateBuilder(args); @@ -27,15 +29,45 @@ var cString = configuration.GetConnectionString("Redis"); string connStringRedis = cString ?? "localhost:6379, DefaultDatabase=5, connectTimeout=5000, syncTimeout=5000, asyncTimeout=5000, abortConnect=false, ssl=false"; //string redisSrvAddr = connStringRedis.Substring(0, connStringRedis.IndexOf(":")); // avvio oggetto shared x redis... -var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); +IConnectionMultiplexer redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); // Add services x accesso dati builder.Services.AddSingleton(redisMultiplexer); +// ✅ FusionCache +builder.Services.AddFusionCache() + .WithDistributedCache(sp => sp.GetRequiredService()) + .WithSerializer(new FusionCacheNewtonsoftJsonSerializer()) + .WithBackplane(new RedisBackplane(new RedisBackplaneOptions + { + ConnectionMultiplexerFactory = () => Task.FromResult(redisMultiplexer) + })); + +// Metodi principali x accesso dati +var connStr = builder.Configuration.GetConnectionString("MP.Data") + ?? throw new InvalidOperationException("ConnString 'MP.Data' mancante."); +// aggiungo il costruttore x i vari DbContextFactory +builder.Services.AddDbContextFactory(options => + options.UseSqlServer(connStr) + .EnableSensitiveDataLogging(false) // true solo in Sviluppo + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); + +var connStrFL = builder.Configuration.GetConnectionString("MP.Flux") + ?? throw new InvalidOperationException("ConnString 'MP.Flux' mancante."); +builder.Services.AddDbContextFactory(options => + options.UseSqlServer(connStrFL) + .EnableSensitiveDataLogging(false) // true solo in Sviluppo + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); + // Add services to the container. builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); + +// Init centralizzato Repository/Servizi da MP.Data Services +builder.Services.AddTabDataLayer(); + +#if false builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); @@ -43,13 +75,10 @@ builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddScoped(); -#if false -builder.Services.AddBlazoredLocalStorage(); -builder.Services.AddBlazoredSessionStorage(); -#endif // aggiunta helper local/session storage service builder.Services.AddScoped(); -builder.Services.AddScoped(); +builder.Services.AddScoped(); +#endif // gestione email builder.Services.Configure(builder.Configuration.GetSection(nameof(MailKitMailSettings))); @@ -62,7 +91,7 @@ logger.Info("Aggiunti services"); var app = builder.Build(); // aggiunt base URL x routing corretto -var pathBase= configuration.GetValue("SpecialConf:AppUrl") ?? (configuration.GetValue("OptConf:AppUrl") ?? ""); +var pathBase = configuration.GetValue("SpecialConf:AppUrl") ?? (configuration.GetValue("OptConf:AppUrl") ?? ""); app.UsePathBase(pathBase); // Configure the HTTP request pipeline. @@ -78,7 +107,7 @@ app.UseHttpsRedirection(); app.UseStaticFiles(); // gestione static files: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-8.0 -string BasePathDisegni = configuration.GetValue("ServerConf:BasePathDisegni") ?? configuration.GetValue("OptConf:BasePathDisegni")?? ""; +string BasePathDisegni = configuration.GetValue("ServerConf:BasePathDisegni") ?? configuration.GetValue("OptConf:BasePathDisegni") ?? ""; if (!string.IsNullOrEmpty(BasePathDisegni)) { // verifico esista folder disegni diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 40cd97d7..8907be06 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                    Versione: 8.16.2606.311

                                                    +

                                                    Versione: 8.16.2606.407


                                                    Note di rilascio:
                                                    • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index aa5451d0..0d17f6bd 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.311 +8.16.2606.407 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index f12d84a9..ab911600 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.311 + 8.16.2606.407 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP-TAB3/appsettings.json b/MP-TAB3/appsettings.json index 6ef14f69..47c80c14 100644 --- a/MP-TAB3/appsettings.json +++ b/MP-TAB3/appsettings.json @@ -8,16 +8,10 @@ "AllowedHosts": "*", "CodApp": "MP.TAB", "ConnectionStrings": { - //"Redis": "redis.ufficio:26379,serviceName=devel,DefaultDatabase=6,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,allowAdmin=true", - //"MP.All": "Server=SQL2022PROD;Database=Donati_LAV_MoonPro_prod; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.TAB3;", - //"MP.Mon": "Server=SQL2022PROD;Database=Donati_LAV_MoonPro_prod; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.TAB3;", - //"MP.IS": "Server=SQL2022PROD;Database=MoonPro_IS_EdilChim; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.INVE;", - //"MP.Tab": "Server=SQL2022PROD;Database=Donati_LAV_MoonPro_prod; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.TAB3;", - //"MP.Mag": "Server=SQL2022PROD;Database=MoonPro_MAG; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.TAB3;" - "Redis": "redis.ufficio:26379,serviceName=devel,DefaultDatabase=5,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,allowAdmin=true", "MP.All": "Server=SQL2016DEV;Database=MoonPro; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.TAB3;", "MP.Data": "Server=SQL2016DEV;Database=MoonPro; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.TAB3;", + "MP.Flux": "Server=SQL2016DEV;Database=MoonPro_FluxData; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.TAB3;", "MP.Mon": "Server=SQL2016DEV;Database=MoonPro; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.TAB3;", "MP.IS": "Server=SQL2016DEV;Database=MoonPro_IS_EdilChim; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.INVE;", "MP.Tab": "Server=SQL2016DEV;Database=MoonPro; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.TAB3;", diff --git a/MP.Data/DataServiceCollectionExtensions.cs b/MP.Data/DataServiceCollectionExtensions.cs index 826ce9f2..ddc1ef7c 100644 --- a/MP.Data/DataServiceCollectionExtensions.cs +++ b/MP.Data/DataServiceCollectionExtensions.cs @@ -148,6 +148,23 @@ namespace MP.Data /// public static IServiceCollection AddTabDataLayer(this IServiceCollection services) { + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + + services.TryAddSingleton(); + + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddScoped(); + // aggiunta helper local/session storage service + services.TryAddScoped(); + services.TryAddScoped(); return services; } diff --git a/MP.INVE/MP.INVE.csproj b/MP.INVE/MP.INVE.csproj index d12186f5..ef7907fa 100644 --- a/MP.INVE/MP.INVE.csproj +++ b/MP.INVE/MP.INVE.csproj @@ -5,7 +5,7 @@ enable enable MP.INVE - 8.16.2606.311 + 8.16.2606.408 diff --git a/MP.INVE/Resources/ChangeLog.html b/MP.INVE/Resources/ChangeLog.html index aff20529..878755a2 100644 --- a/MP.INVE/Resources/ChangeLog.html +++ b/MP.INVE/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOINVE -

                                                      Versione: 8.16.2606.311

                                                      +

                                                      Versione: 8.16.2606.408


                                                      Note di rilascio:
                                                      • diff --git a/MP.INVE/Resources/VersNum.txt b/MP.INVE/Resources/VersNum.txt index aa5451d0..988a0006 100644 --- a/MP.INVE/Resources/VersNum.txt +++ b/MP.INVE/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.311 +8.16.2606.408 diff --git a/MP.INVE/Resources/manifest.xml b/MP.INVE/Resources/manifest.xml index 5e64eb24..e69c68e1 100644 --- a/MP.INVE/Resources/manifest.xml +++ b/MP.INVE/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.311 + 8.16.2606.408 https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/MP.INVE.zip https://nexus.steamware.net/repository/SWS/MP-INVE/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 29e1b914..5f54a793 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2606.318 + 8.16.2606.407 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 0f1cd517..60835c6f 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                        Versione: 8.16.2606.318

                                                        +

                                                        Versione: 8.16.2606.407


                                                        Note di rilascio:
                                                        • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index ea702b6d..0d17f6bd 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.318 +8.16.2606.407 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index 1ddeedf0..e5620788 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.318 + 8.16.2606.407 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index 1d8ab17b..f0bd44bd 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2606.312 + 8.16.2606.318 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 81ed3f86..0e773c8e 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                          Versione: 8.16.2606.312

                                                          +

                                                          Versione: 8.16.2606.318


                                                          Note di rilascio:
                                                          • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index 1b236191..ea702b6d 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.312 +8.16.2606.318 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index ef808f77..f12feb05 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.312 + 8.16.2606.318 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/MP.Prog.csproj b/MP.Prog/MP.Prog.csproj index 82cdeb00..add2792d 100644 --- a/MP.Prog/MP.Prog.csproj +++ b/MP.Prog/MP.Prog.csproj @@ -3,7 +3,7 @@ net8.0 MP.Prog - 8.16.2606.0310 + 8.16.2606.0408 True diff --git a/MP.Prog/Resources/ChangeLog.html b/MP.Prog/Resources/ChangeLog.html index 03a88103..ad30d9e0 100644 --- a/MP.Prog/Resources/ChangeLog.html +++ b/MP.Prog/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo gestione Programmi MAPO -

                                                            Versione: 8.16.2606.0310

                                                            +

                                                            Versione: 8.16.2606.0408


                                                            Note di rilascio:
                                                              diff --git a/MP.Prog/Resources/VersNum.txt b/MP.Prog/Resources/VersNum.txt index 6970c00b..47fe7fc3 100644 --- a/MP.Prog/Resources/VersNum.txt +++ b/MP.Prog/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0310 +8.16.2606.0408 diff --git a/MP.Prog/Resources/manifest.xml b/MP.Prog/Resources/manifest.xml index 70ae7425..93ee4351 100644 --- a/MP.Prog/Resources/manifest.xml +++ b/MP.Prog/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0310 + 8.16.2606.0408 https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/MP.Prog.zip https://nexus.steamware.net/repository/SWS/MP-PROG/stable/LAST/ChangeLog.html false diff --git a/MP.Prog/Startup.cs b/MP.Prog/Startup.cs index 8f941fab..0e2707af 100644 --- a/MP.Prog/Startup.cs +++ b/MP.Prog/Startup.cs @@ -88,9 +88,6 @@ namespace MP.Prog }); CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("it-IT"); - //// Registrazione Elmah: - //// https://github.com/ElmahCore/ElmahCore - //app.UseElmah(); // fix forwarders app.UseForwardedHeaders(new ForwardedHeadersOptions @@ -152,14 +149,6 @@ namespace MP.Prog o.SlidingExpiration = true; }); - //// Elmah - //services.AddElmah(); - //string elmaConn = "Data Source=SQL2016DEV;Initial Catalog=Elmah;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=SHERPA.BBM;"; - //services.AddElmah(options => - //{ - // options.ConnectionString = elmaConn; - //}); - #if false services.AddStackExchangeRedisCache(options => { diff --git a/MP.SPEC/Components/Reparti/ListOperatori.razor.cs b/MP.SPEC/Components/Reparti/ListOperatori.razor.cs index 03bf5bca..73f18c0b 100644 --- a/MP.SPEC/Components/Reparti/ListOperatori.razor.cs +++ b/MP.SPEC/Components/Reparti/ListOperatori.razor.cs @@ -155,7 +155,7 @@ namespace MP.SPEC.Components.Reparti } private async Task DoReset() { - selRec = null; + selRec = null; await EC_RecSel.InvokeAsync(null); } diff --git a/MP.SPEC/Data/MpDataService.cs b/MP.SPEC/Data/MpDataService.cs index f6768500..8ddbce9d 100644 --- a/MP.SPEC/Data/MpDataService.cs +++ b/MP.SPEC/Data/MpDataService.cs @@ -31,7 +31,15 @@ namespace MP.SPEC.Data private readonly IFluxLogRepository _fluxLogRepository; private readonly IProductionRepository _productionRepository; - public MpDataService(IConnectionMultiplexer connMPlex, IConfiguration configuration, IFusionCache cache, IAnagRepository anagRepository, ISystemRepository systemRepository, IDossierRepository dossierRepository, IFluxLogRepository fluxLogRepository, IProductionRepository productionRepository) + public MpDataService( + IConnectionMultiplexer connMPlex, + IConfiguration configuration, + IFusionCache cache, + IAnagRepository anagRepository, + ISystemRepository systemRepository, + IDossierRepository dossierRepository, + IFluxLogRepository fluxLogRepository, + IProductionRepository productionRepository) { // salvataggio oggetti _configuration = configuration; diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 0c0a71b8..57e69437 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2606.317 + 8.16.2606.407 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Program.cs b/MP.SPEC/Program.cs index 04f79f14..a90fc99b 100644 --- a/MP.SPEC/Program.cs +++ b/MP.SPEC/Program.cs @@ -177,6 +177,13 @@ builder.Services.AddDbContextFactory(options => .EnableSensitiveDataLogging(false) // true solo in Sviluppo .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); +var connStrSta = builder.Configuration.GetConnectionString("MP.Stats") + ?? throw new InvalidOperationException("ConnString 'MP.Stats' mancante."); +builder.Services.AddDbContextFactory(options => + options.UseSqlServer(connStrSta) + .EnableSensitiveDataLogging(false) // true solo in Sviluppo + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); + // Init centralizzato Repository/Servizi da MP.Data Services builder.Services.AddSpecDataLayer(); diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 56193a1d..8907be06 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                              Versione: 8.16.2606.317

                                                              +

                                                              Versione: 8.16.2606.407


                                                              Note di rilascio:
                                                              • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 8c2eaf7f..0d17f6bd 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.317 +8.16.2606.407 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index e67b9b17..3ce53f92 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.317 + 8.16.2606.407 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/appsettings.json b/MP.SPEC/appsettings.json index 594aca27..6bda77be 100644 --- a/MP.SPEC/appsettings.json +++ b/MP.SPEC/appsettings.json @@ -63,6 +63,7 @@ "MP.Land": "Server=SQL2016DEV;Database=MoonPro; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.SPEC;", "MP.Land.Auth": "Server=SQL2016DEV;Database=MoonPro_Anagrafica; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.SPEC;", "MP.Sched": "Server=SQL2016DEV;Database=MoonPro_ES3; User ID=sa;Password=keyhammer16; integrated security=False; MultipleActiveResultSets=True; App=MP.SPEC;", + "MP.Stats": "Server=SQL2016DEV;Database=MoonPro_STATS;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.SPEC;", "Redis": "redis.ufficio:26379,serviceName=devel,DefaultDatabase=5,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,allowAdmin=true", "RedisAdmin": "redis.ufficio:26379,serviceName=devel,DefaultDatabase=5,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,allowAdmin=true", "mdbConnString": "mongodb://W2019-MONGODB:27017" diff --git a/MP.Stats/Data/MpStatsService.cs b/MP.Stats/Data/MpStatsService.cs index 54e4803b..247fa567 100644 --- a/MP.Stats/Data/MpStatsService.cs +++ b/MP.Stats/Data/MpStatsService.cs @@ -11,6 +11,7 @@ using System.Data; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; +using ZiggyCreatures.Caching.Fusion; namespace MP.Stats.Data { @@ -24,7 +25,11 @@ namespace MP.Stats.Data #region Public Constructors - public MpStatsService(IConfiguration configuration, IConnectionMultiplexer redConn) : base(configuration, redConn) + public MpStatsService( + IConfiguration configuration, + IConnectionMultiplexer redConn, + IFusionCache cache + ) : base(configuration, cache, redConn) { Stopwatch sw = Stopwatch.StartNew(); sw.Start(); diff --git a/MP.Stats/MP.Stats.csproj b/MP.Stats/MP.Stats.csproj index 73e0c184..6a9935f9 100644 --- a/MP.Stats/MP.Stats.csproj +++ b/MP.Stats/MP.Stats.csproj @@ -4,7 +4,7 @@ net8.0 MP.Stats 826e877c-ba70-4253-84cb-d0b1cafd4440 - 8.16.2606.0311 + 8.16.2606.0408 true en diff --git a/MP.Stats/Resources/ChangeLog.html b/MP.Stats/Resources/ChangeLog.html index 7ee0c500..793e14ba 100644 --- a/MP.Stats/Resources/ChangeLog.html +++ b/MP.Stats/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo statistiche MAPO -

                                                                Versione: 8.16.2606.0311

                                                                +

                                                                Versione: 8.16.2606.0408


                                                                Note di rilascio:
                                                                  diff --git a/MP.Stats/Resources/VersNum.txt b/MP.Stats/Resources/VersNum.txt index 4143bf31..47fe7fc3 100644 --- a/MP.Stats/Resources/VersNum.txt +++ b/MP.Stats/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0311 +8.16.2606.0408 diff --git a/MP.Stats/Resources/manifest.xml b/MP.Stats/Resources/manifest.xml index 7a375362..0a7e3eaa 100644 --- a/MP.Stats/Resources/manifest.xml +++ b/MP.Stats/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0311 + 8.16.2606.0408 https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/MP.Stats.zip https://nexus.steamware.net/repository/SWS/MP-STATS/stable/LAST/ChangeLog.html false diff --git a/MP.Stats/Startup.cs b/MP.Stats/Startup.cs index 3511f254..17c36165 100644 --- a/MP.Stats/Startup.cs +++ b/MP.Stats/Startup.cs @@ -1,10 +1,14 @@ -using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Localization; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; +using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.OpenApi.Models; +using MP.Data; using MP.Data.Services; using MP.Stats.Data; using MP.TaskMan.Services; @@ -13,6 +17,10 @@ using System; using System.Globalization; using System.IO; using System.Reflection; +using System.Threading.Tasks; +using ZiggyCreatures.Caching.Fusion; +using ZiggyCreatures.Caching.Fusion.Backplane.StackExchangeRedis; +using ZiggyCreatures.Caching.Fusion.Serialization.NewtonsoftJson; namespace MP.Stats { @@ -133,11 +141,35 @@ namespace MP.Stats var cString = Configuration.GetConnectionString("Redis"); string connStringRedis = cString ?? "localhost:6379, DefaultDatabase=5, connectTimeout=5000, syncTimeout=5000, asyncTimeout=5000, abortConnect=false, ssl=false"; // avvio oggetto shared x redis... - var redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); + IConnectionMultiplexer redisMultiplexer = ConnectionMultiplexer.Connect(connStringRedis); + + // ✅ FusionCache + services.AddFusionCache() + .WithDistributedCache(sp => sp.GetRequiredService()) + .WithSerializer(new FusionCacheNewtonsoftJsonSerializer()) + .WithBackplane(new RedisBackplane(new RedisBackplaneOptions + { + ConnectionMultiplexerFactory = () => Task.FromResult(redisMultiplexer) + })); // Add services x accesso dati services.AddSingleton(redisMultiplexer); + // aggiungo il costruttore x i vari DbContextFactory + var connStr = Configuration.GetConnectionString("MP.Stats") + ?? throw new InvalidOperationException("ConnString 'MP.Stats' mancante."); + services.AddDbContextFactory(options => + options.UseSqlServer(connStr) + .EnableSensitiveDataLogging(false) // true solo in Sviluppo + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); + + var connStrVoc = Configuration.GetConnectionString("MP.Voc") + ?? throw new InvalidOperationException("ConnString 'MP.Voc' mancante."); + services.AddDbContextFactory(options => + options.UseSqlServer(connStrVoc) + .EnableSensitiveDataLogging(false) // true solo in Sviluppo + .ConfigureWarnings(w => w.Ignore(CoreEventId.ManyServiceProvidersCreatedWarning))); + services.AddLocalization(); @@ -145,9 +177,11 @@ namespace MP.Stats services.AddServerSideBlazor(); services.AddSingleton(Configuration); + services.AddStatsDataLayer(); + //services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); services.AddScoped(); } diff --git a/MP.Stats/appsettings.json b/MP.Stats/appsettings.json index 0dc6bccb..56b81552 100644 --- a/MP.Stats/appsettings.json +++ b/MP.Stats/appsettings.json @@ -53,8 +53,6 @@ "ConnectionStrings": { "DefaultConnection": "Server=SQL2016DEV;Database=MoonPro_STATS;Trusted_Connection=True;MultipleActiveResultSets=true", "MP.Stats": "Server=SQL2016DEV;Database=MoonPro_STATS;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.STATS;", - //"DefaultConnection": "Server=SQL2016DEV;Database=Jetco_MoonPro_STATS_Prod;Trusted_Connection=True;MultipleActiveResultSets=true", - //"MP.Stats": "Server=SQL2022PROD;Database=Jetco_MoonPro_STATS_Prod;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.STATS;", "MP.Voc": "Server=SQL2016DEV;Database=MoonPro;User ID=sa;Password=keyhammer16;integrated security=False;MultipleActiveResultSets=True;App=MP.STATS;", "Redis": "redis.ufficio:26379,serviceName=devel,DefaultDatabase=5,connectTimeout=5000,syncTimeout=5000,asyncTimeout=5000,abortConnect=false,ssl=false,allowAdmin=true" }, From 561c073489344d9801eb7013105dcb49737d4595 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 4 Jun 2026 08:13:10 +0200 Subject: [PATCH 101/102] Refresh compilazione --- MP-TAB3/MP-TAB3.csproj | 2 +- MP-TAB3/Resources/ChangeLog.html | 2 +- MP-TAB3/Resources/VersNum.txt | 2 +- MP-TAB3/Resources/manifest.xml | 2 +- MP.IOC/MP.IOC.csproj | 2 +- MP.IOC/Resources/ChangeLog.html | 2 +- MP.IOC/Resources/VersNum.txt | 2 +- MP.IOC/Resources/manifest.xml | 2 +- MP.Land/MP.Land.csproj | 2 +- MP.Land/Resources/ChangeLog.html | 2 +- MP.Land/Resources/VersNum.txt | 2 +- MP.Land/Resources/manifest.xml | 2 +- MP.MON/MP.MON.csproj | 2 +- MP.MON/Resources/ChangeLog.html | 2 +- MP.MON/Resources/VersNum.txt | 2 +- MP.MON/Resources/manifest.xml | 2 +- MP.RIOC/MP.RIOC.csproj | 2 +- MP.RIOC/Resources/ChangeLog.html | 2 +- MP.RIOC/Resources/VersNum.txt | 2 +- MP.RIOC/Resources/manifest.xml | 2 +- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/MP-TAB3/MP-TAB3.csproj b/MP-TAB3/MP-TAB3.csproj index d50f5fb4..f073261a 100644 --- a/MP-TAB3/MP-TAB3.csproj +++ b/MP-TAB3/MP-TAB3.csproj @@ -3,7 +3,7 @@ net8.0 enable - 8.16.2606.407 + 8.16.2606.408 enable MP_TAB3 diff --git a/MP-TAB3/Resources/ChangeLog.html b/MP-TAB3/Resources/ChangeLog.html index 8907be06..6e774415 100644 --- a/MP-TAB3/Resources/ChangeLog.html +++ b/MP-TAB3/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                  Versione: 8.16.2606.407

                                                                  +

                                                                  Versione: 8.16.2606.408


                                                                  Note di rilascio:
                                                                  • diff --git a/MP-TAB3/Resources/VersNum.txt b/MP-TAB3/Resources/VersNum.txt index 0d17f6bd..988a0006 100644 --- a/MP-TAB3/Resources/VersNum.txt +++ b/MP-TAB3/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.407 +8.16.2606.408 diff --git a/MP-TAB3/Resources/manifest.xml b/MP-TAB3/Resources/manifest.xml index ab911600..1c9cc682 100644 --- a/MP-TAB3/Resources/manifest.xml +++ b/MP-TAB3/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.407 + 8.16.2606.408 https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/MP-TAB3.zip https://nexus.steamware.net/repository/SWS/MP-TAB3/stable/LAST/ChangeLog.html false diff --git a/MP.IOC/MP.IOC.csproj b/MP.IOC/MP.IOC.csproj index 5f54a793..96e0e3b4 100644 --- a/MP.IOC/MP.IOC.csproj +++ b/MP.IOC/MP.IOC.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 8.16.2606.407 + 8.16.2606.408 diff --git a/MP.IOC/Resources/ChangeLog.html b/MP.IOC/Resources/ChangeLog.html index 60835c6f..421f226c 100644 --- a/MP.IOC/Resources/ChangeLog.html +++ b/MP.IOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-IOC -

                                                                    Versione: 8.16.2606.407

                                                                    +

                                                                    Versione: 8.16.2606.408


                                                                    Note di rilascio:
                                                                    • diff --git a/MP.IOC/Resources/VersNum.txt b/MP.IOC/Resources/VersNum.txt index 0d17f6bd..988a0006 100644 --- a/MP.IOC/Resources/VersNum.txt +++ b/MP.IOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.407 +8.16.2606.408 diff --git a/MP.IOC/Resources/manifest.xml b/MP.IOC/Resources/manifest.xml index e5620788..c0b40892 100644 --- a/MP.IOC/Resources/manifest.xml +++ b/MP.IOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.407 + 8.16.2606.408 https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/MP.IOC.zip https://nexus.steamware.net/repository/SWS/MP-IOC/stable/LAST/ChangeLog.html false diff --git a/MP.Land/MP.Land.csproj b/MP.Land/MP.Land.csproj index d7bc72a6..0bbf51c6 100644 --- a/MP.Land/MP.Land.csproj +++ b/MP.Land/MP.Land.csproj @@ -3,7 +3,7 @@ net8.0 MP.Land - 8.16.2606.0318 + 8.16.2606.0408 Debug;Release;Debug_LiManDebug en True diff --git a/MP.Land/Resources/ChangeLog.html b/MP.Land/Resources/ChangeLog.html index 5cc46a2e..72c86f08 100644 --- a/MP.Land/Resources/ChangeLog.html +++ b/MP.Land/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo Tablet MAPO - DotNet6 -

                                                                      Versione: 8.16.2606.0318

                                                                      +

                                                                      Versione: 8.16.2606.0408


                                                                      Note di rilascio:
                                                                        diff --git a/MP.Land/Resources/VersNum.txt b/MP.Land/Resources/VersNum.txt index c21e857b..47fe7fc3 100644 --- a/MP.Land/Resources/VersNum.txt +++ b/MP.Land/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.0318 +8.16.2606.0408 diff --git a/MP.Land/Resources/manifest.xml b/MP.Land/Resources/manifest.xml index d2e91e50..1b36f10a 100644 --- a/MP.Land/Resources/manifest.xml +++ b/MP.Land/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.0318 + 8.16.2606.0408 https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/MP.Land.zip https://nexus.steamware.net/repository/SWS/MP-LAND/stable/LAST/ChangeLog.html false diff --git a/MP.MON/MP.MON.csproj b/MP.MON/MP.MON.csproj index f0bd44bd..1af13f40 100644 --- a/MP.MON/MP.MON.csproj +++ b/MP.MON/MP.MON.csproj @@ -6,7 +6,7 @@ enable MP.MON $(AssemblyName.Replace(' ', '_')) - 8.16.2606.318 + 8.16.2606.408 diff --git a/MP.MON/Resources/ChangeLog.html b/MP.MON/Resources/ChangeLog.html index 0e773c8e..6e774415 100644 --- a/MP.MON/Resources/ChangeLog.html +++ b/MP.MON/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                        Versione: 8.16.2606.318

                                                                        +

                                                                        Versione: 8.16.2606.408


                                                                        Note di rilascio:
                                                                        • diff --git a/MP.MON/Resources/VersNum.txt b/MP.MON/Resources/VersNum.txt index ea702b6d..988a0006 100644 --- a/MP.MON/Resources/VersNum.txt +++ b/MP.MON/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.318 +8.16.2606.408 diff --git a/MP.MON/Resources/manifest.xml b/MP.MON/Resources/manifest.xml index f12feb05..39fe57dc 100644 --- a/MP.MON/Resources/manifest.xml +++ b/MP.MON/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.318 + 8.16.2606.408 https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/MP.MON.zip https://nexus.steamware.net/repository/SWS/MP-MON/stable/LAST/ChangeLog.html false diff --git a/MP.RIOC/MP.RIOC.csproj b/MP.RIOC/MP.RIOC.csproj index 03533e4f..a506ab6c 100644 --- a/MP.RIOC/MP.RIOC.csproj +++ b/MP.RIOC/MP.RIOC.csproj @@ -5,7 +5,7 @@ enable enable MP.RIOC - 8.16.2606.318 + 8.16.2606.408 diff --git a/MP.RIOC/Resources/ChangeLog.html b/MP.RIOC/Resources/ChangeLog.html index c71c5486..e25fa8ef 100644 --- a/MP.RIOC/Resources/ChangeLog.html +++ b/MP.RIOC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MP-RIOC -

                                                                          Versione: 8.16.2606.318

                                                                          +

                                                                          Versione: 8.16.2606.408


                                                                          Note di rilascio:
                                                                          • diff --git a/MP.RIOC/Resources/VersNum.txt b/MP.RIOC/Resources/VersNum.txt index ea702b6d..988a0006 100644 --- a/MP.RIOC/Resources/VersNum.txt +++ b/MP.RIOC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.318 +8.16.2606.408 diff --git a/MP.RIOC/Resources/manifest.xml b/MP.RIOC/Resources/manifest.xml index 734be1e1..ceddb51b 100644 --- a/MP.RIOC/Resources/manifest.xml +++ b/MP.RIOC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.318 + 8.16.2606.408 https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/MP.RIOC.zip https://nexus.steamware.net/repository/SWS/MP-RIOC/stable/LAST/ChangeLog.html false diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 57e69437..2ab421b2 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2606.407 + 8.16.2606.408 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 8907be06..6e774415 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                            Versione: 8.16.2606.407

                                                                            +

                                                                            Versione: 8.16.2606.408


                                                                            Note di rilascio:
                                                                            • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 0d17f6bd..988a0006 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.407 +8.16.2606.408 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index 3ce53f92..c43a43f3 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.407 + 8.16.2606.408 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false From bbdf6b40127efa0476d87e1ae691125fe6b0eec8 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Thu, 4 Jun 2026 09:52:12 +0200 Subject: [PATCH 102/102] SPEC: - aggiunta ricerca x operatori --- MP.SPEC/MP.SPEC.csproj | 2 +- MP.SPEC/Pages/Operatori.razor | 15 +++++++++++++-- MP.SPEC/Pages/Operatori.razor.cs | 31 +++++++++++++++++++++++++------ MP.SPEC/Pages/RepOper.razor.cs | 5 +---- MP.SPEC/Resources/ChangeLog.html | 2 +- MP.SPEC/Resources/VersNum.txt | 2 +- MP.SPEC/Resources/manifest.xml | 2 +- 7 files changed, 43 insertions(+), 16 deletions(-) diff --git a/MP.SPEC/MP.SPEC.csproj b/MP.SPEC/MP.SPEC.csproj index 2ab421b2..5037cd5c 100644 --- a/MP.SPEC/MP.SPEC.csproj +++ b/MP.SPEC/MP.SPEC.csproj @@ -5,7 +5,7 @@ enable enable MP.SPEC - 8.16.2606.408 + 8.16.2606.409 1800a78a-6ff1-40f9-b490-87fb8bfc1394 en diff --git a/MP.SPEC/Pages/Operatori.razor b/MP.SPEC/Pages/Operatori.razor index b1fcb4a3..f70941a2 100644 --- a/MP.SPEC/Pages/Operatori.razor +++ b/MP.SPEC/Pages/Operatori.razor @@ -11,7 +11,18 @@
                                                                              - @* Edit Massivo Fermi *@ +
                                                                              + + @if (ShowDetail) + { + + } + else + { + + } + +
                                                                              @@ -24,7 +35,7 @@ {
                                                                              - +
                                                                              @if (SelRec != null) { diff --git a/MP.SPEC/Pages/Operatori.razor.cs b/MP.SPEC/Pages/Operatori.razor.cs index 75ec7e16..38d664aa 100644 --- a/MP.SPEC/Pages/Operatori.razor.cs +++ b/MP.SPEC/Pages/Operatori.razor.cs @@ -26,28 +26,31 @@ namespace MP.SPEC.Pages #region Private Fields private bool isLoading = false; - private List ListOperatori = new(); private List ListGruppi = new(); + private List ListOperatori = new(); + private string SearchVal = ""; private AnagOperatoriModel? SelRec = null; #endregion Private Fields #region Private Properties + private string btnSearchCss => string.IsNullOrWhiteSpace(SearchVal) ? "btn-secondary" : "btn-primary"; private string cssMain => SelRec == null ? "col-12" : "col-6"; + private bool ShowDetail => SelRec != null; + #endregion Private Properties #region Private Methods - private async Task ReloadDataAsync() + private async Task DoReset() { - isLoading = true; - ListOperatori = await MDService.OperatoriGetFiltAsync("*"); - isLoading = false; + SearchVal = ""; + await ReloadDataAsync(); } - private async Task ShowDetail(AnagOperatoriModel? newRec) + private async Task DoSelect(AnagOperatoriModel? newRec) { SelRec = newRec; if (SelRec == null) @@ -61,6 +64,22 @@ namespace MP.SPEC.Pages } } + private async Task ReloadDataAsync() + { + isLoading = true; + var rawList = await MDService.OperatoriGetFiltAsync("*"); + if (string.IsNullOrEmpty(SearchVal)) + { + ListOperatori = rawList; + } + else + { + ListOperatori = rawList + .Where(x => x.Cognome.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase) || x.Nome.Contains(SearchVal, StringComparison.InvariantCultureIgnoreCase)).ToList(); + } + isLoading = false; + } + #endregion Private Methods } } \ No newline at end of file diff --git a/MP.SPEC/Pages/RepOper.razor.cs b/MP.SPEC/Pages/RepOper.razor.cs index 0dda2fc3..0f3ec8fa 100644 --- a/MP.SPEC/Pages/RepOper.razor.cs +++ b/MP.SPEC/Pages/RepOper.razor.cs @@ -57,10 +57,7 @@ namespace MP.SPEC.Pages #region Private Properties - private string btnSearchCss - { - get => string.IsNullOrWhiteSpace(SearchVal) ? "btn-secondary" : "btn-primary"; - } + private string btnSearchCss => string.IsNullOrWhiteSpace(SearchVal) ? "btn-secondary" : "btn-primary"; private string CssMain => ShowDetail ? "col-4" : "col-12"; diff --git a/MP.SPEC/Resources/ChangeLog.html b/MP.SPEC/Resources/ChangeLog.html index 6e774415..b6126dfe 100644 --- a/MP.SPEC/Resources/ChangeLog.html +++ b/MP.SPEC/Resources/ChangeLog.html @@ -1,6 +1,6 @@ Modulo MAPOSPEC -

                                                                              Versione: 8.16.2606.408

                                                                              +

                                                                              Versione: 8.16.2606.409


                                                                              Note di rilascio:
                                                                              • diff --git a/MP.SPEC/Resources/VersNum.txt b/MP.SPEC/Resources/VersNum.txt index 988a0006..722b7892 100644 --- a/MP.SPEC/Resources/VersNum.txt +++ b/MP.SPEC/Resources/VersNum.txt @@ -1 +1 @@ -8.16.2606.408 +8.16.2606.409 diff --git a/MP.SPEC/Resources/manifest.xml b/MP.SPEC/Resources/manifest.xml index c43a43f3..85bf0bb0 100644 --- a/MP.SPEC/Resources/manifest.xml +++ b/MP.SPEC/Resources/manifest.xml @@ -1,6 +1,6 @@ - 8.16.2606.408 + 8.16.2606.409 https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/MP.SPEC.zip https://nexus.steamware.net/repository/SWS/MP-SPEC/stable/LAST/ChangeLog.html false
                                              Matr. Anagr.
                                              -
                                              @record.MatrOpr
                                              +
                                              -
                                              @record.Cognome @record.Nome
                                              +
                                              +
                                              @item.MatrOpr
                                              - + +
                                              @item.Cognome @item.Nome
                                              + + + @if (item.isEnabled) + { + + } + else + { + + } +
                                              - @if (EditRec == null) + @if (EditEnabled) { - - } - else - { - - } - @if (SelRecord == null) - { - + if (EditRec == null) + { + + } + else + { + + } + if (SelRecord == null) + { + + } } @record.CountMacc @record.CountOpr - @if (DelEnabled(record)) + @if (EditEnabled) { - - } - else - { - + if (DelEnabled(record)) + { + + } + else + { + + } }