2025-12-12 10:07:14 +03:30
|
|
|
using CMSMicroservice.Application.Common.Exceptions;
|
|
|
|
|
using CMSMicroservice.Application.Common.Interfaces;
|
|
|
|
|
using CMSMicroservice.Domain.Entities;
|
2025-12-12 10:22:09 +03:30
|
|
|
using CMSMicroservice.Domain.Entities.Payment;
|
2025-12-12 10:07:14 +03:30
|
|
|
using CMSMicroservice.Domain.Enums;
|
|
|
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
|
|
|
|
|
|
namespace CMSMicroservice.Application.ManualPaymentCQ.Commands.ProcessManualMembershipPayment;
|
|
|
|
|
|
|
|
|
|
public class ProcessManualMembershipPaymentCommandHandler : IRequestHandler<ProcessManualMembershipPaymentCommand, ProcessManualMembershipPaymentResponseDto>
|
|
|
|
|
{
|
|
|
|
|
private readonly IApplicationDbContext _context;
|
2025-12-12 10:22:09 +03:30
|
|
|
private readonly ICurrentUserService _currentUser;
|
2025-12-12 10:07:14 +03:30
|
|
|
private readonly ILogger<ProcessManualMembershipPaymentCommandHandler> _logger;
|
|
|
|
|
|
|
|
|
|
public ProcessManualMembershipPaymentCommandHandler(
|
|
|
|
|
IApplicationDbContext context,
|
2025-12-12 10:22:09 +03:30
|
|
|
ICurrentUserService currentUser,
|
2025-12-12 10:07:14 +03:30
|
|
|
ILogger<ProcessManualMembershipPaymentCommandHandler> logger)
|
|
|
|
|
{
|
|
|
|
|
_context = context;
|
2025-12-12 10:22:09 +03:30
|
|
|
_currentUser = currentUser;
|
2025-12-12 10:07:14 +03:30
|
|
|
_logger = logger;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<ProcessManualMembershipPaymentResponseDto> Handle(
|
|
|
|
|
ProcessManualMembershipPaymentCommand request,
|
|
|
|
|
CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
_logger.LogInformation(
|
|
|
|
|
"Processing manual membership payment for UserId: {UserId}, Amount: {Amount}",
|
|
|
|
|
request.UserId, request.Amount);
|
|
|
|
|
|
2025-12-12 10:22:09 +03:30
|
|
|
// 1. دریافت شناسه ادمین از کاربر جاری
|
|
|
|
|
var currentUserId = _currentUser.UserId;
|
|
|
|
|
if (string.IsNullOrEmpty(currentUserId))
|
|
|
|
|
{
|
|
|
|
|
throw new UnauthorizedAccessException("کاربر احراز هویت نشده است");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!long.TryParse(currentUserId, out var adminUserId))
|
|
|
|
|
{
|
|
|
|
|
throw new UnauthorizedAccessException("شناسه کاربر نامعتبر است");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2. بررسی وجود کاربر
|
2025-12-12 10:07:14 +03:30
|
|
|
var user = await _context.Users
|
|
|
|
|
.FirstOrDefaultAsync(u => u.Id == request.UserId, cancellationToken);
|
|
|
|
|
|
|
|
|
|
if (user == null)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError("User not found: {UserId}", request.UserId);
|
|
|
|
|
throw new NotFoundException($"کاربر با شناسه {request.UserId} یافت نشد");
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-12 10:22:09 +03:30
|
|
|
// 3. ایجاد ManualPayment با وضعیت Approved
|
|
|
|
|
var manualPayment = new ManualPayment
|
2025-12-12 10:07:14 +03:30
|
|
|
{
|
2025-12-12 10:22:09 +03:30
|
|
|
UserId = request.UserId,
|
|
|
|
|
Amount = request.Amount,
|
|
|
|
|
Type = ManualPaymentType.CashDeposit,
|
|
|
|
|
Description = request.Description ?? "پرداخت دستی عضویت",
|
|
|
|
|
ReferenceNumber = request.ReferenceNumber,
|
|
|
|
|
Status = ManualPaymentStatus.Approved,
|
|
|
|
|
RequestedBy = adminUserId,
|
|
|
|
|
ApprovedBy = adminUserId,
|
|
|
|
|
ApprovedAt = DateTime.Now
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
_context.ManualPayments.Add(manualPayment);
|
|
|
|
|
await _context.SaveChangesAsync(cancellationToken);
|
2025-12-12 10:07:14 +03:30
|
|
|
|
2025-12-12 10:22:09 +03:30
|
|
|
// 4. پیدا کردن یا ایجاد کیف پول
|
2025-12-12 10:07:14 +03:30
|
|
|
var wallet = await _context.UserWallets
|
|
|
|
|
.FirstOrDefaultAsync(w => w.UserId == request.UserId, cancellationToken);
|
|
|
|
|
|
|
|
|
|
if (wallet == null)
|
|
|
|
|
{
|
2025-12-12 10:22:09 +03:30
|
|
|
_logger.LogError("Wallet not found for UserId: {UserId}", request.UserId);
|
|
|
|
|
throw new NotFoundException($"کیف پول کاربر {request.UserId} یافت نشد");
|
2025-12-12 10:07:14 +03:30
|
|
|
}
|
|
|
|
|
|
2025-12-12 10:22:09 +03:30
|
|
|
// 6. ثبت تراکنش
|
2025-12-12 10:07:14 +03:30
|
|
|
var transaction = new Transaction
|
|
|
|
|
{
|
|
|
|
|
Amount = request.Amount,
|
2025-12-12 10:22:09 +03:30
|
|
|
Description = $"پرداخت دستی عضویت - {manualPayment.Description} - مرجع: {request.ReferenceNumber}",
|
2025-12-12 10:07:14 +03:30
|
|
|
PaymentStatus = PaymentStatus.Success,
|
|
|
|
|
PaymentDate = DateTime.Now,
|
|
|
|
|
RefId = request.ReferenceNumber,
|
|
|
|
|
Type = TransactionType.DepositExternal1
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
_context.Transactions.Add(transaction);
|
|
|
|
|
await _context.SaveChangesAsync(cancellationToken);
|
|
|
|
|
|
2025-12-12 10:22:09 +03:30
|
|
|
// 7. اعمال تغییرات بر کیف پول
|
|
|
|
|
var oldBalance = wallet.Balance;
|
|
|
|
|
var oldDiscountBalance = wallet.DiscountBalance;
|
|
|
|
|
|
|
|
|
|
wallet.Balance += request.Amount;
|
|
|
|
|
wallet.DiscountBalance += request.Amount;
|
|
|
|
|
|
|
|
|
|
// 8. ثبت لاگ Balance
|
2025-12-12 10:07:14 +03:30
|
|
|
var balanceLog = new UserWalletChangeLog
|
|
|
|
|
{
|
|
|
|
|
WalletId = wallet.Id,
|
|
|
|
|
CurrentBalance = wallet.Balance,
|
|
|
|
|
ChangeValue = request.Amount,
|
|
|
|
|
CurrentNetworkBalance = wallet.NetworkBalance,
|
|
|
|
|
ChangeNerworkValue = 0,
|
2025-12-12 10:22:09 +03:30
|
|
|
CurrentDiscountBalance = wallet.DiscountBalance,
|
|
|
|
|
ChangeDiscountValue = request.Amount,
|
2025-12-12 10:07:14 +03:30
|
|
|
IsIncrease = true,
|
|
|
|
|
RefrenceId = transaction.Id
|
|
|
|
|
};
|
|
|
|
|
await _context.UserWalletChangeLogs.AddAsync(balanceLog, cancellationToken);
|
|
|
|
|
|
2025-12-12 10:22:09 +03:30
|
|
|
|
|
|
|
|
// 10. بهروزرسانی ManualPayment با TransactionId
|
|
|
|
|
manualPayment.TransactionId = transaction.Id;
|
|
|
|
|
await _context.SaveChangesAsync(cancellationToken);
|
|
|
|
|
|
|
|
|
|
// 11. پیدا کردن یا ایجاد آدرس پیشفرض کاربر
|
2025-12-12 10:07:14 +03:30
|
|
|
var userAddress = await _context.UserAddresses
|
|
|
|
|
.Where(a => a.UserId == request.UserId)
|
|
|
|
|
.OrderByDescending(a => a.IsDefault)
|
|
|
|
|
.ThenBy(a => a.Id)
|
|
|
|
|
.FirstOrDefaultAsync(cancellationToken);
|
|
|
|
|
|
|
|
|
|
if (userAddress == null)
|
|
|
|
|
{
|
|
|
|
|
userAddress = new UserAddress
|
|
|
|
|
{
|
|
|
|
|
UserId = request.UserId,
|
|
|
|
|
Title = "آدرس پیشفرض",
|
|
|
|
|
Address = "پرداخت دستی عضویت - آدرس موقت",
|
|
|
|
|
PostalCode = "0000000000",
|
|
|
|
|
IsDefault = true,
|
|
|
|
|
CityId = 1
|
|
|
|
|
};
|
|
|
|
|
await _context.UserAddresses.AddAsync(userAddress, cancellationToken);
|
|
|
|
|
await _context.SaveChangesAsync(cancellationToken);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-12 10:22:09 +03:30
|
|
|
// 12. ثبت سفارش
|
2025-12-12 10:07:14 +03:30
|
|
|
var order = new UserOrder
|
|
|
|
|
{
|
|
|
|
|
UserId = request.UserId,
|
|
|
|
|
Amount = request.Amount,
|
|
|
|
|
TransactionId = transaction.Id,
|
|
|
|
|
PaymentStatus = PaymentStatus.Success,
|
|
|
|
|
PaymentDate = DateTime.Now,
|
2025-12-12 10:22:09 +03:30
|
|
|
PaymentMethod = PaymentMethod.Deposit,
|
2025-12-12 10:07:14 +03:30
|
|
|
DeliveryStatus = DeliveryStatus.None,
|
|
|
|
|
UserAddressId = userAddress.Id,
|
2025-12-12 10:22:09 +03:30
|
|
|
DeliveryDescription = $"پرداخت دستی عضویت - مرجع: {request.ReferenceNumber}"
|
2025-12-12 10:07:14 +03:30
|
|
|
};
|
|
|
|
|
|
|
|
|
|
_context.UserOrders.Add(order);
|
|
|
|
|
await _context.SaveChangesAsync(cancellationToken);
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation(
|
2025-12-12 10:22:09 +03:30
|
|
|
"Manual membership payment processed successfully. UserId: {UserId}, Amount: {Amount}, ManualPaymentId: {ManualPaymentId}, TransactionId: {TransactionId}, OrderId: {OrderId}, AdminUserId: {AdminUserId}",
|
|
|
|
|
request.UserId, request.Amount, manualPayment.Id, transaction.Id, order.Id, adminUserId);
|
2025-12-12 10:07:14 +03:30
|
|
|
|
|
|
|
|
return new ProcessManualMembershipPaymentResponseDto
|
|
|
|
|
{
|
|
|
|
|
TransactionId = transaction.Id,
|
|
|
|
|
OrderId = order.Id,
|
|
|
|
|
NewWalletBalance = wallet.Balance,
|
|
|
|
|
Message = "پرداخت دستی با موفقیت ثبت شد"
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex) when (ex is not NotFoundException)
|
|
|
|
|
{
|
|
|
|
|
_logger.LogError(ex,
|
|
|
|
|
"Error processing manual membership payment for UserId: {UserId}, Amount: {Amount}",
|
|
|
|
|
request.UserId, request.Amount);
|
|
|
|
|
throw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|