diff --git a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckAndProcessDayaLoans/CheckAndProcessDayaLoansCommand.cs b/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckAndProcessDayaLoans/CheckAndProcessDayaLoansCommand.cs
new file mode 100644
index 0000000..40f8aaf
--- /dev/null
+++ b/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckAndProcessDayaLoans/CheckAndProcessDayaLoansCommand.cs
@@ -0,0 +1,15 @@
+using CMSMicroservice.Domain.Enums;
+
+namespace CMSMicroservice.Application.DayaLoanCQ.Commands.CheckAndProcessDayaLoans;
+
+///
+/// Command یکپارچه برای استعلام وضعیت وام از سرویس دایا و پردازش خودکار وامهای تأیید شده
+/// این Command هم استعلام میکند و هم در صورت تأیید، کیف پول را شارژ میکند
+///
+public record CheckAndProcessDayaLoansCommand : IRequest
+{
+ ///
+ /// لیست کدهای ملی برای استعلام
+ ///
+ public required List NationalCodes { get; init; }
+}
diff --git a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckAndProcessDayaLoans/CheckAndProcessDayaLoansCommandHandler.cs b/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckAndProcessDayaLoans/CheckAndProcessDayaLoansCommandHandler.cs
new file mode 100644
index 0000000..346dcad
--- /dev/null
+++ b/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckAndProcessDayaLoans/CheckAndProcessDayaLoansCommandHandler.cs
@@ -0,0 +1,301 @@
+using CMSMicroservice.Domain.Events;
+using CMSMicroservice.Domain.Enums;
+using CMSMicroservice.Domain.Common;
+using CMSMicroservice.Application.DayaLoanCQ.Services;
+using CMSMicroservice.Application.Common.Interfaces;
+using Microsoft.Extensions.Logging;
+
+namespace CMSMicroservice.Application.DayaLoanCQ.Commands.CheckAndProcessDayaLoans;
+
+///
+/// Handler یکپارچه برای استعلام و پردازش وام دایا
+/// 1. استعلام از API دایا
+/// 2. ذخیره/بهروزرسانی DayaLoanContract
+/// 3. شارژ کیف پول برای وامهای تأیید شده
+/// 4. ثبت Order پکیج طلایی
+/// 5. ارسال SMS
+///
+public class CheckAndProcessDayaLoansCommandHandler : IRequestHandler
+{
+ private readonly IApplicationDbContext _context;
+ private readonly IDayaLoanApiService _dayaApiService;
+ private readonly IKavenegarService _smsService;
+ private readonly ILogger _logger;
+
+ public CheckAndProcessDayaLoansCommandHandler(
+ IApplicationDbContext context,
+ IDayaLoanApiService dayaApiService,
+ IKavenegarService smsService,
+ ILogger logger)
+ {
+ _context = context;
+ _dayaApiService = dayaApiService;
+ _smsService = smsService;
+ _logger = logger;
+ }
+
+ public async Task Handle(CheckAndProcessDayaLoansCommand request, CancellationToken cancellationToken)
+ {
+ var results = new List();
+ var processedCount = 0;
+
+ try
+ {
+ // 1. استعلام از سرویس دایا
+ _logger.LogInformation("Checking Daya loan status for {Count} national codes", request.NationalCodes.Count);
+ var dayaResults = await _dayaApiService.CheckLoanStatusAsync(request.NationalCodes, cancellationToken);
+
+ foreach (var dayaResult in dayaResults)
+ {
+ var result = new DayaLoanProcessResult
+ {
+ NationalCode = dayaResult.NationalCode,
+ Status = dayaResult.Status,
+ ContractNumber = dayaResult.ContractNumber,
+ WasProcessed = false,
+ Message = "استعلام موفق"
+ };
+
+ try
+ {
+ // 2. پیدا کردن کاربر
+ var user = await _context.Users
+ .Include(u => u.UserWallets)
+ .FirstOrDefaultAsync(u => u.NationalCode == dayaResult.NationalCode, cancellationToken);
+
+ if (user == null)
+ {
+ result.Message = "کاربر یافت نشد";
+ results.Add(result);
+ continue;
+ }
+
+ result.UserId = user.Id;
+
+ // 3. ذخیره/بهروزرسانی DayaLoanContract
+ var contract = await _context.DayaLoanContracts
+ .FirstOrDefaultAsync(d => d.NationalCode == dayaResult.NationalCode, cancellationToken);
+
+ if (contract == null)
+ {
+ contract = new DayaLoanContract
+ {
+ UserId = user.Id,
+ NationalCode = dayaResult.NationalCode,
+ Status = dayaResult.Status,
+ ContractNumber = dayaResult.ContractNumber,
+ LastCheckDate = DateTime.Now,
+ IsProcessed = false
+ };
+ await _context.DayaLoanContracts.AddAsync(contract, cancellationToken);
+ }
+ else
+ {
+ contract.Status = dayaResult.Status;
+ contract.ContractNumber = dayaResult.ContractNumber;
+ contract.LastCheckDate = DateTime.Now;
+ }
+
+ // 4. آیا باید پردازش مالی انجام شود؟
+ var shouldProcess = !contract.IsProcessed &&
+ !user.HasReceivedDayaCredit &&
+ !string.IsNullOrEmpty(dayaResult.ContractNumber) &&
+ (dayaResult.Status == DayaLoanStatus.PendingReceive ||
+ dayaResult.Status == DayaLoanStatus.Received);
+
+ if (shouldProcess)
+ {
+ // 5. پردازش مالی
+ var processResult = await ProcessDayaLoanAsync(user, dayaResult.ContractNumber!, cancellationToken);
+
+ contract.IsProcessed = true;
+ result.WasProcessed = true;
+ result.NewWalletBalance = processResult.NewBalance;
+ result.Message = "وام پردازش و کیف پول شارژ شد";
+ processedCount++;
+
+ _logger.LogInformation(
+ "Daya loan processed for User {UserId}, Contract: {ContractNumber}, NewBalance: {Balance}",
+ user.Id, dayaResult.ContractNumber, processResult.NewBalance);
+ }
+ else if (contract.IsProcessed || user.HasReceivedDayaCredit)
+ {
+ result.Message = "قبلاً پردازش شده";
+ }
+ else if (string.IsNullOrEmpty(dayaResult.ContractNumber))
+ {
+ result.Message = "هنوز قرارداد ندارد";
+ }
+
+ await _context.SaveChangesAsync(cancellationToken);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error processing Daya loan for NationalCode {NationalCode}", dayaResult.NationalCode);
+ result.Message = $"خطا: {ex.Message}";
+ }
+
+ results.Add(result);
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Error calling Daya API service");
+
+ // در صورت خطا در API
+ foreach (var nationalCode in request.NationalCodes)
+ {
+ if (!results.Any(r => r.NationalCode == nationalCode))
+ {
+ results.Add(new DayaLoanProcessResult
+ {
+ NationalCode = nationalCode,
+ Status = DayaLoanStatus.PendingReceive,
+ WasProcessed = false,
+ Message = $"خطا در استعلام: {ex.Message}"
+ });
+ }
+ }
+ }
+
+ return new CheckAndProcessDayaLoansResponseDto
+ {
+ Results = results,
+ TotalChecked = request.NationalCodes.Count,
+ WithContractCount = results.Count(r => !string.IsNullOrEmpty(r.ContractNumber)),
+ ProcessedCount = processedCount
+ };
+ }
+
+ ///
+ /// پردازش مالی وام دایا
+ ///
+ private async Task<(long NewBalance, long TransactionId)> ProcessDayaLoanAsync(
+ User user,
+ string contractNumber,
+ CancellationToken cancellationToken)
+ {
+ // 1. ایجاد تراکنش
+ var transaction = new Transaction
+ {
+ Amount = SystemConstants.DayaLoanAmount,
+ Description = $"دریافت اعتبار دایا - قرارداد {contractNumber}",
+ PaymentStatus = PaymentStatus.Success,
+ PaymentDate = DateTime.Now,
+ RefId = contractNumber,
+ Type = TransactionType.DepositExternal1
+ };
+
+ await _context.Transactions.AddAsync(transaction, cancellationToken);
+ await _context.SaveChangesAsync(cancellationToken);
+
+ // 2. یافتن یا ایجاد کیف پول
+ var wallet = user.UserWallets.FirstOrDefault();
+ if (wallet == null)
+ {
+ wallet = new UserWallet
+ {
+ UserId = user.Id,
+ Balance = 0,
+ NetworkBalance = 0,
+ DiscountBalance = 0
+ };
+ await _context.UserWallets.AddAsync(wallet, cancellationToken);
+ await _context.SaveChangesAsync(cancellationToken);
+ }
+
+ // 3. شارژ کیف پول عادی
+ wallet.Balance += SystemConstants.DayaLoanAmount;
+
+ var mainLog = new UserWalletChangeLog
+ {
+ WalletId = wallet.Id,
+ CurrentBalance = wallet.Balance,
+ ChangeValue = SystemConstants.DayaLoanAmount,
+ CurrentNetworkBalance = wallet.NetworkBalance,
+ ChangeNerworkValue = 0,
+ IsIncrease = true,
+ RefrenceId = transaction.Id
+ };
+ await _context.UserWalletChangeLogs.AddAsync(mainLog, cancellationToken);
+
+ // 4. شارژ کیف پول تخفیف (دو برابر)
+ var discountAmount = SystemConstants.DayaLoanAmount * 2;
+ wallet.DiscountBalance += discountAmount;
+
+ var discountLog = new UserWalletChangeLog
+ {
+ WalletId = wallet.Id,
+ CurrentBalance = wallet.Balance,
+ ChangeValue = 0,
+ CurrentNetworkBalance = wallet.NetworkBalance,
+ ChangeNerworkValue = 0,
+ CurrentDiscountBalance = wallet.DiscountBalance,
+ ChangeDiscountValue = discountAmount,
+ IsIncrease = true,
+ RefrenceId = transaction.Id
+ };
+ await _context.UserWalletChangeLogs.AddAsync(discountLog, cancellationToken);
+
+ // 5. بهروزرسانی کاربر
+ user.HasReceivedDayaCredit = true;
+ user.DayaCreditReceivedAt = DateTime.Now;
+ user.PackagePurchaseMethod = PackagePurchaseMethod.DayaLoan;
+
+ // 6. ثبت Order پکیج پایه
+ var goldenPackage = await _context.Packages
+ .FirstOrDefaultAsync(p => p.Id == 4, cancellationToken);
+
+ if (goldenPackage != null)
+ {
+ // 6. ثبت UserPackagePurchase برای پکیج پایه
+ var goldenPackageId =goldenPackage.Id;
+ var packagePurchase = new UserPackagePurchase
+ {
+ UserId = user.Id,
+ PackageId = goldenPackageId,
+ PurchaseMethod = PackagePurchaseMethod.DayaLoan,
+ PurchasedAt = DateTime.Now,
+ Amount = SystemConstants.DayaLoanAmount,
+ TransactionId = transaction.Id
+ };
+
+ await _context.UserPackagePurchases.AddAsync(packagePurchase, cancellationToken);
+
+ }
+
+ // 7. Domain Event
+ user.AddDomainEvent(new DayaLoanApprovedEvent(user, transaction, contractNumber));
+
+ await _context.SaveChangesAsync(cancellationToken);
+
+ // 8. ارسال SMS
+ await SendDayaLoanSmsAsync(user);
+
+ return (wallet.Balance, transaction.Id);
+ }
+
+ ///
+ /// ارسال SMS اطلاعرسانی
+ ///
+ private async Task SendDayaLoanSmsAsync(User user)
+ {
+ try
+ {
+ var userName = SmsTemplates.GetUserName(user.FirstName+" "+user.LastName);
+ var message = SmsTemplates.DayaLoanReceived(userName);
+
+ await _smsService.SendAsync(user.Mobile, message);
+
+ // ارسال SMS به ادمین برای اطلاع
+ var adminMessage = $"وام دایا دریافت شد\nکاربر: {user.FirstName} {user.LastName}\nموبایل: {user.Mobile}\nکدملی: {user.NationalCode}";
+ await _smsService.SendAsync("09199877503", adminMessage);
+
+ _logger.LogInformation("Daya loan SMS sent to User {UserId}", user.Id);
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Failed to send Daya loan SMS to User {UserId}", user.Id);
+ }
+ }
+}
diff --git a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckAndProcessDayaLoans/CheckAndProcessDayaLoansResponseDto.cs b/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckAndProcessDayaLoans/CheckAndProcessDayaLoansResponseDto.cs
new file mode 100644
index 0000000..fb7942c
--- /dev/null
+++ b/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckAndProcessDayaLoans/CheckAndProcessDayaLoansResponseDto.cs
@@ -0,0 +1,70 @@
+using CMSMicroservice.Domain.Enums;
+
+namespace CMSMicroservice.Application.DayaLoanCQ.Commands.CheckAndProcessDayaLoans;
+
+///
+/// پاسخ Command استعلام و پردازش وام دایا
+///
+public class CheckAndProcessDayaLoansResponseDto
+{
+ ///
+ /// نتایج استعلام و پردازش
+ ///
+ public required List Results { get; set; }
+
+ ///
+ /// تعداد کل استعلام شده
+ ///
+ public int TotalChecked { get; set; }
+
+ ///
+ /// تعداد موفق (دارای قرارداد)
+ ///
+ public int WithContractCount { get; set; }
+
+ ///
+ /// تعداد پردازش شده (شارژ کیف پول)
+ ///
+ public int ProcessedCount { get; set; }
+}
+
+///
+/// نتیجه پردازش هر کاربر
+///
+public class DayaLoanProcessResult
+{
+ ///
+ /// کد ملی
+ ///
+ public required string NationalCode { get; set; }
+
+ ///
+ /// شناسه کاربر
+ ///
+ public long? UserId { get; set; }
+
+ ///
+ /// وضعیت وام در دایا
+ ///
+ public DayaLoanStatus Status { get; set; }
+
+ ///
+ /// شماره قرارداد
+ ///
+ public string? ContractNumber { get; set; }
+
+ ///
+ /// آیا پردازش مالی انجام شد؟
+ ///
+ public bool WasProcessed { get; set; }
+
+ ///
+ /// موجودی کیف پول بعد از شارژ
+ ///
+ public long? NewWalletBalance { get; set; }
+
+ ///
+ /// پیام
+ ///
+ public required string Message { get; set; }
+}
diff --git a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckDayaLoanStatus/CheckDayaLoanStatusCommand.cs b/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckDayaLoanStatus/CheckDayaLoanStatusCommand.cs
deleted file mode 100644
index 3416f54..0000000
--- a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckDayaLoanStatus/CheckDayaLoanStatusCommand.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using CMSMicroservice.Domain.Enums;
-
-namespace CMSMicroservice.Application.DayaLoanCQ.Commands.CheckDayaLoanStatus;
-
-///
-/// Command برای استعلام وضعیت وام از سرویس دایا
-///
-public record CheckDayaLoanStatusCommand : IRequest
-{
- ///
- /// لیست کدهای ملی برای استعلام
- ///
- public List NationalCodes { get; init; }
-}
diff --git a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckDayaLoanStatus/CheckDayaLoanStatusCommandHandler.cs b/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckDayaLoanStatus/CheckDayaLoanStatusCommandHandler.cs
deleted file mode 100644
index 0f2b57c..0000000
--- a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckDayaLoanStatus/CheckDayaLoanStatusCommandHandler.cs
+++ /dev/null
@@ -1,235 +0,0 @@
-using CMSMicroservice.Domain.Events;
-using CMSMicroservice.Domain.Enums;
-using CMSMicroservice.Domain.Common;
-using CMSMicroservice.Application.DayaLoanCQ.Services;
-using Microsoft.Extensions.Logging;
-
-namespace CMSMicroservice.Application.DayaLoanCQ.Commands.CheckDayaLoanStatus;
-
-public class CheckDayaLoanStatusCommandHandler : IRequestHandler
-{
- private readonly IApplicationDbContext _context;
- private readonly IDayaLoanApiService _dayaApiService;
- private readonly ILogger _logger;
-
- public CheckDayaLoanStatusCommandHandler(
- IApplicationDbContext context,
- IDayaLoanApiService dayaApiService,
- ILogger logger)
- {
- _context = context;
- _dayaApiService = dayaApiService;
- _logger = logger;
- }
-
- public async Task Handle(CheckDayaLoanStatusCommand request, CancellationToken cancellationToken)
- {
- var results = new List();
-
- 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, SystemConstants.DayaLoanAmount);
- }
- }
- 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, SystemConstants.DayaLoanAmount);
- }
-
- 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)
- };
- }
-
- ///
- /// پردازش دریافت وام دایا برای کاربر
- /// 1. شارژ کیف پول (Balance + DiscountBalance)
- /// 2. ثبت تراکنش
- /// 3. ثبت لاگ کیف پول
- /// 4. بهروزرسانی وضعیت کاربر
- ///
- 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 += SystemConstants.DayaLoanAmount;
- wallet.DiscountBalance += SystemConstants.DayaLoanAmount;
-
- // 2. ثبت تراکنش - RefId = شماره قرارداد، Status = 0 (Success)، Type = 2 (DepositExternal1)
- var transaction = new Transaction
- {
- Amount = SystemConstants.DayaLoanAmount,
- 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 = SystemConstants.DayaLoanAmount,
- CurrentNetworkBalance = wallet.NetworkBalance,
- ChangeNerworkValue = 0,
- CurrentDiscountBalance = wallet.DiscountBalance,
- ChangeDiscountValue = SystemConstants.DayaLoanAmount,
- 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);
- }
-}
diff --git a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckDayaLoanStatus/CheckDayaLoanStatusResponseDto.cs b/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckDayaLoanStatus/CheckDayaLoanStatusResponseDto.cs
deleted file mode 100644
index ec9c54c..0000000
--- a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/CheckDayaLoanStatus/CheckDayaLoanStatusResponseDto.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using CMSMicroservice.Domain.Enums;
-
-namespace CMSMicroservice.Application.DayaLoanCQ.Commands.CheckDayaLoanStatus;
-
-public class CheckDayaLoanStatusResponseDto
-{
- public List Results { get; set; }
- public int TotalChecked { get; set; }
- public int SuccessCount { get; set; }
-}
-
-public class DayaLoanStatusItem
-{
- public string NationalCode { get; set; }
- public DayaLoanStatus Status { get; set; }
- public string? ContractNumber { get; set; }
- public string Message { get; set; }
-}
diff --git a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalCommand.cs b/src/CMSMicroservice.Application/DayaLoanCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalCommand.cs
deleted file mode 100644
index 5d60b9c..0000000
--- a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalCommand.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using CMSMicroservice.Domain.Enums;
-using CMSMicroservice.Domain.Common;
-
-namespace CMSMicroservice.Application.DayaLoanCQ.Commands.ProcessDayaLoanApproval;
-
-///
-/// Command برای پردازش تایید وام دایا و شارژ کیف پول
-///
-public record ProcessDayaLoanApprovalCommand : IRequest
-{
- ///
- /// شناسه کاربر
- ///
- public long UserId { get; init; }
-
- ///
- /// شماره قرارداد دایا
- ///
- public string ContractNumber { get; init; }
-
- ///
- /// مبلغ کیف پول عادی
- ///
- public long WalletAmount { get; init; } = SystemConstants.DayaLoanAmount;
-
-
-
- ///
- /// مبلغ کیف پول تخفیف (دو برابر)
- ///
- public long DiscountWalletAmount { get; init; } = SystemConstants.DayaLoanAmount * 2;
-}
diff --git a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalCommandHandler.cs b/src/CMSMicroservice.Application/DayaLoanCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalCommandHandler.cs
deleted file mode 100644
index 6ea84c4..0000000
--- a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalCommandHandler.cs
+++ /dev/null
@@ -1,192 +0,0 @@
-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
-{
- private readonly IApplicationDbContext _context;
- private readonly IKavenegarService _smsService;
- private readonly ILogger _logger;
-
- public ProcessDayaLoanApprovalCommandHandler(
- IApplicationDbContext context,
- IKavenegarService smsService,
- ILogger logger)
- {
- _context = context;
- _smsService = smsService;
- _logger = logger;
- }
-
- public async Task 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 = "اعتبار دایا با موفقیت دریافت شد"
- };
- }
-
- ///
- /// ارسال SMS اطلاعرسانی دریافت اعتبار دایا
- ///
- 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);
- }
- }
-}
diff --git a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalCommandValidator.cs b/src/CMSMicroservice.Application/DayaLoanCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalCommandValidator.cs
deleted file mode 100644
index de3c9fb..0000000
--- a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalCommandValidator.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-namespace CMSMicroservice.Application.DayaLoanCQ.Commands.ProcessDayaLoanApproval;
-
-public class ProcessDayaLoanApprovalCommandValidator : AbstractValidator
-{
- public ProcessDayaLoanApprovalCommandValidator()
- {
- RuleFor(v => v.UserId)
- .GreaterThan(0)
- .WithMessage("شناسه کاربر باید بزرگتر از صفر باشد");
-
- RuleFor(v => v.ContractNumber)
- .NotEmpty()
- .WithMessage("شماره قرارداد الزامی است")
- .MaximumLength(100)
- .WithMessage("شماره قرارداد نباید بیش از 100 کاراکتر باشد");
-
- RuleFor(v => v.WalletAmount)
- .GreaterThan(0)
- .WithMessage("مبلغ کیف پول باید بزرگتر از صفر باشد");
- }
-}
diff --git a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalResponseDto.cs b/src/CMSMicroservice.Application/DayaLoanCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalResponseDto.cs
deleted file mode 100644
index 0dcff74..0000000
--- a/src/CMSMicroservice.Application/DayaLoanCQ/Commands/ProcessDayaLoanApproval/ProcessDayaLoanApprovalResponseDto.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace CMSMicroservice.Application.DayaLoanCQ.Commands.ProcessDayaLoanApproval;
-
-public class ProcessDayaLoanApprovalResponseDto
-{
- public long UserId { get; set; }
- public long TransactionId { get; set; }
- public string ContractNumber { get; set; }
- public long MainWalletBalance { get; set; }
- public long LockedWalletBalance { get; set; }
- public long DiscountWalletBalance { get; set; }
- public string Message { get; set; }
-}
diff --git a/src/CMSMicroservice.Domain/Common/SmsTemplates.cs b/src/CMSMicroservice.Domain/Common/SmsTemplates.cs
index ca7df31..680730c 100644
--- a/src/CMSMicroservice.Domain/Common/SmsTemplates.cs
+++ b/src/CMSMicroservice.Domain/Common/SmsTemplates.cs
@@ -9,7 +9,7 @@ public static class SmsTemplates
/// پیام دریافت اعتبار دایا
///
public static string DayaLoanReceived(string userName) =>
- $"{userName} گرامی، اعتبار شما واریز گردید. شما میتوانید با مراجعه به سامانه کارابازار فرایند فعالسازی خود را ادامه دهید. با تشکر از حسن انتخاب شما";
+ $"{userName} عزیز، تامین اعتبار شما انجام شد. شما میتوانید با مراجعه به سامانه کارابازار فرایند فعالسازی خود را ادامه دهید. با تشکر از حسن انتخاب شما";
///
/// پیام فعالسازی باشگاه مشتریان
@@ -64,8 +64,8 @@ public static class SmsTemplates
///
/// دریافت نام کاربر یا مقدار پیشفرض
///
- public static string GetUserName(string? firstName) =>
- !string.IsNullOrWhiteSpace(firstName) ? firstName : "کاربر";
+ public static string GetUserName(string? fullName) =>
+ !string.IsNullOrWhiteSpace(fullName) ? fullName : "کاربر";
#endregion
}
diff --git a/src/CMSMicroservice.WebApi/Services/ConfigurationService.cs b/src/CMSMicroservice.WebApi/Services/ConfigurationService.cs
new file mode 100644
index 0000000..fa0fda6
--- /dev/null
+++ b/src/CMSMicroservice.WebApi/Services/ConfigurationService.cs
@@ -0,0 +1,162 @@
+using CMSMicroservice.Domain.Common;
+using CMSMicroservice.Protobuf.Protos.Configuration;
+using Google.Protobuf.WellKnownTypes;
+using Grpc.Core;
+using Microsoft.Extensions.Logging;
+
+namespace CMSMicroservice.WebApi.Services;
+
+///
+/// سرویس تنظیمات سیستم - خواندن از SystemConstants
+///
+public class ConfigurationService : ConfigurationContract.ConfigurationContractBase
+{
+ private readonly ILogger _logger;
+
+ public ConfigurationService(ILogger logger)
+ {
+ _logger = logger;
+ }
+
+ ///
+ /// دریافت تنظیمات با کلید خاص
+ ///
+ public override Task GetConfigurationByKey(GetConfigurationByKeyRequest request, ServerCallContext context)
+ {
+ var response = new GetConfigurationByKeyResponse
+ {
+ Key = request.Key,
+ Scope = request.Scope,
+ IsActive = true,
+ Created = Timestamp.FromDateTime(DateTime.UtcNow),
+ LastModified = Timestamp.FromDateTime(DateTime.UtcNow)
+ };
+
+ // خواندن مقدار از SystemConstants بر اساس کلید
+ response.Value = GetConfigurationValue(request.Key);
+ response.Description = GetConfigurationDescription(request.Key);
+
+ _logger.LogDebug("Configuration requested: Key={Key}, Value={Value}", request.Key, response.Value);
+
+ return Task.FromResult(response);
+ }
+
+ ///
+ /// دریافت تمام تنظیمات
+ ///
+ public override Task GetAllConfigurations(GetAllConfigurationsRequest request, ServerCallContext context)
+ {
+ var response = new GetAllConfigurationsResponse();
+
+ // Club Settings
+ response.Models.Add(CreateConfigModel("Club.ActivationFee", SystemConstants.ClubActivationFee.ToString(), "هزینه فعالسازی عضویت باشگاه", 2));
+ response.Models.Add(CreateConfigModel("Club.MembershipGiftValue", SystemConstants.ClubMembershipGiftValue.ToString(), "مبلغ هدیه حق عضویت باشگاه", 2));
+
+ // Commission Settings
+ response.Models.Add(CreateConfigModel("Commission.MinWithdrawalAmount", SystemConstants.CommissionMinWithdrawalAmount.ToString(), "حداقل مبلغ برداشت", 3));
+ response.Models.Add(CreateConfigModel("Commission.MaxWeeklyBalancesPerLeg", SystemConstants.CommissionMaxWeeklyBalancesPerLeg.ToString(), "سقف تعادل هفتگی برای هر دست", 3));
+ response.Models.Add(CreateConfigModel("Commission.MaxNetworkLevel", SystemConstants.CommissionMaxNetworkLevel.ToString(), "حداکثر عمق شبکه برای محاسبه کمیسیون", 3));
+ response.Models.Add(CreateConfigModel("Commission.CashWithdrawalEnabled", SystemConstants.CommissionCashWithdrawalEnabled.ToString(), "امکان برداشت نقدی", 3));
+ response.Models.Add(CreateConfigModel("Commission.CalculationStrategy", SystemConstants.CommissionCalculationStrategy, "روش محاسبه کمیسیون", 3));
+
+ // Network Settings
+ response.Models.Add(CreateConfigModel("Network.AllowOrphanNodes", SystemConstants.NetworkAllowOrphanNodes.ToString(), "اجازه حذف والدین با فرزند", 1));
+ response.Models.Add(CreateConfigModel("Network.MaxChildrenPerLeg", SystemConstants.NetworkMaxChildrenPerLeg.ToString(), "حداکثر تعداد فرزند مستقیم در هر پا", 1));
+
+ // Package Settings
+ response.Models.Add(CreateConfigModel("Package.BasePackageAmount", SystemConstants.BasePackageAmount.ToString(), "مبلغ پکیج پایه", 0));
+ response.Models.Add(CreateConfigModel("Package.DayaLoanAmount", SystemConstants.DayaLoanAmount.ToString(), "مبلغ وام دایا", 0));
+
+ // System Settings
+ response.Models.Add(CreateConfigModel("System.MaintenanceMode", SystemConstants.SystemMaintenanceMode.ToString(), "حالت تعمیر و نگهداری", 0));
+ response.Models.Add(CreateConfigModel("System.EnableAuditLog", SystemConstants.SystemEnableAuditLog.ToString(), "فعالسازی لاگ تغییرات", 0));
+
+ // Shop Settings
+ response.Models.Add(CreateConfigModel("Shop.VAT", SystemConstants.ShopVAT.ToString(), "مالیات بر ارزش افزوده", 0));
+
+ return Task.FromResult(response);
+ }
+
+ ///
+ /// سایر عملیاتها که فعلاً پیادهسازی نشدهاند (چون از constant استفاده میکنیم)
+ ///
+ public override Task CreateOrUpdateConfiguration(CreateOrUpdateConfigurationRequest request, ServerCallContext context)
+ {
+ _logger.LogWarning("CreateOrUpdateConfiguration called but SystemConstants are read-only");
+ throw new RpcException(new Status(StatusCode.Unimplemented, "تنظیمات سیستم فقط خواندنی هستند"));
+ }
+
+ public override Task DeactivateConfiguration(DeactivateConfigurationRequest request, ServerCallContext context)
+ {
+ _logger.LogWarning("DeactivateConfiguration called but SystemConstants are read-only");
+ throw new RpcException(new Status(StatusCode.Unimplemented, "تنظیمات سیستم فقط خواندنی هستند"));
+ }
+
+ public override Task GetConfigurationHistory(GetConfigurationHistoryRequest request, ServerCallContext context)
+ {
+ // چون constant هستند، تاریخچهای وجود نداره
+ return Task.FromResult(new GetConfigurationHistoryResponse());
+ }
+
+ #region Private Helpers
+
+ private static string GetConfigurationValue(string key)
+ {
+ return key switch
+ {
+ "Club.ActivationFee" => SystemConstants.ClubActivationFee.ToString(),
+ "Club.MembershipGiftValue" => SystemConstants.ClubMembershipGiftValue.ToString(),
+ "Commission.MinWithdrawalAmount" => SystemConstants.CommissionMinWithdrawalAmount.ToString(),
+ "Commission.MaxWeeklyBalancesPerLeg" => SystemConstants.CommissionMaxWeeklyBalancesPerLeg.ToString(),
+ "Commission.MaxNetworkLevel" => SystemConstants.CommissionMaxNetworkLevel.ToString(),
+ "Commission.CashWithdrawalEnabled" => SystemConstants.CommissionCashWithdrawalEnabled.ToString(),
+ "Commission.CalculationStrategy" => SystemConstants.CommissionCalculationStrategy,
+ "Network.AllowOrphanNodes" => SystemConstants.NetworkAllowOrphanNodes.ToString(),
+ "Network.MaxChildrenPerLeg" => SystemConstants.NetworkMaxChildrenPerLeg.ToString(),
+ "Package.BasePackageAmount" => SystemConstants.BasePackageAmount.ToString(),
+ "Package.DayaLoanAmount" => SystemConstants.DayaLoanAmount.ToString(),
+ "System.MaintenanceMode" => SystemConstants.SystemMaintenanceMode.ToString(),
+ "System.EnableAuditLog" => SystemConstants.SystemEnableAuditLog.ToString(),
+ "Shop.VAT" => SystemConstants.ShopVAT.ToString(),
+ _ => string.Empty
+ };
+ }
+
+ private static string GetConfigurationDescription(string key)
+ {
+ return key switch
+ {
+ "Club.ActivationFee" => "هزینه فعالسازی عضویت باشگاه (ریال)",
+ "Club.MembershipGiftValue" => "مبلغ هدیه حق عضویت باشگاه (ریال)",
+ "Commission.MinWithdrawalAmount" => "حداقل مبلغ برداشت (ریال)",
+ "Commission.MaxWeeklyBalancesPerLeg" => "سقف تعادل هفتگی برای هر دست",
+ "Commission.MaxNetworkLevel" => "حداکثر عمق شبکه برای محاسبه کمیسیون",
+ "Commission.CashWithdrawalEnabled" => "امکان برداشت نقدی",
+ "Commission.CalculationStrategy" => "روش محاسبه کمیسیون",
+ "Network.AllowOrphanNodes" => "اجازه حذف والدین با فرزند",
+ "Network.MaxChildrenPerLeg" => "حداکثر تعداد فرزند مستقیم در هر پا",
+ "Package.BasePackageAmount" => "مبلغ پکیج پایه (ریال)",
+ "Package.DayaLoanAmount" => "مبلغ وام دایا (ریال)",
+ "System.MaintenanceMode" => "حالت تعمیر و نگهداری سیستم",
+ "System.EnableAuditLog" => "فعالسازی لاگ تغییرات",
+ "Shop.VAT" => "مالیات بر ارزش افزوده",
+ _ => string.Empty
+ };
+ }
+
+ private static ConfigurationModel CreateConfigModel(string key, string value, string description, int scope)
+ {
+ return new ConfigurationModel
+ {
+ Id = key.GetHashCode(),
+ Key = key,
+ Value = value,
+ Description = description,
+ Scope = scope,
+ IsActive = true,
+ Created = Timestamp.FromDateTime(DateTime.UtcNow)
+ };
+ }
+
+ #endregion
+}
diff --git a/src/CMSMicroservice.WebApi/Workers/DayaLoanCheckWorker.cs b/src/CMSMicroservice.WebApi/Workers/DayaLoanCheckWorker.cs
index 610b980..a2e4348 100644
--- a/src/CMSMicroservice.WebApi/Workers/DayaLoanCheckWorker.cs
+++ b/src/CMSMicroservice.WebApi/Workers/DayaLoanCheckWorker.cs
@@ -1,9 +1,7 @@
using Hangfire;
using MediatR;
using Microsoft.Extensions.Logging;
-using CMSMicroservice.Application.DayaLoanCQ.Commands.CheckDayaLoanStatus;
-using CMSMicroservice.Application.DayaLoanCQ.Commands.ProcessDayaLoanApproval;
-using CMSMicroservice.Domain.Enums;
+using CMSMicroservice.Application.DayaLoanCQ.Commands.CheckAndProcessDayaLoans;
using Microsoft.EntityFrameworkCore;
using CMSMicroservice.Infrastructure.Persistence;
using System.Linq;
@@ -11,7 +9,7 @@ using System.Linq;
namespace CMSMicroservice.WebApi.Workers;
///
-/// Worker برای استعلام خودکار وضعیت وام دایا (هر 15 دقیقه)
+/// Worker برای استعلام خودکار وضعیت وام دایا و پردازش خودکار (هر 20 دقیقه)
///
public class DayaLoanCheckWorker
{
@@ -39,18 +37,15 @@ public class DayaLoanCheckWorker
try
{
-
// پیدا کردن کاربرانی که:
// 1. اعتبار دایا را دریافت نکردهاند
// 2. کد ملی دارند
- // 3. قبلاً شماره قرارداد نگرفتهاند
var pendingUsers = await _context.Users
.Where(u =>
u.HasReceivedDayaCredit == false &&
u.NationalCode != null &&
- u.NationalCode != ""
- )
- .Select(u => new { u.Id, u.NationalCode })
+ u.NationalCode != "")
+ .Select(u => u.NationalCode!)
.ToListAsync();
if (!pendingUsers.Any())
@@ -61,47 +56,19 @@ public class DayaLoanCheckWorker
_logger.LogInformation("Found {Count} users with pending Daya loan status", pendingUsers.Count);
- // استعلام از دایا
- var checkCommand = new CheckDayaLoanStatusCommand
+ // استعلام و پردازش یکجا با Command یکپارچه
+ var command = new CheckAndProcessDayaLoansCommand
{
- NationalCodes = pendingUsers.Select(u => u.NationalCode).ToList()
+ NationalCodes = pendingUsers
};
- var checkResult = await _mediator.Send(checkCommand);
+ var result = await _mediator.Send(command);
- // پردازش نتایج
- foreach (var result in checkResult.Results)
- {
- // فقط وضعیت PendingReceive را پردازش میکنیم (یعنی وام درخواست شده)
- if (result.Status == DayaLoanStatus.PendingReceive && !string.IsNullOrEmpty(result.ContractNumber))
- {
- var user = pendingUsers.FirstOrDefault(u => u.NationalCode == result.NationalCode);
- if (user != null)
- {
- try
- {
- // پردازش تایید وام و شارژ کیف پول
- var processCommand = new ProcessDayaLoanApprovalCommand
- {
- UserId = user.Id,
- ContractNumber = result.ContractNumber,
- };
-
- var processResult = await _mediator.Send(processCommand);
-
- _logger.LogInformation("Daya loan processed for user {UserId}. Contract: {ContractNumber}",
- user.Id, result.ContractNumber);
- }
- catch (Exception ex)
- {
- _logger.LogError(ex, "Error processing Daya loan for user {UserId}", user.Id);
- }
- }
- }
- }
-
- _logger.LogInformation("DayaLoanCheckWorker completed. Checked: {Total}, Processed: {Success}",
- checkResult.TotalChecked, checkResult.SuccessCount);
+ _logger.LogInformation(
+ "DayaLoanCheckWorker completed. Checked: {Total}, WithContract: {WithContract}, Processed: {Processed}",
+ result.TotalChecked,
+ result.WithContractCount,
+ result.ProcessedCount);
}
catch (Exception ex)
{
@@ -111,15 +78,14 @@ public class DayaLoanCheckWorker
}
///
- /// متد برای Schedule کردن Worker (هر 15 دقیقه)
+ /// متد برای Schedule کردن Worker (هر 20 دقیقه)
///
public static void Schedule(IRecurringJobManager recurringJobManager)
{
- // هر 15 دقیقه: */15 * * * *
recurringJobManager.AddOrUpdate(
"daya-loan-check",
worker => worker.ExecuteAsync(),
- "*/20 * * * *", // هر 15 دقیقه
+ "*/20 * * * *",
TimeZoneInfo.Local
);
}