new RateSheetImport('export'), 'Import Rate' => new RateSheetImport('import'), 'DocEco' => new SimpleRateSheetImport(ShipmentType::DocEconomy, 'export'), ]; } } /** * کلاس برای پردازش شیت‌های استاندارد نرخ‌ها (Export Rate و Import Rate) */ class RateSheetImport implements OnEachRow, WithStartRow { protected int $imported = 0; protected int $skipped = 0; protected array $errors = []; public function __construct(protected string $direction) {} /** * شروع خواندن از ردیف ۵ (۴ ردیف اول هدر هستند) */ public function startRow(): int { return 5; } /** * پردازش هر ردیف از شیت */ public function onRow(Row $row) { $rowIndex = $row->getIndex(); $cells = $row->toArray(); // بررسی اعتبار ستون وزن (ستون اول) if (empty($cells[0]) || !is_numeric($cells[0])) { $this->skipped++; return; } try { // تشخیص نوع سرویس (Doc یا Parcel) $type = $this->resolveType($rowIndex, $cells); // استخراج و نرمال‌سازی قیمت‌های ۱۰ زون $zones = []; for ($i = 1; $i <= 10; $i++) { $val = str_replace([',', ' '], '', (string) ($cells[$i] ?? 0)); $zones['zone_' . $i] = is_numeric($val) ? (float) $val : 0; } // ثبت یا به‌روزرسانی نرخ در دیتابیس ShippingRate::updateOrCreate( [ 'direction' => $this->direction, // export یا import 'type' => $type->value, 'weight' => (float) $cells[0], ], $zones ); $this->imported++; } catch (\Throwable $e) { $this->errors[] = "Row $rowIndex: " . $e->getMessage(); $this->skipped++; } } /** * دریافت آمار عملیات ایمپورت */ public function getStats(): array { return [ 'imported' => $this->imported, 'skipped' => $this->skipped, 'errors' => $this->errors, ]; } /** * تشخیص نوع سرویس بر اساس محتوای ردیف */ private function resolveType(int $rowIndex, array $cells): ShipmentType { $header = strtoupper((string) ($cells[3] ?? '')); if (str_contains($header, 'DOCUMENT') || str_contains($header, 'DOC')) { return ShipmentType::DocNormal; } if (str_contains($header, 'NON') || str_contains($header, 'PARCEL')) { return ShipmentType::Parcel; } // اگر نوع مشخص نبود، بر اساس شماره ردیف حدس می‌زنیم return $rowIndex < 10 ? ShipmentType::DocNormal : ShipmentType::Parcel; } } /** * کلاس برای پردازش شیت ساده‌تر نرخ‌ها (DocEco) */ class SimpleRateSheetImport implements OnEachRow, WithStartRow { protected int $imported = 0; protected int $skipped = 0; protected array $errors = []; public function __construct( protected ShipmentType $type, protected string $direction = 'export' ) {} /** * شروع خواندن از ردیف ۲ (۱ ردیف اول هدر است) */ public function startRow(): int { return 2; } /** * پردازش هر ردیف از شیت */ public function onRow(Row $row) { $cells = $row->toArray(); // بررسی اعتبار ستون وزن (ستون اول) if (empty($cells[0]) || !is_numeric($cells[0])) { $this->skipped++; return; } try { $weight = (float) $cells[0]; $zoneNumber = (int) $cells[1]; $rawValue = str_replace([',', ' '], '', (string) ($cells[2] ?? 0)); $rawValue = is_numeric($rawValue) ? (float) $rawValue : 0; // بررسی اعتبار شماره زون و قیمت if ($zoneNumber < 1 || $zoneNumber > 10 || $rawValue <= 0) { $this->skipped++; return; } // نرخ‌ها به صورت AED در دیتابیس ذخیره می‌شوند $value = $rawValue; $zoneColumn = 'zone_' . $zoneNumber; // ایجاد مقادیر پیش‌فرض برای زون‌ها $defaults = []; for ($i = 1; $i <= 10; $i++) { $defaults['zone_' . $i] = 0; } // یافتن یا ایجاد رکورد و به‌روزرسانی قیمت زون $record = ShippingRate::firstOrCreate( [ 'direction' => $this->direction, 'type' => $this->type->value, 'weight' => $weight, ], $defaults ); $record->{$zoneColumn} = $value; $record->save(); $this->imported++; } catch (\Throwable $e) { $this->errors[] = "Row " . $row->getIndex() . ": " . $e->getMessage(); $this->skipped++; } } /** * دریافت آمار عملیات ایمپورت */ public function getStats(): array { return [ 'imported' => $this->imported, 'skipped' => $this->skipped, 'errors' => $this->errors, ]; } }