diff --git a/Distribution/Features/Invoice/IInvoiceRepository.cs b/Distribution/Features/Invoice/IInvoiceRepository.cs index c4dc6ad..ccbcfab 100644 --- a/Distribution/Features/Invoice/IInvoiceRepository.cs +++ b/Distribution/Features/Invoice/IInvoiceRepository.cs @@ -6,8 +6,9 @@ public interface IInvoiceRepository { Task GetByIdAsync(Guid id); Task GetByShopPOIdAsync(Guid shopPOId); - Task> GetAllAsync(Guid? agentId, Guid? routeId, Guid? shopId, InvoiceStatus? status, int page, int pageSize); - Task GetCountAsync(Guid? agentId, Guid? routeId, Guid? shopId, InvoiceStatus? status); + Task> GetAllAsync(Guid? agentId, Guid? routeId, Guid? shopId, InvoiceStatus? status, PaymentStatus? paymentStatus, int page, int pageSize); + Task GetCountAsync(Guid? agentId, Guid? routeId, Guid? shopId, InvoiceStatus? status, PaymentStatus? paymentStatus); + Task> GetOutstandingAsync(); Task AddAsync(Models.Invoice invoice); void Update(Models.Invoice invoice); } diff --git a/Distribution/Features/Invoice/InvoiceController.cs b/Distribution/Features/Invoice/InvoiceController.cs index 4f7a9fe..4e7311c 100644 --- a/Distribution/Features/Invoice/InvoiceController.cs +++ b/Distribution/Features/Invoice/InvoiceController.cs @@ -14,10 +14,18 @@ public class InvoiceController(InvoiceService service, ICurrentUserService curre [FromQuery] Guid? routeId, [FromQuery] Guid? shopId, [FromQuery] InvoiceStatus? status, + [FromQuery] PaymentStatus? paymentStatus, [FromQuery] int page = 1, [FromQuery] int pageSize = 20) { - var result = await service.GetAllAsync(agentId, routeId, shopId, status, page, pageSize); + var result = await service.GetAllAsync(agentId, routeId, shopId, status, paymentStatus, page, pageSize); + return Ok(result); + } + + [HttpGet("outstanding-summary")] + public async Task GetOutstandingSummary() + { + var result = await service.GetOutstandingSummaryAsync(); return Ok(result); } diff --git a/Distribution/Features/Invoice/InvoiceDTOs.cs b/Distribution/Features/Invoice/InvoiceDTOs.cs index 3eb47ca..c9de96c 100644 --- a/Distribution/Features/Invoice/InvoiceDTOs.cs +++ b/Distribution/Features/Invoice/InvoiceDTOs.cs @@ -21,3 +21,5 @@ public record InvoiceResponse( decimal TotalAmount, bool IsActive, DateTime CreatedAt); + +public record OutstandingPaymentsResponse(int InvoiceCount, decimal OutstandingAmount); diff --git a/Distribution/Features/Invoice/InvoiceRepository.cs b/Distribution/Features/Invoice/InvoiceRepository.cs index addbb88..6b2e128 100644 --- a/Distribution/Features/Invoice/InvoiceRepository.cs +++ b/Distribution/Features/Invoice/InvoiceRepository.cs @@ -18,27 +18,35 @@ public class InvoiceRepository(AppDBContext context) : IInvoiceRepository .Include(i => i.ShopPO) .FirstOrDefaultAsync(i => i.FK_ShopPOId == shopPOId && i.IsActive); - public async Task> GetAllAsync(Guid? agentId, Guid? routeId, Guid? shopId, InvoiceStatus? status, int page, int pageSize) => + public async Task> GetAllAsync(Guid? agentId, Guid? routeId, Guid? shopId, InvoiceStatus? status, PaymentStatus? paymentStatus, int page, int pageSize) => await context.Invoices .Include(i => i.ShopPO).ThenInclude(p => p.Store) .Where(i => i.IsActive && (agentId == null || i.ShopPO.RaisedById == agentId) && (routeId == null || i.ShopPO.Store.FK_RouteId == routeId) && (shopId == null || i.ShopPO.FK_StoreId == shopId) - && (status == null || i.Status == status)) + && (status == null || i.Status == status) + && (paymentStatus == null || i.PaymentStatus == paymentStatus)) .OrderByDescending(i => i.CreatedAt) .Skip((page - 1) * pageSize) .Take(pageSize) .ToListAsync(); - public async Task GetCountAsync(Guid? agentId, Guid? routeId, Guid? shopId, InvoiceStatus? status) => + public async Task GetCountAsync(Guid? agentId, Guid? routeId, Guid? shopId, InvoiceStatus? status, PaymentStatus? paymentStatus) => await context.Invoices .Include(i => i.ShopPO).ThenInclude(p => p.Store) .CountAsync(i => i.IsActive && (agentId == null || i.ShopPO.RaisedById == agentId) && (routeId == null || i.ShopPO.Store.FK_RouteId == routeId) && (shopId == null || i.ShopPO.FK_StoreId == shopId) - && (status == null || i.Status == status)); + && (status == null || i.Status == status) + && (paymentStatus == null || i.PaymentStatus == paymentStatus)); + + public async Task> GetOutstandingAsync() => + await context.Invoices + .Include(i => i.Payments.Where(p => p.IsActive)) + .Where(i => i.IsActive && i.PaymentStatus != PaymentStatus.Paid) + .ToListAsync(); public async Task AddAsync(Models.Invoice invoice) => await context.Invoices.AddAsync(invoice); diff --git a/Distribution/Features/Invoice/InvoiceService.cs b/Distribution/Features/Invoice/InvoiceService.cs index f7a8e5c..74fa7b4 100644 --- a/Distribution/Features/Invoice/InvoiceService.cs +++ b/Distribution/Features/Invoice/InvoiceService.cs @@ -24,13 +24,21 @@ public class InvoiceService( return invoice is null ? null : ToResponse(invoice); } - public async Task> GetAllAsync(Guid? agentId, Guid? routeId, Guid? shopId, InvoiceStatus? status, int page, int pageSize) + public async Task> GetAllAsync(Guid? agentId, Guid? routeId, Guid? shopId, InvoiceStatus? status, PaymentStatus? paymentStatus, int page, int pageSize) { - var total = await repo.GetCountAsync(agentId, routeId, shopId, status); - var items = await repo.GetAllAsync(agentId, routeId, shopId, status, page, pageSize); + var total = await repo.GetCountAsync(agentId, routeId, shopId, status, paymentStatus); + var items = await repo.GetAllAsync(agentId, routeId, shopId, status, paymentStatus, page, pageSize); return new PagedResponse(page, pageSize, total, items.Select(ToResponse).ToList()); } + public async Task GetOutstandingSummaryAsync() + { + var invoices = await repo.GetOutstandingAsync(); + var count = invoices.Count; + var outstanding = invoices.Sum(i => i.TotalAmount - i.Payments.Sum(p => p.Amount)); + return new OutstandingPaymentsResponse(count, outstanding); + } + public async Task PrintAsync(Guid id, Guid printedBy, CancellationToken ct = default) { var invoice = await repo.GetByIdAsync(id)