feat: implement Kavenegar SMS service and refactor system configurations to use static constants
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 1m38s
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 1m38s
This commit is contained in:
+5
-14
@@ -1,4 +1,5 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Domain.Common;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
@@ -13,13 +14,6 @@ public class CommissionCalculationStrategyFactory : ICommissionCalculationStrate
|
||||
private readonly IWeekDefinitionRepository _weekRepository;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
/// <summary>
|
||||
/// کلید Config برای انتخاب استراتژی
|
||||
/// مقدار: "ORM" یا "SP"
|
||||
/// پیشفرض: "ORM"
|
||||
/// </summary>
|
||||
private const string ConfigKey = "Commission.CalculationStrategy";
|
||||
|
||||
public CommissionCalculationStrategyFactory(
|
||||
IApplicationDbContext context,
|
||||
IWeekDefinitionRepository weekRepository,
|
||||
@@ -31,13 +25,10 @@ public class CommissionCalculationStrategyFactory : ICommissionCalculationStrate
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<ICommissionCalculationStrategy> CreateStrategyAsync(CancellationToken cancellationToken = default)
|
||||
public Task<ICommissionCalculationStrategy> CreateStrategyAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
// خواندن Config از دیتابیس
|
||||
var config = await _context.SystemConfigurations
|
||||
.FirstOrDefaultAsync(x => x.Key == ConfigKey && x.IsActive, cancellationToken);
|
||||
|
||||
var strategyValue = config?.Value?.ToUpperInvariant() ?? "ORM";
|
||||
// خواندن Config از SystemConstants (استاتیک)
|
||||
var strategyValue = SystemConstants.CommissionCalculationStrategy.ToUpperInvariant();
|
||||
|
||||
var strategyType = strategyValue switch
|
||||
{
|
||||
@@ -45,7 +36,7 @@ public class CommissionCalculationStrategyFactory : ICommissionCalculationStrate
|
||||
_ => CommissionCalculationStrategyType.Orm
|
||||
};
|
||||
|
||||
return CreateStrategy(strategyType);
|
||||
return Task.FromResult(CreateStrategy(strategyType));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
+4
-9
@@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Domain.Common;
|
||||
using CMSMicroservice.Domain.Entities.Club;
|
||||
using CMSMicroservice.Domain.Entities.Commission;
|
||||
using CMSMicroservice.Domain.Entities.Network;
|
||||
@@ -87,15 +88,9 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
|
||||
var balancesList = new List<NetworkWeeklyBalance>();
|
||||
var calculatedAt = DateTime.Now;
|
||||
|
||||
// خواندن یکباره Configuration ها
|
||||
var configs = await _context.SystemConfigurations
|
||||
.Where(x => x.IsActive && (
|
||||
x.Key == "Commission.MaxWeeklyBalancesPerLeg" ||
|
||||
x.Key == "Commission.MaxNetworkLevel"))
|
||||
.ToDictionaryAsync(x => x.Key, x => x.Value, cancellationToken);
|
||||
|
||||
var maxBalancesPerLeg = int.Parse(configs.GetValueOrDefault("Commission.MaxWeeklyBalancesPerLeg", "300"));
|
||||
var maxNetworkLevel = int.Parse(configs.GetValueOrDefault("Commission.MaxNetworkLevel", "15"));
|
||||
// استفاده از SystemConstants به جای دیتابیس
|
||||
var maxBalancesPerLeg = SystemConstants.CommissionMaxWeeklyBalancesPerLeg;
|
||||
var maxNetworkLevel = SystemConstants.CommissionMaxNetworkLevel;
|
||||
|
||||
foreach (var user in usersInNetwork.OrderBy(o => o.Id))
|
||||
{
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Infrastructure.Configuration;
|
||||
using Kavenegar;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace CMSMicroservice.Infrastructure.Services;
|
||||
|
||||
/// <summary>
|
||||
/// پیادهسازی سرویس ارسال SMS با کاوهنگار
|
||||
/// </summary>
|
||||
public class KavenegarService : IKavenegarService
|
||||
{
|
||||
private readonly KavenegarApi? _kavenegarApi;
|
||||
private readonly SmsSettings _smsSettings;
|
||||
private readonly ILogger<KavenegarService> _logger;
|
||||
|
||||
public KavenegarService(
|
||||
IOptions<SmsSettings> smsSettings,
|
||||
ILogger<KavenegarService> logger)
|
||||
{
|
||||
_smsSettings = smsSettings.Value;
|
||||
_logger = logger;
|
||||
|
||||
// Initialize Kavenegar API
|
||||
if (_smsSettings.Enabled && !string.IsNullOrEmpty(_smsSettings.KavenegarApiKey))
|
||||
{
|
||||
try
|
||||
{
|
||||
_kavenegarApi = new KavenegarApi(_smsSettings.KavenegarApiKey);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "❌ Failed to initialize Kavenegar API");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task SendAsync(string mobile, string message)
|
||||
{
|
||||
if (!_smsSettings.Enabled)
|
||||
{
|
||||
_logger.LogInformation("SMS is disabled. Skipping send to {Mobile}", mobile);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_kavenegarApi == null)
|
||||
{
|
||||
_logger.LogWarning("⚠️ Kavenegar API not initialized, cannot send SMS");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Kavenegar Send is synchronous
|
||||
await Task.Run(() =>
|
||||
{
|
||||
var result = _kavenegarApi.Send(
|
||||
sender: _smsSettings.Sender,
|
||||
receptor: mobile,
|
||||
message: message);
|
||||
|
||||
_logger.LogInformation("📱 SMS sent successfully to {Mobile}, MessageId: {MessageId}", mobile, result.Messageid);
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "❌ Kavenegar error sending SMS to {Mobile}: {Message}", mobile, ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task VerifyLookupAsync(string mobile, string token, string template = "Afrino")
|
||||
{
|
||||
if (!_smsSettings.Enabled)
|
||||
{
|
||||
_logger.LogInformation("SMS is disabled. Skipping VerifyLookup to {Mobile}", mobile);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_kavenegarApi == null)
|
||||
{
|
||||
_logger.LogWarning("⚠️ Kavenegar API not initialized, cannot send VerifyLookup");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Kavenegar VerifyLookup is synchronous
|
||||
await Task.Run(() =>
|
||||
{
|
||||
var result = _kavenegarApi.VerifyLookup(
|
||||
receptor: mobile,
|
||||
token: token,
|
||||
template: template);
|
||||
|
||||
_logger.LogInformation("📱 VerifyLookup SMS sent successfully to {Mobile} with template {Template}, MessageId: {MessageId}",
|
||||
mobile, template, result.Messageid);
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "❌ Kavenegar error sending VerifyLookup to {Mobile}: {Message}", mobile, ex.Message);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user