Merge branch 'feature/MigrateDataLayerService' of https://gitlab.steamware.net/etis/lux into feature/MigrateDataLayerService

This commit is contained in:
Samuele E. Locatelli (W11-AI)
2026-03-18 18:11:31 +01:00
24 changed files with 536 additions and 320 deletions
+2 -2
View File
@@ -8,8 +8,8 @@
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageVersion>
<PackageVersion Include="Egw.Lux.WebWindow.Base" Version="3.1.3.916" />
<PackageVersion Include="Egw.Lux.WebWindowComplex" Version="3.1.3.916" />
<PackageVersion Include="Egw.Lux.WebWindow.Base" Version="3.1.3.1610" />
<PackageVersion Include="Egw.Lux.WebWindowComplex" Version="3.1.3.1610" />
<PackageVersion Include="Egw.Window.Data" Version="2.8.1.2611" />
<PackageVersion Include="EgwCoreLib.Razor" Version="1.5.2511.312" />
<PackageVersion Include="EgwCoreLib.Utils" Version="1.5.2511.312" />
@@ -959,78 +959,6 @@ namespace EgwCoreLib.Lux.Data.Controllers
return numItem;
}
/// <summary>
/// Elenco PODL non assegnati con struttura DTO appiattita
/// </summary>
/// <returns></returns>
internal async Task<List<OdlAssignDto>?> ProdOdlAssignGetAsync()
{
List<OdlAssignDto>? 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;
}
/// <summary>
/// Recupero record ProdOdl dato Tag/uID
/// </summary>
/// <param name="uID"></param>
/// <returns></returns>
internal async Task<ProductionODLModel?> 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;
}
/// <summary>
/// Aggiorna record ProdOdl (se trovato) con BOM (raw) ricevuta
@@ -1143,109 +1071,6 @@ namespace EgwCoreLib.Lux.Data.Controllers
return answ;
}
internal async Task<List<ProductionPlantModel>> ProdPlantGetAllAsync()
{
List<ProductionPlantModel> dbResult = new List<ProductionPlantModel>();
//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;
}
/// <summary>
/// Creazione di un Batch con relativo Tag e info x creazione ODL correlati
/// </summary>
/// <param name="newRec"></param>
/// <returns></returns>
internal async Task<ProductionBatchModel?> 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;
}
}
/// <summary>
/// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items)
/// </summary>
/// <param name="listOdl2ins"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
internal async Task<List<ProductionODLModel>> ProductionOdlCreateAsync(List<ProductionODLModel> 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);
}
}
}
/// <summary>
/// Elenco PODL non assegnati
/// </summary>
@@ -0,0 +1,15 @@
using EgwCoreLib.Lux.Data.DbModel.Production;
namespace EgwCoreLib.Lux.Data.Repository.Production
{
public interface IProductionBatchRepository
{
/// <summary>
/// Creazione di un Batch con relativo Tag e info x creazione ODL correlati
/// </summary>
/// <param name="newRec"></param>
/// <returns></returns>
Task<ProductionBatchModel?> CreateAsync(ProductionBatchModel entity);
}
}
@@ -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
/// <summary>
/// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items)
/// </summary>
/// <param name="listOdl2ins"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
Task<List<ProductionODLModel>> CreateAsync(List<ProductionODLModel> listOdl2ins);
/// <summary>
/// Recupero record ProdOdl dato Tag/uID
/// </summary>
/// <param name="uID"></param>
/// <returns></returns>
Task<ProductionODLModel?> GetByUidAsync(string uID);
/// <summary>
/// Elenco PODL non assegnati con struttura DTO appiattita
/// </summary>
/// <returns></returns>
Task<List<OdlAssignDto>> GetUnassignAsync();
#endregion Public Methods
}
}
@@ -0,0 +1,9 @@
using EgwCoreLib.Lux.Data.DbModel.Production;
namespace EgwCoreLib.Lux.Data.Repository.Production
{
public interface IProductionPlantRepository
{
Task<List<ProductionPlantModel>> GetAllAsync();
}
}
@@ -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<DataLayerContext> ctxFactory) : base(ctxFactory)
{
}
#endregion Public Constructors
#region Public Methods
/// <summary>
/// Creazione di un Batch con relativo Tag e info x creazione ODL correlati
/// </summary>
/// <param name="newRec"></param>
/// <returns></returns>
public async Task<ProductionBatchModel?> 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
}
}
@@ -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<DataLayerContext> ctxFactory) : base(ctxFactory)
{
}
#endregion Public Constructors
#region Public Methods
/// <summary>
/// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items)
/// </summary>
/// <param name="listOdl2ins"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public async Task<List<ProductionODLModel>> CreateAsync(List<ProductionODLModel> 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);
}
}
/// <summary>
/// Recupero record ProdOdl dato Tag/uID
/// </summary>
/// <param name="uID"></param>
/// <returns></returns>
public async Task<ProductionODLModel?> GetByUidAsync(string uID)
{
await using var dbCtx = await CreateContextAsync();
return await dbCtx.DbSetProdODL
.AsNoTracking()
.FirstOrDefaultAsync(x => x.OdlTag == uID);
}
/// <summary>
/// Elenco PODL non assegnati con struttura DTO appiattita
/// </summary>
/// <returns></returns>
public async Task<List<OdlAssignDto>> 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
}
}
@@ -0,0 +1,28 @@
using EgwCoreLib.Lux.Data.DbModel.Production;
using Microsoft.EntityFrameworkCore;
namespace EgwCoreLib.Lux.Data.Repository.Production
{
public class ProductionPlantRepository : BaseRepository, IProductionPlantRepository
{
#region Public Constructors
public ProductionPlantRepository(IDbContextFactory<DataLayerContext> ctxFactory) : base(ctxFactory)
{
}
#endregion Public Constructors
#region Public Methods
public async Task<List<ProductionPlantModel>> GetAllAsync()
{
await using var dbCtx = await CreateContextAsync();
return await dbCtx.DbSetProdPlant
.AsNoTracking()
.ToListAsync();
}
#endregion Public Methods
}
}
@@ -626,68 +626,6 @@ namespace EgwCoreLib.Lux.Data.Services
return result;
}
/// <summary>
/// Elenco ODL piatto da assegnare
/// </summary>
/// <returns></returns>
public async Task<List<OdlAssignDto>?> ProdOdlAssignGetAsync()
{
using var activity = StartActivity();
string source = "DB";
List<OdlAssignDto>? result = new List<OdlAssignDto>();
// cerco in redis...
string currKey = $"{redisBaseKey}:ProdOdl:Unassigned";
RedisValue rawData = await _redisDb.StringGetAsync(currKey);
if (rawData.HasValue && rawData.Length() > 2)
{
result = JsonConvert.DeserializeObject<List<OdlAssignDto>>($"{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<OdlAssignDto>();
}
activity?.SetTag("data.source", source);
LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Recupero ODL da UID
/// </summary>
/// <param name="uID"></param>
/// <returns></returns>
public async Task<ProductionODLModel?> 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<ProductionODLModel>($"{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;
}
/// <summary>
/// Aggiorna record ProdOdl (se trovato) con ItemListRaw (raw) inviata x calcolo PROD
@@ -706,76 +644,6 @@ namespace EgwCoreLib.Lux.Data.Services
return result;
}
/// <summary>
/// Elenco completo plant gestiti
/// </summary>
/// <returns></returns>
public async Task<List<ProductionPlantModel>> ProdPlantGetAllAsync()
{
using var activity = StartActivity();
string source = "DB";
List<ProductionPlantModel>? result = new List<ProductionPlantModel>();
// cerco in redis...
string currKey = $"{redisBaseKey}:ProdPlantList";
RedisValue rawData = await _redisDb.StringGetAsync(currKey);
if (rawData.HasValue)
{
result = JsonConvert.DeserializeObject<List<ProductionPlantModel>>($"{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<ProductionPlantModel>();
}
activity?.SetTag("data.source", source);
LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Creazione record Batch x intestare gli ODL
/// </summary>
/// <param name="newRec"></param>
/// <returns></returns>
public async Task<ProductionBatchModel?> 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;
}
/// <summary>
/// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items)
/// </summary>
/// <param name="listOdl2ins"></param>
/// <returns></returns>
public async Task<List<ProductionODLModel>> ProductionOdlCreateAsync(List<ProductionODLModel> 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;
}
/// <summary>
/// Esegue salvataggio BOM sul DB
/// </summary>
@@ -0,0 +1,18 @@
using EgwCoreLib.Lux.Data.DbModel.Production;
namespace EgwCoreLib.Lux.Data.Services.Production
{
public interface IProductionBatchService
{
#region Public Methods
/// <summary>
/// Creazione di un Batch con relativo Tag e info x creazione ODL correlati
/// </summary>
/// <param name="newRec"></param>
/// <returns></returns>
Task<ProductionBatchModel?> CreateAsync(ProductionBatchModel entity);
#endregion Public Methods
}
}
@@ -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
/// <summary>
/// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items)
/// </summary>
/// <param name="listOdl2ins"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
Task<List<ProductionODLModel>> CreateAsync(List<ProductionODLModel> listOdl2ins);
/// <summary>
/// Recupero record ProdOdl dato Tag/uID
/// </summary>
/// <param name="uID"></param>
/// <returns></returns>
Task<ProductionODLModel?> GetByUidAsync(string uID);
/// <summary>
/// Elenco PODL non assegnati con struttura DTO appiattita
/// </summary>
/// <returns></returns>
Task<List<OdlAssignDto>> GetUnassignAsync();
#endregion Public Methods
}
}
@@ -0,0 +1,9 @@
using EgwCoreLib.Lux.Data.DbModel.Production;
namespace EgwCoreLib.Lux.Data.Services.Production
{
public interface IProductionPlantService
{
Task<List<ProductionPlantModel>> GetAllAsync();
}
}
@@ -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
/// <summary>
/// Creazione di un Batch con relativo Tag e info x creazione ODL correlati
/// </summary>
/// <param name="newRec"></param>
/// <returns></returns>
public async Task<ProductionBatchModel?> 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
}
}
@@ -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
/// <summary>
/// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items)
/// </summary>
/// <param name="listOdl2ins"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public async Task<List<ProductionODLModel>> CreateAsync(List<ProductionODLModel> listOdl2ins)
{
return await TraceAsync($"{_className}.Create", async (activity) =>
{
return await GetOrSetCacheAsync(
$"{_redisBaseKey}:{_className}:LAST",
async () => await _repo.CreateAsync(listOdl2ins),
UltraFastCache
);
});
}
/// <summary>
/// Recupero record ProdOdl dato Tag/uID
/// </summary>
/// <param name="uID"></param>
/// <returns></returns>
public async Task<ProductionODLModel?> GetByUidAsync(string uID)
{
return await TraceAsync($"{_className}.GetByUid", async (activity) =>
{
return await GetOrSetCacheAsync(
$"{_redisBaseKey}:{_className}:ByUid:{uID}",
async () => await _repo.GetByUidAsync(uID),
FastCache
);
});
}
/// <summary>
/// Elenco PODL non assegnati con struttura DTO appiattita
/// </summary>
/// <returns></returns>
public async Task<List<OdlAssignDto>> 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
}
}
@@ -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<List<ProductionPlantModel>> 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
}
}
+1 -1
View File
@@ -4,7 +4,7 @@
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<Version>1.1.2603.1813</Version>
<Version>1.1.2603.1818</Version>
</PropertyGroup>
<ItemGroup>
+10
View File
@@ -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;
@@ -185,6 +187,10 @@ builder.Services.AddScoped<IJobTaskRepository, JobTaskRepository>();
builder.Services.AddScoped<IOfferRepository, OfferRepository>();
builder.Services.AddScoped<IOfferRowRepository, OfferRowRepository>();
builder.Services.AddScoped<IOrderRepository, OrderRepository>();
builder.Services.AddScoped<IOrderRowRepository, OrderRowRepository>();
builder.Services.AddScoped<IProductionBatchRepository, ProductionBatchRepository>();
builder.Services.AddScoped<IProductionOdlRepository, ProductionOdlRepository>();
builder.Services.AddScoped<IProductionPlantRepository, ProductionPlantRepository>();
builder.Services.AddScoped<IResourceRepository, ResourceRepository>();
builder.Services.AddScoped<ISellingItemRepository, SellingItemRepository>();
builder.Services.AddScoped<ITemplateRepository, TemplateRepository>();
@@ -203,6 +209,10 @@ builder.Services.AddScoped<IJobTaskService, JobTaskService>();
builder.Services.AddScoped<IOfferService, OfferService>();
builder.Services.AddScoped<IOfferRowService, OfferRowService>();
builder.Services.AddScoped<IOrderService, OrderService>();
builder.Services.AddScoped<IOrderRowService, OrderRowService>();
builder.Services.AddScoped<IProductionBatchService, ProductionBatchService>();
builder.Services.AddScoped<IProductionOdlService, ProductionOdlService>();
builder.Services.AddScoped<IProductionPlantService, ProductionPlantService>();
builder.Services.AddScoped<IResourceService, ResourceService>();
builder.Services.AddScoped<ISellingItemService, SellingItemService>();
builder.Services.AddScoped<ITemplateService, TemplateService>();
+4 -1
View File
@@ -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!;
/// <summary>
/// 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");
@@ -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 IProductionBatchService PBService { get; set; } = null!;
[Inject]
private IProductionOdlService 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<int> ordRowIdList = new List<int>();
// se ok batch...
if (recBatch != null)
@@ -242,7 +247,7 @@ namespace Lux.UI.Components.Pages
if (listOdl.Count > 0)
{
// creazione ODL
List<ProductionODLModel> prodODL_DbList = await DLService.ProductionOdlCreateAsync(listOdl);
List<ProductionODLModel> 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();
}
/// <summary>
+1 -1
View File
@@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>aspnet-Lux.UI-a758c101-a2f4-4e38-977d-1c4887dbbd50</UserSecretsId>
<Version>1.1.2603.1813</Version>
<Version>1.1.2603.1818</Version>
</PropertyGroup>
<ItemGroup>
+11 -1
View File
@@ -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;
@@ -223,6 +225,10 @@ builder.Services.AddScoped<IJobTaskRepository, JobTaskRepository>();
builder.Services.AddScoped<IOfferRepository, OfferRepository>();
builder.Services.AddScoped<IOfferRowRepository, OfferRowRepository>();
builder.Services.AddScoped<IOrderRepository, OrderRepository>();
builder.Services.AddScoped<IOrderRowRepository, OrderRowRepository>();
builder.Services.AddScoped<IProductionBatchRepository, ProductionBatchRepository>();
builder.Services.AddScoped<IProductionOdlRepository, ProductionOdlRepository>();
builder.Services.AddScoped<IProductionPlantRepository, ProductionPlantRepository>();
builder.Services.AddScoped<IResourceRepository, ResourceRepository>();
builder.Services.AddScoped<ISellingItemRepository, SellingItemRepository>();
builder.Services.AddScoped<ITemplateRepository, TemplateRepository>();
@@ -241,6 +247,10 @@ builder.Services.AddScoped<IJobTaskService, JobTaskService>();
builder.Services.AddScoped<IOfferService, OfferService>();
builder.Services.AddScoped<IOfferRowService, OfferRowService>();
builder.Services.AddScoped<IOrderService, OrderService>();
builder.Services.AddScoped<IOrderRowService, OrderRowService>();
builder.Services.AddScoped<IProductionBatchService, ProductionBatchService>();
builder.Services.AddScoped<IProductionOdlService, ProductionOdlService>();
builder.Services.AddScoped<IProductionPlantService, ProductionPlantService>();
builder.Services.AddScoped<IResourceService, ResourceService>();
builder.Services.AddScoped<ISellingItemService, SellingItemService>();
builder.Services.AddScoped<ITemplateService, TemplateService>();
@@ -248,7 +258,7 @@ builder.Services.AddScoped<ITemplateRowService, TemplateRowService>();
// Da rivedere!!!
#if false
// registrazione automatica Repository e Servizi con Scrutor
// registrazione automatica Service e Servizi con Scrutor
builder.Services.Scan(scan => scan
.FromAssemblyOf<BaseServ>() // Cerca nell'assembly dove si trova BaseServ
+1 -1
View File
@@ -1,6 +1,6 @@
<body>
<i>LUX - Web Windows MES</i>
<h4>Versione: 1.1.2603.1813</h4>
<h4>Versione: 1.1.2603.1818</h4>
<br /> Note di rilascio:
<ul>
<li>
+1 -1
View File
@@ -1 +1 @@
1.1.2603.1813
1.1.2603.1818
+1 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<item>
<version>1.1.2603.1813</version>
<version>1.1.2603.1818</version>
<url>http://nexus.steamware.net/repository/SWS/GPW/stable/GPW.UI.zip</url>
<changelog>http://nexus.steamware.net/repository/SWS/GPW/stable/ChangeLog.html</changelog>
<mandatory>false</mandatory>