ifnex/04_Laravel
Kazem Alghasi 48c88e9bc7 refactor(shipment): update direction enums and shipment import logic
Refactor the shipment direction logic from 'outbound/inbound' to 'export/import' to align with the new database schema requirements. This includes updating the `ShippingRatesImport` logic, adjusting the Excel import sheet mappings, and removing the AED to IRR conversion during import as rates are now stored in AED.

Additionally, updated the shipment view action to open PDF documents in a new tab and updated the Phase 0 checklist with the new database schema requirements.

- docs: update Phase 0 checklist with new schema requirements
- refactor(ui): update shipment view actions to open in new tab
- refactor(import): update shipping rates import to use new direction enums and AED values
- docs: add file map and new excel document
2026-08-23 21:33:56 +03:30
..
.postman feat(wallet): complete wallet system with admin adjust, freeze/unfreeze, activity logs 2026-08-07 22:51:42 +03:30
app refactor(shipment): update direction enums and shipment import logic 2026-08-23 21:33:56 +03:30
bootstrap feat(laravel): implement user synchronization and shipment schema 2026-08-08 04:58:01 +03:30
config feat: Complete customer ordering and payment system (Phases 1-4) 2026-08-10 13:08:52 +03:30
database feat: Complete customer ordering and payment system (Phases 1-4) 2026-08-10 13:08:52 +03:30
postman feat(wallet): complete wallet system with admin adjust, freeze/unfreeze, activity logs 2026-08-07 22:51:42 +03:30
public feat(finance): implement Filament admin panel and expand wallet/discount features 2026-08-08 03:15:51 +03:30
resources refactor(ui): redesign admin dashboard widgets and exchange service 2026-08-10 04:08:29 +03:30
routes refactor: improve hero section responsiveness and update admin path 2026-08-12 11:58:46 +03:30
storage feat: Complete Phase 1 core logic and WP bridge setup 2026-08-01 04:01:22 +03:30
tests feat(finance): implement Filament admin panel and expand wallet/discount features 2026-08-08 03:15:51 +03:30
.editorconfig feat: Complete Phase 1 core logic and WP bridge setup 2026-08-01 04:01:22 +03:30
.env.example feat(wallet): complete wallet system with admin adjust, freeze/unfreeze, activity logs 2026-08-07 22:51:42 +03:30
.phpunit.result.cache feat(ui): implement unified design system and financial reporting 2026-08-08 06:13:09 +03:30
artisan feat: Complete Phase 1 core logic and WP bridge setup 2026-08-01 04:01:22 +03:30
composer.json feat(auth): implement role-based access control using spatie/laravel-permission 2026-08-10 02:44:23 +03:30
composer.lock feat(auth): implement role-based access control using spatie/laravel-permission 2026-08-10 02:44:23 +03:30
echo feat(wallet): complete wallet system with admin adjust, freeze/unfreeze, activity logs 2026-08-07 22:51:42 +03:30
package.json feat: Complete Phase 1 core logic and WP bridge setup 2026-08-01 04:01:22 +03:30
phpunit.xml feat: Complete Phase 1 core logic and WP bridge setup 2026-08-01 04:01:22 +03:30
README.md docs: update project documentation and roadmap to reflect phase 2 and 3 completion 2026-08-10 18:12:49 +03:30
vite.config.js feat: Complete Phase 1 core logic and WP bridge setup 2026-08-01 04:01:22 +03:30


📄 فایل ۲: 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.