namespace EgwCoreLib.Lux.Data.Services.Sales
{
public class OrderRowService : BaseServ, IOrderRowService
{
#region Public Constructors
public OrderRowService(
IConfiguration config,
IConnectionMultiplexer redis,
IOrderRowRepository repo) : base(config, redis)
{
_className = "OrderRow";
_repo = repo;
}
#endregion Public Constructors
#region Public Methods
///
public async Task DeleteAsync(OrderRowModel rec2del)
{
return await TraceAsync($"{_className}.Delete", async (activity) =>
{
var dbResult = await _repo.GetByIdAsync(rec2del.OrderRowID);
if (dbResult == null) return false;
bool success = await _repo.DeleteAsync(dbResult);
if (success)
{
await ClearCacheAsync($"{_redisBaseKey}:Order:*");
await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
}
return success;
});
}
///
public async Task FixImgTypeAsync(int OrderId)
{
return await TraceAsync($"{_className}.FixImgType", async (activity) =>
{
// 1. Recupero righe
var rows = await _repo.GetByParentAsync(OrderId);
if (rows == null) return false;
// 2. Trovo quelle da sistemare
var list2fix = rows
.Where(x => x.ImgType == ImageType.ND)
.ToList();
// 3. Se non c'è nulla da fare → ritorno
if (list2fix.Count == 0)
return false;
// 5. Aggiorno i record
foreach (var row in list2fix)
{
// se è calcolato il selling item --> img calcolata
if (row.SellingItemNav != null && (row.SellingItemNav.SourceType == ItemSourceType.Jwd || row.SellingItemNav.SourceType == ItemSourceType.FileBTL))
{
row.ImgType = ImageType.Calculated;
}
}
// 6. Salvo
bool success = await _repo.SaveRowsAsync(list2fix);
if (success)
{
await ClearCacheAsync($"{_redisBaseKey}:Order:*");
await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
}
return true;
});
}
///
public async Task> FixUidAsync(int OrderId)
{
return await TraceAsync($"{_className}.FixUid", async (activity) =>
{
List result = new List();
// 1. Recupero righe
var rows = await _repo.GetByParentAsync(OrderId);
if (rows == null)
return result;
// 2. Trovo quelle da sistemare
var list2fix = rows
.Where(x => string.IsNullOrEmpty(x.OrderRowUID) || x.OrderRowUID != x.OrderRowCode)
.ToList();
// 3. Se non c'è nulla da fare → ritorno
if (list2fix.Count == 0)
return result;
// 4. Preparo la lista da restituire
result = list2fix
.Select(x => x.OrderRowCode)
.ToList() ?? new List();
// 5. Aggiorno i record
foreach (var row in list2fix)
row.OrderRowUID = row.OrderRowCode;
// 6. Salvo
bool success = await _repo.SaveRowsAsync(list2fix);
if (success)
{
await ClearCacheAsync($"{_redisBaseKey}:Order:*");
await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
}
return result;
});
}
///
public async Task GetByIdAsync(int OrderRowId)
{
return await TraceAsync($"{_className}.GetById", async (activity) =>
{
return await GetOrSetCacheAsync(
$"{_redisBaseKey}:{_className}:ById:{OrderRowId}",
async () => await _repo.GetByIdAsync(OrderRowId),
LongCache
);
});
}
///
public async Task> GetByParentAsync(int OrderId)
{
return await TraceAsync($"{_className}.GetByParent", async (activity) =>
{
return await GetOrSetCacheAsync(
$"{_redisBaseKey}:{_className}:ByParent:{OrderId}",
async () => await _repo.GetByParentAsync(OrderId),
LongCache
);
});
}
///
public async Task> GetByStateAsync(OrderStates reqState, DateTime dtStart, DateTime dtEnd)
{
return await TraceAsync($"{_className}.GetByState", async (activity) =>
{
return await GetOrSetCacheAsync(
$"{_redisBaseKey}:{_className}:ByState:{reqState}:{dtStart:yyyy-MM-dd}:{dtEnd:yyyy-MM-dd}",
async () => await _repo.GetByStateAsync(reqState, dtStart, dtEnd),
LongCache
);
});
}
///
public async Task> GetByStateMinAsync(OrderStates reqState, DateTime dtStart, DateTime dtEnd)
{
return await TraceAsync($"{_className}.GetByStateMin", async (activity) =>
{
return await GetOrSetCacheAsync(
$"{_redisBaseKey}:{_className}:ByStateMin:{reqState}:{dtStart:yyyy-MM-dd}:{dtEnd:yyyy-MM-dd}",
async () => await _repo.GetByStateMinAsync(reqState, dtStart, dtEnd),
LongCache
);
});
}
///
public async Task GetByUidAsync(string OrderRowUid)
{
return await TraceAsync($"{_className}.GetByUid", async (activity) =>
{
return await GetOrSetCacheAsync(
$"{_redisBaseKey}:{_className}:ByUid:{OrderRowUid}",
async () => await _repo.GetByUidAsync(OrderRowUid),
LongCache
);
});
}
///
public async Task UpdateAwaitStateAsync(int OrderRowId, bool? awaitBom, bool? awaitPrice, bool flushCache = false)
{
return await TraceAsync($"{_className}.UpdateAwaitState", async (activity) =>
{
var currRec = await _repo.GetByIdAsync(OrderRowId);
if (currRec == null)
return false;
currRec.AwaitBom = awaitBom ?? currRec.AwaitBom;
currRec.AwaitPrice = awaitPrice ?? currRec.AwaitPrice;
activity?.SetTag("db.operation", "UPDATE");
bool success = await _repo.UpdateAsync(currRec);
if (success && flushCache)
{
await ClearCacheAsync($"{_redisBaseKey}:Order:*");
await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
}
return success;
});
}
///
public async Task UpdateBomAsync(int OrderRowID, List newBomList)
{
return await TraceAsync($"{_className}.UpdateBom", async (activity) =>
{
var currRec = await _repo.GetByIdAsync(OrderRowID);
if (currRec == null)
return false;
var itemGroups = await _repo.GetItemGroupsAsync();
var bomItems = await _repo.GetBomItemsAsync();
// calcolo il NUOVO costo e lo aggiorno...
double totCost = 0;
double totPrice = 0;
int totItemQty = 0;
int numGroupOk = 0;
int numItemOk = 0;
int numElems = newBomList.Count;
// validazione e completamento BOM
BomCalculator.Validate(itemGroups, bomItems, ref newBomList, null, ref totCost, ref totPrice, ref totItemQty, ref numGroupOk, ref numItemOk);
// salvo BOM...
string itemBom = JsonConvert.SerializeObject(newBomList);
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;
activity?.SetTag("db.operation", "UpdateBomById");
bool success = await _repo.UpdateAsync(currRec);
if (success)
{
await ClearCacheAsync($"{_redisBaseKey}:Order:*");
await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
}
return success;
});
}
///
public async Task UpdateBomAsync(string uID, List newBomList)
{
return await TraceAsync($"{_className}.UpdateBom", async (activity) =>
{
var currRec = await _repo.GetByUidAsync(uID);
if (currRec == null)
return false;
var itemGroups = await _repo.GetItemGroupsAsync();
var bomItems = await _repo.GetBomItemsAsync();
// calcolo il NUOVO costo e lo aggiorno...
double totCost = 0;
double totPrice = 0;
int totItemQty = 0;
int numGroupOk = 0;
int numItemOk = 0;
int numElems = newBomList.Count;
// validazione e completamento BOM
BomCalculator.Validate(itemGroups, bomItems, ref newBomList, null, ref totCost, ref totPrice, ref totItemQty, ref numGroupOk, ref numItemOk);
// salvo BOM...
string itemBom = JsonConvert.SerializeObject(newBomList);
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;
activity?.SetTag("db.operation", "UpdateBomByUid");
bool success = await _repo.UpdateAsync(currRec);
if (success)
{
await ClearCacheAsync($"{_redisBaseKey}:Order:*");
await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
}
return success;
});
}
///
public async Task UpdateFileDataAsync(OrderRowModel updRec)
{
return await TraceAsync($"{_className}.UpdateFileData", async (activity) =>
{
var currRec = await _repo.GetByIdAsync(updRec.OrderRowID);
if (currRec == null)
return false;
currRec.FileName = updRec.FileName;
currRec.FileResource = updRec.FileResource;
currRec.FileSize = updRec.FileSize;
currRec.SerStruct = updRec.SerStruct;
activity?.SetTag("db.operation", "UPDATE");
bool success = await _repo.UpdateAsync(currRec);
if (success)
{
await ClearCacheAsync($"{_redisBaseKey}:Order:*");
await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
}
return success;
});
}
///
public async Task UpdateSerStructAsync(int OrderRowID, string serStruct)
{
return await TraceAsync($"{_className}.UpdateSerStruct", async (activity) =>
{
var currRec = await _repo.GetByIdAsync(OrderRowID);
if (currRec == null)
return false;
currRec.SerStruct = serStruct;
activity?.SetTag("db.operation", "UPDATE");
bool success = await _repo.UpdateAsync(currRec);
if (success)
{
await ClearCacheAsync($"{_redisBaseKey}:Order:*");
await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
}
return success;
});
}
///
public async Task UpdateStateAsync(int orderRowID, OrderStates reqState)
{
return await TraceAsync($"{_className}.UpdateState", async (activity) =>
{
var currRec = await _repo.GetByIdAsync(orderRowID);
if (currRec == null)
return false;
currRec.OrderRowState = reqState;
activity?.SetTag("db.operation", "UPDATE");
bool success = await _repo.UpdateAsync(currRec);
if (success)
{
await ClearCacheAsync($"{_redisBaseKey}:Order:*");
await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
}
return success;
});
}
public async Task ValidateAsync(List list2chk)
{
return await TraceAsync($"{_className}.Validate", async (activity) =>
{
activity?.SetTag("db.operation", "Validate");
var success = await _repo.ValidateAsync(list2chk);
await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
await ClearCacheAsync($"{_redisBaseKey}:Order:*");
await ClearCacheAsync($"{_redisBaseKey}:Orders:*");
await ClearCacheAsync($"{_redisBaseKey}:OrderRowsByState:*");
return success;
});
}
///
public async Task UpsertAsync(OrderRowModel upsRec)
{
return await TraceAsync($"{_className}.Upsert", async (activity) =>
{
OrderRowModel? currRec = await _repo.GetByIdAsync(upsRec.OrderRowID);
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)
{
// sistemo UID...
await FixUidAsync(upsRec.OrderID);
await FixImgTypeAsync(upsRec.OrderID);
currRec = await _repo.GetByIdAsync(upsRec.OrderRowID);
}
else
{
// svuoto comunque cache...
await ClearCacheAsync($"{_redisBaseKey}:Order:*");
await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
}
return currRec;
});
}
///
public async Task SaveProdEstAsync(string uID, string prodEstim)
{
return await TraceAsync($"{_className}.UpsertProdEst", async (activity) =>
{
activity?.SetTag("db.operation", "UpsertProdEst");
var success = await _repo.SaveProdEstAsync(uID, prodEstim);
await ClearCacheAsync($"{_redisBaseKey}:{_className}:*");
return success;
});
}
#endregion Public Methods
#region Private Fields
private readonly string _className;
private readonly IOrderRowRepository _repo;
#endregion Private Fields
}
}