Files
lux/EgwCoreLib.Lux.Data/Services/Sales/OrderService.cs
T
2026-04-16 17:52:58 +02:00

197 lines
7.0 KiB
C#

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
/// <inheritdoc />
public async Task<OrderModel?> 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;
});
}
/// <inheritdoc />
public async Task<bool> 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;
});
}
/// <inheritdoc />
public async Task<OrderModel?> 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
);
}
});
}
/// <inheritdoc />
public async Task<List<OrderModel>> 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
);
});
}
/// <inheritdoc />
public async Task<bool> 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<List<BomItemDTO>>(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;
});
}
/// <inheritdoc />
public async Task<bool> 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
}
}