Files
lux/EgwCoreLib.Lux.Data/Services/General/DataLayerServices.cs
T
2026-04-17 12:35:21 +02:00

287 lines
12 KiB
C#

using EgwCoreLib.Lux.Data.Controllers;
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 System.Runtime.CompilerServices;
namespace EgwCoreLib.Lux.Data.Services.General
{
public class DataLayerServices : BaseServ, IDataLayerServices
{
#region Public Constructors
public DataLayerServices(
IConfiguration configuration,
IConnectionMultiplexer RedisConn,
IServiceProvider serviceProvider) : base(configuration, RedisConn)
{
_serviceProvider = serviceProvider;
Log.Info($"DataLayerServices OK");
dataSimController = new DataSimulatorController();
Log.Info($"DataSimController OK");
}
#endregion Public Constructors
#region Public Properties
public IConfProfileService ConfProfServ => _serviceProvider.GetRequiredService<IConfProfileService>();
public IItemGroupService ItmGrService => _serviceProvider.GetRequiredService<IItemGroupService>();
public IItemService ItmService => _serviceProvider.GetRequiredService<IItemService>();
public IOfferRowService OfferRowServ => _serviceProvider.GetRequiredService<IOfferRowService>();
public IOrderRowService OrderRowServ => _serviceProvider.GetRequiredService<IOrderRowService>();
public IProductionGroupService PrGrpServ => _serviceProvider.GetRequiredService<IProductionGroupService>();
public IProductionOdlService PrOdlServ => _serviceProvider.GetRequiredService<IProductionOdlService>();
#endregion Public Properties
#region Public Methods
/// <summary>
/// Reset completo cache sistema modalità async
/// </summary>
public async Task FlushCacheAsync()
{
using var activity = StartActivity();
string source = "REDIS";
RedisValue pattern = new RedisValue($"{redisBaseKey}:*");
await ExecFlushRedisPatternAsync(pattern);
activity?.SetTag("data.source", source);
LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms");
}
/// <summary>
/// Restituisce un dizionario di <CodFase,EventDto> da usare nel planner
/// </summary>
/// <param name="dtStart"></param>
/// <param name="dtEnd"></param>
/// <returns></returns>
public async Task<Dictionary<string, List<EventDto>>?> PlannerGetEventsAsync(DateTime dtStart, DateTime dtEnd)
{
using var activity = StartActivity();
string source = "DB";
Dictionary<string, List<EventDto>>? result = null;
// cerco in redis...
string currKey = $"{redisBaseKey}:PlannerData:{dtStart:yyyyMMdd}:{dtEnd:yyyyMMdd}";
RedisValue rawData = await _redisDb.StringGetAsync(currKey);
//if (!string.IsNullOrEmpty($"{rawData}"))
if (rawData.HasValue && rawData.Length() > 2)
{
result = JsonConvert.DeserializeObject<Dictionary<string, List<EventDto>>>($"{rawData}");
source = "REDIS";
}
else
{
result = dataSimController.PlannerGetEvents(dtStart, dtEnd);
// serializzo e salvo...
rawData = JsonConvert.SerializeObject(result);
await _redisDb.StringSetAsync(currKey, rawData, LongCache);
}
activity?.SetTag("data.source", source);
LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms");
return result;
}
/// <summary>
/// Esegue salvataggio BOM sul DB
/// </summary>
/// <param name="uID">UID dell'item offerta di cui si è ricevuto la BOM</param>
/// <param name="qMode">Mode della chiamata (x decidere cosa/dove salvare)</param>
/// <param name="execEnvironment">Environment dell'item</param>
/// <param name="bomContent">BOM serializzata</param>
/// <returns></returns>
public async Task SaveBomAsync(string uID, Egw.Window.Data.Enums.QuestionModes qMode, Constants.EXECENVIRONMENTS execEnvironment, string bomContent)
{
using var activity = StartActivity();
string source = "DB";
// salvo sul DB il risultato della BOM
if (!string.IsNullOrEmpty(bomContent))
{
List<BomItemDTO>? bomList = null;
try
{
// deserializzo la Bom...
bomList = JsonConvert.DeserializeObject<List<BomItemDTO>>(bomContent);
}
catch { }
if (bomList != null)
{
// verifico 1:1 gli item ricevuti dalla BOM sul DB con eventuale insert in anagrafica dei nuovi
await ItmGrService.AddMissingAsync(bomList);
await ItmService.UpsertFromBomAsync(bomList);
// se mode = 2 è offerta, se 5 = ODL...
switch (qMode)
{
case Egw.Window.Data.Enums.QuestionModes.NULL:
break;
case Egw.Window.Data.Enums.QuestionModes.PREVIEW:
break;
// BOM in offerta
case Egw.Window.Data.Enums.QuestionModes.BOM:
// salvo la BOM nel record Offer del DB relativo all'oggetto richiesto in base a uID
if (uID.StartsWith("POR"))
{
await OrderRowServ.UpdateBomAsync(uID, bomList);
}
else if (uID.StartsWith("SOR"))
{
await OfferRowServ.UpdateBomAsync(uID, bomList);
}
break;
case Egw.Window.Data.Enums.QuestionModes.HARDWARE:
break;
case Egw.Window.Data.Enums.QuestionModes.CONFIG:
break;
// BOM in ODL
case Egw.Window.Data.Enums.QuestionModes.ORDER:
// salvo la BOM nel record ProdODL del DB relativo all'oggetto richiesto
await PrOdlServ.UpdateBomAsync(uID, bomContent);
// salvo in cache BOM aggiornata...
string currKey = $"{redisBaseKey}:ProdOdl:{uID}";
await _redisDb.StringSetAsync(currKey, bomContent, LongCache);
break;
default:
break;
}
}
}
activity?.SetTag("data.source", source);
LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms");
}
/// <summary>
/// Esegue salvataggio HardwareModelList sul DB
/// </summary>
/// <param name="uID">UID dell'item offerta di cui si è ricevuto la BOM</param>
/// <param name="execEnvironment">Environment dell'item</param>
/// <param name="rawContent">HardwareModelList serializzata</param>
/// <returns></returns>
public async Task SaveHmlAsync(string uID, Constants.EXECENVIRONMENTS execEnvironment, string rawContent)
{
// non effettuo salvataggio sul DB perché master del dato è esterno e lo lasceremo solo in cache REDIS
await Task.Delay(1);
using var activity = StartActivity();
string source = "NONE";
activity?.SetTag("data.source", source);
LogTrace($"{source} | trace: {activity?.TraceId} | {activity?.Duration.TotalMilliseconds}ms");
}
/// <summary>
/// Esegue salvataggio ProdBalance (di un gruppo lavorazioni per riga ordine) sul DB
/// </summary>
/// <param name="uID">UID dell'item offerta di cui si è ricevuto l'oggetto Balance'</param>
/// <param name="rGroup">Prod Group di riferimento</param>
/// <param name="execEnvironment">Environment dell'item</param>
/// <param name="balance">Stima Balance serializzata</param>
/// <returns></returns>
public async Task<bool> SaveProdBalanceAsync(string uID, string rGroup, Constants.EXECENVIRONMENTS execEnvironment, string balance)
{
var result = await PrGrpServ.UpsertBalanceAsync(uID, rGroup, balance);
return result;
}
/// <summary>
/// Esegue salvataggio ProdEstimate (per riga ordine) sul DB
/// </summary>
/// <param name="uID">UID dell'item offerta di cui si è ricevuto la ProdEstim</param>
/// <param name="execEnvironment">Environment dell'item</param>
/// <param name="prodEstim">Stima ProdEstimate serializzata</param>
/// <returns></returns>
public async Task<bool> SaveProdEstimateAsync(string uID, Constants.EXECENVIRONMENTS execEnvironment, string prodEstim)
{
var result = await OrderRowServ.SaveProdEstAsync(uID, prodEstim);
return result;
}
/// <summary>
/// MockUp (fake) salvataggio ProfileListAsync sul DB
/// </summary>
/// <param name="uID">UID ricezione (default tipicamente)</param>
/// <param name="execEnvironment">Environment dell'item</param>
/// <param name="rawContent">ProfileListAsync serializzata</param>
/// <returns></returns>
public async Task<bool> SaveProfileListAsync(string uID, Constants.EXECENVIRONMENTS execEnvironment, string rawContent)
{
var result = await ConfProfServ.SaveProfileListAsync(uID, execEnvironment, rawContent);
return result;
}
/// <summary>
/// MockUp (fake) salvataggio ProfileThreshold sul DB
/// </summary>
/// <param name="uID">UID del profilo</param>
/// <param name="execEnvironment">Environment dell'item</param>
/// <param name="rawThreshold">ThresholdList serializzata</param>
/// <param name="rawData">Info profile data serializzati</param>
/// <returns></returns>
public async Task<bool> SaveProfileThreshAsync(string uID, Constants.EXECENVIRONMENTS execEnvironment, string rawThreshold, string rawData)
{
var result = await ConfProfServ.SaveProfileThreshAsync(uID, execEnvironment, rawThreshold, rawData);
return result;
}
#endregion Public Methods
#region Protected Fields
/// <summary>
/// Numero di operazioni parallele che si possono svolgere... (se 0 NON usa cicli paralleli)
/// </summary>
protected int numPar = 0;
#endregion Protected Fields
#region Protected Methods
/// <summary>
/// Helper avvio attività per la funzione tracciata
/// </summary>
/// <param name="methodName"></param>
/// <returns></returns>
protected new static Activity? StartActivity([CallerMemberName] string? methodName = null)
{
var activity = ActivitySource.StartActivity(methodName ?? "UNDEF");
activity?.SetTag("host.name", Environment.MachineName);
return activity;
}
/// <summary>
/// Helper trace messaggio log (SE abilitato)
/// </summary>
/// <param name="traceMsg"></param>
protected new void LogTrace(string traceMsg, NLog.LogLevel? reqLevel = null, [CallerMemberName] string? methodName = null)
{
if (!_traceEnabled)
return;
reqLevel ??= NLog.LogLevel.Debug;
// Loggo!
Log.Log(reqLevel, $"{methodName} | {traceMsg}");
}
#endregion Protected Methods
#region Private Fields
private new static Logger Log = LogManager.GetCurrentClassLogger();
private readonly IServiceProvider _serviceProvider;
private string redisBaseKey = "Lux:Cache";
#endregion Private Fields
#region Private Properties
private static DataSimulatorController dataSimController { get; set; } = null!;
#endregion Private Properties
}
}