log("Начало импорта справочника районов"); // Загружаем кэш округов $this->loadDistrictCache(); DB::beginTransaction(); try { $spreadsheet = IOFactory::load($this->filePath); $sheet = $spreadsheet->getActiveSheet(); $highestRow = $sheet->getHighestRow(); $imported = 0; $updated = 0; $skipped = 0; for ($row = 2; $row <= $highestRow; $row++) { $id = trim($sheet->getCell('A' . $row)->getValue()); $name = trim($sheet->getCell('B' . $row)->getValue()); $districtShortname = trim($sheet->getCell('C' . $row)->getValue()); $districtId = trim($sheet->getCell('D' . $row)->getValue()); // Пропускаем пустые строки if (empty($name)) { $skipped++; continue; } // Определяем округ $foundDistrictId = null; // Сначала по ID округа if (!empty($districtId) && is_numeric($districtId)) { $foundDistrictId = (int) $districtId; if (!isset($this->districtCache[$foundDistrictId])) { $this->log("Строка {$row}: округ с ID {$districtId} не найден"); $foundDistrictId = null; } } // Потом по сокращению if (!$foundDistrictId && !empty($districtShortname)) { foreach ($this->districtCache as $dId => $dShortname) { if (mb_strtolower($dShortname) === mb_strtolower($districtShortname)) { $foundDistrictId = $dId; break; } } if (!$foundDistrictId) { $this->log("Строка {$row}: округ '{$districtShortname}' не найден"); } } if (!$foundDistrictId) { $this->log("Строка {$row}: пропущена (не найден округ)"); $skipped++; continue; } $data = [ 'name' => $name, 'district_id' => $foundDistrictId, ]; // Если есть ID, ищем по нему if (!empty($id) && is_numeric($id)) { $area = Area::withTrashed()->find((int) $id); if ($area) { if ($area->trashed()) { $area->restore(); } $area->update($data); $updated++; continue; } } // Ищем по названию и округу $area = Area::withTrashed() ->where('name', $name) ->where('district_id', $foundDistrictId) ->first(); if ($area) { if ($area->trashed()) { $area->restore(); } $area->update($data); $updated++; } else { Area::create($data); $imported++; } } DB::commit(); $this->log("Импорт районов: создано {$imported}, обновлено {$updated}, пропущено {$skipped}"); return [ 'success' => true, 'imported' => $imported, 'updated' => $updated, 'skipped' => $skipped, 'logs' => $this->logs, ]; } catch (Exception $e) { DB::rollBack(); throw $e; } } catch (Exception $e) { $this->log("ОШИБКА: " . $e->getMessage()); Log::error("Ошибка импорта районов: " . $e->getMessage(), [ 'trace' => $e->getTraceAsString(), ]); return [ 'success' => false, 'error' => $e->getMessage(), 'logs' => $this->logs, ]; } } private function loadDistrictCache(): void { $this->districtCache = District::pluck('shortname', 'id')->toArray(); } private function log(string $message): void { $this->logs[] = '[' . date('H:i:s') . '] ' . $message; Log::info($message); } public function getLogs(): array { return $this->logs; } }