| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- <?php
- namespace App\Services\Import;
- use App\Models\MafOrder;
- use App\Models\Product;
- use Exception;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Log;
- use PhpOffice\PhpSpreadsheet\IOFactory;
- class ImportMafOrdersService
- {
- private array $logs = [];
- private array $productCache = [];
- public function __construct(
- private readonly string $filePath,
- private readonly int $userId,
- private readonly int $year,
- ) {}
- public function handle(): array
- {
- try {
- $this->log("Начало импорта заказов МАФ (год: {$this->year})");
- // Загружаем кэш товаров по артикулу для выбранного года
- $this->loadProductCache();
- 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=Статус
- for ($row = 2; $row <= $highestRow; $row++) {
- $article = trim((string) $sheet->getCell('A' . $row)->getValue());
- $quantity = (int) $sheet->getCell('B' . $row)->getValue();
- $orderNumber = trim((string) $sheet->getCell('C' . $row)->getValue());
- $statusRaw = trim((string) $sheet->getCell('D' . $row)->getValue());
- // Пропускаем пустые строки
- if (empty($article)) {
- $skipped++;
- continue;
- }
- // Проверяем наличие товара в каталоге выбранного года
- if (!isset($this->productCache[$article])) {
- $this->log("Строка {$row}: МАФ с артикулом '{$article}' не найден в каталоге {$this->year} года", 'ERROR');
- $errors++;
- continue;
- }
- $productId = $this->productCache[$article];
- // Парсим статус
- $status = $this->parseStatus($statusRaw);
- if ($status === null) {
- $this->log("Строка {$row}: неизвестный статус '{$statusRaw}'", 'ERROR');
- $errors++;
- continue;
- }
- // Определяем in_stock в зависимости от статуса
- $inStock = $status === 'на складе' ? $quantity : 0;
- // Создаём заказ МАФ
- MafOrder::create([
- 'year' => $this->year,
- 'product_id' => $productId,
- 'order_number' => $orderNumber ?: null,
- 'status' => $status,
- 'quantity' => $quantity,
- 'in_stock' => $inStock,
- '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 loadProductCache(): void
- {
- $this->productCache = Product::withoutGlobalScopes()
- ->where('year', $this->year)
- ->pluck('id', 'article')
- ->toArray();
- $this->log("Загружено " . count($this->productCache) . " товаров в кэш для {$this->year} года");
- }
- private function parseStatus(string $value): ?string
- {
- $value = mb_strtolower(trim($value));
- $statusMap = [
- 'на складе' => 'на складе',
- 'in_stock' => 'на складе',
- 'in stock' => 'на складе',
- 'заказан' => 'заказан',
- 'заказано' => 'заказан',
- 'ordered' => 'заказан',
- ];
- 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;
- }
- }
|