Files
CMS/src/CMSMicroservice.Application/DayaLoanCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalCommandHandler.cs
T
2025-12-26 09:20:15 +03:30

193 lines
7.4 KiB
C#

using CMSMicroservice.Domain.Events;
using CMSMicroservice.Domain.Enums;
using CMSMicroservice.Domain.Common;
using CMSMicroservice.Application.Common.Interfaces;
using Microsoft.Extensions.Logging;
namespace CMSMicroservice.Application.DayaLoanCQ.Commands.ProcessDayaLoanApproval;
public class ProcessDayaLoanApprovalCommandHandler : IRequestHandler<ProcessDayaLoanApprovalCommand, ProcessDayaLoanApprovalResponseDto>
{
private readonly IApplicationDbContext _context;
private readonly IKavenegarService _smsService;
private readonly ILogger<ProcessDayaLoanApprovalCommandHandler> _logger;
public ProcessDayaLoanApprovalCommandHandler(
IApplicationDbContext context,
IKavenegarService smsService,
ILogger<ProcessDayaLoanApprovalCommandHandler> logger)
{
_context = context;
_smsService = smsService;
_logger = logger;
}
public async Task<ProcessDayaLoanApprovalResponseDto> Handle(ProcessDayaLoanApprovalCommand request, CancellationToken cancellationToken)
{
// پیدا کردن کاربر
var user = await _context.Users
.Include(u => u.UserWallets)
.FirstOrDefaultAsync(u => u.Id == request.UserId, cancellationToken);
if (user == null)
{
throw new NotFoundException(nameof(User), request.UserId);
}
// چک کردن که قبلاً دریافت نکرده باشد
if (user.HasReceivedDayaCredit)
{
throw new InvalidOperationException($"کاربر {request.UserId} قبلاً اعتبار دایا را دریافت کرده است");
}
// ایجاد تراکنش با RefId = شماره قرارداد دایا
var transaction = new Transaction
{
Amount = request.WalletAmount , // 168 میلیون
Description = $"دریافت اعتبار دایا - قرارداد {request.ContractNumber}",
PaymentStatus = PaymentStatus.Success,
PaymentDate = DateTime.Now,
RefId = request.ContractNumber, // شماره قرارداد دایا
Type = TransactionType.DepositExternal1
};
await _context.Transactions.AddAsync(transaction, cancellationToken);
await _context.SaveChangesAsync(cancellationToken);
// یافتن یا ایجاد کیف پول کاربر
var wallet = user.UserWallets.FirstOrDefault();
if (wallet == null)
{
wallet = new UserWallet
{
UserId = request.UserId,
Balance = 0,
NetworkBalance = 0,
DiscountBalance = 0
};
await _context.UserWallets.AddAsync(wallet, cancellationToken);
await _context.SaveChangesAsync(cancellationToken);
}
// شارژ کیف پول عادی (56 میلیون)
var balanceBeforeMain = wallet.Balance;
wallet.Balance += request.WalletAmount;
// لاگ کیف پول عادی
var mainLog = new UserWalletChangeLog
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
ChangeValue = request.WalletAmount,
CurrentNetworkBalance = wallet.NetworkBalance,
ChangeNerworkValue = 0,
IsIncrease = true,
RefrenceId = transaction.Id
};
await _context.UserWalletChangeLogs.AddAsync(mainLog, cancellationToken);
// شارژ کیف پول تخفیف (56 میلیون)
var balanceBeforeDiscount = wallet.DiscountBalance;
wallet.DiscountBalance += request.DiscountWalletAmount;
// لاگ کیف پول تخفیف
var discountLog = new UserWalletChangeLog
{
WalletId = wallet.Id,
CurrentBalance = wallet.Balance,
ChangeValue = 0,
CurrentNetworkBalance = wallet.NetworkBalance,
ChangeNerworkValue = 0,
CurrentDiscountBalance = wallet.DiscountBalance,
ChangeDiscountValue = request.DiscountWalletAmount,
IsIncrease = true,
RefrenceId = transaction.Id
};
await _context.UserWalletChangeLogs.AddAsync(discountLog, cancellationToken);
// به‌روزرسانی وضعیت کاربر
user.HasReceivedDayaCredit = true;
user.DayaCreditReceivedAt = DateTime.Now;
// تنظیم نحوه خرید پکیج به DayaLoan
user.PackagePurchaseMethod = PackagePurchaseMethod.DayaLoan;
// ثبت سفارش پکیج (فعلاً پکیج پایه)
var goldenPackage = await _context.Packages
.FirstOrDefaultAsync(p => p.Id==4, cancellationToken);
if (goldenPackage != null)
{
// پیدا کردن آدرس پیش‌فرض کاربر
var defaultAddress = await _context.UserAddresses
.Where(a => a.UserId == request.UserId)
.OrderByDescending(a => a.Created)
.FirstOrDefaultAsync(cancellationToken);
if (defaultAddress != null)
{
var packageOrder = new UserOrder
{
UserId = request.UserId,
PackageId = goldenPackage.Id,
Amount = request.WalletAmount, // 56 میلیون
PaymentStatus = PaymentStatus.Success,
PaymentDate = DateTime.Now,
DeliveryStatus = DeliveryStatus.None,
UserAddressId = defaultAddress.Id,
TransactionId = transaction.Id,
PaymentMethod = PaymentMethod.IPG
};
await _context.UserOrders.AddAsync(packageOrder, cancellationToken);
}
}
// ثبت Event
user.AddDomainEvent(new DayaLoanApprovedEvent(user, transaction, request.ContractNumber));
await _context.SaveChangesAsync(cancellationToken);
// ارسال SMS به کاربر
await SendDayaLoanSmsAsync(user);
return new ProcessDayaLoanApprovalResponseDto
{
UserId = user.Id,
TransactionId = transaction.Id,
ContractNumber = request.ContractNumber,
MainWalletBalance = wallet.Balance,
LockedWalletBalance = wallet.NetworkBalance,
DiscountWalletBalance = wallet.DiscountBalance,
Message = "اعتبار دایا با موفقیت دریافت شد"
};
}
/// <summary>
/// ارسال SMS اطلاع‌رسانی دریافت اعتبار دایا
/// </summary>
private async Task SendDayaLoanSmsAsync(User user)
{
try
{
var userName = SmsTemplates.GetUserName(user.FirstName);
var message = SmsTemplates.DayaLoanReceived(userName);
await _smsService.SendAsync(user.Mobile, message);
_logger.LogInformation(
"Daya loan SMS sent to User {UserId}, Mobile: {Mobile}",
user.Id, user.Mobile);
}
catch (Exception ex)
{
// خطای SMS نباید فرایند اصلی رو متوقف کنه
_logger.LogError(ex,
"Failed to send Daya loan SMS to User {UserId}, Mobile: {Mobile}",
user.Id, user.Mobile);
}
}
}