# سند تحویل پروژه — سیستم جامع مدیریت کسب‌وکار «پادورا»

این سند کامل وضعیت فعلی پروژه است تا توسعه‌دهنده‌ی بعدی (Claude Code در VSCode) بتواند ادامه دهد.
مسیر پروژه‌ی در حال اجرا: `C:\laragon\www\padoora` — اجرا با `php artisan serve` روی `http://127.0.0.1:8001`.

> یک نسخه‌ی پشتیبان از فایل‌های اولیه نیز در `D:\Padoora-invoice-1` هست که **عقب‌تر** از نسخه‌ی لاراگون است؛ نسخه‌ی مرجع و به‌روز همان `C:\laragon\www\padoora` است.

---

## ۱) پشته‌ی فنی و پکیج‌ها

- **Laravel 11**, **PHP 8.3** (CLI لاراگون) — توجه: PHP 8.4 هم نصب است.
- **Filament v3.2** (پنل ادمین/بک‌آفیس) — تک‌پنل به نام `admin` در مسیر `/admin`.
- **MySQL** (دیتابیس `padoora`).
- رابط کامل **فارسی RTL**، تاریخ‌ها **شمسی**.

پکیج‌های نصب‌شده (`composer.json`):
- `filament/filament ^3.2`
- `morilog/jalali ^3.4` — تاریخ شمسی
- `spatie/laravel-permission ^6` — نقش/دسترسی
- `spatie/laravel-activitylog ^4` — لاگ فعالیت
- `barryvdh/laravel-dompdf ^3` — **(دیگر استفاده نمی‌شود؛ خروجی به HTML پرینت تغییر کرد، اما پکیج هنوز نصب است)**
- `pxlrbt/filament-excel ^2.3` — خروجی اکسل جدول‌ها (به‌همراه `maatwebsite/excel`)
- `ariaieboy/filament-jalali ^1.0` — **تقویم شمسی بازشو** برای DatePicker/DateTimePicker و ستون‌ها

> پکیج `konnco/filament-import` حذف شد (ناسازگار با Laravel 11). ورودی اکسل با `maatwebsite/excel` به‌صورت دستی پیاده شد.

---

## ۲) راه‌اندازی از صفر

```bash
composer install
cp .env.example .env
php artisan key:generate
# تنظیم DB در .env: DB_DATABASE=padoora, DB_USERNAME=root, DB_PASSWORD=
php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan vendor:publish --provider="Spatie\Activitylog\ActivitylogServiceProvider" --tag="activitylog-migrations"
php artisan notifications:table
php artisan storage:link
php artisan migrate --seed
php artisan serve
# زمان‌بند (در محیط واقعی cron):
php artisan schedule:work
```

**کاربران پیش‌فرض (Seeder):** `admin@padoora.test` / `password` و `staff@padoora.test` / `password`.

**فونت:** IRANYekanX در `public/fonts/woff2|woff/` + `public/css/app-fonts.css`. روی پنل (در `AdminPanelProvider->font('Yekan', url: ...)`) و خروجی‌های چاپ اعمال می‌شود.

---

## ۳) قراردادها و درس‌های مهم (برای جلوگیری از باگ تکراری)

1. **کلوزرهای Filament بر اساس نام آرگومان تزریق می‌شوند.** فقط از `$state`، `$record`، `$get`، `$set`, `$livewire` استفاده کن. آرگومان دلخواه مثل `$s` → خطای «closure ... unresolvable». (نوع‌دهی مدل مثل `fn (Task $record)` هم کار می‌کند.)
2. **اسکوپ‌های سفارشی مثل `forUser` را داخل کلوزرِ `->relationship()` فیلامنت صدا نزن** (خطای `forUser() undefined` یا `hydrate() on null`). به‌جایش `->options(fn () => Model::query()->when(...)->pluck(...))` یا شرط inline بنویس. اسکوپ‌ها در `getEloquentQuery()` و ویجت‌ها بدون مشکل کار می‌کنند.
3. **تاریخ شمسی:** `->jalali()` روی DatePicker/DateTimePicker و `->jalaliDate()` / `->jalaliDateTime()` روی TextColumn (از پکیج ariaieboy). ماکروی دستی تعریف نکن (تداخل می‌شود). `JalaliServiceProvider` عمداً خالی است.
4. **تبدیل تصاویر به webp:** ماکروی `->webp()` روی `FileUpload` (در `AppServiceProvider`) و کلاس `App\Support\ImageWebp::store()` برای آپلودهای Livewire (چت).
5. **opcache:** سرور `php artisan serve` تغییرات کد را با ~۲ ثانیه تأخیر می‌گیرد. اگر خطای عجیب/کش‌شده دیدی: `php artisan optimize:clear`.
6. **PHP 8.4 vs 8.3:** `config/database.php` در نسخه‌ی پیش‌فرض از کلاس `Pdo\Mysql` (مخصوص 8.4) استفاده می‌کرد که روی 8.3 خطا می‌داد؛ به ثابت `PDO::MYSQL_ATTR_SSL_CA` تغییر داده شد.
7. **جدول واسط `task_user` ستون زمان ندارد** → در رابطه‌ها `withTimestamps()` استفاده نکن.
8. **DomPDF کنار گذاشته شد** چون شکل‌دهی حروف فارسی (RTL) را درست انجام نمی‌دهد. خروجی فاکتور = **صفحه‌ی HTML با دکمه‌ی پرینت** (فونت مرورگر، فارسی کامل).

---

## ۴) ساختار دیتابیس (جدول‌ها و فیلدهای کلیدی)

> همه‌ی migrationها در `database/migrations/` با پیشوند تاریخ `2026_01_01_*` (هسته)، `2026_02_01_*` (فاکتور/شرکت/رسمی)، `2026_03_01_*` (CRM/داشبورد/چت) هستند.

**هسته**
- `users`: + `phone, job_title, is_active, avatar, bonus_percent` (نقش از spatie)
- `settings` (تک‌ردیف): `company_name, logo_path, phone, email, address, economic_code, national_id, invoice_prefix, default_tax_percent(=10), invoice_header, invoice_footer, follow_up_days(=7), stale_days(=30)`
- جدول‌های spatie: `roles, permissions, model_has_*`; `activity_log`; `notifications`

**CRM**
- `customers`: `type(individual|legal), first_name, last_name, company_name, national_code, national_id, registration_number, economic_code, email, fax, status(lead|following|active|inactive), pipeline_stage_id→pipeline_stages, lost_reason, assigned_user_id→users(Owner), description`
- `customer_phones`, `customer_addresses`(province/city/postal_code), `customer_emails`(چند ایمیل)
- `interactions`: `customer_id, user_id, type(call|meeting|email|note), subject, description, interacted_at`
- `pipeline_stages`: `name, color, sort, is_won, is_lost` (۶ مرحله‌ی پیش‌فرض seed شده)
- `tags` + `customer_tag` (pivot)
- `customer_documents`: `customer_id, title, type(contract|identity|license|insurance|other), file_path, expires_at`
- `message_templates`: `name, channel(email|sms), subject, body`

**فاکتور**
- `products`: `name, description, unit, default_price, is_service, is_active`
- `invoices`: `number, serial_number, tax_id, contract_number, type(proforma|invoice|official), customer_id, company_id→companies, bank_account_id→bank_accounts, user_id(صادرکننده), status(draft|issued|paid|partial|void), issue_date, due_date, subtotal, discount_total, shipping_cost, tax_percent(=10), vat_enabled, layout(portrait|landscape), sale_terms(cash|credit), delivery_place, warranty, attachment(پیش‌فرض «ندارد»), tax_amount, grand_total, paid_amount, balance, notes, share_token, converted_from_id→invoices`
- `invoice_items`: `invoice_id, product_id, product_code, description, unit, quantity, unit_price, discount, line_total, note, sort`
- `payments`: `invoice_id, user_id, amount, paid_at, method(cash|card|transfer|cheque|other), note`
- `companies` (چند سربرگ): `name, tagline, logo_path, stamp_path, signature_path, signer_name, signer_title, phone, fax, email, address, province, city, postal_code, economic_code, national_id, registration_number, bank_account, header, footer, is_default`
- `bank_accounts`: `title, bank_name, account_number, sheba, card_number, holder, is_default`

**تسک / سیستم**
- `tasks`: `title, description, attachments(json), priority(low|medium|high), status(open|in_progress|done|canceled), due_date, customer_id, invoice_id, created_by, recurrence(none|daily|weekly|monthly), parent_task_id, last_notified_at`
- `task_user` (pivot، بدون timestamps)
- `login_logs`: `user_id, logged_in_at, logged_out_at, ip`
- `chat_messages`: `sender_id, receiver_id, body, attachment, attachment_name, read_at`
- `sales_targets`: `user_id, title, target_amount, target_deals, starts_at, ends_at`

محاسبه‌ی فاکتور (در `Invoice::recalculate()`):
`line_total = qty×unit_price − discount` → `subtotal = Σ` → `tax = vat_enabled ? (subtotal−discount_total)×tax_percent/100 : 0` → `grand_total = (subtotal−discount_total) + tax + shipping_cost` → `balance = grand_total − paid_amount`. وضعیت پرداخت خودکار (issued/partial/paid) در `syncPaymentStatus()`.

---

## ۵) فایل‌های کلیدی

**Models** (`app/Models/`): User, Setting, Customer, CustomerPhone, CustomerAddress, CustomerEmail, Interaction, Product, Invoice, InvoiceItem, Payment, Task, Company, BankAccount, LoginLog, ChatMessage, SalesTarget, PipelineStage, Tag, CustomerDocument, MessageTemplate.

**Policies** (`app/Policies/`): Customer, Invoice, Task, Product, User — Row-level: کارمند فقط رکوردهای `assigned_user_id`/`user_id` خودش. (اسکوپ‌های `forUser` در مدل‌های Customer/Invoice/Task.)

**Filament Resources** (`app/Filament/Resources/`):
- `CustomerResource` (+ RelationManagers: Interactions, Invoices, Tasks, Documents) — فرم کامل CRM، تگ‌ها، مرحله قیف، ایمیل‌ها، دکمه‌ی «ارسال پیام» (تکی/گروهی) و متدهای `messageFormSchema()` و `dispatchMessages()`.
- `InvoiceResource` (+ Payments RM) — سه نوع، محاسبات live، اکشن‌های چاپ/اکسل/تبدیل/تکرار/اشتراک، تب‌بندی در `Pages/ListInvoices`.
- `ProductResource`, `TaskResource`, `UserResource`, `CompanyResource`, `BankAccountResource`, `LoginLogResource`(read-only), `SalesTargetResource`, `TagResource`, `MessageTemplateResource`.

**Filament Pages** (`app/Filament/Pages/`): `ManageSettings`, `Chat`, `SalesPipeline` (کانبان Drag&Drop با SortableJS)، `TaskCalendar` (تقویم شمسی ماهانه).

**Filament Widgets** (`app/Filament/Widgets/`): StatsOverview، MonthlySalesChart (فیلتر هفته/ماه/۶ماه/سال)، TodayTasksWidget، EmployeePerformanceWidget (امتیاز عملکرد)، MySalesBonusWidget، MyTargetWidget (نوار پیشرفت هدف)، CrmAnalyticsWidget، StaleLeadsWidget، ExpiringDocumentsWidget. ترتیب با `$sort` (تسک‌ها=۱، عملکرد=۲، ...).

**Support/Logic:**
- `app/Support/NumberToWords.php` — عدد به حروف فارسی + `digits()` (اعداد فارسی) + `money()`.
- `app/Support/ImageWebp.php` — تبدیل آپلود به webp.
- `app/Support/ExcelImporter.php` + `app/Imports/RawImport.php` — خواندن اکسل برای ورودی.
- `app/Support/Sms.php` — استاب پیامک (لاگ؛ آماده‌ی اتصال به درگاه).
- `app/Http/Controllers/InvoicePdfController.php` — `print` (HTML)، `share` (توکن عمومی)، `excel`.
- `app/Exports/InvoiceExport.php` — خروجی اکسل تک‌فاکتور.
- `app/Notifications/TaskReminderNotification.php` (ایمیل + database).
- `app/Console/Commands/SendTaskReminders.php` (`tasks:send-reminders`)، `SendFollowUpReminders.php` (`crm:follow-up-reminders`).
- `app/Providers/AppServiceProvider.php` — locale fa، ماکروی webp، ثبت ورود/خروج (Login/Logout events) + نوتیف به مدیران.
- `app/Providers/Filament/AdminPanelProvider.php` — تم Teal، CSS سایدبار تیره (renderHook)، brandLogo (لوگوی شرکت پیش‌فرض)، فونت Yekan، databaseNotifications.

**Views** (`resources/views/`):
- `invoices/print.blade.php` — قالب فاکتور/پیش‌فاکتور (A4، لوگو بالای نام، جدول فروشنده/خریدار، ستون ارزش افزوده، جدول افقی مبالغ، مبلغ به حروف، امضا/مهر سمت راست، حاشیه‌ی ۶mm پرینت).
- `invoices/official.blade.php` — صورتحساب رسمی ایران (۱۱ ستونه، افقی).
- `invoices/excel.blade.php` — قالب خروجی اکسل تک‌فاکتور.
- `invoices/pdf.blade.php` — **قدیمی/dompdf، بلااستفاده** (می‌توان حذف کرد).
- `filament/pages/{manage-settings,chat,sales-pipeline,task-calendar}.blade.php`
- `filament/widgets/my-target.blade.php`

**Routes:** `routes/web.php` (`/`→admin، `invoices.print`، `invoices.share`، `invoices.excel`)؛ `routes/console.php` (زمان‌بندی یادآوری تسک ساعتی + هشدار پیگیری روزانه).

---

## ۶) وضعیت قابلیت‌ها نسبت به پرامپت جامع

**انجام‌شده:** هسته، نقش/دسترسی Row-level، تنظیمات، CRM (مشتری حقیقی/حقوقی، چند تلفن/آدرس/ایمیل، Owner، نمای ۳۶۰، تعاملات)، قیف فروش کانبان + دلیل باخت، برچسب‌ها، اسناد + انقضا، Communication Hub (ایمیل/پیامک + قالب + ثبت در تاریخچه)، هدف‌گذاری/KPI + نوار پیشرفت، گزارش تحلیلی (نرخ تبدیل/LTV/راکد)، هشدار سرنخ بدون پیگیری، فاکتور/پیش‌فاکتور/**فاکتور رسمی** کامل، پرداخت‌ها، چاپ HTML + اکسل + اشتراک، تسک کامل + یادآوری + تقویم شمسی + فایل، چت داخلی، ردیابی ورود/خروج، تم/سایدبار/لوگو/فونت/webp.

**نیازمند تکمیل/بازبینی (مهم برای توسعه‌دهنده‌ی بعدی):**
- پیامک فقط در لاگ است؛ اتصال درگاه واقعی در `App\Support\Sms`.
- ارسال ایمیل با `MAIL_MAILER=log` است؛ SMTP واقعی تنظیم شود.
- خروجی PDF واقعی نداریم (HTML+پرینت)؛ اگر PDF سروری لازم شد، `mpdf/mpdf` پیشنهاد می‌شود (نه dompdf).
- در قالب چاپ، فقط یک ایمیل/آدرس اصلی نمایش داده می‌شود (با اینکه چند ایمیل ذخیره می‌شود).
- فازهای ۹ تا ۱۴ (KPI، کانبان، تگ، اسناد، Communication، تحلیل/تقویم) کدنویسی شده ولی **هنوز در مرورگر تست کامل نشده‌اند**؛ ممکن است باگ‌های جزئی Filament داشته باشند (طبق بخش ۳ رفع شوند).
- نمای کانبان از SortableJS از CDN استفاده می‌کند (نیاز به اینترنت در مرورگر).

---

## ۷) فرمان‌های مفید

```bash
php artisan migrate                 # اعمال همه‌ی جدول‌ها
php artisan optimize:clear          # پاک‌کردن کش هنگام خطای عجیب
php artisan tasks:send-reminders    # تست یادآوری تسک
php artisan crm:follow-up-reminders # تست هشدار سرنخ راکد
php artisan schedule:work           # اجرای زمان‌بند در توسعه
```
