option('stabile-id') ?: 0); $userId = max(1, (int) ($this->option('user-id') ?: 1)); $skipFeRefresh = (bool) $this->option('skip-fe-refresh'); $maxFePerStabile = max(0, (int) ($this->option('max-fe-per-stabile') ?: 0)); $stabileIds = StabileServizio::query() ->where('tipo', 'acqua') ->when($stabileId > 0, fn(Builder $query): Builder => $query->where('stabile_id', $stabileId)) ->pluck('stabile_id') ->filter(fn($value): bool => is_numeric($value) && (int) $value > 0) ->map(fn($value): int => (int) $value) ->unique() ->sort() ->values(); if (! $skipFeRefresh) { $invoiceStabileIds = $this->waterInvoiceQuery() ->when($stabileId > 0, fn(Builder $query): Builder => $query->where('stabile_id', $stabileId)) ->pluck('stabile_id') ->filter(fn($value): bool => is_numeric($value) && (int) $value > 0) ->map(fn($value): int => (int) $value) ->unique(); $stabileIds = $stabileIds->merge($invoiceStabileIds)->unique()->sort()->values(); } if ($stabileIds->isEmpty()) { $this->warn('Nessuno stabile acqua da normalizzare.'); return self::SUCCESS; } $totals = [ 'stabili' => 0, 'fe_refreshed' => 0, 'services' => 0, 'synced' => 0, 'merged' => 0, ]; foreach ($stabileIds as $currentStabileId) { $totals['stabili']++; $this->line(''); $this->info('Stabile #' . $currentStabileId); $refreshed = 0; if (! $skipFeRefresh) { $invoiceQuery = $this->waterInvoiceQuery()->where('stabile_id', $currentStabileId); if ($maxFePerStabile > 0) { $invoiceQuery->limit($maxFePerStabile); } $invoiceQuery->orderBy('id')->each(function (FatturaElettronica $fattura) use ($importer, $userId, &$refreshed): void { $importer->refreshWaterInvoiceFromStoredPdf($fattura, ['user_id' => $userId]); $refreshed++; }); } $stats = $syncService->normalizeStabile($currentStabileId, $userId); $totals['fe_refreshed'] += $refreshed; $totals['services'] += (int) ($stats['services'] ?? 0); $totals['synced'] += (int) ($stats['synced'] ?? 0); $totals['merged'] += (int) ($stats['merged'] ?? 0); $this->line(sprintf( ' FE rilette: %d | servizi acqua: %d | servizi sincronizzati: %d | contratti prima/dopo: %d/%d | duplicati fusi: %d', $refreshed, (int) ($stats['services'] ?? 0), (int) ($stats['synced'] ?? 0), (int) ($stats['contracts_before'] ?? 0), (int) ($stats['contracts_after'] ?? 0), (int) ($stats['merged'] ?? 0), )); } $this->line(''); $this->info(sprintf( 'Bonifica acqua completata. Stabili: %d, FE rilette: %d, servizi acqua: %d, servizi sincronizzati: %d, duplicati fusi: %d.', $totals['stabili'], $totals['fe_refreshed'], $totals['services'], $totals['synced'], $totals['merged'], )); return self::SUCCESS; } private function waterInvoiceQuery(): Builder { return FatturaElettronica::query() ->where(function (Builder $query): void { $query->whereNotNull('consumo_raw') ->orWhere('consumo_unita', 'mc'); }); } }