feat: enhance club membership activation with pool and features

This commit is contained in:
masoodafar-web
2025-12-23 00:02:14 +03:30
parent 5bcf6c9840
commit 30144a07c8
@@ -1,5 +1,9 @@
using CMSMicroservice.Application.Common.Exceptions; using CMSMicroservice.Application.Common.Exceptions;
using CMSMicroservice.Application.Common.Interfaces;
using CMSMicroservice.Domain.Entities; using CMSMicroservice.Domain.Entities;
using CMSMicroservice.Domain.Entities.Club;
using CMSMicroservice.Domain.Entities.Commission;
using CMSMicroservice.Domain.Entities.History;
using CMSMicroservice.Domain.Enums; using CMSMicroservice.Domain.Enums;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@@ -12,6 +16,8 @@ namespace CMSMicroservice.Application.ClubMembershipCQ.Commands.AcceptClubMember
/// 1. کد OTP را تایید می‌کند /// 1. کد OTP را تایید می‌کند
/// 2. قرارداد را در جدول UserContract ثبت می‌کند /// 2. قرارداد را در جدول UserContract ثبت می‌کند
/// 3. باشگاه مشتری را فعال می‌کند (IsActive = true) /// 3. باشگاه مشتری را فعال می‌کند (IsActive = true)
/// 4. مبلغ را به Pool هفته جاری اضافه می‌کند
/// 5. ویژگی‌های باشگاه را به کاربر اعطا می‌کند
/// </summary> /// </summary>
public class AcceptClubMembershipContractCommandHandler public class AcceptClubMembershipContractCommandHandler
: IRequestHandler<AcceptClubMembershipContractCommand, AcceptClubMembershipContractResponseDto> : IRequestHandler<AcceptClubMembershipContractCommand, AcceptClubMembershipContractResponseDto>
@@ -19,6 +25,8 @@ public class AcceptClubMembershipContractCommandHandler
private readonly IApplicationDbContext _context; private readonly IApplicationDbContext _context;
private readonly IConfiguration _cfg; private readonly IConfiguration _cfg;
private readonly IHashService _hashService; private readonly IHashService _hashService;
private readonly ICurrentUserService _currentUser;
private readonly IWeekDefinitionRepository _weekRepository;
private readonly ILogger<AcceptClubMembershipContractCommandHandler> _logger; private readonly ILogger<AcceptClubMembershipContractCommandHandler> _logger;
private const int MaxAttempts = 5; private const int MaxAttempts = 5;
@@ -28,11 +36,15 @@ public class AcceptClubMembershipContractCommandHandler
IApplicationDbContext context, IApplicationDbContext context,
IConfiguration cfg, IConfiguration cfg,
IHashService hashService, IHashService hashService,
ICurrentUserService currentUser,
IWeekDefinitionRepository weekRepository,
ILogger<AcceptClubMembershipContractCommandHandler> logger) ILogger<AcceptClubMembershipContractCommandHandler> logger)
{ {
_context = context; _context = context;
_cfg = cfg; _cfg = cfg;
_hashService = hashService; _hashService = hashService;
_currentUser = currentUser;
_weekRepository = weekRepository;
_logger = logger; _logger = logger;
} }
@@ -114,33 +126,173 @@ public class AcceptClubMembershipContractCommandHandler
}; };
await _context.UserContracts.AddAsync(userContract, cancellationToken); await _context.UserContracts.AddAsync(userContract, cancellationToken);
// 6. فعال‌سازی باشگاه مشتریان // 6. دریافت مقادیر از تنظیمات سیستم
if (user.ClubMembership == null) var giftValueConfig = await _context.SystemConfigurations
.FirstOrDefaultAsync(
c => c.Key == "Club.MembershipGiftValue" && c.IsActive,
cancellationToken
);
var activationFeeConfig = await _context.SystemConfigurations
.FirstOrDefaultAsync(
c => c.Key == "Club.ActivationFee" && c.IsActive,
cancellationToken
);
long giftValue = 28_000_000; // مقدار پیش‌فرض
if (giftValueConfig != null && long.TryParse(giftValueConfig.Value, out var configValue))
{ {
user.ClubMembership = new Domain.Entities.Club.ClubMembership giftValue = configValue;
_logger.LogInformation(
"Using Club.MembershipGiftValue from configuration: {GiftValue}",
giftValue
);
}
long activationFeeValue = 25_200_000; // مقدار پیش‌فرض
if (activationFeeConfig != null && long.TryParse(activationFeeConfig.Value, out var activationFeeConfigValue))
{
activationFeeValue = activationFeeConfigValue;
_logger.LogInformation(
"Using Club.ActivationFee from configuration: {activationFeeValue}",
activationFeeValue
);
}
// 7. فعال‌سازی باشگاه مشتریان
ClubMembership clubMembership;
bool isNewMembership = user.ClubMembership == null;
var activationDate = DateTime.Now;
if (isNewMembership)
{
clubMembership = new ClubMembership
{ {
UserId = user.Id, UserId = user.Id,
IsActive = true, IsActive = true,
ActivatedAt = DateTime.Now, ActivatedAt = activationDate,
InitialContribution = 56_000_000, InitialContribution = activationFeeValue,
GiftValue = 25_200_000, GiftValue = giftValue,
TotalEarned = 0,
PurchaseMethod = user.PackagePurchaseMethod PurchaseMethod = user.PackagePurchaseMethod
}; };
await _context.ClubMemberships.AddAsync(user.ClubMembership, cancellationToken); await _context.ClubMemberships.AddAsync(clubMembership, cancellationToken);
_logger.LogInformation(
"Created new club membership for UserId {UserId} via {Method}, GiftValue: {GiftValue}",
user.Id,
user.PackagePurchaseMethod,
giftValue
);
} }
else else
{ {
user.ClubMembership.IsActive = true; clubMembership = user.ClubMembership!;
user.ClubMembership.ActivatedAt = DateTime.Now; clubMembership.IsActive = true;
_context.ClubMemberships.Update(user.ClubMembership); clubMembership.ActivatedAt = activationDate;
clubMembership.PurchaseMethod = user.PackagePurchaseMethod;
_context.ClubMemberships.Update(clubMembership);
_logger.LogInformation(
"Reactivated club membership for UserId {UserId}",
user.Id
);
} }
await _context.SaveChangesAsync(cancellationToken); await _context.SaveChangesAsync(cancellationToken);
// 8. ثبت تاریخچه
var history = new ClubMembershipHistory
{
ClubMembershipId = clubMembership.Id,
UserId = clubMembership.UserId,
OldIsActive = !isNewMembership && !user.ClubMembership!.IsActive,
NewIsActive = true,
Action = ClubMembershipAction.Activated,
Reason = isNewMembership
? $"Initial activation via contract signing - {user.PackagePurchaseMethod}"
: $"Reactivated via contract signing - {user.PackagePurchaseMethod}",
PerformedBy = _currentUser.GetPerformedBy()
};
_context.ClubMembershipHistories.Add(history);
await _context.SaveChangesAsync(cancellationToken);
// 9. اضافه کردن مبلغ به Pool هفته جاری
var currentWeekDefinitionId = GetCurrentWeekDefinitionId();
var weeklyPool = await _context.WeeklyCommissionPools
.FirstOrDefaultAsync(p => p.WeekDefinitionId == currentWeekDefinitionId, cancellationToken);
if (weeklyPool == null)
{
weeklyPool = new WeeklyCommissionPool
{
WeekDefinitionId = currentWeekDefinitionId,
TotalPoolAmount = activationFeeValue,
TotalBalances = 0,
ValuePerBalance = 0,
IsCalculated = false,
CalculatedAt = null
};
await _context.WeeklyCommissionPools.AddAsync(weeklyPool, cancellationToken);
_logger.LogInformation( _logger.LogInformation(
"Club membership contract accepted and activated for UserId: {UserId}, ContractId: {ContractId}", "Created new WeeklyCommissionPool for WeekDefinitionId={WeekDefinitionId} with initial amount: {Amount}",
currentWeekDefinitionId,
activationFeeValue
);
}
else
{
weeklyPool.TotalPoolAmount += activationFeeValue;
_context.WeeklyCommissionPools.Update(weeklyPool);
_logger.LogInformation(
"Added {Amount} to existing WeeklyCommissionPool for WeekDefinitionId={WeekDefinitionId}. New total: {NewTotal}",
activationFeeValue,
currentWeekDefinitionId,
weeklyPool.TotalPoolAmount
);
}
await _context.SaveChangesAsync(cancellationToken);
// 10. اعطای ویژگی‌های باشگاه برای کاربر (فقط برای عضویت جدید)
if (isNewMembership)
{
var clubFeatures = await _context.ClubFeatures
.Where(f => !f.IsDeleted && new long[] { 1, 2, 3, 4 }.Contains(f.Id))
.ToListAsync(cancellationToken);
if (clubFeatures.Any())
{
var userClubFeatures = clubFeatures.Select(feature => new UserClubFeature
{
UserId = user.Id,
ClubMembershipId = clubMembership.Id,
ClubFeatureId = feature.Id,
GrantedAt = activationDate,
IsActive = true,
Notes = "اعطا شده هنگام امضای قرارداد"
}).ToList();
_context.UserClubFeatures.AddRange(userClubFeatures);
await _context.SaveChangesAsync(cancellationToken);
_logger.LogInformation(
"Granted {Count} club features to UserId {UserId}",
clubFeatures.Count,
user.Id
);
}
}
_logger.LogInformation(
"Club membership contract accepted and activated for UserId: {UserId}, ContractId: {ContractId}, MembershipId: {MembershipId}",
request.UserId, request.UserId,
userContract.Id userContract.Id,
clubMembership.Id
); );
return new AcceptClubMembershipContractResponseDto return new AcceptClubMembershipContractResponseDto
@@ -151,6 +303,19 @@ public class AcceptClubMembershipContractCommandHandler
}; };
} }
/// <summary>
/// دریافت شناسه تعریف هفته جاری
/// </summary>
private long GetCurrentWeekDefinitionId()
{
var week = _weekRepository.GetCurrentWeek();
if (week == null)
{
throw new InvalidOperationException("هفته جاری در سیستم تعریف نشده است");
}
return week.Id;
}
private async Task<(bool Success, string Message)> VerifyOtpAsync( private async Task<(bool Success, string Message)> VerifyOtpAsync(
string mobile, string mobile,
string code, string code,