240 lines
11 KiB
C#
240 lines
11 KiB
C#
using CMSMicroservice.Domain.Events;
|
|
using CMSMicroservice.Domain.Enums;
|
|
using CMSMicroservice.Application.DayaLoanCQ.Services;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace CMSMicroservice.Application.DayaLoanCQ.Commands.CheckDayaLoanStatus;
|
|
|
|
public class CheckDayaLoanStatusCommandHandler : IRequestHandler<CheckDayaLoanStatusCommand, CheckDayaLoanStatusResponseDto>
|
|
{
|
|
private readonly IApplicationDbContext _context;
|
|
private readonly IDayaLoanApiService _dayaApiService;
|
|
private readonly ILogger<CheckDayaLoanStatusCommandHandler> _logger;
|
|
|
|
/// <summary>
|
|
/// مبلغ وام دایا - 56 میلیون ریال
|
|
/// </summary>
|
|
private const long DAYA_LOAN_AMOUNT = 56_000_000;
|
|
|
|
public CheckDayaLoanStatusCommandHandler(
|
|
IApplicationDbContext context,
|
|
IDayaLoanApiService dayaApiService,
|
|
ILogger<CheckDayaLoanStatusCommandHandler> logger)
|
|
{
|
|
_context = context;
|
|
_dayaApiService = dayaApiService;
|
|
_logger = logger;
|
|
}
|
|
|
|
public async Task<CheckDayaLoanStatusResponseDto> Handle(CheckDayaLoanStatusCommand request, CancellationToken cancellationToken)
|
|
{
|
|
var results = new List<DayaLoanStatusItem>();
|
|
|
|
try
|
|
{
|
|
// فراخوانی سرویس دایا (Mock یا Real)
|
|
var dayaResults = await _dayaApiService.CheckLoanStatusAsync(request.NationalCodes, cancellationToken);
|
|
|
|
foreach (var dayaResult in dayaResults)
|
|
{
|
|
try
|
|
{
|
|
results.Add(new DayaLoanStatusItem
|
|
{
|
|
NationalCode = dayaResult.NationalCode,
|
|
Status = dayaResult.Status,
|
|
ContractNumber = dayaResult.ContractNumber,
|
|
Message = "استعلام موفق"
|
|
});
|
|
|
|
// ذخیره یا بهروزرسانی در دیتابیس
|
|
var existingContract = await _context.DayaLoanContracts
|
|
.FirstOrDefaultAsync(d => d.NationalCode == dayaResult.NationalCode, cancellationToken);
|
|
|
|
if (existingContract != null)
|
|
{
|
|
var previousStatus = existingContract.Status;
|
|
existingContract.LastCheckDate = DateTime.Now;
|
|
existingContract.Status = dayaResult.Status;
|
|
existingContract.ContractNumber = dayaResult.ContractNumber;
|
|
|
|
// بررسی تغییر وضعیت به PendingReceive یا Received
|
|
// فقط اگر قبلاً پردازش نشده باشد
|
|
if (!existingContract.IsProcessed &&
|
|
!string.IsNullOrEmpty(dayaResult.ContractNumber) &&
|
|
(dayaResult.Status == DayaLoanStatus.PendingReceive || dayaResult.Status == DayaLoanStatus.Received))
|
|
{
|
|
await ProcessDayaLoanReceivedAsync(existingContract.UserId, dayaResult.ContractNumber, cancellationToken);
|
|
existingContract.IsProcessed = true;
|
|
|
|
_logger.LogInformation(
|
|
"Daya loan processed for User {UserId}, ContractNumber: {ContractNumber}, Amount: {Amount}",
|
|
existingContract.UserId, dayaResult.ContractNumber, DAYA_LOAN_AMOUNT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var user = await _context.Users
|
|
.FirstOrDefaultAsync(u => u.NationalCode == dayaResult.NationalCode, cancellationToken);
|
|
|
|
if (user != null)
|
|
{
|
|
var isProcessed = false;
|
|
|
|
// اگر وضعیت PendingReceive یا Received بود و قرارداد دارد، فوری پردازش کن
|
|
if (!string.IsNullOrEmpty(dayaResult.ContractNumber) &&
|
|
(dayaResult.Status == DayaLoanStatus.PendingReceive || dayaResult.Status == DayaLoanStatus.Received))
|
|
{
|
|
await ProcessDayaLoanReceivedAsync(user.Id, dayaResult.ContractNumber, cancellationToken);
|
|
isProcessed = true;
|
|
|
|
_logger.LogInformation(
|
|
"Daya loan processed for new contract - User {UserId}, ContractNumber: {ContractNumber}, Amount: {Amount}",
|
|
user.Id, dayaResult.ContractNumber, DAYA_LOAN_AMOUNT);
|
|
}
|
|
|
|
var newContract = new DayaLoanContract
|
|
{
|
|
UserId = user.Id,
|
|
NationalCode = dayaResult.NationalCode,
|
|
Status = dayaResult.Status,
|
|
ContractNumber = dayaResult.ContractNumber,
|
|
LastCheckDate = DateTime.Now,
|
|
IsProcessed = isProcessed
|
|
};
|
|
|
|
await _context.DayaLoanContracts.AddAsync(newContract, cancellationToken);
|
|
}
|
|
}
|
|
|
|
await _context.SaveChangesAsync(cancellationToken);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error processing Daya result for {NationalCode}", dayaResult.NationalCode);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Error calling Daya API service");
|
|
|
|
// در صورت خطا، نتایج خالی برمیگردانیم
|
|
foreach (var nationalCode in request.NationalCodes)
|
|
{
|
|
results.Add(new DayaLoanStatusItem
|
|
{
|
|
NationalCode = nationalCode,
|
|
Status = DayaLoanStatus.PendingReceive,
|
|
ContractNumber = null,
|
|
Message = $"خطا در استعلام: {ex.Message}"
|
|
});
|
|
}
|
|
}
|
|
|
|
return new CheckDayaLoanStatusResponseDto
|
|
{
|
|
Results = results,
|
|
TotalChecked = request.NationalCodes.Count,
|
|
SuccessCount = results.Count(r => r.ContractNumber != null)
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// پردازش دریافت وام دایا برای کاربر
|
|
/// 1. شارژ کیف پول (Balance + DiscountBalance)
|
|
/// 2. ثبت تراکنش
|
|
/// 3. ثبت لاگ کیف پول
|
|
/// 4. بهروزرسانی وضعیت کاربر
|
|
/// </summary>
|
|
private async Task ProcessDayaLoanReceivedAsync(long userId, string contractNumber, CancellationToken cancellationToken)
|
|
{
|
|
// پیدا کردن کاربر
|
|
var user = await _context.Users
|
|
.FirstOrDefaultAsync(u => u.Id == userId, cancellationToken);
|
|
|
|
if (user == null)
|
|
{
|
|
_logger.LogWarning("User {UserId} not found for Daya loan processing", userId);
|
|
return;
|
|
}
|
|
|
|
// بررسی اینکه قبلاً دریافت نکرده باشد
|
|
if (user.HasReceivedDayaCredit)
|
|
{
|
|
_logger.LogWarning("User {UserId} has already received Daya credit", userId);
|
|
return;
|
|
}
|
|
|
|
// پیدا کردن یا ایجاد کیف پول کاربر
|
|
var wallet = await _context.UserWallets
|
|
.FirstOrDefaultAsync(w => w.UserId == userId, cancellationToken);
|
|
|
|
if (wallet == null)
|
|
{
|
|
wallet = new UserWallet
|
|
{
|
|
UserId = userId,
|
|
Balance = 0,
|
|
NetworkBalance = 0,
|
|
DiscountBalance = 0
|
|
};
|
|
await _context.UserWallets.AddAsync(wallet, cancellationToken);
|
|
await _context.SaveChangesAsync(cancellationToken);
|
|
}
|
|
|
|
// 1. شارژ کیف پول - هم موجودی اصلی و هم موجودی تخفیف
|
|
var previousBalance = wallet.Balance;
|
|
var previousDiscountBalance = wallet.DiscountBalance;
|
|
|
|
wallet.Balance += DAYA_LOAN_AMOUNT;
|
|
wallet.DiscountBalance += DAYA_LOAN_AMOUNT;
|
|
|
|
// 2. ثبت تراکنش - RefId = شماره قرارداد، Status = 0 (Success)، Type = 2 (DepositExternal1)
|
|
var transaction = new Transaction
|
|
{
|
|
Amount = DAYA_LOAN_AMOUNT,
|
|
Description = $"شارژ کیف پول از وام دایا - قرارداد {contractNumber}",
|
|
PaymentStatus = PaymentStatus.Success, // 0
|
|
PaymentDate = DateTime.Now,
|
|
RefId = contractNumber,
|
|
Type = TransactionType.DepositExternal1 // 2
|
|
};
|
|
|
|
await _context.Transactions.AddAsync(transaction, cancellationToken);
|
|
await _context.SaveChangesAsync(cancellationToken);
|
|
|
|
// 3. ثبت لاگ کیف پول با شناسه تراکنش
|
|
var walletLog = new UserWalletChangeLog
|
|
{
|
|
WalletId = wallet.Id,
|
|
CurrentBalance = wallet.Balance,
|
|
ChangeValue = DAYA_LOAN_AMOUNT,
|
|
CurrentNetworkBalance = wallet.NetworkBalance,
|
|
ChangeNerworkValue = 0,
|
|
CurrentDiscountBalance = wallet.DiscountBalance,
|
|
ChangeDiscountValue = DAYA_LOAN_AMOUNT,
|
|
IsIncrease = true,
|
|
RefrenceId = transaction.Id
|
|
};
|
|
|
|
await _context.UserWalletChangeLogs.AddAsync(walletLog, cancellationToken);
|
|
|
|
// 4. بهروزرسانی وضعیت کاربر
|
|
user.HasReceivedDayaCredit = true;
|
|
user.DayaCreditReceivedAt = DateTime.Now;
|
|
user.PackagePurchaseMethod = PackagePurchaseMethod.DayaLoan; // 1
|
|
|
|
await _context.SaveChangesAsync(cancellationToken);
|
|
|
|
_logger.LogInformation(
|
|
"Daya loan fully processed for User {UserId}: " +
|
|
"Wallet Balance {PreviousBalance} -> {NewBalance}, " +
|
|
"DiscountBalance {PreviousDiscountBalance} -> {NewDiscountBalance}, " +
|
|
"Transaction Id: {TransactionId}",
|
|
userId, previousBalance, wallet.Balance,
|
|
previousDiscountBalance, wallet.DiscountBalance,
|
|
transaction.Id);
|
|
}
|
|
}
|