feat: Enhance withdrawal request handling with additional fields and network level configurations
This commit is contained in:
+48
-29
@@ -54,12 +54,16 @@ public class CalculateWeeklyBalancesCommandHandler : IRequestHandler<CalculateWe
|
||||
.Where(x => x.IsActive && (
|
||||
x.Key == "Club.ActivationFee" ||
|
||||
x.Key == "Commission.WeeklyPoolContributionPercent" ||
|
||||
x.Key == "Commission.MaxWeeklyBalancesPerUser"))
|
||||
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 maxWeeklyBalances = int.Parse(configs.GetValueOrDefault("Commission.MaxWeeklyBalancesPerUser", "300"));
|
||||
// سقف تعادل هفتگی برای هر دست (نه کل) - 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)
|
||||
{
|
||||
@@ -72,31 +76,32 @@ public class CalculateWeeklyBalancesCommandHandler : IRequestHandler<CalculateWe
|
||||
rightCarryover = previousWeekCarryovers[user.Id].RightLegRemainder;
|
||||
}
|
||||
|
||||
// محاسبه تعداد اعضای جدید در این هفته (فقط فرزندان مستقیم که در این هفته فعال شدند)
|
||||
var leftNewMembers = await CountNewMembersInLeg(user.Id, NetworkLeg.Left, request.WeekNumber, cancellationToken);
|
||||
var rightNewMembers = await CountNewMembersInLeg(user.Id, NetworkLeg.Right, request.WeekNumber, cancellationToken);
|
||||
// محاسبه تعداد اعضای جدید در این هفته (تا maxNetworkLevel لول پایینتر)
|
||||
var leftNewMembers = await CountNewMembersInLeg(user.Id, NetworkLeg.Left, request.WeekNumber, maxNetworkLevel, cancellationToken);
|
||||
var rightNewMembers = await CountNewMembersInLeg(user.Id, NetworkLeg.Right, request.WeekNumber, maxNetworkLevel, cancellationToken);
|
||||
|
||||
// محاسبه مجموع هر پا (جدید + باقیمانده)
|
||||
var leftTotal = leftNewMembers + leftCarryover;
|
||||
var rightTotal = rightNewMembers + rightCarryover;
|
||||
|
||||
// محاسبه تعادل (کمترین مقدار)
|
||||
var totalBalances = Math.Min(leftTotal, rightTotal);
|
||||
// ✅ اصلاح شده: اعمال سقف روی هر دست جداگانه (نه روی کل)
|
||||
// سقف 300 برای دست چپ + 300 برای دست راست = حداکثر 600 تعادل در هفته
|
||||
var cappedLeftTotal = Math.Min(leftTotal, maxBalancesPerLeg);
|
||||
var cappedRightTotal = Math.Min(rightTotal, maxBalancesPerLeg);
|
||||
|
||||
// اعمال محدودیت سقف تعادل هفتگی (مثلاً 300)
|
||||
var cappedBalances = Math.Min(totalBalances, maxWeeklyBalances);
|
||||
// محاسبه تعادل (کمترین مقدار بعد از اعمال سقف)
|
||||
var totalBalances = Math.Min(cappedLeftTotal, cappedRightTotal);
|
||||
|
||||
// محاسبه باقیمانده برای هفته بعد (Flash Out Logic)
|
||||
// محاسبه باقیمانده برای هفته بعد
|
||||
// باقیمانده = مقداری که از سقف هر دست رد شده
|
||||
// مثال: چپ=350، راست=450، سقف=300
|
||||
// تعادل پرداختی = MIN(MIN(350, 450), 300) = 300
|
||||
// از هر طرف نصف تعادل پرداختی کسر میشود: 300÷2 = 150
|
||||
// باقیمانده چپ: 350 - 150 = 200
|
||||
// باقیمانده راست: 450 - 150 = 300
|
||||
var balancesToPay = cappedBalances; // تعادل نهایی قابل پرداخت
|
||||
var balancesConsumedPerSide = balancesToPay / 2; // هر طرف نصف تعادل را مصرف میکند
|
||||
|
||||
var leftRemainder = leftTotal - balancesConsumedPerSide;
|
||||
var rightRemainder = rightTotal - balancesConsumedPerSide;
|
||||
// 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;
|
||||
|
||||
// محاسبه سهم استخر (20% از مجموع فعالسازیهای جدید کل شبکه)
|
||||
// طبق گفته دکتر: کل افراد جدید در شبکه × هزینه فعالسازی × 20%
|
||||
@@ -117,9 +122,9 @@ public class CalculateWeeklyBalancesCommandHandler : IRequestHandler<CalculateWe
|
||||
// مجموع
|
||||
LeftLegTotal = leftTotal,
|
||||
RightLegTotal = rightTotal,
|
||||
TotalBalances = cappedBalances, // تعادل واقعی بعد از اعمال سقف
|
||||
TotalBalances = totalBalances, // تعادل واقعی بعد از اعمال سقف روی هر دست
|
||||
|
||||
// باقیمانده برای هفته بعد
|
||||
// باقیمانده برای هفته بعد (مازاد سقف هر دست)
|
||||
LeftLegRemainder = leftRemainder,
|
||||
RightLegRemainder = rightRemainder,
|
||||
|
||||
@@ -165,24 +170,38 @@ public class CalculateWeeklyBalancesCommandHandler : IRequestHandler<CalculateWe
|
||||
|
||||
/// <summary>
|
||||
/// شمارش اعضای جدیدی که در این هفته به یک پا اضافه شدند
|
||||
/// فقط فرزندان مستقیم که ActivatedAt آنها در این هفته است
|
||||
/// تا maxLevel لول پایینتر شمارش میشود
|
||||
/// </summary>
|
||||
private async Task<int> CountNewMembersInLeg(long userId, NetworkLeg leg, string weekNumber, CancellationToken cancellationToken)
|
||||
private async Task<int> CountNewMembersInLeg(long userId, NetworkLeg leg, string weekNumber, int maxLevel, CancellationToken cancellationToken)
|
||||
{
|
||||
// تبدیل WeekNumber به بازه تاریخی
|
||||
var (startDate, endDate) = GetWeekDateRange(weekNumber);
|
||||
|
||||
// شمارش تمام اعضای زیرمجموعه که در این هفته فعال شدند
|
||||
var count = await CountNewMembersRecursive(userId, leg, startDate, endDate, cancellationToken);
|
||||
// شمارش تمام اعضای زیرمجموعه که در این هفته فعال شدند (تا maxLevel لول)
|
||||
var count = await CountNewMembersRecursive(userId, leg, startDate, endDate, 0, maxLevel, cancellationToken);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// شمارش بازگشتی اعضای جدید در یک پا
|
||||
/// محدودیت عمق: تا maxLevel لول پایینتر شمارش میشود
|
||||
/// </summary>
|
||||
private async Task<int> CountNewMembersRecursive(long userId, NetworkLeg leg, DateTime startDate, DateTime endDate, CancellationToken cancellationToken)
|
||||
private async Task<int> CountNewMembersRecursive(
|
||||
long userId,
|
||||
NetworkLeg leg,
|
||||
DateTime startDate,
|
||||
DateTime endDate,
|
||||
int currentLevel,
|
||||
int maxLevel,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
// ⭐ محدودیت عمق: اگر به حداکثر لول رسیدیم، توقف
|
||||
if (currentLevel >= maxLevel)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// پیدا کردن فرزند مستقیم در پای مورد نظر
|
||||
var child = await _context.Users
|
||||
.FirstOrDefaultAsync(x => x.NetworkParentId == userId && x.LegPosition == leg, cancellationToken);
|
||||
@@ -203,9 +222,9 @@ public class CalculateWeeklyBalancesCommandHandler : IRequestHandler<CalculateWe
|
||||
count = 1;
|
||||
}
|
||||
|
||||
// جمع کردن اعضای جدید از پای چپ و راست فرزند
|
||||
var childLeft = await CountNewMembersRecursive(child.Id, NetworkLeg.Left, startDate, endDate, cancellationToken);
|
||||
var childRight = await CountNewMembersRecursive(child.Id, NetworkLeg.Right, startDate, endDate, cancellationToken);
|
||||
// جمع کردن اعضای جدید از پای چپ و راست فرزند (با افزایش لول)
|
||||
var childLeft = await CountNewMembersRecursive(child.Id, NetworkLeg.Left, startDate, endDate, currentLevel + 1, maxLevel, cancellationToken);
|
||||
var childRight = await CountNewMembersRecursive(child.Id, NetworkLeg.Right, startDate, endDate, currentLevel + 1, maxLevel, cancellationToken);
|
||||
|
||||
return count + childLeft + childRight;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user