feat: Enhance withdrawal request handling with additional fields and network level configurations
This commit is contained in:
@@ -37,24 +37,75 @@ public class ProcessUserPayoutsCommandHandler : IRequestHandler<ProcessUserPayou
|
||||
await _context.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
// دریافت تعادلهای هفتگی
|
||||
var weeklyBalances = await _context.NetworkWeeklyBalances
|
||||
// ⭐ خواندن MaxNetworkLevel از Config
|
||||
var maxNetworkLevelConfig = await _context.SystemConfigurations
|
||||
.Where(x => x.Key == "Commission.MaxNetworkLevel" && x.IsActive)
|
||||
.Select(x => x.Value)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
var maxNetworkLevel = int.Parse(maxNetworkLevelConfig ?? "15");
|
||||
|
||||
// دریافت همه تعادلهای هفتگی (شامل صفرها هم برای محاسبه زیرمجموعه)
|
||||
var allWeeklyBalances = await _context.NetworkWeeklyBalances
|
||||
.Where(x => x.WeekNumber == request.WeekNumber)
|
||||
.ToDictionaryAsync(x => x.UserId, cancellationToken);
|
||||
|
||||
// دریافت کاربرانی که تعادل > 0 دارند (یا زیرمجموعهشان دارد)
|
||||
var usersWithBalances = await _context.NetworkWeeklyBalances
|
||||
.Where(x => x.WeekNumber == request.WeekNumber && x.TotalBalances > 0)
|
||||
.Select(x => x.UserId)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
// پیدا کردن تمام کاربرانی که باید کمیسیون بگیرند (شامل والدین)
|
||||
var usersToProcess = new HashSet<long>(usersWithBalances);
|
||||
|
||||
// اضافه کردن والدین تا 15 لول بالاتر
|
||||
foreach (var userId in usersWithBalances)
|
||||
{
|
||||
var ancestors = await GetAncestors(userId, maxNetworkLevel, cancellationToken);
|
||||
foreach (var ancestorId in ancestors)
|
||||
{
|
||||
usersToProcess.Add(ancestorId);
|
||||
}
|
||||
}
|
||||
|
||||
var payoutsList = new List<UserCommissionPayout>();
|
||||
|
||||
foreach (var balance in weeklyBalances)
|
||||
foreach (var userId in usersToProcess)
|
||||
{
|
||||
// ⭐ محاسبه تعادل شخصی
|
||||
var personalBalances = 0;
|
||||
if (allWeeklyBalances.ContainsKey(userId))
|
||||
{
|
||||
personalBalances = allWeeklyBalances[userId].TotalBalances;
|
||||
}
|
||||
|
||||
// ⭐ محاسبه مجموع تعادلهای زیرمجموعه تا maxNetworkLevel لول
|
||||
var subordinateBalances = await CalculateSubordinateBalancesAsync(
|
||||
userId,
|
||||
request.WeekNumber,
|
||||
allWeeklyBalances,
|
||||
maxNetworkLevel,
|
||||
cancellationToken
|
||||
);
|
||||
|
||||
// ⭐ مجموع تعادل = شخصی + زیرمجموعه
|
||||
var totalBalancesWithSubordinates = personalBalances + subordinateBalances;
|
||||
|
||||
// اگر مجموع تعادل صفر است، نیازی به ثبت نیست
|
||||
if (totalBalancesWithSubordinates <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// محاسبه مبلغ کمیسیون
|
||||
var totalAmount = (long)(balance.TotalBalances * pool.ValuePerBalance);
|
||||
var totalAmount = (long)(totalBalancesWithSubordinates * pool.ValuePerBalance);
|
||||
|
||||
var payout = new UserCommissionPayout
|
||||
{
|
||||
UserId = balance.UserId,
|
||||
UserId = userId,
|
||||
WeekNumber = request.WeekNumber,
|
||||
WeeklyPoolId = pool.Id,
|
||||
BalancesEarned = balance.TotalBalances,
|
||||
BalancesEarned = totalBalancesWithSubordinates, // ⭐ شامل زیرمجموعه
|
||||
ValuePerBalance = pool.ValuePerBalance,
|
||||
TotalAmount = totalAmount,
|
||||
Status = CommissionPayoutStatus.Pending,
|
||||
@@ -96,4 +147,92 @@ public class ProcessUserPayoutsCommandHandler : IRequestHandler<ProcessUserPayou
|
||||
|
||||
return payoutsList.Count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// پیدا کردن والدین یک کاربر تا N لول بالاتر
|
||||
/// </summary>
|
||||
private async Task<List<long>> GetAncestors(long userId, int maxLevels, CancellationToken cancellationToken)
|
||||
{
|
||||
var ancestors = new List<long>();
|
||||
var currentUserId = userId;
|
||||
|
||||
for (int level = 0; level < maxLevels; level++)
|
||||
{
|
||||
var user = await _context.Users
|
||||
.Where(x => x.Id == currentUserId)
|
||||
.Select(x => x.NetworkParentId)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
if (user == null || !user.HasValue)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
ancestors.Add(user.Value);
|
||||
currentUserId = user.Value;
|
||||
}
|
||||
|
||||
return ancestors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// محاسبه مجموع تعادلهای زیرمجموعه یک کاربر تا N لول پایینتر
|
||||
/// </summary>
|
||||
private async Task<int> CalculateSubordinateBalancesAsync(
|
||||
long userId,
|
||||
string weekNumber,
|
||||
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>
|
||||
/// پیدا کردن بازگشتی زیرمجموعهها تا N لول
|
||||
/// </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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user