diff --git a/EgwCoreLib.Lux.Data/Controllers/LuxController.cs b/EgwCoreLib.Lux.Data/Controllers/LuxController.cs
index 53c8ae6e..e3ead987 100644
--- a/EgwCoreLib.Lux.Data/Controllers/LuxController.cs
+++ b/EgwCoreLib.Lux.Data/Controllers/LuxController.cs
@@ -1,324 +1,18 @@
-using EgwCoreLib.Lux.Core.RestPayload;
-using EgwCoreLib.Lux.Data.DbModel.Items;
-using EgwCoreLib.Lux.Data.DbModel.Job;
-using EgwCoreLib.Lux.Data.DbModel.Production;
+using EgwCoreLib.Lux.Data.DbModel.Production;
using EgwCoreLib.Lux.Data.DbModel.Stats;
-using EgwCoreLib.Lux.Data.Domains;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
-using Newtonsoft.Json;
using NLog;
using StackExchange.Redis;
using System.Data;
-using static EgwCoreLib.Lux.Core.Enums;
namespace EgwCoreLib.Lux.Data.Controllers
{
internal class LuxController
{
- // manca costruttore parametrico contoller...
#region Internal Methods
- ///
- /// Add item ricevuti da BOM calcolata
- ///
- ///
- ///
- internal bool ItemUpsertFromBom(List bomList)
- {
- bool answ = false;
- //using (DataLayerContext dbCtx = new DataLayerContext(_config))
- using (DataLayerContext dbCtx = new DataLayerContext())
- {
- // Controllo ed inserisco eventuali gruppi mancanti
- UpdateCodGroup(bomList);
-
- // prendo solo elementi a prezzo 0 da salvare sul DB
- var item2save = bomList
- .Where(x => x.Price == 0)
- .ToList();
- List listInserted = new List();
-
- // ciclo x ogni elemento della BOM, cercando x gruppo e ExtItemCode
- foreach (var item in item2save)
- {
- var currRec = dbCtx
- .DbSetItem
- .Where(x => x.CodGroup == item.ClassCode && x.ExtItemCode == item.ItemCode)
- .FirstOrDefault();
-
- // se nullo --> verifico x inserire!!!
- if (currRec == null)
- {
- // verifico NON sia tra gli list2upd già in fase di inserimento
- if (!listInserted.Any(x => x.CodGroup == item.ClassCode && x.ExtItemCode == item.ItemCode))
- {
- ItemModel newRec = new ItemModel()
- {
- CodGroup = item.ClassCode,
- ItemType = Core.Enums.ItemClassType.Bom,
- IsService = false,
- // da calcolare meglio x gruppo
- ItemCode = 0,
- ExtItemCode = item.ItemCode,
- SupplCode = "BOM ITEM",
- Description = $"BOM | {item.ClassCode} | {item.ItemCode}",
- Cost = 0,
- Margin = 0,
- QtyMin = 0,
- QtyMax = 0,
- UM = "#"
- };
- dbCtx.DbSetItem.Add(newRec);
- listInserted.Add(newRec);
- }
- }
- }
-
- // salvo...
- dbCtx.SaveChanges();
-
- }
- return answ;
- }
- ///
- /// Elenco item da ricerca filtro x gruppo/tipo
- ///
- ///
- ///
- ///
- internal List ItemGetFilt(string CodGroup, ItemClassType ItemType)
- {
- List dbResult = new List();
- //using (DataLayerContext dbCtx = new DataLayerContext(_config))
- using (DataLayerContext dbCtx = new DataLayerContext())
- {
- try
- {
- dbResult = dbCtx
- .DbSetItem
- .Where(x => (string.IsNullOrEmpty(CodGroup) || x.CodGroup == CodGroup)
- && (ItemType == ItemClassType.ND || x.ItemType == ItemType))
- .ToList();
- }
- catch (Exception exc)
- {
- Log.Error($"Eccezione durante ItemGetFilt{Environment.NewLine}{exc}");
- }
- }
- return dbResult;
- }
-
- internal async Task OffersCheckExpired()
- {
- bool answ = false;
- //using (DataLayerContext dbCtx = new DataLayerContext(_config))
- using (DataLayerContext dbCtx = new DataLayerContext())
- {
- try
- {
- DateTime adesso = DateTime.Now;
- // recupero offerta...
- var listExpired = dbCtx
- .DbSetOffer
- .Where(x => x.ValidUntil < adesso && x.OffertState == OfferStates.Open)
- .ToList();
-
- // se trovo le aggiorno come stato
- if (listExpired != null)
- {
- foreach (var item in listExpired)
- {
- item.OffertState = OfferStates.Expired;
- dbCtx.Entry(item).State = EntityState.Modified;
- }
- // salvo TUTTI i cambiamenti...
- var result = await dbCtx.SaveChangesAsync();
- answ = result > 0;
- }
- }
- catch (Exception exc)
- {
- Log.Error($"Eccezione durante OffersCheckExpired{Environment.NewLine}{exc}");
- }
- }
- return answ;
- }
-
-#if true
- ///
- /// Esegue upsert del record offerta data la BOM ricevuta
- ///
- ///
- ///
- internal bool OfferUpsertFromBom(string uID, List bomList)
- {
- bool answ = false;
- //using (DataLayerContext dbCtx = new DataLayerContext(_config))
- using (DataLayerContext dbCtx = new DataLayerContext())
- {
- try
- {
- var currRec = dbCtx
- .DbSetOfferRow
- .Where(x => x.OfferRowUID == uID)
- .FirstOrDefault();
- // se trovato --> salvo BOM e calcolo costi
- if (currRec != null)
- {
- // recupero l'elenco degli itemGroup gestiti
- var itemGroupList = dbCtx
- .DbSetItemGroup
- .ToList();
-
- // recupero il subset item da BOM...
- var bomGenList = dbCtx
- .DbSetItem
- //.Where(x => x.sourceType == Core.Enums.ItemClassType.Bom)
- .Where(x => (x.ItemType == Core.Enums.ItemClassType.Bom || x.ItemType == Core.Enums.ItemClassType.BomAlt))
- .ToList();
-
- // recupero la BOM list precedente
- var bomListPrev = JsonConvert.DeserializeObject>(currRec.ItemBOM);
-
- // calcolo il NUOVO costo e lo aggiorno...
- double totCost = 0;
- double totPrice = 0;
- int totItemQty = 0;
- int numGroupOk = 0;
- int numItemOk = 0;
- int numElems = bomList.Count;
- // validazione e completamento BOM
- BomCalculator.Validate(itemGroupList, bomGenList, ref bomList, bomListPrev, ref totCost, ref totPrice, ref totItemQty, ref numGroupOk, ref numItemOk);
- // salvo BOM...
- string itemBom = JsonConvert.SerializeObject(bomList);
- currRec.ItemBOM = itemBom;
- // salvo arrotondato alla 3° decimale
- currRec.BomCost = Math.Round(totCost, 3);
- currRec.BomPrice = Math.Round(totPrice, 3);
- currRec.BomOk = numElems == numGroupOk;
- currRec.ItemOk = numElems == numItemOk;
- // setto ok await di BOM e Price
- currRec.AwaitBom = false;
- currRec.AwaitPrice = false;
- currRec.ProdItemQty = totItemQty;
- dbCtx.Entry(currRec).State = EntityState.Modified;
- }
-
- // salvo...
- var result = dbCtx.SaveChanges();
- answ = result > 0;
- }
- catch (Exception exc)
- {
- Log.Error($"Eccezione durante OfferUpsertFromBom{Environment.NewLine}{exc}");
- }
- }
- return answ;
- }
-#endif
-
- ///
- /// Elenco record Fasi da DB
- ///
- ///
- internal async Task> PhasesGetAllAsync()
- {
- List dbResult = new List();
- //using (DataLayerContext dbCtx = new DataLayerContext(_config))
- using (DataLayerContext dbCtx = new DataLayerContext())
- {
- try
- {
- dbResult = await dbCtx
- .DbSetPhase
- .ToListAsync();
- }
- catch (Exception exc)
- {
- Log.Error($"Eccezione durante PhasesGetAllAsync{Environment.NewLine}{exc}");
- }
- }
- return dbResult;
- }
-
-#if false
- ///
- /// Add record di un singolo ProdGroup da fase Balance
- ///
- /// UID dell'item offerta di cui si è ricevuto l'oggetto Balance'
- /// Prod Group di riferimento
- ///
- internal async Task ProdGroupUpsertBalance(string uID, string rGroup, string rawBalance)
- {
- bool answ = false;
- //using (DataLayerContext dbCtx = new DataLayerContext(_config))
- using (DataLayerContext dbCtx = new DataLayerContext())
- {
- try
- {
- // Tentativo di deserializzazione
- var data = JsonConvert.DeserializeObject>(rawBalance);
- // proseguo solo se è valida la deserializzazione...
- if (data != null)
- {
- // Togliamo la 'G' e convertiamo in int (gestisce automaticamente "01" -> 1)
- int grpIdx = int.Parse(rGroup.TrimStart('G'));
- // recupero ord row (parent)...
- var ordRowRec = dbCtx
- .DbSetOrderRow
- .Where(x => x.OrderRowUID == uID)
- .FirstOrDefault();
- if (ordRowRec != null)
- {
- // recupero record specifico
- var currRec = dbCtx
- .DbSetProdGroup
- .Where(x => x.OrderRowID == ordRowRec.OrderRowID && x.GrpIdx == grpIdx)
- .FirstOrDefault();
-
- // se trovato aggiorno
- if (currRec != null)
- {
- currRec.WorkGroupListRaw = rawBalance;
- dbCtx.Entry(currRec).State = EntityState.Modified;
- }
- // altrimenti aggiungo
- else
- {
- ProductionGroupModel newRec = new ProductionGroupModel()
- {
- OrderRowID = ordRowRec.OrderRowID,
- GrpIdx = grpIdx,
- WorkGroupListRaw = rawBalance
- };
- dbCtx
- .DbSetProdGroup
- .Add(newRec);
- }
-
- // segno ordine come Assigned se non lo fosse...
- if (ordRowRec.OrderRowState != OrderStates.Assigned)
- {
- ordRowRec.OrderRowState = OrderStates.Assigned;
- dbCtx.Entry(ordRowRec).State = EntityState.Modified;
- }
-
- // salvo TUTTI i cambiamenti...
- var result = await dbCtx.SaveChangesAsync();
- answ = result > 0;
- }
- }
- }
- catch (Exception exc)
- {
- Log.Error($"Eccezione durante ProdGroupUpsertBalance{Environment.NewLine}{exc}");
- }
- }
- return answ;
- }
-#endif
#if true
///
@@ -405,8 +99,9 @@ namespace EgwCoreLib.Lux.Data.Controllers
}
#endif
+#if true
///
- /// Elenco da DB delel stats aggregate dato periodo inizio/fine
+ /// Elenco da DB delle stats aggregate dato periodo inizio/fine
///
///
///
@@ -490,6 +185,8 @@ namespace EgwCoreLib.Lux.Data.Controllers
}
return answ;
}
+#endif
+#if true
///
/// Recupera dati stats di dettaglio dato filtro envir/tipo (opzionali) e periodo
@@ -595,44 +292,9 @@ namespace EgwCoreLib.Lux.Data.Controllers
}
return answ;
}
-
-#if true
- internal bool UpdateCodGroup(List bomList)
- {
- bool answ = false;
- //using (DataLayerContext dbCtx = new DataLayerContext(_config))
- using (DataLayerContext dbCtx = new DataLayerContext())
- {
- // in primis calcolo i distinct dei CodGroup x eventuale insert preventivo
- List distCodGroups = bomList
- .Select(i => i.ClassCode)
- .Distinct()
- .Where(c => !string.IsNullOrWhiteSpace(c))
- .ToList();
-
- // recupero l'elenco degli itemGroup gestiti
- var itemGroupList = dbCtx
- .DbSetItemGroup
- .ToList();
- // elenco da inserire...
- var codGroupsToInsert = distCodGroups
- .Where(x => !itemGroupList.Any(i => i.CodGroup == x))
- .Select(x => new ItemGroupModel() { CodGroup = x, Description = x })
- .ToList();
- // se ci sono inserisco!
- if (codGroupsToInsert != null && codGroupsToInsert.Count > 0)
- {
- dbCtx
- .DbSetItemGroup
- .AddRange(codGroupsToInsert);
- // salvo...
- dbCtx.SaveChanges();
- }
- }
- return answ;
- }
#endif
+
#endregion Internal Methods
#region Private Fields
diff --git a/EgwCoreLib.Lux.Data/DataServiceCollectionExtensions.cs b/EgwCoreLib.Lux.Data/DataServiceCollectionExtensions.cs
index 574d898c..57532484 100644
--- a/EgwCoreLib.Lux.Data/DataServiceCollectionExtensions.cs
+++ b/EgwCoreLib.Lux.Data/DataServiceCollectionExtensions.cs
@@ -44,6 +44,7 @@ namespace EgwCoreLib.Lux.Data
services.TryAddScoped();
services.TryAddScoped();
services.TryAddScoped();
+ services.TryAddScoped();
services.TryAddScoped();
services.TryAddScoped();
services.TryAddScoped();
@@ -73,6 +74,7 @@ namespace EgwCoreLib.Lux.Data
services.TryAddScoped();
services.TryAddScoped();
services.TryAddScoped();
+ services.TryAddScoped();
services.TryAddScoped();
services.TryAddScoped();
services.TryAddScoped();
diff --git a/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj b/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj
index fed9128f..6d5e1dd7 100644
--- a/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj
+++ b/EgwCoreLib.Lux.Data/EgwCoreLib.Lux.Data.csproj
@@ -22,6 +22,8 @@
+
+
diff --git a/EgwCoreLib.Lux.Data/Repository/Items/IItemGroupRepository.cs b/EgwCoreLib.Lux.Data/Repository/Items/IItemGroupRepository.cs
index 77883751..ae73ac1d 100644
--- a/EgwCoreLib.Lux.Data/Repository/Items/IItemGroupRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Items/IItemGroupRepository.cs
@@ -1,9 +1,18 @@
-using EgwCoreLib.Lux.Data.DbModel.Items;
+using EgwCoreLib.Lux.Core.RestPayload;
+using EgwCoreLib.Lux.Data.DbModel.Items;
namespace EgwCoreLib.Lux.Data.Repository.Items
{
public interface IItemGroupRepository
{
+ #region Public Methods
+
+ Task AddMissingAsync(List bomList);
+
+ Task AddRangeAsync(List entityList);
+
Task> GetAllAsync();
+
+ #endregion Public Methods
}
-}
+}
\ No newline at end of file
diff --git a/EgwCoreLib.Lux.Data/Repository/Items/ItemGroupRepository.cs b/EgwCoreLib.Lux.Data/Repository/Items/ItemGroupRepository.cs
index a48d051f..4f3c35b6 100644
--- a/EgwCoreLib.Lux.Data/Repository/Items/ItemGroupRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Items/ItemGroupRepository.cs
@@ -1,4 +1,5 @@
-using EgwCoreLib.Lux.Data.DbModel.Items;
+using EgwCoreLib.Lux.Core.RestPayload;
+using EgwCoreLib.Lux.Data.DbModel.Items;
using Microsoft.EntityFrameworkCore;
namespace EgwCoreLib.Lux.Data.Repository.Items
@@ -15,6 +16,47 @@ namespace EgwCoreLib.Lux.Data.Repository.Items
#region Public Methods
+ public async Task AddMissingAsync(List bomList)
+ {
+ await using var dbCtx = await CreateContextAsync();
+ bool fatto = false;
+ // recupero lista esistenti
+ var itemGroupList = await dbCtx.DbSetItemGroup
+ .AsNoTracking()
+ .ToListAsync();
+
+ // calcolo i distinct dei CodGroup x eventuale insert preventivo
+ List distCodGroups = bomList
+ .Select(i => i.ClassCode)
+ .Distinct()
+ .Where(c => !string.IsNullOrWhiteSpace(c))
+ .ToList();
+
+ // elenco da inserire...
+ var codGroupsToInsert = distCodGroups
+ .Where(x => !itemGroupList.Any(i => i.CodGroup == x))
+ .Select(x => new ItemGroupModel() { CodGroup = x, Description = x })
+ .ToList();
+ // se ci sono inserisco!
+ if (codGroupsToInsert != null && codGroupsToInsert.Count > 0)
+ {
+ await dbCtx
+ .DbSetItemGroup
+ .AddRangeAsync(codGroupsToInsert);
+
+ // e salvo
+ fatto = await dbCtx.SaveChangesAsync() > 0;
+ }
+ return fatto;
+ }
+
+ public async Task AddRangeAsync(List entityList)
+ {
+ await using var dbCtx = await CreateContextAsync();
+ await dbCtx.DbSetItemGroup.AddRangeAsync(entityList);
+ return await dbCtx.SaveChangesAsync() > 0;
+ }
+
public async Task> GetAllAsync()
{
await using var dbCtx = await CreateContextAsync();
@@ -25,4 +67,4 @@ namespace EgwCoreLib.Lux.Data.Repository.Items
#endregion Public Methods
}
-}
+}
\ No newline at end of file
diff --git a/EgwCoreLib.Lux.Data/Repository/Items/ItemRepository.cs b/EgwCoreLib.Lux.Data/Repository/Items/ItemRepository.cs
index 6a269e09..0077993a 100644
--- a/EgwCoreLib.Lux.Data/Repository/Items/ItemRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Items/ItemRepository.cs
@@ -221,6 +221,8 @@ namespace EgwCoreLib.Lux.Data.Repository.Items
{
await using var dbCtx = await CreateContextAsync();
+ // Spostato in ItemGroupRepository.AddMissingAsync
+#if false
// in primis calcolo i distinct dei CodGroup x eventuale insert preventivo
List distCodGroups = bomList
.Select(i => i.ClassCode)
@@ -245,7 +247,8 @@ namespace EgwCoreLib.Lux.Data.Repository.Items
.AddRange(codGroupsToInsert);
// salvo...
await dbCtx.SaveChangesAsync();
- }
+ }
+#endif
// prendo solo elementi a prezzo 0 da salvare sul DB
var item2save = bomList
diff --git a/EgwCoreLib.Lux.Data/Repository/Job/IPhaseRepository.cs b/EgwCoreLib.Lux.Data/Repository/Job/IPhaseRepository.cs
new file mode 100644
index 00000000..fbd293a2
--- /dev/null
+++ b/EgwCoreLib.Lux.Data/Repository/Job/IPhaseRepository.cs
@@ -0,0 +1,9 @@
+using EgwCoreLib.Lux.Data.DbModel.Job;
+
+namespace EgwCoreLib.Lux.Data.Repository.Job
+{
+ public interface IPhaseRepository
+ {
+ Task> GetAllAsync();
+ }
+}
diff --git a/EgwCoreLib.Lux.Data/Repository/Job/PhaseRepository.cs b/EgwCoreLib.Lux.Data/Repository/Job/PhaseRepository.cs
new file mode 100644
index 00000000..0ca63dbe
--- /dev/null
+++ b/EgwCoreLib.Lux.Data/Repository/Job/PhaseRepository.cs
@@ -0,0 +1,28 @@
+using EgwCoreLib.Lux.Data.DbModel.Job;
+using Microsoft.EntityFrameworkCore;
+
+namespace EgwCoreLib.Lux.Data.Repository.Job
+{
+ public class PhaseRepository : BaseRepository, IPhaseRepository
+ {
+ #region Public Constructors
+
+ public PhaseRepository(IDbContextFactory ctxFactory) : base(ctxFactory)
+ {
+ }
+
+ #endregion Public Constructors
+
+ #region Public Methods
+
+ public async Task> GetAllAsync()
+ {
+ await using var dbCtx = await CreateContextAsync();
+ return await dbCtx.DbSetPhase
+ .AsNoTracking()
+ .ToListAsync();
+ }
+
+ #endregion Public Methods
+ }
+}
diff --git a/EgwCoreLib.Lux.Data/Repository/Sales/IOfferRepository.cs b/EgwCoreLib.Lux.Data/Repository/Sales/IOfferRepository.cs
index 6b0a2f2b..67c55576 100644
--- a/EgwCoreLib.Lux.Data/Repository/Sales/IOfferRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Sales/IOfferRepository.cs
@@ -9,6 +9,8 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales
Task AddAsync(OfferModel entity);
+ Task CheckExpiredAsync();
+
Task CloneAsync(OfferModel rec2clone);
Task DeleteAsync(OfferModel entity);
diff --git a/EgwCoreLib.Lux.Data/Repository/Sales/OfferRepository.cs b/EgwCoreLib.Lux.Data/Repository/Sales/OfferRepository.cs
index e36993a2..75647785 100644
--- a/EgwCoreLib.Lux.Data/Repository/Sales/OfferRepository.cs
+++ b/EgwCoreLib.Lux.Data/Repository/Sales/OfferRepository.cs
@@ -27,6 +27,34 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales
return await dbCtx.SaveChangesAsync() > 0;
}
+ public async Task CheckExpiredAsync()
+ {
+ await using var dbCtx = await CreateContextAsync();
+ DateTime adesso = DateTime.Now;
+ // recupero offerta...
+ var listExpired = await dbCtx
+ .DbSetOffer
+ .Where(x => x.ValidUntil < adesso && x.OffertState == OfferStates.Open)
+ .ToListAsync();
+
+ // se trovo le aggiorno come stato
+ if (listExpired != null)
+ {
+ foreach (var item in listExpired)
+ {
+ item.OffertState = OfferStates.Expired;
+ dbCtx.Entry(item).State = EntityState.Modified;
+ }
+
+ // salvo TUTTI i cambiamenti...
+ return await dbCtx.SaveChangesAsync() > 0;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
///
/// Esegue il cloning completo di un Offerta e di TUTTE le relative righe...
///
@@ -203,10 +231,10 @@ namespace EgwCoreLib.Lux.Data.Repository.Sales
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/Stats/IStatsAggrRepository.cs b/EgwCoreLib.Lux.Data/Repository/Stats/IStatsAggrRepository.cs
new file mode 100644
index 00000000..3107632e
--- /dev/null
+++ b/EgwCoreLib.Lux.Data/Repository/Stats/IStatsAggrRepository.cs
@@ -0,0 +1,18 @@
+using EgwCoreLib.Lux.Data.DbModel.Stats;
+using EgwCoreLib.Utils;
+
+namespace EgwCoreLib.Lux.Data.Repository.Stats
+{
+ public interface IStatsAggrRepository
+ {
+ #region Public Methods
+
+ Task> GetFiltAsync(DateTime dtStart, DateTime dtEnd);
+
+ Task GetRangeAsync();
+
+ Task UpsertManyAsync(List listRecords, bool removeOld);
+
+ #endregion Public Methods
+ }
+}
\ No newline at end of file
diff --git a/EgwCoreLib.Lux.Data/Repository/Stats/IStatsDetailRepository.cs b/EgwCoreLib.Lux.Data/Repository/Stats/IStatsDetailRepository.cs
new file mode 100644
index 00000000..c311469c
--- /dev/null
+++ b/EgwCoreLib.Lux.Data/Repository/Stats/IStatsDetailRepository.cs
@@ -0,0 +1,18 @@
+using EgwCoreLib.Lux.Data.DbModel.Stats;
+using EgwCoreLib.Utils;
+
+namespace EgwCoreLib.Lux.Data.Repository.Stats
+{
+ public interface IStatsDetailRepository
+ {
+ #region Public Methods
+
+ Task> GetFiltAsync(DateTime dtStart, DateTime dtEnd, string sEnvir = "", string sType = "");
+
+ Task GetRangeAsync(string sEnvir, string sType);
+
+ Task UpsertAsync(List listRecords, bool removeOld);
+
+ #endregion Public Methods
+ }
+}
\ No newline at end of file
diff --git a/EgwCoreLib.Lux.Data/Repository/Stats/StatsAggrRepository.cs b/EgwCoreLib.Lux.Data/Repository/Stats/StatsAggrRepository.cs
new file mode 100644
index 00000000..f980efe4
--- /dev/null
+++ b/EgwCoreLib.Lux.Data/Repository/Stats/StatsAggrRepository.cs
@@ -0,0 +1,108 @@
+using EgwCoreLib.Lux.Data.DbModel.Stats;
+using EgwCoreLib.Utils;
+using Microsoft.EntityFrameworkCore;
+
+namespace EgwCoreLib.Lux.Data.Repository.Stats
+{
+ public class StatsAggrRepository : BaseRepository, IStatsAggrRepository
+ {
+ #region Public Constructors
+
+ public StatsAggrRepository(IDbContextFactory ctxFactory) : base(ctxFactory)
+ {
+ }
+
+ #endregion Public Constructors
+
+ #region Public Methods
+
+ ///
+ /// Elenco da DB delel stats aggregate dato periodo inizio/fine
+ ///
+ ///
+ ///
+ ///
+ public async Task> GetFiltAsync(DateTime dtStart, DateTime dtEnd)
+ {
+ await using var dbCtx = await CreateContextAsync();
+ return await dbCtx
+ .DbSetStatsAggr
+ .Where(x => x.Hour >= dtStart && x.Hour <= dtEnd)
+ .AsNoTracking()
+ .OrderBy(x => x.Hour)
+ .ToListAsync();
+ }
+
+ ///
+ /// Range periodo per chiamate aggregate
+ ///
+ ///
+ public async Task GetRangeAsync()
+ {
+ await using var dbCtx = await CreateContextAsync();
+ DtUtils.Periodo answ = new DtUtils.Periodo(DtUtils.PeriodSet.Today);
+ 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;
+ // ritorno!
+ return answ;
+ }
+
+ ///
+ /// Esegue insert statistiche aggregate sul DB
+ ///
+ /// Elenco dei record da inserire
+ /// Se true preventivamente elimina record nel periodo richiesto
+ ///
+ public async Task UpsertManyAsync(List listRecords, bool removeOld)
+ {
+ int answ = 0;
+ await using var dbCtx = await CreateContextAsync();
+ await using var tx = dbCtx.Database.BeginTransaction();
+ try
+ {
+ // 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();
+
+ // commit transazione
+ tx.Commit();
+
+ // libero memoria del changeTracker
+ dbCtx.ChangeTracker.Clear();
+ return answ;
+ }
+ catch
+ {
+ tx.Rollback();
+ throw;
+ }
+ }
+
+ #endregion Public Methods
+ }
+}
\ No newline at end of file
diff --git a/EgwCoreLib.Lux.Data/Repository/Stats/StatsDetailRepository.cs b/EgwCoreLib.Lux.Data/Repository/Stats/StatsDetailRepository.cs
new file mode 100644
index 00000000..10d1a8db
--- /dev/null
+++ b/EgwCoreLib.Lux.Data/Repository/Stats/StatsDetailRepository.cs
@@ -0,0 +1,132 @@
+using EgwCoreLib.Lux.Data.DbModel.Stats;
+using EgwCoreLib.Utils;
+using Microsoft.EntityFrameworkCore;
+
+namespace EgwCoreLib.Lux.Data.Repository.Stats
+{
+ public class StatsDetailRepository : BaseRepository, IStatsDetailRepository
+ {
+ #region Public Constructors
+
+ public StatsDetailRepository(IDbContextFactory ctxFactory) : base(ctxFactory)
+ {
+ }
+
+ #endregion Public Constructors
+
+ #region Internal Methods
+
+ ///
+ /// Recupera dati stats di dettaglio dato filtro envir/tipo (opzionali) e periodo
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task> GetFiltAsync(DateTime dtStart, DateTime dtEnd, string sEnvir = "", string sType = "")
+ {
+ await using var dbCtx = await CreateContextAsync();
+ List answ = new List();
+
+ // 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
+ ///
+ ///
+ ///
+ ///
+ public async Task GetRangeAsync(string sEnvir, string sType)
+ {
+ await using var dbCtx = await CreateContextAsync();
+ DtUtils.Periodo answ = new DtUtils.Periodo(DtUtils.PeriodSet.Today);
+
+ 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
+ ///
+ public async Task UpsertAsync(List listRecords, bool removeOld)
+ {
+ int answ = 0;
+ await using var dbCtx = await CreateContextAsync();
+ await using var tx = dbCtx.Database.BeginTransaction();
+ try
+ {
+ // 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();
+ // commit transazione
+ tx.Commit();
+
+ // libero memoria del changeTracker
+ dbCtx.ChangeTracker.Clear();
+ return answ;
+ }
+ catch
+ {
+ tx.Rollback();
+ throw;
+ }
+ }
+
+ #endregion Internal Methods
+ }
+}
\ No newline at end of file
diff --git a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs
index 9113d8a8..1146310e 100644
--- a/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs
+++ b/EgwCoreLib.Lux.Data/Services/DataLayerServices.cs
@@ -1,10 +1,10 @@
using EgwCoreLib.Lux.Core.Generic;
using EgwCoreLib.Lux.Core.RestPayload;
using EgwCoreLib.Lux.Data.Controllers;
-using EgwCoreLib.Lux.Data.DbModel.Job;
using EgwCoreLib.Lux.Data.DbModel.Production;
using EgwCoreLib.Lux.Data.DbModel.Sales;
using EgwCoreLib.Lux.Data.Services.Config;
+using EgwCoreLib.Lux.Data.Services.Items;
using EgwCoreLib.Lux.Data.Services.Production;
using EgwCoreLib.Lux.Data.Services.Sales;
using EgwMultiEngineManager.Data;
@@ -16,7 +16,6 @@ using StackExchange.Redis;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Text;
-using static EgwCoreLib.Lux.Core.Enums;
namespace EgwCoreLib.Lux.Data.Services
{
@@ -54,6 +53,8 @@ namespace EgwCoreLib.Lux.Data.Services
#region Public Properties
public IConfProfileService ConfProfServ => _serviceProvider.GetRequiredService();
+ public IItemGroupService ItmGrService => _serviceProvider.GetRequiredService();
+ public IItemService ItmService => _serviceProvider.GetRequiredService();
public IOfferRowService OfferRowServ => _serviceProvider.GetRequiredService();
public IOrderRowService OrderRowServ => _serviceProvider.GetRequiredService();
public IProductionGroupService PrGrpServ => _serviceProvider.GetRequiredService();
@@ -63,46 +64,6 @@ namespace EgwCoreLib.Lux.Data.Services
#region Public Methods
- ///
- /// Sistema gli item che mancassero di ItemID leggendo da DB
- ///
- ///
- ///
- public List BomFixItemId(List listOrg)
- {
- using var activity = StartActivity();
- string source = "DB";
- List listFix = listOrg;
- // sistemo ItemID per gli item della BOM...
- var listItemDB = dbController.ItemGetFilt("", ItemClassType.Bom);
- // cerco i record da sistemare ed 1:1 li fixo...
- foreach (var item in listFix.Where(x => x.ItemID == 0))
- {
- var dbRec = listItemDB.FirstOrDefault(x => x.ExtItemCode == item.ItemCode);
- if ((dbRec != null))
- {
- item.ItemID = dbRec.ItemID;
- }
- }
- activity?.SetTag("data.source", source);
- LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms");
- return listFix;
- }
-
- ///
- /// Reset completo cache sistema
- ///
- public bool FlushCache()
- {
- using var activity = StartActivity();
- string source = "REDIS";
- bool answ = false;
- RedisValue pattern = new RedisValue($"{redisBaseKey}:*");
- answ = ExecFlushRedisPattern(pattern);
- activity?.SetTag("data.source", source);
- LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms");
- return answ;
- }
///
/// Reset completo cache sistema modalità async
@@ -119,53 +80,6 @@ namespace EgwCoreLib.Lux.Data.Services
return answ;
}
- ///
- /// Reset cache sistema x Offerte modalità async
- ///
- public async Task FlushCacheOffersAsync()
- {
- using var activity = StartActivity();
- string source = "REDIS";
- bool answ = false;
- await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:Offers:*");
- await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:OfferRows:*");
- activity?.SetTag("data.source", source);
- LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms");
- return answ;
- }
-
- ///
- /// Reset cache sistema x Ordini modalità async
- ///
- public async Task FlushCacheOrdersAsync()
- {
- using var activity = StartActivity();
- string source = "REDIS";
- bool answ = false;
- await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:Orders:*");
- await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:OrderRows:*");
- activity?.SetTag("data.source", source);
- LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms");
- return answ;
- }
-
- ///
- /// Verifica offerte scadute, con update sul DB
- ///
- public async Task OffersCheckExpired()
- {
- using var activity = StartActivity();
- string source = "DB+REDIS";
- // calcolo
- bool fatto = await dbController.OffersCheckExpired();
- // svuoto cache...
- await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:Offers:*");
- await ExecFlushRedisPatternAsync((RedisValue)$"{redisBaseKey}:OfferRows:*");
- activity?.SetTag("data.source", source);
- LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms");
- return fatto;
- }
-
///
/// Converte il campo raw della BOM in lista oggetti da gestire
///
@@ -182,39 +96,6 @@ namespace EgwCoreLib.Lux.Data.Services
return answ;
}
- ///
- /// Elenco completo Fasi
- ///
- ///
- public async Task> PhasesGetAllAsync()
- {
- using var activity = StartActivity();
- string source = "DB";
- List? result = new List();
- // cerco in redis...
- string currKey = $"{redisBaseKey}:Phases:ALL";
- RedisValue rawData = await _redisDb.StringGetAsync(currKey);
- if (rawData.HasValue)
- {
- result = JsonConvert.DeserializeObject>($"{rawData}");
- source = "REDIS";
- }
- else
- {
- result = await dbController.PhasesGetAllAsync();
- // serializzo e salvo con config x evitare loop...
- rawData = JsonConvert.SerializeObject(result, JSSettings);
- await _redisDb.StringSetAsync(currKey, rawData, LongCache);
- }
- if (result == null)
- {
- result = new List();
- }
- activity?.SetTag("data.source", source);
- LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms");
- return result;
- }
-
///
/// Restituisce un dizionario di da usare nel planner
///
@@ -295,7 +176,9 @@ namespace EgwCoreLib.Lux.Data.Services
if (bomList != null)
{
// verifico 1:1 gli item ricevuti dalla BOM sul DB con eventuale insert in anagrafica dei nuovi
- dbController.ItemUpsertFromBom(bomList);
+ await ItmGrService.AddMissingAsync(bomList);
+ await ItmService.UpsertFromBomAsync(bomList);
+
// se mode = 2 è offerta, se 5 = ODL...
switch (qMode)
{
diff --git a/EgwCoreLib.Lux.Data/Services/Items/IItemGroupService.cs b/EgwCoreLib.Lux.Data/Services/Items/IItemGroupService.cs
index d2c3daeb..19ccdfa8 100644
--- a/EgwCoreLib.Lux.Data/Services/Items/IItemGroupService.cs
+++ b/EgwCoreLib.Lux.Data/Services/Items/IItemGroupService.cs
@@ -1,9 +1,13 @@
-using EgwCoreLib.Lux.Data.DbModel.Items;
+using EgwCoreLib.Lux.Core.RestPayload;
+using EgwCoreLib.Lux.Data.DbModel.Items;
namespace EgwCoreLib.Lux.Data.Services.Items
{
public interface IItemGroupService
{
+ Task AddMissingAsync(List bomList);
+
Task> GetAllAsync();
+
}
}
diff --git a/EgwCoreLib.Lux.Data/Services/Items/IItemService.cs b/EgwCoreLib.Lux.Data/Services/Items/IItemService.cs
index 34ddfa64..ce9ea677 100644
--- a/EgwCoreLib.Lux.Data/Services/Items/IItemService.cs
+++ b/EgwCoreLib.Lux.Data/Services/Items/IItemService.cs
@@ -12,6 +12,8 @@ namespace EgwCoreLib.Lux.Data.Services.Items
Task> GetAltAsync(int recId);
+ Task> GetBomFixItemIdAsync(List listOrg);
+
Task> GetFiltAsync(string CodGroup, ItemClassType ItemType);
Task> GetSearchAsync(string term);
@@ -20,8 +22,8 @@ namespace EgwCoreLib.Lux.Data.Services.Items
Task UpsertAsync(ItemModel upsRec);
- Task UpsertFromBom(List bomList);
+ Task UpsertFromBomAsync(List bomList);
#endregion Public Methods
}
-}
+}
\ No newline at end of file
diff --git a/EgwCoreLib.Lux.Data/Services/Items/ItemGroupService.cs b/EgwCoreLib.Lux.Data/Services/Items/ItemGroupService.cs
index 27809f3c..565557a0 100644
--- a/EgwCoreLib.Lux.Data/Services/Items/ItemGroupService.cs
+++ b/EgwCoreLib.Lux.Data/Services/Items/ItemGroupService.cs
@@ -1,4 +1,5 @@
-using EgwCoreLib.Lux.Data.DbModel.Items;
+using EgwCoreLib.Lux.Core.RestPayload;
+using EgwCoreLib.Lux.Data.DbModel.Items;
using EgwCoreLib.Lux.Data.Repository.Items;
using Microsoft.Extensions.Configuration;
using StackExchange.Redis;
@@ -22,6 +23,24 @@ namespace EgwCoreLib.Lux.Data.Services.Items
#region Public Methods
+ public async Task AddMissingAsync(List bomList)
+ {
+ return await TraceAsync($"{_className}.AddMissing", async (activity) =>
+ {
+ string operation = "AddMissing";
+ bool success = await _repo.AddMissingAsync(bomList);
+
+ activity?.SetTag("db.operation", operation);
+
+ if (success)
+ {
+ await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
+ }
+
+ return success;
+ });
+ }
+
public async Task> GetAllAsync()
{
return await TraceAsync($"{_className}.GetAll", async (activity) =>
diff --git a/EgwCoreLib.Lux.Data/Services/Items/ItemService.cs b/EgwCoreLib.Lux.Data/Services/Items/ItemService.cs
index 0e4540c1..8cabdb39 100644
--- a/EgwCoreLib.Lux.Data/Services/Items/ItemService.cs
+++ b/EgwCoreLib.Lux.Data/Services/Items/ItemService.cs
@@ -55,9 +55,28 @@ namespace EgwCoreLib.Lux.Data.Services.Items
});
}
+ public async Task> GetBomFixItemIdAsync(List listOrg)
+ {
+ return await TraceAsync($"{_className}.GetBomFixItemIdAsync", async (activity) =>
+ {
+ List listFix = listOrg;
+ // sistemo ItemID per gli item della BOM...
+ var listItemDB = await _repo.GetFiltAsync("", ItemClassType.Bom);
+ // cerco i record da sistemare ed 1:1 li fixo...
+ foreach (var item in listFix.Where(x => x.ItemID == 0))
+ {
+ var dbRec = listItemDB.FirstOrDefault(x => x.ExtItemCode == item.ItemCode);
+ if ((dbRec != null))
+ {
+ item.ItemID = dbRec.ItemID;
+ }
+ }
+ return listFix;
+ });
+ }
+
public async Task> GetFiltAsync(string CodGroup, ItemClassType ItemType)
{
- // Uso helper TraceAsync che gestisce automaticamente StartActivity, Log e Exception tracking
return await TraceAsync($"{_className}.GetFilt", async (activity) =>
{
return await GetOrSetCacheAsync(
@@ -70,7 +89,6 @@ namespace EgwCoreLib.Lux.Data.Services.Items
public async Task> GetSearchAsync(string term)
{
- // Uso helper TraceAsync che gestisce automaticamente StartActivity, Log e Exception tracking
return await TraceAsync($"{_className}.GetSearch", async (activity) =>
{
return await GetOrSetCacheAsync(
@@ -131,13 +149,13 @@ namespace EgwCoreLib.Lux.Data.Services.Items
}
- public async Task UpsertFromBom(List bomList)
+ public async Task UpsertFromBomAsync(List bomList)
{
- return await TraceAsync($"{_className}.UpsertFromBom", async (activity) =>
+ return await TraceAsync($"{_className}.UpsertFromBomAsync", async (activity) =>
{
bool success = await _repo.UpsertFromBomAsync(bomList);
- activity?.SetTag("db.operation", "UpsertFromBom");
+ activity?.SetTag("db.operation", "UpsertFromBomAsync");
if (success)
{
diff --git a/EgwCoreLib.Lux.Data/Services/Job/IPhaseService.cs b/EgwCoreLib.Lux.Data/Services/Job/IPhaseService.cs
new file mode 100644
index 00000000..781b6d88
--- /dev/null
+++ b/EgwCoreLib.Lux.Data/Services/Job/IPhaseService.cs
@@ -0,0 +1,9 @@
+using EgwCoreLib.Lux.Data.DbModel.Job;
+
+namespace EgwCoreLib.Lux.Data.Services.Job
+{
+ public interface IPhaseService
+ {
+ Task> GetAllAsync();
+ }
+}
diff --git a/EgwCoreLib.Lux.Data/Services/Job/PhaseService.cs b/EgwCoreLib.Lux.Data/Services/Job/PhaseService.cs
new file mode 100644
index 00000000..7eca4b54
--- /dev/null
+++ b/EgwCoreLib.Lux.Data/Services/Job/PhaseService.cs
@@ -0,0 +1,50 @@
+using EgwCoreLib.Lux.Data.DbModel.Job;
+using EgwCoreLib.Lux.Data.Repository.Job;
+using Microsoft.Extensions.Configuration;
+using StackExchange.Redis;
+
+namespace EgwCoreLib.Lux.Data.Services.Job
+{
+ public class PhaseService : BaseServ, IPhaseService
+ {
+ #region Public Constructors
+
+ public PhaseService(
+ IConfiguration config,
+ IConnectionMultiplexer redis,
+ IPhaseRepository repo) : base(config, redis)
+ {
+ _className = "Phase";
+ _repo = repo;
+ }
+
+ #endregion Public Constructors
+
+ #region Public Methods
+
+ ///
+ /// Elenco completo Phase da DB
+ ///
+ ///
+ public async Task> GetAllAsync()
+ {
+ return await TraceAsync($"{_className}.GetAll", async (activity) =>
+ {
+ return await GetOrSetCacheAsync(
+ $"{_redisBaseKey}:{_className}:ALL",
+ async () => await _repo.GetAllAsync(),
+ UltraLongCache
+ );
+ });
+ }
+
+ #endregion Public Methods
+
+ #region Private Fields
+
+ private readonly string _className;
+ private readonly IPhaseRepository _repo;
+
+ #endregion Private Fields
+ }
+}
\ No newline at end of file
diff --git a/EgwCoreLib.Lux.Data/Services/Sales/IOfferService.cs b/EgwCoreLib.Lux.Data/Services/Sales/IOfferService.cs
index 967f7235..06d7db90 100644
--- a/EgwCoreLib.Lux.Data/Services/Sales/IOfferService.cs
+++ b/EgwCoreLib.Lux.Data/Services/Sales/IOfferService.cs
@@ -6,8 +6,12 @@ namespace EgwCoreLib.Lux.Data.Services.Sales
{
#region Public Methods
+ Task CheckExpiredAsync();
+
Task CloneAsync(OfferModel rec2clone);
+ Task FlushCacheOffersAsync();
+
Task> GetAllAsync();
Task> GetFiltAsync(DateTime inizio, DateTime fine);
diff --git a/EgwCoreLib.Lux.Data/Services/Sales/IOrderService.cs b/EgwCoreLib.Lux.Data/Services/Sales/IOrderService.cs
index 19f57c9b..fca1b12f 100644
--- a/EgwCoreLib.Lux.Data/Services/Sales/IOrderService.cs
+++ b/EgwCoreLib.Lux.Data/Services/Sales/IOrderService.cs
@@ -8,6 +8,8 @@ namespace EgwCoreLib.Lux.Data.Services.Sales
Task CloneOfferAsync(OfferModel rec2clone);
+ Task FlushCacheOrdersAsync();
+
Task> GetFiltAsync(DateTime inizio, DateTime fine);
Task GetByIdAsync(int recId, bool doForce);
diff --git a/EgwCoreLib.Lux.Data/Services/Sales/OfferService.cs b/EgwCoreLib.Lux.Data/Services/Sales/OfferService.cs
index 3bda19f3..d2648439 100644
--- a/EgwCoreLib.Lux.Data/Services/Sales/OfferService.cs
+++ b/EgwCoreLib.Lux.Data/Services/Sales/OfferService.cs
@@ -25,6 +25,24 @@ namespace EgwCoreLib.Lux.Data.Services.Sales
#region Public Methods
+ ///
+ /// Verifica offerte scadute, con update sul DB
+ ///
+ public async Task CheckExpiredAsync()
+ {
+ return await TraceAsync($"{_className}.CheckExpired", async (activity) =>
+ {
+ // eseguo clone
+ var result = await _repo.CheckExpiredAsync();
+
+ // se eseguito, pulisco la cache correlata
+ if (result)
+ {
+ await FlushCacheOffersAsync();
+ }
+ return result;
+ });
+ }
///
/// Esegue il cloning completo di un Offer e di TUTTE le relative righe...
///
@@ -40,14 +58,30 @@ namespace EgwCoreLib.Lux.Data.Services.Sales
// se eseguito, pulisco la cache correlata
if (result)
{
- // Invalido sia la lista classi che eventuali dettagli correlati
- await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
- await ClearCacheAsync($"{_redisBaseKey}:OfferRows:*");
+ await FlushCacheOffersAsync();
}
return result;
});
}
+ ///
+ /// Reset cache sistema x Offerte modalità async
+ ///
+ public async Task FlushCacheOffersAsync()
+ {
+ return await TraceAsync($"{_className}.FlushCache", async (activity) =>
+ {
+ string operation = "FlushCache";
+ activity?.SetTag("db.operation", operation);
+
+ await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
+ await ClearCacheAsync($"{_redisBaseKey}:OfferRows:*");
+ //await ClearCacheAsync($"{_redisBaseKey}:Offers:*");
+
+ return true;
+ });
+ }
+
///
/// Elenco completo Offer da DB
///
@@ -138,8 +172,7 @@ namespace EgwCoreLib.Lux.Data.Services.Sales
if (result)
{
// 4. Invalido cache
- await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
- await ClearCacheAsync($"{_redisBaseKey}:OfferRows:*");
+ await FlushCacheOffersAsync();
}
return result;
@@ -173,8 +206,7 @@ namespace EgwCoreLib.Lux.Data.Services.Sales
if (success)
{
- await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
- await ClearCacheAsync($"{_redisBaseKey}:OfferRows:*");
+ await FlushCacheOffersAsync();
}
return success;
diff --git a/EgwCoreLib.Lux.Data/Services/Sales/OrderService.cs b/EgwCoreLib.Lux.Data/Services/Sales/OrderService.cs
index e7c68131..a5324715 100644
--- a/EgwCoreLib.Lux.Data/Services/Sales/OrderService.cs
+++ b/EgwCoreLib.Lux.Data/Services/Sales/OrderService.cs
@@ -51,6 +51,25 @@ namespace EgwCoreLib.Lux.Data.Services.Sales
});
}
+ ///
+ /// Reset cache sistema x Ordini modalità async
+ ///
+ public async Task FlushCacheOrdersAsync()
+ {
+ return await TraceAsync($"{_className}.FlushCache", async (activity) =>
+ {
+ string operation = "FlushCache";
+ activity?.SetTag("db.operation", operation);
+
+ await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
+ await ClearCacheAsync($"{_redisBaseKey}:OrderRows:*");
+ await ClearCacheAsync($"{_redisBaseKey}:OrderRowsByState:*");
+ //await ClearCacheAsync($"{_redisBaseKey}:Orders:*");
+
+ return true;
+ });
+ }
+
public async Task GetByIdAsync(int recId, bool doForce)
{
// Uso helper TraceAsync che gestisce automaticamente StartActivity, Log e Exception tracking
diff --git a/EgwCoreLib.Lux.Data/Services/Stats/IStatsAggrService.cs b/EgwCoreLib.Lux.Data/Services/Stats/IStatsAggrService.cs
new file mode 100644
index 00000000..dad0ab78
--- /dev/null
+++ b/EgwCoreLib.Lux.Data/Services/Stats/IStatsAggrService.cs
@@ -0,0 +1,18 @@
+using EgwCoreLib.Lux.Data.DbModel.Stats;
+using EgwCoreLib.Utils;
+
+namespace EgwCoreLib.Lux.Data.Services.Stats
+{
+ public interface IStatsAggrService
+ {
+ #region Public Methods
+
+ Task> GetFiltAsync(DateTime dtStart, DateTime dtEnd);
+
+ Task GetRangeAsync();
+
+ Task UpsertManyAsync(List listRecords, bool removeOld);
+
+ #endregion Public Methods
+ }
+}
\ No newline at end of file
diff --git a/EgwCoreLib.Lux.Data/Services/Stats/IStatsDetailService.cs b/EgwCoreLib.Lux.Data/Services/Stats/IStatsDetailService.cs
new file mode 100644
index 00000000..ee99f7a1
--- /dev/null
+++ b/EgwCoreLib.Lux.Data/Services/Stats/IStatsDetailService.cs
@@ -0,0 +1,18 @@
+using EgwCoreLib.Lux.Data.DbModel.Stats;
+using EgwCoreLib.Utils;
+
+namespace EgwCoreLib.Lux.Data.Services.Stats
+{
+ public interface IStatsDetailService
+ {
+ #region Public Methods
+
+ Task> GetFiltAsync(DateTime dtStart, DateTime dtEnd, string sEnvir = "", string sType = "");
+
+ Task GetRangeAsync(string sEnvir, string sType);
+
+ Task UpsertAsync(List listRecords, bool removeOld);
+
+ #endregion Public Methods
+ }
+}
\ No newline at end of file
diff --git a/EgwCoreLib.Lux.Data/Services/Stats/StatsAggrService.cs b/EgwCoreLib.Lux.Data/Services/Stats/StatsAggrService.cs
new file mode 100644
index 00000000..f153105a
--- /dev/null
+++ b/EgwCoreLib.Lux.Data/Services/Stats/StatsAggrService.cs
@@ -0,0 +1,93 @@
+using EgwCoreLib.Lux.Data.DbModel.Stats;
+using EgwCoreLib.Lux.Data.Repository.Stats;
+using EgwCoreLib.Utils;
+using Microsoft.Extensions.Configuration;
+using StackExchange.Redis;
+
+namespace EgwCoreLib.Lux.Data.Services.Stats
+{
+ public class StatsAggrService : BaseServ, IStatsAggrService
+ {
+ #region Public Constructors
+
+ public StatsAggrService(
+ IConfiguration config,
+ IConnectionMultiplexer redis,
+ IStatsAggrRepository repo) : base(config, redis)
+ {
+ _className = "StatsAggr";
+ _repo = repo;
+ }
+
+ #endregion Public Constructors
+
+ #region Public Methods
+
+ ///
+ /// Elenco da DB delel stats aggregate dato periodo inizio/fine
+ ///
+ ///
+ ///
+ ///
+ public async Task> GetFiltAsync(DateTime dtStart, DateTime dtEnd)
+ {
+ return await TraceAsync($"{_className}.GetFilt", async (activity) =>
+ {
+ return await GetOrSetCacheAsync(
+ $"{_redisBaseKey}:{_className}:DT:{dtStart:yyyyMMdd}:{dtEnd:yyyyMMdd}",
+ async () => await _repo.GetFiltAsync(dtStart, dtEnd),
+ UltraLongCache
+ );
+ });
+ }
+
+ ///
+ /// Range periodo per chiamate aggregate
+ ///
+ ///
+ public async Task GetRangeAsync()
+ {
+ return await TraceAsync($"{_className}.GetRange", async (activity) =>
+ {
+ return await GetOrSetCacheAsync(
+ $"{_redisBaseKey}:{_className}:Range",
+ async () => await _repo.GetRangeAsync(),
+ UltraFastCache
+ );
+ });
+ }
+
+ ///
+ /// Esegue insert statistiche aggregate sul DB
+ ///
+ /// Elenco dei record da inserire
+ /// Se true preventivamente elimina record nel periodo richiesto
+ ///
+ public async Task UpsertManyAsync(List listRecords, bool removeOld)
+ {
+ return await TraceAsync($"{_className}.UpsertMany", async (activity) =>
+ {
+ string operation = "UpsertMany";
+ var success = await _repo.UpsertManyAsync(listRecords, removeOld);
+
+ activity?.SetTag("db.operation", operation);
+
+ if (success > 0)
+ {
+ await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
+ }
+
+ return success;
+ });
+ }
+
+ #endregion Public Methods
+
+ #region Private Fields
+
+ private readonly string _className;
+ private readonly IStatsAggrRepository _repo;
+
+ #endregion Private Fields
+ }
+}
\ No newline at end of file
diff --git a/EgwCoreLib.Lux.Data/Services/Stats/StatsDetailService.cs b/EgwCoreLib.Lux.Data/Services/Stats/StatsDetailService.cs
new file mode 100644
index 00000000..77c3f470
--- /dev/null
+++ b/EgwCoreLib.Lux.Data/Services/Stats/StatsDetailService.cs
@@ -0,0 +1,169 @@
+using EgwCoreLib.Lux.Data.DbModel.Config;
+using EgwCoreLib.Lux.Data.DbModel.Stats;
+using EgwCoreLib.Lux.Data.Repository.Config;
+using EgwCoreLib.Lux.Data.Repository.Stats;
+using EgwCoreLib.Lux.Data.Services.Config;
+using Microsoft.Extensions.Configuration;
+using StackExchange.Redis;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace EgwCoreLib.Lux.Data.Services.Stats
+{
+ public class StatsDetailService : BaseServ, IStatsDetailService
+ {
+ #region Public Constructors
+
+ public StatsDetailService(
+ IConfiguration config,
+ IConnectionMultiplexer redis,
+ IStatsDetailRepository repo) : base(config, redis)
+ {
+ _className = "StatsDetail";
+ _repo = repo;
+ }
+
+ #endregion Public Constructors
+
+ #region Public Methods
+
+ ///
+ /// Elenco completo StatsDetail da DB
+ ///
+ ///
+ public async Task> GetAllAsync()
+ {
+ return await TraceAsync($"{_className}.GetAll", async (activity) =>
+ {
+ return await GetOrSetCacheAsync(
+ $"{_redisBaseKey}:{_className}:ALL",
+ async () => await _repo.GetAllAsync(),
+ UltraLongCache
+ );
+ });
+ }
+
+ ///
+ /// Recupera dati stats di dettaglio dato filtro envir/tipo (opzionali) e periodo
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task> GetFiltAsync(DateTime dtStart, DateTime dtEnd, string sEnvir = "", string sType = "")
+ {
+ await using var dbCtx = await CreateContextAsync();
+ List answ = new List();
+
+ // 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
+ ///
+ ///
+ ///
+ ///
+ public async Task GetRangeAsync(string sEnvir, string sType)
+ {
+ await using var dbCtx = await CreateContextAsync();
+ DtUtils.Periodo answ = new DtUtils.Periodo(DtUtils.PeriodSet.Today);
+
+ 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
+ ///
+ public async Task UpsertAsync(List listRecords, bool removeOld)
+ {
+ int answ = 0;
+ await using var dbCtx = await CreateContextAsync();
+ await using var tx = dbCtx.Database.BeginTransaction();
+ try
+ {
+ // 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();
+ // commit transazione
+ tx.Commit();
+
+ // libero memoria del changeTracker
+ dbCtx.ChangeTracker.Clear();
+ return answ;
+ }
+ catch
+ {
+ tx.Rollback();
+ throw;
+ }
+ }
+
+ #endregion Public Methods
+
+ #region Private Fields
+
+ private readonly string _className;
+ private readonly IStatsDetailRepository _repo;
+
+ #endregion Private Fields
+ }
+}
diff --git a/Lux.API/Lux.API.csproj b/Lux.API/Lux.API.csproj
index 02fc2115..1c257d37 100644
--- a/Lux.API/Lux.API.csproj
+++ b/Lux.API/Lux.API.csproj
@@ -4,7 +4,7 @@
net8.0
enable
enable
- 1.1.2603.2010
+ 1.1.2603.2019
diff --git a/Lux.UI/Components/Compo/OfferRowMan.razor.cs b/Lux.UI/Components/Compo/OfferRowMan.razor.cs
index 5471e147..0f798c20 100644
--- a/Lux.UI/Components/Compo/OfferRowMan.razor.cs
+++ b/Lux.UI/Components/Compo/OfferRowMan.razor.cs
@@ -8,6 +8,7 @@ using EgwCoreLib.Lux.Data.DbModel.Utils;
using EgwCoreLib.Lux.Data.Domains;
using EgwCoreLib.Lux.Data.Services;
using EgwCoreLib.Lux.Data.Services.Config;
+using EgwCoreLib.Lux.Data.Services.Items;
using EgwCoreLib.Lux.Data.Services.Sales;
using EgwCoreLib.Lux.Data.Services.Utils;
using Microsoft.AspNetCore.Components;
@@ -278,9 +279,15 @@ namespace Lux.UI.Components.Compo
[Inject]
private ConfigDataService CDService { get; set; } = default!;
+ [Inject]
+ private IConfGlassService CGService { get; set; } = null!;
+
[Inject]
private IConfiguration Config { get; set; } = default!;
+ [Inject]
+ private IConfProfileService CPService { get; set; } = null!;
+
[Inject]
private CalcRuidService CRService { get; set; } = default!;
@@ -290,33 +297,15 @@ namespace Lux.UI.Components.Compo
[Inject]
private IWebHostEnvironment CurrEnv { get; set; } = default!;
- [Inject]
- private IConfGlassService CGService { get; set; } = null!;
-
- [Inject]
- private IConfProfileService CPService { get; set; } = null!;
-
[Inject]
private IConfWoodService CWService { get; set; } = null!;
[Inject]
private DataLayerServices DLService { get; set; } = default!;
- [Inject]
- private IOfferRowService ORService { get; set; } = default!;
-
[Inject]
private IEnvirParamService EPService { get; set; } = null!;
- [Inject]
- private IOfferService OService { get; set; } = default!;
-
- [Inject]
- private ITemplateService TService { get; set; } = default!;
-
- [Inject]
- private ITemplateRowService TRService { get; set; } = default!;
-
[Inject]
private FileService FService { get; set; } = default!;
@@ -390,6 +379,9 @@ namespace Lux.UI.Components.Compo
[Inject]
private ImageCacheService ICService { get; set; } = default!;
+ [Inject]
+ private IItemService ItemService { get; set; } = null!;
+
[Inject]
private IJSRuntime JSRuntime { get; set; } = default!;
@@ -401,6 +393,18 @@ namespace Lux.UI.Components.Compo
get => CurrRecord.OfferID;
}
+ [Inject]
+ private IOfferRowService ORService { get; set; } = default!;
+
+ [Inject]
+ private IOfferService OService { get; set; } = default!;
+
+ [Inject]
+ private ITemplateRowService TRService { get; set; } = default!;
+
+ [Inject]
+ private ITemplateService TService { get; set; } = default!;
+
#endregion Private Properties
#region Private Methods
@@ -759,7 +763,7 @@ namespace Lux.UI.Components.Compo
CurrEditMode = EditMode.None;
EditRecord = null;
await Task.Delay(20);
- await DLService.FlushCacheOffersAsync();
+ await OService.FlushCacheOffersAsync();
await Task.Delay(20);
await ReloadData();
UpdateTable();
@@ -929,7 +933,7 @@ namespace Lux.UI.Components.Compo
// reset
CurrEditMode = EditMode.None;
EditRecord = null;
- await DLService.FlushCacheOffersAsync();
+ await OService.FlushCacheOffersAsync();
await ReloadData();
UpdateTable();
isLoading = false;
@@ -957,20 +961,20 @@ namespace Lux.UI.Components.Compo
/// Imposta modalita edit ciclo di lavoro
///
///
- private void DoSwapJobCycle(OfferRowModel currRow)
+ private Task DoSwapJobCycle(OfferRowModel currRow)
{
CurrEditMode = EditMode.JobCycle;
- selectBom(currRow);
+ return selectBom(currRow);
}
///
/// Imposta modalita ad edit BOM
///
///
- private void DoSwapMat(OfferRowModel currRow)
+ private Task DoSwapMat(OfferRowModel currRow)
{
CurrEditMode = EditMode.BOM;
- selectBom(currRow);
+ return selectBom(currRow);
}
///
@@ -1044,7 +1048,7 @@ namespace Lux.UI.Components.Compo
CurrEditMode = EditMode.None;
EditRecord = null;
await Task.Delay(20);
- await DLService.FlushCacheOffersAsync();
+ await OService.FlushCacheOffersAsync();
await Task.Delay(20);
await ReloadData();
UpdateTable();
@@ -1652,14 +1656,14 @@ namespace Lux.UI.Components.Compo
///
///
///
- private void selectBom(OfferRowModel currRow)
+ private async Task selectBom(OfferRowModel currRow)
{
EditRecord = currRow;
//CurrBomList = DLService.OffertGetBomList(EditRecord);
CurrBomList = BomCalculator.GetBomList(EditRecord.ItemBOM);
if (CurrBomList.Any(x => x.ItemID == 0))
{
- CurrBomList = DLService.BomFixItemId(CurrBomList);
+ CurrBomList = await ItemService.GetBomFixItemIdAsync(CurrBomList);
}
}
@@ -1746,7 +1750,7 @@ namespace Lux.UI.Components.Compo
{
CurrBomList = new List();
// fa refresh dei dati della BOM visualizzata
- selectBom(updRec);
+ await selectBom(updRec);
await InvokeAsync(StateHasChanged);
}
}
diff --git a/Lux.UI/Components/Compo/OrderRowMan.razor.cs b/Lux.UI/Components/Compo/OrderRowMan.razor.cs
index 36bb04a5..74db479f 100644
--- a/Lux.UI/Components/Compo/OrderRowMan.razor.cs
+++ b/Lux.UI/Components/Compo/OrderRowMan.razor.cs
@@ -8,6 +8,7 @@ using EgwCoreLib.Lux.Data.DbModel.Sales;
using EgwCoreLib.Lux.Data.DbModel.Utils;
using EgwCoreLib.Lux.Data.Services;
using EgwCoreLib.Lux.Data.Services.Config;
+using EgwCoreLib.Lux.Data.Services.Items;
using EgwCoreLib.Lux.Data.Services.Production;
using EgwCoreLib.Lux.Data.Services.Sales;
using EgwCoreLib.Lux.Data.Services.Utils;
@@ -367,6 +368,9 @@ namespace Lux.UI.Components.Compo
[Inject]
private IEnvirParamService EPService { get; set; } = null!;
+ [Inject]
+ private IItemService ItemService { get; set; } = null!;
+
[Inject]
private IProductionItemService PIService { get; set; } = null!;
@@ -699,7 +703,7 @@ namespace Lux.UI.Components.Compo
CurrEditMode = EditMode.None;
EditRecord = null;
await Task.Delay(20);
- await DLService.FlushCacheOffersAsync();
+ await OrdService.FlushCacheOrdersAsync();
await Task.Delay(20);
await ReloadData();
UpdateTable();
@@ -863,7 +867,7 @@ namespace Lux.UI.Components.Compo
// reset
CurrEditMode = EditMode.None;
EditRecord = null;
- await DLService.FlushCacheOrdersAsync();
+ await OrdService.FlushCacheOrdersAsync();
await ReloadData();
UpdateTable();
isLoading = false;
@@ -885,20 +889,20 @@ namespace Lux.UI.Components.Compo
/// Imposta modalita edit ciclo di lavoro
///
///
- private void DoSwapJobCycle(OrderRowModel currRow)
+ private Task DoSwapJobCycle(OrderRowModel currRow)
{
CurrEditMode = EditMode.JobCycle;
- selectBom(currRow);
+ return selectBom(currRow);
}
///
/// Imposta modalita ad edit BOM
///
///
- private void DoSwapMat(OrderRowModel currRow)
+ private Task DoSwapMat(OrderRowModel currRow)
{
CurrEditMode = EditMode.BOM;
- selectBom(currRow);
+ return selectBom(currRow);
}
///
@@ -975,7 +979,7 @@ namespace Lux.UI.Components.Compo
CurrEditMode = EditMode.None;
EditRecord = null;
await Task.Delay(20);
- await DLService.FlushCacheOffersAsync();
+ await OrdService.FlushCacheOrdersAsync();
await Task.Delay(20);
await ReloadData();
UpdateTable();
@@ -1716,13 +1720,13 @@ namespace Lux.UI.Components.Compo
///
///
///
- private void selectBom(OrderRowModel currRow)
+ private async Task selectBom(OrderRowModel currRow)
{
EditRecord = currRow;
CurrBomList = DLService.OrderGetBomList(EditRecord);
if (CurrBomList.Any(x => x.ItemID == 0))
{
- CurrBomList = DLService.BomFixItemId(CurrBomList);
+ CurrBomList = await ItemService.GetBomFixItemIdAsync(CurrBomList);
}
}
@@ -1834,7 +1838,7 @@ namespace Lux.UI.Components.Compo
{
CurrBomList = new List();
// fa refresh dei dati della BOM visualizzata
- selectBom(updRec);
+ await selectBom(updRec);
await InvokeAsync(StateHasChanged);
}
}
diff --git a/Lux.UI/Components/Pages/JobRoute.razor.cs b/Lux.UI/Components/Pages/JobRoute.razor.cs
index e632b9b6..fa309818 100644
--- a/Lux.UI/Components/Pages/JobRoute.razor.cs
+++ b/Lux.UI/Components/Pages/JobRoute.razor.cs
@@ -60,6 +60,9 @@ namespace Lux.UI.Components.Pages
get => selRecord == null ? "col-6" : "col-4";
}
+ [Inject]
+ private IPhaseService PhService { get; set; } = null!;
+
[Inject]
private IResourceService ResService { get; set; } = null!;
@@ -83,7 +86,7 @@ namespace Lux.UI.Components.Pages
var rawTags = await TagService.GetAllAsync();
ListTagsAvailable = rawTags.Select(x => x.CodTag).ToList();
ListCostDrivers = await CDService.GetAllAsync();
- ListPhases = await DLService.PhasesGetAllAsync();
+ ListPhases = await PhService.GetAllAsync();
ListResources = await ResService.GetAllAsync();
ListJobTask = await JTaService.GetAllAsync();
ListStep = null;
diff --git a/Lux.UI/Components/Pages/Offers.razor.cs b/Lux.UI/Components/Pages/Offers.razor.cs
index c4ac54e3..5f890110 100644
--- a/Lux.UI/Components/Pages/Offers.razor.cs
+++ b/Lux.UI/Components/Pages/Offers.razor.cs
@@ -453,7 +453,7 @@ namespace Lux.UI.Components.Pages
///
private async Task ReloadData()
{
- await DLService.OffersCheckExpired();
+ await OffService.CheckExpiredAsync();
AllRecords = await OffService.GetFiltAsync(PeriodoSel.Inizio, PeriodoSel.Fine);
DoFilter();
}
diff --git a/Lux.UI/Components/Pages/Orders.razor.cs b/Lux.UI/Components/Pages/Orders.razor.cs
index 868f9ebd..9cf22531 100644
--- a/Lux.UI/Components/Pages/Orders.razor.cs
+++ b/Lux.UI/Components/Pages/Orders.razor.cs
@@ -531,7 +531,6 @@ namespace Lux.UI.Components.Pages
///
private async Task ReloadData()
{
- await DLService.OffersCheckExpired();
AllRecords = await OrdService.GetFiltAsync(PeriodoSel.Inizio, PeriodoSel.Fine);
DoFilter();
}
diff --git a/Lux.UI/Lux.UI.csproj b/Lux.UI/Lux.UI.csproj
index 979ac68a..b83502f6 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.2010
+ 1.1.2603.2019
diff --git a/Resources/ChangeLog.html b/Resources/ChangeLog.html
index 98101281..93fe476a 100644
--- a/Resources/ChangeLog.html
+++ b/Resources/ChangeLog.html
@@ -1,6 +1,6 @@
LUX - Web Windows MES
- Versione: 1.1.2603.2010
+ Versione: 1.1.2603.2019
Note di rilascio:
-
diff --git a/Resources/VersNum.txt b/Resources/VersNum.txt
index af7c0f8c..fdaf61d6 100644
--- a/Resources/VersNum.txt
+++ b/Resources/VersNum.txt
@@ -1 +1 @@
-1.1.2603.2010
+1.1.2603.2019
diff --git a/Resources/manifest.xml b/Resources/manifest.xml
index 995f6add..8ace2160 100644
--- a/Resources/manifest.xml
+++ b/Resources/manifest.xml
@@ -1,6 +1,6 @@
-
- 1.1.2603.2010
+ 1.1.2603.2019
http://nexus.steamware.net/repository/SWS/GPW/stable/GPW.UI.zip
http://nexus.steamware.net/repository/SWS/GPW/stable/ChangeLog.html
false