resolveProduct((string) $this->argument('product')); if (! $product instanceof Product) { $this->error('Prodotto non trovato.'); return self::FAILURE; } try { $options = [ 'asin' => trim((string) $this->option('asin')), 'query' => trim((string) $this->option('query')), 'marketplace' => trim((string) $this->option('marketplace')), 'dry_run' => (bool) $this->option('dry-run'), 'source' => 'api', ]; $jsonPath = trim((string) $this->option('json')); if ($jsonPath !== '') { $options['response'] = $this->readJsonFile($jsonPath); $options['source'] = 'json'; } $result = $syncService->syncProduct($product, $options); } catch (\Throwable $e) { $this->error($e->getMessage()); return self::FAILURE; } $this->table( ['Campo', 'Valore'], [ ['Prodotto', (string) ($product->internal_code ?: ('#' . $product->id)) . ' ยท ' . (string) ($product->name ?? '')], ['Fonte', (string) ($result['source'] ?? 'api')], ['Dry run', ! empty($result['dry_run']) ? 'si' : 'no'], ['ASIN', (string) ($result['asin'] ?? '')], ['EAN', (string) ($result['ean'] ?? '')], ['Titolo Amazon', (string) ($result['title'] ?? '')], ['Prezzo', $this->formatMoney($result['price_amount'] ?? null, (string) ($result['currency'] ?? 'EUR'))], ['Prezzo listino', $this->formatMoney($result['price_compare_at'] ?? null, (string) ($result['currency'] ?? 'EUR'))], ['Disponibilita', (string) ($result['availability'] ?? '')], ['Detail URL', (string) ($result['detail_url'] ?? '')], ['Referral URL', (string) ($result['referral_url'] ?? '')], ['Immagine', (string) ($result['image_url'] ?? '')], ['Codici creati', (string) ($result['identifiers_created'] ?? 0)], ['Media creati', (string) ($result['media_created'] ?? 0)], ['Offer ID', (string) ($result['offer_id'] ?? '')], ] ); return self::SUCCESS; } private function resolveProduct(string $value): ?Product { $value = trim($value); if ($value === '') { return null; } $query = Product::query(); if (is_numeric($value)) { $product = (clone $query)->find((int) $value); if ($product instanceof Product) { return $product; } } return (clone $query) ->where('internal_code', $value) ->orWhere('canonical_key', $value) ->first(); } /** @return array */ private function readJsonFile(string $path): array { if (! is_file($path)) { throw new RuntimeException('File JSON non trovato: ' . $path); } $decoded = json_decode((string) file_get_contents($path), true); if (! is_array($decoded)) { throw new RuntimeException('Il file JSON non contiene un payload valido.'); } return $decoded; } private function formatMoney(mixed $amount, string $currency): string { return is_numeric($amount) ? number_format((float) $amount, 2, ',', '.') . ' ' . strtoupper(trim($currency) !== '' ? $currency : 'EUR') : '-'; } }