log("Начало импорта заказов запчастей"); // Загружаем кэш запчастей по артикулу $this->loadSparePartCache(); DB::beginTransaction(); try { $spreadsheet = IOFactory::load($this->filePath); $sheet = $spreadsheet->getActiveSheet(); $highestRow = $sheet->getHighestRow(); $imported = 0; $skipped = 0; $errors = 0; // Начинаем со 2-й строки (пропускаем заголовок) // Колонки: A=Артикул, B=кол-во, C=С документами?, D=Номер заказа, E=Статус for ($row = 2; $row <= $highestRow; $row++) { $article = trim($sheet->getCell('A' . $row)->getValue()); $quantity = (int) $sheet->getCell('B' . $row)->getValue(); $withDocsRaw = trim($sheet->getCell('C' . $row)->getValue()); $orderNumber = trim($sheet->getCell('D' . $row)->getValue()); $statusRaw = trim($sheet->getCell('E' . $row)->getValue()); // Пропускаем пустые строки if (empty($article)) { $skipped++; continue; } // Проверяем наличие запчасти в каталоге if (!isset($this->sparePartCache[$article])) { $this->log("Строка {$row}: запчасть с артикулом '{$article}' не найдена в каталоге", 'ERROR'); $errors++; continue; } $sparePartId = $this->sparePartCache[$article]; // Парсим "С документами?" $withDocuments = $this->parseWithDocuments($withDocsRaw); // Парсим статус $status = $this->parseStatus($statusRaw); if ($status === null) { $this->log("Строка {$row}: неизвестный статус '{$statusRaw}'", 'ERROR'); $errors++; continue; } // Создаём заказ запчасти SparePartOrder::create([ 'spare_part_id' => $sparePartId, 'order_number' => $orderNumber ?: null, 'status' => $status, 'ordered_quantity' => $quantity, 'available_qty' => $quantity, 'with_documents' => $withDocuments, 'user_id' => $this->userId, ]); $imported++; } DB::commit(); $this->log("=== РЕЗЮМЕ ИМПОРТА ==="); $this->log("Импортировано: {$imported}"); $this->log("Пропущено (пустые строки): {$skipped}"); $this->log("Ошибок: {$errors}"); return [ 'success' => $errors === 0, 'imported' => $imported, 'skipped' => $skipped, 'errors' => $errors, 'logs' => $this->logs, ]; } catch (Exception $e) { DB::rollBack(); throw $e; } } catch (Exception $e) { $this->log("КРИТИЧЕСКАЯ ОШИБКА: " . $e->getMessage(), 'ERROR'); Log::error("Ошибка импорта заказов запчастей: " . $e->getMessage(), [ 'trace' => $e->getTraceAsString(), ]); return [ 'success' => false, 'error' => $e->getMessage(), 'logs' => $this->logs, ]; } } private function loadSparePartCache(): void { $this->sparePartCache = SparePart::pluck('id', 'article')->toArray(); $this->log("Загружено " . count($this->sparePartCache) . " запчастей в кэш"); } private function parseWithDocuments(string $value): bool { $value = mb_strtolower(trim($value)); return in_array($value, ['да', 'yes', '1', 'true']); } private function parseStatus(string $value): ?string { $value = mb_strtolower(trim($value)); $statusMap = [ 'на складе' => SparePartOrder::STATUS_IN_STOCK, 'in_stock' => SparePartOrder::STATUS_IN_STOCK, 'in stock' => SparePartOrder::STATUS_IN_STOCK, 'заказано' => SparePartOrder::STATUS_ORDERED, 'ordered' => SparePartOrder::STATUS_ORDERED, 'отгружено' => SparePartOrder::STATUS_SHIPPED, 'shipped' => SparePartOrder::STATUS_SHIPPED, ]; return $statusMap[$value] ?? null; } private function log(string $message, string $level = 'INFO'): void { $this->logs[] = '[' . date('H:i:s') . '] ' . $level . ': ' . $message; Log::info($message); } public function getLogs(): array { return $this->logs; } }