argument('manifest'); if (! is_file($manifest) || ! is_readable($manifest)) { $this->error("JSON-файл {$manifest} не найден или недоступен для чтения."); return self::FAILURE; } $userId = (int) $this->option('user'); if (! User::query()->whereKey($userId)->exists()) { $this->error("Пользователь #{$userId} не найден."); return self::FAILURE; } try { $products = json_decode( (string) file_get_contents($manifest), true, 512, JSON_THROW_ON_ERROR, ); } catch (JsonException $exception) { $this->error('Некорректный JSON: '.$exception->getMessage()); return self::FAILURE; } if (! is_array($products) || ! array_is_list($products)) { $this->error('Корень JSON должен быть массивом позиций.'); return self::FAILURE; } $stats = $service->handle( $products, $this->option('images') ? (string) $this->option('images') : null, $userId, (bool) $this->option('overwrite'), (bool) $this->option('create-missing'), (bool) $this->option('apply-to-variants'), (bool) $this->option('dry-run'), ); $this->table(['Показатель', 'Количество'], [ ['Источник', $stats['source']], ['Сопоставлено', $stats['matched']], ['Обновлено', $stats['updated']], ['Создано', $stats['created']], ['Без изменений', $stats['unchanged']], ['Нет в каталоге', $stats['missing']], ['Неоднозначный артикул', $stats['ambiguous']], ['Перенесено изображений', $stats['images_imported']], ['Не найдено изображений', $stats['images_missing']], ]); if ($stats['missing_articles'] !== []) { $this->warn('Нет в каталоге: '.implode(', ', $stats['missing_articles'])); } if ($stats['ambiguous_articles'] !== []) { $this->warn('Неоднозначные артикулы: '.implode(', ', $stats['ambiguous_articles'])); } if ($this->option('dry-run')) { $this->info('Dry-run завершён: данные не изменены.'); } return self::SUCCESS; } }