using Distribution.Data; using Distribution.Models; using Microsoft.EntityFrameworkCore; namespace Distribution.Features.Stock; public class StockRepository(AppDBContext db) : IStockRepository { public Task GetBalanceAsync(Guid itemId, Guid locationId) => db.StockBalances .Include(b => b.Item) .FirstOrDefaultAsync(b => b.FK_ItemId == itemId && b.LocationId == locationId); public Task> GetBalancesByLocationAsync(Guid locationId, LocationType locationType) => db.StockBalances .Include(b => b.Item) .Where(b => b.LocationId == locationId && b.LocationType == locationType) .ToListAsync(); public Task> GetBalancesAsync(Guid? locationId, LocationType? locationType, Guid? itemId, int page, int pageSize) { var query = db.StockBalances.Include(b => b.Item).AsQueryable(); if (locationId.HasValue) query = query.Where(b => b.LocationId == locationId.Value); if (locationType.HasValue) query = query.Where(b => b.LocationType == locationType.Value); if (itemId.HasValue) query = query.Where(b => b.FK_ItemId == itemId.Value); return query.Skip((page - 1) * pageSize).Take(pageSize).ToListAsync(); } public Task GetBalancesCountAsync(Guid? locationId, LocationType? locationType, Guid? itemId) { var query = db.StockBalances.AsQueryable(); if (locationId.HasValue) query = query.Where(b => b.LocationId == locationId.Value); if (locationType.HasValue) query = query.Where(b => b.LocationType == locationType.Value); if (itemId.HasValue) query = query.Where(b => b.FK_ItemId == itemId.Value); return query.CountAsync(); } public Task> GetBalancesByItemAsync(Guid itemId) => db.StockBalances .Include(b => b.Item) .Where(b => b.FK_ItemId == itemId) .ToListAsync(); public Task> GetLowStockAsync(Guid? locationId) { var query = db.StockBalances .Include(b => b.Item) .Where(b => b.LocationType == LocationType.Warehouse && b.Item.ReorderLevel != null && b.Quantity < b.Item.ReorderLevel); if (locationId.HasValue) query = query.Where(b => b.LocationId == locationId.Value); return query.OrderBy(b => b.Quantity).ToListAsync(); } public async Task AddBalanceAsync(StockBalance balance) => await db.StockBalances.AddAsync(balance); public void UpdateBalance(StockBalance balance) => db.StockBalances.Update(balance); public async Task AddMovementAsync(StockMovement movement) => await db.StockMovements.AddAsync(movement); public Task GetMovementByIdAsync(Guid id) => db.StockMovements.Include(m => m.Item).FirstOrDefaultAsync(m => m.Id == id); public void UpdateMovement(StockMovement movement) => db.StockMovements.Update(movement); public Task> GetMovementsAsync(Guid? locationId, Guid? itemId, MovementType? type, DateTime? from, DateTime? to, int page, int pageSize) { var query = db.StockMovements.Include(m => m.Item).AsQueryable(); if (locationId.HasValue) query = query.Where(m => m.FromLocationId == locationId.Value || m.ToLocationId == locationId.Value); if (itemId.HasValue) query = query.Where(m => m.FK_ItemId == itemId.Value); if (type.HasValue) query = query.Where(m => m.Type == type.Value); if (from.HasValue) query = query.Where(m => m.CreatedAt >= from.Value); if (to.HasValue) query = query.Where(m => m.CreatedAt <= to.Value); return query.OrderByDescending(m => m.CreatedAt).Skip((page - 1) * pageSize).Take(pageSize).ToListAsync(); } public Task GetMovementsCountAsync(Guid? locationId, Guid? itemId, MovementType? type, DateTime? from, DateTime? to) { var query = db.StockMovements.AsQueryable(); if (locationId.HasValue) query = query.Where(m => m.FromLocationId == locationId.Value || m.ToLocationId == locationId.Value); if (itemId.HasValue) query = query.Where(m => m.FK_ItemId == itemId.Value); if (type.HasValue) query = query.Where(m => m.Type == type.Value); if (from.HasValue) query = query.Where(m => m.CreatedAt >= from.Value); if (to.HasValue) query = query.Where(m => m.CreatedAt <= to.Value); return query.CountAsync(); } }