log("Начало импорта справочника округов"); 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()); $shortname = trim($sheet->getCell('B' . $row)->getValue()); $name = trim($sheet->getCell('C' . $row)->getValue()); // Пропускаем пустые строки if (empty($shortname) && empty($name)) { $skipped++; continue; } if (empty($name)) { $this->log("Строка {$row}: пропущена (пустое название)"); $skipped++; continue; } $data = [ 'shortname' => $shortname ?: mb_substr($name, 0, 10), 'name' => $name, ]; // Если есть ID, ищем по нему if (!empty($id) && is_numeric($id)) { $district = District::withTrashed()->find((int) $id); if ($district) { if ($district->trashed()) { $district->restore(); } $district->update($data); $updated++; continue; } } // Ищем по сокращению $district = District::withTrashed()->where('shortname', $shortname)->first(); if ($district) { if ($district->trashed()) { $district->restore(); } $district->update($data); $updated++; } else { District::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 log(string $message): void { $this->logs[] = '[' . date('H:i:s') . '] ' . $message; Log::info($message); } public function getLogs(): array { return $this->logs; } }