18 KiB
Executable file
📚 مستندات کامل افزونه مدیریت تعمیرگاه
فهرست مطالب
- معرفی
- معماری سیستم
- دیتابیس
- API Documentation
- یکپارچگیها
- جریان کاری
- امنیت و دسترسیها
- خطاها و عیبیابی
معرفی
افزونه مدیریت تعمیرگاه یک سیستم جامع برای مدیریت فرآیند تعمیرات از دریافت کالا تا تحویل نهایی است.
ویژگیهای کلیدی
- ✅ دریافت و ثبت کالای تعمیری
- ✅ مدیریت تعمیرکاران و حقالزحمه
- ✅ کارتابل تعمیرات (10 وضعیت)
- ✅ یکپارچگی با سیستم گارانتی
- ✅ حواله خروج خودکار قطعات
- ✅ صدور فاکتور و ثبت حسابداری
- ✅ تاریخچه کامل تعمیرات
معماری سیستم
لایههای سیستم
┌─────────────────────────────────┐
│ API Layer (FastAPI) │
│ /api/v1/repair-shop/* │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ Service Layer │
│ - repair_shop_service │
│ - repair_shop_operations │
│ - repair_shop_accounting │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ Repository Layer │
│ - RepairOrderRepository │
│ - RepairTechnicianRepository │
│ - etc. │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ Database Layer (MySQL) │
│ 7 جدول اصلی │
└─────────────────────────────────┘
یکپارچگی با سیستمهای دیگر
┌──────────────────────────┐
│ Repair Shop System │
└──────────────────────────┘
↓ ↑
┌────────────┬─────────────┬─────────────┬──────────────┐
↓ ↓ ↓ ↓ ↓
┌────────┐ ┌──────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐
│Products│ │Warehouse │ │Accounting│ │Warranty │ │ Storage │
└────────┘ └──────────┘ └──────────┘ └─────────┘ └──────────┘
دیتابیس
ERD (Entity Relationship Diagram)
┌─────────────────────┐
│ repair_shop_settings│
│ - business_id (PK) │
│ - receipt_format │
│ - auto_send_sms │
└─────────────────────┘
┌──────────────────────┐ ┌─────────────────────┐
│ repair_technicians │ │ repair_orders │
│ - id (PK) │◄───────│ - id (PK) │
│ - business_id │ │ - code (UNIQUE) │
│ - person_id (FK) │ │ - customer_id (FK) │
│ - commission_type │ │ - technician_id (FK)│
│ - commission_value │ │ - status │
└──────────────────────┘ │ - final_cost │
└─────────────────────┘
↓ 1:N
┌────────────────┴────────────────┐
↓ ↓
┌──────────────────────┐ ┌─────────────────────────┐
│ repair_order_parts │ │ repair_order_statuses │
│ - id (PK) │ │ - id (PK) │
│ - repair_order_id(FK)│ │ - repair_order_id (FK) │
│ - product_id (FK) │ │ - status │
│ - quantity │ │ - created_at │
│ - unit_price │ │ - sms_sent │
└──────────────────────┘ └─────────────────────────┘
جدول repair_orders (جدول اصلی)
| ستون | نوع | توضیحات |
|---|---|---|
id |
INT | شناسه یکتا |
code |
VARCHAR(50) | کد یکتا (مثل REC-2025-0001) |
business_id |
INT | کسبوکار |
customer_person_id |
INT | مشتری از جدول persons |
product_name |
VARCHAR(255) | نام کالا |
warranty_code_id |
INT NULL | کد گارانتی (اختیاری) |
status |
VARCHAR(50) | وضعیت فعلی |
assigned_technician_id |
INT NULL | تعمیرکار |
final_cost |
DECIMAL(18,2) | هزینه نهایی |
parts_cost |
DECIMAL(18,2) | هزینه قطعات |
labor_cost |
DECIMAL(18,2) | دستمزد |
technician_commission |
DECIMAL(18,2) | حقالزحمه |
received_at |
DATETIME | تاریخ دریافت |
completed_at |
DATETIME NULL | تاریخ تکمیل |
delivered_at |
DATETIME NULL | تاریخ تحویل |
وضعیتهای مجاز (Status)
| وضعیت | توضیح |
|---|---|
received |
دریافت شده |
assigned |
اختصاص داده شده |
in_progress |
در حال تعمیر |
waiting_parts |
منتظر قطعات |
testing |
در حال تست |
completed_fixed |
تعمیر موفق |
completed_unfixable |
غیرقابل تعمیر |
ready_for_pickup |
آماده تحویل |
delivered |
تحویل داده شده |
cancelled |
لغو شده |
API Documentation
Authentication
تمام API ها نیاز به Bearer Token دارند:
Authorization: Bearer sk_your_api_key
Base URL
/api/v1/repair-shop
Endpoints
1. Settings
GET /businesses/{business_id}/settings
دریافت تنظیمات تعمیرگاه
Response:
{
"id": 1,
"business_id": 1,
"receipt_code_format": "sequential",
"receipt_code_prefix": "REC",
"auto_send_sms_on_receive": true,
"sms_templates": {...}
}
PUT /businesses/{business_id}/settings
بهروزرسانی تنظیمات
Request Body:
{
"auto_send_sms_on_receive": true,
"receipt_code_prefix": "REC"
}
2. Technicians
POST /businesses/{business_id}/technicians
ایجاد تعمیرکار جدید
Request Body:
{
"person_id": 123,
"commission_type": "percentage",
"commission_value": 30,
"is_active": true
}
Commission Types:
fixed: مبلغ فیکس (مثلاً 200,000 تومان)percentage: درصد از دستمزد (مثلاً 30%)case_by_case: موردی (دستی وارد میشود)
3. Repair Orders
POST /businesses/{business_id}/orders
ایجاد سفارش تعمیر جدید
Request Body:
{
"customer_person_id": 123,
"product_name": "لپتاپ ایسوس",
"product_serial": "ABC123",
"warranty_code_id": 456,
"problem_description": "روشن نمیشود",
"estimated_cost": 1500000
}
Response:
{
"id": 1,
"code": "REC-2025-0001",
"status": "received",
"customer_name": "علی احمدی",
"product_name": "لپتاپ ایسوس",
"received_at": "2025-02-05T10:30:00",
...
}
GET /businesses/{business_id}/orders?status=in_progress
لیست سفارشات با فیلتر
Query Parameters:
status: فیلتر بر اساس وضعیتcustomer_person_id: فیلتر بر اساس مشتریassigned_technician_id: فیلتر بر اساس تعمیرکارsearch: جستجو در کد، نام کالا، سریالoffset: شروع از (pagination)limit: تعداد نتایج
4. Operations
POST /businesses/{business_id}/orders/{order_id}/assign-technician
اختصاص تعمیرکار
Request Body:
{
"technician_id": 1
}
POST /businesses/{business_id}/orders/{order_id}/update-status
تغییر وضعیت
Request Body:
{
"status": "in_progress",
"notes": "شروع تعمیر",
"send_notification": true
}
POST /businesses/{business_id}/orders/{order_id}/add-parts
افزودن قطعات
Request Body:
{
"parts": [
{
"product_id": 10,
"quantity": 1,
"unit_price": 500000,
"warehouse_id": 1
},
{
"product_id": 11,
"quantity": 2,
"warehouse_id": 1
}
]
}
نکته: سیستم به صورت خودکار:
- موجودی را بررسی میکند
- حواله خروج پیشنویس ایجاد میکند
- هزینه قطعات را محاسبه میکند
POST /businesses/{business_id}/orders/{order_id}/calculate-costs
محاسبه هزینهها
Request Body:
{
"labor_cost": 1000000
}
Response:
{
"parts_cost": 500000,
"labor_cost": 1000000,
"technician_commission": 300000,
"final_cost": 1500000
}
POST /businesses/{business_id}/orders/{order_id}/complete
اتمام تعمیر
Request Body:
{
"is_fixed": true,
"notes": "تعمیر با موفقیت انجام شد"
}
نکته: در این مرحله:
- حواله خروج پست میشود
- وضعیت به
completed_fixedیاcompleted_unfixableتغییر میکند - موجودی از انبار کسر میشود
POST /businesses/{business_id}/orders/{order_id}/deliver
تحویل کالا
Request Body:
{
"notes": "تحویل به مشتری"
}
5. Accounting
POST /businesses/{business_id}/orders/{order_id}/create-invoice
صدور فاکتور تعمیر
Response:
{
"document": {
"id": 123,
"code": "INV-2025-001",
"document_type": "invoice_sales",
...
},
"accounting_summary": {
"labor_cost": 1000000,
"parts_cost": 500000,
"final_cost": 1500000
}
}
اسناد حسابداری ثبت شده:
حساب دریافتنی (10401) بدهکار: 1,500,000
درآمد فروش (50001) بستانکار: 1,000,000 (خدمات)
درآمد فروش (50001) بستانکار: 500,000 (قطعات)
بهای تمام شده (40001) بدهکار: 300,000
موجودی کالا (10102) بستانکار: 300,000
یکپارچگیها
1. Marketplace Plugin System
# بررسی فعال بودن
from app.core.repair_shop_plugin_dependency import check_repair_shop_plugin_active
is_active = check_repair_shop_plugin_active(db, business_id)
2. Permission System
دسترسیهای مورد نیاز:
repair_shop.read: مشاهدهrepair_shop.write: ثبت و ویرایشrepair_shop.delete: حذفrepair_shop.manage: مدیریت تنظیمات
3. Warehouse Integration
# هنگام افزودن قطعات
from app.services.warehouse_service import get_product_stock
stock = get_product_stock(db, business_id, product_id, warehouse_id)
if stock < quantity:
raise ApiError("INSUFFICIENT_STOCK", ...)
4. Accounting Integration
from app.services.invoice_service import create_invoice
# صدور فاکتور
invoice = create_invoice(db, business_id, user_id, invoice_payload)
جریان کاری
سناریوی کامل: تعمیر لپتاپ
1️⃣ دریافت کالا
POST /orders
{
"customer_person_id": 1,
"product_name": "لپتاپ",
"problem_description": "روشن نمیشود"
}
2️⃣ اختصاص تعمیرکار
POST /orders/1/assign-technician
{"technician_id": 1}
3️⃣ شروع تعمیر
POST /orders/1/update-status
{"status": "in_progress"}
4️⃣ افزودن قطعات
POST /orders/1/add-parts
{
"parts": [{"product_id": 10, "quantity": 1, "warehouse_id": 1}]
}
→ حواله خروج پیشنویس ایجاد میشود
5️⃣ محاسبه هزینه
POST /orders/1/calculate-costs
{"labor_cost": 1000000}
→ حقالزحمه تعمیرکار محاسبه میشود
6️⃣ اتمام تعمیر
POST /orders/1/complete
{"is_fixed": true}
→ حواله خروج پست میشود
→ موجودی کسر میشود
7️⃣ صدور فاکتور
POST /orders/1/create-invoice
→ فاکتور فروش ایجاد میشود
→ اسناد حسابداری ثبت میشوند
8️⃣ تحویل
POST /orders/1/deliver
امنیت و دسترسیها
نقشهای پیشنهادی
1. مدیر تعمیرگاه
{
"repair_shop": {
"read": true,
"write": true,
"delete": true,
"manage": true
}
}
2. تعمیرکار
{
"repair_shop": {
"read": true,
"write": true
}
}
3. کارشناس پذیرش
{
"repair_shop": {
"read": true,
"write": true
},
"people": {
"read": true,
"write": true
}
}
خطاها و عیبیابی
خطاهای رایج
1. PLUGIN_NOT_ACTIVE
{
"error_code": "PLUGIN_NOT_ACTIVE",
"message": "افزونه مدیریت تعمیرگاه فعال نیست"
}
حل: افزونه را از marketplace خریداری یا trial کنید.
2. INSUFFICIENT_STOCK
{
"error_code": "INSUFFICIENT_STOCK",
"message": "موجودی کافی نیست",
"extra_data": {
"product_id": 10,
"current_stock": 5,
"requested": 10
}
}
حل: موجودی را افزایش دهید یا تعداد را کاهش دهید.
3. INVOICE_ALREADY_EXISTS
{
"error_code": "INVOICE_ALREADY_EXISTS",
"message": "فاکتور قبلاً ایجاد شده است"
}
حل: هر سفارش فقط یک فاکتور دارد.
4. NO_ACTIVE_STORAGE_PLAN
{
"error_code": "NO_ACTIVE_STORAGE_PLAN",
"message": "پکیج ذخیرهسازی فعالی وجود ندارد"
}
حل: برای آپلود تصاویر، پلن ذخیرهسازی فعال کنید.
Logging
تمام عملیات مهم لاگ میشوند:
import logging
logger = logging.getLogger(__name__)
logger.info(f"سفارش تعمیر {order.code} ایجاد شد")
logger.warning(f"موجودی کافی نیست: {product_id}")
logger.error(f"خطا در ایجاد فاکتور: {e}")
نکات عملیاتی
1. Performance
- استفاده از Index ها برای جستجوی سریع
- Pagination برای لیستها
- Lazy Loading برای relationships
2. Scalability
- جداسازی concerns (Service, Repository, API)
- استفاده از Queue برای پیامک/ایمیل
- Cache برای تنظیمات
3. Best Practices
- Validation در Pydantic models
- Transaction management در service layer
- Error handling مناسب
- Logging جامع
مثالهای کاربردی
مثال 1: دریافت آمار تعمیرات
from sqlalchemy import func
# تعداد تعمیرات موفق
successful_repairs = db.query(func.count(RepairOrder.id)).filter(
RepairOrder.business_id == business_id,
RepairOrder.status == "completed_fixed"
).scalar()
# میانگین زمان تعمیر
avg_duration = db.query(
func.avg(
func.timestampdiff(
sa.text('HOUR'),
RepairOrder.received_at,
RepairOrder.completed_at
)
)
).filter(
RepairOrder.business_id == business_id,
RepairOrder.completed_at.isnot(None)
).scalar()
مثال 2: گزارش عملکرد تعمیرکار
from sqlalchemy import func, case
technician_report = db.query(
RepairTechnician.id,
Person.name,
func.count(RepairOrder.id).label('total_repairs'),
func.sum(
case(
(RepairOrder.status == 'completed_fixed', 1),
else_=0
)
).label('successful_repairs'),
func.sum(RepairOrder.technician_commission).label('total_commission')
).join(
Person, RepairTechnician.person_id == Person.id
).outerjoin(
RepairOrder, RepairOrder.assigned_technician_id == RepairTechnician.id
).filter(
RepairTechnician.business_id == business_id
).group_by(
RepairTechnician.id, Person.name
).all()
تاریخ: 2025-02-05
نسخه: 1.0.0
نویسنده: AI Assistant