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:
@@ -0,0 +1,329 @@
|
||||
# توضیحات جدید بیزینس - 2025-12-08
|
||||
|
||||
**تاریخ دریافت**: 2025-12-08
|
||||
**وضعیت**: نیاز به تطبیق با کد و داکیومنت موجود
|
||||
**منبع**: توضیحات شفاهی از صاحب پروژه
|
||||
|
||||
---
|
||||
|
||||
## 1️⃣ فعالسازی کاربر و نمایش لینک معرفی
|
||||
|
||||
### قوانین فعالسازی:
|
||||
کاربر زمانی میتواند **لینک معرفی** خود را ببیند که:
|
||||
- ✅ وام خود را از **دایا** گرفته باشه
|
||||
- ✅ یا **پرداخت مستقیم 56 میلیون تومان** انجام داده باشه
|
||||
|
||||
### عضویت باشگاه مشتریان (الزامی):
|
||||
در هر دو حالت بالا:
|
||||
1. کاربر **اجباراً** باید عضو باشگاه مشتریان بشه
|
||||
2. دیالوگ باشگاه مشتریان و امضای قرارداد **الزامی** است
|
||||
3. **تا زمانی که این کار انجام نشه** → لینک معرفی نمایش داده نمیشود
|
||||
|
||||
### فرآیند:
|
||||
```
|
||||
کاربر ثبت نام میکنه
|
||||
↓
|
||||
پرداخت 56M (دایا یا مستقیم)
|
||||
↓
|
||||
دیالوگ باشگاه مشتریان (الزامی) ← امضای قرارداد
|
||||
↓
|
||||
لینک معرفی نمایش داده میشود
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2️⃣ محاسبه تعادل (Balance) شبکه
|
||||
|
||||
### قانون اصلی:
|
||||
**هر نود شبکه = یک تعادل**
|
||||
|
||||
```
|
||||
تعداد تعادل = MIN(دست راست، دست چپ)
|
||||
```
|
||||
|
||||
### حالت عادی (زیر 300 تعادل):
|
||||
- اگر دست راست = 200 نفر و دست چپ = 150 نفر
|
||||
- ✅ تعادل = MIN(200, 150) = **150 امتیاز**
|
||||
- ✅ باقیمانده راست = 200 - 150 = **50** → برای هفته بعد
|
||||
|
||||
### حالت بالای 300 تعادل (سقف):
|
||||
اگر مجموع کاربران جفت دست یک نفر **بیشتر از 600 نفر** باشد:
|
||||
|
||||
#### مثال:
|
||||
```
|
||||
دست راست = 600 نفر
|
||||
دست چپ = 400 نفر
|
||||
```
|
||||
|
||||
**مرحله 1: محاسبه تعادل اولیه**
|
||||
- تعادل = MIN(600, 400) = 400
|
||||
|
||||
**مرحله 2: محاسبه باقیمانده اولیه**
|
||||
- باقیمانده راست = 600 - 400 = 200 → **میرود برای هفته بعد**
|
||||
|
||||
**مرحله 3: اعمال سقف 300**
|
||||
- چون تعادل (400) > 300 → فقط **300 امتیاز** حساب میشود
|
||||
- از دست راست: 100 نفر فلش میشود
|
||||
- از دست چپ: 100 نفر فلش میشود
|
||||
- **مجموع 200 نفر فلش میشود** (دیگه هیچ جا حساب نمیشن)
|
||||
|
||||
**نتیجه نهایی:**
|
||||
- امتیاز این هفته: **300**
|
||||
- باقیمانده راست برای هفته بعد: **200** (این مجزا از فلش است)
|
||||
- فلش شده (از بین رفته): **200** (100 چپ + 100 راست)
|
||||
|
||||
### نکته مهم:
|
||||
> باقیماندهای که از هفته قبل میآید **فلش نمیشود**، فقط اضافهای که بزرگتر از 300 تعادل است فلش میشود.
|
||||
|
||||
---
|
||||
|
||||
## 3️⃣ محاسبه تعادل بازگشتی (Recursive Balance)
|
||||
|
||||
### قانون مهم:
|
||||
**هر نفر تعداد تعادلهاش فقط برای خودش حساب میشه**
|
||||
|
||||
### مثال درخت:
|
||||
```
|
||||
کاربر 1
|
||||
/ \
|
||||
کاربر 2 کاربر 3
|
||||
/ \
|
||||
کاربر 4 کاربر 5
|
||||
```
|
||||
|
||||
### محاسبات:
|
||||
1. **کاربر 2**:
|
||||
- جذب کرده: کاربر 4 و کاربر 5
|
||||
- تعادل کاربر 2 = MIN(1, 1) = **1 تعادل**
|
||||
|
||||
2. **کاربر 1**:
|
||||
- دست راست: کاربر 2 = 1 نفر
|
||||
- دست چپ: کاربر 3 = 1 نفر
|
||||
- تعادل کاربر 1 = MIN(1, 1) = **1 تعادل**
|
||||
|
||||
### ⚠️ نکته کلیدی:
|
||||
**کاربر 1 پورسانت کاربر 4 و 5 را نمیگیرد!**
|
||||
|
||||
چرا؟ چون:
|
||||
- کاربر 3 کسی را جذب نکرده
|
||||
- برای اینکه کاربر 1 از تعادل کاربر 4 و 5 بهرهمند شود
|
||||
- کاربر 3 حتماً باید **دو نفر** جذب کند
|
||||
|
||||
### مثال تصحیح شده:
|
||||
```
|
||||
کاربر 1
|
||||
/ \
|
||||
کاربر 2 کاربر 3
|
||||
/ \ / \
|
||||
کاربر 4 5 کاربر 6 7
|
||||
```
|
||||
|
||||
حالا:
|
||||
- کاربر 3: تعادل = MIN(1, 1) = 1
|
||||
- کاربر 2: تعادل = MIN(1, 1) = 1
|
||||
- **کاربر 1**: تعادل = MIN(2, 2) = **2 تعادل** ✅
|
||||
|
||||
---
|
||||
|
||||
## 4️⃣ ارزش امتیاز و توزیع کمیسیون
|
||||
|
||||
### فرمول:
|
||||
```
|
||||
ارزش هر امتیاز = (مجموع مبلغ صندوق) ÷ (تعداد کل تعادلها)
|
||||
```
|
||||
|
||||
### مبلغ صندوق:
|
||||
هر کاربری که 56 میلیون تومان واریز میکند:
|
||||
- **25 میلیون تومان** وارد صندوق میشود
|
||||
|
||||
### مثال محاسبه:
|
||||
```
|
||||
صندوق هفته = 175 میلیون تومان (7 نفر × 25M)
|
||||
مجموع تعادلهای سیستم = 50 امتیاز
|
||||
|
||||
ارزش هر امتیاز = 175,000,000 ÷ 50 = 3,500,000 ریال
|
||||
```
|
||||
|
||||
اگر یک کاربر **5 تعادل** داشته باشد:
|
||||
```
|
||||
کمیسیون = 5 × 3,500,000 = 17,500,000 ریال
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5️⃣ حذف خودکار کاربران غیرفعال (Worker جدید مورد نیاز)
|
||||
|
||||
### قانون:
|
||||
کاربری که تا **2 هفته** بعد از ثبت نام:
|
||||
- ❌ وام دایا را نگرفته
|
||||
- ❌ 56 میلیون تومان مستقیم واریز نکرده
|
||||
|
||||
→ **به صورت اتوماتیک حذف میشود**
|
||||
|
||||
### Worker مورد نیاز:
|
||||
```csharp
|
||||
// نام پیشنهادی: DeleteInactiveUsersWorker
|
||||
// زمان اجرا: روزانه یک بار (مثلاً 3 صبح)
|
||||
|
||||
شبهکد:
|
||||
1. کاربرانی که CreatedAt < (Now - 14 روز)
|
||||
2. IsActive == false (یعنی نه دایا گرفته، نه پرداخت مستقیم)
|
||||
3. ClubMembershipId == null
|
||||
4. حذف کاربر
|
||||
5. آزاد کردن جایگاه در شبکه برای معرف
|
||||
```
|
||||
|
||||
### هدف:
|
||||
- معرفی که این کاربر را جذب کرده بود، یکی از دستهایش آزاد میشود
|
||||
- میتواند **کاربر جدید** جذب کند
|
||||
- امکان **تعادل متعادل** دست چپ و راست فراهم میشود
|
||||
|
||||
---
|
||||
|
||||
## 6️⃣ محدودیت تعداد زیرمجموعه
|
||||
|
||||
### قانون سخت:
|
||||
**هر کاربر فقط 2 نفر میتواند جذب کند** (دست چپ + دست راست)
|
||||
|
||||
### سناریو خطا:
|
||||
```
|
||||
کاربر A: دو نفر زیرمجموعه فعال دارد
|
||||
کاربر B: با کد معرف کاربر A ثبت نام میکند
|
||||
|
||||
→ ❌ پیغام خطا:
|
||||
"این کاربر تعداد زیرمجموعههاش پر شده و شما نمیتونید جزو زیرمجموعه این آدم بشید"
|
||||
```
|
||||
|
||||
### نکته:
|
||||
**فعال** یعنی:
|
||||
- وام دایا گرفته یا پرداخت مستقیم کرده
|
||||
- عضو باشگاه مشتریان شده
|
||||
|
||||
---
|
||||
|
||||
## 7️⃣ فرآیند کامل ثبت نام تا فعالسازی
|
||||
|
||||
```
|
||||
1. ثبت نام با کد معرف
|
||||
↓
|
||||
2. بررسی ظرفیت معرف (حداکثر 2 نفر)
|
||||
↓ (اگر پر بود → خطا)
|
||||
↓
|
||||
3. درخواست وام دایا یا پرداخت مستقیم (56M)
|
||||
↓
|
||||
4. تأیید پرداخت 56M
|
||||
↓
|
||||
5. شارژ کیف پولها:
|
||||
- کیف پول اصلی: +56M
|
||||
- کیف پول تخفیفی: +56M
|
||||
↓
|
||||
6. **دیالوگ الزامی باشگاه مشتریان**
|
||||
- امضای قرارداد
|
||||
- تخصیص 25M به صندوق
|
||||
↓
|
||||
7. کاربر فعال میشود
|
||||
↓
|
||||
8. لینک معرفی نمایش داده میشود
|
||||
↓
|
||||
9. ورود به فرآیند محاسبه کمیسیون هفتگی
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8️⃣ خرید از فروشگاهها
|
||||
|
||||
### دو نوع فروشگاه:
|
||||
|
||||
1. **فروشگاه اصلی**:
|
||||
- از کیف پول اصلی کسر میشود
|
||||
|
||||
2. **فروشگاه تخفیفی** (باشگاه مشتریان):
|
||||
- از کیف پول تخفیفی کسر میشود
|
||||
- به مقداری که تخفیف دارد
|
||||
|
||||
---
|
||||
|
||||
## 9️⃣ جمعبندی تعادل و فلش
|
||||
|
||||
### سناریو کامل:
|
||||
|
||||
```
|
||||
هفته 1:
|
||||
- چپ = 500، راست = 600
|
||||
- تعادل = MIN(500, 600) = 500
|
||||
|
||||
چون 500 > 300:
|
||||
- امتیاز این هفته = 300
|
||||
- فلش چپ = 500 - 300 = 200
|
||||
- فلش راست = 600 - 300 = 300
|
||||
- جمع فلش = 500 (از بین رفت)
|
||||
```
|
||||
|
||||
### قوانین فلش:
|
||||
1. ❌ باقیماندهای که از هفته قبل میآید فلش **نمیشود**
|
||||
2. ✅ فقط اضافهای که بزرگتر از 300 است فلش میشود
|
||||
3. ✅ هر دو طرف (چپ و راست) فلش میشوند
|
||||
4. ❌ **نمیتواند** فقط یک طرف فلش شود
|
||||
|
||||
### مثال فلش:
|
||||
```
|
||||
هفته قبل باقیمانده راست = 200
|
||||
هفته جدید راست = 400
|
||||
مجموع راست = 600
|
||||
|
||||
سقف = 300
|
||||
فلش راست = 600 - 300 = 300 ✅ (نه 200)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔟 نکات مهم اضافی
|
||||
|
||||
### چرخش هفتگی:
|
||||
- محاسبات هر هفته صورت میگیرد
|
||||
- تعادلهای استفاده شده **ریست** میشوند
|
||||
- فقط **باقیمانده** به هفته بعد منتقل میشود
|
||||
- فلشها **هیچ جا حساب نمیشوند**
|
||||
|
||||
### محدودیتهای عمق شبکه:
|
||||
- **تا همه کاربرها** در زیر شبکه حساب میشوند
|
||||
- **بدون محدودیت عمق** (تا سطح آخر درخت)
|
||||
|
||||
### اولویت محاسبه:
|
||||
1. محاسبه تعادل اولیه
|
||||
2. محاسبه باقیمانده
|
||||
3. اعمال سقف 300
|
||||
4. محاسبه فلش
|
||||
5. ذخیره باقیمانده برای هفته بعد
|
||||
|
||||
---
|
||||
|
||||
## 📊 جدول مقایسه حالات مختلف
|
||||
|
||||
| چپ | راست | تعادل اولیه | سقف 300 | امتیاز | باقی چپ | باقی راست | فلش کل |
|
||||
|-----|-------|-------------|---------|--------|---------|-----------|---------|
|
||||
| 200 | 250 | 200 | 200 | 200 | 0 | 50 | 0 |
|
||||
| 400 | 350 | 350 | 300 | 300 | 100 | 50 | 100 |
|
||||
| 500 | 600 | 500 | 300 | 300 | 200 | 300 | 400 |
|
||||
| 150 | 280 | 150 | 150 | 150 | 0 | 130 | 0 |
|
||||
| 350 | 350 | 350 | 300 | 300 | 50 | 50 | 100 |
|
||||
|
||||
**توضیح ستونها:**
|
||||
- **تعادل اولیه**: MIN(چپ، راست)
|
||||
- **سقف 300**: MIN(تعادل اولیه، 300)
|
||||
- **امتیاز**: همان سقف 300 (امتیاز نهایی)
|
||||
- **باقی چپ**: چپ - سقف چپ (300)
|
||||
- **باقی راست**: راست - سقف راست (300)
|
||||
- **فلش کل**: (چپ - 300) + (راست - 300) اگر > 0
|
||||
|
||||
---
|
||||
|
||||
## ✅ وضعیت پیادهسازی فعلی
|
||||
|
||||
این سند نیاز به **تطبیق کامل** با:
|
||||
1. ✅ کد موجود در `CalculateWeeklyBalancesCommandHandler`
|
||||
2. ✅ داکیومنتهای موجود در `totalDoc/01-BUSINESS/`
|
||||
3. ✅ Entity ها در Domain Layer
|
||||
4. ✅ Worker های پسزمینه
|
||||
|
||||
→ در مرحله بعد مقایسه و شناسایی تفاوتها انجام میشود.
|
||||
Reference in New Issue
Block a user