You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

711 lines
25 KiB

from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from rest_framework import status
def doc_upload_transaction_receipts():
return """
# 🐈 Scenario
🛠️ آپلود رسید پرداخت برای تراکنش
این API برای آپلود یک یا چند رسید پرداخت برای یک تراکنش استفاده می‌شود.
پس از آپلود موفقیت‌آمیز، وضعیت تراکنش به 'waiting_approval' (در انتظار تایید) تغییر می‌کند.
---
## 🚀 روند آپلود (دو مرحله‌ای)
### مرحله 1️⃣: آپلود فایل به سرور موقت
ابتدا باید فایل‌های خود را به endpoint زیر آپلود کنید:
```
POST /upload-tmp-media/
Content-Type: multipart/form-data
Body:
- file: [فایل رسید]
```
**پاسخ:**
```json
{
"url": "/static/tmp/xyz123-receipt.jpg",
"name": "receipt.jpg",
"size": "1024000",
"mime_type": "image/jpeg"
}
```
### مرحله 2️⃣: ثبت URL فایل‌ها در تراکنش
سپس URL های دریافتی را به این endpoint ارسال کنید:
```
POST /api/transactions/<transaction_id>/receipts/upload/
Content-Type: application/json
```
---
## 🚀 درخواست API (مرحله 2)
### URL:
```
POST /api/transactions/<transaction_id>/receipts/upload/
```
### پارامترهای URL:
| کلید | نوع داده | توضیحات |
|------------------|-----------|----------------------------------------------------------|
| `transaction_id` | Integer | شناسه تراکنش که می‌خواهید رسید برای آن ثبت کنید |
### پارامترهای درخواست (JSON Body):
| کلید | نوع داده | الزامی | توضیحات |
|---------------|-----------|--------|----------------------------------------------------------|
| `files` | String[] | بله | لیست URL های فایل‌های آپلود شده از مرحله 1 (حداکثر 10 فایل) |
| `description` | String | خیر | توضیحات اختیاری درباره رسیدها |
---
## 💡 نکات مهم:
1. **روند دو مرحله‌ای**:
- **مرحله 1**: ابتدا فایل‌ها را به `/upload-tmp-media/` آپلود کنید
- **مرحله 2**: سپس URL های دریافتی را به این API ارسال کنید
2. **محدودیت فایل‌ها**:
- حداکثر 10 فایل می‌توانید در هر درخواست ثبت کنید
3. **وضعیت تراکنش**:
- فقط می‌توانید برای تراکنش‌هایی با وضعیت 'pending' یا 'waiting_approval' رسید آپلود کنید
- پس از ثبت موفقیت‌آمیز، وضعیت تراکنش به 'waiting_approval' تغییر می‌کند
4. **احراز هویت**:
- باید توکن احراز هویت را در هدر درخواست ارسال کنید
- فقط می‌توانید برای تراکنش‌های خودتان رسید آپلود کنید
---
## 📊 پاسخ‌ها
| کد وضعیت | توضیحات |
|---------------|-----------------------------------------------------------|
| `201` | موفقیت‌آمیز - رسیدها با موفقیت ثبت شدند |
| `400` | داده‌های نامعتبر یا تراکنش قادر به دریافت رسید نیست |
| `403` | عدم دسترسی - شما صاحب این تراکنش نیستید |
| `404` | تراکنش یافت نشد |
---
## 📄 نمونه درخواست کامل (JSON):
```json
{
"files": [
"/static/tmp/xyz123-receipt1.jpg",
"/static/tmp/abc456-receipt2.jpg"
],
"description": "Payment receipt for Python course"
}
```
---
## 📄 نمونه پاسخ موفقیت‌آمیز
```json
{
"success": true,
"message": "Receipts uploaded successfully",
"transaction_status": "waiting_approval",
"receipts": [
{
"id": 1,
"file": "http://example.com/media/receipts/1/receipt1.jpg",
"description": "Payment receipt for course enrollment",
"uploaded_at": "2025-12-03T10:30:00Z"
},
{
"id": 2,
"file": "http://example.com/media/receipts/1/receipt2.jpg",
"description": "Payment receipt for course enrollment",
"uploaded_at": "2025-12-03T10:30:05Z"
}
]
}
```
---
## 📄 نمونه درخواست کامل (cURL):
### مرحله 1 - آپلود فایل:
```bash
curl -X POST \\
'http://your-api.com/upload-tmp-media/' \\
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \\
-F 'file=@/path/to/receipt1.jpg'
```
### مرحله 2 - ثبت رسید:
```bash
curl -X POST \\
'http://your-api.com/api/transactions/123/receipts/upload/' \\
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \\
-H 'Content-Type: application/json' \\
-d '{
"files": ["/static/tmp/xyz123-receipt1.jpg"],
"description": "Payment receipt for Python course"
}'
```
---
## 📄 نمونه پاسخ خطا (403 - عدم دسترسی):
```json
{
"message": "You don't have permission to upload receipts for this transaction"
}
```
---
## 📄 نمونه پاسخ خطا (400 - وضعیت نامعتبر):
```json
{
"message": "Cannot upload receipts for transaction with status 'success'"
}
```
"""
def doc_list_transaction_receipts():
return """
# 🐈 Scenario
🛠️ لیست رسیدهای پرداخت یک تراکنش
این API برای دریافت لیست تمام رسیدهای آپلود شده برای یک تراکنش خاص استفاده می‌شود.
---
## 🚀 درخواست API
### URL:
```
GET /api/transactions/<transaction_id>/receipts/
```
### پارامترهای URL:
| کلید | نوع داده | توضیحات |
|------------------|-----------|----------------------------------------------------------|
| `transaction_id` | Integer | شناسه تراکنش که می‌خواهید رسیدهای آن را مشاهده کنید |
---
## 💡 نکات مهم:
1. **احراز هویت**:
- باید توکن احراز هویت را در هدر درخواست ارسال کنید
- فقط می‌توانید رسیدهای تراکنش‌های خودتان را مشاهده کنید
2. **مرتب‌سازی**:
- رسیدها بر اساس تاریخ آپلود (جدیدترین اول) مرتب می‌شوند
---
## 📊 پاسخ‌ها
| کد وضعیت | توضیحات |
|---------------|-----------------------------------------------------------|
| `200` | موفقیت‌آمیز - لیست رسیدها بازگردانده شد |
| `403` | عدم دسترسی - شما صاحب این تراکنش نیستید |
| `404` | تراکنش یافت نشد |
---
## 📄 نمونه پاسخ موفقیت‌آمیز
```json
[
{
"id": 1,
"file": "http://example.com/media/receipts/1/receipt1.jpg",
"description": "Payment receipt for course enrollment",
"uploaded_at": "2025-12-03T10:30:00Z"
},
{
"id": 2,
"file": "http://example.com/media/receipts/1/receipt2.jpg",
"description": "Second payment receipt",
"uploaded_at": "2025-12-03T10:25:00Z"
}
]
```
---
## 📄 توضیحات مقادیر پاسخ
| کلید | نوع داده | توضیحات |
|---------------|------------|----------------------------------------------------------|
| `id` | Integer | شناسه یکتای رسید |
| `file` | String | URL کامل فایل رسید آپلود شده |
| `description` | String | توضیحات اختیاری درباره رسید (ممکن است خالی باشد) |
| `uploaded_at` | DateTime | تاریخ و زمان آپلود رسید |
---
## 📄 نمونه درخواست (cURL):
```bash
curl -X GET \\
'http://your-api.com/api/transactions/123/receipts/' \\
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'
```
---
## 📄 نمونه پاسخ خطا (403 - عدم دسترسی):
```json
{
"message": "You don't have permission to view receipts for this transaction"
}
```
---
## 📄 نمونه پاسخ خطا (404 - تراکنش یافت نشد):
```json
{
"message": "Transaction not found"
}
```
"""
def doc_transaction_list():
return """
# 🐈 Scenario
🛠️ لیست تراکنش‌های کاربر
این API برای دریافت لیست تمام تراکنش‌های کاربر احراز هویت شده استفاده می‌شود.
---
## 🚀 درخواست API
### URL:
```
GET /api/transactions/list/
```
---
## 💡 نکات مهم:
1. **احراز هویت**:
- باید توکن احراز هویت را در هدر درخواست ارسال کنید
- فقط تراکنش‌های خودتان را مشاهده می‌کنید
2. **فیلترینگ خودکار**:
- تراکنش‌های حذف شده (soft deleted) نمایش داده نمی‌شوند
3. **وضعیت‌های تراکنش**:
- `pending`: در انتظار پرداخت
- `waiting_approval`: در انتظار تایید (رسید آپلود شده)
- `success`: پرداخت موفق و تایید شده
- `failed`: پرداخت ناموفق
---
## 📊 پاسخ‌ها
| کد وضعیت | توضیحات |
|---------------|-----------------------------------------------------------|
| `200` | موفقیت‌آمیز - لیست تراکنش‌ها بازگردانده شد |
| `401` | عدم احراز هویت |
---
## 📄 توضیحات مقادیر پاسخ
| کلید | نوع داده | توضیحات |
|---------------|------------|----------------------------------------------------------|
| `id` | Integer | شناسه یکتای تراکنش |
| `course` | Object | اطلاعات دوره مرتبط با تراکنش |
| `status` | String | وضعیت تراکنش (pending, waiting_approval, success, failed) |
| `price` | Decimal | مبلغ تراکنش |
| `created_at` | DateTime | تاریخ و زمان ایجاد تراکنش |
| `updated_at` | DateTime | تاریخ و زمان آخرین به‌روزرسانی تراکنش |
---
## 📄 نمونه پاسخ موفقیت‌آمیز
```json
[
{
"id": 1,
"course": {
"id": 5,
"title": "Python Programming Basics",
"slug": "python-programming-basics",
"thumbnail": "http://example.com/media/courses/thumbnails/python.jpg",
"price": "99.00",
"final_price": "79.00"
},
"status": "waiting_approval",
"price": "79.00",
"created_at": "2025-12-01T10:00:00Z",
"updated_at": "2025-12-03T10:30:00Z"
},
{
"id": 2,
"course": {
"id": 8,
"title": "Django Web Development",
"slug": "django-web-development",
"thumbnail": "http://example.com/media/courses/thumbnails/django.jpg",
"price": "149.00",
"final_price": "149.00"
},
"status": "success",
"price": "149.00",
"created_at": "2025-11-28T14:20:00Z",
"updated_at": "2025-11-29T09:15:00Z"
}
]
```
---
## 📄 نمونه درخواست (cURL):
```bash
curl -X GET \\
'http://your-api.com/api/transactions/list/' \\
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN'
```
"""
def doc_create_transaction():
return """
# 🐈 Scenario
🛠️ ثبت‌نام در دوره و ایجاد تراکنش
این API برای ثبت‌نام کاربر در یک دوره و ایجاد تراکنش استفاده می‌شود.
---
## 🚀 درخواست API
### URL:
```
POST /api/transactions/<slug>/join/
```
### پارامترهای URL:
| کلید | نوع داده | توضیحات |
|---------|-----------|----------------------------------------------------------|
| `slug` | String | اسلاگ دوره‌ای که می‌خواهید در آن ثبت‌نام کنید |
### پارامترهای درخواست (JSON Body):
| کلید | نوع داده | الزامی | توضیحات |
|---------------------|-----------|--------|----------------------------------------------------------|
| `participant_infos` | Array | بله | لیست اطلاعات شرکت‌کنندگان |
### ساختار `participant_infos`:
| کلید | نوع داده | الزامی | توضیحات |
|---------------|-----------|--------|----------------------------------------------------------|
| `fullname` | String | بله | نام کامل شرکت‌کننده |
| `email` | String | بله | ایمیل شرکت‌کننده (برای دوره رایگان باید با ایمیل کاربر احراز هویت شده یکسان باشد) |
| `phone_number`| String | خیر | شماره تلفن شرکت‌کننده |
| `gender` | String | خیر | جنسیت شرکت‌کننده (male, female) |
| `birthdate` | Date | خیر | تاریخ تولد شرکت‌کننده (فرمت: YYYY-MM-DD) |
---
## 💡 نکات مهم:
1. **دوره رایگان**:
- اگر دوره رایگان باشد و فقط یک شرکت‌کننده در لیست باشد و ایمیل او با کاربر احراز هویت شده یکسان باشد، تراکنش به صورت خودکار تایید می‌شود (status = 'success')
- کاربر به صورت خودکار به عنوان دانشجو در دوره ثبت می‌شود
2. **دوره پولی**:
- تراکنش با وضعیت 'pending' ایجاد می‌شود
- سیستم بر اساس موقعیت جغرافیایی کاربر، روش پرداخت مناسب را تعیین می‌کند
3. **روش پرداخت (Payment Method)**:
- **Payment_Gateway**: برای کاربران غیر روسی - پرداخت از طریق درگاه پرداخت آنلاین
- **Receipt**: برای کاربران روسی - آپلود رسید پرداخت از طریق واتس‌اپ
4. **تشخیص موقعیت جغرافیایی**:
- ابتدا از هدر Cloudflare (`CF-IPCountry`) استفاده می‌شود
- در صورت عدم وجود، از پایگاه داده GeoIP محلی استفاده می‌شود
- کاربران روسی روش پرداخت Receipt دریافت می‌کنند
- کاربران سایر کشورها روش پرداخت Payment_Gateway دریافت می‌کنند
5. **احراز هویت**:
- باید توکن احراز هویت را در هدر درخواست ارسال کنید
---
## 📊 پاسخ‌ها
| کد وضعیت | توضیحات |
|---------------|-----------------------------------------------------------|
| `201` | موفقیت‌آمیز - تراکنش ایجاد شد |
| `400` | داده‌های نامعتبر |
| `404` | دوره یافت نشد |
### ساختار پاسخ:
| کلید | نوع داده | توضیحات |
|---------------------|-----------|----------------------------------------------------------|
| `message` | String | پیام موفقیت‌آمیز |
| `transaction_id` | Integer | شناسه تراکنش ایجاد شده |
| `payment_method` | String | روش پرداخت (Payment_Gateway یا Receipt) |
| `payment_link` | String | لینک پرداخت (فقط برای Payment_Gateway) |
| `participant_infos` | Array | لیست اطلاعات شرکت‌کنندگان |
---
## 💳 روش‌های پرداخت:
### Payment_Gateway (درگاه پرداخت):
- **کاربران**: غیر روسی
- **اقدام کاربر**: کلیک روی `payment_link` و پرداخت آنلاین
- **فرآیند**: پرداخت مستقیم از طریق درگاه پرداخت
### Receipt (رسید پرداخت):
- **کاربران**: روسی
- **اقدام کاربر**: آپلود رسید پرداخت از طریق واتس‌اپ
- **فرآیند**: آپلود رسید → بررسی توسط ادمین → تایید پرداخت
---
## 📄 نمونه درخواست (JSON Body):
```json
{
"participant_infos": [
{
"fullname": "علی رضایی",
"email": "ali@example.com",
"phone_number": "+989123456789",
"gender": "male",
"birthdate": "1995-05-15"
}
]
}
```
---
## 📄 نمونه پاسخ (دوره رایگان):
```json
{
"message": "Transaction Participant created successfully.",
"transaction_id": 123,
"payment_method": Free,
"payment_link": null,
"participant_infos": [
{
"fullname": "علی رضایی",
"email": "ali@example.com",
"phone_number": "+989123456789",
"gender": "male",
"birthdate": "1995-05-15"
}
]
}
```
---
## 📄 نمونه پاسخ (دوره پولی - Payment_Gateway):
```json
{
"message": "Transaction Participant created successfully.",
"transaction_id": 374,
"payment_method": "Payment_Gateway",
"payment_link": "https://russia-payment.com/pay/374",
"participant_infos": [
{
"fullname": "John Doe",
"email": "john@example.com",
"phone_number": "+1234567890",
"gender": "male",
"birthdate": "1990-01-01"
}
]
}
```
---
## 📄 نمونه پاسخ (دوره پولی - Receipt):
```json
{
"message": "Transaction Participant created successfully.",
"transaction_id": 375,
"payment_method": "receipt",
"payment_link": null,
"participant_infos": [
{
"fullname": "Иван Иванов",
"email": "ivan@example.ru",
"phone_number": "+71234567890",
"gender": "male",
"birthdate": "1992-05-15"
}
]
}
```
**نکته**: برای روش پرداخت Receipt، کاربر باید رسید پرداخت خود را از طریق واتس‌اپ آپلود کند.
---
## 📄 نمونه درخواست (cURL):
```bash
curl -X POST \\
'http://your-api.com/api/transactions/python-programming-basics/join/' \\
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \\
-H 'Content-Type: application/json' \\
-d '{
"participant_infos": [
{
"fullname": "علی رضایی",
"email": "ali@example.com",
"phone_number": "+989123456789",
"gender": "male",
"birthdate": "1995-05-15"
}
]
}'
```
"""
hadis_list_swagger = swagger_auto_schema(
operation_description="""
Retrieve a paginated list of Hadis (traditions) for a specific category.
**Key Features:**
- Returns hadis entries filtered by category ID
- Supports pagination for large datasets
- Translations are automatically provided based on the Accept-Language header
- Each hadis includes its category information, title, narrator, Arabic text, and translation
**Usage:**
- Use this endpoint to browse hadis within a specific category
- The response includes pagination links (next/previous) for navigation
- Set the Accept-Language header to get translations in your preferred language (en, fa, ar, ur)
- Only active (status=True) hadis are returned
**Response Structure:**
- `count`: Total number of hadis in the category
- `next`: URL for the next page (null if on last page)
- `previous`: URL for the previous page (null if on first page)
- `results`: Array of hadis objects with full details
""",
operation_summary="List Hadis by Category",
tags=['Hadis'],
manual_parameters=[
openapi.Parameter(
'category_slug',
openapi.IN_PATH,
description="Unique identifier of the Hadis category. Must be a valid category ID that exists in the system.",
type=openapi.TYPE_STRING,
required=True,
example='-330'
),
openapi.Parameter(
'page',
openapi.IN_QUERY,
description="Page number for pagination. Starts from 1. If not provided, returns the first page.",
type=openapi.TYPE_INTEGER,
required=False,
example=1
),
openapi.Parameter(
'Accept-Language',
openapi.IN_HEADER,
description="Language code for translations. Supported codes: 'en' (English), 'fa' (Persian), 'ar' (Arabic), 'ur' (Urdu). Defaults to 'en' if not specified.",
type=openapi.TYPE_STRING,
required=False,
default='en',
enum=['en', 'fa', 'ar', 'ur']
)
],
responses={
status.HTTP_200_OK: openapi.Response(
description="Successfully retrieved paginated list of hadis for the specified category",
examples={
"application/json": {
"count": 150,
"next": "http://example.com/api/hadis/category/1/?page=2",
"previous": None,
"results": [
{
"id": 1,
"number": 1,
"title": "The Opening",
"title_narrator": "From Abu Hurairah",
"text": "إنما الأعمال بالنيات وإنما لكل امرئ ما نوى",
"translation": "Actions are but by intention, and every man shall have only what he intended",
"category": {
"id": 1,
"title": "Book of Faith",
"slug": "book-of-faith",
"source_type": "hadith",
"sect_type": "sunni"
},
"status": {
"id": 130,
"title": "Прерванный",
"color": "orange"
},
"share_link": "http://example.com/hadis/1"
},
{
"id": 2,
"number": 2,
"title": "The Second Hadith",
"title_narrator": "From Umar ibn al-Khattab",
"text": "بينما نحن عند رسول الله صلى الله عليه وسلم ذات يوم",
"translation": "While we were sitting with the Messenger of Allah (peace be upon him) one day",
"category": {
"id": 1,
"title": "Book of Faith",
"slug": "book-of-faith",
"source_type": "hadith",
"sect_type": "sunni"
},
"status": {
"id": 130,
"title": "Прерванный",
"color": "orange"
},
"share_link": "http://example.com/hadis/2"
}
]
}
}
),
status.HTTP_404_NOT_FOUND: openapi.Response(
description="The specified category ID does not exist or the category has no active hadis",
examples={
"application/json": {
"detail": "Not found."
}
}
),
status.HTTP_500_INTERNAL_SERVER_ERROR: openapi.Response(
description="Internal server error occurred while processing the request"
)
}
)