- Add SendSmsMessage class for encapsulating SMS message data. - Create KavehNegarProvider and RanginehProvider classes implementing SmsProviderInterface for sending SMS. - Implement SmsLogRepository and SmsTemplateRepository for managing SMS logs and templates. - Develop SendSmsHandler for handling SMS sending messages. - Create SmsService to manage SMS dispatching and logging. - Add UserProfileController for managing user profiles with CRUD operations. - Implement UserProfile entity and repository for user profile data management. - Update symfony.lock and bootstrap.php for project dependencies and environment setup.
91 lines
3.7 KiB
Markdown
91 lines
3.7 KiB
Markdown
# پایگاه داده — تسک ۱۸: تسویه نماینده
|
||
|
||
## جدول: wallet_transactions (تراکنشهای کیف پول)
|
||
|
||
| ستون | نوع | توضیح |
|
||
|------|-----|-------|
|
||
| id | INT UNSIGNED AUTO_INCREMENT PK | |
|
||
| uuid | CHAR(36) UNIQUE NOT NULL | |
|
||
| representation_id | INT FK → representations.id NOT NULL | نماینده |
|
||
| type | VARCHAR(10) NOT NULL | `credit` (واریز) یا `debit` (برداشت) |
|
||
| amount | INT NOT NULL | مبلغ به ریال |
|
||
| source | VARCHAR(20) NOT NULL | `appointment` یا `subscription` یا `settlement` |
|
||
| source_id | INT NULL | FK به payments.id یا subscription_payments.id یا settlements.id |
|
||
| description | VARCHAR(255) NULL | توضیح تراکنش |
|
||
| created_at | INT NOT NULL | Unix timestamp |
|
||
|
||
```sql
|
||
CREATE INDEX idx_wallet_representation ON wallet_transactions(representation_id);
|
||
CREATE INDEX idx_wallet_type ON wallet_transactions(representation_id, type);
|
||
CREATE INDEX idx_wallet_source ON wallet_transactions(source, source_id);
|
||
```
|
||
|
||
---
|
||
|
||
## جدول: settlements (درخواستهای تسویه)
|
||
|
||
| ستون | نوع | توضیح |
|
||
|------|-----|-------|
|
||
| id | INT UNSIGNED AUTO_INCREMENT PK | |
|
||
| uuid | CHAR(36) UNIQUE NOT NULL | |
|
||
| representation_id | INT FK → representations.id NOT NULL | نماینده درخواستدهنده |
|
||
| amount | INT NOT NULL | مبلغ درخواستی (ریال) |
|
||
| card_number | VARCHAR(25) NOT NULL | شماره کارت بانکی برداشت |
|
||
| bank_name | VARCHAR(50) NOT NULL | نام بانک |
|
||
| status | VARCHAR(10) DEFAULT 'pending' | `pending` / `approved` / `rejected` |
|
||
| description | VARCHAR(255) NULL | توضیح نماینده |
|
||
| admin_note | VARCHAR(255) NULL | یادداشت ادمین هنگام تأیید/رد |
|
||
| requested_at | INT NOT NULL | Unix timestamp — زمان درخواست |
|
||
| resolved_at | INT NULL | Unix timestamp — زمان تأیید/رد |
|
||
| created_at | INT NOT NULL | Unix timestamp |
|
||
| updated_at | INT NOT NULL | Unix timestamp |
|
||
|
||
```sql
|
||
CREATE INDEX idx_settlements_representation ON settlements(representation_id);
|
||
CREATE INDEX idx_settlements_status ON settlements(status);
|
||
CREATE UNIQUE INDEX idx_settlements_pending ON settlements(representation_id, status)
|
||
WHERE status = 'pending';
|
||
-- این index یکتایی یک pending در هر زمان را enforce میکند
|
||
```
|
||
|
||
---
|
||
|
||
## فیلد balance در representations
|
||
|
||
جدول `representations` باید یک فیلد `balance` داشته باشد:
|
||
|
||
| ستون | نوع | توضیح |
|
||
|------|-----|-------|
|
||
| balance | INT DEFAULT 0 | موجودی کیف پول (ریال) — همیشه sync با wallet_transactions |
|
||
|
||
> **نکته:** `balance` باید همزمان با هر تراکنش در wallet_transactions آپدیت شود
|
||
> تا query موجودی سریع باشد (بدون SUM روی wallet_transactions).
|
||
|
||
---
|
||
|
||
## فلوی واریز کمیسیون (هنگام پرداخت موفق)
|
||
|
||
```
|
||
payments.status → 'received'
|
||
↓
|
||
commission = payments.amount × (representation.commission_percent / 100)
|
||
↓
|
||
INSERT INTO wallet_transactions (representation_id, type='credit', amount=commission, source='appointment', source_id=payment.id)
|
||
↓
|
||
UPDATE representations SET balance = balance + commission WHERE id = representation_id
|
||
```
|
||
|
||
## فلوی تسویه (هنگام تأیید ادمین)
|
||
|
||
```
|
||
PATCH /api/v1/settlement/{uuid}/approve
|
||
↓
|
||
بررسی: representations.balance >= settlements.amount
|
||
↓
|
||
INSERT INTO wallet_transactions (type='debit', amount=settlement.amount, source='settlement', source_id=settlement.id)
|
||
↓
|
||
UPDATE representations SET balance = balance - settlement.amount
|
||
↓
|
||
UPDATE settlements SET status='approved', resolved_at=NOW(), admin_note=...
|
||
```
|