feat: refactor week number handling to use WeekDefinitionId across multiple entities and queries

This commit is contained in:
masoodafar-web
2025-12-19 10:41:22 +03:30
parent 3cb95dc349
commit 8b784101be
83 changed files with 17592 additions and 566 deletions
@@ -8,10 +8,10 @@ public record CalculateWeeklyCommissionPoolCommand : IRequest<long>
/// <summary>
/// شماره هفته (فرمت: YYYY-Www)
/// </summary>
public string WeekNumber { get; init; } = string.Empty;
public long WeekDefinitionId { get; init; }
/// <summary>
/// آیا محاسبه مجدد انجام شود؟
/// </summary>
public bool ForceRecalculate { get; init; }
public bool ForceRecalculate { get; init; }
}
@@ -3,39 +3,50 @@ namespace CMSMicroservice.Application.CommissionCQ.Commands.CalculateWeeklyCommi
public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<CalculateWeeklyCommissionPoolCommand, long>
{
private readonly IApplicationDbContext _context;
private readonly IWeekDefinitionRepository _weekRepository;
public CalculateWeeklyCommissionPoolCommandHandler(IApplicationDbContext context)
public CalculateWeeklyCommissionPoolCommandHandler(
IApplicationDbContext context,
IWeekDefinitionRepository weekRepository)
{
_context = context;
_weekRepository = weekRepository;
}
public async Task<long> Handle(CalculateWeeklyCommissionPoolCommand request, CancellationToken cancellationToken)
{
// تبدیل WeekNumber به WeekDefinitionId
var weekDefinitionId = _weekRepository.GetGregorianWeekNumber(request.WeekDefinitionId);
if (weekDefinitionId == null)
{
throw new InvalidOperationException($"هفته {request.WeekDefinitionId} در سیستم تعریف نشده است");
}
// بررسی وجود استخر
var existingPool = await _context.WeeklyCommissionPools
.FirstOrDefaultAsync(x => x.WeekNumber == request.WeekNumber, cancellationToken);
.FirstOrDefaultAsync(x => x.WeekDefinitionId == request.WeekDefinitionId, cancellationToken);
if (existingPool == null)
{
throw new InvalidOperationException(
$"Pool هفته {request.WeekNumber} وجود ندارد. " +
$"Pool هفته {request.WeekDefinitionId} وجود ندارد. " +
"Pool باید در هنگام فعالسازی باشگاه مشتریان ایجاد شده باشد"
);
}
if (existingPool.IsCalculated && !request.ForceRecalculate)
{
throw new InvalidOperationException($"استخر کمیسیون هفته {request.WeekNumber} قبلاً محاسبه شده است");
throw new InvalidOperationException($"استخر کمیسیون هفته {request.WeekDefinitionId} قبلاً محاسبه شده است");
}
// بررسی وجود تعادل‌های هفتگی
var weeklyBalances = await _context.NetworkWeeklyBalances
.Where(x => x.WeekNumber == request.WeekNumber)
.Where(x => x.WeekDefinitionId == request.WeekDefinitionId)
.ToListAsync(cancellationToken);
if (!weeklyBalances.Any())
{
throw new InvalidOperationException($"تعادل‌های هفته {request.WeekNumber} هنوز محاسبه نشده است. ابتدا CalculateWeeklyBalances را اجرا کنید");
throw new InvalidOperationException($"تعادل‌های هفته {request.WeekDefinitionId} هنوز محاسبه نشده است. ابتدا CalculateWeeklyBalances را اجرا کنید");
}
// ⭐ Pool از قبل پُر شده (توسط ActivateClubMembership)
@@ -66,7 +77,7 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
if (request.ForceRecalculate)
{
var oldPayouts = await _context.UserCommissionPayouts
.Where(p => p.WeekNumber == request.WeekNumber)
.Where(p => p.WeekDefinitionId == request.WeekDefinitionId)
.ToListAsync(cancellationToken);
if (oldPayouts.Any())
@@ -110,7 +121,7 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
var payout = new UserCommissionPayout
{
UserId = balance.UserId,
WeekNumber = request.WeekNumber,
WeekDefinitionId = request.WeekDefinitionId,
WeeklyPoolId = existingPool.Id,
BalancesEarned = userBalance,
ValuePerBalance = valuePerBalance,
@@ -138,7 +149,7 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
{
UserCommissionPayoutId = payout.Id,
UserId = payout.UserId,
WeekNumber = request.WeekNumber,
WeekDefinitionId = request.WeekDefinitionId,
AmountBefore = 0,
AmountAfter = payout.TotalAmount,
OldStatus = default(CommissionPayoutStatus),
@@ -4,11 +4,10 @@ public class CalculateWeeklyCommissionPoolCommandValidator : AbstractValidator<C
{
public CalculateWeeklyCommissionPoolCommandValidator()
{
RuleFor(x => x.WeekNumber)
.NotEmpty()
.WithMessage("شماره هفته نمی‌تواند خالی باشد")
.Matches(@"^\d{4}-W\d{2}$")
.WithMessage("فرمت شماره هفته باید YYYY-Www باشد");
RuleFor(x => x.WeekDefinitionId)
.NotNull()
.GreaterThan(0)
.WithMessage("شماره هفته نمی‌تواند خالی باشد");
}
public Func<object, string, Task<IEnumerable<string>>> ValidateValue => async (model, propertyName) =>