feat: add PackageId to CalculateWeeklyCommissionPoolCommand and related logic for package-specific calculations
Build and Deploy to Kubernetes / build-and-deploy (push) Successful in 8m43s

This commit is contained in:
masoodafar-web
2026-05-04 02:31:26 +03:30
parent c4409491c1
commit 41e7f29a0d
5 changed files with 82 additions and 25 deletions
@@ -10,6 +10,11 @@ public record CalculateWeeklyCommissionPoolCommand : IRequest<long>
/// </summary> /// </summary>
public long WeekDefinitionId { get; init; } public long WeekDefinitionId { get; init; }
/// <summary>
/// شناسه پکیج — اگر مقدار داشته باشد فقط همین پکیج محاسبه می‌شود.
/// </summary>
public long? PackageId { get; init; }
/// <summary> /// <summary>
/// آیا محاسبه مجدد انجام شود؟ /// آیا محاسبه مجدد انجام شود؟
/// </summary> /// </summary>
@@ -23,8 +23,17 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
} }
// بررسی وجود استخر // بررسی وجود استخر
var existingPool = await _context.WeeklyCommissionPools var existingPoolQuery = _context.WeeklyCommissionPools
.FirstOrDefaultAsync(x => x.WeekDefinitionId == request.WeekDefinitionId, cancellationToken); .Where(x => x.WeekDefinitionId == request.WeekDefinitionId);
if (request.PackageId.HasValue)
{
existingPoolQuery = existingPoolQuery.Where(x => x.PackageId == request.PackageId.Value);
}
var existingPool = await existingPoolQuery
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(cancellationToken);
if (existingPool == null) if (existingPool == null)
{ {
@@ -40,9 +49,15 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
} }
// بررسی وجود تعادل‌های هفتگی // بررسی وجود تعادل‌های هفتگی
var weeklyBalances = await _context.NetworkWeeklyBalances var weeklyBalancesQuery = _context.NetworkWeeklyBalances
.Where(x => x.WeekDefinitionId == request.WeekDefinitionId) .Where(x => x.WeekDefinitionId == request.WeekDefinitionId);
.ToListAsync(cancellationToken);
if (request.PackageId.HasValue)
{
weeklyBalancesQuery = weeklyBalancesQuery.Where(x => x.PackageId == request.PackageId.Value);
}
var weeklyBalances = await weeklyBalancesQuery.ToListAsync(cancellationToken);
if (!weeklyBalances.Any()) if (!weeklyBalances.Any())
{ {
@@ -76,9 +91,15 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
// حذف پرداخت‌های قبلی در صورت ForceRecalculate // حذف پرداخت‌های قبلی در صورت ForceRecalculate
if (request.ForceRecalculate) if (request.ForceRecalculate)
{ {
var oldPayouts = await _context.UserCommissionPayouts var oldPayoutsQuery = _context.UserCommissionPayouts
.Where(p => p.WeekDefinitionId == request.WeekDefinitionId) .Where(p => p.WeekDefinitionId == request.WeekDefinitionId);
.ToListAsync(cancellationToken);
if (request.PackageId.HasValue)
{
oldPayoutsQuery = oldPayoutsQuery.Where(p => p.PackageId == request.PackageId.Value);
}
var oldPayouts = await oldPayoutsQuery.ToListAsync(cancellationToken);
if (oldPayouts.Any()) if (oldPayouts.Any())
{ {
@@ -159,14 +159,16 @@ public class WeeklyCommissionJob
long weekDefinitionId, long weekDefinitionId,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
// Check idempotency: Skip if already calculated // Skip only when all pools for the week are already calculated.
var existingPool = await _context.WeeklyCommissionPools var hasAnyPool = await _context.WeeklyCommissionPools
.FirstOrDefaultAsync(x => x.WeekDefinitionId == weekDefinitionId, cancellationToken); .AnyAsync(x => x.WeekDefinitionId == weekDefinitionId, cancellationToken);
var hasPendingPool = await _context.WeeklyCommissionPools
.AnyAsync(x => x.WeekDefinitionId == weekDefinitionId && !x.IsCalculated, cancellationToken);
if (existingPool != null && existingPool.IsCalculated) if (hasAnyPool && !hasPendingPool)
{ {
_logger.LogWarning( _logger.LogWarning(
"⚠️ [{ExecutionId}] WeekDefinitionId={WeekDefinitionId} already calculated. Skipping.", "⚠️ [{ExecutionId}] WeekDefinitionId={WeekDefinitionId} already fully calculated. Skipping.",
executionId, weekDefinitionId); executionId, weekDefinitionId);
return; return;
} }
@@ -69,17 +69,25 @@ BEGIN
-- ============================================= -- =============================================
-- 2. بررسی محاسبه قبلی -- 2. بررسی محاسبه قبلی
-- ============================================= -- =============================================
IF EXISTS (SELECT 1 FROM CMS.NetworkWeeklyBalances WHERE WeekDefinitionId = @WeekDefinitionId) IF EXISTS (
SELECT 1
FROM CMS.NetworkWeeklyBalances
WHERE WeekDefinitionId = @WeekDefinitionId
AND PackageId = @PackageId
)
BEGIN BEGIN
IF @ForceRecalculate = 0 IF @ForceRecalculate = 0
BEGIN BEGIN
SET @ErrorMessage = N'تعادل‌های هفته ' + CAST(@WeekDefinitionId AS NVARCHAR(20)) + N' قبلاً محاسبه شده است. برای محاسبه مجدد از ForceRecalculate استفاده کنید'; SET @ErrorMessage = N'تعادل‌های هفته ' + CAST(@WeekDefinitionId AS NVARCHAR(20))
+ N' (پکیج ' + CAST(@PackageId AS NVARCHAR(20)) + N') قبلاً محاسبه شده است. برای محاسبه مجدد از ForceRecalculate استفاده کنید';
RAISERROR(@ErrorMessage, 16, 1); RAISERROR(@ErrorMessage, 16, 1);
RETURN; RETURN;
END END
-- حذف محاسبات قبلی -- حذف محاسبات قبلی فقط برای همین پکیج
DELETE FROM CMS.NetworkWeeklyBalances WHERE WeekDefinitionId = @WeekDefinitionId; DELETE FROM CMS.NetworkWeeklyBalances
WHERE WeekDefinitionId = @WeekDefinitionId
AND PackageId = @PackageId;
END END
-- ============================================= -- =============================================
@@ -222,8 +222,17 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
} }
// بررسی وجود استخر // بررسی وجود استخر
var existingPool = await _context.WeeklyCommissionPools var existingPoolQuery = _context.WeeklyCommissionPools
.FirstOrDefaultAsync(x => x.WeekDefinitionId == weekDefinitionId, cancellationToken); .Where(x => x.WeekDefinitionId == weekDefinitionId);
if (packageId.HasValue)
{
existingPoolQuery = existingPoolQuery.Where(x => x.PackageId == packageId.Value);
}
var existingPool = await existingPoolQuery
.OrderBy(x => x.Id)
.FirstOrDefaultAsync(cancellationToken);
if (existingPool == null) if (existingPool == null)
{ {
@@ -239,9 +248,15 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
} }
// بررسی وجود تعادل‌های هفتگی // بررسی وجود تعادل‌های هفتگی
var weeklyBalances = await _context.NetworkWeeklyBalances var weeklyBalancesQuery = _context.NetworkWeeklyBalances
.Where(x => x.WeekDefinitionId == weekDefinitionId) .Where(x => x.WeekDefinitionId == weekDefinitionId);
.ToListAsync(cancellationToken);
if (packageId.HasValue)
{
weeklyBalancesQuery = weeklyBalancesQuery.Where(x => x.PackageId == packageId.Value);
}
var weeklyBalances = await weeklyBalancesQuery.ToListAsync(cancellationToken);
if (!weeklyBalances.Any()) if (!weeklyBalances.Any())
{ {
@@ -269,9 +284,15 @@ public class OrmCommissionCalculationStrategy : ICommissionCalculationStrategy
// حذف پرداخت‌های قبلی در صورت ForceRecalculate // حذف پرداخت‌های قبلی در صورت ForceRecalculate
if (forceRecalculate) if (forceRecalculate)
{ {
var oldPayouts = await _context.UserCommissionPayouts var oldPayoutsQuery = _context.UserCommissionPayouts
.Where(p => p.WeekDefinitionId == weekDefinitionId) .Where(p => p.WeekDefinitionId == weekDefinitionId);
.ToListAsync(cancellationToken);
if (packageId.HasValue)
{
oldPayoutsQuery = oldPayoutsQuery.Where(p => p.PackageId == packageId.Value);
}
var oldPayouts = await oldPayoutsQuery.ToListAsync(cancellationToken);
if (oldPayouts.Any()) if (oldPayouts.Any())
{ {