feat: add IsActive field to UserClubFeatures for admin management
This commit is contained in:
+111
-29
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user