Add pricing and supplier master data
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
namespace Distribution.Features.Order;
|
||||
|
||||
public record OrderItemRequest(Guid ItemId, int Quantity);
|
||||
public record OrderItemRequest(Guid ItemId, int Quantity, decimal? UnitPrice = null);
|
||||
|
||||
public record CreateOrderRequest(Guid StoreId, DateTime OrderDate, decimal TotalAmount, List<OrderItemRequest> Items);
|
||||
|
||||
public record UpdateOrderRequest(DateTime OrderDate, decimal TotalAmount);
|
||||
|
||||
public record OrderItemResponse(Guid ItemId, int Quantity);
|
||||
public record OrderItemResponse(Guid ItemId, int Quantity, decimal UnitPrice);
|
||||
|
||||
public record OrderResponse(
|
||||
Guid Id,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
using Distribution.Features.Item;
|
||||
using Distribution.Features.PriceList;
|
||||
using Distribution.Features.Store;
|
||||
using Distribution.Infra.Authorization;
|
||||
using Distribution.Infra.UoW;
|
||||
@@ -9,6 +11,8 @@ namespace Distribution.Features.Order;
|
||||
public class OrderService(
|
||||
IOrderRepository repo,
|
||||
IStoreRepository storeRepo,
|
||||
IItemRepository itemRepo,
|
||||
PriceListService priceListService,
|
||||
IUnitOfWork uow,
|
||||
ICurrentUserService currentUser,
|
||||
IScopeAccessService scopeAccess,
|
||||
@@ -18,7 +22,7 @@ public class OrderService(
|
||||
|
||||
private static OrderResponse ToResponse(Models.Order o, List<Models.OrderItem> items) =>
|
||||
new(o.Id, o.OrderDate, o.FK_StoreId, o.TotalAmount,
|
||||
items.Select(i => new OrderItemResponse(i.FK_ItemId, i.Quantity)).ToList(),
|
||||
items.Select(i => new OrderItemResponse(i.FK_ItemId, i.Quantity, i.UnitPrice)).ToList(),
|
||||
o.IsActive, o.CreatedAt);
|
||||
|
||||
private bool HasGlobalScope => currentUser.RoleLevel >= GlobalScopeRoleLevel;
|
||||
@@ -29,6 +33,29 @@ public class OrderService(
|
||||
return await scopeAccess.HasStoreScopeAsync(currentUser.UserId.Value, storeId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// applyPricingAndDiscounts (price-list half, 14_pricing_and_suppliers.md): resolves the
|
||||
/// region-scoped active price list, then global, then Item.SalePrice, and validates any
|
||||
/// caller-supplied override falls within [MinPrice ?? Price, Price]. Returns null if no price
|
||||
/// can be resolved, or if the requested price is outside the allowed band.
|
||||
/// </summary>
|
||||
private async Task<decimal?> ResolveUnitPriceAsync(Guid itemId, decimal? requestedUnitPrice, Models.Store store, DateTime orderDate)
|
||||
{
|
||||
var item = await itemRepo.GetByIdAsync(itemId);
|
||||
if (item is null) return null;
|
||||
var regionId = store.Route?.FK_RegionId;
|
||||
var resolution = await priceListService.ResolvePriceAsync(itemId, regionId, item.SalePrice, orderDate);
|
||||
if (resolution is null) return null;
|
||||
|
||||
if (!requestedUnitPrice.HasValue) return resolution.Price;
|
||||
|
||||
var min = resolution.MinPrice ?? resolution.Price;
|
||||
var max = resolution.Price;
|
||||
if (requestedUnitPrice.Value < min || requestedUnitPrice.Value > max) return null;
|
||||
|
||||
return requestedUnitPrice.Value;
|
||||
}
|
||||
|
||||
public async Task<List<OrderResponse>> GetAllAsync()
|
||||
{
|
||||
var orders = (await repo.GetAllAsync()).Where(o => o.IsActive).ToList();
|
||||
@@ -72,7 +99,7 @@ public class OrderService(
|
||||
{
|
||||
if (!await HasStoreScopeAsync(request.StoreId)) return null;
|
||||
|
||||
var store = await storeRepo.GetByIdAsync(request.StoreId);
|
||||
var store = await storeRepo.GetByIdWithRegionAsync(request.StoreId);
|
||||
if (store is null || !store.IsActive) return null;
|
||||
if (store.KycStatus != KycStatus.Verified)
|
||||
{
|
||||
@@ -86,12 +113,20 @@ public class OrderService(
|
||||
OrderDate = request.OrderDate,
|
||||
TotalAmount = request.TotalAmount
|
||||
};
|
||||
var orderItems = request.Items.Select(i => new Models.OrderItem
|
||||
var orderItems = new List<Models.OrderItem>();
|
||||
foreach (var i in request.Items)
|
||||
{
|
||||
FK_OrderId = order.Id,
|
||||
FK_ItemId = i.ItemId,
|
||||
Quantity = i.Quantity
|
||||
}).ToList();
|
||||
var unitPrice = await ResolveUnitPriceAsync(i.ItemId, i.UnitPrice, store, request.OrderDate);
|
||||
if (unitPrice is null) return null;
|
||||
|
||||
orderItems.Add(new Models.OrderItem
|
||||
{
|
||||
FK_OrderId = order.Id,
|
||||
FK_ItemId = i.ItemId,
|
||||
Quantity = i.Quantity,
|
||||
UnitPrice = unitPrice.Value
|
||||
});
|
||||
}
|
||||
|
||||
await uow.BeginAsync(ct);
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user