getIndex(); $rowArray = $row->toArray(); try { // استخراج و نرمال‌سازی داده‌ها از ردیف اکسل $awbNo = $this->normalizeAwb($rowArray['awb'] ?? null); $eventDate = $this->normalizeDate($rowArray['date'] ?? null); $eventTime = $this->normalizeTime($rowArray['time'] ?? null); $eventDescription = $this->normalizeDescription($rowArray['state'] ?? null); $location = $this->normalizeLocation($rowArray['country'] ?? null); $deliveryStatus = $this->normalizeDeliveryStatus($rowArray['last_state'] ?? null); // بررسی اعتبار داده‌های ضروری if (!$awbNo || !$eventDate || !$eventDescription) { $this->skippedEvents++; return; } // جستجوی مرسوله بر اساس AWB $shipment = Shipment::where('awb_no', $awbNo)->first(); // اگر مرسوله وجود نداشت، آن را ایجاد کن if (!$shipment) { $shipment = $this->createShipmentFromTrackingRow($rowArray, $awbNo, $location); $this->createdShipments++; } // ثبت رویداد ترکینگ ShipmentTrackingEvent::create([ 'shipment_id' => $shipment->id, 'event_date' => $eventDate, 'event_time' => $eventTime, 'location' => $location, 'event_description' => $eventDescription, 'delivery_status' => $deliveryStatus, 'source' => 'manual', ]); $this->importedEvents++; } catch (\Throwable $e) { $this->skippedEvents++; $this->errors[] = "Row {$rowIndex}: " . $e->getMessage(); Log::error('Tracking import error', ['row' => $rowIndex, 'error' => $e->getMessage()]); } } protected function createShipmentFromTrackingRow(array $row, string $awbNo, ?string $location): Shipment { // استخراج نام کشور از لوکیشن $countryName = $location ? explode(' - ', $location)[0] : null; $country = Country::where('name', 'like', "%{$countryName}%")->first(); // تعیین وضعیت مرسوله بر اساس آخرین وضعیت $lastState = strtolower($row['last_state'] ?? ''); $status = 'processed'; if (str_contains($lastState, 'delivered')) $status = 'delivered'; elseif (str_contains($lastState, 'in transit')) $status = 'in_transit'; elseif (str_contains($lastState, 'picked')) $status = 'picked_up'; elseif (str_contains($lastState, 'out for delivery')) $status = 'out_for_delivery'; elseif (str_contains($lastState, 'failed')) $status = 'failed'; // ایجاد مرسوله جدید با مقادیر پیش‌فرض return Shipment::create([ 'awb_no' => $awbNo, 'direction' => 'export', 'type' => 'PARCEL', 'status' => $status, 'weight' => 0, 'volumetric_weight' => 0, 'chargeable_weight' => 0, 'shipping_price' => 0, 'extra_service' => 0, 'packing_cost' => 0, 'domestic_pickup' => 0, 'domestic_delivery' => 0, 'warehousing_cost' => 0, 'vat_amount' => 0, 'discount' => 0, 'total_fee' => 0, 'net_dirham' => 0, 'net_rial' => 0, 'from_country_id' => Country::where('name', 'Iran')->first()?->id, 'to_country_id' => $country?->id, 'sender_name' => 'Unknown', 'receiver_name' => 'Unknown', ]); } // --- متدهای کمکی برای نرمال‌سازی داده‌ها --- protected function normalizeAwb($value): ?string { if (!$value) return null; $value = trim($value); return $value === '' || $value === '0' ? null : $value; } protected function normalizeDate($value): ?string { if (!$value) return null; if ($value instanceof \DateTime) { return $value->format('Y-m-d'); } $value = trim($value); if ($value === '' || $value === '1899-12-31') return null; try { return date('Y-m-d', strtotime($value)); } catch (\Throwable $e) { return null; } } protected function normalizeTime($value): ?string { if (!$value) return null; if ($value instanceof \DateTime) { return $value->format('H:i:s'); } $value = trim($value); if ($value === '' || $value === '1899-12-31') return null; try { return date('H:i:s', strtotime($value)); } catch (\Throwable $e) { return null; } } protected function normalizeDescription($value): ?string { if (!$value) return null; $value = trim($value); return $value === '' ? null : $value; } protected function normalizeLocation($value): ?string { if (!$value) return null; $value = trim($value); return $value === '' || $value === '.' ? null : $value; } protected function normalizeDeliveryStatus($value): ?string { if (!$value) return null; $value = trim($value); if ($value === '') return null; $statuses = [ 'processed' => 'processed', 'picked up' => 'picked_up', 'in transit' => 'in_transit', 'out for delivery' => 'out_for_delivery', 'failed' => 'failed', 'delivered' => 'delivered', 'returned' => 'returned', ]; $lower = strtolower($value); foreach ($statuses as $key => $status) { if (str_contains($lower, $key)) { return $status; } } return null; } // --- متدهای دریافت آمار --- public function getImportedEvents(): int { return $this->importedEvents; } public function getSkippedEvents(): int { return $this->skippedEvents; } public function getErrors(): array { return $this->errors; } public function getCreatedShipments(): int { return $this->createdShipments; } }