From cb51e3f7fcb3589d49e27fa725c4bcb5a48e5b21 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 18 Mar 2026 16:14:47 +0100 Subject: [PATCH 1/5] registrazione repository/servizi orderRow --- Lux.API/Lux.API.csproj | 2 +- Lux.API/Program.cs | 2 ++ Lux.UI/Lux.UI.csproj | 2 +- Lux.UI/Program.cs | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Lux.API/Lux.API.csproj b/Lux.API/Lux.API.csproj index 146d536e..f85a6be0 100644 --- a/Lux.API/Lux.API.csproj +++ b/Lux.API/Lux.API.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 1.1.2603.1813 + 1.1.2603.1816 diff --git a/Lux.API/Program.cs b/Lux.API/Program.cs index 6fd30f97..f3e53f96 100644 --- a/Lux.API/Program.cs +++ b/Lux.API/Program.cs @@ -185,6 +185,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); @@ -203,6 +204,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/Lux.UI/Lux.UI.csproj b/Lux.UI/Lux.UI.csproj index 680957dc..4b051c89 100644 --- a/Lux.UI/Lux.UI.csproj +++ b/Lux.UI/Lux.UI.csproj @@ -5,7 +5,7 @@ enable enable aspnet-Lux.UI-a758c101-a2f4-4e38-977d-1c4887dbbd50 - 1.1.2603.1813 + 1.1.2603.1816 diff --git a/Lux.UI/Program.cs b/Lux.UI/Program.cs index ac55065a..03eaf6cc 100644 --- a/Lux.UI/Program.cs +++ b/Lux.UI/Program.cs @@ -223,6 +223,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); @@ -241,6 +242,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); From b629b5ce1f833ffaea0e150d08d0783f9626bf44 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 18 Mar 2026 16:14:56 +0100 Subject: [PATCH 2/5] Inizio inserimento info Production --- Directory.Packages.props | 4 +-- .../EgwCoreLib.Lux.Data.csproj | 1 + .../Production/IProductionPlantRepository.cs | 9 ++++++ .../Production/ProductionPlantRepository.cs | 28 +++++++++++++++++++ Resources/ChangeLog.html | 2 +- Resources/VersNum.txt | 2 +- Resources/manifest.xml | 2 +- 7 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 EgwCoreLib.Lux.Data/Repository/Production/IProductionPlantRepository.cs create mode 100644 EgwCoreLib.Lux.Data/Repository/Production/ProductionPlantRepository.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index de11e9b3..fd14e937 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -8,8 +8,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive all - - + + diff --git a/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj b/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj index de103521..3aa97f82 100644 --- a/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj +++ b/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj @@ -55,6 +55,7 @@ + diff --git a/EgwCoreLib.Lux.Data/Repository/Production/IProductionPlantRepository.cs b/EgwCoreLib.Lux.Data/Repository/Production/IProductionPlantRepository.cs new file mode 100644 index 00000000..827f6404 --- /dev/null +++ b/EgwCoreLib.Lux.Data/Repository/Production/IProductionPlantRepository.cs @@ -0,0 +1,9 @@ +using EgwCoreLib.Lux.Data.DbModel.Config; + +namespace EgwCoreLib.Lux.Data.Repository.Config +{ + public interface IProductionPlantRepository + { + Task> GetAllAsync(); + } +} diff --git a/EgwCoreLib.Lux.Data/Repository/Production/ProductionPlantRepository.cs b/EgwCoreLib.Lux.Data/Repository/Production/ProductionPlantRepository.cs new file mode 100644 index 00000000..8e27a38d --- /dev/null +++ b/EgwCoreLib.Lux.Data/Repository/Production/ProductionPlantRepository.cs @@ -0,0 +1,28 @@ +using EgwCoreLib.Lux.Data.DbModel.Config; +using Microsoft.EntityFrameworkCore; + +namespace EgwCoreLib.Lux.Data.Repository.Config +{ + public class ProductionPlantRepository : BaseRepository, IProductionPlantRepository + { + #region Public Constructors + + public ProductionPlantRepository(IDbContextFactory ctxFactory) : base(ctxFactory) + { + } + + #endregion Public Constructors + + #region Public Methods + + public async Task> GetAllAsync() + { + await using var dbCtx = await CreateContextAsync(); + return await dbCtx.DbSetEnvirPar + .AsNoTracking() + .ToListAsync(); + } + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/Resources/ChangeLog.html b/Resources/ChangeLog.html index 18447d8a..1fb27bdf 100644 --- a/Resources/ChangeLog.html +++ b/Resources/ChangeLog.html @@ -1,6 +1,6 @@ LUX - Web Windows MES -

Versione: 1.1.2603.1813

+

Versione: 1.1.2603.1816


Note di rilascio:
  • diff --git a/Resources/VersNum.txt b/Resources/VersNum.txt index ec6b8f7f..cb33259f 100644 --- a/Resources/VersNum.txt +++ b/Resources/VersNum.txt @@ -1 +1 @@ -1.1.2603.1813 +1.1.2603.1816 diff --git a/Resources/manifest.xml b/Resources/manifest.xml index 4521aec6..69c3d6eb 100644 --- a/Resources/manifest.xml +++ b/Resources/manifest.xml @@ -1,6 +1,6 @@ - 1.1.2603.1813 + 1.1.2603.1816 http://nexus.steamware.net/repository/SWS/GPW/stable/GPW.UI.zip http://nexus.steamware.net/repository/SWS/GPW/stable/ChangeLog.html false From f59d4c98763166ff13bf7e2635c13066a6e2da35 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 18 Mar 2026 16:20:10 +0100 Subject: [PATCH 3/5] Inizio aggiunta repo/servizi x ProdPlant --- .../Controllers/LuxController.cs | 2 + .../EgwCoreLib.Lux.Data.csproj | 1 - .../Production/IProductionPlantRepository.cs | 6 +-- .../Production/ProductionPlantRepository.cs | 8 ++-- .../Services/DataLayerServices.cs | 2 + .../Production/IProductionPlantService.cs | 9 ++++ .../Production/ProductionPlantService.cs | 46 +++++++++++++++++++ 7 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 EgwCoreLib.Lux.Data/Services/Production/IProductionPlantService.cs create mode 100644 EgwCoreLib.Lux.Data/Services/Production/ProductionPlantService.cs diff --git a/EgwCoreLib.Lux.Data/Controllers/LuxController.cs b/EgwCoreLib.Lux.Data/Controllers/LuxController.cs index 1efef7fd..eb412a97 100644 --- a/EgwCoreLib.Lux.Data/Controllers/LuxController.cs +++ b/EgwCoreLib.Lux.Data/Controllers/LuxController.cs @@ -1143,6 +1143,7 @@ namespace EgwCoreLib.Lux.Data.Controllers return answ; } +#if true internal async Task> ProdPlantGetAllAsync() { List dbResult = new List(); @@ -1163,6 +1164,7 @@ namespace EgwCoreLib.Lux.Data.Controllers return dbResult; } +#endif /// /// Creazione di un Batch con relativo Tag e info x creazione ODL correlati /// diff --git a/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj b/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj index 3aa97f82..de103521 100644 --- a/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj +++ b/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj @@ -55,7 +55,6 @@ - diff --git a/EgwCoreLib.Lux.Data/Repository/Production/IProductionPlantRepository.cs b/EgwCoreLib.Lux.Data/Repository/Production/IProductionPlantRepository.cs index 827f6404..142936c2 100644 --- a/EgwCoreLib.Lux.Data/Repository/Production/IProductionPlantRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Production/IProductionPlantRepository.cs @@ -1,9 +1,9 @@ -using EgwCoreLib.Lux.Data.DbModel.Config; +using EgwCoreLib.Lux.Data.DbModel.Production; -namespace EgwCoreLib.Lux.Data.Repository.Config +namespace EgwCoreLib.Lux.Data.Repository.Production { public interface IProductionPlantRepository { - Task> GetAllAsync(); + Task> GetAllAsync(); } } diff --git a/EgwCoreLib.Lux.Data/Repository/Production/ProductionPlantRepository.cs b/EgwCoreLib.Lux.Data/Repository/Production/ProductionPlantRepository.cs index 8e27a38d..1fc369b5 100644 --- a/EgwCoreLib.Lux.Data/Repository/Production/ProductionPlantRepository.cs +++ b/EgwCoreLib.Lux.Data/Repository/Production/ProductionPlantRepository.cs @@ -1,7 +1,7 @@ -using EgwCoreLib.Lux.Data.DbModel.Config; +using EgwCoreLib.Lux.Data.DbModel.Production; using Microsoft.EntityFrameworkCore; -namespace EgwCoreLib.Lux.Data.Repository.Config +namespace EgwCoreLib.Lux.Data.Repository.Production { public class ProductionPlantRepository : BaseRepository, IProductionPlantRepository { @@ -15,10 +15,10 @@ namespace EgwCoreLib.Lux.Data.Repository.Config #region Public Methods - public async Task> GetAllAsync() + public async Task> GetAllAsync() { await using var dbCtx = await CreateContextAsync(); - return await dbCtx.DbSetEnvirPar + return await dbCtx.DbSetProdPlant .AsNoTracking() .ToListAsync(); } diff --git a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs index c9b5bb64..92935cb5 100644 --- a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs +++ b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs @@ -706,6 +706,7 @@ namespace EgwCoreLib.Lux.Data.Services return result; } +#if true /// /// Elenco completo plant gestiti /// @@ -738,6 +739,7 @@ namespace EgwCoreLib.Lux.Data.Services LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms"); return result; } +#endif /// /// Creazione record Batch x intestare gli ODL diff --git a/EgwCoreLib.Lux.Data/Services/Production/IProductionPlantService.cs b/EgwCoreLib.Lux.Data/Services/Production/IProductionPlantService.cs new file mode 100644 index 00000000..c66fa841 --- /dev/null +++ b/EgwCoreLib.Lux.Data/Services/Production/IProductionPlantService.cs @@ -0,0 +1,9 @@ +using EgwCoreLib.Lux.Data.DbModel.Production; + +namespace EgwCoreLib.Lux.Data.Services.Production +{ + public interface IProductionPlantService + { + Task> GetAllAsync(); + } +} diff --git a/EgwCoreLib.Lux.Data/Services/Production/ProductionPlantService.cs b/EgwCoreLib.Lux.Data/Services/Production/ProductionPlantService.cs new file mode 100644 index 00000000..0a7447c7 --- /dev/null +++ b/EgwCoreLib.Lux.Data/Services/Production/ProductionPlantService.cs @@ -0,0 +1,46 @@ +using EgwCoreLib.Lux.Data.DbModel.Production; +using EgwCoreLib.Lux.Data.Repository.Production; +using Microsoft.Extensions.Configuration; +using StackExchange.Redis; + +namespace EgwCoreLib.Lux.Data.Services.Production +{ + public class ProductionPlantService : BaseServ, IProductionPlantService + { + #region Public Constructors + + public ProductionPlantService( + IConfiguration config, + IConnectionMultiplexer redis, + IProductionPlantRepository repo) : base(config, redis) + { + _className = "ProductionPlant"; + _repo = repo; + } + + #endregion Public Constructors + + #region Public Methods + + public async Task> GetAllAsync() + { + return await TraceAsync($"{_className}.GetAll", async (activity) => + { + return await GetOrSetCacheAsync( + $"{_redisBaseKey}:{_className}", + async () => await _repo.GetAllAsync(), + UltraLongCache + ); + }); + } + + #endregion Public Methods + + #region Private Fields + + private readonly string _className; + private readonly IProductionPlantRepository _repo; + + #endregion Private Fields + } +} From e73766589dea94ced2f55bd8e162d13d4f86ee98 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 18 Mar 2026 18:07:02 +0100 Subject: [PATCH 4/5] Migrazione serivce/repository production --- .../Controllers/LuxController.cs | 151 +++++++-------- .../Production/IProductionBatchRepository.cs | 15 ++ .../Production/IProductionOdlRepository.cs | 33 ++++ .../Production/ProductionBatchRepository.cs | 50 +++++ .../Production/ProductionOdlRepository.cs | 117 ++++++++++++ .../Services/DataLayerServices.cs | 175 +++++++++--------- .../Production/IProductionBatchService.cs | 18 ++ .../Production/IProductionOdlService.cs | 33 ++++ .../Production/ProductionBatchService.cs | 51 +++++ .../Production/ProductionOdlService.cs | 86 +++++++++ Lux.API/Lux.API.csproj | 2 +- Lux.API/Program.cs | 8 + Lux.UI/Components/Compo/OrderRowMan.razor.cs | 5 +- .../Components/Pages/WorkLoadBalance.razor.cs | 13 +- Lux.UI/Lux.UI.csproj | 2 +- Lux.UI/Program.cs | 10 +- Resources/ChangeLog.html | 2 +- Resources/VersNum.txt | 2 +- Resources/manifest.xml | 2 +- 19 files changed, 603 insertions(+), 172 deletions(-) create mode 100644 EgwCoreLib.Lux.Data/Repository/Production/IProductionBatchRepository.cs create mode 100644 EgwCoreLib.Lux.Data/Repository/Production/IProductionOdlRepository.cs create mode 100644 EgwCoreLib.Lux.Data/Repository/Production/ProductionBatchRepository.cs create mode 100644 EgwCoreLib.Lux.Data/Repository/Production/ProductionOdlRepository.cs create mode 100644 EgwCoreLib.Lux.Data/Services/Production/IProductionBatchService.cs create mode 100644 EgwCoreLib.Lux.Data/Services/Production/IProductionOdlService.cs create mode 100644 EgwCoreLib.Lux.Data/Services/Production/ProductionBatchService.cs create mode 100644 EgwCoreLib.Lux.Data/Services/Production/ProductionOdlService.cs diff --git a/EgwCoreLib.Lux.Data/Controllers/LuxController.cs b/EgwCoreLib.Lux.Data/Controllers/LuxController.cs index eb412a97..d813d7b1 100644 --- a/EgwCoreLib.Lux.Data/Controllers/LuxController.cs +++ b/EgwCoreLib.Lux.Data/Controllers/LuxController.cs @@ -959,78 +959,6 @@ namespace EgwCoreLib.Lux.Data.Controllers return numItem; } - /// - /// Elenco PODL non assegnati con struttura DTO appiattita - /// - /// - internal async Task?> ProdOdlAssignGetAsync() - { - List? dbResults = null; - //using (DataLayerContext dbCtx = new DataLayerContext(_config)) - using (DataLayerContext dbCtx = new DataLayerContext()) - { - try - { - dbResults = await dbCtx.DbSetProdODL - .Where(x => !x.DateAssign.HasValue) - .Select(odl => new OdlAssignDto - { - Envir = odl.ProdBatchNav.Envir, - ProdODLID = odl.ProdODLID, - Description = odl.Description, - EstimTime = odl.EstimTime, - Index = odl.Index, - OdlTag = odl.OdlTag, - PhaseID = odl.PhaseID, - ProdBatchID = odl.ProdBatchID, - ProdPlantCod = odl.ProdPlantCod, - Qty = odl.Qty, - ResourceID = odl.ResourceID, - ItemList = odl.Item2OdlNav.Select(i => new ItemAssignDto - { - ProdItemID = i.ProdItemID, - OrderID = i.ProductionItemNav.OrderRowNav.OrderNav.OrderID, - OrderRowID = i.ProductionItemNav.OrderRowNav.OrderRowID, - OrderTag = i.ProductionItemNav.OrderRowNav.OrderNav.OrderCode, - OrderRowTag = i.ProductionItemNav.OrderRowNav.OrderRowCode, - ProdItemTag = i.ProductionItemNav.ProdItemTag ?? "***" - }).ToList() - }) - .ToListAsync(); - } - catch (Exception exc) - { - Log.Error($"Eccezione durante ProductionOdlUnassignAsync{Environment.NewLine}{exc}"); - } - } - return dbResults; - } - - /// - /// Recupero record ProdOdl dato Tag/uID - /// - /// - /// - internal async Task ProdOdlGetByUidAsync(string uID) - { - ProductionODLModel? answ = null; - //using (DataLayerContext dbCtx = new DataLayerContext(_config)) - using (DataLayerContext dbCtx = new DataLayerContext()) - { - try - { - answ = await dbCtx - .DbSetProdODL - .Where(x => x.OdlTag == uID) - .FirstOrDefaultAsync(); - } - catch (Exception exc) - { - Log.Error($"Eccezione durante ProdOdlGetByUidAsync{Environment.NewLine}{exc}"); - } - } - return answ; - } /// /// Aggiorna record ProdOdl (se trovato) con BOM (raw) ricevuta @@ -1143,7 +1071,7 @@ namespace EgwCoreLib.Lux.Data.Controllers return answ; } -#if true +#if false internal async Task> ProdPlantGetAllAsync() { List dbResult = new List(); @@ -1164,7 +1092,6 @@ namespace EgwCoreLib.Lux.Data.Controllers return dbResult; } -#endif /// /// Creazione di un Batch con relativo Tag e info x creazione ODL correlati /// @@ -1248,6 +1175,82 @@ namespace EgwCoreLib.Lux.Data.Controllers } } + /// + /// Elenco PODL non assegnati con struttura DTO appiattita + /// + /// + internal async Task?> ProdOdlAssignGetAsync() + { + List? dbResults = null; + //using (DataLayerContext dbCtx = new DataLayerContext(_config)) + using (DataLayerContext dbCtx = new DataLayerContext()) + { + try + { + dbResults = await dbCtx.DbSetProdODL + .Where(x => !x.DateAssign.HasValue) + .Select(odl => new OdlAssignDto + { + Envir = odl.ProdBatchNav.Envir, + ProdODLID = odl.ProdODLID, + Description = odl.Description, + EstimTime = odl.EstimTime, + Index = odl.Index, + OdlTag = odl.OdlTag, + PhaseID = odl.PhaseID, + ProdBatchID = odl.ProdBatchID, + ProdPlantCod = odl.ProdPlantCod, + Qty = odl.Qty, + ResourceID = odl.ResourceID, + ItemList = odl.Item2OdlNav.Select(i => new ItemAssignDto + { + ProdItemID = i.ProdItemID, + OrderID = i.ProductionItemNav.OrderRowNav.OrderNav.OrderID, + OrderRowID = i.ProductionItemNav.OrderRowNav.OrderRowID, + OrderTag = i.ProductionItemNav.OrderRowNav.OrderNav.OrderCode, + OrderRowTag = i.ProductionItemNav.OrderRowNav.OrderRowCode, + ProdItemTag = i.ProductionItemNav.ProdItemTag ?? "***" + }).ToList() + }) + .ToListAsync(); + } + catch (Exception exc) + { + Log.Error($"Eccezione durante ProductionOdlUnassignAsync{Environment.NewLine}{exc}"); + } + } + return dbResults; + } + + /// + /// Recupero record ProdOdl dato Tag/uID + /// + /// + /// + internal async Task ProdOdlGetByUidAsync(string uID) + { + ProductionODLModel? answ = null; + //using (DataLayerContext dbCtx = new DataLayerContext(_config)) + using (DataLayerContext dbCtx = new DataLayerContext()) + { + try + { + answ = await dbCtx + .DbSetProdODL + .Where(x => x.OdlTag == uID) + .FirstOrDefaultAsync(); + } + catch (Exception exc) + { + Log.Error($"Eccezione durante ProdOdlGetByUidAsync{Environment.NewLine}{exc}"); + } + } + return answ; + } + +#endif + + /// /// Elenco PODL non assegnati /// diff --git a/EgwCoreLib.Lux.Data/Repository/Production/IProductionBatchRepository.cs b/EgwCoreLib.Lux.Data/Repository/Production/IProductionBatchRepository.cs new file mode 100644 index 00000000..ae03ca07 --- /dev/null +++ b/EgwCoreLib.Lux.Data/Repository/Production/IProductionBatchRepository.cs @@ -0,0 +1,15 @@ +using EgwCoreLib.Lux.Data.DbModel.Production; + +namespace EgwCoreLib.Lux.Data.Repository.Production +{ + public interface IProductionBatchRepository + { + + /// + /// Creazione di un Batch con relativo Tag e info x creazione ODL correlati + /// + /// + /// + Task CreateAsync(ProductionBatchModel entity); + } +} diff --git a/EgwCoreLib.Lux.Data/Repository/Production/IProductionOdlRepository.cs b/EgwCoreLib.Lux.Data/Repository/Production/IProductionOdlRepository.cs new file mode 100644 index 00000000..ba18e3c6 --- /dev/null +++ b/EgwCoreLib.Lux.Data/Repository/Production/IProductionOdlRepository.cs @@ -0,0 +1,33 @@ +using EgwCoreLib.Lux.Core.Generic; +using EgwCoreLib.Lux.Data.DbModel.Production; + +namespace EgwCoreLib.Lux.Data.Repository.Production +{ + public interface IProductionOdlRepository + { + #region Public Methods + + /// + /// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items) + /// + /// + /// + /// + Task> CreateAsync(List listOdl2ins); + + /// + /// Recupero record ProdOdl dato Tag/uID + /// + /// + /// + Task GetByUidAsync(string uID); + + /// + /// Elenco PODL non assegnati con struttura DTO appiattita + /// + /// + Task> GetUnassignAsync(); + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/EgwCoreLib.Lux.Data/Repository/Production/ProductionBatchRepository.cs b/EgwCoreLib.Lux.Data/Repository/Production/ProductionBatchRepository.cs new file mode 100644 index 00000000..426bd8b1 --- /dev/null +++ b/EgwCoreLib.Lux.Data/Repository/Production/ProductionBatchRepository.cs @@ -0,0 +1,50 @@ +using EgwCoreLib.Lux.Data.DbModel.Production; +using Microsoft.EntityFrameworkCore; +using MySqlConnector; + +namespace EgwCoreLib.Lux.Data.Repository.Production +{ + public class ProductionBatchRepository : BaseRepository, IProductionBatchRepository + { + #region Public Constructors + + public ProductionBatchRepository(IDbContextFactory ctxFactory) : base(ctxFactory) + { + } + + #endregion Public Constructors + + #region Public Methods + + + /// + /// Creazione di un Batch con relativo Tag e info x creazione ODL correlati + /// + /// + /// + public async Task CreateAsync(ProductionBatchModel entity) + { + await using var dbCtx = await CreateContextAsync(); + + // chiamo stored + ProductionBatchModel dbResult = null; + // Definiamo i parametri di input + var pDesc = new MySqlParameter("@pDescription", entity.Description ?? (object)DBNull.Value); + var pDate = new MySqlParameter("@pDueDate", entity.DueDate); + var pPref = new MySqlParameter("@pPrefix", "BC."); + var pYear = new MySqlParameter("@pYear", entity.DueDate.Year); + var pEnv = new MySqlParameter("@pEnv", entity.Envir); + + // Eseguiamo la procedura e mappiamo il risultato direttamente sul modello + // Nota: DbSetProdBatch deve essere configurato nel DbContext + var result = await dbCtx + .DbSetProdBatch + .FromSqlRaw("CALL stp_ProdBatch_insert(@pDescription, @pDueDate, @pPrefix, @pYear, @pEnv)", pDesc, pDate, pPref, pYear, pEnv) + .ToListAsync(); + + return dbResult; + } + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/EgwCoreLib.Lux.Data/Repository/Production/ProductionOdlRepository.cs b/EgwCoreLib.Lux.Data/Repository/Production/ProductionOdlRepository.cs new file mode 100644 index 00000000..56ebd5d9 --- /dev/null +++ b/EgwCoreLib.Lux.Data/Repository/Production/ProductionOdlRepository.cs @@ -0,0 +1,117 @@ +using EgwCoreLib.Lux.Core.Generic; +using EgwCoreLib.Lux.Data.DbModel.Production; +using Microsoft.EntityFrameworkCore; +using MySqlConnector; + +namespace EgwCoreLib.Lux.Data.Repository.Production +{ + public class ProductionOdlRepository : BaseRepository, IProductionOdlRepository + { + #region Public Constructors + + public ProductionOdlRepository(IDbContextFactory ctxFactory) : base(ctxFactory) + { + } + + #endregion Public Constructors + + #region Public Methods + + + /// + /// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items) + /// + /// + /// + /// + public async Task> CreateAsync(List listOdl2ins) + { + await using var dbCtx = await CreateContextAsync(); + + // avvio transazione + using var transaction = await dbCtx.Database.BeginTransactionAsync(); + + try + { + int cYear = DateTime.Today.Year; + + // insert in blocco + dbCtx.DbSetProdODL.AddRange(listOdl2ins); + + // 3. Salvataggio massivo + // EF Core 8 ottimizzerà gli insert in batch dove possibile + await dbCtx.SaveChangesAsync(); + + // stored update Tags + var pProdBatchID = new MySqlParameter("@pDueDate", listOdl2ins.FirstOrDefault()?.ProdBatchID ?? 0); + var pPref = new MySqlParameter("@pPrefix", "ODL."); + var pYear = new MySqlParameter("@pYear", cYear); + await dbCtx.Database.ExecuteSqlRawAsync("CALL stp_ProdOdl_UpdateTag(@pProdBatchID, @pPrefix, @pYear)", pProdBatchID, pPref, pYear); + + // 4. Conferma transazione + await transaction.CommitAsync(); + + // A questo punto, ogni oggetto in 'listOdl2ins' ha il ProdODLID aggiornato dal DB + return listOdl2ins; + } + catch (Exception ex) + { + await transaction.RollbackAsync(); + // Logga l'errore secondo le tue necessità + throw new Exception("Errore durante la creazione massiva degli ODL", ex); + } + } + + /// + /// Recupero record ProdOdl dato Tag/uID + /// + /// + /// + public async Task GetByUidAsync(string uID) + { + await using var dbCtx = await CreateContextAsync(); + return await dbCtx.DbSetProdODL + .AsNoTracking() + .FirstOrDefaultAsync(x => x.OdlTag == uID); + } + + /// + /// Elenco PODL non assegnati con struttura DTO appiattita + /// + /// + public async Task> GetUnassignAsync() + { + + await using var dbCtx = await CreateContextAsync(); + return await dbCtx.DbSetProdODL + .Where(x => !x.DateAssign.HasValue) + .AsNoTracking() + .Select(odl => new OdlAssignDto + { + Envir = odl.ProdBatchNav.Envir, + ProdODLID = odl.ProdODLID, + Description = odl.Description, + EstimTime = odl.EstimTime, + Index = odl.Index, + OdlTag = odl.OdlTag, + PhaseID = odl.PhaseID, + ProdBatchID = odl.ProdBatchID, + ProdPlantCod = odl.ProdPlantCod, + Qty = odl.Qty, + ResourceID = odl.ResourceID, + ItemList = odl.Item2OdlNav.Select(i => new ItemAssignDto + { + ProdItemID = i.ProdItemID, + OrderID = i.ProductionItemNav.OrderRowNav.OrderNav.OrderID, + OrderRowID = i.ProductionItemNav.OrderRowNav.OrderRowID, + OrderTag = i.ProductionItemNav.OrderRowNav.OrderNav.OrderCode, + OrderRowTag = i.ProductionItemNav.OrderRowNav.OrderRowCode, + ProdItemTag = i.ProductionItemNav.ProdItemTag ?? "***" + }).ToList() + }) + .ToListAsync(); + } + + #endregion Public Methods + } +} diff --git a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs index 92935cb5..c8c27b92 100644 --- a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs +++ b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs @@ -626,6 +626,94 @@ namespace EgwCoreLib.Lux.Data.Services return result; } + + /// + /// Aggiorna record ProdOdl (se trovato) con ItemListRaw (raw) inviata x calcolo PROD + /// + /// + /// + /// + public async Task ProdOdlUpdateItemRawAsync(string uID, string itemListRaw) + { + using var activity = StartActivity(); + string source = "DB+REDIS"; + bool result = await dbController.ProdOdlUpdateItemRawAsync(uID, itemListRaw); + await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:ProdOdl:*"); + activity?.SetTag("data.source", source); + LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms"); + return result; + } + +#if false + /// + /// Elenco completo plant gestiti + /// + /// + public async Task> ProdPlantGetAllAsync() + { + using var activity = StartActivity(); + string source = "DB"; + List? result = new List(); + // cerco in redis... + string currKey = $"{redisBaseKey}:ProdPlantList"; + RedisValue rawData = await _redisDb.StringGetAsync(currKey); + if (rawData.HasValue) + { + result = JsonConvert.DeserializeObject>($"{rawData}"); + source = "REDIS"; + } + else + { + result = await dbController.ProdPlantGetAllAsync(); + // serializzo e salvo con config x evitare loop... + rawData = JsonConvert.SerializeObject(result, JSSettings); + await _redisDb.StringSetAsync(currKey, rawData, UltraLongCache); + } + if (result == null) + { + result = new List(); + } + activity?.SetTag("data.source", source); + LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms"); + return result; + } + /// + /// Creazione record Batch x intestare gli ODL + /// + /// + /// + public async Task ProductionBatchCreateAsync(ProductionBatchModel newRec) + { + using var activity = StartActivity(); + string source = "DB+REDIS"; + // calcolo + var dbResult = await dbController.ProductionBatchCreateAsync(newRec); + // svuoto cache... + await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:Batch:*"); + await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:ODL:*"); + activity?.SetTag("data.source", source); + LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms"); + return dbResult; + } + + /// + /// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items) + /// + /// + /// + public async Task> ProductionOdlCreateAsync(List listOdl2ins) + { + using var activity = StartActivity(); + string source = "DB+REDIS"; + // calcolo + var dbResult = await dbController.ProductionOdlCreateAsync(listOdl2ins); + // svuoto cache... + await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:ODL:*"); + activity?.SetTag("data.source", source); + LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms"); + return dbResult; + } + /// /// Elenco ODL piatto da assegnare /// @@ -688,95 +776,8 @@ namespace EgwCoreLib.Lux.Data.Services LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms"); return result; } - - /// - /// Aggiorna record ProdOdl (se trovato) con ItemListRaw (raw) inviata x calcolo PROD - /// - /// - /// - /// - public async Task ProdOdlUpdateItemRawAsync(string uID, string itemListRaw) - { - using var activity = StartActivity(); - string source = "DB+REDIS"; - bool result = await dbController.ProdOdlUpdateItemRawAsync(uID, itemListRaw); - await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:ProdOdl:*"); - activity?.SetTag("data.source", source); - LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms"); - return result; - } - -#if true - /// - /// Elenco completo plant gestiti - /// - /// - public async Task> ProdPlantGetAllAsync() - { - using var activity = StartActivity(); - string source = "DB"; - List? result = new List(); - // cerco in redis... - string currKey = $"{redisBaseKey}:ProdPlantList"; - RedisValue rawData = await _redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.ProdPlantGetAllAsync(); - // serializzo e salvo con config x evitare loop... - rawData = JsonConvert.SerializeObject(result, JSSettings); - await _redisDb.StringSetAsync(currKey, rawData, UltraLongCache); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms"); - return result; - } #endif - /// - /// Creazione record Batch x intestare gli ODL - /// - /// - /// - public async Task ProductionBatchCreateAsync(ProductionBatchModel newRec) - { - using var activity = StartActivity(); - string source = "DB+REDIS"; - // calcolo - var dbResult = await dbController.ProductionBatchCreateAsync(newRec); - // svuoto cache... - await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:Batch:*"); - await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:ODL:*"); - activity?.SetTag("data.source", source); - LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms"); - return dbResult; - } - - /// - /// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items) - /// - /// - /// - public async Task> ProductionOdlCreateAsync(List listOdl2ins) - { - using var activity = StartActivity(); - string source = "DB+REDIS"; - // calcolo - var dbResult = await dbController.ProductionOdlCreateAsync(listOdl2ins); - // svuoto cache... - await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:ODL:*"); - activity?.SetTag("data.source", source); - LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms"); - return dbResult; - } /// /// Esegue salvataggio BOM sul DB diff --git a/EgwCoreLib.Lux.Data/Services/Production/IProductionBatchService.cs b/EgwCoreLib.Lux.Data/Services/Production/IProductionBatchService.cs new file mode 100644 index 00000000..c3785d80 --- /dev/null +++ b/EgwCoreLib.Lux.Data/Services/Production/IProductionBatchService.cs @@ -0,0 +1,18 @@ +using EgwCoreLib.Lux.Data.DbModel.Production; + +namespace EgwCoreLib.Lux.Data.Services.Production +{ + public interface IProductionBatchService + { + #region Public Methods + + /// + /// Creazione di un Batch con relativo Tag e info x creazione ODL correlati + /// + /// + /// + Task CreateAsync(ProductionBatchModel entity); + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/EgwCoreLib.Lux.Data/Services/Production/IProductionOdlService.cs b/EgwCoreLib.Lux.Data/Services/Production/IProductionOdlService.cs new file mode 100644 index 00000000..cfaa11f7 --- /dev/null +++ b/EgwCoreLib.Lux.Data/Services/Production/IProductionOdlService.cs @@ -0,0 +1,33 @@ +using EgwCoreLib.Lux.Core.Generic; +using EgwCoreLib.Lux.Data.DbModel.Production; + +namespace EgwCoreLib.Lux.Data.Services.Production +{ + public interface IProductionOdlService + { + #region Public Methods + + /// + /// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items) + /// + /// + /// + /// + Task> CreateAsync(List listOdl2ins); + + /// + /// Recupero record ProdOdl dato Tag/uID + /// + /// + /// + Task GetByUidAsync(string uID); + + /// + /// Elenco PODL non assegnati con struttura DTO appiattita + /// + /// + Task> GetUnassignAsync(); + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/EgwCoreLib.Lux.Data/Services/Production/ProductionBatchService.cs b/EgwCoreLib.Lux.Data/Services/Production/ProductionBatchService.cs new file mode 100644 index 00000000..0b7470cf --- /dev/null +++ b/EgwCoreLib.Lux.Data/Services/Production/ProductionBatchService.cs @@ -0,0 +1,51 @@ +using EgwCoreLib.Lux.Data.DbModel.Production; +using EgwCoreLib.Lux.Data.Repository.Production; +using Microsoft.Extensions.Configuration; +using StackExchange.Redis; + +namespace EgwCoreLib.Lux.Data.Services.Production +{ + public class ProductionBatchService : BaseServ, IProductionBatchService + { + #region Public Constructors + + public ProductionBatchService( + IConfiguration config, + IConnectionMultiplexer redis, + IProductionBatchRepository repo) : base(config, redis) + { + _className = "ProductionBatch"; + _repo = repo; + } + + #endregion Public Constructors + + #region Public Methods + + /// + /// Creazione di un Batch con relativo Tag e info x creazione ODL correlati + /// + /// + /// + public async Task CreateAsync(ProductionBatchModel entity) + { + return await TraceAsync($"{_className}.Create", async (activity) => + { + return await GetOrSetCacheAsync( + $"{_redisBaseKey}:{_className}:{entity.ProdBatchID}", + async () => await _repo.CreateAsync(entity), + FastCache + ); + }); + } + + #endregion Public Methods + + #region Private Fields + + private readonly string _className; + private readonly IProductionBatchRepository _repo; + + #endregion Private Fields + } +} \ No newline at end of file diff --git a/EgwCoreLib.Lux.Data/Services/Production/ProductionOdlService.cs b/EgwCoreLib.Lux.Data/Services/Production/ProductionOdlService.cs new file mode 100644 index 00000000..78498b09 --- /dev/null +++ b/EgwCoreLib.Lux.Data/Services/Production/ProductionOdlService.cs @@ -0,0 +1,86 @@ +using EgwCoreLib.Lux.Core.Generic; +using EgwCoreLib.Lux.Data.DbModel.Production; +using EgwCoreLib.Lux.Data.Repository.Production; +using Microsoft.Extensions.Configuration; +using StackExchange.Redis; + +namespace EgwCoreLib.Lux.Data.Services.Production +{ + public class ProductionOdlService : BaseServ, IProductionOdlService + { + #region Public Constructors + + public ProductionOdlService( + IConfiguration config, + IConnectionMultiplexer redis, + IProductionOdlRepository repo) : base(config, redis) + { + _className = "ProductionOdl"; + _repo = repo; + } + + #endregion Public Constructors + + #region Public Methods + + /// + /// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items) + /// + /// + /// + /// + public async Task> CreateAsync(List listOdl2ins) + { + return await TraceAsync($"{_className}.Create", async (activity) => + { + return await GetOrSetCacheAsync( + $"{_redisBaseKey}:{_className}:LAST", + async () => await _repo.CreateAsync(listOdl2ins), + UltraFastCache + ); + }); + } + + /// + /// Recupero record ProdOdl dato Tag/uID + /// + /// + /// + public async Task GetByUidAsync(string uID) + { + return await TraceAsync($"{_className}.GetByUid", async (activity) => + { + return await GetOrSetCacheAsync( + $"{_redisBaseKey}:{_className}:ByUid:{uID}", + async () => await _repo.GetByUidAsync(uID), + FastCache + ); + }); + } + + /// + /// Elenco PODL non assegnati con struttura DTO appiattita + /// + /// + public async Task> GetUnassignAsync() + { + return await TraceAsync($"{_className}.GetUnassign", async (activity) => + { + return await GetOrSetCacheAsync( + $"{_redisBaseKey}:{_className}:unassign", + async () => await _repo.GetUnassignAsync(), + UltraFastCache + ); + }); + } + + #endregion Public Methods + + #region Private Fields + + private readonly string _className; + private readonly IProductionOdlRepository _repo; + + #endregion Private Fields + } +} \ No newline at end of file diff --git a/Lux.API/Lux.API.csproj b/Lux.API/Lux.API.csproj index f85a6be0..52096a05 100644 --- a/Lux.API/Lux.API.csproj +++ b/Lux.API/Lux.API.csproj @@ -4,7 +4,7 @@ net8.0 enable enable - 1.1.2603.1816 + 1.1.2603.1818 diff --git a/Lux.API/Program.cs b/Lux.API/Program.cs index f3e53f96..e6460a68 100644 --- a/Lux.API/Program.cs +++ b/Lux.API/Program.cs @@ -3,6 +3,7 @@ using EgwCoreLib.Lux.Data.Repository.Config; using EgwCoreLib.Lux.Data.Repository.Cost; using EgwCoreLib.Lux.Data.Repository.Items; using EgwCoreLib.Lux.Data.Repository.Job; +using EgwCoreLib.Lux.Data.Repository.Production; using EgwCoreLib.Lux.Data.Repository.Sales; using EgwCoreLib.Lux.Data.Repository.Utils; using EgwCoreLib.Lux.Data.Services; @@ -10,6 +11,7 @@ using EgwCoreLib.Lux.Data.Services.Config; using EgwCoreLib.Lux.Data.Services.Cost; using EgwCoreLib.Lux.Data.Services.Items; using EgwCoreLib.Lux.Data.Services.Job; +using EgwCoreLib.Lux.Data.Services.Production; using EgwCoreLib.Lux.Data.Services.Sales; using EgwCoreLib.Lux.Data.Services.Utils; using Lux.API.Services; @@ -186,6 +188,9 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); @@ -205,6 +210,9 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/Lux.UI/Components/Compo/OrderRowMan.razor.cs b/Lux.UI/Components/Compo/OrderRowMan.razor.cs index 069ee9c6..9713dd2e 100644 --- a/Lux.UI/Components/Compo/OrderRowMan.razor.cs +++ b/Lux.UI/Components/Compo/OrderRowMan.razor.cs @@ -8,6 +8,7 @@ using EgwCoreLib.Lux.Data.DbModel.Sales; using EgwCoreLib.Lux.Data.DbModel.Utils; using EgwCoreLib.Lux.Data.Services; using EgwCoreLib.Lux.Data.Services.Config; +using EgwCoreLib.Lux.Data.Services.Production; using EgwCoreLib.Lux.Data.Services.Sales; using EgwCoreLib.Lux.Data.Services.Utils; using Microsoft.AspNetCore.Components; @@ -365,6 +366,8 @@ namespace Lux.UI.Components.Compo [Inject] private IEnvirParamService EPService { get; set; } = null!; + [Inject] + private IProductionPlantService PPService { get; set; } = null!; /// /// Costo totale calcolato x offerta @@ -1388,7 +1391,7 @@ namespace Lux.UI.Components.Compo AllConfEnvir = await EPService.GetAllAsync(); AllConfGlass = await CGService.GetAllAsync(); AvailProfileList = await CPService.GetAllAsync(); - AllProdPlant = await DLService.ProdPlantGetAllAsync(); + AllProdPlant = await PPService.GetAllAsync(); // FixMe ToDo rimuovere vers redis obsolete var rawProfiles = CDService.ProfileList(cEnvir, "Default"); diff --git a/Lux.UI/Components/Pages/WorkLoadBalance.razor.cs b/Lux.UI/Components/Pages/WorkLoadBalance.razor.cs index 5a752932..bcc4afe1 100644 --- a/Lux.UI/Components/Pages/WorkLoadBalance.razor.cs +++ b/Lux.UI/Components/Pages/WorkLoadBalance.razor.cs @@ -4,6 +4,7 @@ using EgwCoreLib.Lux.Data.DbModel.Production; using EgwCoreLib.Lux.Data.DbModel.Sales; using EgwCoreLib.Lux.Data.DbModel.Utils; using EgwCoreLib.Lux.Data.Services; +using EgwCoreLib.Lux.Data.Services.Production; using EgwCoreLib.Lux.Data.Services.Sales; using EgwCoreLib.Lux.Data.Services.Utils; using Microsoft.AspNetCore.Components; @@ -89,6 +90,10 @@ namespace Lux.UI.Components.Pages [Inject] private IOrderService OrdService { get; set; } = null!; + [Inject] + private ProductionBatchService PBService { get; set; } = null!; + [Inject] + private ProductionOdlService POService { get; set; } = null!; [Inject] private ProdService PService { get; set; } = null!; @@ -207,7 +212,7 @@ namespace Lux.UI.Components.Pages private async Task DoCreateBatch(BatchCreateInfo batchData) { // per prima cosa creo il batch... - var recBatch = await DLService.ProductionBatchCreateAsync(batchData.NewBatch); + var recBatch = await PBService.CreateAsync(batchData.NewBatch); List ordRowIdList = new List(); // se ok batch... if (recBatch != null) @@ -242,7 +247,7 @@ namespace Lux.UI.Components.Pages if (listOdl.Count > 0) { // creazione ODL - List prodODL_DbList = await DLService.ProductionOdlCreateAsync(listOdl); + List prodODL_DbList = await POService.CreateAsync(listOdl); // fix items sul batch ID, ciclo sui prodGroup int numParts = 0; @@ -346,7 +351,7 @@ namespace Lux.UI.Components.Pages private async Task DoPrepareRawMatSel(OdlAssignDto odlRec) { // recupero bomOdl da passare... - var prodOdlRec = await DLService.ProdOdlGetByUidAsync(odlRec.OdlTag); + var prodOdlRec = await POService.GetByUidAsync(odlRec.OdlTag); // se ho qualcosa e contiene bom... if (prodOdlRec != null && prodOdlRec.ListBoM.Count > 0) { @@ -399,7 +404,7 @@ namespace Lux.UI.Components.Pages // prendo solo ordini stimati (NON ancora bilanciati o pianificati) ListEstimRecords = await OrdRService.GetByStateMinAsync(OrderStates.Estimated, PeriodoSel.Inizio, PeriodoSel.Fine); ListBalancedRecords = await DLService.ProdGroupByOrderState(OrderStates.Assigned); - ListOdl = await DLService.ProdOdlAssignGetAsync(); + ListOdl = await POService.GetUnassignAsync(); } /// diff --git a/Lux.UI/Lux.UI.csproj b/Lux.UI/Lux.UI.csproj index 4b051c89..1b0f853b 100644 --- a/Lux.UI/Lux.UI.csproj +++ b/Lux.UI/Lux.UI.csproj @@ -5,7 +5,7 @@ enable enable aspnet-Lux.UI-a758c101-a2f4-4e38-977d-1c4887dbbd50 - 1.1.2603.1816 + 1.1.2603.1818 diff --git a/Lux.UI/Program.cs b/Lux.UI/Program.cs index 03eaf6cc..ec17cffb 100644 --- a/Lux.UI/Program.cs +++ b/Lux.UI/Program.cs @@ -3,6 +3,7 @@ using EgwCoreLib.Lux.Data.Repository.Config; using EgwCoreLib.Lux.Data.Repository.Cost; using EgwCoreLib.Lux.Data.Repository.Items; using EgwCoreLib.Lux.Data.Repository.Job; +using EgwCoreLib.Lux.Data.Repository.Production; using EgwCoreLib.Lux.Data.Repository.Sales; using EgwCoreLib.Lux.Data.Repository.Utils; using EgwCoreLib.Lux.Data.Services; @@ -10,6 +11,7 @@ using EgwCoreLib.Lux.Data.Services.Config; using EgwCoreLib.Lux.Data.Services.Cost; using EgwCoreLib.Lux.Data.Services.Items; using EgwCoreLib.Lux.Data.Services.Job; +using EgwCoreLib.Lux.Data.Services.Production; using EgwCoreLib.Lux.Data.Services.Sales; using EgwCoreLib.Lux.Data.Services.Utils; using Lux.UI.Components; @@ -224,6 +226,9 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); @@ -243,6 +248,9 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); @@ -250,7 +258,7 @@ builder.Services.AddScoped(); // Da rivedere!!! #if false -// registrazione automatica Repository e Servizi con Scrutor +// registrazione automatica Service e Servizi con Scrutor builder.Services.Scan(scan => scan .FromAssemblyOf() // Cerca nell'assembly dove si trova BaseServ diff --git a/Resources/ChangeLog.html b/Resources/ChangeLog.html index 1fb27bdf..99afd8e4 100644 --- a/Resources/ChangeLog.html +++ b/Resources/ChangeLog.html @@ -1,6 +1,6 @@ LUX - Web Windows MES -

    Versione: 1.1.2603.1816

    +

    Versione: 1.1.2603.1818


    Note di rilascio:
    • diff --git a/Resources/VersNum.txt b/Resources/VersNum.txt index cb33259f..b7202442 100644 --- a/Resources/VersNum.txt +++ b/Resources/VersNum.txt @@ -1 +1 @@ -1.1.2603.1816 +1.1.2603.1818 diff --git a/Resources/manifest.xml b/Resources/manifest.xml index 69c3d6eb..70c53cc6 100644 --- a/Resources/manifest.xml +++ b/Resources/manifest.xml @@ -1,6 +1,6 @@ - 1.1.2603.1816 + 1.1.2603.1818 http://nexus.steamware.net/repository/SWS/GPW/stable/GPW.UI.zip http://nexus.steamware.net/repository/SWS/GPW/stable/ChangeLog.html false From e3b9c6e0e721bf7bf31e8bf36678ffbc12ffbc28 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 18 Mar 2026 18:09:43 +0100 Subject: [PATCH 5/5] Eliminazione commenti e fix nome servizi --- .../Controllers/LuxController.cs | 180 ------------------ .../Services/DataLayerServices.cs | 135 ------------- .../Components/Pages/WorkLoadBalance.razor.cs | 4 +- 3 files changed, 2 insertions(+), 317 deletions(-) diff --git a/EgwCoreLib.Lux.Data/Controllers/LuxController.cs b/EgwCoreLib.Lux.Data/Controllers/LuxController.cs index d813d7b1..91969895 100644 --- a/EgwCoreLib.Lux.Data/Controllers/LuxController.cs +++ b/EgwCoreLib.Lux.Data/Controllers/LuxController.cs @@ -1071,186 +1071,6 @@ namespace EgwCoreLib.Lux.Data.Controllers return answ; } -#if false - internal async Task> ProdPlantGetAllAsync() - { - List dbResult = new List(); - //using (DataLayerContext dbCtx = new DataLayerContext(_config)) - using (DataLayerContext dbCtx = new DataLayerContext()) - { - try - { - dbResult = await dbCtx - .DbSetProdPlant - .ToListAsync(); - } - catch (Exception exc) - { - Log.Error($"Eccezione durante ProdPlantGetAllAsync{Environment.NewLine}{exc}"); - } - } - return dbResult; - } - - /// - /// Creazione di un Batch con relativo Tag e info x creazione ODL correlati - /// - /// - /// - internal async Task ProductionBatchCreateAsync(ProductionBatchModel newRec) - { - ProductionBatchModel dbResult = null; - //using (DataLayerContext dbCtx = new DataLayerContext(_config)) - using (DataLayerContext dbCtx = new DataLayerContext()) - { - try - { - // Definiamo i parametri di input - var pDesc = new MySqlParameter("@pDescription", newRec.Description ?? (object)DBNull.Value); - var pDate = new MySqlParameter("@pDueDate", newRec.DueDate); - var pPref = new MySqlParameter("@pPrefix", "BC."); - var pYear = new MySqlParameter("@pYear", newRec.DueDate.Year); - var pEnv = new MySqlParameter("@pEnv", newRec.Envir); - - // Eseguiamo la procedura e mappiamo il risultato direttamente sul modello - // Nota: DbSetProdBatch deve essere configurato nel DbContext - var result = await dbCtx - .DbSetProdBatch - .FromSqlRaw("CALL stp_ProdBatch_insert(@pDescription, @pDueDate, @pPrefix, @pYear, @pEnv)", pDesc, pDate, pPref, pYear, pEnv) - .ToListAsync(); - - dbResult = result.FirstOrDefault() ?? new ProductionBatchModel(); - } - catch (Exception ex) - { - throw new Exception("Errore durante ProductionBatchCreateAsync", ex); - } - return dbResult; - } - } - - /// - /// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items) - /// - /// - /// - /// - internal async Task> ProductionOdlCreateAsync(List listOdl2ins) - { - //using (DataLayerContext dbCtx = new DataLayerContext(_config)) - using (DataLayerContext dbCtx = new DataLayerContext()) - { - // avvio transazione - using var transaction = await dbCtx.Database.BeginTransactionAsync(); - - try - { - int cYear = DateTime.Today.Year; - - // insert in blocco - dbCtx.DbSetProdODL.AddRange(listOdl2ins); - - // 3. Salvataggio massivo - // EF Core 8 ottimizzerà gli insert in batch dove possibile - await dbCtx.SaveChangesAsync(); - - // stored update Tags - var pProdBatchID = new MySqlParameter("@pDueDate", listOdl2ins.FirstOrDefault()?.ProdBatchID ?? 0); - var pPref = new MySqlParameter("@pPrefix", "ODL."); - var pYear = new MySqlParameter("@pYear", cYear); - await dbCtx.Database.ExecuteSqlRawAsync("CALL stp_ProdOdl_UpdateTag(@pProdBatchID, @pPrefix, @pYear)", pProdBatchID, pPref, pYear); - - // 4. Conferma transazione - await transaction.CommitAsync(); - - // A questo punto, ogni oggetto in 'listOdl2ins' ha il ProdODLID aggiornato dal DB - return listOdl2ins; - } - catch (Exception ex) - { - await transaction.RollbackAsync(); - // Logga l'errore secondo le tue necessità - throw new Exception("Errore durante la creazione massiva degli ODL", ex); - } - } - } - - /// - /// Elenco PODL non assegnati con struttura DTO appiattita - /// - /// - internal async Task?> ProdOdlAssignGetAsync() - { - List? dbResults = null; - //using (DataLayerContext dbCtx = new DataLayerContext(_config)) - using (DataLayerContext dbCtx = new DataLayerContext()) - { - try - { - dbResults = await dbCtx.DbSetProdODL - .Where(x => !x.DateAssign.HasValue) - .Select(odl => new OdlAssignDto - { - Envir = odl.ProdBatchNav.Envir, - ProdODLID = odl.ProdODLID, - Description = odl.Description, - EstimTime = odl.EstimTime, - Index = odl.Index, - OdlTag = odl.OdlTag, - PhaseID = odl.PhaseID, - ProdBatchID = odl.ProdBatchID, - ProdPlantCod = odl.ProdPlantCod, - Qty = odl.Qty, - ResourceID = odl.ResourceID, - ItemList = odl.Item2OdlNav.Select(i => new ItemAssignDto - { - ProdItemID = i.ProdItemID, - OrderID = i.ProductionItemNav.OrderRowNav.OrderNav.OrderID, - OrderRowID = i.ProductionItemNav.OrderRowNav.OrderRowID, - OrderTag = i.ProductionItemNav.OrderRowNav.OrderNav.OrderCode, - OrderRowTag = i.ProductionItemNav.OrderRowNav.OrderRowCode, - ProdItemTag = i.ProductionItemNav.ProdItemTag ?? "***" - }).ToList() - }) - .ToListAsync(); - } - catch (Exception exc) - { - Log.Error($"Eccezione durante ProductionOdlUnassignAsync{Environment.NewLine}{exc}"); - } - } - return dbResults; - } - - /// - /// Recupero record ProdOdl dato Tag/uID - /// - /// - /// - internal async Task ProdOdlGetByUidAsync(string uID) - { - ProductionODLModel? answ = null; - //using (DataLayerContext dbCtx = new DataLayerContext(_config)) - using (DataLayerContext dbCtx = new DataLayerContext()) - { - try - { - answ = await dbCtx - .DbSetProdODL - .Where(x => x.OdlTag == uID) - .FirstOrDefaultAsync(); - } - catch (Exception exc) - { - Log.Error($"Eccezione durante ProdOdlGetByUidAsync{Environment.NewLine}{exc}"); - } - } - return answ; - } - -#endif - - /// /// Elenco PODL non assegnati /// diff --git a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs index c8c27b92..31373a1c 100644 --- a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs +++ b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs @@ -644,141 +644,6 @@ namespace EgwCoreLib.Lux.Data.Services return result; } -#if false - /// - /// Elenco completo plant gestiti - /// - /// - public async Task> ProdPlantGetAllAsync() - { - using var activity = StartActivity(); - string source = "DB"; - List? result = new List(); - // cerco in redis... - string currKey = $"{redisBaseKey}:ProdPlantList"; - RedisValue rawData = await _redisDb.StringGetAsync(currKey); - if (rawData.HasValue) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.ProdPlantGetAllAsync(); - // serializzo e salvo con config x evitare loop... - rawData = JsonConvert.SerializeObject(result, JSSettings); - await _redisDb.StringSetAsync(currKey, rawData, UltraLongCache); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms"); - return result; - } - /// - /// Creazione record Batch x intestare gli ODL - /// - /// - /// - public async Task ProductionBatchCreateAsync(ProductionBatchModel newRec) - { - using var activity = StartActivity(); - string source = "DB+REDIS"; - // calcolo - var dbResult = await dbController.ProductionBatchCreateAsync(newRec); - // svuoto cache... - await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:Batch:*"); - await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:ODL:*"); - activity?.SetTag("data.source", source); - LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms"); - return dbResult; - } - - /// - /// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items) - /// - /// - /// - public async Task> ProductionOdlCreateAsync(List listOdl2ins) - { - using var activity = StartActivity(); - string source = "DB+REDIS"; - // calcolo - var dbResult = await dbController.ProductionOdlCreateAsync(listOdl2ins); - // svuoto cache... - await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:ODL:*"); - activity?.SetTag("data.source", source); - LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms"); - return dbResult; - } - - /// - /// Elenco ODL piatto da assegnare - /// - /// - public async Task?> ProdOdlAssignGetAsync() - { - using var activity = StartActivity(); - string source = "DB"; - List? result = new List(); - // cerco in redis... - string currKey = $"{redisBaseKey}:ProdOdl:Unassigned"; - RedisValue rawData = await _redisDb.StringGetAsync(currKey); - if (rawData.HasValue && rawData.Length() > 2) - { - result = JsonConvert.DeserializeObject>($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.ProdOdlAssignGetAsync(); - // serializzo e salvo con config x evitare loop... - rawData = JsonConvert.SerializeObject(result, JSSettings); - await _redisDb.StringSetAsync(currKey, rawData, LongCache); - } - if (result == null) - { - result = new List(); - } - activity?.SetTag("data.source", source); - LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms"); - return result; - } - - /// - /// Recupero ODL da UID - /// - /// - /// - public async Task ProdOdlGetByUidAsync(string uID) - { - using var activity = StartActivity(); - string source = "DB"; - ProductionODLModel? result = null; - // cerco in redis... - string currKey = $"{redisBaseKey}:ProdOdl:{uID}"; - RedisValue rawData = await _redisDb.StringGetAsync(currKey); - if (rawData.HasValue && rawData.Length() > 2) - { - result = JsonConvert.DeserializeObject($"{rawData}"); - source = "REDIS"; - } - else - { - result = await dbController.ProdOdlGetByUidAsync(uID); - // serializzo e salvo con config x evitare loop... - rawData = JsonConvert.SerializeObject(result, JSSettings); - await _redisDb.StringSetAsync(currKey, rawData, LongCache); - } - activity?.SetTag("data.source", source); - LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms"); - return result; - } -#endif - - /// /// Esegue salvataggio BOM sul DB /// diff --git a/Lux.UI/Components/Pages/WorkLoadBalance.razor.cs b/Lux.UI/Components/Pages/WorkLoadBalance.razor.cs index bcc4afe1..0f207ffe 100644 --- a/Lux.UI/Components/Pages/WorkLoadBalance.razor.cs +++ b/Lux.UI/Components/Pages/WorkLoadBalance.razor.cs @@ -91,9 +91,9 @@ namespace Lux.UI.Components.Pages [Inject] private IOrderService OrdService { get; set; } = null!; [Inject] - private ProductionBatchService PBService { get; set; } = null!; + private IProductionBatchService PBService { get; set; } = null!; [Inject] - private ProductionOdlService POService { get; set; } = null!; + private IProductionOdlService POService { get; set; } = null!; [Inject] private ProdService PService { get; set; } = null!;