- 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.
154 lines
4.7 KiB
Markdown
154 lines
4.7 KiB
Markdown
# تسک ۱۶: ماژول Representation (نمایندگی + داشبورد)
|
||
|
||
## توضیح
|
||
این ماژول دو کارکرد دارد:
|
||
۱. **مدیریت نمایندگیها (Multi-tenant)** — هر نماینده دامنهای دارد؛ نوبتها و دکترها به نماینده مرتبط میشوند
|
||
۲. **داشبورد دکتر/نماینده** — آمار نوبتها، درآمد ماهانه/سالانه، بیماران
|
||
|
||
## Endpoint ها
|
||
|
||
| متد | مسیر | توضیح | نیاز به Auth |
|
||
|-----|------|-------|-------------|
|
||
| GET | `/api/v1/representation/{uuid}` | اطلاعات نمایندگی | بله (Admin) |
|
||
| POST | `/api/v1/representations/{id}/bank-accounts` | اضافه کردن کارت بانکی | بله (Admin) |
|
||
| GET | `/api/v1/representation/my-appointments/{representationId}` | نوبتهای نماینده | بله |
|
||
| GET | `/api/v1/representation/my-doctor/{userId}` | دکترهای یک بیمار | بله |
|
||
| GET | `/api/v1/representation/filter/{representationId}` | آمار ماه جاری شمسی | بله |
|
||
| GET | `/api/v1/representation/yearly-income/{representationId}` | درآمد سالانه شمسی | بله |
|
||
|
||
## پیشنیازها
|
||
- تسک ۰۱، ۰۲، ۰۵ (Doctor)، ۱۰ (Appointment)، ۱۵ (Payment)
|
||
- پیادهسازی `JalaliDateService` (برای تبدیل تاریخ شمسی)
|
||
|
||
> **تسویه نماینده** در تسک ۱۸ پوشش داده میشود (کیف پول، درخواست برداشت، تأیید ادمین)
|
||
|
||
## زمان تخمینی
|
||
۸ تا ۱۰ ساعت
|
||
|
||
## Query Params
|
||
|
||
### GET /api/v1/representation/filter/{representationId}
|
||
```
|
||
?timestamp=1704067200 (اختیاری — Unix timestamp — برای تعیین ماه شمسی)
|
||
```
|
||
اگر timestamp نداده شود، ماه جاری شمسی استفاده میشود.
|
||
|
||
### GET /api/v1/representation/yearly-income/{representationId}
|
||
```
|
||
?timestamp=1704067200 (اختیاری — Unix timestamp — برای تعیین سال شمسی)
|
||
```
|
||
|
||
## نمونه Responseها
|
||
|
||
### GET /api/v1/representation/{uuid}
|
||
```json
|
||
{
|
||
"id": 1,
|
||
"uuid": "...",
|
||
"domain_name": "http://yasuj-nobat.localhost:3000/",
|
||
"city": { "id": 5, "uuid": "...", "label": "یاسوج" },
|
||
"active": true,
|
||
"commission_percent": 10.0,
|
||
"created": 1704067200,
|
||
"changed": 1716000000
|
||
}
|
||
```
|
||
|
||
### GET /api/v1/representation/filter/{id}
|
||
```json
|
||
{
|
||
"payments_total": { "total_price": 12500000, "count": 25 },
|
||
"total_patients": 142,
|
||
"today_appointments": 8
|
||
}
|
||
```
|
||
|
||
### GET /api/v1/representation/yearly-income/{id}
|
||
```json
|
||
{
|
||
"year": 1403,
|
||
"monthly_income": [
|
||
{ "month": 1, "income": 8500000 },
|
||
{ "month": 2, "income": 9200000 },
|
||
{ "month": 3, "income": 0 },
|
||
...
|
||
{ "month": 12, "income": 0 }
|
||
]
|
||
}
|
||
```
|
||
|
||
### GET /api/v1/representation/my-appointments/{id}
|
||
```json
|
||
{
|
||
"data": [
|
||
{
|
||
"id": 10, "uuid": "...",
|
||
"start_time": 1716000000, "end_time": 1716001800,
|
||
"status": "confirmed",
|
||
"slot": { "start": "09:00", "end": "09:30", "duration": 30, "location_id": 42 },
|
||
"doctor": { "id": 5, "uuid": "...", "label": "دکتر محمدی" },
|
||
"address": { "id": 42, "uuid": "...", "label": "مطب شیراز" },
|
||
"representation": { "id": 1, "uuid": "...", "label": "نمایندگی یاسوج" },
|
||
"owner": { "id": 20, "uuid": "...", "name": "علی رضایی" }
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## POST /api/v1/representations/{id}/bank-accounts
|
||
|
||
```
|
||
ورودی:
|
||
Authorization: Bearer <token>
|
||
Content-Type: application/json
|
||
|
||
Body:
|
||
{
|
||
"card_number": "6037-9999-1234-5678",
|
||
"bank_name": "ملت",
|
||
"is_default": true
|
||
}
|
||
```
|
||
|
||
```json
|
||
// خروجی HTTP 201:
|
||
{
|
||
"success": true,
|
||
"bank_account": {
|
||
"card_number": "6037-9999-1234-5678",
|
||
"bank_name": "ملت",
|
||
"is_default": true
|
||
}
|
||
}
|
||
```
|
||
|
||
> **⚠ نکات مهم:**
|
||
> - فیلد `bank_account` در جدول Representation بهصورت JSON Array ذخیره میشود
|
||
> - هر آیتم شامل: `card_number`, `bank_name`, `is_default`
|
||
> - اگر `is_default=true` باشد، `is_default` سایر کارتها باید `false` شود
|
||
> - حداقل یک کارت باید `is_default=true` داشته باشد
|
||
|
||
---
|
||
|
||
## نمونه `bank_account` در GET /api/v1/representation/{uuid}
|
||
```json
|
||
{
|
||
"bank_account": [
|
||
{ "card_number": "6037-9999-1234-5678", "bank_name": "ملت", "is_default": true },
|
||
{ "card_number": "5859-3312-4455-6677", "bank_name": "صادرات", "is_default": false }
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## فیلدهای Representation Entity
|
||
```
|
||
field_domain_name → دامنه (مثل: http://yasuj-nobat.localhost:3000/)
|
||
field_city → entity reference → category (شهر)
|
||
field_active → boolean
|
||
field_commission_percent → درصد کمیسیون
|
||
```
|