475 lines
17 KiB
C#
475 lines
17 KiB
C#
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
|
|
|
|
/// <inheritdoc />
|
|
public async Task<bool> 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;
|
|
});
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<bool> 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;
|
|
});
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<List<string>> FixUidAsync(int OrderId)
|
|
{
|
|
return await TraceAsync($"{_className}.FixUid", async (activity) =>
|
|
{
|
|
List<string> result = new List<string>();
|
|
|
|
// 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<string>();
|
|
|
|
// 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;
|
|
});
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<OrderRowModel?> GetByIdAsync(int OrderRowId)
|
|
{
|
|
return await TraceAsync($"{_className}.GetById", async (activity) =>
|
|
{
|
|
return await GetOrSetCacheAsync(
|
|
$"{_redisBaseKey}:{_className}:ById:{OrderRowId}",
|
|
async () => await _repo.GetByIdAsync(OrderRowId),
|
|
LongCache
|
|
);
|
|
});
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<List<OrderRowModel>> GetByParentAsync(int OrderId)
|
|
{
|
|
return await TraceAsync($"{_className}.GetByParent", async (activity) =>
|
|
{
|
|
return await GetOrSetCacheAsync(
|
|
$"{_redisBaseKey}:{_className}:ByParent:{OrderId}",
|
|
async () => await _repo.GetByParentAsync(OrderId),
|
|
LongCache
|
|
);
|
|
});
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<List<OrderRowModel>> 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
|
|
);
|
|
});
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<List<OrderRowModel>> 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
|
|
);
|
|
});
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<OrderRowModel?> GetByUidAsync(string OrderRowUid)
|
|
{
|
|
return await TraceAsync($"{_className}.GetByUid", async (activity) =>
|
|
{
|
|
return await GetOrSetCacheAsync(
|
|
$"{_redisBaseKey}:{_className}:ByUid:{OrderRowUid}",
|
|
async () => await _repo.GetByUidAsync(OrderRowUid),
|
|
LongCache
|
|
);
|
|
});
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<bool> 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;
|
|
});
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<bool> UpdateBomAsync(int OrderRowID, List<BomItemDTO> 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;
|
|
});
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<bool> UpdateBomAsync(string uID, List<BomItemDTO> 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;
|
|
});
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<bool> 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;
|
|
});
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<bool> 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;
|
|
});
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<bool> 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<int> ValidateAsync(List<OrderRowModel> 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;
|
|
});
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<OrderRowModel?> 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;
|
|
});
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<bool> 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
|
|
}
|
|
}
|