ifnex/04_Laravel/README.md
Kazem Alghasi cd8021e6e1 docs: update project documentation and roadmap to reflect phase 2 and 3 completion
Update project documentation, status reports, and technical READMEs to
reflect the successful completion of Phase 2 (Financial Automation) and
Phase 3 (Customer Portal & WordPress Integration).

Changes include:
- Updated `STATUS.md` and `README.md` to mark Phases 2 and 3 as completed
- Updated `01_Documents/IFNEX_Phase0_Checklist.md` with detailed task
  completion status for Phases 1, 2, and 3
- Refined technical architecture documentation in `04_Laravel/README.md`
  to include new services (Zarinpal, OrderPayment), controllers (Auth,
  CustomerOrder), and Filament resources (Wallet, Payment, DiscountCode)
- Added `DEPLOYMENT.md` for deployment instructions
- Updated system specifications to include Laravel Sanctum, RBAC via
  spatie/laravel-permission, and the updated WordPress/IFNEX Bridge
  capabilities
2026-08-10 18:12:49 +03:30

20 KiB
Raw Blame History


📄 فایل ۲: 04_Laravel/README.md (پوشه لاراول)

# 🚀 IFNEX Laravel Backend
> هسته مرکزی سیستم مدیریت لجستیک ایف‌نکس

| مورد | توضیحات |
| :--- | :--- |
| **نسخه لاراول** | Laravel 11.x |
| **نسخه PHP** | PHP 8.2+ |
| **پنل ادمین** | Filament 3.3.x |
| **دیتابیس** | MySQL 8+ |
| **تاریخ آخرین به‌روزرسانی** | 2026-08-10 |

---

## 📋 فهرست مطالب

1. [پیش‌نیازها](#پیشنیازها)
2. [نصب و راه‌اندازی](#نصب-و-راهاندازی)
3. [ساختار پوشه‌ها](#ساختار-پوشهها)
4. [API Endpoints](#api-endpoints)
5. [Artisan Commands](#artisan-commands)
6. [تست‌ها](#تستها)
7. [پیکربندی](#پیکربندی)
8. [نکات امنیتی](#نکات-امنیتی)

---

## پیش‌نیازها

قبل از شروع، مطمئن شوید که موارد زیر روی سیستم شما نصب هستند:

| ابزار | نسخه حداقل | نصب |
|-------|-----------|-----|
| PHP | 8.2+ | [دانلود](https://www.php.net/downloads) |
| Composer | 2.x | [دانلود](https://getcomposer.org/) |
| MySQL | 8+ | [دانلود](https://dev.mysql.com/downloads/) |
| Node.js & NPM | 18+ | [دانلود](https://nodejs.org/) (اختیاری - برای WordPress tools) |
| XAMPP/WAMP | آخرین نسخه | [دانلود](https://www.apachefriends.org/) (پیشنهادی برای Windows) |

---

## نصب و راه‌اندازی

### ۱. کلون مخزن و ورود به پوشه لاراول

```bash
# کلون مخزن
git clone https://www.git.vernahost.ir/gitmodir110/ifnex.git

# ورود به پوشه لاراول
cd ifnex/04_Laravel


۲. نصب پکیج‌های Composer
composer install

۳. کپی فایل محیط و تنظیم دیتابیس
# کپی فایل محیط
cp .env.example .env

# ویرایش فایل .env و تنظیم اطلاعات دیتابیس
nano .env  # یا هر ویرایشگر دلخواه

تنظیمات مهم در فایل .env:
# دیتابیس
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=ifnex_db
DB_USERNAME=root
DB_PASSWORD=

# API Key برای ترکینگ
IFNEX_API_KEY=ifnex-local-dev-key

# CORS - فقط دامنه وردپرس
CORS_ALLOWED_ORIGINS=http://localhost:8080

# Rate Limiting
IFNEX_TRACKING_RATE_LIMIT=60

# Currency API (برای فاز ۲)
CURRENCY_API_KEY=your_api_key_here


۴. تولید کلید اپلیکیشن
php artisan key:generate


۵. ایجاد دیتابیس
# ورود به MySQL
mysql -u root -p

# ایجاد دیتابیس
CREATE DATABASE ifnex_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
EXIT;

۶. اجرای Migration ها
php artisan migrate --force

۷. درج داده‌های اولیه (Seeders)
# این دستور ۲۳۳ کشور + تنظیمات اولیه + کاربر ادمین را ایجاد می‌کند
php artisan db:seed --force

اطلاعات ورود پیش‌فرض به پنل ادمین:
URL: http://localhost:8000/admin
Email: admin@ifnex.local
Password: password (در Seeder تنظیم شده)

۸. اجرای سرور توسعه
php artisan serve

اکنون پروژه در http://localhost:8000 قابل دسترسی است.


ساختار پوشه‌ها
04_Laravel/
├── app/
│   ├── Models/                    # مدل‌های Eloquent
│   │   ├── Country.php           # کشورها با ۴ زون
│   │   ├── Shipment.php          # مرسولات
│   │   ├── ShipmentItem.php      # اقلام گمرکی (۹ ردیف)
│   │   ├── ShippingRate.php      # تعرفه‌های حمل
│   │   ├── ShipmentCarrierMapping.php  # نگاشت کدهای ترکینگ
│   │   ├── ShipmentTrackingEvent.php   # رویدادهای ترکینگ
│   │   ├── SystemSetting.php     # تنظیمات سیستم
│   │   └── User.php              # کاربران
│   │
│   ├── Enums/                    # Enum ها
│   │   ├── ShipmentDirection.php # import/export
│   │   ├── ShipmentType.php      # DOC_NORMAL/DOC_ECONOMY/PARCEL
│   │   ├── ShipmentStatus.php    # ۹ وضعیت مرسوله
│   │   ├── CarrierCode.php       # ۹ شرکت حمل
│   │   ├── TrackingSource.php    # ۵ منبع (manual, api, import, system, customer)
│   │   ├── TransactionType.php
│   │   ├── TransactionStatus.php
│   │   ├── PaymentGateway.php     # ۴ درگاه (zarinpal, wallet, manual, system)
│   │   └── UserRole.php
│   │
│   ├── Services/                 # لایه سرویس (Business Logic)
│   │   ├── PriceCalculatorService.php
│   │   ├── TrackingService.php
│   │   ├── ExchangeRateService.php
│   │   ├── ZarinpalService.php
│   │   ├── MockZarinpalService.php
│   │   └── OrderPaymentService.php
│   │
│   ├── Http/
│   │   ├── Controllers/
│   │   │   ├── Api/
│   │   │   │   ├── TrackController.php
│   │   │   │   ├── PricingController.php
│   │   │   │   ├── AuthController.php              # ورود/خروج Sanctum
│   │   │   │   ├── BridgeAuthController.php        # لاگین از پلاگین وردپرس
│   │   │   │   ├── WalletController.php
│   │   │   │   ├── PaymentController.php
│   │   │   │   ├── DiscountCodeController.php
│   │   │   │   └── Customer/
│   │   │   │       └── CustomerOrderController.php # ۶ endpoint سفارش مشتری
│   │   │   ├── OrderController.php
│   │   │   ├── PricingPageController.php
│   │   │   └── ShipmentPdfController.php
│   │   ├── Middleware/
│   │   │   └── ApiKeyMiddleware.php
│   │   └── Requests/
│   │
│   ├── Imports/                  # Excel Imports
│   │   ├── ShippingRatesImport.php           # واردات تعرفه‌ها
│   │   ├── HistoricalShipmentsImport.php     # واردات مرسولات تاریخی
│   │   └── RateSheetImport.php               # شیت‌های نرخ
│   │
│   ├── Console/Commands/         # Artisan Commands
│   │   ├── ImportShippingRates.php
│   │   ├── ImportHistoricalData.php
│   │   ├── UpdateExchangeRates.php
│   │   ├── SyncWordPressUsers.php
│   │   └── DebugImportCommand.php
│   │
│   └── Filament/                 # پنل ادمین Filament
│       ├── Resources/
│       │   ├── CountryResource.php
│       │   ├── ShipmentResource.php
│       │   ├── ShippingRateResource.php
│       │   ├── ShipmentItemResource.php
│       │   ├── WalletResource.php
│       │   ├── WalletTransactionResource.php
│       │   ├── PaymentResource.php
│       │   ├── DiscountCodeResource.php
│       │   ├── ExchangeRateHistoryResource.php
│       │   ├── RoleResource.php
│       │   └── UserResource.php
│       ├── Widgets/
│       │   ├── DashboardInfoWidget.php
│       │   ├── ExchangeRateWidget.php
│       │   ├── WalletStats.php
│       │   ├── TransactionChartWidget.php
│       │   └── RecentTransactionsWidget.php
│       └── Pages/
│           ├── IfnexSettingsPage.php
│           ├── PriceTestPage.php
│           └── Reports/
│               └── FinancialReport.php
│
├── database/
│   ├── migrations/               # Migration ها
│   │   ├── 2026_08_02_000001_create_countries_table.php
│   │   ├── 2026_08_02_000002_create_shipments_table.php
│   │   ├── 2026_08_02_000003_create_shipping_rates_table.php
│   │   ├── 2026_08_02_000004_create_shipment_carrier_mappings_table.php
│   │   ├── 2026_08_02_000005_create_shipment_tracking_events_table.php
│   │   ├── 2026_08_02_000006_create_system_settings_table.php
│   │   ├── 2026_08_02_000007_update_users_table.php
│   │   ├── 2026_08_08_000001_create_shipment_items_table.php
│   │   ├── 2026_08_05_135026_create_discount_codes_table.php
│   │   ├── 2026_08_09_231738_create_exchange_rate_history_table.php
│   │   ├── 2026_08_10_080853_add_wallet_to_payment_gateway_enum.php
│   │   ├── 2026_08_10_082121_add_system_to_tracking_source_enum.php
│   │   ├── 2026_08_09_012526_create_notifications_table.php
│   │   └── 2026_08_09_220409_create_permission_tables.php
│   └── seeders/                  # Seeders
│       ├── CountriesTableSeeder.php
│       ├── SystemSettingSeeder.php
│       ├── DatabaseSeeder.php
│       ├── RoleAndPermissionSeeder.php
│       └── SampleDataSeeder.php
│
├── routes/
│   ├── web.php                   # روت‌های وب (فرم‌ها و صفحات)
│   └── api.php                   # روت‌های API
│
├── resources/views/
│   ├── layouts/app.blade.php     # لایاوت اصلی
│   ├── orders/                   # فرم ثبت سفارش
│   ├── pricing/                  # صفحه استعلام قیمت
│   └── pdfs/                     # قالب‌های PDF
│
├── config/
│   ├── ifnex.php                 # تنظیمات اختصاصی IFNEX
│   └── cors.php                  # تنظیمات CORS
│
├── tests/
│   └── Feature/
│       └── Services/
│           └── PriceCalculatorServiceTest.php  # ⭐ تست‌های موتور قیمت
│
├── bootstrap/
│   └── app.php                   # Bootstrap لاراول ۱۱
│
├── .env.example                  # نمونه فایل محیط
├── composer.json                 # وابستگی‌های Composer
└── README.md                     # این فایل


API Endpoints

🔓 API های عمومی (نیاز به API Key)

۱. رهگیری مرسوله
GET /api/v1/track/{awb_no}

Headers:
Authorization: Bearer {IFNEX_API_KEY}

مثال:
curl -H "Authorization: Bearer ifnex-local-dev-key" \
     http://localhost:8000/api/v1/track/980100010

     پاسخ موفق (200 OK):
  {
  "success": true,
  "data": {
    "awb_no": "980100010",
    "status": "delivered",
    "carrier_mappings": [...],
    "tracking_events": [...]
  }
}

۲. استعلام قیمت
POST /api/v1/calculate

Body (JSON):
{
  "direction": "export",
  "type": "DOC_NORMAL",
  "country_iso": "US",
  "weight": 2.5,
  "volumetric_weight": 3.0,
  "extra_service": 10.00
}

مثال:
curl -X POST http://localhost:8000/api/v1/calculate \
     -H "Content-Type: application/json" \
     -d '{
       "direction": "export",
       "type": "DOC_NORMAL",
       "country_iso": "US",
       "weight": 2.5,
       "volumetric_weight": 3.0
     }'

     پاسخ موفق:
{
  "base_price": 40.00,
  "net_dirham": 50.00,
  "net_rial": 22750000,
  "total_fee": 24906510.9,
  "zone": 1,
  "chargeable_weight": 3.0
}

💳 API های کیف پول (فاز ۲)

۱. بررسی موجودی
GET /api/v1/wallet/balance

۲. شارژ کیف پول
POST /api/v1/wallet/charge

Body:

{
  "amount": 1000000,
  "description": "شارژ اولیه"
}

۳. تاریخچه تراکنش‌ها
GET /api/v1/wallet/transactions

🎟️ API های تخفیف (فاز ۲)
۱. لیست کدهای تخفیف فعال

GET /api/v1/discount-codes/active

۲. اعتبارسنجی کد تخفیف
POST /api/v1/discount-codes/validate

Body:
{
  "code": "SUMMER20",
  "amount": 1000000
}

🔐 API های احراز هویت (فاز ۳)

۱. ورود و دریافت توکن Sanctum
POST /api/v1/auth/login

Body:
{
  "email": "user@example.com",
  "password": "password",
  "token_name": "api-token"
}

۲. خروج و حذف توکن
POST /api/v1/auth/logout

Header: Authorization: Bearer {token}

🛒 API های سفارشات مشتری (فاز ۳)

۱. پروفایل و آمار کاربر
GET /api/v1/customer/profile

۲. لیست کشورها برای فرم سفارش
GET /api/v1/customer/countries

۳. لیست سفارشات کاربر
GET /api/v1/customer/orders

۴. ثبت سفارش جدید
POST /api/v1/customer/orders

Body:
{
  "direction": "export",
  "type": "PARCEL",
  "from_country_id": 1,
  "to_country_id": 2,
  "weight": 2.5,
  "sender_name": "نام فرستنده",
  "sender_phone": "۰۹۱۲۳۴۵۶۷۸۹",
  "sender_address": "آدرس",
  "receiver_name": "نام گیرنده",
  "receiver_phone": "۰۹۱۲۳۴۵۶۷۸۹",
  "receiver_address": "آدرس",
  "items": [
    {
      "description": "کالای گمرکی",
      "hs_code": "8542390001",
      "quantity": 1,
      "unit_price": 100
    }
  ]
}

۵. جزئیات یک سفارش
GET /api/v1/customer/orders/{shipment}

۶. لغو سفارش (فقط pending_payment)
POST /api/v1/customer/orders/{shipment}/cancel

۷. پرداخت از کیف پول
POST /api/v1/customer/orders/{shipment}/pay-wallet

۸. پرداخت از درگاه بانکی
POST /api/v1/customer/orders/{shipment}/pay-gateway

Body:
{
  "frontend_callback": "https://your-wordpress.com/order-payment/"
}

🔗 API پل وردپرس (فاز ۳)

POST /api/v1/bridge/login

Body:
{
  "bridge_api_key": "ifnex-bridge-key",
  "wp_user_id": 1,
  "wp_user_email": "user@wordpress.local",
  "wp_user_name": "نام کاربر"
}


Artisan Commands
📥 واردات داده‌ها
۱. واردات تعرفه‌های حمل از اکسل

# واردات عادی
php artisan ifnex:import:rates storage/app/public/rates.xlsx

# پاک‌سازی و واردات مجدد
php artisan ifnex:import:rates storage/app/public/rates.xlsx --clear

# تست بدون ذخیره (Dry Run)
php artisan ifnex:import:rates storage/app/public/rates.xlsx --dry-run

۲. واردات مرسولات تاریخی

php artisan ifnex:import:shipments storage/app/public/historical.xlsx

💱 به‌روزرسانی نرخ ارز (فاز ۲)
# به‌روزرسانی دستی
php artisan ifnex:update-exchange-rates

# تنظیم Cron Job برای به‌روزرسانی روزانه
# crontab -e
# 0 0 * * * cd /path/to/04_Laravel && php artisan ifnex:update-exchange-rates >> /dev/null 2>&1

🔄 سینک کاربران وردپرس (فاز ۳)
# سینک دستی کاربران بین وردپرس و لاراول
php artisan ifnex:sync-wp-users

🔑 تولید توکن API (فاز ۲)
php artisan ifnex:token --user=admin@ifnex.local --name=api-token

🧪 تست‌ها
# اجرای همه تست‌ها
php artisan test

# اجرای تست‌های یک کلاس خاص
php artisan test --filter=PriceCalculatorServiceTest

# اجرای تست با نمایش دقیق
php artisan test --filter=it_calculates_price_correctly_for_standard_package

# گزارش پوشش تست (نیاز به Xdebug)
php artisan test --coverage

تست‌ها
تست‌های موجود
۱. PriceCalculatorServiceTest
این تست کلاس PriceCalculatorService را به طور کامل تست می‌کند:

php artisan test --filter=PriceCalculatorServiceTest


موارد تست شده:
✅ محاسبه صحیح قیمت برای بسته استاندارد
✅ استفاده از وزن حجمی وقتی از وزن واقعی بزرگتر است
✅ اعمال صحیح ضریب سود و VAT
✅ اعمال هزینه‌های جانبی
✅ اعمال کد تخفیف درصدی و ثابت

۲. WalletServiceTest (فاز ۲)
تست‌های مربوط به کیف پول و تراکنش‌ها:

php artisan test --filter=WalletServiceTest


۳. PaymentControllerTest (فاز ۲)
تست‌های مربوط به درگاه پرداخت:

php artisan test --filter=PaymentControllerTest


۴. DiscountCodeControllerTest (فاز ۲)
تست‌های مربوط به کدهای تخفیف:

php artisan test --filter=DiscountCodeControllerTest


نوشتن تست جدید
برای نوشتن تست جدید، از این الگو استفاده کنید:

<?php

namespace Tests\Feature\Services;

use App\Models\Country;
use App\Models\ShippingRate;
use App\Models\SystemSetting;
use App\Services\PriceCalculatorService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;

class PriceCalculatorServiceTest extends TestCase
{
    use RefreshDatabase;

    #[Test]
    public function it_calculates_price_correctly()
    {
        // 1. تنظیم SystemSetting ها
        SystemSetting::create(['key' => 'profit_margin', 'value' => 1.0]);
        SystemSetting::create(['key' => 'aed_to_irr', 'value' => 1.0]);
        SystemSetting::create(['key' => 'vat_rate', 'value' => 0.0]);
        SystemSetting::create(['key' => 'packing_cost_default', 'value' => 0]);

        // 2. ایجاد داده‌های تست
        $country = Country::factory()->create([...]);
        ShippingRate::create([...]);

        // 3. اجرای سرویس
        $service = app(PriceCalculatorService::class);
        $result = $service->calculate([...]);

        // 4. بررسی نتیجه
        $this->assertEquals(50.00, $result['total_fee']);
    }
}

پیکربندی
فایل config/ifnex.php
return [
    // API Key برای احراز هویت
    'api_key' => env('IFNEX_API_KEY', 'default-key'),

    // Rate Limiting
    'tracking_rate_limit' => env('IFNEX_TRACKING_RATE_LIMIT', 60),

    // Currency API
    'currency_api_key' => env('CURRENCY_API_KEY'),
    'currency_api_url' => env('CURRENCY_API_URL', 'https://api.freecurrencyapi.com/v1/latest'),

    // Zarinpal Payment Gateway
    'zarinpal' => [
        'merchant_id' => env('ZARINPAL_MERCHANT_ID', 'fake-merchant-id-for-testing'),
        'sandbox' => env('ZARINPAL_SANDBOX', true),
        'callback_url' => env('ZARINPAL_CALLBACK_URL', 'http://localhost:8000/api/v1/payment/callback'),
    ],

    // WordPress Bridge
    'bridge_api_key' => env('IFNEX_BRIDGE_API_KEY', 'ifnex-bridge-key'),

    // CORS
    'cors_allowed_origins' => explode(',', env('CORS_ALLOWED_ORIGINS', '*')),
];

فایل config/cors.php

return [
    'paths' => ['api/*'],
    'allowed_methods' => ['*'],
    'allowed_origins' => explode(',', env('CORS_ALLOWED_ORIGINS', '*')),
    'allowed_headers' => ['*'],
    'exposed_headers' => [],
    'max_age' => 0,
    'supports_credentials' => false,
];


نکات امنیتی
🚫 هرگز این کارها را نکنید
هرگز فایل .env را در Git کامیت نکنید

# بررسی کنید در .gitignore باشد
.env
.env.local
.env.production

هرگز APP_DEBUG=true را در محیط تولید بگذارید
# Production
APP_DEBUG=false


هرگز از CORS * در محیط تولید استفاده نکنید

# فقط دامنه وردپرس
CORS_ALLOWED_ORIGINS=https://your-wordpress-domain.com

هرگز API Key را در کد Hardcode نکنید

// ❌ اشتباه
$apiKey = 'secret-key-123';

// ✅ درست
$apiKey = config('ifnex.api_key');

🐛 عیب‌یابی
مشکل: CHECK constraint failed: direction
علت: Factory مقادیر پیش‌فرض اشتباه می‌سازد (مثلاً 'Outbound' به جای 'export')
راه‌حل: در تست‌ها از ShippingRate::create() به جای ShippingRate::factory()->create() استفاده کنید:
ShippingRate::create([
    'direction' => 'export',  // حروف کوچک
    'type' => 'DOC_NORMAL',
    'weight' => 1.0,
    'zone_1' => 20.00,
    // ... بقیه zone ها
]);


مشکل: No rate found for the given parameters
علت: Query نمی‌تواند نرخ مناسبی پیدا کند
راه‌حل:
بررسی کنید که zone_column درست است (zone_1, zone_2, ...)
مطمئن شوید که وزن در تست بیشتر از وزن‌های موجود در دیتابیس نیست
SystemSetting ها را در تست Mock کنید
📞 پشتیبانی
اگر سوالی داشتید که در این فایل یا مستندات 01_Documents پاسخ آن نبود، از کاربر (Kazem) بپرسید — حدس نزنید.
© 2026 VernaSoft Group. Internal use only.