namespace EgwCoreLib.Lux.Data.Services.Sales { public class OrderService : BaseServ, IOrderService { #region Public Constructors public OrderService( IConfiguration config, IConnectionMultiplexer redis, IOrderRepository repo) : base(config, redis) { _className = "Order"; _repo = repo; } #endregion Public Constructors #region Public Methods /// public async Task CloneOfferAsync(OfferModel rec2clone) { return await TraceAsync($"{_className}.CloneOffer", async (activity) => { // eseguo clone var result = await _repo.CloneOfferAsync(rec2clone); // se eseguito, pulisco la cache correlata if (result != null) { // Invalido sia la lista classi che eventuali dettagli correlati await ClearCacheAsync($"{_redisBaseKey}:{_className}:*"); await ClearCacheAsync($"{_redisBaseKey}:OrderRows:*"); await ClearCacheAsync($"{_redisBaseKey}:OrderRowsByState:*"); } return result; }); } /// 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 return await TraceAsync($"{_className}.GetFilt", async (activity) => { if (doForce) { return await _repo.GetByIdAsync(recId) ?? new OrderModel(); } else { return await GetOrSetCacheAsync( $"{_redisBaseKey}:{_className}:ById:{recId}", async () => await _repo.GetByIdAsync(recId), LongCache ); } }); } /// public async Task> GetFiltAsync(DateTime inizio, DateTime fine) { // Uso helper TraceAsync che gestisce automaticamente StartActivity, Log e Exception tracking return await TraceAsync($"{_className}.GetFilt", async (activity) => { return await GetOrSetCacheAsync( $"{_redisBaseKey}:{_className}:Filt:{inizio:yyMMdd-HHmm}:{fine:yyMMdd-HHmm}", async () => await _repo.GetFiltAsync(inizio, fine), LongCache ); }); } /// public async Task UpdateCostAsync(int OrderId) { return await TraceAsync($"{_className}.UpdateCost", async (activity) => { // 1. Recupero dati var rows = await _repo.GetRowsAsync(OrderId); if (rows.Count == 0) return false; var itemGroups = await _repo.GetItemGroupsAsync(); var bomItems = await _repo.GetBomItemsAsync(); // 2. Calcolo costi BOM foreach (var row in rows) { if (!string.IsNullOrEmpty(row.ItemBOM) && row.ItemBOM.Length > 2) { var bomList = JsonConvert.DeserializeObject>(row.ItemBOM); if (bomList != null) { double totCost = 0; double totPrice = 0; int totItemQty = 0; int numGroupOk = 0; int numItemOk = 0; BomCalculator.Validate( itemGroups, bomItems, ref bomList, null, ref totCost, ref totPrice, ref totItemQty, ref numGroupOk, ref numItemOk ); row.ItemBOM = JsonConvert.SerializeObject(bomList); row.BomCost = Math.Round(totCost, 3); row.BomPrice = Math.Round(totPrice, 3); row.BomOk = bomList.Count == numGroupOk; row.ItemOk = bomList.Count == numItemOk; row.ProdItemQty = totItemQty; } } } // 3. Salvo var result = await _repo.SaveRowsAsync(rows); if (result) { // 4. Invalido cache await ClearCacheAsync($"{_redisBaseKey}:{_className}:*"); await ClearCacheAsync($"{_redisBaseKey}:OrderRows:*"); await ClearCacheAsync($"{_redisBaseKey}:OrderRowsByState:*"); } return result; }); } /// public async Task UpsertAsync(OrderModel upsRec) { return await TraceAsync($"{_className}.Upsert", async (activity) => { var currRec = await _repo.GetByIdAsync(upsRec.OrderID); string operation = "UPDATE"; bool success = false; if (currRec != null) { success = await _repo.UpdateAsync(upsRec); } else { operation = "INSERT"; success = await _repo.AddAsync(upsRec); } activity?.SetTag("db.operation", operation); if (success) { await ClearCacheAsync($"{_redisBaseKey}:{_className}:*"); await ClearCacheAsync($"{_redisBaseKey}:OrderRows:*"); await ClearCacheAsync($"{_redisBaseKey}:OrderRowsByState:*"); } return success; }); } #endregion Public Methods #region Private Fields private readonly string _className; private readonly IOrderRepository _repo; #endregion Private Fields } }