# ساختار دیتابیس و رابطه‌ها

## جدول‌ها

### users
کاربران سیستم (ادمین/کارمند). نقش از طریق spatie تعیین می‌شود.
`id, name, email(unique), email_verified_at, password, phone, is_active(bool, default true), avatar, remember_token, timestamps`

### settings
تنظیمات عمومی شرکت (تک‌ردیفه).
`id, company_name, logo_path, phone, email, address, economic_code, national_id, invoice_prefix, default_tax_percent(decimal), invoice_header(text), invoice_footer(text), timestamps`

### customers
`id, type(enum: individual|legal), first_name, last_name, company_name, national_code, national_id, economic_code, email, status(enum: lead|following|active|inactive, default lead), assigned_user_id(FK users, nullable), description(text), timestamps`

### customer_phones
`id, customer_id(FK customers, cascade), phone, label, is_primary(bool), timestamps`

### customer_addresses
`id, customer_id(FK customers, cascade), province, city, address(text), postal_code, label, is_primary(bool), timestamps`

### interactions
تاریخچه تعاملات با مشتری.
`id, customer_id(FK customers, cascade), user_id(FK users), type(enum: call|meeting|email|note), subject, description(text), interacted_at(datetime), timestamps`

### products
لیست کالا/خدمات با قیمت پیش‌فرض.
`id, name, description(text), unit, default_price(decimal 15,2), is_service(bool), is_active(bool), timestamps`

### invoices
`id, number(unique), type(enum: proforma|invoice, default proforma), customer_id(FK customers), user_id(FK users), status(enum: draft|issued|paid|partial|void, default draft), issue_date(date), due_date(date, nullable), subtotal(decimal 15,2), discount_total(decimal 15,2), tax_percent(decimal 5,2), tax_amount(decimal 15,2), grand_total(decimal 15,2), paid_amount(decimal 15,2), balance(decimal 15,2), notes(text), share_token(unique, nullable), converted_from_id(FK invoices, nullable), timestamps`

### invoice_items
`id, invoice_id(FK invoices, cascade), product_id(FK products, nullable), description, quantity(decimal 12,2), unit_price(decimal 15,2), discount(decimal 15,2), line_total(decimal 15,2), sort(int), timestamps`

### payments
`id, invoice_id(FK invoices, cascade), user_id(FK users), amount(decimal 15,2), paid_at(date), method(enum: cash|card|transfer|cheque|other), note, timestamps`

### tasks
`id, title, description(text), priority(enum: low|medium|high), status(enum: open|in_progress|done|canceled, default open), due_date(datetime, nullable), customer_id(FK customers, nullable), invoice_id(FK invoices, nullable), created_by(FK users), recurrence(enum: none|daily|weekly|monthly, default none), parent_task_id(FK tasks, nullable), last_notified_at(datetime, nullable), timestamps`

### task_user (pivot)
اختصاص تسک به چند کارمند.
`task_id(FK tasks, cascade), user_id(FK users, cascade), primary key مرکب`

### جدول‌های پکیج‌ها
- `roles, permissions, model_has_roles, model_has_permissions, role_has_permissions` — از spatie/permission
- `activity_log` — از spatie/activitylog
- `notifications` — از Laravel (`php artisan notifications:table`)

## نمودار رابطه‌ها

```
User 1───* Customer        (assigned_user_id: کارمند مسئول)
User 1───* Invoice         (user_id: صادرکننده)
User 1───* Interaction
User 1───* Payment
User *───* Task            (pivot task_user)

Customer 1───* CustomerPhone
Customer 1───* CustomerAddress
Customer 1───* Interaction
Customer 1───* Invoice
Customer 1───* Task        (اختیاری)

Invoice 1───* InvoiceItem
Invoice 1───* Payment
Invoice 1───* Task         (اختیاری)
Invoice 0/1──1 Invoice     (converted_from_id: تبدیل پیش‌فاکتور)

Product 1───* InvoiceItem

Task 0/1──* Task           (parent_task_id: نمونه‌های تکرارشونده)
```

## منطق محاسبه‌ی فاکتور

```
line_total   = quantity × unit_price − discount            (هر ردیف)
subtotal     = Σ line_total
tax_amount   = (subtotal − discount_total) × tax_percent / 100
grand_total  = subtotal − discount_total + tax_amount
balance      = grand_total − paid_amount

وضعیت پرداخت خودکار:
  paid_amount = 0                  → بدون تغییر وضعیت دستی (draft/issued)
  0 < paid_amount < grand_total    → partial
  paid_amount >= grand_total       → paid
```
