diff --git a/src/CMSMicroservice.Application/OrderManagementCQ/Commands/CancelOrderByAdmin/CancelOrderByAdminCommandHandler.cs b/src/CMSMicroservice.Application/OrderManagementCQ/Commands/CancelOrderByAdmin/CancelOrderByAdminCommandHandler.cs index c53ea04..c71ed8d 100644 --- a/src/CMSMicroservice.Application/OrderManagementCQ/Commands/CancelOrderByAdmin/CancelOrderByAdminCommandHandler.cs +++ b/src/CMSMicroservice.Application/OrderManagementCQ/Commands/CancelOrderByAdmin/CancelOrderByAdminCommandHandler.cs @@ -10,15 +10,18 @@ public class CancelOrderByAdminCommandHandler : IRequestHandler _logger; public CancelOrderByAdminCommandHandler( IApplicationDbContext context, ICurrentUserService currentUser, + IInventoryService inventoryService, ILogger logger) { _context = context; _currentUser = currentUser; + _inventoryService = inventoryService; _logger = logger; } @@ -33,6 +36,7 @@ public class CancelOrderByAdminCommandHandler : IRequestHandler x.User) .ThenInclude(x => x.UserWallets) + .Include(x => x.FactorDetails) .FirstOrDefaultAsync(x => x.Id == request.OrderId && !x.IsDeleted, cancellationToken); if (order == null) @@ -87,6 +91,26 @@ public class CancelOrderByAdminCommandHandler : IRequestHandler - public const long MagicWalletEntryThreshold = 1_000_000; + public const long MagicWalletEntryThreshold = 100_000; /// /// مقدار پیش‌فرض ضریب جادویی وقتی پکیج یافت نشود (بازگشت به پایه) @@ -74,12 +74,12 @@ public static class SystemConstants /// /// مقدار پیش‌فرض حداکثر واریز جادویی وقتی پکیج یافت نشود (ریال) /// - public const long MagicWalletDefaultMaxDeposit = 1_000_000_000; + public const long MagicWalletDefaultMaxDeposit = 100_000_000; /// /// مقدار پیش‌فرض حداکثر اعتبار جادویی وقتی پکیج یافت نشود (ریال) /// - public const long MagicWalletDefaultMaxCredit = 2_500_000_000; + public const long MagicWalletDefaultMaxCredit = 250_000_000; #endregion diff --git a/src/CMSMicroservice.WebApi/Services/UserOrderService.cs b/src/CMSMicroservice.WebApi/Services/UserOrderService.cs index ee43e6a..fea1e6a 100644 --- a/src/CMSMicroservice.WebApi/Services/UserOrderService.cs +++ b/src/CMSMicroservice.WebApi/Services/UserOrderService.cs @@ -29,12 +29,14 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase private readonly ISender _sender; private readonly IApplicationDbContext _context; private readonly ICurrentUserService _currentUserService; + private readonly IInventoryService _inventoryService; - public UserOrderService(ISender sender, IApplicationDbContext context, ICurrentUserService currentUserService) + public UserOrderService(ISender sender, IApplicationDbContext context, ICurrentUserService currentUserService, IInventoryService inventoryService) { _sender = sender; _context = context; _currentUserService = currentUserService; + _inventoryService = inventoryService; } [RequiresPermission(PermissionNames.OrdersCreate)] public override async Task CreateNewUserOrder(CreateNewUserOrderRequest request, ServerCallContext context) @@ -285,6 +287,18 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase throw new RpcException(new Status(StatusCode.InvalidArgument, $"مبلغ نامعتبر است. محاسبه شده: {totalAmount}, دریافتی: {request.TotalAmount}")); } + + // Validate stock availability for all cart items before any financial operation + foreach (var cartItem in cartItems) + { + var available = await _inventoryService.GetAvailableQuantityAsync( + cartItem.ProductId, ProductType.RegularProduct, ct: context.CancellationToken); + if (available < cartItem.Count) + { + throw new RpcException(new Status(StatusCode.FailedPrecondition, + $"موجودی «{cartItem.Product.Title}» کافی نیست. موجود: {available}، درخواستی: {cartItem.Count}")); + } + } // Get user's wallet var wallet = await _context.UserWallets @@ -338,7 +352,7 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase _context.UserWalletHistories.Add(walletLog); // ═══ Magic Wallet: Entry / Exit Trigger ═══ - // Q24: آستانه <= 1,000,000 ریال به جای == 0 (چون قیمت محصولات متفاوت است) + // Q24: آستانه <= 1,00,000 تومان به جای == 0 (چون قیمت محصولات متفاوت است) if (wallet.Balance <= SystemConstants.MagicWalletEntryThreshold) { var user = await _context.Users @@ -461,6 +475,18 @@ public class UserOrderService : UserOrderContract.UserOrderContractBase cartItem.IsDeleted = true; } + await _context.SaveChangesAsync(context.CancellationToken); + + // Deduct inventory and update SaleCount for each purchased item + foreach (var cartItem in cartItems) + { + await _inventoryService.ConfirmSaleAsync( + cartItem.ProductId, ProductType.RegularProduct, + cartItem.Count, order.Id, context.CancellationToken); + + cartItem.Product.SaleCount += cartItem.Count; + } + await _context.SaveChangesAsync(context.CancellationToken); return new SubmitShopBuyOrderResponse