feat: add IsActive field to UserClubFeatures for admin management
This commit is contained in:
@@ -33,10 +33,10 @@ public class ApproveWithdrawalCommandHandler : IRequestHandler<ApproveWithdrawal
|
||||
|
||||
// Update status to Withdrawn (approved)
|
||||
payout.Status = CommissionPayoutStatus.Withdrawn;
|
||||
payout.WithdrawnAt = DateTime.UtcNow;
|
||||
payout.WithdrawnAt = DateTime.Now;
|
||||
payout.ProcessedBy = _currentUser.GetPerformedBy();
|
||||
payout.ProcessedAt = DateTime.UtcNow;
|
||||
payout.LastModified = DateTime.UtcNow;
|
||||
payout.ProcessedAt = DateTime.Now;
|
||||
payout.LastModified = DateTime.Now;
|
||||
|
||||
// TODO: Add PayoutHistory record
|
||||
// var history = new CommissionPayoutHistory
|
||||
@@ -51,7 +51,7 @@ public class ApproveWithdrawalCommandHandler : IRequestHandler<ApproveWithdrawal
|
||||
// Action = (int)CommissionPayoutAction.Approved,
|
||||
// PerformedBy = "Admin", // TODO: Get from authenticated user
|
||||
// Reason = request.Notes,
|
||||
// Created = DateTime.UtcNow
|
||||
// Created = DateTime.Now
|
||||
// };
|
||||
// _context.CommissionPayoutHistories.Add(history);
|
||||
|
||||
|
||||
@@ -28,9 +28,17 @@ public class CalculateWeeklyBalancesCommandHandler : IRequestHandler<CalculateWe
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
// دریافت کاربران فعال در شبکه
|
||||
// ⭐ دریافت همه کاربرانی که عضو فعال باشگاه هستند
|
||||
// بدون محدودیت زمانی - همه اعضای فعال کلاب باید کمیسیون بگیرند
|
||||
var activeClubMemberUserIds = await _context.ClubMemberships
|
||||
.Where(c => c.IsActive)
|
||||
.Select(c => c.UserId)
|
||||
.ToHashSetAsync(cancellationToken);
|
||||
|
||||
// دریافت کاربران فعال در شبکه که عضو باشگاه هستند
|
||||
// نکته: شرط NetworkParentId.HasValue نداریم چون ریشه شبکه (اولین نفر) هم باید حساب بشه
|
||||
var usersInNetwork = await _context.Users
|
||||
.Where(x => x.NetworkParentId.HasValue)
|
||||
.Where(x => activeClubMemberUserIds.Contains(x.Id))
|
||||
.Select(x => new { x.Id })
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
@@ -47,7 +55,7 @@ public class CalculateWeeklyBalancesCommandHandler : IRequestHandler<CalculateWe
|
||||
.ToDictionaryAsync(x => x.UserId, cancellationToken);
|
||||
|
||||
var balancesList = new List<NetworkWeeklyBalance>();
|
||||
var calculatedAt = DateTime.UtcNow;
|
||||
var calculatedAt = DateTime.Now;
|
||||
|
||||
// خواندن یکباره Configuration ها (بهینهسازی - به جای N query)
|
||||
var configs = await _context.SystemConfigurations
|
||||
@@ -57,15 +65,15 @@ public class CalculateWeeklyBalancesCommandHandler : IRequestHandler<CalculateWe
|
||||
x.Key == "Commission.MaxWeeklyBalancesPerLeg" ||
|
||||
x.Key == "Commission.MaxNetworkLevel"))
|
||||
.ToDictionaryAsync(x => x.Key, x => x.Value, cancellationToken);
|
||||
|
||||
var activationFee = long.Parse(configs.GetValueOrDefault("Club.ActivationFee", "25000000"));
|
||||
var poolPercent = decimal.Parse(configs.GetValueOrDefault("Commission.WeeklyPoolContributionPercent", "20")) / 100m;
|
||||
|
||||
// var activationFee = long.Parse(configs.GetValueOrDefault("Club.ActivationFee", "25000000"));
|
||||
// var poolPercent = decimal.Parse(configs.GetValueOrDefault("Commission.WeeklyPoolContributionPercent", "20")) / 100m;
|
||||
// سقف تعادل هفتگی برای هر دست (نه کل) - 300 برای چپ + 300 برای راست = حداکثر 600 تعادل
|
||||
var maxBalancesPerLeg = int.Parse(configs.GetValueOrDefault("Commission.MaxWeeklyBalancesPerLeg", "300"));
|
||||
// حداکثر عمق شبکه برای شمارش اعضا (15 لول)
|
||||
var maxNetworkLevel = int.Parse(configs.GetValueOrDefault("Commission.MaxNetworkLevel", "15"));
|
||||
|
||||
foreach (var user in usersInNetwork)
|
||||
foreach (var user in usersInNetwork.OrderBy(o=>o.Id))
|
||||
{
|
||||
// دریافت باقیمانده هفته قبل
|
||||
var leftCarryover = 0;
|
||||
@@ -84,29 +92,34 @@ public class CalculateWeeklyBalancesCommandHandler : IRequestHandler<CalculateWe
|
||||
var leftTotal = leftNewMembers + leftCarryover;
|
||||
var rightTotal = rightNewMembers + rightCarryover;
|
||||
|
||||
// ✅ اصلاح شده: اعمال سقف روی هر دست جداگانه (نه روی کل)
|
||||
// سقف 300 برای دست چپ + 300 برای دست راست = حداکثر 600 تعادل در هفته
|
||||
var cappedLeftTotal = Math.Min(leftTotal, maxBalancesPerLeg);
|
||||
var cappedRightTotal = Math.Min(rightTotal, maxBalancesPerLeg);
|
||||
// ✅ مرحله 1: محاسبه تعادل اولیه (قبل از اعمال سقف)
|
||||
// تعادل = کمترین مقدار بین چپ و راست
|
||||
// مثال: چپ=500، راست=600 → تعادل=500
|
||||
var totalBalances = Math.Min(leftTotal, rightTotal);
|
||||
|
||||
// محاسبه تعادل (کمترین مقدار بعد از اعمال سقف)
|
||||
var totalBalances = Math.Min(cappedLeftTotal, cappedRightTotal);
|
||||
// ✅ مرحله 2: محاسبه باقیمانده (قبل از سقف)
|
||||
// باقیمانده = اضافهای که یک طرف دارد
|
||||
// مثال: چپ=500، راست=600، تعادل=500
|
||||
// → باقی چپ = 500-500 = 0
|
||||
// → باقی راست = 600-500 = 100 (میرود برای هفته بعد)
|
||||
var leftRemainder = leftTotal - totalBalances;
|
||||
var rightRemainder = rightTotal - totalBalances;
|
||||
|
||||
// محاسبه باقیمانده برای هفته بعد
|
||||
// باقیمانده = مقداری که از سقف هر دست رد شده
|
||||
// مثال: چپ=350، راست=450، سقف=300
|
||||
// cappedLeft = MIN(350, 300) = 300
|
||||
// cappedRight = MIN(450, 300) = 300
|
||||
// totalBalances = MIN(300, 300) = 300
|
||||
// leftRemainder = 350 - 300 = 50 (مازاد سقف)
|
||||
// rightRemainder = 450 - 300 = 150 (مازاد سقف)
|
||||
var leftRemainder = leftTotal - cappedLeftTotal;
|
||||
var rightRemainder = rightTotal - cappedRightTotal;
|
||||
// ✅ مرحله 3: اعمال سقف 300 (برای امتیاز نهایی)
|
||||
// از تعادل، فقط 300 از هر طرف حساب میشود
|
||||
// مثال: تعادل=500 → امتیاز=300
|
||||
// از چپ: 300 حساب میشود، 200 فلش میشود
|
||||
// از راست: 300 حساب میشود، 200 فلش میشود
|
||||
// جمع فلش = 400 (از بین میرود)
|
||||
var cappedBalances = Math.Min(totalBalances, maxBalancesPerLeg);
|
||||
|
||||
// ✅ مرحله 4: محاسبه فلش (از هر دو طرف)
|
||||
var flushedPerSide = totalBalances - cappedBalances; // 500-300=200
|
||||
var totalFlushed = flushedPerSide * 2; // 200×2=400 (از بین میرود)
|
||||
|
||||
// محاسبه سهم استخر (20% از مجموع فعالسازیهای جدید کل شبکه)
|
||||
// طبق گفته دکتر: کل افراد جدید در شبکه × هزینه فعالسازی × 20%
|
||||
var totalNewMembers = leftNewMembers + rightNewMembers;
|
||||
var weeklyPoolContribution = (long)(totalNewMembers * activationFee * poolPercent);
|
||||
// ⚠️ توجه: تعادل زیرمجموعه در این مرحله محاسبه نمیشه
|
||||
// چون هنوز تمام تعادلها محاسبه نشدن
|
||||
// بعد از ذخیره همه تعادلها، در یک حلقه دوم محاسبه خواهد شد
|
||||
|
||||
var balance = new NetworkWeeklyBalance
|
||||
{
|
||||
@@ -122,19 +135,26 @@ public class CalculateWeeklyBalancesCommandHandler : IRequestHandler<CalculateWe
|
||||
// مجموع
|
||||
LeftLegTotal = leftTotal,
|
||||
RightLegTotal = rightTotal,
|
||||
TotalBalances = totalBalances, // تعادل واقعی بعد از اعمال سقف روی هر دست
|
||||
TotalBalances = cappedBalances, // امتیاز نهایی بعد از اعمال سقف 300
|
||||
|
||||
// باقیمانده برای هفته بعد (مازاد سقف هر دست)
|
||||
// باقیمانده برای هفته بعد (اضافهای که یک طرف دارد)
|
||||
LeftLegRemainder = leftRemainder,
|
||||
RightLegRemainder = rightRemainder,
|
||||
|
||||
// فلش (از دست رفته)
|
||||
FlushedPerSide = flushedPerSide,
|
||||
TotalFlushed = totalFlushed,
|
||||
|
||||
// تعادل زیرمجموعه - فعلاً 0 (بعد از ذخیره همه تعادلها محاسبه میشه)
|
||||
SubordinateBalances = 0,
|
||||
|
||||
// فیلدهای قدیمی (deprecated) - برای سازگاری با کدهای قبلی
|
||||
#pragma warning disable CS0618
|
||||
LeftLegBalances = leftTotal,
|
||||
RightLegBalances = rightTotal,
|
||||
#pragma warning restore CS0618
|
||||
|
||||
WeeklyPoolContribution = weeklyPoolContribution,
|
||||
WeeklyPoolContribution = 0, // Pool در مرحله بعد محاسبه میشه
|
||||
CalculatedAt = calculatedAt,
|
||||
IsExpired = false
|
||||
};
|
||||
@@ -145,6 +165,26 @@ public class CalculateWeeklyBalancesCommandHandler : IRequestHandler<CalculateWe
|
||||
await _context.NetworkWeeklyBalances.AddRangeAsync(balancesList, cancellationToken);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// ⭐ مرحله 2: محاسبه تعادل زیرمجموعه برای هر کاربر (تا 15 لول)
|
||||
// حالا که همه تعادلها ذخیره شدن، میتونیم تعادل زیرمجموعه رو حساب کنیم
|
||||
var balancesDictionary = balancesList.ToDictionary(x => x.UserId);
|
||||
|
||||
foreach (var balance in balancesList)
|
||||
{
|
||||
var subordinateBalances = await CalculateSubordinateBalancesAsync(
|
||||
balance.UserId,
|
||||
balancesDictionary,
|
||||
maxNetworkLevel,
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
balance.SubordinateBalances = subordinateBalances;
|
||||
}
|
||||
|
||||
// ذخیره تعادلهای زیرمجموعه
|
||||
_context.NetworkWeeklyBalances.UpdateRange(balancesList);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return balancesList.Count;
|
||||
}
|
||||
|
||||
@@ -248,4 +288,64 @@ public class CalculateWeeklyBalancesCommandHandler : IRequestHandler<CalculateWe
|
||||
|
||||
return (weekStart, weekEnd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// محاسبه مجموع تعادلهای زیرمجموعه یک کاربر تا maxLevel لول پایینتر
|
||||
/// </summary>
|
||||
private async Task<int> CalculateSubordinateBalancesAsync(
|
||||
long userId,
|
||||
Dictionary<long, NetworkWeeklyBalance> allBalances,
|
||||
int maxLevel,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// پیدا کردن همه زیرمجموعهها تا maxLevel لول
|
||||
var subordinates = await GetSubordinatesRecursive(userId, 1, maxLevel, cancellationToken);
|
||||
|
||||
// جمع تعادلهای آنها
|
||||
var totalSubordinateBalances = 0;
|
||||
foreach (var subordinateId in subordinates)
|
||||
{
|
||||
if (allBalances.ContainsKey(subordinateId))
|
||||
{
|
||||
totalSubordinateBalances += allBalances[subordinateId].TotalBalances;
|
||||
}
|
||||
}
|
||||
|
||||
return totalSubordinateBalances;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// پیدا کردن بازگشتی زیرمجموعهها تا maxLevel لول
|
||||
/// </summary>
|
||||
private async Task<List<long>> GetSubordinatesRecursive(
|
||||
long userId,
|
||||
int currentLevel,
|
||||
int maxLevel,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// محدودیت عمق
|
||||
if (currentLevel > maxLevel)
|
||||
{
|
||||
return new List<long>();
|
||||
}
|
||||
|
||||
var result = new List<long>();
|
||||
|
||||
// پیدا کردن فرزندان مستقیم
|
||||
var children = await _context.Users
|
||||
.Where(x => x.NetworkParentId == userId)
|
||||
.Select(x => x.Id)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
result.AddRange(children);
|
||||
|
||||
// بازگشت برای هر فرزند
|
||||
foreach (var childId in children)
|
||||
{
|
||||
var grandChildren = await GetSubordinatesRecursive(childId, currentLevel + 1, maxLevel, cancellationToken);
|
||||
result.AddRange(grandChildren);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,11 +11,19 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
|
||||
|
||||
public async Task<long> Handle(CalculateWeeklyCommissionPoolCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
// بررسی وجود استخر قبلی
|
||||
// بررسی وجود استخر
|
||||
var existingPool = await _context.WeeklyCommissionPools
|
||||
.FirstOrDefaultAsync(x => x.WeekNumber == request.WeekNumber, cancellationToken);
|
||||
|
||||
if (existingPool != null && existingPool.IsCalculated && !request.ForceRecalculate)
|
||||
if (existingPool == null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"Pool هفته {request.WeekNumber} وجود ندارد. " +
|
||||
"Pool باید در هنگام فعالسازی باشگاه مشتریان ایجاد شده باشد"
|
||||
);
|
||||
}
|
||||
|
||||
if (existingPool.IsCalculated && !request.ForceRecalculate)
|
||||
{
|
||||
throw new InvalidOperationException($"استخر کمیسیون هفته {request.WeekNumber} قبلاً محاسبه شده است");
|
||||
}
|
||||
@@ -30,48 +38,122 @@ public class CalculateWeeklyCommissionPoolCommandHandler : IRequestHandler<Calcu
|
||||
throw new InvalidOperationException($"تعادلهای هفته {request.WeekNumber} هنوز محاسبه نشده است. ابتدا CalculateWeeklyBalances را اجرا کنید");
|
||||
}
|
||||
|
||||
// محاسبه مجموع مشارکتها در استخر
|
||||
var totalPoolAmount = weeklyBalances.Sum(x => x.WeeklyPoolContribution);
|
||||
// ⭐ Pool از قبل پُر شده (توسط ActivateClubMembership)
|
||||
var totalPoolAmount = existingPool.TotalPoolAmount;
|
||||
|
||||
// محاسبه مجموع Balances
|
||||
var totalBalances = weeklyBalances.Sum(x => x.TotalBalances);
|
||||
// محاسبه مجموع تعادلهای کل شبکه
|
||||
// نکته: SubordinateBalances اضافه نمیکنیم چون وقتی همه TotalBalances رو جمع میزنیم،
|
||||
// خودش شامل بالانسهای زیرمجموعهها هم هست (تکراری نشه)
|
||||
var totalBalancesInNetwork = weeklyBalances.Sum(x => x.TotalBalances);
|
||||
|
||||
// محاسبه ارزش هر Balance (تقسیم صحیح برای ریال)
|
||||
// محاسبه ارزش هر امتیاز
|
||||
long valuePerBalance = 0;
|
||||
if (totalBalances > 0)
|
||||
if (totalBalancesInNetwork > 0)
|
||||
{
|
||||
valuePerBalance = totalPoolAmount / totalBalances;
|
||||
valuePerBalance = totalPoolAmount / totalBalancesInNetwork;
|
||||
}
|
||||
|
||||
if (existingPool != null)
|
||||
{
|
||||
// بهروزرسانی
|
||||
existingPool.TotalPoolAmount = totalPoolAmount;
|
||||
existingPool.TotalBalances = totalBalances;
|
||||
existingPool.ValuePerBalance = valuePerBalance;
|
||||
existingPool.IsCalculated = true;
|
||||
existingPool.CalculatedAt = DateTime.UtcNow;
|
||||
// بهروزرسانی Pool
|
||||
existingPool.TotalBalances = totalBalancesInNetwork;
|
||||
existingPool.ValuePerBalance = valuePerBalance;
|
||||
existingPool.IsCalculated = true;
|
||||
existingPool.CalculatedAt = DateTime.Now;
|
||||
|
||||
_context.WeeklyCommissionPools.Update(existingPool);
|
||||
}
|
||||
else
|
||||
_context.WeeklyCommissionPools.Update(existingPool);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// حذف پرداختهای قبلی در صورت ForceRecalculate
|
||||
if (request.ForceRecalculate)
|
||||
{
|
||||
// ایجاد جدید
|
||||
var pool = new WeeklyCommissionPool
|
||||
var oldPayouts = await _context.UserCommissionPayouts
|
||||
.Where(p => p.WeekNumber == request.WeekNumber)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
if (oldPayouts.Any())
|
||||
{
|
||||
var oldPayoutIds = oldPayouts.Select(p => p.Id).ToList();
|
||||
|
||||
// ⭐ اول باید تاریخچهها حذف بشن (به خاطر FK constraint)
|
||||
var oldHistories = await _context.CommissionPayoutHistories
|
||||
.Where(h => oldPayoutIds.Contains(h.UserCommissionPayoutId))
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
if (oldHistories.Any())
|
||||
{
|
||||
_context.CommissionPayoutHistories.RemoveRange(oldHistories);
|
||||
}
|
||||
|
||||
// بعد پرداختها حذف میشن
|
||||
_context.UserCommissionPayouts.RemoveRange(oldPayouts);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
// ⭐ ثبت پرداخت برای کاربرانی که تعادل دارند
|
||||
// تعادل شخصی + زیرمجموعه قبلاً در CalculateWeeklyBalances محاسبه شده
|
||||
var payouts = new List<UserCommissionPayout>();
|
||||
|
||||
foreach (var balance in weeklyBalances)
|
||||
{
|
||||
// فقط تعادل شخصی (SubordinateBalances اضافه نمیشه چون در SUM کل شبکه خودش حساب میشه)
|
||||
var userBalance = balance.TotalBalances;
|
||||
|
||||
// اگر تعادل صفر است، نیازی به ثبت نیست
|
||||
if (userBalance <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// محاسبه مبلغ کمیسیون
|
||||
var totalAmount = (long)(userBalance * valuePerBalance);
|
||||
|
||||
var payout = new UserCommissionPayout
|
||||
{
|
||||
UserId = balance.UserId,
|
||||
WeekNumber = request.WeekNumber,
|
||||
TotalPoolAmount = totalPoolAmount,
|
||||
TotalBalances = totalBalances,
|
||||
WeeklyPoolId = existingPool.Id,
|
||||
BalancesEarned = userBalance,
|
||||
ValuePerBalance = valuePerBalance,
|
||||
IsCalculated = true,
|
||||
CalculatedAt = DateTime.UtcNow
|
||||
TotalAmount = totalAmount,
|
||||
Status = CommissionPayoutStatus.Pending,
|
||||
PaidAt = null,
|
||||
WithdrawalMethod = null,
|
||||
IbanNumber = null,
|
||||
WithdrawnAt = null
|
||||
};
|
||||
|
||||
await _context.WeeklyCommissionPools.AddAsync(pool, cancellationToken);
|
||||
existingPool = pool;
|
||||
payouts.Add(payout);
|
||||
}
|
||||
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
if (payouts.Any())
|
||||
{
|
||||
await _context.UserCommissionPayouts.AddRangeAsync(payouts, cancellationToken);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
// ثبت تاریخچه برای هر پرداخت
|
||||
var historyList = new List<CommissionPayoutHistory>();
|
||||
foreach (var payout in payouts)
|
||||
{
|
||||
var history = new CommissionPayoutHistory
|
||||
{
|
||||
UserCommissionPayoutId = payout.Id,
|
||||
UserId = payout.UserId,
|
||||
WeekNumber = request.WeekNumber,
|
||||
AmountBefore = 0,
|
||||
AmountAfter = payout.TotalAmount,
|
||||
OldStatus = default(CommissionPayoutStatus),
|
||||
NewStatus = CommissionPayoutStatus.Pending,
|
||||
Action = CommissionPayoutAction.Created,
|
||||
PerformedBy = "System",
|
||||
Reason = "پردازش خودکار کمیسیون هفتگی"
|
||||
};
|
||||
|
||||
historyList.Add(history);
|
||||
}
|
||||
|
||||
await _context.CommissionPayoutHistories.AddRangeAsync(historyList, cancellationToken);
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
return existingPool.Id;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class ProcessWithdrawalCommandHandler : IRequestHandler<ProcessWithdrawal
|
||||
}
|
||||
|
||||
var oldStatus = payout.Status;
|
||||
var now = DateTime.UtcNow;
|
||||
var now = DateTime.Now;
|
||||
|
||||
if (request.IsApproved)
|
||||
{
|
||||
|
||||
@@ -34,9 +34,9 @@ public class RejectWithdrawalCommandHandler : IRequestHandler<RejectWithdrawalCo
|
||||
// Update status to Cancelled (rejected)
|
||||
payout.Status = CommissionPayoutStatus.Cancelled;
|
||||
payout.ProcessedBy = _currentUser.GetPerformedBy();
|
||||
payout.ProcessedAt = DateTime.UtcNow;
|
||||
payout.ProcessedAt = DateTime.Now;
|
||||
payout.RejectionReason = request.Reason;
|
||||
payout.LastModified = DateTime.UtcNow;
|
||||
payout.LastModified = DateTime.Now;
|
||||
|
||||
// TODO: Add PayoutHistory record with rejection reason
|
||||
// var history = new CommissionPayoutHistory
|
||||
@@ -51,7 +51,7 @@ public class RejectWithdrawalCommandHandler : IRequestHandler<RejectWithdrawalCo
|
||||
// Action = (int)CommissionPayoutAction.Rejected,
|
||||
// PerformedBy = "Admin", // TODO: Get from authenticated user
|
||||
// Reason = request.Reason,
|
||||
// Created = DateTime.UtcNow
|
||||
// Created = DateTime.Now
|
||||
// };
|
||||
// _context.CommissionPayoutHistories.Add(history);
|
||||
|
||||
|
||||
@@ -13,17 +13,12 @@ public record TriggerWeeklyCalculationCommand : IRequest<TriggerWeeklyCalculatio
|
||||
public bool ForceRecalculate { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Skip balance calculation
|
||||
/// Skip balance calculation (Step 1)
|
||||
/// </summary>
|
||||
public bool SkipBalances { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Skip pool calculation
|
||||
/// </summary>
|
||||
public bool SkipPool { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Skip payout processing
|
||||
/// Skip pool calculation and payout processing (Step 2)
|
||||
/// </summary>
|
||||
public bool SkipPayouts { get; init; }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using CMSMicroservice.Application.Common.Interfaces;
|
||||
using CMSMicroservice.Application.CommissionCQ.Commands.CalculateWeeklyBalances;
|
||||
using CMSMicroservice.Application.CommissionCQ.Commands.CalculateWeeklyCommissionPool;
|
||||
using CMSMicroservice.Application.CommissionCQ.Commands.ProcessUserPayouts;
|
||||
|
||||
namespace CMSMicroservice.Application.CommissionCQ.Commands.TriggerWeeklyCalculation;
|
||||
|
||||
@@ -23,7 +22,7 @@ public class TriggerWeeklyCalculationCommandHandler : IRequestHandler<TriggerWee
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
var executionId = Guid.NewGuid().ToString();
|
||||
var startedAt = DateTime.UtcNow;
|
||||
var startedAt = DateTime.Now;
|
||||
|
||||
try
|
||||
{
|
||||
@@ -41,7 +40,7 @@ public class TriggerWeeklyCalculationCommandHandler : IRequestHandler<TriggerWee
|
||||
|
||||
var steps = new List<string>();
|
||||
|
||||
// Step 1: Calculate Weekly Balances
|
||||
// Step 1: Calculate Weekly Balances (تا 15 لول)
|
||||
if (!request.SkipBalances)
|
||||
{
|
||||
await _mediator.Send(new CalculateWeeklyBalancesCommand
|
||||
@@ -52,25 +51,15 @@ public class TriggerWeeklyCalculationCommandHandler : IRequestHandler<TriggerWee
|
||||
steps.Add("محاسبه امتیازات هفتگی");
|
||||
}
|
||||
|
||||
// Step 2: Calculate Weekly Commission Pool
|
||||
if (!request.SkipPool)
|
||||
// Step 2: Calculate Pool & Process Payouts (محاسبه استخر + پرداخت کاربران)
|
||||
if (!request.SkipPayouts)
|
||||
{
|
||||
await _mediator.Send(new CalculateWeeklyCommissionPoolCommand
|
||||
{
|
||||
WeekNumber = request.WeekNumber
|
||||
}, cancellationToken);
|
||||
steps.Add("محاسبه استخر کمیسیون");
|
||||
}
|
||||
|
||||
// Step 3: Process User Payouts
|
||||
if (!request.SkipPayouts)
|
||||
{
|
||||
await _mediator.Send(new ProcessUserPayoutsCommand
|
||||
{
|
||||
WeekNumber = request.WeekNumber,
|
||||
ForceReprocess = request.ForceRecalculate
|
||||
ForceRecalculate = request.ForceRecalculate
|
||||
}, cancellationToken);
|
||||
steps.Add("پردازش پرداختهای کاربران");
|
||||
steps.Add("محاسبه استخر و پرداخت کاربران");
|
||||
}
|
||||
|
||||
return new TriggerWeeklyCalculationResponseDto
|
||||
|
||||
Reference in New Issue
Block a user