using CMSMicroservice.Application.Common.Interfaces; using CMSMicroservice.Domain.Enums; using MediatR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; namespace CMSMicroservice.Application.OrderManagementCQ.Commands.CancelOrderByAdmin; public class CancelOrderByAdminCommandHandler : IRequestHandler { private readonly IApplicationDbContext _context; private readonly ICurrentUserService _currentUser; private readonly ILogger _logger; public CancelOrderByAdminCommandHandler( IApplicationDbContext context, ICurrentUserService currentUser, ILogger logger) { _context = context; _currentUser = currentUser; _logger = logger; } public async Task Handle(CancelOrderByAdminCommand request, CancellationToken cancellationToken) { // بررسی Admin if (string.IsNullOrEmpty(_currentUser.UserId)) { throw new UnauthorizedAccessException("کاربر احراز هویت نشده است"); } var order = await _context.UserOrders .Include(x => x.User) .ThenInclude(x => x.UserWallets) .FirstOrDefaultAsync(x => x.Id == request.OrderId && !x.IsDeleted, cancellationToken); if (order == null) { throw new KeyNotFoundException($"سفارش با شناسه {request.OrderId} یافت نشد"); } if (order.DeliveryStatus == DeliveryStatus.Cancelled) { throw new InvalidOperationException("این سفارش قبلاً لغو شده است"); } if (order.DeliveryStatus == DeliveryStatus.Delivered) { throw new InvalidOperationException("سفارش تحویل داده شده را نمی‌توان لغو کرد"); } // تغییر وضعیت به لغو شده order.DeliveryStatus = DeliveryStatus.Cancelled; order.DeliveryDescription = $"لغو توسط Admin: {request.CancelReason}"; // بازگشت وجه به کیف پول if (request.RefundToWallet && order.PaymentMethod == PaymentMethod.Wallet) { var wallet = order.User.UserWallets.FirstOrDefault(); if (wallet != null) { var walletLog = new UserWalletHistory { WalletId = wallet.Id, CurrentBalance = wallet.Balance, CurrentNetworkBalance = wallet.NetworkBalance, CurrentDiscountBalance = wallet.DiscountBalance, ChangeValue = order.Amount, ChangeDiscountValue = 0, IsIncrease = true, RefrenceId = order.Id }; wallet.Balance += order.Amount; await _context.UserWalletHistories.AddAsync(walletLog, cancellationToken); _logger.LogInformation( "Refund processed. OrderId: {OrderId}, Amount: {Amount}, UserId: {UserId}", order.Id, order.Amount, order.UserId ); } } await _context.SaveChangesAsync(cancellationToken); _logger.LogInformation( "Order cancelled by admin. OrderId: {OrderId}, Reason: {Reason}, Refunded: {Refunded}, Admin: {AdminId}", order.Id, request.CancelReason, request.RefundToWallet, _currentUser.UserId ); return Unit.Value; } }