diff --git a/EgwCoreLib.Lux.Data/Controllers/LuxController.cs b/EgwCoreLib.Lux.Data/Controllers/LuxController.cs
deleted file mode 100644
index 39bf865a..00000000
--- a/EgwCoreLib.Lux.Data/Controllers/LuxController.cs
+++ /dev/null
@@ -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
- ///
- /// Assegnazione in blocco degli item agli ODL corrispondenti
- ///
- ///
- ///
- ///
- internal async Task ProdItem2ODL_AssignAsync(List dbList, Dictionary<(int phaseId, int resId, string machine, int index), List> dictParts)
- {
- int totalCreated = 0;
- using (DataLayerContext dbCtx = new DataLayerContext())
- {
- // 1. Recuperiamo tutti i ProdBatchID coinvolti per fare una sola query
- List 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();
-
- foreach (var odl in dbList)
- {
- var key = (odl.PhaseID ?? 0, odl.ResourceID ?? 0, odl.ProdPlantCod, odl.Index);
-
- if (dictParts.TryGetValue(key, out List 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
- ///
- /// Elenco da DB delle stats aggregate dato periodo inizio/fine
- ///
- ///
- ///
- ///
- internal async Task> StatsAggrGetAsync(DateTime dtStart, DateTime dtEnd)
- {
- List answ = new List();
- //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;
- }
-
- ///
- /// Range periodo per chiamate aggregate
- ///
- ///
- internal async Task 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;
- }
- }
-
- ///
- /// Esegue insert statistiche aggregate sul DB
- ///
- /// Elenco dei record da inserire
- /// Se true preventivamente elimina record nel periodo richiesto
- ///
- internal async Task StatsAggrUpsertAsync(List 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
-
- ///
- /// Recupera dati stats di dettaglio dato filtro envir/tipo (opzionali) e periodo
- ///
- ///
- ///
- ///
- ///
- ///
- internal async Task> StatsDetailModelGetAsync(DateTime dtStart, DateTime dtEnd, string sEnvir = "", string sType = "")
- {
- List answ = new List();
- //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;
- }
-
- ///
- /// Range periodo x chiamate detail eventualmente filtrate
- ///
- ///
- ///
- ///
- internal async Task 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;
- }
- }
-
- ///
- /// Esegue insert statistiche di dettaglio sul DB
- ///
- /// Elenco dei record da inserire
- /// Se true preventivamente elimina record nel periodo richiesto
- ///
- internal async Task StatsDetailModelUpsertAsync(List 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
- }
-}
\ No newline at end of file
diff --git a/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRepository.cs b/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRepository.cs
index 39d004ec..22b5ceca 100644
--- a/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRepository.cs
@@ -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)
diff --git a/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRowRepository.cs b/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRowRepository.cs
index b6ea44ae..86793c04 100644
--- a/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRowRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Catalog/TemplateRowRepository.cs
@@ -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)
diff --git a/EgwCoreLib.Lux.Data/Repository/Job/JobStepRepository.cs b/EgwCoreLib.Lux.Data/Repository/Job/JobStepRepository.cs
index 3059ab1b..54339891 100644
--- a/EgwCoreLib.Lux.Data/Repository/Job/JobStepRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Job/JobStepRepository.cs
@@ -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
diff --git a/EgwCoreLib.Lux.Data/Repository/Job/JobTaskRepository.cs b/EgwCoreLib.Lux.Data/Repository/Job/JobTaskRepository.cs
index ae2e749c..ce4af2b5 100644
--- a/EgwCoreLib.Lux.Data/Repository/Job/JobTaskRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Job/JobTaskRepository.cs
@@ -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
diff --git a/EgwCoreLib.Lux.Data/Repository/Production/IProductionOdlRepository.cs b/EgwCoreLib.Lux.Data/Repository/Production/IProductionOdlRepository.cs
index 3e075f09..8ae15981 100644
--- a/EgwCoreLib.Lux.Data/Repository/Production/IProductionOdlRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Production/IProductionOdlRepository.cs
@@ -14,6 +14,8 @@ namespace EgwCoreLib.Lux.Data.Repository.Production
///
Task AddAsync(ProductionODLModel entity);
+ Task AssignProdItem2OdlAsync(List dbList, Dictionary<(int phaseId, int resId, string machine, int index), List> dictParts);
+
///
/// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items)
///
diff --git a/EgwCoreLib.Lux.Data/Repository/Production/ProductionGroupRepository.cs b/EgwCoreLib.Lux.Data/Repository/Production/ProductionGroupRepository.cs
index 75189754..6bcf42bf 100644
--- a/EgwCoreLib.Lux.Data/Repository/Production/ProductionGroupRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Production/ProductionGroupRepository.cs
@@ -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
diff --git a/EgwCoreLib.Lux.Data/Repository/Production/ProductionItemRepository.cs b/EgwCoreLib.Lux.Data/Repository/Production/ProductionItemRepository.cs
index 7590c50b..46ec6de3 100644
--- a/EgwCoreLib.Lux.Data/Repository/Production/ProductionItemRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Production/ProductionItemRepository.cs
@@ -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
diff --git a/EgwCoreLib.Lux.Data/Repository/Production/ProductionOdlRepository.cs b/EgwCoreLib.Lux.Data/Repository/Production/ProductionOdlRepository.cs
index 4b4ffe76..0c3b17fe 100644
--- a/EgwCoreLib.Lux.Data/Repository/Production/ProductionOdlRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Production/ProductionOdlRepository.cs
@@ -24,6 +24,83 @@ namespace EgwCoreLib.Lux.Data.Repository.Production
return await dbCtx.SaveChangesAsync() > 0;
}
+ ///
+ /// Assegnazione in blocco degli item agli ODL corrispondenti
+ ///
+ ///
+ ///
+ ///
+ public async Task AssignProdItem2OdlAsync(List dbList, Dictionary<(int phaseId, int resId, string machine, int index), List> dictParts)
+ {
+ int totalCreated = 0;
+ await using var dbCtx = await CreateContextAsync();
+
+ // 1. Recuperiamo tutti i ProdBatchID coinvolti per fare una sola query
+ List 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();
+
+ foreach (var odl in dbList)
+ {
+ var key = (odl.PhaseID ?? 0, odl.ResourceID ?? 0, odl.ProdPlantCod, odl.Index);
+
+ if (dictParts.TryGetValue(key, out List 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;
+ }
+
///
/// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items)
///
@@ -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;
}
}
diff --git a/EgwCoreLib.Lux.Data/Repository/Sales/OfferRepository.cs b/EgwCoreLib.Lux.Data/Repository/Sales/OfferRepository.cs
index 75647785..b83a3817 100644
--- a/EgwCoreLib.Lux.Data/Repository/Sales/OfferRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Sales/OfferRepository.cs
@@ -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)
diff --git a/EgwCoreLib.Lux.Data/Repository/Sales/OfferRowRepository.cs b/EgwCoreLib.Lux.Data/Repository/Sales/OfferRowRepository.cs
index 186e66de..86c71b0f 100644
--- a/EgwCoreLib.Lux.Data/Repository/Sales/OfferRowRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Sales/OfferRowRepository.cs
@@ -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)
diff --git a/EgwCoreLib.Lux.Data/Repository/Sales/OrderRepository.cs b/EgwCoreLib.Lux.Data/Repository/Sales/OrderRepository.cs
index d0455019..66316380 100644
--- a/EgwCoreLib.Lux.Data/Repository/Sales/OrderRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Sales/OrderRepository.cs
@@ -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
diff --git a/EgwCoreLib.Lux.Data/Repository/Sales/OrderRowRepository.cs b/EgwCoreLib.Lux.Data/Repository/Sales/OrderRowRepository.cs
index 77b99722..d4ea7623 100644
--- a/EgwCoreLib.Lux.Data/Repository/Sales/OrderRowRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Sales/OrderRowRepository.cs
@@ -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...
diff --git a/EgwCoreLib.Lux.Data/Repository/Stats/StatsAggrRepository.cs b/EgwCoreLib.Lux.Data/Repository/Stats/StatsAggrRepository.cs
index 2baec0ad..fb72381a 100644
--- a/EgwCoreLib.Lux.Data/Repository/Stats/StatsAggrRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Stats/StatsAggrRepository.cs
@@ -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...
diff --git a/EgwCoreLib.Lux.Data/Repository/Stats/StatsDetailRepository.cs b/EgwCoreLib.Lux.Data/Repository/Stats/StatsDetailRepository.cs
index 4a16a0a1..cf5e3e5a 100644
--- a/EgwCoreLib.Lux.Data/Repository/Stats/StatsDetailRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Stats/StatsDetailRepository.cs
@@ -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...
diff --git a/EgwCoreLib.Lux.Data/Repository/Utils/GenValRepository.cs b/EgwCoreLib.Lux.Data/Repository/Utils/GenValRepository.cs
index 49927e47..a48bf5b7 100644
--- a/EgwCoreLib.Lux.Data/Repository/Utils/GenValRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Utils/GenValRepository.cs
@@ -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
diff --git a/EgwCoreLib.Lux.Data/Services/CalcRuidService.cs b/EgwCoreLib.Lux.Data/Services/CalcRuidService.cs
index 7bbb3df3..9294043b 100644
--- a/EgwCoreLib.Lux.Data/Services/CalcRuidService.cs
+++ b/EgwCoreLib.Lux.Data/Services/CalcRuidService.cs
@@ -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("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();
- public IStatsDetailService StDetServ => _serviceProvider.GetRequiredService();
- private readonly IServiceProvider _serviceProvider;
#region Public Enums
///
@@ -82,6 +61,13 @@ namespace EgwCoreLib.Lux.Data.Services
#endregion Public Enums
+ #region Public Properties
+
+ public IStatsAggrService StAggServ => _serviceProvider.GetRequiredService();
+ public IStatsDetailService StDetServ => _serviceProvider.GetRequiredService();
+
+ #endregion Public Properties
+
#region Public Methods
///
@@ -138,109 +124,6 @@ namespace EgwCoreLib.Lux.Data.Services
return ruid;
}
-#if false
- ///
- /// Metodo di Cleanup periodico
- ///
- /// Environment calcolo
- /// Tipologia richiesta
- ///
- 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();
-
- 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);
- }
-
- ///
- /// Metodo di Cleanup dato periodo limite prima del quale va eliminato l'elenco dei dati
- ///
- /// Environment calcolo
- /// Tipologia richiesta
- /// Limite temporale dati da eliminare
- ///
- 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();
-
- 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
-
///
/// Effettua pulizia delle statistiche collezionate una volta migrate sul DB
///
@@ -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
+ ///
+ /// Metodo di Cleanup periodico
+ ///
+ /// Environment calcolo
+ /// Tipologia richiesta
+ ///
+ 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();
+
+ 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);
+ }
+
+ ///
+ /// Metodo di Cleanup dato periodo limite prima del quale va eliminato l'elenco dei dati
+ ///
+ /// Environment calcolo
+ /// Tipologia richiesta
+ /// Limite temporale dati da eliminare
+ ///
+ 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();
+
+ 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
diff --git a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs
index 1146310e..e74b4e37 100644
--- a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs
+++ b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs
@@ -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;
}
- ///
- /// Assegnazione in blocco degli item agli ODL corrispondenti
- ///
- ///
- ///
- ///
- public async Task ProdItem2ODL_AssignAsync(List dbList, Dictionary<(int phaseId, int resId, string machine, int index), List> 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;
- }
-
///
/// Esegue salvataggio BOM sul DB
///
@@ -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
}
diff --git a/EgwCoreLib.Lux.Data/Services/Production/IProductionOdlService.cs b/EgwCoreLib.Lux.Data/Services/Production/IProductionOdlService.cs
index 1cfeed55..5e1e4a0e 100644
--- a/EgwCoreLib.Lux.Data/Services/Production/IProductionOdlService.cs
+++ b/EgwCoreLib.Lux.Data/Services/Production/IProductionOdlService.cs
@@ -7,6 +7,8 @@ namespace EgwCoreLib.Lux.Data.Services.Production
{
#region Public Methods
+ Task AssignProdItem2OdlAsync(List dbList, Dictionary<(int phaseId, int resId, string machine, int index), List> dictParts);
+
///
/// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items)
///
diff --git a/EgwCoreLib.Lux.Data/Services/Production/ProductionOdlService.cs b/EgwCoreLib.Lux.Data/Services/Production/ProductionOdlService.cs
index 87cbd509..c31e3467 100644
--- a/EgwCoreLib.Lux.Data/Services/Production/ProductionOdlService.cs
+++ b/EgwCoreLib.Lux.Data/Services/Production/ProductionOdlService.cs
@@ -23,6 +23,27 @@ namespace EgwCoreLib.Lux.Data.Services.Production
#region Public Methods
+ ///
+ /// Assegnazione in blocco degli item agli ODL corrispondenti
+ ///
+ ///
+ ///
+ ///
+ public async Task AssignProdItem2OdlAsync(List dbList, Dictionary<(int phaseId, int resId, string machine, int index), List> 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;
+ });
+ }
+
///
/// Insert sul DB di un elenco ODL con calcolo della relativa KEY a cui poter, successivamente, collegare i record child (items)
///
diff --git a/Lux.API/Lux.API.csproj b/Lux.API/Lux.API.csproj
index 286d0a1f..963bb4da 100644
--- a/Lux.API/Lux.API.csproj
+++ b/Lux.API/Lux.API.csproj
@@ -4,7 +4,7 @@
net8.0
enable
enable
- 1.1.2603.2111
+ 1.1.2603.2112
diff --git a/Lux.UI/Components/Pages/WorkLoadBalance.razor.cs b/Lux.UI/Components/Pages/WorkLoadBalance.razor.cs
index c589bc2e..063d4355 100644
--- a/Lux.UI/Components/Pages/WorkLoadBalance.razor.cs
+++ b/Lux.UI/Components/Pages/WorkLoadBalance.razor.cs
@@ -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)
diff --git a/Lux.UI/Lux.UI.csproj b/Lux.UI/Lux.UI.csproj
index b938fdf5..58998bbf 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.2111
+ 1.1.2603.2112
diff --git a/Resources/ChangeLog.html b/Resources/ChangeLog.html
index 06fa929d..ea5e4363 100644
--- a/Resources/ChangeLog.html
+++ b/Resources/ChangeLog.html
@@ -1,6 +1,6 @@
LUX - Web Windows MES
- Versione: 1.1.2603.2111
+ Versione: 1.1.2603.2112
Note di rilascio:
-
diff --git a/Resources/VersNum.txt b/Resources/VersNum.txt
index 17f8de52..2b9f4319 100644
--- a/Resources/VersNum.txt
+++ b/Resources/VersNum.txt
@@ -1 +1 @@
-1.1.2603.2111
+1.1.2603.2112
diff --git a/Resources/manifest.xml b/Resources/manifest.xml
index ba23e1d7..0265dd38 100644
--- a/Resources/manifest.xml
+++ b/Resources/manifest.xml
@@ -1,6 +1,6 @@
-
- 1.1.2603.2111
+ 1.1.2603.2112
http://nexus.steamware.net/repository/SWS/GPW/stable/GPW.UI.zip
http://nexus.steamware.net/repository/SWS/GPW/stable/ChangeLog.html
false