ifnex/04_Laravel
Kazem Alghasi f61de6f3a5 refactor(ui): redesign admin dashboard widgets and exchange service
Refactor the Filament dashboard by replacing the legacy FinanceOverviewWidget
with a new set of specialized widgets:
- DashboardInfoWidget for general information
- ExchangeRateWidget for real-time rate monitoring
- WalletStats for financial overview

Additionally, refactor the ExchangeRateService to improve encapsulation
and clean up the ExchangeRateHistory model by moving business logic
(change calculation and recording) from the model to the service layer.

Changes include:
- Removing deprecated helper methods from ExchangeRateHistory model
- Implementing direct queries in ExchangeRateService to replace model scopes
- Adding support for rate chart data retrieval
- Reordering and updating widget sorting in AdminPanelProvider
2026-08-10 04:08:29 +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(ui): redesign admin dashboard widgets and exchange service 2026-08-10 04:08:29 +03:30
bootstrap feat(laravel): implement user synchronization and shipment schema 2026-08-08 04:58:01 +03:30
config feat(auth): implement role-based access control using spatie/laravel-permission 2026-08-10 02:44:23 +03:30
database feat(exchange): implement exchange rate history tracking 2026-08-10 03:04:18 +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 feat(wallet): complete online payment with Zarinpal + mock gateway 2026-08-08 00:46:54 +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(project): update project status, roadmap, and documentation 2026-08-07 05:58:12 +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-07 |

---

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

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_carrier/api_aggregator
│   │   └── UserRole.php          # ۴ نقش کاربری
│   │
│   ├── Services/                 # لایه سرویس (Business Logic)
│   │   ├── PriceCalculatorService.php  # ⭐ موتور قیمت‌گذاری
│   │   └── TrackingService.php         # سرویس ترکینگ
│   │
│   ├── Http/
│   │   ├── Controllers/
│   │   │   ├── Api/
│   │   │   │   ├── TrackController.php       # API ترکینگ
│   │   │   │   ├── PricingController.php     # API استعلام قیمت
│   │   │   │   ├── WalletController.php      # API کیف پول
│   │   │   │   └── DiscountCodeController.php # API تخفیف
│   │   │   ├── OrderController.php           # فرم ثبت سفارش
│   │   │   ├── PricingPageController.php     # صفحه استعلام قیمت
│   │   │   └── ShipmentPdfController.php     # تولید PDF
│   │   ├── Middleware/
│   │   │   └── ApiKeyMiddleware.php          # احراز هویت API
│   │   └── Requests/                         # Form Request Validation
│   │
│   ├── Imports/                  # Excel Imports
│   │   ├── ShippingRatesImport.php           # واردات تعرفه‌ها
│   │   ├── HistoricalShipmentsImport.php     # واردات مرسولات تاریخی
│   │   └── RateSheetImport.php               # شیت‌های نرخ
│   │
│   ├── Console/Commands/         # Artisan Commands
│   │   ├── ImportShippingRates.php           # واردات تعرفه‌ها
│   │   ├── ImportHistoricalData.php          # واردات داده‌های تاریخی
│   │   └── UpdateExchangeRates.php           # به‌روزرسانی نرخ ارز
│   │
│   └── Filament/                 # پنل ادمین Filament
│       ├── Resources/
│       │   ├── CountryResource.php
│       │   ├── ShipmentResource.php
│       │   ├── ShippingRateResource.php
│       │   └── ShipmentItemResource.php
│       └── Pages/
│           └── IfnexSettingsPage.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
│   └── seeders/                  # Seeders
│       ├── CountriesTableSeeder.php
│       ├── SystemSettingSeeder.php
│       └── DatabaseSeeder.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/discounts/active

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

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


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 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
✅ اعمال هزینه‌های جانبی
✅ اعمال کد تخفیف درصدی و ثابت
نوشتن تست جدید
برای نوشتن تست جدید، از این الگو استفاده کنید:

<?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'),
];

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