form->fill([ 'csv_file' => null, 'status' => 'in_transit', 'description' => '', ]); } public function form(Form $form): Form { return $form ->schema([ Forms\Components\Section::make('فایل CSV') ->schema([ Forms\Components\FileUpload::make('csv_file') ->label('فایل CSV') ->acceptedFileTypes(['text/csv', 'text/plain']) ->maxSize(10240) // 10MB ->required() ->helperText('فرمت: awb_no,status,description (هر سطر یک سفارش)'), ]), Forms\Components\Section::make('تنظیمات') ->schema([ Forms\Components\Select::make('status') ->label('وضعیت جدید') ->options(collect(ShipmentStatus::cases())->mapWithKeys(fn ($status) => [$status->value => $status->label()])->toArray()) ->default('in_transit') ->required(), Forms\Components\TextInput::make('description') ->label('توضیحات پیش‌فرض') ->placeholder('مثال: به‌روزرسانی گروهی وضعیت ترکینگ') ->default('ایمپورت گروهی وضعیت'), ]), Forms\Components\Section::make('پیش‌نمایش') ->schema([ Forms\Components\Placeholder::make('preview') ->label('پیش‌نمایش فایل') ->content(fn () => $this->getPreviewContent()), ]) ->collapsible(), ]) ->statePath('data'); } private function getPreviewContent(): string { $file = $this->data['csv_file'] ?? null; if (!$file) { return 'فایلی انتخاب نشده است. لطفاً فایل CSV را آپلود کنید.'; } try { $path = is_array($file) ? ($file['path'] ?? reset($file)) : $file; $content = file_get_contents($path); $lines = explode("\n", trim($content)); $preview = "
"; $preview .= "خط اول (هدر): " . e($lines[0] ?? '') . "
"; $preview .= "تعداد خطوط: " . count($lines) . "
"; if (isset($lines[1])) { $preview .= "
نمونه (خط دوم): " . e($lines[1]); } $preview .= "
"; return $preview; } catch (\Exception $e) { return 'خطا در خواندن فایل: ' . $e->getMessage(); } } public function submit(): void { $data = $this->form->getState(); $file = $data['csv_file']; $path = is_array($file) ? ($file['path'] ?? reset($file)) : $file; $content = file_get_contents($path); $lines = explode("\n", trim($content)); // حذف خط اول (هدر) $dataLines = array_slice($lines, 1); $successCount = 0; $errorCount = 0; $errors = []; DB::beginTransaction(); try { foreach ($dataLines as $lineNumber => $line) { $line = trim($line); if (empty($line)) continue; $parts = str_getcsv($line); if (count($parts) < 1) { $errors[] = "خط " . ($lineNumber + 2) . ": فرمت نادرست"; $errorCount++; continue; } $awbNo = $parts[0]; $status = $parts[1] ?? $data['status']; $description = $parts[2] ?? $data['description']; // بررسی وجود سفارش $shipment = Shipment::where('awb_no', $awbNo)->first(); if (!$shipment) { $errors[] = "خط " . ($lineNumber + 2) . ": سفارش {$awbNo} یافت نشد"; $errorCount++; continue; } // به‌روزرسانی وضعیت $shipment->update([ 'status' => $status, 'tracking_description' => $description, ]); // ثبت تاریخچه DB::table('tracking_histories')->insert([ 'shipment_id' => $shipment->id, 'status' => $status, 'description' => $description, 'location' => 'سیستم ایمپورت گروهی', 'created_at' => now(), 'updated_at' => now(), ]); $successCount++; } DB::commit(); Notification::make() ->title('ایمپورت با موفقیت انجام شد') ->body("{$successCount} سفارش با موفقیت به‌روزرسانی شد. {$errorCount} خطا رخ داد.") ->success() ->send(); if (!empty($errors)) { Notification::make() ->title('خطاها') ->body(implode("\n", array_slice($errors, 0, 10))) ->warning() ->send(); } $this->form->fill([ 'csv_file' => null, 'status' => 'in_transit', 'description' => '', ]); } catch (\Exception $e) { DB::rollBack(); Notification::make() ->title('خطا در ایمپورت') ->body($e->getMessage()) ->danger() ->send(); } } }