rate} {--limit=20 : Numero massimo righe snapshot} {--dry-run : Mostra payload senza inviarlo alla mini AI}'; protected $description = 'Invia alla mini AI banca/contabilita uno snapshot read-only dell HUB incassi.'; public function handle(IncassiHubReadService $hub, MiniAiReconciliationClient $client): int { $movementId = $this->option('movimento-id'); if (is_numeric($movementId)) { $snapshot = $hub->forBankMovement((int) $movementId, (int) $this->option('limit')); return $this->sendOrPreview($snapshot, $client); } $stabileId = $this->resolveStabileId(); if (! $stabileId) { $this->error('Specificare --stabile-id oppure --codice-stabile valido.'); return self::FAILURE; } $snapshot = $hub->forStabile($stabileId, (int) $this->option('limit')); return $this->sendOrPreview($snapshot, $client); } private function sendOrPreview(array $snapshot, MiniAiReconciliationClient $client): int { $request = $client->buildIncassiRequest($snapshot); if ($this->option('dry-run')) { $this->line(json_encode($request, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)); return self::SUCCESS; } $result = $client->sendIncassiSnapshot($snapshot); $this->line('ai_request_id=' . ($result['ai_request_id'] ?? '')); $this->line((string) ($result['message'] ?? '')); return ($result['ok'] ?? false) ? self::SUCCESS : self::FAILURE; } private function resolveStabileId(): ?int { $direct = $this->option('stabile-id'); if (is_numeric($direct)) { return (int) $direct; } $code = trim((string) ($this->option('codice-stabile') ?? '')); if ($code === '' || ! Schema::hasTable('stabili')) { return null; } $trimmed = ltrim($code, '0'); $id = DB::table('stabili') ->where(function ($query) use ($code, $trimmed): void { $query->where('codice_stabile', $code); if ($trimmed !== '' && $trimmed !== $code) { $query->orWhere('codice_stabile', $trimmed); } }) ->value('id'); return $id ? (int) $id : null; } }