Merge branch 'kub-stage' into production
Build and Deploy to Production / build-and-deploy (push) Successful in 1m50s
Build and Deploy to Production / build-and-deploy (push) Successful in 1m50s
This commit is contained in:
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// سرویس تنظیمات سیستم - خواندن از SystemConstants
|
||||
/// </summary>
|
||||
public class ConfigurationService : ConfigurationContract.ConfigurationContractBase
|
||||
{
|
||||
private readonly ILogger<ConfigurationService> _logger;
|
||||
|
||||
public ConfigurationService(ILogger<ConfigurationService> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// دریافت تنظیمات با کلید خاص
|
||||
/// </summary>
|
||||
public override Task<GetConfigurationByKeyResponse> 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// دریافت تمام تنظیمات
|
||||
/// </summary>
|
||||
public override Task<GetAllConfigurationsResponse> 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// سایر عملیاتها که فعلاً پیادهسازی نشدهاند (چون از constant استفاده میکنیم)
|
||||
/// </summary>
|
||||
public override Task<Empty> CreateOrUpdateConfiguration(CreateOrUpdateConfigurationRequest request, ServerCallContext context)
|
||||
{
|
||||
_logger.LogWarning("CreateOrUpdateConfiguration called but SystemConstants are read-only");
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, "تنظیمات سیستم فقط خواندنی هستند"));
|
||||
}
|
||||
|
||||
public override Task<Empty> DeactivateConfiguration(DeactivateConfigurationRequest request, ServerCallContext context)
|
||||
{
|
||||
_logger.LogWarning("DeactivateConfiguration called but SystemConstants are read-only");
|
||||
throw new RpcException(new Status(StatusCode.Unimplemented, "تنظیمات سیستم فقط خواندنی هستند"));
|
||||
}
|
||||
|
||||
public override Task<GetConfigurationHistoryResponse> 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
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// Worker برای استعلام خودکار وضعیت وام دایا (هر 15 دقیقه)
|
||||
/// Worker برای استعلام خودکار وضعیت وام دایا و پردازش خودکار (هر 20 دقیقه)
|
||||
/// </summary>
|
||||
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
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// متد برای Schedule کردن Worker (هر 15 دقیقه)
|
||||
/// متد برای Schedule کردن Worker (هر 20 دقیقه)
|
||||
/// </summary>
|
||||
public static void Schedule(IRecurringJobManager recurringJobManager)
|
||||
{
|
||||
// هر 15 دقیقه: */15 * * * *
|
||||
recurringJobManager.AddOrUpdate<DayaLoanCheckWorker>(
|
||||
"daya-loan-check",
|
||||
worker => worker.ExecuteAsync(),
|
||||
"*/20 * * * *", // هر 15 دقیقه
|
||||
"*/20 * * * *",
|
||||
TimeZoneInfo.Local
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user