netgescon-day0/app/Console/Commands/NetgesconNormalizeAcquaContractsCommand.php

120 lines
4.7 KiB
PHP
Executable File

<?php
namespace App\Console\Commands;
use App\Models\FatturaElettronica;
use App\Models\StabileServizio;
use App\Services\Consumi\AcquaContractSyncService;
use App\Services\FattureElettroniche\FatturaElettronicaImporter;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\Builder;
class NetgesconNormalizeAcquaContractsCommand extends Command
{
protected $signature = 'netgescon:acqua-normalize
{--stabile-id= : Limita la bonifica a uno stabile}
{--user-id=1 : Utente tecnico per i campi created_by/updated_by}
{--skip-fe-refresh : Non rilegge i PDF FE acqua salvati}
{--max-fe-per-stabile=0 : Limite FE da rileggere per stabile (0 = tutte)}';
protected $description = 'Canonicalizza i contratti acqua, bonifica i duplicati e rigenera le scadenze operative acqua per tutti gli stabili.';
public function handle(AcquaContractSyncService $syncService, FatturaElettronicaImporter $importer): int
{
$stabileId = (int) ($this->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');
});
}
}