Files
lux/EgwCoreLib.Lux.Data/Services/Catalog/TemplateService.cs
T
2026-05-29 19:21:45 +02:00

192 lines
6.7 KiB
C#

namespace EgwCoreLib.Lux.Data.Services.Catalog
{
public class TemplateService : BaseServ, ITemplateService
{
#region Public Constructors
public TemplateService(
IConfiguration config,
IConnectionMultiplexer redis,
ITemplateRepository repo) : base(config, redis)
{
_className = "Template";
_repo = repo;
}
#endregion Public Constructors
#region Public Methods
/// <inheritdoc />
public async Task<bool> CloneAsync(TemplateModel rec2clone)
{
return await TraceAsync($"{_className}.Clone", async (activity) =>
{
// eseguo clone
var result = await _repo.CloneAsync(rec2clone);
// se eseguito, pulisco la cache correlata
if (result)
{
// Invalido sia la lista classi che eventuali dettagli correlati
await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
await ClearCacheAsync($"{_redisBaseKey}:TemplateRows:*");
}
return result;
});
}
/// <inheritdoc />
public async Task<bool> DeleteAsync(TemplateModel rec2del)
{
return await TraceAsync($"{_className}.Delete", async (activity) =>
{
var dbResult = await _repo.GetByIdAsync(rec2del.TemplateID);
if (dbResult == null) return false;
var numChild = await _repo.CountChildrenAsync(rec2del.TemplateID);
if (numChild > 0)
{
activity?.SetTag("delete.status", "rejected_has_children");
return false;
}
bool success = await _repo.DeleteAsync(dbResult);
if (success)
{
await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
await ClearCacheAsync($"{_redisBaseKey}:TemplateRows:*");
}
return success;
});
}
/// <inheritdoc />
public async Task<List<TemplateModel>> GetAllAsync()
{
// Uso helper TraceAsync che gestisce automaticamente StartActivity, Log e Exception tracking
return await TraceAsync($"{_className}.GetAllAsync", async (activity) =>
{
return await GetOrSetCacheAsync(
$"{_redisBaseKey}:{_className}:ALL",
async () => await _repo.GetAllWithNavAsync()
);
});
}
/// <inheritdoc />
public async Task<TemplateModel?> GetByIdAsync(int recId)
{
// Uso helper TraceAsync che gestisce automaticamente StartActivity, Log e Exception tracking
return await TraceAsync($"{_className}.GetById", async (activity) =>
{
return await GetOrSetCacheAsync(
$"{_redisBaseKey}:{_className}:GetById:{recId}",
async () => await _repo.GetByIdAsync(recId)
);
});
}
/// <inheritdoc />
public async Task<bool> UpdateCostAsync(int templateId)
{
return await TraceAsync($"{_className}.Upsert", async (activity) =>
{
// 1. Recupero dati
var rows = await _repo.GetRowsAsync(templateId);
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}:TemplateRows:*");
}
return result;
});
}
/// <inheritdoc />
public async Task<bool> UpsertAsync(TemplateModel upsRec)
{
return await TraceAsync($"{_className}.Upsert", async (activity) =>
{
var currRec = await _repo.GetByIdAsync(upsRec.TemplateID);
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}:TemplateRows:*");
}
return success;
});
}
#endregion Public Methods
#region Private Fields
private readonly string _className;
private readonly ITemplateRepository _repo;
#endregion Private Fields
}
}