Completata dismissione LuxController!!!
This commit is contained in:
@@ -1,307 +0,0 @@
|
||||
using EgwCoreLib.Lux.Data.DbModel.Production;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using NLog;
|
||||
using StackExchange.Redis;
|
||||
using System.Data;
|
||||
|
||||
namespace EgwCoreLib.Lux.Data.Controllers
|
||||
{
|
||||
internal class LuxController
|
||||
{
|
||||
|
||||
#region Internal Methods
|
||||
|
||||
|
||||
#if true
|
||||
/// <summary>
|
||||
/// Assegnazione in blocco degli item agli ODL corrispondenti
|
||||
/// </summary>
|
||||
/// <param name="dbList"></param>
|
||||
/// <param name="dictParts"></param>
|
||||
/// <returns></returns>
|
||||
internal async Task<int> ProdItem2ODL_AssignAsync(List<ProductionODLModel> dbList, Dictionary<(int phaseId, int resId, string machine, int index), List<string>> dictParts)
|
||||
{
|
||||
int totalCreated = 0;
|
||||
using (DataLayerContext dbCtx = new DataLayerContext())
|
||||
{
|
||||
// 1. Recuperiamo tutti i ProdBatchID coinvolti per fare una sola query
|
||||
List<int> batchIds = dbList.Select(o => o.ProdBatchID).Distinct().ToList();
|
||||
|
||||
if (batchIds != null && batchIds.Count > 0)
|
||||
{
|
||||
// 2. Carichiamo in memoria i ProdItem necessari (solo ID e Tag per risparmiare RAM)
|
||||
var itemsList = await dbCtx.DbSetProdItem
|
||||
.Where(x => batchIds.Contains(x.ProdBatchID ?? 0) && x.ProdItemTag != null && x.ProdItemTag != "")
|
||||
.Select(x => new { x.ProdItemID, x.ProdItemTag })
|
||||
.ToListAsync();
|
||||
|
||||
// 1. Usiamo il "!" (null-forgiving operator) dopo x.ProdItemTag
|
||||
// perché il filtro .Where sopra garantisce che non sia null.
|
||||
var itemLookup = itemsList
|
||||
.GroupBy(x => x.ProdItemTag!)
|
||||
.ToDictionary(
|
||||
g => g.Key,
|
||||
g => g.First().ProdItemID,
|
||||
StringComparer.OrdinalIgnoreCase
|
||||
);
|
||||
|
||||
using var transaction = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
var relationsToInsert = new List<ProductionItem2ODLModel>();
|
||||
|
||||
foreach (var odl in dbList)
|
||||
{
|
||||
var key = (odl.PhaseID ?? 0, odl.ResourceID ?? 0, odl.ProdPlantCod, odl.Index);
|
||||
|
||||
if (dictParts.TryGetValue(key, out List<string> tagList))
|
||||
{
|
||||
foreach (var tag in tagList)
|
||||
{
|
||||
// 3. Cerchiamo l'ID corrispondente al tag nel nostro lookup locale
|
||||
if (itemLookup.TryGetValue(tag, out int realItemId))
|
||||
{
|
||||
relationsToInsert.Add(new ProductionItem2ODLModel
|
||||
{
|
||||
ProdODLID = odl.ProdODLID,
|
||||
ProdItemID = realItemId,
|
||||
DtAssign = DateTime.Now
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
//Log.Warning($"Tag {tag} non trovato nel database per i batch selezionati.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (relationsToInsert.Any())
|
||||
{
|
||||
await dbCtx.DbSetProdItem2ODL.AddRangeAsync(relationsToInsert);
|
||||
totalCreated = relationsToInsert.Count;
|
||||
await dbCtx.SaveChangesAsync();
|
||||
}
|
||||
|
||||
await transaction.CommitAsync();
|
||||
}
|
||||
catch (Exception exc)
|
||||
{
|
||||
await transaction.RollbackAsync();
|
||||
Log.Error($"Errore nel salvataggio relazioni ODL-Parts: {exc.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
return totalCreated;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if false
|
||||
/// <summary>
|
||||
/// Elenco da DB delle stats aggregate dato periodo inizio/fine
|
||||
/// </summary>
|
||||
/// <param name="dtStart"></param>
|
||||
/// <param name="dtEnd"></param>
|
||||
/// <returns></returns>
|
||||
internal async Task<List<StatsAggregatedModel>> StatsAggrGetAsync(DateTime dtStart, DateTime dtEnd)
|
||||
{
|
||||
List<StatsAggregatedModel> answ = new List<StatsAggregatedModel>();
|
||||
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
|
||||
using (DataLayerContext dbCtx = new DataLayerContext())
|
||||
{
|
||||
// recupero ed ordino per data-ora
|
||||
answ = await dbCtx
|
||||
.DbSetStatsAggr
|
||||
.Where(x => x.Hour >= dtStart && x.Hour <= dtEnd)
|
||||
.AsNoTracking()
|
||||
.OrderBy(x => x.Hour)
|
||||
.ToListAsync();
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Range periodo per chiamate aggregate
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
internal async Task<Utils.DtUtils.Periodo> StatsAggrRangeAsync()
|
||||
{
|
||||
Utils.DtUtils.Periodo answ = new Utils.DtUtils.Periodo(Utils.DtUtils.PeriodSet.Today);
|
||||
using (DataLayerContext dbCtx = new DataLayerContext())
|
||||
{
|
||||
var query = dbCtx.DbSetStatsAggr.AsQueryable();
|
||||
|
||||
var minHour = await query.MinAsync(x => x.Hour);
|
||||
var maxHour = await query.MaxAsync(x => x.Hour);
|
||||
answ.Inizio = minHour;
|
||||
answ.Fine = maxHour;
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue insert statistiche aggregate sul DB
|
||||
/// </summary>
|
||||
/// <param name="listRecords">Elenco dei record da inserire</param>
|
||||
/// <param name="removeOld">Se true preventivamente elimina record nel periodo richiesto</param>
|
||||
/// <returns></returns>
|
||||
internal async Task<long> StatsAggrUpsertAsync(List<StatsAggregatedModel> listRecords, bool removeOld)
|
||||
{
|
||||
int answ = 0;
|
||||
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
|
||||
using (DataLayerContext dbCtx = new DataLayerContext())
|
||||
{
|
||||
// in primis se richiesto calcolo range periodo e svuoto...
|
||||
if (removeOld)
|
||||
{
|
||||
var firstRec = listRecords.OrderBy(x => x.Hour).FirstOrDefault();
|
||||
var lastRec = listRecords.OrderByDescending(x => x.Hour).FirstOrDefault();
|
||||
|
||||
if (firstRec != null && lastRec != null)
|
||||
{
|
||||
DateTime startDate = firstRec.Hour;
|
||||
DateTime endDate = lastRec.Hour;
|
||||
// uso direttamente ExecuteDelete
|
||||
await dbCtx
|
||||
.DbSetStatsAggr
|
||||
.Where(x => x.Hour >= startDate && x.Hour <= endDate)
|
||||
.ExecuteDeleteAsync();
|
||||
}
|
||||
}
|
||||
|
||||
// ora preparo inserimento massivo
|
||||
await dbCtx
|
||||
.DbSetStatsAggr
|
||||
.AddRangeAsync(listRecords);
|
||||
|
||||
// salvo!
|
||||
answ = await dbCtx.SaveChangesAsync();
|
||||
|
||||
// libero memoria del changeTracker
|
||||
dbCtx.ChangeTracker.Clear();
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
#endif
|
||||
#if false
|
||||
|
||||
/// <summary>
|
||||
/// Recupera dati stats di dettaglio dato filtro envir/tipo (opzionali) e periodo
|
||||
/// </summary>
|
||||
/// <param name="dtStart"></param>
|
||||
/// <param name="dtEnd"></param>
|
||||
/// <param name="sEnvir"></param>
|
||||
/// <param name="sType"></param>
|
||||
/// <returns></returns>
|
||||
internal async Task<List<StatsDetailModel>> StatsDetailModelGetAsync(DateTime dtStart, DateTime dtEnd, string sEnvir = "", string sType = "")
|
||||
{
|
||||
List<StatsDetailModel> answ = new List<StatsDetailModel>();
|
||||
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
|
||||
using (DataLayerContext dbCtx = new DataLayerContext())
|
||||
{
|
||||
// recupero ed ordino per data-ora
|
||||
var query = dbCtx.DbSetStatsDet
|
||||
.Where(x => x.Hour >= dtStart && x.Hour <= dtEnd);
|
||||
|
||||
if (!string.IsNullOrEmpty(sEnvir))
|
||||
query = query.Where(x => x.Environment == sEnvir);
|
||||
|
||||
if (!string.IsNullOrEmpty(sType))
|
||||
query = query.Where(x => x.Type == sType);
|
||||
|
||||
answ = await query
|
||||
.AsNoTracking()
|
||||
.OrderBy(x => x.Hour)
|
||||
.ThenBy(x => x.Environment)
|
||||
.ThenBy(x => x.Type)
|
||||
.ToListAsync();
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Range periodo x chiamate detail eventualmente filtrate
|
||||
/// </summary>
|
||||
/// <param name="sEnvir"></param>
|
||||
/// <param name="sType"></param>
|
||||
/// <returns></returns>
|
||||
internal async Task<Utils.DtUtils.Periodo> StatsDetailModelRangeAsync(string sEnvir, string sType)
|
||||
{
|
||||
Utils.DtUtils.Periodo answ = new Utils.DtUtils.Periodo(Utils.DtUtils.PeriodSet.Today);
|
||||
using (DataLayerContext dbCtx = new DataLayerContext())
|
||||
{
|
||||
var query = dbCtx.DbSetStatsDet.AsQueryable();
|
||||
|
||||
if (!string.IsNullOrEmpty(sEnvir))
|
||||
query = query.Where(x => x.Environment == sEnvir);
|
||||
|
||||
if (!string.IsNullOrEmpty(sType))
|
||||
query = query.Where(x => x.Type == sType);
|
||||
|
||||
var minHour = await query.MinAsync(x => x.Hour);
|
||||
var maxHour = await query.MaxAsync(x => x.Hour);
|
||||
answ.Inizio = minHour;
|
||||
answ.Fine = maxHour;
|
||||
return answ;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue insert statistiche di dettaglio sul DB
|
||||
/// </summary>
|
||||
/// <param name="listRecords">Elenco dei record da inserire</param>
|
||||
/// <param name="removeOld">Se true preventivamente elimina record nel periodo richiesto</param>
|
||||
/// <returns></returns>
|
||||
internal async Task<long> StatsDetailModelUpsertAsync(List<StatsDetailModel> listRecords, bool removeOld)
|
||||
{
|
||||
int answ = 0;
|
||||
//using (DataLayerContext dbCtx = new DataLayerContext(_config))
|
||||
using (DataLayerContext dbCtx = new DataLayerContext())
|
||||
{
|
||||
// in primis se richiesto calcolo range periodo e svuoto...
|
||||
if (removeOld)
|
||||
{
|
||||
var firstRec = listRecords.OrderBy(x => x.Hour).FirstOrDefault();
|
||||
var lastRec = listRecords.OrderByDescending(x => x.Hour).FirstOrDefault();
|
||||
|
||||
if (firstRec != null && lastRec != null)
|
||||
{
|
||||
DateTime startDate = firstRec.Hour;
|
||||
DateTime endDate = lastRec.Hour;
|
||||
// uso direttamente ExecuteDelete
|
||||
await dbCtx
|
||||
.DbSetStatsDet
|
||||
.Where(x => x.Hour >= startDate && x.Hour <= endDate)
|
||||
.ExecuteDeleteAsync();
|
||||
}
|
||||
}
|
||||
|
||||
// ora preparo inserimento massivo
|
||||
await dbCtx
|
||||
.DbSetStatsDet
|
||||
.AddRangeAsync(listRecords);
|
||||
|
||||
// salvo!
|
||||
answ = await dbCtx.SaveChangesAsync();
|
||||
|
||||
// libero memoria del changeTracker
|
||||
dbCtx.ChangeTracker.Clear();
|
||||
}
|
||||
return answ;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endregion Internal Methods
|
||||
|
||||
#region Private Fields
|
||||
|
||||
private static IConfiguration _configuration;
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
#endregion Private Fields
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Utils
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
@@ -163,7 +163,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Utils
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity when saving multiple rows
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
foreach (var row in rows)
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Utils
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
var currRec = await dbCtx.DbSetTemplateRow
|
||||
@@ -136,7 +136,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Utils
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity when saving multiple rows
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
foreach (var row in rows)
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Job
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity (multi-row update + delete)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
var dbResult = await dbCtx.DbSetJobStep
|
||||
@@ -93,7 +93,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Job
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity (multi-row update)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
var currRec = await dbCtx.DbSetJobStep
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Job
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity (multi-row update + delete)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
var dbResult = await dbCtx.DbSetJobTask
|
||||
@@ -86,7 +86,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Job
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity (multi-row add + multi-row remove)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
var currRec = await dbCtx.DbSetJobTask
|
||||
@@ -144,7 +144,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Job
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity (multi-row update)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
var currRec = await dbCtx.DbSetJobTask
|
||||
|
||||
@@ -14,6 +14,8 @@ namespace EgwCoreLib.Lux.Data.Repository.Production
|
||||
/// <returns></returns>
|
||||
Task<bool> AddAsync(ProductionODLModel entity);
|
||||
|
||||
Task<int> AssignProdItem2OdlAsync(List<ProductionODLModel> dbList, Dictionary<(int phaseId, int resId, string machine, int index), List<string>> dictParts);
|
||||
|
||||
/// <summary>
|
||||
/// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items)
|
||||
/// </summary>
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Production
|
||||
}
|
||||
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
// Tentativo di deserializzazione
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Production
|
||||
{
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
int totUpd = 0;
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
int rowsAffected = await dbCtx.DbSetProdItem
|
||||
@@ -56,7 +56,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Production
|
||||
{
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
int totUpd = 0;
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
foreach (var entry in itemsToAssign)
|
||||
@@ -93,7 +93,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Production
|
||||
{
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
int numItem = 0;
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
numItem = await dbCtx.DbSetProdItem
|
||||
|
||||
@@ -24,6 +24,83 @@ namespace EgwCoreLib.Lux.Data.Repository.Production
|
||||
return await dbCtx.SaveChangesAsync() > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assegnazione in blocco degli item agli ODL corrispondenti
|
||||
/// </summary>
|
||||
/// <param name="dbList"></param>
|
||||
/// <param name="dictParts"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<int> AssignProdItem2OdlAsync(List<ProductionODLModel> dbList, Dictionary<(int phaseId, int resId, string machine, int index), List<string>> dictParts)
|
||||
{
|
||||
int totalCreated = 0;
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// 1. Recuperiamo tutti i ProdBatchID coinvolti per fare una sola query
|
||||
List<int> batchIds = dbList.Select(o => o.ProdBatchID).Distinct().ToList();
|
||||
|
||||
if (batchIds != null && batchIds.Count > 0)
|
||||
{
|
||||
// 2. Carichiamo in memoria i ProdItem necessari (solo ID e Tag per risparmiare RAM)
|
||||
var itemsList = await dbCtx.DbSetProdItem
|
||||
.Where(x => batchIds.Contains(x.ProdBatchID ?? 0) && x.ProdItemTag != null && x.ProdItemTag != "")
|
||||
.Select(x => new { x.ProdItemID, x.ProdItemTag })
|
||||
.ToListAsync();
|
||||
|
||||
// 1. Usiamo il "!" (null-forgiving operator) dopo x.ProdItemTag
|
||||
// perché il filtro .Where sopra garantisce che non sia null.
|
||||
var itemLookup = itemsList
|
||||
.GroupBy(x => x.ProdItemTag!)
|
||||
.ToDictionary(
|
||||
g => g.Key,
|
||||
g => g.First().ProdItemID,
|
||||
StringComparer.OrdinalIgnoreCase
|
||||
);
|
||||
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
var relationsToInsert = new List<ProductionItem2ODLModel>();
|
||||
|
||||
foreach (var odl in dbList)
|
||||
{
|
||||
var key = (odl.PhaseID ?? 0, odl.ResourceID ?? 0, odl.ProdPlantCod, odl.Index);
|
||||
|
||||
if (dictParts.TryGetValue(key, out List<string> tagList))
|
||||
{
|
||||
foreach (var tag in tagList)
|
||||
{
|
||||
// 3. Cerchiamo l'ID corrispondente al tag nel nostro lookup locale
|
||||
if (itemLookup.TryGetValue(tag, out int realItemId))
|
||||
{
|
||||
relationsToInsert.Add(new ProductionItem2ODLModel
|
||||
{
|
||||
ProdODLID = odl.ProdODLID,
|
||||
ProdItemID = realItemId,
|
||||
DtAssign = DateTime.Now
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (relationsToInsert.Any())
|
||||
{
|
||||
await dbCtx.DbSetProdItem2ODL.AddRangeAsync(relationsToInsert);
|
||||
totalCreated = relationsToInsert.Count;
|
||||
await dbCtx.SaveChangesAsync();
|
||||
}
|
||||
|
||||
await tx.CommitAsync();
|
||||
}
|
||||
catch
|
||||
{
|
||||
await tx.RollbackAsync();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return totalCreated;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items)
|
||||
/// </summary>
|
||||
@@ -35,8 +112,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Production
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// avvio transazione
|
||||
using var transaction = await dbCtx.Database.BeginTransactionAsync();
|
||||
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
int cYear = DateTime.Today.Year;
|
||||
@@ -55,16 +131,16 @@ namespace EgwCoreLib.Lux.Data.Repository.Production
|
||||
await dbCtx.Database.ExecuteSqlRawAsync("CALL stp_ProdOdl_UpdateTag(@pProdBatchID, @pPrefix, @pYear)", pProdBatchID, pPref, pYear);
|
||||
|
||||
// 4. Conferma transazione
|
||||
await transaction.CommitAsync();
|
||||
await tx.CommitAsync();
|
||||
|
||||
// A questo punto, ogni oggetto in 'listOdl2ins' ha il ProdODLID aggiornato dal DB
|
||||
return listOdl2ins;
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch
|
||||
{
|
||||
await transaction.RollbackAsync();
|
||||
await tx.RollbackAsync();
|
||||
// Logga l'errore secondo le tue necessità
|
||||
throw new Exception("Errore durante la creazione massiva degli ODL", ex);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity (parent + children clone)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
@@ -224,7 +224,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity (batch update multiple rows)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
foreach (var row in rows)
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity (multi-row update + delete)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
// 1. Recupero il record da eliminare
|
||||
@@ -116,7 +116,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity (batch update multiple rows)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
foreach (var row in rows)
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales
|
||||
OrderModel? newRec = null;
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
// avvio transazione
|
||||
using var transaction = await dbCtx.Database.BeginTransactionAsync();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
@@ -168,13 +168,12 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales
|
||||
await dbCtx.Database.ExecuteSqlRawAsync("CALL stp_ProdItem_UpdateProdItemTag(0,0);");
|
||||
|
||||
// committo in un unica transazione (da provare!!!)
|
||||
await transaction.CommitAsync();
|
||||
await tx.CommitAsync();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
await transaction.RollbackAsync();
|
||||
// sollevo exception
|
||||
await tx.RollbackAsync();
|
||||
throw;
|
||||
}
|
||||
return newRec;
|
||||
@@ -246,17 +245,17 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity (batch update multiple rows)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
foreach (var row in rows)
|
||||
dbCtx.Entry(row).State = EntityState.Modified;
|
||||
|
||||
bool done = await dbCtx.SaveChangesAsync() > 0;
|
||||
|
||||
|
||||
if (done)
|
||||
tx.Commit();
|
||||
|
||||
|
||||
return done;
|
||||
}
|
||||
catch
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity (multi-row update + delete)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
// 1. Recupero il record da eliminare
|
||||
@@ -137,7 +137,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity (batch update multiple rows)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
foreach (var row in rows)
|
||||
@@ -183,7 +183,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity (batch update multiple rows)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
// recupero offerta...
|
||||
@@ -357,7 +357,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales
|
||||
// context
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
// Wrap in transaction for atomicity (batch update multiple rows)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
// verifica preliminare: serve SSE stato e estimate non corrispondono...
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Stats
|
||||
{
|
||||
int answ = 0;
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
// in primis se richiesto calcolo range periodo e svuoto...
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Stats
|
||||
{
|
||||
int answ = 0;
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
// in primis se richiesto calcolo range periodo e svuoto...
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Utils
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity (multi-row update + delete)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
// 1. Recupero il record da eliminare
|
||||
@@ -92,7 +92,7 @@ namespace EgwCoreLib.Lux.Data.Repository.Utils
|
||||
await using var dbCtx = await CreateContextAsync();
|
||||
|
||||
// Wrap in transaction for atomicity (multi-row update - swap positions)
|
||||
await using var tx = dbCtx.Database.BeginTransaction();
|
||||
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
||||
try
|
||||
{
|
||||
// 1. Recupero il record corrente
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
using EgwCoreLib.Lux.Core.Stats;
|
||||
using EgwCoreLib.Lux.Data.Controllers;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Stats;
|
||||
using EgwCoreLib.Lux.Data.Services.Stats;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NLog;
|
||||
using StackExchange.Redis;
|
||||
using System.Text;
|
||||
using static Egw.Window.Data.Enums;
|
||||
|
||||
namespace EgwCoreLib.Lux.Data.Services
|
||||
@@ -23,7 +20,6 @@ namespace EgwCoreLib.Lux.Data.Services
|
||||
IConfiguration configuration,
|
||||
IConnectionMultiplexer redisConn,
|
||||
IServiceProvider serviceProvider) : base(configuration, redisConn)
|
||||
//public CalcRuidService(IConfiguration configuration, IConnectionMultiplexer redisConn, string redisBaseKey, TimeSpan retention, TimeSpan archivePeriod) : base(configuration, redisConn)
|
||||
{
|
||||
// leggo conf retention/archive da config...
|
||||
string cleanupDayTTL = configuration.GetValue<string>("ServerConf:CleanupDayTTL") ?? "360";
|
||||
@@ -38,28 +34,11 @@ namespace EgwCoreLib.Lux.Data.Services
|
||||
_base = rBaseKey.TrimEnd(':');
|
||||
_retention = TimeSpan.FromDays(dayTTL);
|
||||
_archivePeriod = TimeSpan.FromDays(archTTL);
|
||||
|
||||
// conf DB
|
||||
string connStr = _config.GetConnectionString("Lux.All") ?? "";
|
||||
if (string.IsNullOrEmpty(connStr))
|
||||
{
|
||||
Log.Error("ConnString empty!");
|
||||
}
|
||||
else
|
||||
{
|
||||
//dbController = new Controllers.LuxController(_config);
|
||||
dbController = new LuxController();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.AppendLine($"CalcRuidService | LuxController OK");
|
||||
Log.Info(sb.ToString());
|
||||
}
|
||||
Log.Info($"CalcRuidService | Started");
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
|
||||
public IStatsAggrService StAggServ => _serviceProvider.GetRequiredService<IStatsAggrService>();
|
||||
public IStatsDetailService StDetServ => _serviceProvider.GetRequiredService<IStatsDetailService>();
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
#region Public Enums
|
||||
|
||||
/// <summary>
|
||||
@@ -82,6 +61,13 @@ namespace EgwCoreLib.Lux.Data.Services
|
||||
|
||||
#endregion Public Enums
|
||||
|
||||
#region Public Properties
|
||||
|
||||
public IStatsAggrService StAggServ => _serviceProvider.GetRequiredService<IStatsAggrService>();
|
||||
public IStatsDetailService StDetServ => _serviceProvider.GetRequiredService<IStatsDetailService>();
|
||||
|
||||
#endregion Public Properties
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
@@ -138,109 +124,6 @@ namespace EgwCoreLib.Lux.Data.Services
|
||||
return ruid;
|
||||
}
|
||||
|
||||
#if false
|
||||
/// <summary>
|
||||
/// Metodo di Cleanup periodico
|
||||
/// </summary>
|
||||
/// <param name="environment">Environment calcolo</param>
|
||||
/// <param name="tipo">Tipologia richiesta</param>
|
||||
/// <returns></returns>
|
||||
public async Task CleanupOldRequestsAsync(string environment, string tipo)
|
||||
{
|
||||
var cutoff = DateTimeOffset.Now.Add(-_retention).ToUnixTimeMilliseconds();
|
||||
var setKey = GetSortedSetKey(environment, tipo);
|
||||
|
||||
var oldIds = await _db.SortedSetRangeByScoreAsync(setKey, stop: cutoff);
|
||||
if (oldIds.Length == 0) return;
|
||||
|
||||
var batch = _db.CreateBatch();
|
||||
var tasks = new List<Task>();
|
||||
|
||||
foreach (var id in oldIds)
|
||||
{
|
||||
var ruid = id.ToString();
|
||||
var hashKey = GetRequestKey(ruid);
|
||||
|
||||
var uid = await _db.HashGetAsync(hashKey, "UID");
|
||||
if (!uid.IsNull)
|
||||
{
|
||||
var uidKey = GetUidSetKey(uid);
|
||||
tasks.Add(batch.SetRemoveAsync(uidKey, ruid));
|
||||
|
||||
tasks.Add(batch.SetLengthAsync(uidKey).ContinueWith(t =>
|
||||
{
|
||||
if (t.Result == 0)
|
||||
_db.KeyDelete(uidKey);
|
||||
}));
|
||||
}
|
||||
|
||||
tasks.Add(batch.KeyDeleteAsync(hashKey));
|
||||
}
|
||||
|
||||
tasks.Add(batch.SortedSetRemoveRangeByScoreAsync(setKey, double.NegativeInfinity, cutoff));
|
||||
|
||||
tasks.Add(batch.SortedSetLengthAsync(setKey).ContinueWith(t =>
|
||||
{
|
||||
if (t.Result == 0)
|
||||
_db.KeyDelete(setKey);
|
||||
}));
|
||||
|
||||
batch.Execute();
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metodo di Cleanup dato periodo limite prima del quale va eliminato l'elenco dei dati
|
||||
/// </summary>
|
||||
/// <param name="environment">Environment calcolo</param>
|
||||
/// <param name="tipo">Tipologia richiesta</param>
|
||||
/// <param name="timeLimit">Limite temporale dati da eliminare</param>
|
||||
/// <returns></returns>
|
||||
public async Task CleanupOldRequestsAsync(string environment, string tipo, TimeSpan timeLimit)
|
||||
{
|
||||
var cutoff = DateTimeOffset.Now.Add(-timeLimit).ToUnixTimeMilliseconds();
|
||||
var setKey = GetSortedSetKey(environment, tipo);
|
||||
|
||||
var oldIds = await _db.SortedSetRangeByScoreAsync(setKey, stop: cutoff);
|
||||
if (oldIds.Length == 0) return;
|
||||
|
||||
var batch = _db.CreateBatch();
|
||||
var tasks = new List<Task>();
|
||||
|
||||
foreach (var id in oldIds)
|
||||
{
|
||||
var ruid = id.ToString();
|
||||
var hashKey = GetRequestKey(ruid);
|
||||
|
||||
var uid = await _db.HashGetAsync(hashKey, "UID");
|
||||
if (!uid.IsNull)
|
||||
{
|
||||
var uidKey = GetUidSetKey(uid);
|
||||
tasks.Add(batch.SetRemoveAsync(uidKey, ruid));
|
||||
|
||||
tasks.Add(batch.SetLengthAsync(uidKey).ContinueWith(t =>
|
||||
{
|
||||
if (t.Result == 0)
|
||||
_db.KeyDelete(uidKey);
|
||||
}));
|
||||
}
|
||||
|
||||
tasks.Add(batch.KeyDeleteAsync(hashKey));
|
||||
}
|
||||
|
||||
tasks.Add(batch.SortedSetRemoveRangeByScoreAsync(setKey, double.NegativeInfinity, cutoff));
|
||||
|
||||
tasks.Add(batch.SortedSetLengthAsync(setKey).ContinueWith(t =>
|
||||
{
|
||||
if (t.Result == 0)
|
||||
_db.KeyDelete(setKey);
|
||||
}));
|
||||
|
||||
batch.Execute();
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// <summary>
|
||||
/// Effettua pulizia delle statistiche collezionate una volta migrate sul DB
|
||||
/// </summary>
|
||||
@@ -845,24 +728,117 @@ namespace EgwCoreLib.Lux.Data.Services
|
||||
#region Private Fields
|
||||
|
||||
private static Logger Log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly TimeSpan _archivePeriod;
|
||||
|
||||
private readonly string _base;
|
||||
|
||||
private readonly IDatabase _db;
|
||||
|
||||
private readonly TimeSpan _retention;
|
||||
|
||||
private readonly Random _rnd = new Random();
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
#endregion Private Fields
|
||||
|
||||
#region Private Properties
|
||||
#if false
|
||||
/// <summary>
|
||||
/// Metodo di Cleanup periodico
|
||||
/// </summary>
|
||||
/// <param name="environment">Environment calcolo</param>
|
||||
/// <param name="tipo">Tipologia richiesta</param>
|
||||
/// <returns></returns>
|
||||
public async Task CleanupOldRequestsAsync(string environment, string tipo)
|
||||
{
|
||||
var cutoff = DateTimeOffset.Now.Add(-_retention).ToUnixTimeMilliseconds();
|
||||
var setKey = GetSortedSetKey(environment, tipo);
|
||||
|
||||
private static LuxController dbController { get; set; } = null!;
|
||||
var oldIds = await _db.SortedSetRangeByScoreAsync(setKey, stop: cutoff);
|
||||
if (oldIds.Length == 0) return;
|
||||
|
||||
#endregion Private Properties
|
||||
var batch = _db.CreateBatch();
|
||||
var tasks = new List<Task>();
|
||||
|
||||
foreach (var id in oldIds)
|
||||
{
|
||||
var ruid = id.ToString();
|
||||
var hashKey = GetRequestKey(ruid);
|
||||
|
||||
var uid = await _db.HashGetAsync(hashKey, "UID");
|
||||
if (!uid.IsNull)
|
||||
{
|
||||
var uidKey = GetUidSetKey(uid);
|
||||
tasks.Add(batch.SetRemoveAsync(uidKey, ruid));
|
||||
|
||||
tasks.Add(batch.SetLengthAsync(uidKey).ContinueWith(t =>
|
||||
{
|
||||
if (t.Result == 0)
|
||||
_db.KeyDelete(uidKey);
|
||||
}));
|
||||
}
|
||||
|
||||
tasks.Add(batch.KeyDeleteAsync(hashKey));
|
||||
}
|
||||
|
||||
tasks.Add(batch.SortedSetRemoveRangeByScoreAsync(setKey, double.NegativeInfinity, cutoff));
|
||||
|
||||
tasks.Add(batch.SortedSetLengthAsync(setKey).ContinueWith(t =>
|
||||
{
|
||||
if (t.Result == 0)
|
||||
_db.KeyDelete(setKey);
|
||||
}));
|
||||
|
||||
batch.Execute();
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Metodo di Cleanup dato periodo limite prima del quale va eliminato l'elenco dei dati
|
||||
/// </summary>
|
||||
/// <param name="environment">Environment calcolo</param>
|
||||
/// <param name="tipo">Tipologia richiesta</param>
|
||||
/// <param name="timeLimit">Limite temporale dati da eliminare</param>
|
||||
/// <returns></returns>
|
||||
public async Task CleanupOldRequestsAsync(string environment, string tipo, TimeSpan timeLimit)
|
||||
{
|
||||
var cutoff = DateTimeOffset.Now.Add(-timeLimit).ToUnixTimeMilliseconds();
|
||||
var setKey = GetSortedSetKey(environment, tipo);
|
||||
|
||||
var oldIds = await _db.SortedSetRangeByScoreAsync(setKey, stop: cutoff);
|
||||
if (oldIds.Length == 0) return;
|
||||
|
||||
var batch = _db.CreateBatch();
|
||||
var tasks = new List<Task>();
|
||||
|
||||
foreach (var id in oldIds)
|
||||
{
|
||||
var ruid = id.ToString();
|
||||
var hashKey = GetRequestKey(ruid);
|
||||
|
||||
var uid = await _db.HashGetAsync(hashKey, "UID");
|
||||
if (!uid.IsNull)
|
||||
{
|
||||
var uidKey = GetUidSetKey(uid);
|
||||
tasks.Add(batch.SetRemoveAsync(uidKey, ruid));
|
||||
|
||||
tasks.Add(batch.SetLengthAsync(uidKey).ContinueWith(t =>
|
||||
{
|
||||
if (t.Result == 0)
|
||||
_db.KeyDelete(uidKey);
|
||||
}));
|
||||
}
|
||||
|
||||
tasks.Add(batch.KeyDeleteAsync(hashKey));
|
||||
}
|
||||
|
||||
tasks.Add(batch.SortedSetRemoveRangeByScoreAsync(setKey, double.NegativeInfinity, cutoff));
|
||||
|
||||
tasks.Add(batch.SortedSetLengthAsync(setKey).ContinueWith(t =>
|
||||
{
|
||||
if (t.Result == 0)
|
||||
_db.KeyDelete(setKey);
|
||||
}));
|
||||
|
||||
batch.Execute();
|
||||
await Task.WhenAll(tasks);
|
||||
}
|
||||
#endif
|
||||
|
||||
#region Private Methods
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using EgwCoreLib.Lux.Core.Generic;
|
||||
using EgwCoreLib.Lux.Core.RestPayload;
|
||||
using EgwCoreLib.Lux.Data.Controllers;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Production;
|
||||
using EgwCoreLib.Lux.Data.DbModel.Sales;
|
||||
using EgwCoreLib.Lux.Data.Services.Config;
|
||||
using EgwCoreLib.Lux.Data.Services.Items;
|
||||
@@ -15,7 +14,6 @@ using NLog;
|
||||
using StackExchange.Redis;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace EgwCoreLib.Lux.Data.Services
|
||||
{
|
||||
@@ -29,23 +27,8 @@ namespace EgwCoreLib.Lux.Data.Services
|
||||
IServiceProvider serviceProvider) : base(configuration, RedisConn)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
// conf DB
|
||||
string connStr = _config.GetConnectionString("Lux.All") ?? "";
|
||||
if (string.IsNullOrEmpty(connStr))
|
||||
{
|
||||
Log.Error("ConnString empty!");
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
//dbController = new Controllers.LuxController(_config);
|
||||
dbController = new LuxController();
|
||||
sb.AppendLine($"LuxController OK");
|
||||
dataSimController = new DataSimulatorController();
|
||||
sb.AppendLine($"DataSimController OK");
|
||||
sb.AppendLine($"LuxController OK");
|
||||
Log.Info(sb.ToString());
|
||||
}
|
||||
dataSimController = new DataSimulatorController();
|
||||
Log.Info($"DataSimController OK");
|
||||
}
|
||||
|
||||
#endregion Public Constructors
|
||||
@@ -128,29 +111,6 @@ namespace EgwCoreLib.Lux.Data.Services
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assegnazione in blocco degli item agli ODL corrispondenti
|
||||
/// </summary>
|
||||
/// <param name="dbList"></param>
|
||||
/// <param name="dictParts"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<int> ProdItem2ODL_AssignAsync(List<ProductionODLModel> dbList, Dictionary<(int phaseId, int resId, string machine, int index), List<string>> dictParts)
|
||||
{
|
||||
using var activity = StartActivity();
|
||||
string source = "DB+REDIS";
|
||||
// calcolo
|
||||
int fatto = await dbController.ProdItem2ODL_AssignAsync(dbList, dictParts);
|
||||
// svuoto cache...
|
||||
//await ExecFlushRedisPatternAsync((RedisValue)$"{_redisBaseKey}:ProdItems:*");
|
||||
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:ProdItems:OrdRowId:*");
|
||||
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:ProdGroup:OrdRowId:*");
|
||||
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:OrderRows:*");
|
||||
await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:OrderRowsByState:*");
|
||||
activity?.SetTag("data.source", source);
|
||||
LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms");
|
||||
return fatto;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Esegue salvataggio BOM sul DB
|
||||
/// </summary>
|
||||
@@ -502,7 +462,6 @@ namespace EgwCoreLib.Lux.Data.Services
|
||||
#region Private Properties
|
||||
|
||||
private static DataSimulatorController dataSimController { get; set; } = null!;
|
||||
private static LuxController dbController { get; set; } = null!;
|
||||
|
||||
#endregion Private Properties
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ namespace EgwCoreLib.Lux.Data.Services.Production
|
||||
{
|
||||
#region Public Methods
|
||||
|
||||
Task<int> AssignProdItem2OdlAsync(List<ProductionODLModel> dbList, Dictionary<(int phaseId, int resId, string machine, int index), List<string>> dictParts);
|
||||
|
||||
/// <summary>
|
||||
/// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items)
|
||||
/// </summary>
|
||||
|
||||
@@ -23,6 +23,27 @@ namespace EgwCoreLib.Lux.Data.Services.Production
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Assegnazione in blocco degli item agli ODL corrispondenti
|
||||
/// </summary>
|
||||
/// <param name="dbList"></param>
|
||||
/// <param name="dictParts"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<int> AssignProdItem2OdlAsync(List<ProductionODLModel> dbList, Dictionary<(int phaseId, int resId, string machine, int index), List<string>> dictParts)
|
||||
{
|
||||
return await TraceAsync($"{_className}.Upsert", async (activity) =>
|
||||
{
|
||||
string operation = "AssignProdItem2Odl";
|
||||
var result = await _repo.AssignProdItem2OdlAsync(dbList, dictParts);
|
||||
|
||||
activity?.SetTag("db.operation", operation);
|
||||
|
||||
await ClearCacheAsync($"{_redisBaseKey}:{_className}");
|
||||
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items)
|
||||
/// </summary>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Version>1.1.2603.2111</Version>
|
||||
<Version>1.1.2603.2112</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -265,7 +265,7 @@ namespace Lux.UI.Components.Pages
|
||||
}
|
||||
|
||||
// ora lavoro sugli items x collegarli agli ODL... parto dal dizionario e cerco nell'elenco degli ODL creati...
|
||||
int fatto = await DLService.ProdItem2ODL_AssignAsync(prodODL_DbList, dictParts);
|
||||
int fatto = await POService.AssignProdItem2OdlAsync(prodODL_DbList, dictParts);
|
||||
|
||||
// aggiorno sales order status a ProdOdl creato
|
||||
foreach (var ordRowId in ordRowIdList)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UserSecretsId>aspnet-Lux.UI-a758c101-a2f4-4e38-977d-1c4887dbbd50</UserSecretsId>
|
||||
<Version>1.1.2603.2111</Version>
|
||||
<Version>1.1.2603.2112</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<body>
|
||||
<i>LUX - Web Windows MES</i>
|
||||
<h4>Versione: 1.1.2603.2111</h4>
|
||||
<h4>Versione: 1.1.2603.2112</h4>
|
||||
<br /> Note di rilascio:
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.1.2603.2111
|
||||
1.1.2603.2112
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>1.1.2603.2111</version>
|
||||
<version>1.1.2603.2112</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>
|
||||
|
||||
Reference in New Issue
Block a user