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 Microsoft.EntityFrameworkCore; using CMSMicroservice.Infrastructure.Persistence; using System.Linq; namespace CMSMicroservice.WebApi.Workers; /// /// Worker برای استعلام خودکار وضعیت وام دایا (هر 15 دقیقه) /// public class DayaLoanCheckWorker { private readonly IMediator _mediator; private readonly ApplicationDbContext _context; private readonly ILogger _logger; public DayaLoanCheckWorker( IMediator mediator, ApplicationDbContext context, ILogger logger) { _mediator = mediator; _context = context; _logger = logger; } /// /// متد اصلی که توسط Hangfire فراخوانی می‌شود /// [AutomaticRetry(Attempts = 3)] public async Task ExecuteAsync() { _logger.LogInformation("DayaLoanCheckWorker started at {Time}", DateTime.Now); try { // پیدا کردن کاربرانی که اعتبار دایا را دریافت نکرده‌اند var pendingUsers = await _context.Users .Where(u => u.HasReceivedDayaCredit == false && u.NationalCode != null && u.NationalCode != "") .Select(u => new { u.Id, u.NationalCode }) .ToListAsync(); if (!pendingUsers.Any()) { _logger.LogInformation("No pending users found for Daya loan check"); return; } _logger.LogInformation("Found {Count} users with pending Daya loan status", pendingUsers.Count); // استعلام از دایا var checkCommand = new CheckDayaLoanStatusCommand { NationalCodes = pendingUsers.Select(u => u.NationalCode).ToList() }; var checkResult = await _mediator.Send(checkCommand); // پردازش نتایج 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); } catch (Exception ex) { _logger.LogError(ex, "Error in DayaLoanCheckWorker"); throw; // Hangfire will retry } } /// /// متد برای Schedule کردن Worker (هر 15 دقیقه) /// public static void Schedule(IRecurringJobManager recurringJobManager) { // هر 15 دقیقه: */15 * * * * recurringJobManager.AddOrUpdate( "daya-loan-check", worker => worker.ExecuteAsync(), "*/01 * * * *", // هر 15 دقیقه TimeZoneInfo.Local ); } }