netgescon-day0/resources/views/filament/pages/condomini/contratti-hub.blade.php

229 lines
18 KiB
PHP
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<x-filament-panels::page>
@php($stats = $this->stats)
@php($contratti = $this->contrattiRows)
@php($scadenze = $this->upcomingScadenze)
@php($acqua = $this->acquaSnapshot)
@php($acquaDiagnostics = $this->acquaExtractionDiagnostics)
<div class="space-y-6">
<div class="rounded-2xl border border-slate-200 bg-gradient-to-r from-cyan-50 via-white to-emerald-50 p-5">
<div class="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
<div>
<div class="text-sm font-semibold uppercase tracking-[0.18em] text-slate-500">Stabile</div>
<h2 class="mt-2 text-2xl font-semibold text-slate-900">HUB Contratti {{ $this->stabileAttivo?->denominazione ? '· ' . $this->stabileAttivo->denominazione : '' }}</h2>
<p class="mt-2 max-w-3xl text-sm text-slate-600">Qui registriamo il contratto, i riferimenti tecnici e le scadenze operative da inviare anche al calendario. Il collegamento documentale e contabile parte da qui.</p>
</div>
<div class="rounded-xl border border-white/70 bg-white/80 px-4 py-3 shadow-sm">
<div class="text-xs uppercase tracking-wide text-slate-500">Collegamenti</div>
<div class="mt-2 text-sm text-slate-700">Fornitore, manutentore, servizio, utenza, documento e codici tecnici nello stesso record.</div>
</div>
</div>
<div class="mt-5 grid gap-3 md:grid-cols-2 xl:grid-cols-4">
<div class="rounded-xl border bg-white p-4">
<div class="text-xs uppercase tracking-wide text-slate-500">Contratti</div>
<div class="mt-2 text-2xl font-semibold text-slate-900">{{ $stats['totale'] ?? 0 }}</div>
</div>
<div class="rounded-xl border bg-white p-4">
<div class="text-xs uppercase tracking-wide text-slate-500">Attivi</div>
<div class="mt-2 text-2xl font-semibold text-slate-900">{{ $stats['attivi'] ?? 0 }}</div>
</div>
<div class="rounded-xl border bg-white p-4">
<div class="text-xs uppercase tracking-wide text-slate-500">Scadenze 45 gg</div>
<div class="mt-2 text-2xl font-semibold text-slate-900">{{ $stats['scadenze'] ?? 0 }}</div>
</div>
<div class="rounded-xl border bg-white p-4">
<div class="text-xs uppercase tracking-wide text-slate-500">Documenti contratto</div>
<div class="mt-2 text-2xl font-semibold text-slate-900">{{ $stats['documenti'] ?? 0 }}</div>
</div>
</div>
</div>
<div class="grid gap-6 xl:grid-cols-[minmax(0,1.4fr)_minmax(320px,0.6fr)]">
<x-filament::section>
<x-slot name="heading">Registro contratti</x-slot>
<x-slot name="description">CRUD In-line: modifica direttamente i campi della riga per aggiornare scadenze, importi e caricare i PDF allegati.</x-slot>
<div class="overflow-x-auto">
<table class="w-full text-left text-xs border-collapse border border-slate-200 rounded-xl overflow-hidden shadow-xs">
<thead>
<tr class="bg-slate-100 dark:bg-slate-800 text-slate-700 dark:text-slate-300 font-bold uppercase border-b border-slate-200">
<th class="p-3">Titolo / Fornitore</th>
<th class="p-3">Tipo / Gestione</th>
<th class="p-3">Data Scadenza</th>
<th class="p-3">Importo Periodico</th>
<th class="p-3 text-center">Documento PDF</th>
<th class="p-3">Note / Info</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-200 bg-white dark:bg-slate-900">
@forelse($contratti as $contratto)
<tr class="hover:bg-slate-50 dark:hover:bg-slate-800/50 transition-colors">
<!-- Titolo e Fornitore -->
<td class="p-3 font-medium text-slate-900 dark:text-slate-100">
<div class="font-bold text-sm">{{ $contratto->titolo }}</div>
<div class="text-xs text-slate-500 mt-0.5">
Fornitore: {{ $contratto->fornitore?->ragione_sociale ?: trim(($contratto->fornitore?->nome ?? '') . ' ' . ($contratto->fornitore?->cognome ?? '')) ?: 'Non specificato' }}
</div>
</td>
<!-- Tipo Contratto / Gestione -->
<td class="p-3">
<select
wire:change="aggiornaCampoInline({{ $contratto->id }}, 'tipo_contratto', $event.target.value)"
class="rounded-lg border-slate-200 dark:border-slate-700 py-1 text-xs bg-slate-50 dark:bg-slate-800 focus:bg-white w-full font-medium"
>
@foreach($this->getTipoContrattoOptions() as $key => $lbl)
<option value="{{ $key }}" {{ $contratto->tipo_contratto === $key ? 'selected' : '' }}>{{ $lbl }}</option>
@endforeach
</select>
</td>
<!-- Data Scadenza -->
<td class="p-3">
<input
type="date"
value="{{ $contratto->decorrenza_al?->format('Y-m-d') }}"
wire:change="aggiornaCampoInline({{ $contratto->id }}, 'decorrenza_al', $event.target.value)"
class="rounded-lg border-slate-200 dark:border-slate-700 py-1 text-xs bg-slate-50 dark:bg-slate-800 focus:bg-white w-full"
/>
</td>
<!-- Importo Periodico -->
<td class="p-3">
<div class="relative rounded-lg shadow-xs">
<div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-2">
<span class="text-slate-500 text-xs"></span>
</div>
<input
type="number"
step="0.01"
value="{{ $contratto->importo_periodico }}"
wire:change="aggiornaCampoInline({{ $contratto->id }}, 'importo_periodico', $event.target.value)"
class="rounded-lg border-slate-200 dark:border-slate-700 py-1 pl-6 text-xs text-right bg-slate-50 dark:bg-slate-800 focus:bg-white w-28 font-semibold"
/>
</div>
</td>
<!-- Documento PDF -->
<td class="p-3 text-center">
@if($contratto->documentoPrincipale)
<a
href="{{ storage_url($contratto->documentoPrincipale->path_file) }}"
target="_blank"
class="inline-flex items-center gap-1 rounded-md bg-emerald-50 dark:bg-emerald-950/40 px-2 py-1 text-xxs font-bold text-emerald-700 dark:text-emerald-300 hover:underline"
>
<x-filament::icon icon="heroicon-o-document-text" class="h-4.5 w-4.5 text-emerald-600" />
{{ Str::limit($contratto->documentoPrincipale->nome_file ?: 'Visualizza PDF', 15) }}
</a>
@else
{{ ($this->caricaPdfContrattoAction)(['contract_id' => $contratto->id]) }}
@endif
</td>
<!-- Note / Info -->
<td class="p-3 text-slate-600 dark:text-slate-400">
<div class="max-w-[150px] overflow-hidden text-ellipsis whitespace-nowrap text-xxs" title="{{ $contratto->note }}">
{{ $contratto->note ?: 'Nessuna nota' }}
</div>
<div class="text-[10px] text-slate-400 mt-0.5">
Codice: {{ $contratto->codice_contratto ?: 'n/d' }} · Rif: {{ $contratto->riferimento_esterno ?: 'n/d' }}
</div>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="p-8 text-center text-slate-500 border border-dashed rounded-xl bg-slate-50">
Nessun contratto registrato per lo stabile attivo.
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</x-filament::section>
<div class="space-y-6">
<x-filament::section>
<x-slot name="heading">Scadenze programmate</x-slot>
<x-slot name="description">Le nuove scadenze vengono registrate sulla tabella calendario operativa.</x-slot>
<div class="space-y-3">
@forelse($scadenze as $scadenza)
<div class="rounded-xl border bg-white px-4 py-3">
<div class="flex items-start justify-between gap-3">
<div>
<div class="text-sm font-semibold text-slate-900">{{ $scadenza->stabileContratto?->titolo ?: $scadenza->descrizione_sintetica }}</div>
<div class="mt-1 text-xs text-slate-500">{{ $scadenza->stabileContratto?->tipo_contratto ? $this->contractTypeLabel($scadenza->stabileContratto->tipo_contratto) : 'Scadenza contratto' }}</div>
</div>
<div class="text-sm font-semibold text-slate-900">{{ $scadenza->data_scadenza?->format('d/m/Y') ?: '—' }}</div>
</div>
@if(!empty($scadenza->legacy_payload['codice_contratto']))
<div class="mt-2 text-xs text-slate-500">Codice: {{ $scadenza->legacy_payload['codice_contratto'] }}</div>
@endif
</div>
@empty
<div class="rounded-xl border border-dashed bg-white px-4 py-6 text-sm text-slate-500">Nessuna scadenza contrattuale registrata.</div>
@endforelse
</div>
</x-filament::section>
<x-filament::section>
<x-slot name="heading">Acqua operativa</x-slot>
<x-slot name="description">Allineamento tra servizio acqua dello stabile e contratto registrato nell'hub.</x-slot>
<div class="space-y-3 text-sm text-slate-600">
<div class="rounded-xl border bg-white px-4 py-3">
<div class="text-xs uppercase tracking-wide text-slate-500">Servizio</div>
<div class="mt-1 font-medium text-slate-900">{{ $acqua['servizio_nome'] ?: 'Servizio acqua non configurato' }}</div>
</div>
<div class="rounded-xl border bg-white px-4 py-3">
<div>Fornitore: <span class="font-medium text-slate-900">{{ $acqua['fornitore'] ?: '' }}</span></div>
<div class="mt-1">Utenza: <span class="font-medium text-slate-900">{{ $acqua['utenza'] ?: '' }}</span></div>
<div class="mt-1">Cliente: <span class="font-medium text-slate-900">{{ $acqua['cliente'] ?: '' }}</span></div>
<div class="mt-1">Contratto: <span class="font-medium text-slate-900">{{ $acqua['contratto'] ?: '' }}</span></div>
<div class="mt-1">Matricola: <span class="font-medium text-slate-900">{{ $acqua['matricola'] ?: '' }}</span></div>
<div class="mt-2 text-xs text-slate-500">Record HUB acqua: {{ $acqua['contratto_hub_id'] ? ('#' . $acqua['contratto_hub_id']) : 'non ancora registrato' }}</div>
</div>
@if(auth()->user()?->hasAnyRole(['super-admin', 'admin']))
<div class="rounded-xl border {{ count($acquaDiagnostics['warnings'] ?? []) > 0 ? 'border-amber-200 bg-amber-50' : 'border-emerald-200 bg-emerald-50' }} px-4 py-3">
<div class="text-xs uppercase tracking-wide {{ count($acquaDiagnostics['warnings'] ?? []) > 0 ? 'text-amber-700' : 'text-emerald-700' }}">Diagnostica estrazione FE acqua</div>
<div class="mt-2 grid gap-2 text-xs text-slate-700 md:grid-cols-3">
<div>FE lette: <span class="font-semibold">{{ $acquaDiagnostics['counts']['totale'] ?? 0 }}</span></div>
<div>Con identificativi: <span class="font-semibold">{{ $acquaDiagnostics['counts']['con_identificativi'] ?? 0 }}</span></div>
<div>Con dati pagamento: <span class="font-semibold">{{ $acquaDiagnostics['counts']['con_pagamento'] ?? 0 }}</span></div>
</div>
@if(!empty($acquaDiagnostics['latest']))
<div class="mt-3 rounded-lg border border-white/70 bg-white/80 px-3 py-2 text-xs text-slate-700">
<div class="font-semibold text-slate-900">Ultima FE acqua estratta</div>
<div class="mt-1">{{ $acquaDiagnostics['latest']['numero_fattura'] ?: ('FE #' . $acquaDiagnostics['latest']['id']) }} · {{ $acquaDiagnostics['latest']['data_fattura'] ?: 'n/d' }}</div>
<div class="mt-1">Utenza {{ $acquaDiagnostics['latest']['utenza'] ?: '—' }} · Cliente {{ $acquaDiagnostics['latest']['cliente'] ?: '—' }}</div>
<div class="mt-1">Contratto {{ $acquaDiagnostics['latest']['contratto'] ?: '—' }} · Matricola {{ $acquaDiagnostics['latest']['matricola'] ?: '—' }}</div>
<div class="mt-1">CBILL {{ $acquaDiagnostics['latest']['cbill'] ?: '—' }} @if(!empty($acquaDiagnostics['latest']['codice_avviso']))· Avviso {{ $acquaDiagnostics['latest']['codice_avviso'] }}@endif @if(!empty($acquaDiagnostics['latest']['sia']))· SIA {{ $acquaDiagnostics['latest']['sia'] }}@endif</div>
</div>
@endif
@if(!empty($acquaDiagnostics['warnings']))
<div class="mt-3 space-y-2 text-xs text-amber-900">
@foreach($acquaDiagnostics['warnings'] as $warning)
<div class="rounded-lg border border-amber-200 bg-white px-3 py-2">{{ $warning }}</div>
@endforeach
</div>
@else
<div class="mt-3 text-xs text-emerald-800">Nessun disallineamento evidente tra contratto acqua e ultimi dati estratti dalle FE.</div>
@endif
</div>
@endif
</div>
</x-filament::section>
<x-filament::section>
<x-slot name="heading">Copertura dati</x-slot>
<div class="space-y-3 text-sm text-slate-600">
<div class="rounded-xl border bg-white px-4 py-3">Per acqua, energia e altri impianti usa i codici collegati per registrare POD, PDR, matricole, codice cliente, numero utenza e riferimenti bolletta.</div>
<div class="rounded-xl border bg-white px-4 py-3">Il SIA resta sul fornitore; qui teniamo i dati specifici del singolo contratto dello stabile.</div>
<div class="rounded-xl border bg-white px-4 py-3">Il documento principale può essere un PDF già registrato nellarchivio documentale con categoria contratto.</div>
</div>
</x-filament::section>
</div>
</div>
</div>
<x-filament-actions::modals />
</x-filament-panels::page>