282 lines
11 KiB
C#
282 lines
11 KiB
C#
using EgwCoreLib.Lux.Core.RestPayload;
|
|
using EgwCoreLib.Lux.Data.DbModel.Items;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using System.Globalization;
|
|
using static EgwCoreLib.Lux.Core.Enums;
|
|
|
|
namespace EgwCoreLib.Lux.Data.Repository.Items
|
|
{
|
|
public class ItemRepository : BaseRepository, IItemRepository
|
|
{
|
|
#region Public Constructors
|
|
|
|
public ItemRepository(IDbContextFactory<DataLayerContext> ctxFactory) : base(ctxFactory)
|
|
{
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Public Methods
|
|
|
|
public async Task<bool> AddAsync(ItemModel entity)
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
await dbCtx.DbSetItem.AddAsync(entity);
|
|
return await dbCtx.SaveChangesAsync() > 0;
|
|
}
|
|
|
|
public async Task<bool> DeleteAsync(ItemModel entity)
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
dbCtx.DbSetItem.Remove(entity);
|
|
return await dbCtx.SaveChangesAsync() > 0;
|
|
}
|
|
|
|
public async Task<List<ItemModel>> GetAltAsync(int recId)
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
List<ItemModel> dbResult = new List<ItemModel>();
|
|
// cerco singolo record x partire...
|
|
var currRec = dbCtx
|
|
.DbSetItem
|
|
.Where(x => x.ItemID == recId)
|
|
.FirstOrDefault();
|
|
|
|
if ((currRec != null))
|
|
{
|
|
// se è un record che ha parentId > 0 --> cerco da quello record analoghi + parent
|
|
if (currRec.ItemIDParent > 0)
|
|
{
|
|
dbResult = await dbCtx
|
|
.DbSetItem
|
|
.Where(x => x.ItemID == currRec.ItemIDParent || x.ItemIDParent == currRec.ItemIDParent)
|
|
.ToListAsync();
|
|
}
|
|
// altrimenti cerco child collegati
|
|
else
|
|
{
|
|
dbResult = await dbCtx
|
|
.DbSetItem
|
|
.Where(x => x.ItemID == currRec.ItemID || x.ItemIDParent == currRec.ItemID)
|
|
.ToListAsync();
|
|
}
|
|
}
|
|
|
|
return dbResult;
|
|
}
|
|
|
|
public async Task<ItemModel?> GetByIdAsync(int recId)
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
return await dbCtx.DbSetItem
|
|
.Where(x => x.ItemID == recId)
|
|
.FirstOrDefaultAsync();
|
|
}
|
|
|
|
public async Task<List<ItemModel>> GetFiltAsync(string CodGroup, ItemClassType ItemType)
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
return await dbCtx.DbSetItem
|
|
.Where(x => (string.IsNullOrEmpty(CodGroup) || x.CodGroup == CodGroup) && (ItemType == ItemClassType.ND || x.ItemType == ItemType))
|
|
.AsNoTracking()
|
|
.Include(g => g.ItemGroupNav)
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<List<ItemModel>> GetSearchAsync(string term)
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
return await dbCtx.DbSetItem
|
|
.Where(x => x.Description.Contains(term, StringComparison.InvariantCultureIgnoreCase) || x.ExtItemCode.Contains(term, StringComparison.InvariantCultureIgnoreCase) || x.SupplCode.Contains(term, StringComparison.InvariantCultureIgnoreCase))
|
|
.AsNoTracking()
|
|
//.Include(g => g.ItemGroupNav)
|
|
.ToListAsync();
|
|
}
|
|
|
|
public async Task<bool> MassUpdateAsync(List<BomItemDTO> list2upd, double setCost, double defMargin, double defQtyMax, string defUM, int roundVal = 0, double scaleFactor = 1_000_000.0)
|
|
{
|
|
bool answ = false;
|
|
if (list2upd == null || !list2upd.Any())
|
|
return answ;
|
|
|
|
await using var dbCtx = await CreateContextAsync();
|
|
// Validate input
|
|
if (setCost <= 0)
|
|
throw new ArgumentException("setCost must be greater than 0.");
|
|
|
|
// Step 1: Extract width and height from ExtItemCode
|
|
var itemUpdates = new List<ItemModel>();
|
|
|
|
foreach (var item in list2upd)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(item.ItemCode))
|
|
continue;
|
|
|
|
// Try to parse ExtItemCode: "Pine-200.0x360.0"
|
|
if (!item.ItemCode.Contains("-") || !item.ItemCode.Contains("x"))
|
|
{
|
|
// Skip invalid format
|
|
continue;
|
|
}
|
|
|
|
// Split by "-" to get prefix and number part
|
|
var parts = item.ItemCode.Split('-', 2);
|
|
if (parts.Length < 2)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
string numberPart = parts[1]; // e.g. "200.0x360.0"
|
|
|
|
// Split by "x" to get width and height
|
|
var widthHeight = numberPart.Split('x', 2);
|
|
if (widthHeight.Length < 2)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (!double.TryParse(widthHeight[0], NumberStyles.Any, CultureInfo.InvariantCulture, out double width) ||
|
|
!double.TryParse(widthHeight[1], NumberStyles.Any, CultureInfo.InvariantCulture, out double height))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Step 2: Calculate Cost using formula:
|
|
// Cost = setCost / 1,000,000 * width * height
|
|
double calculatedCost = (setCost / scaleFactor) * width * height;
|
|
// if requested do round ceiling
|
|
if (roundVal > 0)
|
|
{
|
|
calculatedCost = Math.Ceiling(calculatedCost / roundVal) * roundVal;
|
|
}
|
|
|
|
// Optional: you can also apply margin to cost if needed, but you said "Cost = ..."
|
|
// So we're just computing it based on width/height
|
|
|
|
// Step 4: Create a new ItemModel with updated values
|
|
var updatedItem = new ItemModel
|
|
{
|
|
ItemID = item.ItemID,
|
|
ExtItemCode = item.ItemCode, // keep original
|
|
Cost = calculatedCost,
|
|
Margin = defMargin,
|
|
QtyMax = defQtyMax,
|
|
UM = defUM
|
|
};
|
|
|
|
itemUpdates.Add(updatedItem);
|
|
}
|
|
|
|
// Step 5: Update database using EF Core (EF Core doesn't support "update" on entire list directly)
|
|
// We'll use .UpdateRange() or a raw update via .Where() and .SetProperty()
|
|
|
|
// ✅ Use EF Core's Update method (for bulk update)
|
|
if (itemUpdates.Any())
|
|
{
|
|
// Update only the ones that exist in the DB
|
|
var existingItems = await dbCtx.DbSetItem
|
|
.Where(i => itemUpdates.Select(ui => ui.ItemID).Contains(i.ItemID))
|
|
.ToListAsync();
|
|
|
|
if (existingItems.Any())
|
|
{
|
|
// Update existing records using EF Core's Update method
|
|
foreach (var updatedItem in itemUpdates)
|
|
{
|
|
var existing = existingItems.FirstOrDefault(i => i.ItemID == updatedItem.ItemID);
|
|
if (existing != null)
|
|
{
|
|
// Update only the fields we're setting
|
|
existing.Cost = updatedItem.Cost;
|
|
existing.Margin = updatedItem.Margin;
|
|
existing.QtyMax = updatedItem.QtyMax;
|
|
}
|
|
}
|
|
|
|
answ = await dbCtx.SaveChangesAsync() > 0;
|
|
}
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
public async Task<bool> UpdateAsync(ItemModel entity)
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
// Recuperiamo l'entità tracciata dal context
|
|
var trackedEntity = await dbCtx.DbSetItem.FirstOrDefaultAsync(x => x.ItemID == entity.ItemID);
|
|
|
|
if (trackedEntity != null)
|
|
{
|
|
// Aggiorna i valori dell'entità tracciata con quelli della nuova
|
|
dbCtx.Entry(trackedEntity).CurrentValues.SetValues(entity);
|
|
}
|
|
else
|
|
{
|
|
dbCtx.DbSetItem.Update(entity);
|
|
}
|
|
return await dbCtx.SaveChangesAsync() > 0;
|
|
}
|
|
|
|
public async Task<bool> UpsertFromBomAsync(List<BomItemDTO> bomList)
|
|
{
|
|
await using var dbCtx = await CreateContextAsync();
|
|
|
|
// Wrap in transaction for atomicity
|
|
await using var tx = await dbCtx.Database.BeginTransactionAsync();
|
|
try
|
|
{
|
|
// prendo solo elementi a prezzo 0 da salvare sul DB
|
|
var item2save = bomList
|
|
.Where(x => x.Price == 0)
|
|
.ToList();
|
|
List<ItemModel> listInserted = new List<ItemModel>();
|
|
|
|
// ciclo x ogni elemento della BOM, cercando x gruppo e ExtItemCode
|
|
foreach (var item in item2save)
|
|
{
|
|
var currRec = dbCtx
|
|
.DbSetItem
|
|
.Where(x => x.CodGroup == item.ClassCode && x.ExtItemCode == item.ItemCode)
|
|
.FirstOrDefault();
|
|
|
|
// se nullo --> verifico x inserire!!!
|
|
if (currRec == null)
|
|
{
|
|
// verifico NON sia tra gli list2upd già in fase di inserimento
|
|
if (!listInserted.Any(x => x.CodGroup == item.ClassCode && x.ExtItemCode == item.ItemCode))
|
|
{
|
|
ItemModel newRec = new ItemModel()
|
|
{
|
|
CodGroup = item.ClassCode,
|
|
ItemType = Core.Enums.ItemClassType.Bom,
|
|
IsService = false,
|
|
// da calcolare meglio x gruppo
|
|
ItemCode = 0,
|
|
ExtItemCode = item.ItemCode,
|
|
SupplCode = "BOM ITEM",
|
|
Description = $"BOM | {item.ClassCode} | {item.ItemCode}",
|
|
Cost = 0,
|
|
Margin = 0,
|
|
QtyMin = 0,
|
|
QtyMax = 0,
|
|
UM = "#"
|
|
};
|
|
dbCtx.DbSetItem.Add(newRec);
|
|
listInserted.Add(newRec);
|
|
}
|
|
}
|
|
}
|
|
bool done = await dbCtx.SaveChangesAsync() > 0;
|
|
await tx.CommitAsync();
|
|
return done;
|
|
}
|
|
catch
|
|
{
|
|
await tx.RollbackAsync();
|
|
throw;
|
|
}
|
|
}
|
|
|
|
#endregion Public Methods
|
|
}
|
|
} |