From 18a2299d9388dc37ff3f35be7a21683d9188d1d7 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Thu, 14 May 2026 03:12:45 +0330 Subject: [PATCH 1/3] fix: update MagicWallet thresholds for consistency with business logic - Adjust MagicWalletEntryThreshold from 1,000,000 to 100,000 - Update MagicWalletDefaultMaxDeposit from 1,000,000,000 to 100,000,000 - Change MagicWalletDefaultMaxCredit from 2,500,000,000 to 250,000,000 - Modify comments in UserOrderService to reflect updated threshold values --- src/CMSMicroservice.Domain/Common/SystemConstants.cs | 6 +++--- src/CMSMicroservice.WebApi/Services/UserOrderService.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/CMSMicroservice.Domain/Common/SystemConstants.cs b/src/CMSMicroservice.Domain/Common/SystemConstants.cs index 0bf961c..961913c 100644 --- a/src/CMSMicroservice.Domain/Common/SystemConstants.cs +++ b/src/CMSMicroservice.Domain/Common/SystemConstants.cs @@ -64,7 +64,7 @@ public static class SystemConstants /// مقدار ۱٬۰۰۰٬۰۰۰ ریال = ۱۰۰ هزار تومان /// (Q24: چون قیمت محصولات متفاوت است، موجودی دقیقاً صفر نمی‌شود) /// - 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..c9dea29 100644 --- a/src/CMSMicroservice.WebApi/Services/UserOrderService.cs +++ b/src/CMSMicroservice.WebApi/Services/UserOrderService.cs @@ -338,7 +338,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 From 4d7932f335900dcb50ba5977e412c302f6008fd6 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Sun, 17 May 2026 21:57:48 +0330 Subject: [PATCH 2/3] fix(regular-store): deduct inventory and restore on cancel - UserOrderService.SubmitShopBuyOrder: inject IInventoryService; validate available stock per item before any financial operation; call ConfirmSaleAsync and increment Product.SaleCount after order is persisted. - CancelOrderByAdminCommandHandler: inject IInventoryService; include FactorDetails in query; call ProcessReturnAsync for each item so stock is restored when an order is cancelled by admin. Co-authored-by: Cursor --- .../CancelOrderByAdminCommandHandler.cs | 24 ++++++++++++++++ .../Services/UserOrderService.cs | 28 ++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/CMSMicroservice.Application/OrderManagementCQ/Commands/CancelOrderByAdmin/CancelOrderByAdminCommandHandler.cs b/src/CMSMicroservice.Application/OrderManagementCQ/Commands/CancelOrderByAdmin/CancelOrderByAdminCommandHandler.cs index c53ea04..2a72c7b 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 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 @@ -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 From cdd124ac25b0cfcd4074c6ad81a624f0f0c06992 Mon Sep 17 00:00:00 2001 From: masoodafar-web Date: Sun, 17 May 2026 22:38:40 +0330 Subject: [PATCH 3/3] fix: rename cancellationToken to ct in ProcessReturnAsync call Co-authored-by: Cursor --- .../CancelOrderByAdmin/CancelOrderByAdminCommandHandler.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMSMicroservice.Application/OrderManagementCQ/Commands/CancelOrderByAdmin/CancelOrderByAdminCommandHandler.cs b/src/CMSMicroservice.Application/OrderManagementCQ/Commands/CancelOrderByAdmin/CancelOrderByAdminCommandHandler.cs index 2a72c7b..c71ed8d 100644 --- a/src/CMSMicroservice.Application/OrderManagementCQ/Commands/CancelOrderByAdmin/CancelOrderByAdminCommandHandler.cs +++ b/src/CMSMicroservice.Application/OrderManagementCQ/Commands/CancelOrderByAdmin/CancelOrderByAdminCommandHandler.cs @@ -100,7 +100,7 @@ public class CancelOrderByAdminCommandHandler : IRequestHandler