ifnex/04_Laravel/database/seeders/SampleShippingRatesSeeder.php
Kazem Alghasi 4ee1d27d44 feat: Complete customer ordering system (Phase 3)
Laravel Backend:
- Add AuthController for Sanctum token login/logout
- Add CustomerOrderController with 6 endpoints
  (profile, countries, orders CRUD, cancel)
- Extend ShipmentStatus enum with pending_payment/cancelled
- Add SampleShippingRatesSeeder (10 zones, 3 service types)
- Zone-assign 232 countries (Gulf=1, Asia=2, EU=3, East=4, US=5)
- Add migration to extend shipments.status enum
- Add test-api.php automated test suite (5 tests)

WordPress Frontend:
- Add [ifnex_order_form] multi-step wizard (4 steps)
- Add [ifnex_orders_list] with status filter & cancel action
- Add [ifnex_user_profile] with wallet & stats
- Add ifnex-orders.css (RTL-ready, IFNEX theme)
- Add ifnex-order-form.js (step navigation + AJAX)
- Add AJAX handlers (countries, calculate, submit, cancel)
- Fix plugin asset paths with dirname(__FILE__)
2026-08-10 06:09:56 +03:30

214 lines
8.6 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Database\Seeders;
use App\Models\Country;
use App\Models\ShippingRate;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Schema;
class SampleShippingRatesSeeder extends Seeder
{
public function run(): void
{
// بررسی zoneهای موجود در جدول
$allColumns = Schema::getColumnListing('shipping_rates');
$zoneColumns = array_filter($allColumns, fn($col) => str_starts_with($col, 'zone_'));
$zoneCount = count($zoneColumns);
$this->command->info("📊 Found {$zoneCount} zones in shipping_rates table");
$this->command->info(" Zones: " . implode(', ', $zoneColumns));
$this->command->info('');
// ─── نرخ پایه برای هر zone (PARCEL Export) ──────────
// قیمت‌ها به درهم برای وزن‌های مختلف
// Zone 1: نزدیک‌ترین (Gulf)
// Zone 2-5: متوسط تا دور
// Zone 6+: خیلی دور (با ۲۰٪ افزایش نسبت به zone قبلی)
$baseParcelRates = [
0.5 => [25, 35, 50, 65, 85],
1.0 => [40, 55, 80, 100, 130],
2.0 => [65, 90, 130, 165, 210],
5.0 => [120, 170, 240, 310, 400],
10.0 => [200, 290, 410, 530, 680],
20.0 => [350, 510, 720, 930, 1200],
30.0 => [480, 700, 990, 1280, 1650],
];
$this->command->info('📦 Creating Export Parcel rates...');
foreach ($baseParcelRates as $weight => $zones) {
$rateData = [
'direction' => 'export',
'type' => 'PARCEL',
'weight' => $weight,
];
// اضافه کردن zoneهای موجود
for ($i = 1; $i <= $zoneCount; $i++) {
if (isset($zones[$i - 1])) {
$rateData["zone_{$i}"] = $zones[$i - 1];
} else {
// Zone بیشتر از ۵ = افزایش ۲۰٪ نسبت به قبلی
$prevZone = $rateData["zone_" . ($i - 1)] ?? end($zones);
$rateData["zone_{$i}"] = round($prevZone * 1.2);
}
}
ShippingRate::firstOrCreate(
[
'direction' => 'export',
'type' => 'PARCEL',
'weight' => $weight,
],
$rateData
);
}
$this->command->info(' ✅ ' . count($baseParcelRates) . ' Parcel rates created');
// ─── DOC_NORMAL Export ────────────────────────
$baseDocNormalRates = [
0.5 => [30, 42, 60, 78, 100],
1.0 => [50, 70, 100, 130, 165],
2.0 => [80, 110, 160, 205, 260],
5.0 => [150, 210, 300, 390, 500],
10.0 => [250, 360, 510, 660, 850],
];
$this->command->info('📄 Creating Export DOC_NORMAL rates...');
foreach ($baseDocNormalRates as $weight => $zones) {
$rateData = [
'direction' => 'export',
'type' => 'DOC_NORMAL',
'weight' => $weight,
];
for ($i = 1; $i <= $zoneCount; $i++) {
if (isset($zones[$i - 1])) {
$rateData["zone_{$i}"] = $zones[$i - 1];
} else {
$prevZone = $rateData["zone_" . ($i - 1)] ?? end($zones);
$rateData["zone_{$i}"] = round($prevZone * 1.2);
}
}
ShippingRate::firstOrCreate(
[
'direction' => 'export',
'type' => 'DOC_NORMAL',
'weight' => $weight,
],
$rateData
);
}
$this->command->info(' ✅ ' . count($baseDocNormalRates) . ' DOC_NORMAL rates created');
// ─── DOC_ECONOMY Export ───────────────────────
$baseDocEconomyRates = [
0.5 => [20, 28, 40, 52, 67],
1.0 => [35, 48, 68, 88, 112],
2.0 => [55, 76, 108, 140, 178],
5.0 => [105, 145, 208, 270, 345],
];
$this->command->info('📃 Creating Export DOC_ECONOMY rates...');
foreach ($baseDocEconomyRates as $weight => $zones) {
$rateData = [
'direction' => 'export',
'type' => 'DOC_ECONOMY',
'weight' => $weight,
];
for ($i = 1; $i <= $zoneCount; $i++) {
if (isset($zones[$i - 1])) {
$rateData["zone_{$i}"] = $zones[$i - 1];
} else {
$prevZone = $rateData["zone_" . ($i - 1)] ?? end($zones);
$rateData["zone_{$i}"] = round($prevZone * 1.2);
}
}
ShippingRate::firstOrCreate(
[
'direction' => 'export',
'type' => 'DOC_ECONOMY',
'weight' => $weight,
],
$rateData
);
}
$this->command->info(' ✅ ' . count($baseDocEconomyRates) . ' DOC_ECONOMY rates created');
// ─── Update Country Zones ─────────────────────
$this->command->info('');
$this->command->info('🌍 Updating country zones...');
// امارات و کشورهای حاشیه خلیج فارس = Zone 1
$zone1IsoCodes = ['AE', 'QA', 'KW', 'BH', 'OM', 'SA', 'IQ', 'TR'];
Country::whereIn('iso_code', $zone1IsoCodes)->update([
'export_zone_parcel' => 1,
'export_zone_doc' => 1,
'import_zone_parcel' => 1,
'import_zone_doc' => 1,
]);
$this->command->info(' ✅ Zone 1 (Gulf): ' . count($zone1IsoCodes) . ' countries');
// خاورمیانه و آسیای مرکزی = Zone 2
$zone2IsoCodes = ['PK', 'IN', 'AF', 'AZ', 'AM', 'GE', 'KZ', 'UZ', 'TM', 'TJ', 'KG'];
Country::whereIn('iso_code', $zone2IsoCodes)->update([
'export_zone_parcel' => 2,
'export_zone_doc' => 2,
'import_zone_parcel' => 2,
'import_zone_doc' => 2,
]);
$this->command->info(' ✅ Zone 2 (Central Asia): ' . count($zone2IsoCodes) . ' countries');
// اروپا = Zone 3
$europeanCountries = Country::whereIn('iso_code', [
'DE', 'FR', 'IT', 'ES', 'GB', 'NL', 'BE', 'AT', 'CH', 'SE', 'NO', 'DK',
'FI', 'IE', 'PT', 'GR', 'PL', 'CZ', 'HU', 'RO', 'BG', 'HR', 'SI', 'SK',
'EE', 'LV', 'LT'
])->update([
'export_zone_parcel' => 3,
'export_zone_doc' => 3,
'import_zone_parcel' => 3,
'import_zone_doc' => 3,
]);
$this->command->info(" ✅ Zone 3 (Europe): {$europeanCountries} countries");
// شرق آسیا = Zone 4
$zone4IsoCodes = ['CN', 'JP', 'KR', 'SG', 'MY', 'TH', 'VN', 'PH', 'ID', 'TW', 'HK'];
Country::whereIn('iso_code', $zone4IsoCodes)->update([
'export_zone_parcel' => 4,
'export_zone_doc' => 4,
'import_zone_parcel' => 4,
'import_zone_doc' => 4,
]);
$this->command->info(' ✅ Zone 4 (East Asia): ' . count($zone4IsoCodes) . ' countries');
// آمریکا = Zone 5
$zone5IsoCodes = ['US', 'CA', 'MX', 'BR', 'AR', 'CL', 'AU', 'NZ'];
Country::whereIn('iso_code', $zone5IsoCodes)->update([
'export_zone_parcel' => 5,
'export_zone_doc' => 5,
'import_zone_parcel' => 5,
'import_zone_doc' => 5,
]);
$this->command->info(' ✅ Zone 5 (Americas/Oceania): ' . count($zone5IsoCodes) . ' countries');
// کشورهای باقی‌مانده = Zone 6 (اگر وجود دارد) یا Zone 5
$defaultZone = $zoneCount >= 6 ? 6 : ($zoneCount >= 5 ? 5 : min($zoneCount, 3));
$updated = Country::whereNull('export_zone_parcel')
->orWhere('export_zone_parcel', 0)
->update([
'export_zone_parcel' => $defaultZone,
'export_zone_doc' => $defaultZone,
'import_zone_parcel' => $defaultZone,
'import_zone_doc' => $defaultZone,
]);
$this->command->info(" ✅ Remaining → Zone {$defaultZone}: {$updated} countries");
$this->command->info('');
$this->command->info('🎉 All shipping rates and zones seeded successfully!');
}
}