netgescon-day0/resources/views/filament/pages/condomini/riscaldamento-stabile-archivio.blade.php

982 lines
86 KiB
PHP
Executable File

<x-filament-panels::page>
@php
$stats = $this->riscaldamentoDashboardStats;
$annoGestioneAttivo = \App\Support\AnnoGestioneContext::resolveActiveAnno(auth()->user());
$fatturePerGestione = $this->riscaldamentoFatturePerGestione;
$feEstratteSummary = $this->riscaldamentoFeEstratteSummary;
$feSelezioneSummary = $this->riscaldamentoFeSelezioneSummary;
$feEstratteRows = $this->riscaldamentoFeEstratteRows;
$lettureCondomini = $this->riscaldamentoLettureCondomini;
$lettureGenerali = $this->riscaldamentoLettureGenerali;
$uiReadingForm = $this->riscaldamentoUiReadingForm;
$uiServiceOptions = $this->riscaldamentoUiServiceOptions;
$uiUnitOptions = $this->riscaldamentoUiUnitOptions;
$tariffeRows = $this->riscaldamentoTariffeRows;
$legacyArchive = $this->riscaldamentoLegacyArchiveAvailability;
$legacyExtraRows = $this->riscaldamentoAltreVociLegacy;
$legacyOpsSummary = $this->riscaldamentoLegacyOperazioniSummary;
$legacyOpsRows = $this->riscaldamentoLegacyOperazioniRows;
$riscaldamentoContratto = $this->riscaldamentoContrattoStabile;
$riscaldamentoRipartoNominativi = $this->riscaldamentoRipartoNominativiLegacy;
$campagnaStats = $this->riscaldamentoCampagnaStats;
$campagnaRows = $this->riscaldamentoCampagnaRows;
@endphp
<div class="space-y-6">
<div>
<h1 class="text-2xl font-bold text-gray-900 dark:text-gray-100">Servizi / Beni comuni - RISCALDAMENTO</h1>
<p class="mt-1 text-sm text-gray-600 dark:text-gray-400">
Cruscotto operativo per utenze, beni comuni, locali condivisi e contatori riscaldamento dello stabile. Qui convivono contratti, servizi ad uso comune, rimborsi spesa, contatori generali e contatori particolari con storico e tariffe.
</p>
<div class="mt-2 inline-flex items-center rounded-full border border-blue-200 bg-blue-50 px-3 py-1 text-xs font-medium text-blue-700 dark:border-blue-700/50 dark:bg-blue-900/20 dark:text-blue-200">
Anno gestione attivo: {{ $annoGestioneAttivo }}
</div>
</div>
<div class="border-b border-gray-200 dark:border-gray-800">
<nav class="-mb-px flex flex-wrap gap-6" aria-label="Tabs">
<button type="button"
wire:click="setRiscaldamentoTab('dashboard')"
class="pb-3 px-1 border-b-2 font-medium text-sm {{ $riscaldamentoTab === 'dashboard' ? 'border-blue-600 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}">
Dashboard
</button>
<button type="button"
wire:click="setRiscaldamentoTab('fatture')"
class="pb-3 px-1 border-b-2 font-medium text-sm {{ $riscaldamentoTab === 'fatture' ? 'border-blue-600 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}">
Fatture per gestione
</button>
<button type="button"
wire:click="setRiscaldamentoTab('letture')"
class="pb-3 px-1 border-b-2 font-medium text-sm {{ $riscaldamentoTab === 'letture' ? 'border-blue-600 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}">
Lett. Contatori UI
</button>
<button type="button"
wire:click="setRiscaldamentoTab('generale')"
class="pb-3 px-1 border-b-2 font-medium text-sm {{ $riscaldamentoTab === 'generale' ? 'border-blue-600 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}">
Letture contatore generale
</button>
<button type="button"
wire:click="setRiscaldamentoTab('tariffe')"
class="pb-3 px-1 border-b-2 font-medium text-sm {{ $riscaldamentoTab === 'tariffe' ? 'border-blue-600 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}">
Rendiconto Spese / Bilancio
</button>
<button type="button"
wire:click="setRiscaldamentoTab('servizi')"
class="pb-3 px-1 border-b-2 font-medium text-sm {{ $riscaldamentoTab === 'servizi' ? 'border-blue-600 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}">
Servizi / Utenze (tabella)
</button>
</nav>
</div>
@if($riscaldamentoTab === 'dashboard')
<div class="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-4">
<div class="rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-900">
<div class="text-xs text-gray-500">Totale fatture riscaldamento (import registrato)</div>
<div class="mt-2 text-xl font-semibold">EUR {{ number_format((float) ($stats['totale_fatture'] ?? 0), 2, ',', '.') }}</div>
</div>
<div class="rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-900">
<div class="text-xs text-gray-500">Controllo legacy operazioni (R%)</div>
<div class="mt-2 text-xl font-semibold">EUR {{ number_format((float) ($stats['totale_operazioni_ac12_legacy'] ?? 0), 2, ',', '.') }}</div>
<div class="mt-1 text-xs {{ ((float) ($stats['delta_operazioni_vs_fatture'] ?? 0)) == 0.0 ? 'text-emerald-600' : 'text-amber-600' }}">
Delta fatture registrate - legacy R%: {{ number_format((float) ($stats['delta_operazioni_vs_fatture'] ?? 0), 2, ',', '.') }}
</div>
</div>
<div class="rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-900">
<div class="text-xs text-gray-500">Letture condomini registrate</div>
<div class="mt-2 text-xl font-semibold">{{ number_format((int) ($stats['totale_letture'] ?? 0), 0, ',', '.') }}</div>
<div class="mt-1 text-xs text-gray-500">con riferimento acquisizione: {{ number_format((int) ($stats['totale_letture_con_riferimento'] ?? 0), 0, ',', '.') }}</div>
</div>
<div class="rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-900">
<div class="text-xs text-gray-500">Consumi e tariffe</div>
<div class="mt-2 text-xl font-semibold">{{ number_format((float) ($stats['totale_consumi_mc'] ?? 0), 3, ',', '.') }} mc</div>
<div class="mt-1 text-xs text-gray-500">snapshot tariffe: {{ number_format((int) ($stats['totale_tariffe'] ?? 0), 0, ',', '.') }}</div>
</div>
</div>
<div class="rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-900">
<div class="text-sm font-semibold text-gray-900 dark:text-gray-100">Copertura archivio legacy ACEA</div>
<div class="mt-2 text-sm text-gray-600 dark:text-gray-300">
<div>Tabella <code>contratti_ACEA</code>: <span class="font-semibold">{{ ($legacyArchive['contratti_acea'] ?? false) ? 'presente' : 'non presente' }}</span></div>
<div>Tabella <code>Tariffe_ACEA_Standard</code>: <span class="font-semibold">{{ ($legacyArchive['tariffe_acea_standard'] ?? false) ? 'presente' : 'non presente' }}</span></div>
<div class="mt-1 text-xs text-gray-500">{{ $legacyArchive['note'] ?? '' }}</div>
</div>
</div>
<div class="rounded-lg border border-blue-200 bg-blue-50 p-4 dark:border-blue-700/50 dark:bg-blue-900/10">
<div class="mb-2 flex flex-wrap items-center justify-between gap-3">
<div class="text-sm font-semibold text-blue-900 dark:text-blue-200">Contratto servizio RISCALDAMENTO (stabile -> fornitore)</div>
<x-filament::button size="xs" color="info" wire:click="ensureRiscaldamentoAceaContract">
Allinea/crea contratto con Acea Ato2
</x-filament::button>
</div>
<div class="grid grid-cols-1 gap-2 text-xs text-blue-900 dark:text-blue-100 md:grid-cols-2">
<div>Servizio: <span class="font-semibold">{{ $riscaldamentoContratto['servizio_nome'] ?: 'non configurato' }}</span></div>
<div>Fornitore: <span class="font-semibold">{{ $riscaldamentoContratto['fornitore_nome'] ?: 'non assegnato' }}</span></div>
<div>Codice utenza: <span class="font-semibold">{{ $riscaldamentoContratto['codice_utenza'] ?: '—' }}</span></div>
<div>Codice cliente: <span class="font-semibold">{{ $riscaldamentoContratto['codice_cliente'] ?: '—' }}</span></div>
<div>Codice contratto: <span class="font-semibold">{{ $riscaldamentoContratto['codice_contratto'] ?: '—' }}</span></div>
<div>Matricola contatore: <span class="font-semibold">{{ $riscaldamentoContratto['matricola'] ?: '—' }}</span></div>
</div>
@if(!($riscaldamentoContratto['fornitore_nome'] ?? null) && ($riscaldamentoContratto['suggerito_fornitore'] ?? null))
<div class="mt-2 text-xs text-blue-700 dark:text-blue-300">Suggerito in anagrafica fornitori: {{ $riscaldamentoContratto['suggerito_fornitore'] }}</div>
@endif
</div>
@endif
@if($riscaldamentoTab === 'fatture')
<div class="space-y-4">
<!-- Filtro Periodo Esercizio Riscaldamento Personalizzato -->
<div class="rounded-lg border border-cyan-200 bg-white p-4 dark:border-cyan-700/50 dark:bg-gray-900 shadow-sm">
<div class="text-xs font-semibold uppercase tracking-wide text-cyan-900 dark:text-cyan-200 mb-3">Periodo Esercizio Riscaldamento (Personalizzato per Stabile)</div>
<div class="flex flex-wrap items-end gap-4">
<div>
<label class="block text-[10px] font-medium text-gray-500 uppercase dark:text-gray-400">Data inizio periodo</label>
<input type="date" wire:model.live="riscaldamentoDataInizioFiltro" class="mt-1 block rounded-md border-gray-300 shadow-sm text-xs dark:bg-gray-800 dark:border-gray-700 dark:text-gray-100 focus:border-cyan-500 focus:ring-cyan-500">
</div>
<div>
<label class="block text-[10px] font-medium text-gray-500 uppercase dark:text-gray-400">Data fine periodo</label>
<input type="date" wire:model.live="riscaldamentoDataFineFiltro" class="mt-1 block rounded-md border-gray-300 shadow-sm text-xs dark:bg-gray-800 dark:border-gray-700 dark:text-gray-100 focus:border-cyan-500 focus:ring-cyan-500">
</div>
<x-filament::button type="button" size="sm" color="info" wire:click="saveRiscaldamentoFilterDates">Salva e allinea fatture</x-filament::button>
</div>
<div class="mt-2 text-[10px] text-gray-500 dark:text-gray-400">Impostando queste date, le FE dello stabile verranno filtrate per questo intervallo temporale anziché per l'anno solare, e verranno collegate alla gestione ordinaria corretta.</div>
</div>
<div class="rounded-lg border border-cyan-200 bg-cyan-50 p-4 dark:border-cyan-700/50 dark:bg-cyan-900/10">
<div class="mb-3 flex flex-wrap items-center justify-between gap-3">
<div>
<div class="text-sm font-semibold text-cyan-900 dark:text-cyan-200">Dati estratti dalle fatture FE riscaldamento</div>
<div class="mt-1 text-xs text-cyan-800 dark:text-cyan-300">Qui vedi consumo, contratto, cliente, matricola, CBILL e riepilogo letture letti dalle FE riscaldamento, con i collegamenti operativi verso scheda FE, ticket generale, contratti e archivio letture.</div>
</div>
<div class="flex flex-wrap gap-2">
<a href="{{ \App\Filament\Pages\Supporto\TicketRiscaldamentoGenerale::getUrl(panel: 'admin-filament') }}"
class="inline-flex items-center rounded-md border border-cyan-300 bg-white px-3 py-1.5 text-xs font-medium text-cyan-800 hover:bg-cyan-100">
Contatore generale
</a>
<a href="{{ \App\Filament\Pages\Condomini\ContrattiHub::getUrl(panel: 'admin-filament') }}"
class="inline-flex items-center rounded-md border border-cyan-300 bg-white px-3 py-1.5 text-xs font-medium text-cyan-800 hover:bg-cyan-100">
Contratti riscaldamento
</a>
</div>
</div>
<div class="mb-4 grid gap-3 md:grid-cols-5">
<div class="rounded-lg border bg-white p-3 text-sm dark:bg-gray-900">
<div class="text-xs uppercase tracking-wide text-gray-500">FE estratte</div>
<div class="mt-2 text-xl font-semibold">{{ number_format((int) ($feEstratteSummary['fatture'] ?? 0), 0, ',', '.') }}</div>
</div>
<div class="rounded-lg border bg-white p-3 text-sm dark:bg-gray-900">
<div class="text-xs uppercase tracking-wide text-gray-500">Periodi letti</div>
<div class="mt-2 text-xl font-semibold">{{ number_format((int) ($feEstratteSummary['periodi'] ?? 0), 0, ',', '.') }}</div>
</div>
<div class="rounded-lg border bg-white p-3 text-sm dark:bg-gray-900">
<div class="text-xs uppercase tracking-wide text-gray-500">Totale mc FE</div>
<div class="mt-2 text-xl font-semibold">{{ number_format((float) ($feEstratteSummary['totale_mc'] ?? 0), 3, ',', '.') }} mc</div>
</div>
<div class="rounded-lg border bg-white p-3 text-sm dark:bg-gray-900">
<div class="text-xs uppercase tracking-wide text-gray-500">Totale spesa FE</div>
<div class="mt-2 text-xl font-semibold">{{ number_format((float) ($feEstratteSummary['totale_spesa'] ?? 0), 2, ',', '.') }} EUR</div>
</div>
<div class="rounded-lg border bg-white p-3 text-sm dark:bg-gray-900">
<div class="text-xs uppercase tracking-wide text-gray-500">Finestra autolettura</div>
<div class="mt-2 text-xl font-semibold">{{ number_format((int) ($feEstratteSummary['con_finestra'] ?? 0), 0, ',', '.') }}</div>
<div class="mt-1 text-[11px] text-gray-500">ultima FE {{ !empty($feEstratteSummary['ultima_data']) ? \Carbon\Carbon::parse($feEstratteSummary['ultima_data'])->format('d/m/Y') : '' }}</div>
</div>
</div>
<div class="mb-4 flex flex-wrap items-center justify-between gap-3 rounded-lg border border-cyan-200 bg-white px-4 py-3 text-xs dark:border-cyan-700/50 dark:bg-gray-900">
<div class="flex flex-wrap items-center gap-4 text-cyan-900 dark:text-cyan-100">
<span class="font-semibold">Selezione per ripartizione:</span>
<span>{{ number_format((int) ($feSelezioneSummary['fatture'] ?? 0), 0, ',', '.') }} FE</span>
<span>{{ number_format((float) ($feSelezioneSummary['totale_mc'] ?? 0), 3, ',', '.') }} mc</span>
<span>{{ number_format((float) ($feSelezioneSummary['totale_spesa'] ?? 0), 2, ',', '.') }} EUR</span>
</div>
<div class="flex flex-wrap gap-2">
<button type="button" wire:click="riconciliaAutomaticamentePagamenti" class="inline-flex items-center rounded-md border border-emerald-300 bg-emerald-600 px-3 py-1.5 font-medium text-white hover:bg-emerald-500 shadow-sm focus:outline-none focus:ring-2 focus:ring-emerald-500">Riconcilia Pagamenti (Banca)</button>
<button type="button" wire:click="selectAllRiscaldamentoFe" class="inline-flex items-center rounded-md border border-cyan-300 bg-white px-3 py-1.5 font-medium text-cyan-800 hover:bg-cyan-100">Seleziona tutte</button>
<button type="button" wire:click="clearRiscaldamentoFeSelection" class="inline-flex items-center rounded-md border border-cyan-300 bg-white px-3 py-1.5 font-medium text-cyan-800 hover:bg-cyan-100">Azzera selezione</button>
<a href="{{ $this->riscaldamentoRipartizionePrintUrl }}" target="_blank" class="inline-flex items-center rounded-md border border-cyan-300 bg-white px-3 py-1.5 font-medium text-cyan-800 hover:bg-cyan-100">Stampa riepilogo</a>
<a href="{{ $this->riscaldamentoRipartizionePdfUrl }}" target="_blank" class="inline-flex items-center rounded-md border border-cyan-300 bg-white px-3 py-1.5 font-medium text-cyan-800 hover:bg-cyan-100">PDF riepilogo</a>
<button type="button" wire:click="$set('showSendEmailModal', true)" class="inline-flex items-center rounded-md border border-cyan-300 bg-cyan-600 px-3 py-1.5 font-medium text-white hover:bg-cyan-500 shadow-sm focus:outline-none focus:ring-2 focus:ring-cyan-500">Invia via email</button>
</div>
</div>
<div class="mb-4 rounded-lg border border-amber-200 bg-amber-50 px-4 py-3 text-xs text-amber-900 dark:border-amber-700/50 dark:bg-amber-900/10 dark:text-amber-100">
Le FE mostrate sono filtrate per anno gestione e fornitore riscaldamento dello stabile. Se il PDF non espone matricola o utenza, usa la selezione manuale per separare le fatture del contatore corretto prima della ripartizione.
</div>
<div class="overflow-x-visible">
<table class="w-full table-auto text-xs">
<thead>
<tr class="border-b border-cyan-200 dark:border-cyan-700/50">
<th class="px-2 py-2 text-left">Sel.</th>
<th class="px-2 py-2 text-left">Fattura</th>
<th class="px-2 py-2 text-left">Servizio / codici</th>
<th class="px-2 py-2 text-left">Periodo FE</th>
<th class="px-2 py-2 text-left">Finestra lettura</th>
<th class="px-2 py-2 text-right">Mc</th>
<th class="px-2 py-2 text-right">Spesa</th>
<th class="px-2 py-2 text-left">Azioni</th>
</tr>
</thead>
<tbody>
@forelse($feEstratteRows as $row)
<tr class="border-b border-cyan-100 dark:border-cyan-800/30">
<td class="px-2 py-2 align-top">
<input type="checkbox"
wire:click="toggleRiscaldamentoFeSelection({{ (int) $row['fattura_id'] }})"
@checked((bool) ($row['selected'] ?? false))
class="rounded border-cyan-300 text-cyan-600 focus:ring-cyan-500">
</td>
<td class="px-2 py-2 align-top">
<div class="font-medium text-gray-900 dark:text-gray-100">{{ $row['numero_fattura'] ?: ('FE #' . $row['fattura_id']) }}</div>
<div class="text-[10px] text-cyan-700 dark:text-cyan-300">{{ $row['data_fattura'] ?: '—' }}</div>
@if(!empty($row['legacy_n_spe']))
<div class="mt-1 text-[10px] bg-indigo-50 dark:bg-indigo-950/30 text-indigo-700 dark:text-indigo-300 px-1.5 py-0.5 rounded font-semibold inline-block">
Legacy: Reg. #{{ $row['legacy_id'] }} · Prot. {{ $row['legacy_n_spe'] }}
</div>
@endif
<div class="mt-1">
@if($row['registrata_stato'] === 'pagato')
<span class="inline-flex items-center rounded-md bg-green-50 dark:bg-green-950/30 px-1.5 py-0.5 text-[10px] font-semibold text-green-700 dark:text-green-300 ring-1 ring-inset ring-green-600/20">Pagata il {{ $row['registrata_data_pagamento'] }}</span>
@elseif($row['registrata_stato'] === 'da_pagare')
<span class="inline-flex items-center rounded-md bg-amber-50 dark:bg-amber-950/30 px-1.5 py-0.5 text-[10px] font-semibold text-amber-700 dark:text-amber-300 ring-1 ring-inset ring-amber-600/20">Debito ( {{ number_format($row['registrata_netto_da_pagare'], 2, ',', '.') }})</span>
@else
<span class="inline-flex items-center rounded-md bg-gray-50 dark:bg-gray-950/30 px-1.5 py-0.5 text-[10px] font-semibold text-gray-700 dark:text-gray-300 ring-1 ring-inset ring-gray-600/20">Da registrare</span>
@endif
</div>
</td>
<td class="px-2 py-2">
<div class="font-medium text-gray-900 dark:text-gray-100" title="{{ $row['servizio'] ?: 'Riscaldamento' }}">{{ $row['servizio'] ?: 'Riscaldamento' }}</div>
<div class="break-words text-[10px] text-gray-500" title="Matr. {{ $row['matricola'] ?: '—' }} · Utenza {{ $row['codice_utenza'] ?: '—' }} · Cliente {{ $row['codice_cliente'] ?: '—' }} · Contratto {{ $row['codice_contratto'] ?: '—' }} · CBILL {{ $row['cbill_display'] ?: '—' }}{{ !empty($row['sia']) ? ' · SIA ' . $row['sia'] : '' }}">
Matr. {{ $row['matricola'] ?: '—' }} · Utenza {{ $row['codice_utenza'] ?: '—' }} · Cliente {{ $row['codice_cliente'] ?: '—' }} · Contratto {{ $row['codice_contratto'] ?: '—' }} · CBILL {{ $row['cbill_display'] ?: '—' }} @if(!empty($row['sia'])) · SIA {{ $row['sia'] }} @endif
</div>
<div class="mt-1 text-[10px] text-gray-500 font-medium">
Voce pre-assegnata fornitore: <span class="text-cyan-800 dark:text-cyan-400 font-semibold">{{ $row['voce_spesa_default_name'] }}</span>
</div>
@if(!empty($row['periodicita_fatturazione']) || !empty($row['numero_componenti']) || !empty($row['numero_unita_abitative']))
<div class="break-words text-[10px] text-cyan-700 dark:text-cyan-300">{{ $row['periodicita_fatturazione'] ?: 'periodicita n/d' }} @if(!empty($row['numero_componenti'])) · comp. {{ $row['numero_componenti'] }} @endif @if(!empty($row['numero_unita_abitative'])) · unita {{ $row['numero_unita_abitative'] }} @endif</div>
@endif
@if(!($row['identificativi_noti'] ?? false))
<div class="mt-1 text-[10px] text-amber-700 dark:text-amber-300">Identificativi non leggibili dal PDF: usare la selezione FE per il contatore corretto.</div>
@endif
</td>
<td class="px-2 py-2 align-top">
<div>{{ $row['periodo_label'] ?: '—' }}</div>
<div class="text-[10px] text-gray-500">periodi {{ number_format((int) ($row['periodi_count'] ?? 0), 0, ',', '.') }} · riepiloghi {{ number_format((int) ($row['letture_count'] ?? 0), 0, ',', '.') }}</div>
@if(!empty($row['letture_preview']))
<div class="mt-1 break-words text-[10px] text-cyan-700 dark:text-cyan-300" title="{{ implode(' | ', $row['letture_preview']) }}">
{{ implode(' | ', $row['letture_preview']) }}
</div>
@endif
</td>
<td class="px-2 py-2 align-top">
@if($row['ha_finestra'])
<span class="inline-block rounded bg-emerald-100 px-1.5 py-0.5 font-semibold text-emerald-700">{{ $row['finestra_label'] }}</span>
@else
<span class="text-gray-400"></span>
@endif
</td>
<td class="px-2 py-2 text-right align-top whitespace-nowrap">{{ number_format((float) ($row['totale_mc'] ?? 0), 3, ',', '.') }}</td>
<td class="px-2 py-2 text-right align-top whitespace-nowrap">{{ number_format((float) ($row['totale_spesa'] ?? 0), 2, ',', '.') }}</td>
<td class="px-2 py-2 align-top">
<div class="flex flex-wrap gap-2">
<a href="{{ $row['scheda_fe_url'] }}" class="inline-flex items-center rounded-md bg-white px-2 py-1 text-[11px] font-medium text-cyan-800 ring-1 ring-inset ring-cyan-300 hover:bg-cyan-100">Scheda FE</a>
<a href="{{ $row['ticket_generale_url'] }}" class="inline-flex items-center rounded-md bg-white px-2 py-1 text-[11px] font-medium text-cyan-800 ring-1 ring-inset ring-cyan-300 hover:bg-cyan-100">Ticket generale</a>
<a href="{{ $row['contratti_url'] }}" class="inline-flex items-center rounded-md bg-white px-2 py-1 text-[11px] font-medium text-cyan-800 ring-1 ring-inset ring-cyan-300 hover:bg-cyan-100">Contratti</a>
<a href="{{ $row['letture_servizio_url'] }}" class="inline-flex items-center rounded-md bg-white px-2 py-1 text-[11px] font-medium text-cyan-800 ring-1 ring-inset ring-cyan-300 hover:bg-cyan-100">Archivio letture</a>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="8" class="px-2 py-4 text-center text-cyan-700 dark:text-cyan-300">Nessuna FE riscaldamento estratta nello storico attivo.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
<div class="rounded-lg border border-sky-200 bg-sky-50 p-4 dark:border-sky-700/50 dark:bg-sky-900/10">
<div class="mb-3 flex flex-wrap items-center justify-between gap-3">
<div>
<div class="text-sm font-semibold text-sky-900 dark:text-sky-200">Estrazione dati riscaldamento dalle FE pregresse</div>
<div class="mt-1 text-xs text-sky-800 dark:text-sky-300">Rilegge le fatture elettroniche gia' presenti per lo stabile e la gestione selezionata, aggiorna consumo, letture e tariffe senza creare doppioni.</div>
</div>
<x-filament::button size="sm" color="info" wire:click="backfillRiscaldamentoFromFatturePregresse">
Estrai dati dalle FE pregresse
</x-filament::button>
</div>
<div class="grid gap-3 md:grid-cols-3">
<label class="text-xs font-medium text-sky-900 dark:text-sky-100">
Gestione
<select wire:model.live="riscaldamentoBackfillGestione" class="mt-1 block w-full rounded-md border-sky-300 bg-white text-sm text-gray-900 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:border-sky-700 dark:bg-gray-950 dark:text-gray-100">
<option value="ordinaria">Ordinaria</option>
<option value="riscaldamento">Riscaldamento</option>
<option value="straordinaria">Straordinaria</option>
<option value="tutte">Tutte</option>
</select>
</label>
<label class="flex items-center gap-2 rounded-md border border-sky-200 bg-white px-3 py-2 text-xs font-medium text-sky-900 dark:border-sky-700 dark:bg-gray-950 dark:text-sky-100">
<input type="checkbox" wire:model.live="riscaldamentoBackfillOnlyMissing" class="rounded border-sky-300 text-sky-600 focus:ring-sky-500">
Processa solo FE non ancora estratte
</label>
<div class="rounded-md border border-sky-200 bg-white px-3 py-2 text-xs text-sky-800 dark:border-sky-700 dark:bg-gray-950 dark:text-sky-100">
Dopo la creazione della regola servizio, l'import FE continua gia' in automatico sul nuovo scarico; qui recuperi il pregresso.
</div>
</div>
</div>
<div class="rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-900">
<div class="mb-3 text-sm font-semibold text-gray-900 dark:text-gray-100">Fatture registrate divise per gestione</div>
<div class="overflow-x-auto">
<table class="min-w-full text-sm">
<thead>
<tr class="border-b border-gray-200 dark:border-gray-800">
<th class="px-3 py-2 text-left">Gestione</th>
<th class="px-3 py-2 text-right">Numero fatture</th>
<th class="px-3 py-2 text-right">FE</th>
<th class="px-3 py-2 text-right">Manuali</th>
<th class="px-3 py-2 text-right">Totale EUR</th>
<th class="px-3 py-2 text-right">Mc FE</th>
<th class="px-3 py-2 text-left">Contratti / contatori</th>
</tr>
</thead>
<tbody>
@forelse($fatturePerGestione as $row)
<tr class="border-b border-gray-100 dark:border-gray-800">
<td class="px-3 py-2">{{ strtoupper((string) ($row['gestione'] ?? 'non definita')) }}</td>
<td class="px-3 py-2 text-right">{{ number_format((int) ($row['fatture_count'] ?? 0), 0, ',', '.') }}</td>
<td class="px-3 py-2 text-right">{{ number_format((int) ($row['fe_count'] ?? 0), 0, ',', '.') }}</td>
<td class="px-3 py-2 text-right">{{ number_format((int) ($row['manual_count'] ?? 0), 0, ',', '.') }}</td>
<td class="px-3 py-2 text-right">{{ number_format((float) ($row['totale_fatture'] ?? 0), 2, ',', '.') }}</td>
<td class="px-3 py-2 text-right">{{ number_format((float) ($row['totale_mc'] ?? 0), 3, ',', '.') }}</td>
<td class="px-3 py-2 text-xs text-gray-600 dark:text-gray-300">
<div>Contratti: {{ !empty($row['contratti']) ? implode(', ', $row['contratti']) : '' }}</div>
<div>Matricole: {{ !empty($row['matricole']) ? implode(', ', $row['matricole']) : '' }}</div>
@if(!empty($row['cbill_codes']))
<div>CBILL: {{ implode(', ', $row['cbill_codes']) }}</div>
@endif
</td>
</tr>
@empty
<tr>
<td colspan="7" class="px-3 py-4 text-center text-gray-500 dark:text-gray-400">Nessuna fattura riscaldamento trovata per lo stabile selezionato.</td>
</tr>
@endforelse
</tbody>
@if(count($fatturePerGestione) > 0)
<tfoot>
<tr class="bg-gray-50 dark:bg-gray-950/30">
<td class="px-3 py-2 font-semibold">Totale</td>
<td class="px-3 py-2 text-right font-semibold">{{ number_format((int) collect($fatturePerGestione)->sum('fatture_count'), 0, ',', '.') }}</td>
<td class="px-3 py-2 text-right font-semibold">{{ number_format((int) collect($fatturePerGestione)->sum('fe_count'), 0, ',', '.') }}</td>
<td class="px-3 py-2 text-right font-semibold">{{ number_format((int) collect($fatturePerGestione)->sum('manual_count'), 0, ',', '.') }}</td>
<td class="px-3 py-2 text-right font-semibold">{{ number_format((float) collect($fatturePerGestione)->sum('totale_fatture'), 2, ',', '.') }}</td>
</tr>
</tfoot>
@endif
</table>
</div>
</div>
<div class="rounded-lg border border-indigo-200 bg-indigo-50 p-4 dark:border-indigo-700/50 dark:bg-indigo-900/10">
<div class="mb-2 text-sm font-semibold text-indigo-900 dark:text-indigo-200">Archivio legacy operazioni Riscaldamento (R%)</div>
@if(!empty($legacyOpsSummary['scope_note']))
<div class="mb-3 text-[11px] text-indigo-800 dark:text-indigo-300">{{ $legacyOpsSummary['scope_note'] }}</div>
@endif
<div class="mb-3 grid grid-cols-1 gap-2 text-xs text-indigo-900 dark:text-indigo-100 md:grid-cols-2">
<div>Righe: <span class="font-semibold">{{ number_format((int) ($legacyOpsSummary['righe'] ?? 0), 0, ',', '.') }}</span></div>
<div>Totale Riscaldamento: <span class="font-semibold">{{ number_format((float) ($legacyOpsSummary['totale'] ?? 0), 2, ',', '.') }}</span></div>
</div>
<div class="overflow-x-auto">
<table class="min-w-full text-xs">
<thead>
<tr class="border-b border-indigo-200 dark:border-indigo-700/50">
<th class="px-2 py-2 text-left">Data op.</th>
<th class="px-2 py-2 text-left">Voce</th>
<th class="px-2 py-2 text-left">Doc legacy</th>
<th class="px-2 py-2 text-left">Fornitore</th>
<th class="px-2 py-2 text-left">Descrizione</th>
<th class="px-2 py-2 text-right">Importo</th>
<th class="px-2 py-2 text-left">Match fattura locale</th>
</tr>
</thead>
<tbody>
@forelse($legacyOpsRows as $row)
<tr class="border-b border-indigo-100 dark:border-indigo-800/30">
<td class="px-2 py-2">
{{ $row['data_operazione'] ? \Carbon\Carbon::parse($row['data_operazione'])->format('d/m/Y') : '' }}
@if(!empty($row['n_spe']))
<div class="text-[9px] text-gray-500 font-semibold" title="Protocollo Legacy">Prot. {{ $row['n_spe'] }}</div>
@endif
</td>
<td class="px-2 py-2 font-medium">{{ $row['cod_spe'] ?: '' }}</td>
<td class="px-2 py-2">
{{ $row['num_fat'] ?: '' }}
<div class="text-[10px] text-indigo-700 dark:text-indigo-300">{{ $row['dt_fat'] ? \Carbon\Carbon::parse($row['dt_fat'])->format('d/m/Y') : '' }}</div>
</td>
<td class="px-2 py-2">{{ $row['fornitore_legacy'] ?: ('cod. ' . ($row['cod_for'] ?: '')) }}</td>
<td class="px-2 py-2 max-w-[22rem] truncate" title="{{ $row['benef'] }}">{{ $row['benef'] ?: '' }}</td>
<td class="px-2 py-2 text-right">{{ number_format((float) ($row['importo'] ?? 0), 2, ',', '.') }}</td>
<td class="px-2 py-2">
@if(($row['matched_fattura_id'] ?? null))
<span class="rounded bg-emerald-100 px-1.5 py-0.5 text-[10px] font-semibold text-emerald-700">OK {{ strtoupper((string) ($row['match_type'] ?? '')) }}</span>
<div class="text-[10px] text-emerald-700">ID {{ $row['matched_fattura_id'] }} @if($row['matched_fe_id']) / FE {{ $row['matched_fe_id'] }} @endif</div>
@else
<span class="rounded bg-amber-100 px-1.5 py-0.5 text-[10px] font-semibold text-amber-700">DA COLLEGARE</span>
@endif
</td>
</tr>
@empty
<tr>
<td colspan="7" class="px-2 py-4 text-center text-indigo-700 dark:text-indigo-300">Nessuna operazione di Riscaldamento trovata in archivio legacy.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
@if(false)
<div class="rounded-lg border border-amber-200 bg-amber-50 p-4 dark:border-amber-700/50 dark:bg-amber-900/10">
<div class="mb-3 text-sm font-semibold text-amber-900 dark:text-amber-200">Altre voci AC (escluse AC1/AC2) - archivio legacy</div>
<div class="overflow-x-auto">
<table class="min-w-full text-sm">
<thead>
<tr class="border-b border-amber-200 dark:border-amber-700/50">
<th class="px-3 py-2 text-left">Voce</th>
<th class="px-3 py-2 text-right">Totale EUR</th>
</tr>
</thead>
<tbody>
@forelse($legacyExtraRows as $row)
<tr class="border-b border-amber-100 dark:border-amber-800/30">
<td class="px-3 py-2">{{ $row['cod_spe'] }}</td>
<td class="px-3 py-2 text-right">{{ number_format((float) ($row['totale'] ?? 0), 2, ',', '.') }}</td>
</tr>
@empty
<tr>
<td colspan="2" class="px-3 py-4 text-center text-amber-700 dark:text-amber-300">Nessuna voce AC diversa da AC1 trovata.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
@endif
</div>
@endif
@if($riscaldamentoTab === 'letture')
<div class="space-y-4">
<div class="rounded-lg border border-emerald-200 bg-emerald-50 p-4 dark:border-emerald-700/50 dark:bg-emerald-900/10">
<div class="mb-3 flex flex-wrap items-center justify-between gap-3">
<div>
<div class="text-sm font-semibold text-emerald-900 dark:text-emerald-200">Campagna letture riscaldamento per unità</div>
<div class="mt-1 text-xs text-emerald-800 dark:text-emerald-300">Vista operativa ordinabile e modificabile riga per riga: puoi salvare una riga o tutte insieme, inviare il link pubblico e aprire il ticket riscaldamento della singola unità.</div>
</div>
<div class="flex flex-wrap gap-2">
<button type="button" wire:click="setRiscaldamentoCampagnaSort('scala_interno')" class="inline-flex items-center rounded-md border px-3 py-1.5 text-xs font-medium {{ $this->riscaldamentoCampagnaSort === 'scala_interno' ? 'border-emerald-300 bg-emerald-100 text-emerald-900' : 'border-emerald-200 bg-white text-emerald-700' }}">Ordina per scala/interno</button>
<button type="button" wire:click="setRiscaldamentoCampagnaSort('nominativo')" class="inline-flex items-center rounded-md border px-3 py-1.5 text-xs font-medium {{ $this->riscaldamentoCampagnaSort === 'nominativo' ? 'border-emerald-300 bg-emerald-100 text-emerald-900' : 'border-emerald-200 bg-white text-emerald-700' }}">Ordina per nominativo</button>
<button type="button" wire:click="saveAllRiscaldamentoCampagnaRows" class="inline-flex items-center rounded-md border border-emerald-200 bg-white px-3 py-1.5 text-xs font-medium text-emerald-700 hover:bg-emerald-100">Salva tutte le righe</button>
<x-filament::button size="sm" color="success" wire:click="prepareRiscaldamentoReadingCampaign">
Prepara / aggiorna campagna letture
</x-filament::button>
</div>
</div>
<div class="grid gap-3 md:grid-cols-4">
<div class="rounded-lg border bg-white p-3 text-sm dark:bg-gray-900">
<div class="text-xs uppercase tracking-wide text-gray-500">Unità</div>
<div class="mt-2 text-xl font-semibold">{{ $campagnaStats['totale'] }}</div>
</div>
<div class="rounded-lg border bg-white p-3 text-sm dark:bg-gray-900">
<div class="text-xs uppercase tracking-wide text-gray-500">Fatte</div>
<div class="mt-2 text-xl font-semibold text-emerald-700">{{ $campagnaStats['completate'] }}</div>
</div>
<div class="rounded-lg border bg-white p-3 text-sm dark:bg-gray-900">
<div class="text-xs uppercase tracking-wide text-gray-500">Pendenti</div>
<div class="mt-2 text-xl font-semibold text-amber-700">{{ $campagnaStats['pendenti'] }}</div>
</div>
<div class="rounded-lg border bg-white p-3 text-sm dark:bg-gray-900">
<div class="text-xs uppercase tracking-wide text-gray-500">Sollecitate</div>
<div class="mt-2 text-xl font-semibold text-sky-700">{{ $campagnaStats['sollecitate'] }}</div>
</div>
</div>
<div class="mt-4 overflow-x-auto">
<table class="min-w-full text-xs">
<thead>
<tr class="border-b border-emerald-200 dark:border-emerald-700/50">
<th class="px-2 py-2 text-left">Unità</th>
<th class="px-2 py-2 text-left">Nominativo</th>
<th class="px-2 py-2 text-left">Email</th>
<th class="px-2 py-2 text-right">Lettura precedente</th>
<th class="px-2 py-2 text-left">Stato</th>
<th class="px-2 py-2 text-left">Richiesta</th>
<th class="px-2 py-2 text-left">Inserimento rapido</th>
<th class="px-2 py-2 text-left">Azioni</th>
</tr>
</thead>
<tbody>
@forelse($campagnaRows as $row)
<tr class="border-b border-emerald-100 dark:border-emerald-800/30">
<td class="px-2 py-2">{{ $row['unit_label'] }}</td>
<td class="px-2 py-2">{{ $row['nominativo'] }}</td>
<td class="px-2 py-2 text-[11px] text-gray-600">{{ $row['email'] ?: '' }}</td>
<td class="px-2 py-2 text-right">{{ $row['previous_reading'] !== null ? number_format((float) $row['previous_reading'], 3, ',', '.') : '' }}</td>
<td class="px-2 py-2">
@if($row['status'] === 'fatta')
<span class="rounded bg-emerald-100 px-1.5 py-0.5 font-semibold text-emerald-700">Fatta</span>
@elseif($row['status'] === 'sollecito')
<span class="rounded bg-sky-100 px-1.5 py-0.5 font-semibold text-sky-700">Sollecito</span>
@elseif($row['status'] === 'richiesta')
<span class="rounded bg-amber-100 px-1.5 py-0.5 font-semibold text-amber-700">Richiesta inviata</span>
@else
<span class="rounded bg-slate-100 px-1.5 py-0.5 font-semibold text-slate-700">Da inviare</span>
@endif
</td>
<td class="px-2 py-2">
{{ $row['requested_at'] ?: '' }}
@if($row['deadline_at'])
<div class="text-[10px] text-gray-500">Scadenza {{ $row['deadline_at'] }}</div>
@endif
</td>
<td class="px-2 py-2">
<div class="flex flex-nowrap items-center gap-2 overflow-x-auto pb-1">
<input type="date" wire:model.defer="riscaldamentoCampagnaEditRows.{{ $row['unit_id'] }}.data_lettura" class="w-32 rounded-md border-emerald-200 text-[11px]" />
<input type="date" wire:model.defer="riscaldamentoCampagnaEditRows.{{ $row['unit_id'] }}.deadline_at" class="w-32 rounded-md border-emerald-200 text-[11px]" />
<select wire:model.defer="riscaldamentoCampagnaEditRows.{{ $row['unit_id'] }}.canale" class="w-28 rounded-md border-emerald-200 text-[11px]">
<option value="manuale">Manuale</option>
<option value="email">Email</option>
<option value="whatsapp">WhatsApp</option>
<option value="link_pubblico">Link pubblico</option>
</select>
<input type="text" wire:model.defer="riscaldamentoCampagnaEditRows.{{ $row['unit_id'] }}.riferimento" placeholder="Rif." class="w-32 rounded-md border-emerald-200 text-[11px]" />
<input type="number" step="0.001" wire:model.defer="riscaldamentoCampagnaEditRows.{{ $row['unit_id'] }}.previous_reading" placeholder="Prec." class="w-24 rounded-md border-emerald-200 text-[11px]" />
<input type="number" step="0.001" wire:model.defer="riscaldamentoCampagnaEditRows.{{ $row['unit_id'] }}.lettura_finale" placeholder="Finale" class="w-24 rounded-md border-emerald-200 text-[11px]" />
<input type="text" wire:model.defer="riscaldamentoCampagnaEditRows.{{ $row['unit_id'] }}.reader_name" placeholder="Rilevatore" class="w-28 rounded-md border-emerald-200 text-[11px]" />
<input type="text" wire:model.defer="riscaldamentoCampagnaEditRows.{{ $row['unit_id'] }}.note" placeholder="Nota" class="w-40 rounded-md border-emerald-200 text-[11px]" />
</div>
</td>
<td class="px-2 py-2">
<div class="flex flex-wrap gap-2">
<a href="{{ $row['public_url'] }}" target="_blank" class="inline-flex items-center rounded-md bg-white px-2 py-1 text-[11px] font-medium text-emerald-800 ring-1 ring-inset ring-emerald-300 hover:bg-emerald-100">Apri link</a>
<a href="{{ $row['ticket_url'] }}" class="inline-flex items-center rounded-md bg-white px-2 py-1 text-[11px] font-medium text-emerald-800 ring-1 ring-inset ring-emerald-300 hover:bg-emerald-100">Ticket riscaldamento</a>
<button type="button" wire:click="saveRiscaldamentoCampagnaRow({{ (int) $row['unit_id'] }})" class="inline-flex items-center rounded-md bg-emerald-600 px-2 py-1 text-[11px] font-medium text-white hover:bg-emerald-500">Salva riga</button>
@if($row['request_id'] && $row['status'] !== 'fatta')
<button type="button" wire:click="markRiscaldamentoReadingReminder({{ (int) $row['request_id'] }})" class="inline-flex items-center rounded-md bg-slate-100 px-2 py-1 text-[11px] font-medium text-slate-700 hover:bg-slate-200">Sollecito</button>
@endif
</div>
</td>
</tr>
@empty
<tr>
<td colspan="8" class="px-2 py-4 text-center text-emerald-700 dark:text-emerald-300">Nessuna unità disponibile per la campagna letture.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
<!-- Importazione Letture Contatori Elettronici (CSV) -->
<div class="rounded-lg border border-emerald-200 bg-white p-4 dark:border-emerald-700/50 dark:bg-gray-900 shadow-sm">
<div class="text-xs font-semibold uppercase tracking-wide text-emerald-900 dark:text-emerald-200 mb-3">Importazione Letture Contatori Elettronici (CSV)</div>
<form wire:submit.prevent="importElectronicReadings" class="flex flex-wrap items-end gap-4">
<div>
<label class="block text-[10px] font-medium text-gray-500 uppercase dark:text-gray-400">File CSV Letture</label>
<input type="file" wire:model="riscaldamentoReadingsFile" class="mt-1 block text-xs dark:text-gray-100">
@error('riscaldamentoReadingsFile') <span class="text-red-500 text-xs">{{ $message }}</span> @enderror
</div>
<button type="submit" class="rounded-md bg-emerald-600 px-3 py-2 text-xs font-semibold text-white shadow-sm hover:bg-emerald-500 transition focus:outline-none focus:ring-2 focus:ring-emerald-500">Importa letture CSV</button>
</form>
<div class="mt-2 text-[10px] text-gray-500 dark:text-gray-400">Tracciato supportato: <code>#ID,Modulo n°,Contatore n°,Nome,Cognome,Indirizzo,Interno,Lettura...</code> (la colonna #ID verrà abbinata con <code>riscaldamento_gateway_device_id</code> o in alternativa con l'<code>interno</code>).</div>
</div>
<div class="rounded-lg border border-slate-200 bg-slate-50 p-4 dark:border-slate-700/50 dark:bg-slate-900/20">
<div class="mb-2 text-sm font-semibold text-slate-900 dark:text-slate-100">Base nominativi riparto RISCALDAMENTO (legacy) per inserimento letture manuali</div>
<div class="mb-2 text-xs text-slate-600 dark:text-slate-300">
Fonte letture manuali PDF: <code>/home/michele/netgescon/netgescon-laravel/Miki-Bug-workspace/RISCALDAMENTO-Acea/06 - 2024 VIA_A_DORIA_36.0.RIPARTO.2.pdf</code>
</div>
<div class="overflow-x-auto">
<table class="min-w-full text-xs">
<thead>
<tr class="border-b border-slate-200 dark:border-slate-700/50">
<th class="px-2 py-2 text-left">Scala</th>
<th class="px-2 py-2 text-left">Interno</th>
<th class="px-2 py-2 text-left">Nominativo</th>
<th class="px-2 py-2 text-left">Ruolo</th>
<th class="px-2 py-2 text-right">Lettura iniziale</th>
<th class="px-2 py-2 text-right">Consumo mc</th>
<th class="px-2 py-2 text-right">Quota EUR (riparto)</th>
</tr>
</thead>
<tbody>
@forelse($riscaldamentoRipartoNominativi as $row)
<tr class="border-b border-slate-100 dark:border-slate-800/30">
<td class="px-2 py-2">{{ $row['scala'] ?: '—' }}</td>
<td class="px-2 py-2">{{ $row['interno'] ?: '—' }}</td>
<td class="px-2 py-2">{{ $row['nominativo'] ?: '—' }}</td>
<td class="px-2 py-2">{{ $row['ruolo'] ?: '—' }}</td>
<td class="px-2 py-2 text-right">{{ isset($row['lettura_iniziale']) && $row['lettura_iniziale'] !== null ? number_format((float) $row['lettura_iniziale'], 3, ',', '.') : '—' }}</td>
<td class="px-2 py-2 text-right">{{ isset($row['consumo_mc']) && $row['consumo_mc'] !== null ? number_format((float) $row['consumo_mc'], 3, ',', '.') : '—' }}</td>
<td class="px-2 py-2 text-right">{{ number_format((float) ($row['quota_euro'] ?? 0), 2, ',', '.') }}</td>
</tr>
@empty
<tr>
<td colspan="7" class="px-2 py-4 text-center text-slate-500">Nominativi riparto legacy non disponibili.</td>
</tr>
@endforelse
</tbody>
@if(count($riscaldamentoRipartoNominativi) > 0)
<tfoot>
<tr class="bg-slate-100 dark:bg-slate-900/40 font-semibold">
<td class="px-2 py-2" colspan="5">Totali</td>
<td class="px-2 py-2 text-right">{{ number_format((float) collect($riscaldamentoRipartoNominativi)->sum(fn($r) => (float) ($r['consumo_mc'] ?? 0)), 3, ',', '.') }}</td>
<td class="px-2 py-2 text-right">{{ number_format((float) collect($riscaldamentoRipartoNominativi)->sum(fn($r) => (float) ($r['quota_euro'] ?? 0)), 2, ',', '.') }}</td>
</tr>
</tfoot>
@endif
</table>
</div>
</div>
<div class="rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-900">
<div class="mb-3 flex flex-wrap items-center justify-between gap-3">
<div>
<div class="text-sm font-semibold text-gray-900 dark:text-gray-100">Letture contatori UI (con data ricezione e riferimento)</div>
<div class="mt-1 text-xs text-gray-500 dark:text-gray-400">CRUD rapido inline per le letture UI correnti; l'archivio completo resta disponibile per foto, riassegnazioni e storico esteso.</div>
</div>
<div class="flex flex-wrap gap-2">
<button type="button" wire:click="startCreateRiscaldamentoUiReading" class="inline-flex items-center rounded-md border border-emerald-200 bg-emerald-50 px-3 py-1.5 text-xs font-medium text-emerald-700 hover:bg-emerald-100">Nuova lettura UI</button>
<a href="{{ \App\Filament\Pages\Condomini\LettureServiziArchivio::getUrl(['scope' => 'active']) }}"
class="inline-flex items-center rounded-md border border-blue-200 bg-blue-50 px-3 py-1.5 text-xs font-medium text-blue-700 hover:bg-blue-100 dark:border-blue-700/50 dark:bg-blue-900/20 dark:text-blue-200">
Apri archivio letture UI / CRUD (anno {{ $annoGestioneAttivo }})
</a>
</div>
</div>
<div class="mb-4 rounded-lg border border-emerald-200 bg-emerald-50 p-4 dark:border-emerald-700/50 dark:bg-emerald-900/10">
<div class="mb-3 flex flex-wrap items-center justify-between gap-2">
<div class="text-sm font-semibold text-emerald-900 dark:text-emerald-200">{{ $this->riscaldamentoUiEditingId ? 'Modifica lettura UI' : 'Inserimento rapido lettura UI' }}</div>
@if($this->riscaldamentoUiEditingId)
<button type="button" wire:click="cancelRiscaldamentoUiEditing" class="inline-flex items-center rounded-md border border-emerald-300 bg-white px-2 py-1 text-[11px] font-medium text-emerald-800 hover:bg-emerald-100">Annulla modifica</button>
@endif
</div>
<div class="grid gap-3 md:grid-cols-2 xl:grid-cols-4">
<label class="text-xs font-medium text-emerald-900 dark:text-emerald-100">
Servizio riscaldamento
<select wire:model.defer="riscaldamentoUiReadingForm.stabile_servizio_id" class="mt-1 block w-full rounded-md border-emerald-300 bg-white text-sm text-gray-900 shadow-sm focus:border-emerald-500 focus:ring-emerald-500">
<option value="">Seleziona servizio</option>
@foreach($uiServiceOptions as $id => $label)
<option value="{{ $id }}">{{ $label }}</option>
@endforeach
</select>
</label>
<label class="text-xs font-medium text-emerald-900 dark:text-emerald-100">
Unità immobiliare
<select wire:model.defer="riscaldamentoUiReadingForm.unita_immobiliare_id" class="mt-1 block w-full rounded-md border-emerald-300 bg-white text-sm text-gray-900 shadow-sm focus:border-emerald-500 focus:ring-emerald-500">
<option value="">Seleziona unità</option>
@foreach($uiUnitOptions as $id => $label)
<option value="{{ $id }}">{{ $label }}</option>
@endforeach
</select>
</label>
<label class="text-xs font-medium text-emerald-900 dark:text-emerald-100">
Periodo dal
<input type="date" wire:model.defer="riscaldamentoUiReadingForm.periodo_dal" class="mt-1 block w-full rounded-md border-emerald-300 bg-white text-sm text-gray-900 shadow-sm focus:border-emerald-500 focus:ring-emerald-500" />
</label>
<label class="text-xs font-medium text-emerald-900 dark:text-emerald-100">
Periodo al
<input type="date" wire:model.defer="riscaldamentoUiReadingForm.periodo_al" class="mt-1 block w-full rounded-md border-emerald-300 bg-white text-sm text-gray-900 shadow-sm focus:border-emerald-500 focus:ring-emerald-500" />
</label>
<label class="text-xs font-medium text-emerald-900 dark:text-emerald-100">
Canale
<select wire:model.defer="riscaldamentoUiReadingForm.canale_acquisizione" class="mt-1 block w-full rounded-md border-emerald-300 bg-white text-sm text-gray-900 shadow-sm focus:border-emerald-500 focus:ring-emerald-500">
<option value="manuale">Manuale</option>
<option value="email">Email</option>
<option value="whatsapp">WhatsApp</option>
<option value="link_pubblico">Link pubblico</option>
<option value="import_file">Import file</option>
</select>
</label>
<label class="text-xs font-medium text-emerald-900 dark:text-emerald-100">
Riferimento
<input type="text" wire:model.defer="riscaldamentoUiReadingForm.riferimento_acquisizione" class="mt-1 block w-full rounded-md border-emerald-300 bg-white text-sm text-gray-900 shadow-sm focus:border-emerald-500 focus:ring-emerald-500" placeholder="Es. mail, ticket, protocollo" />
</label>
<label class="text-xs font-medium text-emerald-900 dark:text-emerald-100">
Lettura precedente
<input type="number" step="0.001" min="0" wire:model.defer="riscaldamentoUiReadingForm.lettura_precedente_valore" class="mt-1 block w-full rounded-md border-emerald-300 bg-white text-sm text-gray-900 shadow-sm focus:border-emerald-500 focus:ring-emerald-500" />
</label>
<label class="text-xs font-medium text-emerald-900 dark:text-emerald-100">
Lettura finale
<input type="number" step="0.001" min="0" wire:model.defer="riscaldamentoUiReadingForm.lettura_fine" class="mt-1 block w-full rounded-md border-emerald-300 bg-white text-sm text-gray-900 shadow-sm focus:border-emerald-500 focus:ring-emerald-500" />
</label>
</div>
<div class="mt-3 grid gap-3 md:grid-cols-2 xl:grid-cols-4">
<label class="text-xs font-medium text-emerald-900 dark:text-emerald-100">
Lettura inizio
<input type="number" step="0.001" min="0" wire:model.defer="riscaldamentoUiReadingForm.lettura_inizio" class="mt-1 block w-full rounded-md border-emerald-300 bg-white text-sm text-gray-900 shadow-sm focus:border-emerald-500 focus:ring-emerald-500" />
</label>
<label class="text-xs font-medium text-emerald-900 dark:text-emerald-100">
Consumo
<input type="number" step="0.001" wire:model.defer="riscaldamentoUiReadingForm.consumo_valore" class="mt-1 block w-full rounded-md border-emerald-300 bg-white text-sm text-gray-900 shadow-sm focus:border-emerald-500 focus:ring-emerald-500" />
</label>
<label class="text-xs font-medium text-emerald-900 dark:text-emerald-100">
Rilevatore
<input type="text" wire:model.defer="riscaldamentoUiReadingForm.rilevatore_nome" class="mt-1 block w-full rounded-md border-emerald-300 bg-white text-sm text-gray-900 shadow-sm focus:border-emerald-500 focus:ring-emerald-500" />
</label>
<label class="text-xs font-medium text-emerald-900 dark:text-emerald-100">
Deadline
<input type="date" wire:model.defer="riscaldamentoUiReadingForm.deadline_lettura_at" class="mt-1 block w-full rounded-md border-emerald-300 bg-white text-sm text-gray-900 shadow-sm focus:border-emerald-500 focus:ring-emerald-500" />
</label>
</div>
<label class="mt-3 block text-xs font-medium text-emerald-900 dark:text-emerald-100">
Nota operativa
<textarea rows="2" wire:model.defer="riscaldamentoUiReadingForm.note" class="mt-1 block w-full rounded-md border-emerald-300 bg-white text-sm text-gray-900 shadow-sm focus:border-emerald-500 focus:ring-emerald-500" placeholder="Nota inline editor"></textarea>
</label>
<div class="mt-3 flex flex-wrap gap-2">
<button type="button" wire:click="saveRiscaldamentoUiReading" class="inline-flex items-center rounded-md bg-emerald-600 px-3 py-1.5 text-xs font-medium text-white hover:bg-emerald-500">{{ $this->riscaldamentoUiEditingId ? 'Salva modifica' : 'Crea lettura UI' }}</button>
@if($this->riscaldamentoUiEditingId)
<button type="button" wire:click="cancelRiscaldamentoUiEditing" class="inline-flex items-center rounded-md border border-emerald-300 bg-white px-3 py-1.5 text-xs font-medium text-emerald-800 hover:bg-emerald-100">Chiudi</button>
@endif
</div>
</div>
<div class="overflow-x-auto">
<table class="min-w-full text-xs">
<thead>
<tr class="border-b border-gray-200 dark:border-gray-800">
<th class="px-2 py-2 text-left">Data ricezione</th>
<th class="px-2 py-2 text-left">Servizio</th>
<th class="px-2 py-2 text-left">Unità</th>
<th class="px-2 py-2 text-left">Canale</th>
<th class="px-2 py-2 text-left">Riferimento / immagine</th>
<th class="px-2 py-2 text-left">Periodo</th>
<th class="px-2 py-2 text-right">Lettura/consumo</th>
<th class="px-2 py-2 text-left">Azioni</th>
</tr>
</thead>
<tbody>
@forelse($lettureCondomini as $row)
<tr class="border-b border-gray-100 dark:border-gray-800">
<td class="px-2 py-2">{{ $row['data_ricezione'] ?: '' }}</td>
<td class="px-2 py-2">{{ $row['servizio'] ?: '' }}<br><span class="text-[10px] text-gray-500">Matr. {{ $row['matricola'] ?: '' }}</span></td>
<td class="px-2 py-2">{{ trim((string) ($row['unita'] ?? '')) !== '' ? $row['unita'] : '' }}</td>
<td class="px-2 py-2">{{ strtoupper((string) ($row['canale'] ?? '')) }}</td>
<td class="px-2 py-2 break-all">{{ $row['riferimento'] ?: '' }}</td>
<td class="px-2 py-2">{{ $row['periodo'] ?: '' }}</td>
<td class="px-2 py-2 text-right">
@if(isset($row['consumo_valore']) && $row['consumo_valore'] !== null)
{{ number_format((float) $row['consumo_valore'], 3, ',', '.') }} {{ $row['consumo_unita'] ?: 'mc' }}
@else
@endif
</td>
<td class="px-2 py-2">
<div class="flex flex-wrap gap-2">
<button type="button" wire:click="startEditRiscaldamentoUiReading({{ (int) $row['id'] }})" class="inline-flex items-center rounded-md bg-white px-2 py-1 text-[11px] font-medium text-emerald-800 ring-1 ring-inset ring-emerald-300 hover:bg-emerald-100">Modifica</button>
<button type="button" wire:click="deleteRiscaldamentoUiReading({{ (int) $row['id'] }})" class="inline-flex items-center rounded-md bg-white px-2 py-1 text-[11px] font-medium text-rose-700 ring-1 ring-inset ring-rose-300 hover:bg-rose-100">Elimina</button>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="8" class="px-2 py-4 text-center text-gray-500">Nessuna lettura disponibile.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
@endif
@if($riscaldamentoTab === 'generale')
<div class="space-y-4">
<div class="rounded-lg border border-cyan-200 bg-cyan-50 p-4 dark:border-cyan-700/50 dark:bg-cyan-900/10">
<div class="mb-3 flex flex-wrap items-center justify-between gap-3">
<div>
<div class="text-sm font-semibold text-cyan-900 dark:text-cyan-200">Letture del contatore generale</div>
<div class="mt-1 text-xs text-cyan-800 dark:text-cyan-300">Storico operativo del solo contatore generale: letture manuali, stime, finestre Acea e agganci alle FE riscaldamento.</div>
</div>
<div class="flex flex-wrap gap-2">
<a href="{{ \App\Filament\Pages\Supporto\TicketRiscaldamentoGenerale::getUrl(panel: 'admin-filament') }}"
class="inline-flex items-center rounded-md border border-cyan-300 bg-white px-3 py-1.5 text-xs font-medium text-cyan-800 hover:bg-cyan-100">
Ticket contatore generale
</a>
<a href="{{ \App\Filament\Pages\Condomini\LettureServiziArchivio::getUrl(['scope' => 'active']) }}"
class="inline-flex items-center rounded-md border border-cyan-300 bg-white px-3 py-1.5 text-xs font-medium text-cyan-800 hover:bg-cyan-100">
Archivio letture / storico
</a>
</div>
</div>
<div class="overflow-x-auto">
<table class="min-w-full text-xs">
<thead>
<tr class="border-b border-cyan-200 dark:border-cyan-700/50">
<th class="px-2 py-2 text-left">Data ricezione</th>
<th class="px-2 py-2 text-left">Servizio / codici</th>
<th class="px-2 py-2 text-left">Canale / protocollo</th>
<th class="px-2 py-2 text-left">Periodo / finestra</th>
<th class="px-2 py-2 text-right">Lettura</th>
<th class="px-2 py-2 text-right">Consumo</th>
<th class="px-2 py-2 text-left">Azioni</th>
</tr>
</thead>
<tbody>
@forelse($lettureGenerali as $row)
<tr class="border-b border-cyan-100 dark:border-cyan-800/30">
<td class="px-2 py-2">{{ $row['data_ricezione'] ?: '' }}</td>
<td class="px-2 py-2">
<div>{{ $row['servizio'] ?: 'Riscaldamento' }}</div>
<div class="text-[10px] text-gray-500">Matr. {{ $row['matricola'] ?: '' }} · Utenza {{ $row['codice_utenza'] ?: '' }}</div>
<div class="text-[10px] text-gray-500">Cliente {{ $row['codice_cliente'] ?: '' }} · Contratto {{ $row['codice_contratto'] ?: '' }}</div>
</td>
<td class="px-2 py-2">
<div>{{ strtoupper((string) ($row['canale'] ?? '')) }}</div>
<div class="text-[10px] text-gray-500">{{ $row['protocollo'] ?: '' }} · {{ $row['workflow'] ?: '' }}</div>
<div class="text-[10px] text-gray-500">{{ $row['reader'] ?: '' }}</div>
</td>
<td class="px-2 py-2">
<div>{{ $row['periodo'] ?: '' }}</div>
@if(!empty($row['window_label']))
<div class="text-[10px] text-cyan-700 dark:text-cyan-300">Finestra {{ $row['window_label'] }}</div>
@endif
@if(!empty($row['visit_date']))
<div class="text-[10px] text-cyan-700 dark:text-cyan-300">Passaggio Acea {{ \Carbon\Carbon::parse($row['visit_date'])->format('d/m/Y') }}</div>
@endif
@if(!empty($row['fattura_label']))
<div class="text-[10px] text-gray-500">Origine FE {{ $row['fattura_label'] }}</div>
@endif
</td>
<td class="px-2 py-2 text-right">
{{ isset($row['lettura_fine']) && $row['lettura_fine'] !== null ? number_format((float) $row['lettura_fine'], 3, ',', '.') . ' mc' : '' }}
</td>
<td class="px-2 py-2 text-right">
{{ isset($row['consumo_valore']) && $row['consumo_valore'] !== null ? number_format((float) $row['consumo_valore'], 3, ',', '.') . ' ' . ($row['consumo_unita'] ?: 'mc') : '' }}
</td>
<td class="px-2 py-2">
<div class="flex flex-wrap gap-2">
<a href="{{ $row['ticket_url'] }}" class="inline-flex items-center rounded-md bg-white px-2 py-1 text-[11px] font-medium text-cyan-800 ring-1 ring-inset ring-cyan-300 hover:bg-cyan-100">Ticket</a>
<a href="{{ $row['archivio_url'] }}" class="inline-flex items-center rounded-md bg-white px-2 py-1 text-[11px] font-medium text-cyan-800 ring-1 ring-inset ring-cyan-300 hover:bg-cyan-100">Archivio</a>
@if(!empty($row['fattura_url']))
<a href="{{ $row['fattura_url'] }}" class="inline-flex items-center rounded-md bg-white px-2 py-1 text-[11px] font-medium text-cyan-800 ring-1 ring-inset ring-cyan-300 hover:bg-cyan-100">FE</a>
@endif
</div>
</td>
</tr>
@empty
<tr>
<td colspan="7" class="px-2 py-4 text-center text-cyan-700 dark:text-cyan-300">Nessuna lettura generale disponibile per l'anno attivo.</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
@endif
@if($riscaldamentoTab === 'tariffe')
<div class="rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-900 shadow-sm">
<div class="mb-3 text-sm font-semibold text-gray-900 dark:text-gray-100 font-bold">Rendiconto Spese & Bilancio Riscaldamento</div>
<div class="overflow-x-auto">
<table class="min-w-full text-xs text-left">
<thead>
<tr class="border-b border-gray-200 dark:border-gray-800">
<th class="px-3 py-3 font-semibold text-gray-700 dark:text-gray-300">Codice</th>
<th class="px-3 py-3 font-semibold text-gray-700 dark:text-gray-300">Descrizione Voce</th>
<th class="px-3 py-3 font-semibold text-gray-700 dark:text-gray-300">Tabella Millesimale</th>
<th class="px-3 py-3 text-right font-semibold text-gray-700 dark:text-gray-300">Preventivo (Default)</th>
<th class="px-3 py-3 text-right font-semibold text-gray-700 dark:text-gray-300">Consuntivo (Registrato)</th>
<th class="px-3 py-3 text-right font-semibold text-gray-700 dark:text-gray-300">Scostamento (Delta)</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100 dark:divide-gray-800">
@php($groupedRows = collect($tariffeRows)->groupBy('tabella'))
@forelse($groupedRows as $tabellaName => $rows)
<tr class="bg-gray-100/50 dark:bg-gray-800/50">
<td colspan="6" class="px-3 py-2 font-bold text-sm text-cyan-800 dark:text-cyan-400 border-b border-cyan-200/50">
Tabella Millesimale: {{ $tabellaName }}
</td>
</tr>
@foreach($rows as $row)
<tr class="hover:bg-gray-50/50 dark:hover:bg-gray-800/10">
<td class="px-3 py-3 font-medium text-gray-900 dark:text-gray-100">{{ $row['codice'] }}</td>
<td class="px-3 py-3 text-gray-700 dark:text-gray-300">{{ $row['descrizione'] }}</td>
<td class="px-3 py-3 text-gray-500">{{ $row['tabella'] }}</td>
<td class="px-3 py-3 text-right text-gray-900 dark:text-gray-100"> {{ number_format($row['preventivo'], 2, ',', '.') }}</td>
<td class="px-3 py-3 text-right font-semibold text-gray-900 dark:text-gray-100"> {{ number_format($row['consuntivo'], 2, ',', '.') }}</td>
<td class="px-3 py-3 text-right font-semibold {{ $row['scostamento'] > 0 ? 'text-rose-600 dark:text-rose-400' : ($row['scostamento'] < 0 ? 'text-emerald-600 dark:text-emerald-400' : 'text-gray-500') }}">
{{ $row['scostamento'] > 0 ? '+' : '' }} {{ number_format($row['scostamento'], 2, ',', '.') }}
</td>
</tr>
@endforeach
@empty
<tr>
<td colspan="6" class="px-3 py-4 text-center text-gray-500">Nessuna voce di spesa riscaldamento configurata per lo stabile.</td>
</tr>
@endforelse
</tbody>
@if(count($tariffeRows) > 0)
<tfoot>
<tr class="bg-gray-50 dark:bg-gray-950/30 font-bold border-t border-gray-200">
<td colspan="3" class="px-3 py-3">Totale</td>
<td class="px-3 py-3 text-right"> {{ number_format(collect($tariffeRows)->sum('preventivo'), 2, ',', '.') }}</td>
<td class="px-3 py-3 text-right"> {{ number_format(collect($tariffeRows)->sum('consuntivo'), 2, ',', '.') }}</td>
@php($totScostamento = collect($tariffeRows)->sum('scostamento'))
<td class="px-3 py-3 text-right {{ $totScostamento > 0 ? 'text-rose-600 dark:text-rose-400' : ($totScostamento < 0 ? 'text-emerald-600 dark:text-emerald-400' : 'text-gray-900 dark:text-gray-100') }}">
{{ $totScostamento > 0 ? '+' : '' }} {{ number_format($totScostamento, 2, ',', '.') }}
</td>
</tr>
</tfoot>
@endif
</table>
</div>
</div>
@endif
@if($riscaldamentoTab === 'servizi')
<div class="rounded-lg border border-gray-200 bg-white p-4 dark:border-gray-800 dark:bg-gray-900">
<div class="mb-3 text-sm font-semibold text-gray-900 dark:text-gray-100">Servizi / Utenze (anagrafica completa)</div>
{{ $this->table }}
</div>
@endif
</div>
<!-- Modal per invio email ripartizione -->
@if($showSendEmailModal)
<div class="fixed inset-0 z-50 flex items-center justify-center overflow-y-auto bg-gray-500 bg-opacity-75 p-4" style="background-color: rgba(0,0,0,0.5);">
<div class="w-full max-w-md transform overflow-hidden rounded-lg bg-white p-6 shadow-xl dark:bg-gray-900 transition-all">
<div class="flex items-center justify-between border-b pb-3 dark:border-gray-800">
<h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100">Invia riepilogo contatori via email</h3>
<button type="button" wire:click="$set('showSendEmailModal', false)" class="text-gray-400 hover:text-gray-500">&times;</button>
</div>
<div class="mt-4 space-y-4 text-xs">
<div>
<label class="block font-medium text-gray-700 dark:text-gray-300">Email Destinatario *</label>
<input type="email" wire:model="emailDestinatario" placeholder="es. info@studio.it" class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 dark:bg-gray-800 shadow-sm text-xs text-gray-900 dark:text-gray-100">
</div>
<div>
<label class="block font-medium text-gray-700 dark:text-gray-300">Oggetto</label>
<input type="text" wire:model="emailOggetto" class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 dark:bg-gray-800 shadow-sm text-xs text-gray-900 dark:text-gray-100">
</div>
<div>
<label class="block font-medium text-gray-700 dark:text-gray-300">Corpo del messaggio</label>
<textarea wire:model="emailCorpo" rows="4" class="mt-1 block w-full rounded-md border-gray-300 dark:border-gray-700 dark:bg-gray-800 shadow-sm text-xs text-gray-900 dark:text-gray-100"></textarea>
</div>
</div>
<div class="mt-6 flex justify-end gap-3">
<button type="button" wire:click="$set('showSendEmailModal', false)" class="rounded-md border border-gray-300 bg-white px-3 py-2 text-xs font-semibold text-gray-700 hover:bg-gray-50">Annulla</button>
<button type="button" wire:click="sendRipartizioneEmail" class="rounded-md bg-blue-600 px-3 py-2 text-xs font-semibold text-white shadow-sm hover:bg-blue-500">Invia</button>
</div>
</div>
</div>
@endif
</x-filament-panels::page>