using Imprink.Domain.Entities; using Imprink.Domain.Repositories; using Imprink.Infrastructure.Database; using Microsoft.EntityFrameworkCore; namespace Imprink.Infrastructure.Repositories; public class ProductVariantRepository(ApplicationDbContext context) : IProductVariantRepository { public async Task GetByIdAsync(Guid id, CancellationToken cancellationToken = default) { return await context.ProductVariants .FirstOrDefaultAsync(pv => pv.Id == id, cancellationToken); } public async Task GetByIdWithProductAsync(Guid id, CancellationToken cancellationToken = default) { return await context.ProductVariants .Include(pv => pv.Product) .ThenInclude(p => p.Category) .FirstOrDefaultAsync(pv => pv.Id == id, cancellationToken); } public async Task GetBySkuAsync(string sku, CancellationToken cancellationToken = default) { return await context.ProductVariants .Include(pv => pv.Product) .FirstOrDefaultAsync(pv => pv.Sku == sku, cancellationToken); } public async Task> GetByProductIdAsync(Guid productId, CancellationToken cancellationToken = default) { return await context.ProductVariants .Include(pv => pv.Product) .Where(pv => pv.ProductId == productId) .OrderBy(pv => pv.Size) .ThenBy(pv => pv.Color) .ToListAsync(cancellationToken); } public async Task> GetActiveByProductIdAsync(Guid productId, CancellationToken cancellationToken = default) { return await context.ProductVariants .Include(pv => pv.Product) .Where(pv => pv.ProductId == productId && pv.IsActive) .OrderBy(pv => pv.Size) .ThenBy(pv => pv.Color) .ToListAsync(cancellationToken); } public async Task> GetInStockByProductIdAsync(Guid productId, CancellationToken cancellationToken = default) { return await context.ProductVariants .Include(pv => pv.Product) .Where(pv => pv.ProductId == productId && pv.IsActive && pv.StockQuantity > 0) .OrderBy(pv => pv.Size) .ThenBy(pv => pv.Color) .ToListAsync(cancellationToken); } public Task AddAsync(ProductVariant productVariant, CancellationToken cancellationToken = default) { productVariant.Id = Guid.NewGuid(); productVariant.CreatedAt = DateTime.UtcNow; productVariant.ModifiedAt = DateTime.UtcNow; context.ProductVariants.Add(productVariant); return Task.FromResult(productVariant); } public Task UpdateAsync(ProductVariant productVariant, CancellationToken cancellationToken = default) { productVariant.ModifiedAt = DateTime.UtcNow; context.ProductVariants.Update(productVariant); return Task.FromResult(productVariant); } public async Task DeleteAsync(Guid id, CancellationToken cancellationToken = default) { var productVariant = await GetByIdAsync(id, cancellationToken); if (productVariant != null) { context.ProductVariants.Remove(productVariant); } } public async Task ExistsAsync(Guid id, CancellationToken cancellationToken = default) { return await context.ProductVariants .AnyAsync(pv => pv.Id == id, cancellationToken); } public async Task SkuExistsAsync(string sku, Guid? excludeId = null, CancellationToken cancellationToken = default) { var query = context.ProductVariants.Where(pv => pv.Sku == sku); if (excludeId.HasValue) { query = query.Where(pv => pv.Id != excludeId.Value); } return await query.AnyAsync(cancellationToken); } public async Task UpdateStockQuantityAsync(Guid id, int quantity, CancellationToken cancellationToken = default) { var productVariant = await GetByIdAsync(id, cancellationToken); if (productVariant != null) { productVariant.StockQuantity = quantity; productVariant.ModifiedAt = DateTime.UtcNow; } } }