diff --git a/Distribution/Features/Sale/SaleService.cs b/Distribution/Features/Sale/SaleService.cs index dd4bfd8..cddfb84 100644 --- a/Distribution/Features/Sale/SaleService.cs +++ b/Distribution/Features/Sale/SaleService.cs @@ -153,20 +153,13 @@ public class SaleService( if (request.TotalAmount > threshold) return null; } - var saleStatus = request.FulfillImmediately ? SaleStatus.Completed : SaleStatus.Pending; - var orderStatus = request.FulfillImmediately ? OrderStatus.Fulfilled : OrderStatus.Pending; - var fulfilledAt = request.FulfillImmediately ? DateTime.Now : (DateTime?)null; - var sale = new Models.Sale { FK_StoreId = request.StoreId, SaleDate = request.SaleDate, CreatedByUserId = userId, FK_RideId = request.RideId, - TotalAmount = request.TotalAmount, - Status = saleStatus, - FulfillImmediately = request.FulfillImmediately, - CompletedAt = request.FulfillImmediately ? DateTime.Now : null + FulfillImmediately = request.FulfillImmediately }; var orderItems = new List(); @@ -179,7 +172,6 @@ public class SaleService( { FK_ItemId = item.ItemId, Quantity = item.Quantity, - QuantityFulfilled = request.FulfillImmediately ? item.Quantity : 0, UnitPrice = unitPrice.Value }); } @@ -189,14 +181,14 @@ public class SaleService( FK_SaleId = sale.Id, FK_StoreId = request.StoreId, OrderDate = request.SaleDate, - TotalAmount = request.TotalAmount, - Status = orderStatus, - FulfilledAt = fulfilledAt }; foreach (var orderItem in orderItems) orderItem.FK_OrderId = order.Id; + // For a van sale against a specific ride, sell whatever quantity is actually on that + // vehicle instead of rejecting the whole sale over one short item — the sale is always a + // clean, completed sale of what's handed over, never a "partially fulfilled" order. Guid? vehicleId = null; if (request.FulfillImmediately && request.RideId.HasValue) { @@ -207,11 +199,29 @@ public class SaleService( foreach (var item in orderItems) { var balance = await stockRepo.GetBalanceAsync(item.FK_ItemId, vehicleId.Value); - if (balance is null || balance.Quantity < item.Quantity) - return null; + item.Quantity = Math.Min(item.Quantity, (int)(balance?.Quantity ?? 0)); } } + foreach (var item in orderItems) + item.QuantityFulfilled = request.FulfillImmediately ? item.Quantity : 0; + + if (request.FulfillImmediately) + { + sale.Status = SaleStatus.Completed; + sale.CompletedAt = DateTime.Now; + order.Status = OrderStatus.Fulfilled; + order.FulfilledAt = DateTime.Now; + } + else + { + sale.Status = SaleStatus.Pending; + order.Status = OrderStatus.Pending; + } + + sale.TotalAmount = orderItems.Sum(i => i.Quantity * i.UnitPrice); + order.TotalAmount = sale.TotalAmount; + await uow.BeginAsync(ct); try { @@ -221,10 +231,10 @@ public class SaleService( if (vehicleId.HasValue) { - foreach (var item in orderItems) + foreach (var item in orderItems.Where(i => i.QuantityFulfilled > 0)) { var balance = await stockRepo.GetBalanceAsync(item.FK_ItemId, vehicleId.Value); - balance!.Quantity -= item.Quantity; + balance!.Quantity -= item.QuantityFulfilled; balance.UpdatedAt = DateTime.Now; stockRepo.UpdateBalance(balance); @@ -233,7 +243,7 @@ public class SaleService( FK_ItemId = item.FK_ItemId, FromLocationId = vehicleId.Value, FromLocationType = LocationType.Vehicle, - Quantity = item.Quantity, + Quantity = item.QuantityFulfilled, Type = MovementType.Sale, ReferenceId = order.Id });