Implement Persian Date Conversion and Enhance User Network Information Service
- Added PersianDateTimeService for converting Gregorian dates to Persian format in the BackOffice frontend. - Updated multiple frontend pages (Dashboard, UserPayouts, WorkerControl, UserNetworkInfo) to utilize the new Persian date service. - Enhanced GetUserNetworkPositionDto with 28+ new fields for comprehensive user network data. - Updated GetUserNetworkPositionQueryHandler to include new methods for calculating network statistics. - Modified Protobuf messages to accommodate the new fields, increasing from 14 to 42. - Refined week number calculation algorithm to ensure consistency across C# and SQL implementations. - Created new CSV and Excel files for binary plan calculations. - Ensured all changes are tested and validated for accuracy and performance.
This commit is contained in:
@@ -1,16 +1,36 @@
|
||||
# Balance Calculation with Carryover Logic - Complete Guide
|
||||
|
||||
**Date**: 2025-12-01
|
||||
**Last Updated**: 2025-12-04 (⚠️ تغییر مهم: سقف 300 برای هر دست، نه کل)
|
||||
**Status**: ✅ Implemented (نیاز به اصلاح سقف دارد)
|
||||
**Last Updated**: 2025-12-09 (✅ اصلاح نهایی: محاسبات تعادل و فلش)
|
||||
**Status**: ✅ Fully Implemented & Verified
|
||||
**Migration**: `UpdateNetworkWeeklyBalanceWithCarryover`
|
||||
|
||||
---
|
||||
|
||||
## ⚠️ اصلاحیه مهم بیزینس (2025-12-04)
|
||||
## ✅ آخرین بهروزرسانی (2025-12-09)
|
||||
|
||||
### مشکل شناسایی شده:
|
||||
در پیادهسازی فعلی، سقف تعادل هفتگی **300 کل** در نظر گرفته شده بود. اما طبق قانون صحیح بیزینس:
|
||||
### تغییرات اعمال شده:
|
||||
کد محاسبه تعادل با توضیحات دقیق بیزینس تطبیق داده شد:
|
||||
|
||||
1. ✅ **ترتیب محاسبات اصلاح شد**:
|
||||
- اول تعادل اولیه محاسبه میشود
|
||||
- بعد باقیمانده (برای هفته بعد)
|
||||
- سپس سقف 300 اعمال میشود
|
||||
- در نهایت فلش محاسبه میشود
|
||||
|
||||
2. ✅ **فلش از هر دو طرف**:
|
||||
- اگر تعادل > 300 باشد
|
||||
- از چپ: (تعادل - 300) فلش میشود
|
||||
- از راست: (تعادل - 300) فلش میشود
|
||||
- جمع فلش = (تعادل - 300) × 2
|
||||
|
||||
3. ✅ **باقیمانده جداگانه ذخیره میشود**:
|
||||
- `LeftLegRemainder`: باقیمانده دست چپ
|
||||
- `RightLegRemainder`: باقیمانده دست راست
|
||||
|
||||
---
|
||||
|
||||
## 📋 قوانین اصلی بیزینس
|
||||
|
||||
| توضیح | منطق فعلی (اشتباه) | منطق صحیح |
|
||||
|-------|---------------------|-----------|
|
||||
@@ -71,10 +91,10 @@ Key = "Commission.MaxWeeklyBalancesPerLeg", Value = "300"
|
||||
// تمام مقادیر از جدول SystemConfigurations خوانده میشوند
|
||||
Club.ActivationFee = 25,000,000 ریال (هزینه فعالسازی)
|
||||
Commission.WeeklyPoolContributionPercent = 20% (سهم استخر)
|
||||
Commission.MaxWeeklyBalancesPerLeg = 300 (⚠️ سقف تعادل هفتگی - هر دست)
|
||||
Commission.MaxWeeklyBalancesPerLeg = 300 (✅ سقف امتیاز نهایی)
|
||||
```
|
||||
|
||||
**توجه:** کلید قدیمی `MaxWeeklyBalancesPerUser` باید به `MaxWeeklyBalancesPerLeg` تغییر کند.
|
||||
**نکته مهم**: سقف 300 روی **امتیاز نهایی** اعمال میشود، نه روی تعادل اولیه!
|
||||
|
||||
### **Pool Contribution Calculation:**
|
||||
|
||||
@@ -90,38 +110,52 @@ weeklyPoolContribution = totalNewMembers × activationFee × poolPercent
|
||||
|
||||
---
|
||||
|
||||
## 🚫 MaxWeeklyBalances Cap (محدودیت سقف - هر دست)
|
||||
## 🚫 MaxWeeklyBalances Cap (محدودیت سقف 300)
|
||||
|
||||
### **Logic (صحیح):**
|
||||
### **Logic صحیح (بهروز شده 2025-12-09):**
|
||||
|
||||
```csharp
|
||||
// ⚠️ سقف روی هر دست جداگانه اعمال میشود
|
||||
cappedLeftTotal = MIN(leftTotal, maxBalancesPerLeg) // 300
|
||||
cappedRightTotal = MIN(rightTotal, maxBalancesPerLeg) // 300
|
||||
// ✅ مرحله 1: محاسبه تعادل اولیه (بدون سقف)
|
||||
totalBalances = MIN(leftTotal, rightTotal)
|
||||
|
||||
// تعادل = کمترین مقدار بعد از اعمال سقف
|
||||
totalBalances = MIN(cappedLeftTotal, cappedRightTotal)
|
||||
// ✅ مرحله 2: محاسبه باقیمانده برای هفته بعد
|
||||
leftRemainder = leftTotal - totalBalances
|
||||
rightRemainder = rightTotal - totalBalances
|
||||
|
||||
// باقیمانده = مقدار قبل از سقف - سقف (نه از totalBalances)
|
||||
leftRemainder = leftTotal - cappedLeftTotal
|
||||
rightRemainder = rightTotal - cappedRightTotal
|
||||
// ✅ مرحله 3: اعمال سقف 300 (برای امتیاز نهایی)
|
||||
cappedBalances = MIN(totalBalances, 300)
|
||||
|
||||
// ✅ مرحله 4: محاسبه فلش (از هر دو طرف)
|
||||
flushedPerSide = totalBalances - cappedBalances
|
||||
totalFlushed = flushedPerSide × 2
|
||||
```
|
||||
|
||||
### **Example (جدید):**
|
||||
### **Example (مثال کامل):**
|
||||
|
||||
```
|
||||
Week 5:
|
||||
leftTotal = 350, rightTotal = 400
|
||||
maxBalancesPerLeg = 300
|
||||
leftTotal = 500, rightTotal = 600
|
||||
|
||||
cappedLeftTotal = MIN(350, 300) = 300
|
||||
cappedRightTotal = MIN(400, 300) = 300
|
||||
مرحله 1️⃣: تعادل اولیه
|
||||
totalBalances = MIN(500, 600) = 500 ✅
|
||||
|
||||
totalBalances = MIN(300, 300) = 300 ✅
|
||||
مرحله 2️⃣: باقیمانده برای هفته بعد
|
||||
leftRemainder = 500 - 500 = 0 ✅
|
||||
rightRemainder = 600 - 500 = 100 ✅
|
||||
|
||||
// باقیمانده = اضافهای که از سقف رد شده
|
||||
leftRemainder = 350 - 300 = 50
|
||||
rightRemainder = 400 - 300 = 100
|
||||
مرحله 3️⃣: اعمال سقف
|
||||
cappedBalances = MIN(500, 300) = 300 ✅
|
||||
|
||||
مرحله 4️⃣: محاسبه فلش
|
||||
flushedPerSide = 500 - 300 = 200
|
||||
از چپ: 200 فلش میشود
|
||||
از راست: 200 فلش میشود
|
||||
totalFlushed = 200 × 2 = 400 ✅
|
||||
|
||||
نتیجه نهایی:
|
||||
✅ امتیاز این هفته: 300
|
||||
✅ باقیمانده چپ: 0
|
||||
✅ باقیمانده راست: 100
|
||||
✅ جمع فلش: 400 (از بین میرود)
|
||||
```
|
||||
|
||||
### **مقایسه منطق قدیم vs جدید:**
|
||||
@@ -147,24 +181,34 @@ leftRemainder = leftTotal - cappedLeftTotal // باقیمانده از سقف
|
||||
|
||||
```csharp
|
||||
// محاسبه تعداد کل اعضا در هر پا
|
||||
leftLegBalances = CountAllMembers(userId, Left);
|
||||
rightLegBalances = CountAllMembers(userId, Right);
|
||||
## ✅ **Current (Correct) Logic - Updated 2025-12-09:**
|
||||
|
||||
// تعادل = کمترین مقدار
|
||||
TotalBalances = MIN(leftLegBalances, rightLegBalances);
|
||||
### **Formula (4 مرحله):**
|
||||
```
|
||||
// مرحله 1: جمع با هفته قبل
|
||||
leftTotal = leftNewMembers + leftCarryover
|
||||
rightTotal = rightNewMembers + rightCarryover
|
||||
|
||||
// مرحله 2: محاسبه تعادل اولیه
|
||||
totalBalances = MIN(leftTotal, rightTotal)
|
||||
|
||||
// مرحله 3: محاسبه باقیمانده برای هفته بعد
|
||||
leftRemainder = leftTotal - totalBalances
|
||||
rightRemainder = rightTotal - totalBalances
|
||||
|
||||
// مرحله 4: اعمال سقف 300
|
||||
cappedBalances = MIN(totalBalances, 300)
|
||||
flushedPerSide = totalBalances - cappedBalances
|
||||
totalFlushed = flushedPerSide × 2
|
||||
```
|
||||
|
||||
**مشکلات:**
|
||||
1. تعداد کل اعضا را میشمارد (نه فقط جدیدها)
|
||||
2. باقیمانده هفته قبل را نادیده میگیرد
|
||||
3. هر هفته از صفر شروع میکند
|
||||
|
||||
---
|
||||
|
||||
## ✅ **Current (Correct) Logic:**
|
||||
|
||||
### **Formula:**
|
||||
```
|
||||
### **Key Principles:**
|
||||
1. **Only count NEW members** activated in current week
|
||||
2. **Add carryover** from previous week (جداگانه چپ و راست)
|
||||
3. **Calculate remainder** for next week (قبل از سقف)
|
||||
4. **Apply cap 300** on final score (بعد از تعادل)
|
||||
5. **Flush from both sides** if balance > 300
|
||||
6. **Recursive counting** through entire tree structure
|
||||
leftTotal = leftNewMembers + leftCarryover
|
||||
rightTotal = rightNewMembers + rightCarryover
|
||||
|
||||
|
||||
Reference in New Issue
Block a user