fix(regular-store): deduct inventory and restore on cancel
Build and Deploy to Kubernetes / build-and-deploy (push) Failing after 19m38s

- 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 <cursoragent@cursor.com>
This commit is contained in:
masoodafar-web
2026-05-17 21:57:48 +03:30
parent 18a2299d93
commit 4d7932f335
2 changed files with 51 additions and 1 deletions
@@ -10,15 +10,18 @@ public class CancelOrderByAdminCommandHandler : IRequestHandler<CancelOrderByAdm
{
private readonly IApplicationDbContext _context;
private readonly ICurrentUserService _currentUser;
private readonly IInventoryService _inventoryService;
private readonly ILogger<CancelOrderByAdminCommandHandler> _logger;
public CancelOrderByAdminCommandHandler(
IApplicationDbContext context,
ICurrentUserService currentUser,
IInventoryService inventoryService,
ILogger<CancelOrderByAdminCommandHandler> logger)
{
_context = context;
_currentUser = currentUser;
_inventoryService = inventoryService;
_logger = logger;
}
@@ -33,6 +36,7 @@ public class CancelOrderByAdminCommandHandler : IRequestHandler<CancelOrderByAdm
var order = await _context.UserOrders
.Include(x => 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<CancelOrderByAdm
await _context.SaveChangesAsync(cancellationToken);
// Restore inventory for each item (only if order was not yet delivered)
if (order.FactorDetails != null && order.FactorDetails.Any())
{
foreach (var item in order.FactorDetails)
{
var restored = await _inventoryService.ProcessReturnAsync(
item.ProductId, ProductType.RegularProduct,
item.Count, order.Id,
note: $"برگشت موجودی — لغو سفارش #{order.Id} توسط Admin",
cancellationToken: cancellationToken);
if (!restored)
{
_logger.LogWarning(
"Failed to restore inventory for ProductId={ProductId} on cancel OrderId={OrderId}",
item.ProductId, order.Id);
}
}
}
_logger.LogInformation(
"Order cancelled by admin. OrderId: {OrderId}, Reason: {Reason}, Refunded: {Refunded}, Admin: {AdminId}",
order.Id,