using EgwCoreLib.Lux.Data.DbModel.Items; using EgwCoreLib.Lux.Data.DbModel.Sales; using Microsoft.EntityFrameworkCore; using static EgwCoreLib.Lux.Core.Enums; namespace EgwCoreLib.Lux.Data.Repository.Sales { public class OfferRowRepository : BaseRepository, IOfferRowRepository { #region Public Constructors public OfferRowRepository(IDbContextFactory ctxFactory) : base(ctxFactory) { } #endregion Public Constructors #region Public Methods public async Task AddAsync(OfferRowModel entity) { await using var dbCtx = await CreateContextAsync(); await dbCtx.DbSetOfferRow.AddAsync(entity); return await dbCtx.SaveChangesAsync() > 0; } public async Task DeleteAsync(OfferRowModel entity) { await using var dbCtx = await CreateContextAsync(); // Wrap in transaction for atomicity (multi-row update + delete) await using var tx = await dbCtx.Database.BeginTransactionAsync(); try { // 1. Recupero il record da eliminare var dbResult = await dbCtx.DbSetOfferRow .FirstOrDefaultAsync(x => x.OfferRowID == entity.OfferRowID); if (dbResult == null) return false; // 2. Recupero i record successivi da shiftare var list2Move = await dbCtx.DbSetOfferRow .Where(x => x.OfferID == entity.OfferID && x.RowNum > dbResult.RowNum) .ToListAsync(); foreach (var item in list2Move) { item.RowNum--; dbCtx.Entry(item).State = EntityState.Modified; } // 3. Rimuovo il record dbCtx.DbSetOfferRow.Remove(dbResult); // 4. Salvo tutto bool done = await dbCtx.SaveChangesAsync() > 0; if (done) tx.Commit(); return done; } catch { tx.Rollback(); throw; } } public async Task> GetBomItemsAsync() { await using var dbCtx = await CreateContextAsync(); return await dbCtx.DbSetItem .Where(x => x.ItemType == ItemClassType.Bom || x.ItemType == ItemClassType.BomAlt) .ToListAsync(); } public async Task GetByIdAsync(int offerRowId) { await using var dbCtx = await CreateContextAsync(); return await dbCtx.DbSetOfferRow .Include(r => r.SellingItemNav) .FirstOrDefaultAsync(x => x.OfferRowID == offerRowId); } public async Task> GetByParentAsync(int offerId) { await using var dbCtx = await CreateContextAsync(); return await dbCtx.DbSetOfferRow .Where(x => x.OfferID == offerId) .Include(r => r.SellingItemNav) .AsNoTracking() .ToListAsync(); } public async Task GetByUidAsync(string offerRowUid) { await using var dbCtx = await CreateContextAsync(); return await dbCtx.DbSetOfferRow .Include(r => r.SellingItemNav) .FirstOrDefaultAsync(x => x.OfferRowUID == offerRowUid); } public async Task> GetItemGroupsAsync() { await using var dbCtx = await CreateContextAsync(); return await dbCtx.DbSetItemGroup.ToListAsync(); } public async Task SaveRowsAsync(List rows) { // Add validation for null or empty list if (rows == null || rows.Count == 0) return false; await using var dbCtx = await CreateContextAsync(); // Wrap in transaction for atomicity (batch update multiple rows) await using var tx = await dbCtx.Database.BeginTransactionAsync(); try { foreach (var row in rows) dbCtx.Entry(row).State = EntityState.Modified; bool done = await dbCtx.SaveChangesAsync() > 0; if (done) tx.Commit(); return done; } catch { tx.Rollback(); throw; } } public async Task UpdateAsync(OfferRowModel entity) { await using var dbCtx = await CreateContextAsync(); // Recuperiamo l'entità tracciata dal context var trackedEntity = await dbCtx.DbSetOfferRow.FirstOrDefaultAsync(x => x.OfferRowID == entity.OfferRowID); if (trackedEntity != null) { // Aggiorna i valori dell'entità tracciata con quelli della nuova dbCtx.Entry(trackedEntity).CurrentValues.SetValues(entity); } else { dbCtx.DbSetOfferRow.Update(entity); } return await dbCtx.SaveChangesAsync() > 0; } #endregion Public Methods } }