1173 lines
86 KiB
PHP
Executable File
1173 lines
86 KiB
PHP
Executable File
<x-filament-panels::page>
|
|
<div class="mx-auto max-w-7xl space-y-4">
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
<a
|
|
class="inline-flex items-center gap-2 rounded-lg border px-3 py-2 text-sm font-semibold transition border-transparent bg-gray-50 text-gray-700 hover:border-gray-200"
|
|
href="{{ \App\Filament\Pages\Condomini\NominativiStabile::getUrl(panel: 'admin-filament') }}">
|
|
<x-filament::icon icon="heroicon-o-users" class="h-4 w-4" />
|
|
<span>Nominativi</span>
|
|
</a>
|
|
<a
|
|
class="inline-flex items-center gap-2 rounded-lg border px-3 py-2 text-sm font-semibold transition border-primary-300 bg-primary-50 text-primary-700 shadow-sm"
|
|
href="{{ \App\Filament\Pages\UnitaImmobiliarePage::getUrl(panel: 'admin-filament') }}">
|
|
<x-filament::icon icon="heroicon-o-home-modern" class="h-4 w-4" />
|
|
<span>Unità immobiliari</span>
|
|
</a>
|
|
</div>
|
|
|
|
<x-filament::section class="p-4!">
|
|
@include('filament.components.page-breadcrumbs', [
|
|
'breadcrumbs' => [
|
|
['label' => 'Condomini', 'url' => route('admin.dashboards.condomini')],
|
|
['label' => 'Unità immobiliari', 'url' => \App\Filament\Pages\Condomini\UnitaImmobiliariArchivio::getUrl(panel: 'admin-filament')],
|
|
['label' => 'Scheda unità'],
|
|
],
|
|
'backUrl' => $this->getBackUrl(),
|
|
'backLabel' => 'Torna indietro',
|
|
])
|
|
</x-filament::section>
|
|
|
|
@php
|
|
$unitaOptions = $this->getUnitaOptions();
|
|
$prevUrl = $this->getPrevUnitaUrl();
|
|
$nextUrl = $this->getNextUnitaUrl();
|
|
$visibilityOptions = [
|
|
'attive' => 'Attive',
|
|
'tutte' => 'Tutte',
|
|
'archiviate' => 'Archiviate',
|
|
];
|
|
@endphp
|
|
|
|
<x-filament::section class="p-4!">
|
|
<div class="flex flex-wrap items-end justify-between gap-4">
|
|
<div class="flex items-end gap-2">
|
|
<div class="flex flex-col items-center gap-1">
|
|
<span class="text-[10px] text-gray-500">Prec.</span>
|
|
@if($prevUrl)
|
|
<a class="fi-btn fi-btn-color-gray fi-btn-size-sm" href="{{ $prevUrl }}">←</a>
|
|
@else
|
|
<span class="fi-btn fi-btn-color-gray fi-btn-size-sm opacity-40">←</span>
|
|
@endif
|
|
</div>
|
|
|
|
<div class="min-w-72 max-w-xl flex flex-col items-start gap-1">
|
|
<span class="text-[10px] text-gray-500">Unità</span>
|
|
<div class="w-full">{{ $this->getSchema('unitaPicker') }}</div>
|
|
</div>
|
|
|
|
<div class="flex flex-col items-center gap-1">
|
|
<span class="text-[10px] text-gray-500">Succ.</span>
|
|
@if($nextUrl)
|
|
<a class="fi-btn fi-btn-color-gray fi-btn-size-sm" href="{{ $nextUrl }}">→</a>
|
|
@else
|
|
<span class="fi-btn fi-btn-color-gray fi-btn-size-sm opacity-40">→</span>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex flex-wrap items-center gap-2">
|
|
<span class="text-xs font-medium text-gray-500">Visibilità:</span>
|
|
@foreach($visibilityOptions as $key => $label)
|
|
<button
|
|
type="button"
|
|
wire:click="setUnitaVisibilita('{{ $key }}')"
|
|
class="rounded-lg border px-3 py-2 text-xs font-semibold transition {{ $this->unitaVisibilita === $key ? 'border-primary-300 bg-primary-50 text-primary-700 shadow-sm' : 'border-gray-200 bg-white text-gray-700 hover:border-gray-300 hover:bg-gray-50' }}">
|
|
{{ $label }}
|
|
</button>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
</x-filament::section>
|
|
|
|
@if(!$unita)
|
|
<div class="rounded-xl border border-dashed border-gray-200 bg-white p-6 text-center text-gray-500">Nessuna unità immobiliare trovata.</div>
|
|
@else
|
|
|
|
{{-- Header compatto --}}
|
|
<x-filament::section class="p-4!">
|
|
@php
|
|
$isArchivedUnita = method_exists($unita, 'trashed') && $unita->trashed();
|
|
@endphp
|
|
|
|
<div class="flex items-start justify-between gap-4 flex-wrap">
|
|
<div class="space-y-1">
|
|
<div class="space-y-1">
|
|
<div class="flex flex-wrap items-center gap-3 text-lg font-semibold text-gray-900">
|
|
<x-filament::icon icon="heroicon-o-home-modern" class="h-5 w-5 text-primary-600" />
|
|
<span class="text-primary-700">Unità immobiliare</span>
|
|
@if($isArchivedUnita)
|
|
<span class="rounded-full border border-amber-300 bg-amber-50 px-2 py-0.5 text-xs font-semibold text-amber-700">Archiviata</span>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
@php
|
|
$labelUnita = (string) ($unita->denominazione ?? '');
|
|
if ($labelUnita !== '' && preg_match('/^\s*area\s+condominiale\s*$/i', $labelUnita)) {
|
|
$labelUnita = '';
|
|
}
|
|
$condominoDaCondomin = trim((string) ($this->getLegacyCondominoRiferimentoNome() ?? ''));
|
|
$proprietariAttivi = collect($relazioniPerTipo['proprietari'] ?? []);
|
|
$condominoRiferimento = $proprietariAttivi
|
|
->first(fn (array $relazione): bool => strtolower(trim((string) ($relazione['tipo_raw'] ?? ''))) !== 'comproprietario')
|
|
?? ($relazioniPerTipo['proprietari'][0] ?? null);
|
|
$condominoNome = $condominoDaCondomin !== ''
|
|
? $condominoDaCondomin
|
|
: (string) ($condominoRiferimento['nome'] ?? '');
|
|
$condominoCf = trim((string) ($this->getLegacyCondominoRiferimentoCodiceFiscale() ?? ''));
|
|
if ($condominoCf === '') {
|
|
$condominoCf = (string) ($condominoRiferimento['codice_fiscale'] ?? '');
|
|
}
|
|
$inquilinoNome = (string) ($relazioniPerTipo['inquilini'][0]['nome'] ?? '');
|
|
$comproprietariCount = $proprietariAttivi
|
|
->filter(fn (array $relazione): bool => strtolower(trim((string) ($relazione['tipo_raw'] ?? ''))) === 'comproprietario')
|
|
->count();
|
|
$labelStoricoScaduto = $labelUnita !== ''
|
|
&& collect($nominativiStorici ?? [])->contains(function (array $nominativo) use ($labelUnita, $condominoNome, $inquilinoNome): bool {
|
|
$nome = trim((string) ($nominativo['nominativo'] ?? ''));
|
|
|
|
return $nome !== ''
|
|
&& trim($labelUnita) === $nome
|
|
&& trim($labelUnita) !== trim($condominoNome)
|
|
&& trim($labelUnita) !== trim($inquilinoNome);
|
|
});
|
|
if ($labelUnita === '' || $labelStoricoScaduto) {
|
|
$labelUnita = (string) ($unita->codice_unita ?? $unita->codice_completo ?? 'Unità');
|
|
}
|
|
@endphp
|
|
@if($labelUnita !== '' && $condominoNome !== '' && trim($labelUnita) !== trim($condominoNome))
|
|
<div class="text-sm text-gray-700">{{ $labelUnita }}</div>
|
|
@endif
|
|
<div class="text-sm text-gray-700">Condomino di riferimento: {{ $condominoNome !== '' ? $condominoNome : '—' }}</div>
|
|
@if($comproprietariCount > 0)
|
|
<div class="text-xs text-gray-500">Comproprietari collegati: {{ $comproprietariCount }}</div>
|
|
@endif
|
|
<div class="text-sm text-gray-700">Inquilino: {{ $inquilinoNome !== '' ? $inquilinoNome : '—' }}</div>
|
|
<div class="text-xs text-gray-500">{{ trim(($unita->indirizzo ?? '').' '.($unita->civico ?? '').' '.($unita->comune ?? '')) }}</div>
|
|
</div>
|
|
|
|
@php
|
|
$rateCondominiHeader = $rateEmessePerCategoria['condomini'] ?? [];
|
|
$rateInquiliniHeader = $rateEmessePerCategoria['inquilini'] ?? [];
|
|
$sumHeader = function (array $items, string $field): float {
|
|
$s = 0.0;
|
|
foreach ($items as $it) {
|
|
$s += (float) ($it[$field] ?? 0);
|
|
}
|
|
return $s;
|
|
};
|
|
$totCAddebH = $sumHeader($rateCondominiHeader, 'totale_addebitato');
|
|
$totCPagH = $sumHeader($rateCondominiHeader, 'totale_pagato');
|
|
$totCResH = $sumHeader($rateCondominiHeader, 'residuo');
|
|
$totIAddebH = $sumHeader($rateInquiliniHeader, 'totale_addebitato');
|
|
$totIPagH = $sumHeader($rateInquiliniHeader, 'totale_pagato');
|
|
$totIResH = $sumHeader($rateInquiliniHeader, 'residuo');
|
|
$hasInquilino = !empty($relazioniPerTipo['inquilini'][0]['nome'] ?? null);
|
|
if (empty($rateCondominiHeader) && empty($rateInquiliniHeader) && !$hasInquilino) {
|
|
$totCAddebH = (float) collect($estrattoCompattoRateRows ?? [])->sum(fn (array $row): float => (float) ($row['dovuto'] ?? 0));
|
|
$totCPagH = (float) collect($estrattoCompattoIncassi ?? [])->sum(fn (array $row): float => (float) ($row['importo'] ?? 0));
|
|
$totCResH = round($totCAddebH - $totCPagH, 2);
|
|
}
|
|
@endphp
|
|
|
|
<div class="grid gap-2 sm:grid-cols-3 min-w-70">
|
|
<div class="rounded-lg border p-3 {{ ($estrattoTipo ?? 'condomini') === 'condomini' ? 'border-primary-300 bg-primary-50' : 'bg-gray-50' }}">
|
|
<div class="text-xs text-gray-500">Condomino di riferimento</div>
|
|
<div class="text-sm font-semibold text-gray-900">{{ $condominoNome !== '' ? $condominoNome : '—' }}</div>
|
|
<div class="text-xs text-gray-500">CF: {{ $condominoCf !== '' ? $condominoCf : '—' }}</div>
|
|
</div>
|
|
<div class="rounded-lg border p-3 {{ ($estrattoTipo ?? 'condomini') === 'inquilini' ? 'border-emerald-300 bg-emerald-50' : 'bg-gray-50' }} {{ $hasInquilino ? '' : 'opacity-60' }}">
|
|
<div class="text-xs text-gray-500">Inquilino</div>
|
|
<div class="text-sm font-semibold text-gray-900">{{ $inquilinoNome !== '' ? $inquilinoNome : '—' }}</div>
|
|
<div class="text-xs text-gray-500">CF: {{ $relazioniPerTipo['inquilini'][0]['codice_fiscale'] ?? '—' }}</div>
|
|
</div>
|
|
<div class="rounded-lg border bg-gray-50 p-3 space-y-2">
|
|
<div class="text-xs text-gray-500">Estratto rapido</div>
|
|
<button type="button"
|
|
wire:click="setEstrattoTipo('condomini')"
|
|
class="w-full rounded-md border px-2 py-1 text-left text-xs font-semibold transition {{ ($estrattoTipo ?? 'condomini') === 'condomini' ? 'border-primary-300 bg-primary-50 text-primary-700' : 'border-gray-200 bg-white text-gray-700 hover:bg-gray-50' }}">
|
|
<div>Condomino</div>
|
|
<div class="text-[11px] text-gray-600">Addebito {{ number_format($totCAddebH, 2, ',', '.') }} € · Incasso {{ number_format($totCPagH, 2, ',', '.') }} € · Residuo {{ number_format($totCResH, 2, ',', '.') }} €</div>
|
|
</button>
|
|
|
|
<button type="button"
|
|
wire:click="setEstrattoTipo('inquilini')"
|
|
class="w-full rounded-md border px-2 py-1 text-left text-xs font-semibold transition {{ ($estrattoTipo ?? 'condomini') === 'inquilini' ? 'border-emerald-300 bg-emerald-50 text-emerald-700' : 'border-gray-200 bg-white text-gray-700 hover:bg-gray-50' }} {{ $hasInquilino ? '' : 'opacity-50' }}"
|
|
@if(!$hasInquilino) disabled @endif>
|
|
<div>Inquilino</div>
|
|
<div class="text-[11px] text-gray-600">Addebito {{ number_format($totIAddebH, 2, ',', '.') }} € · Incasso {{ number_format($totIPagH, 2, ',', '.') }} € · Residuo {{ number_format($totIResH, 2, ',', '.') }} €</div>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</x-filament::section>
|
|
|
|
{{-- Tabs + contenuto --}}
|
|
<x-filament::section class="p-0! overflow-hidden">
|
|
<div class="flex flex-wrap items-center gap-2 px-4 py-2 bg-white border-b">
|
|
@php
|
|
$tabs = [
|
|
'riepilogo' => ['icon' => 'heroicon-o-rectangle-group', 'label' => 'Riepilogo'],
|
|
'millesimi' => ['icon' => 'heroicon-o-chart-pie', 'label' => 'Tabelle millesimali'],
|
|
'persone' => ['icon' => 'heroicon-o-user-group', 'label' => 'Persone collegate'],
|
|
'acqua' => ['icon' => 'heroicon-o-beaker', 'label' => 'Acqua'],
|
|
'estratto' => ['icon' => 'heroicon-o-document-text', 'label' => 'Estratto conto'],
|
|
'economico' => ['icon' => 'heroicon-o-banknotes', 'label' => 'Economico'],
|
|
];
|
|
@endphp
|
|
@foreach($tabs as $key => $cfg)
|
|
<button
|
|
type="button"
|
|
wire:click="setTab('{{ $key }}')"
|
|
class="inline-flex items-center gap-2 rounded-lg border px-3 py-2 text-sm font-semibold transition
|
|
{{ $tab === $key ? 'border-primary-300 bg-primary-50 text-primary-700 shadow-sm' : 'border-transparent bg-gray-50 text-gray-700 hover:border-gray-200' }}">
|
|
<x-filament::icon :icon="$cfg['icon']" class="h-4 w-4" />
|
|
<span>{{ $cfg['label'] }}</span>
|
|
</button>
|
|
@endforeach
|
|
</div>
|
|
|
|
<div class="p-4 space-y-4">
|
|
@if($tab === 'riepilogo')
|
|
<div class="grid gap-4 lg:grid-cols-3">
|
|
<x-filament::section class="lg:col-span-2">
|
|
<x-slot name="heading">Indicatori principali</x-slot>
|
|
<x-slot name="description">Superficie, millesimi, percentuale, valore</x-slot>
|
|
<div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
|
@foreach([
|
|
['Superficie', ($unita->superficie_commerciale ?? 0) . ' m²'],
|
|
['Millesimi', $unita->millesimi_proprieta ?? $unita->millesimi_generali ?? 0],
|
|
['Percentuale', ($unita->millesimi_proprieta ?? $unita->millesimi_generali) ? number_format((($unita->millesimi_proprieta ?? $unita->millesimi_generali)/1000)*100,2) . '%' : '0%'],
|
|
['Valore stimato', ($unita->valore_commerciale_stimato ?? 0) . ' €'],
|
|
] as [$label, $value])
|
|
<x-filament::section class="p-4!">
|
|
<div class="text-xs text-gray-500">{{ $label }}</div>
|
|
<div class="text-lg font-semibold text-gray-900">{{ $value }}</div>
|
|
</x-filament::section>
|
|
@endforeach
|
|
</div>
|
|
</x-filament::section>
|
|
|
|
<x-filament::section>
|
|
<x-slot name="heading">Identificazione</x-slot>
|
|
<x-slot name="description">Tipologia e stato</x-slot>
|
|
<div class="space-y-2">
|
|
@foreach([
|
|
['Tipologia', $unita->tipo_unita ?? 'ND'],
|
|
['Stato occupazione', $unita->stato_occupazione ?? 'ND'],
|
|
['Utilizzo', $unita->utilizzo_attuale ?? 'ND'],
|
|
['Codice stabile', $unita->stabile?->codice_operatore ?? $unita->stabile?->codice_stabile ?? 'ND'],
|
|
] as [$label, $value])
|
|
<x-filament::section class="p-3! bg-gray-50">
|
|
<div class="text-xs text-gray-500">{{ $label }}</div>
|
|
<div class="text-sm font-semibold text-gray-900">{{ $value }}</div>
|
|
</x-filament::section>
|
|
@endforeach
|
|
</div>
|
|
</x-filament::section>
|
|
</div>
|
|
|
|
<x-filament::section>
|
|
<x-slot name="heading">Dati catastali</x-slot>
|
|
<x-slot name="description">Identificativi e classamento</x-slot>
|
|
<div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
|
@foreach([
|
|
['Sezione urbana', $unita->sezione_urbana ?? 'ND'],
|
|
['Foglio', $unita->foglio ?? 'ND'],
|
|
['Particella', $unita->particella ?? 'ND'],
|
|
['Subalterno', $unita->subalterno ?? 'ND'],
|
|
['Categoria', $unita->categoria_catastale ?? 'ND'],
|
|
['Classe', $unita->classe ?? 'ND'],
|
|
['Consistenza', $unita->consistenza ?? 'ND'],
|
|
['Rendita', $unita->rendita_catastale ?? 'ND'],
|
|
] as [$label, $value])
|
|
<div class="rounded-lg border bg-gray-50 p-3">
|
|
<div class="text-xs text-gray-500">{{ $label }}</div>
|
|
<div class="text-sm font-semibold text-gray-900">{{ $value }}</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</x-filament::section>
|
|
|
|
<x-filament::section>
|
|
<x-slot name="heading">Persone collegate</x-slot>
|
|
<x-slot name="description">Proprietari, inquilini, altri</x-slot>
|
|
<div class="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
|
|
@foreach([
|
|
'proprietari' => ['label' => 'Proprietari', 'color' => 'text-primary-700'],
|
|
'inquilini' => ['label' => 'Inquilini', 'color' => 'text-emerald-700'],
|
|
'altri' => ['label' => 'Altri soggetti', 'color' => 'text-gray-700'],
|
|
] as $key => $cfg)
|
|
@php $relazioni = $relazioniPerTipo[$key] ?? []; @endphp
|
|
<x-filament::section class="bg-gray-50">
|
|
<div class="mb-2 text-sm font-semibold {{ $cfg['color'] }}">{{ $cfg['label'] }} ({{ count($relazioni) }})</div>
|
|
@if(empty($relazioni))
|
|
<div class="text-sm text-gray-500">Nessun soggetto.</div>
|
|
@else
|
|
<div class="space-y-2">
|
|
@foreach($relazioni as $relazione)
|
|
@php
|
|
$tipoRawRelazione = strtolower(trim((string) ($relazione['tipo_raw'] ?? '')));
|
|
$roleBadge = null;
|
|
if ($key === 'proprietari') {
|
|
$roleBadge = $tipoRawRelazione === 'comproprietario'
|
|
? 'Comproprietario'
|
|
: 'Condomino di riferimento';
|
|
}
|
|
@endphp
|
|
<x-filament::section class="p-3!">
|
|
<div class="flex items-start justify-between gap-2">
|
|
<div class="text-sm font-semibold text-gray-900">{{ $relazione['nome'] }}</div>
|
|
@if($roleBadge)
|
|
<span class="rounded-full border border-gray-200 bg-white px-2 py-0.5 text-[11px] font-semibold text-gray-600">{{ $roleBadge }}</span>
|
|
@endif
|
|
</div>
|
|
<div class="text-xs text-gray-500">CF: {{ $relazione['codice_fiscale'] ?? '—' }}</div>
|
|
<div class="text-xs text-gray-500">Quota: {{ $relazione['quota_label'] ?? '—' }}%</div>
|
|
@php
|
|
$dal = $relazione['data_inizio'] ?? null;
|
|
$al = $relazione['data_fine'] ?? null;
|
|
@endphp
|
|
<div class="text-xs text-gray-500">
|
|
Periodo:
|
|
@if($dal || $al)
|
|
@if($dal) Da {{ $dal }} @endif
|
|
@if($al) · fino a {{ $al }} @endif
|
|
@else
|
|
Da sempre
|
|
@endif
|
|
</div>
|
|
@if(!empty($relazione['ruolo_rate']))
|
|
<div class="text-xs text-gray-500">Ruolo rate: ({{ $relazione['ruolo_rate'] }})</div>
|
|
@endif
|
|
</x-filament::section>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
</x-filament::section>
|
|
@endforeach
|
|
</div>
|
|
|
|
<div class="mt-6">
|
|
<div class="text-sm font-semibold text-gray-900 mb-2">Recapiti email per servizio</div>
|
|
@if(empty($recapitiServizio))
|
|
<div class="text-sm text-gray-500">Nessun recapito email disponibile.</div>
|
|
@else
|
|
<div class="grid gap-3 lg:grid-cols-2">
|
|
@foreach($recapitiServizio as $service)
|
|
<div class="rounded-xl border bg-gray-50 p-3">
|
|
<div class="text-sm font-semibold text-gray-900">{{ $service['label'] ?? 'Servizio' }}</div>
|
|
@if(empty($service['rows']))
|
|
<div class="mt-2 text-sm text-gray-500">Nessun recapito risolto.</div>
|
|
@else
|
|
<div class="mt-2 space-y-2">
|
|
@foreach($service['rows'] as $recipient)
|
|
<div class="rounded-lg border bg-white p-3">
|
|
<div class="text-sm font-semibold text-gray-900">{{ $recipient['email'] ?? '—' }}</div>
|
|
<div class="text-xs text-gray-500">{{ $recipient['persona'] ?: 'Recapito unità' }} · {{ $recipient['sourceLabel'] ?? 'Anagrafica persona' }}</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<div class="mt-6">
|
|
<div class="text-sm font-semibold text-gray-900 mb-2">Nominativi storici (legacy)</div>
|
|
@if(empty($nominativiStorici))
|
|
<div class="text-sm text-gray-500">Nessun nominativo storico disponibile.</div>
|
|
@else
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full text-sm">
|
|
<thead>
|
|
<tr class="border-b text-left text-gray-500">
|
|
<th class="py-2 pr-4">Ruolo</th>
|
|
<th class="py-2 pr-4">Nominativo</th>
|
|
<th class="py-2 pr-4">Periodo</th>
|
|
<th class="py-2 pr-4 text-right">Quota</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y">
|
|
@foreach($nominativiStorici as $nominativo)
|
|
<tr>
|
|
<td class="py-2 pr-4 text-gray-700">{{ $nominativo['ruolo'] ?? '—' }}</td>
|
|
<td class="py-2 pr-4">
|
|
<div class="text-sm font-semibold text-gray-900">{{ $nominativo['nominativo'] ?? '—' }}</div>
|
|
@if(!empty($nominativo['fonte']))
|
|
<div class="text-xs text-gray-500">Fonte: {{ $nominativo['fonte'] }}</div>
|
|
@endif
|
|
@if(!empty($nominativo['detail']))
|
|
<div class="text-xs text-gray-500">{{ $nominativo['detail'] }}</div>
|
|
@endif
|
|
</td>
|
|
<td class="py-2 pr-4 text-gray-700">{{ $nominativo['periodo'] ?? '—' }}</td>
|
|
<td class="py-2 pr-4 text-right text-gray-900">{{ $nominativo['percentuale'] ?? '—' }}</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</x-filament::section>
|
|
@endif
|
|
|
|
@if($tab === 'millesimi')
|
|
<x-filament::section>
|
|
<div class="flex items-center gap-2 text-sm font-semibold text-gray-900 mb-3">
|
|
<x-filament::icon icon="heroicon-o-chart-pie" class="h-5 w-5 text-primary-600" />
|
|
<span>Tabelle millesimali assegnate</span>
|
|
</div>
|
|
|
|
<div class="mb-4 flex flex-wrap gap-2">
|
|
@php
|
|
$gruppi = [
|
|
'ordinarie' => 'ORDINARIE',
|
|
'riscaldamento' => 'RISCALDAMENTO',
|
|
'straordinarie' => 'STRAORDINARIE',
|
|
];
|
|
@endphp
|
|
@foreach($gruppi as $key => $label)
|
|
<button
|
|
type="button"
|
|
wire:click="setMillesimiGruppo('{{ $key }}')"
|
|
class="inline-flex items-center rounded-lg border px-4 py-2 text-sm font-semibold transition
|
|
{{ ($millesimiGruppo ?? 'ordinarie') === $key ? 'border-primary-300 bg-primary-50 text-primary-700 shadow-sm' : 'border-gray-200 bg-white text-gray-700 hover:bg-gray-50' }}"
|
|
>
|
|
{{ $label }}
|
|
</button>
|
|
@endforeach
|
|
</div>
|
|
|
|
@if(empty($millesimiPerTabella))
|
|
<div class="text-sm text-gray-500">Nessuna tabella millesimale associata.</div>
|
|
@else
|
|
@php
|
|
$selectedGruppo = $millesimiGruppo ?? 'ordinarie';
|
|
$filteredMillesimi = array_values(array_filter($millesimiPerTabella, fn ($r) => ($r['gruppo'] ?? 'ordinarie') === $selectedGruppo));
|
|
@endphp
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full text-sm">
|
|
<thead>
|
|
<tr class="border-b text-left text-gray-500">
|
|
<th class="py-2 pr-4">Tabella</th>
|
|
<th class="py-2 pr-4">Denominazione</th>
|
|
<th class="py-2 pr-4 text-right">Millesimi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y">
|
|
@forelse($filteredMillesimi as $r)
|
|
@php
|
|
$tipo = $r['tipo'] ?? 'altro';
|
|
$tipoLabel = $tipo;
|
|
$tipoLabel = str_replace('_', ' ', (string) $tipoLabel);
|
|
$tipoLabel = ucwords($tipoLabel);
|
|
|
|
$prevTipo = $loop->first ? null : ($filteredMillesimi[$loop->index - 1]['tipo'] ?? 'altro');
|
|
@endphp
|
|
|
|
@if($loop->first || $tipo !== $prevTipo)
|
|
<tr class="bg-gray-50">
|
|
<td class="py-2 pr-4 font-semibold" colspan="3">{{ $tipoLabel }}</td>
|
|
</tr>
|
|
@endif
|
|
|
|
<tr>
|
|
<td class="py-2 pr-4 font-medium">{{ $r['codice'] }}</td>
|
|
<td class="py-2 pr-4">{{ $r['nome'] }}</td>
|
|
<td class="py-2 pr-4 text-right">{{ number_format($r['millesimi'], 4, ',', '.') }}</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td class="py-4 text-center text-gray-500" colspan="3">Nessun millesimo presente</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@endif
|
|
</x-filament::section>
|
|
@endif
|
|
|
|
@if($tab === 'persone')
|
|
<x-filament::section>
|
|
<div class="flex items-center gap-2 text-sm font-semibold text-gray-900 mb-3">
|
|
<x-filament::icon icon="heroicon-o-user-group" class="h-5 w-5 text-primary-600" />
|
|
<span>Persone collegate</span>
|
|
</div>
|
|
@php
|
|
$blocchiRelazioni = [
|
|
'proprietari' => ['label' => 'Proprietari / comproprietari', 'class' => 'text-primary-700'],
|
|
'inquilini' => ['label' => 'Inquilini / conduttori', 'class' => 'text-emerald-700'],
|
|
'altri' => ['label' => 'Altri soggetti collegati', 'class' => 'text-gray-700'],
|
|
];
|
|
@endphp
|
|
<div class="space-y-3">
|
|
@foreach($blocchiRelazioni as $key => $cfg)
|
|
@php $relazioni = $relazioniPerTipo[$key] ?? []; @endphp
|
|
<div class="rounded-2xl border bg-gray-50 p-3">
|
|
<div class="mb-2 text-sm font-semibold {{ $cfg['class'] }}">{{ $cfg['label'] }} ({{ count($relazioni) }})</div>
|
|
@if(empty($relazioni))
|
|
<div class="text-sm text-gray-500">Nessun soggetto collegato.</div>
|
|
@else
|
|
<div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
|
@foreach($relazioni as $relazione)
|
|
<div class="rounded-xl border bg-white p-3 shadow-sm">
|
|
<div class="text-xs text-gray-500">{{ $relazione['tipo'] ?? 'Relazione' }}</div>
|
|
<div class="text-sm font-semibold text-gray-900">{{ $relazione['nome'] }}</div>
|
|
<div class="text-xs text-gray-500 mt-1">CF: {{ $relazione['codice_fiscale'] ?? '—' }}</div>
|
|
<div class="text-xs text-gray-500 mt-1">Quota: {{ $relazione['quota_label'] ?? '—' }}%</div>
|
|
@if(!empty($relazione['telefono']))
|
|
<div class="text-xs text-gray-500 mt-1">Telefono: {{ $relazione['telefono'] }}</div>
|
|
@endif
|
|
@if(!empty($relazione['email']))
|
|
<div class="text-xs text-gray-500 mt-1">Email: {{ $relazione['email'] }}</div>
|
|
@endif
|
|
@if(!empty($relazione['data_inizio']) || !empty($relazione['data_fine']))
|
|
<div class="text-xs text-gray-500 mt-1">
|
|
Periodo:
|
|
@if(!empty($relazione['data_inizio'])) Da {{ $relazione['data_inizio'] }} @endif
|
|
@if(!empty($relazione['data_fine'])) · fino a {{ $relazione['data_fine'] }} @endif
|
|
</div>
|
|
@endif
|
|
@if(!empty($relazione['rubrica_url']))
|
|
<div class="mt-2">
|
|
<a href="{{ $relazione['rubrica_url'] }}" class="inline-flex items-center rounded-md border border-indigo-200 bg-indigo-50 px-2 py-1 text-[11px] font-medium text-indigo-700 hover:bg-indigo-100">Apri scheda rubrica</a>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
|
|
<div class="mt-6">
|
|
<div class="mb-2 text-sm font-semibold text-gray-900">Recapiti email per servizio</div>
|
|
@if(empty($recapitiServizio))
|
|
<div class="text-sm text-gray-500">Nessun recapito email disponibile.</div>
|
|
@else
|
|
<div class="grid gap-3 lg:grid-cols-2">
|
|
@foreach($recapitiServizio as $service)
|
|
<div class="rounded-2xl border bg-gray-50 p-3">
|
|
<div class="text-sm font-semibold text-gray-900">{{ $service['label'] ?? 'Servizio' }}</div>
|
|
@if(empty($service['rows']))
|
|
<div class="mt-2 text-sm text-gray-500">Nessun recapito risolto.</div>
|
|
@else
|
|
<div class="mt-2 space-y-2">
|
|
@foreach($service['rows'] as $recipient)
|
|
<div class="rounded-xl border bg-white p-3 shadow-sm">
|
|
<div class="text-sm font-semibold text-gray-900">{{ $recipient['email'] ?? '—' }}</div>
|
|
<div class="text-xs text-gray-500 mt-1">{{ $recipient['persona'] ?: 'Recapito unità' }}</div>
|
|
<div class="text-xs text-gray-500 mt-1">Origine: {{ $recipient['sourceLabel'] ?? 'Anagrafica persona' }}</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</x-filament::section>
|
|
@endif
|
|
|
|
@if($tab === 'acqua')
|
|
<div class="space-y-4">
|
|
<x-filament::section>
|
|
<x-slot name="heading">Storico letture acqua unità</x-slot>
|
|
<x-slot name="description">Andamento letture, consumi e richieste legate a questa utenza immobiliare.</x-slot>
|
|
|
|
<div class="grid gap-3 md:grid-cols-4">
|
|
<div class="rounded-lg border bg-gray-50 p-3">
|
|
<div class="text-xs text-gray-500">Letture registrate</div>
|
|
<div class="mt-2 text-xl font-semibold text-gray-900">{{ number_format((int) ($acquaStats['totale_letture'] ?? 0), 0, ',', '.') }}</div>
|
|
</div>
|
|
<div class="rounded-lg border bg-gray-50 p-3">
|
|
<div class="text-xs text-gray-500">Consumi storici</div>
|
|
<div class="mt-2 text-xl font-semibold text-gray-900">{{ number_format((float) ($acquaStats['totale_consumi_mc'] ?? 0), 3, ',', '.') }} mc</div>
|
|
</div>
|
|
<div class="rounded-lg border bg-gray-50 p-3">
|
|
<div class="text-xs text-gray-500">Ultima lettura</div>
|
|
<div class="mt-2 text-xl font-semibold text-gray-900">{{ isset($acquaStats['ultima_lettura']) && $acquaStats['ultima_lettura'] !== null ? number_format((float) $acquaStats['ultima_lettura'], 3, ',', '.') : '—' }}</div>
|
|
<div class="mt-1 text-[11px] text-gray-500">{{ $acquaStats['ultima_data'] ?? 'nessuna data' }}</div>
|
|
</div>
|
|
<div class="rounded-lg border bg-gray-50 p-3">
|
|
<div class="text-xs text-gray-500">Richieste aperte</div>
|
|
<div class="mt-2 text-xl font-semibold text-gray-900">{{ number_format((int) ($acquaStats['richieste_aperte'] ?? 0), 0, ',', '.') }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mt-4 grid gap-4 lg:grid-cols-[1.2fr_0.8fr]">
|
|
<div class="rounded-xl border bg-cyan-50 p-4">
|
|
<div class="text-sm font-semibold text-cyan-900">Utenza acqua collegata</div>
|
|
<div class="mt-2 grid gap-2 text-xs text-cyan-900 md:grid-cols-2">
|
|
<div>Servizio: <span class="font-semibold">{{ $acquaStats['servizio_label'] ?? 'non configurato' }}</span></div>
|
|
<div>Matricola: <span class="font-semibold">{{ $acquaStats['matricola'] ?? '—' }}</span></div>
|
|
<div>Seriale unità: <span class="font-semibold">{{ $unita->acqua_contatore_seriale ?? '—' }}</span></div>
|
|
<div>Gateway ID: <span class="font-semibold">{{ $unita->acqua_gateway_device_id ?? '—' }}</span></div>
|
|
<div>Codice utenza: <span class="font-semibold">{{ $acquaStats['utenza'] ?? '—' }}</span></div>
|
|
<div>Contratto: <span class="font-semibold">{{ $acquaStats['contratto'] ?? '—' }}</span></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="rounded-xl border bg-white p-4">
|
|
<div class="text-sm font-semibold text-gray-900">Azioni rapide</div>
|
|
<div class="mt-3 flex flex-wrap gap-2">
|
|
@if(!empty($acquaQuickLinks['ticket_light']))
|
|
<a href="{{ $acquaQuickLinks['ticket_light'] }}" class="inline-flex items-center rounded-md border border-cyan-300 bg-cyan-50 px-3 py-1.5 text-xs font-medium text-cyan-800 hover:bg-cyan-100">Nuova lettura unità</a>
|
|
@endif
|
|
@if(!empty($acquaQuickLinks['archivio']))
|
|
<a href="{{ $acquaQuickLinks['archivio'] }}" class="inline-flex items-center rounded-md border border-gray-300 bg-gray-50 px-3 py-1.5 text-xs font-medium text-gray-700 hover:bg-gray-100">Archivio letture</a>
|
|
@endif
|
|
@if(!empty($acquaQuickLinks['hub_stabile']))
|
|
<a href="{{ $acquaQuickLinks['hub_stabile'] }}" class="inline-flex items-center rounded-md border border-gray-300 bg-gray-50 px-3 py-1.5 text-xs font-medium text-gray-700 hover:bg-gray-100">Campagna stabile</a>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</x-filament::section>
|
|
|
|
<x-filament::section>
|
|
<x-slot name="heading">Dettaglio letture e consumi nel tempo</x-slot>
|
|
<x-slot name="description">Storico operativo della singola unità con canale di arrivo, riferimento e protocollo.</x-slot>
|
|
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full text-sm">
|
|
<thead>
|
|
<tr class="border-b text-gray-500">
|
|
<th class="px-2 py-2 text-left">Data</th>
|
|
<th class="px-2 py-2 text-left">Periodo</th>
|
|
<th class="px-2 py-2 text-right">Lett. iniziale</th>
|
|
<th class="px-2 py-2 text-right">Lett. finale</th>
|
|
<th class="px-2 py-2 text-right">Consumo</th>
|
|
<th class="px-2 py-2 text-left">Canale / stato</th>
|
|
<th class="px-2 py-2 text-left">Riferimento</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@forelse($acquaLettureStorico as $row)
|
|
<tr class="border-b border-gray-100">
|
|
<td class="px-2 py-2">{{ $row['data'] ?: '—' }}</td>
|
|
<td class="px-2 py-2">{{ $row['periodo'] ?: '—' }}</td>
|
|
<td class="px-2 py-2 text-right">{{ isset($row['lettura_inizio']) && $row['lettura_inizio'] !== null ? number_format((float) $row['lettura_inizio'], 3, ',', '.') : '—' }}</td>
|
|
<td class="px-2 py-2 text-right">{{ isset($row['lettura_fine']) && $row['lettura_fine'] !== null ? number_format((float) $row['lettura_fine'], 3, ',', '.') : '—' }}</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>{{ $row['canale'] ?: '—' }}</div>
|
|
<div class="text-[11px] text-gray-500">{{ $row['workflow'] ?: '—' }} @if(!empty($row['protocollo'])) · {{ $row['protocollo'] }} @endif</div>
|
|
</td>
|
|
<td class="px-2 py-2">
|
|
<div>{{ $row['riferimento'] ?: '—' }}</div>
|
|
@if(!empty($row['fattura_label']))
|
|
<div class="text-[11px] text-cyan-700">{{ $row['fattura_label'] }}</div>
|
|
@endif
|
|
</td>
|
|
</tr>
|
|
@empty
|
|
<tr>
|
|
<td colspan="7" class="px-2 py-6 text-center text-gray-500">Nessuna lettura acqua registrata per questa unità.</td>
|
|
</tr>
|
|
@endforelse
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</x-filament::section>
|
|
</div>
|
|
@endif
|
|
|
|
@if($tab === 'economico')
|
|
<div class="grid gap-4">
|
|
{{-- Contenuti economici: preventivi/riparti (rate emesse spostate nel tab Estratto conto) --}}
|
|
|
|
@if(!empty($preventiviPerTabella))
|
|
<x-filament::section>
|
|
<div class="flex flex-wrap items-center justify-between gap-3 mb-3">
|
|
<div>
|
|
<div class="text-sm font-semibold text-gray-900">Preventivo per tabella</div>
|
|
<div class="text-xs text-gray-500">Quote unità e riparto proprietario/inquilino (dett_tab cond_inquil).</div>
|
|
</div>
|
|
@if(!empty($totaliPerGestione))
|
|
<div class="flex flex-wrap gap-2 text-sm text-gray-700">
|
|
<span class="rounded border px-3 py-1 bg-gray-50">O: {{ number_format($totaliPerGestione['O'] ?? 0, 2, ',', '.') }} €</span>
|
|
<span class="rounded border px-3 py-1 bg-gray-50">R: {{ number_format($totaliPerGestione['R'] ?? 0, 2, ',', '.') }} €</span>
|
|
<span class="rounded border px-3 py-1 bg-gray-50">S: {{ number_format($totaliPerGestione['S'] ?? 0, 2, ',', '.') }} €</span>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<div class="space-y-4">
|
|
@foreach($preventiviPerTabella as $tabella)
|
|
<div class="rounded-2xl border bg-gray-50 p-4">
|
|
<div class="flex items-center justify-between mb-2">
|
|
<div>
|
|
<div class="text-xs text-gray-600">{{ $tabella['tabella_codice'] }} · tipo {{ $tabella['tipo'] }}</div>
|
|
<div class="text-sm font-semibold text-gray-900">{{ $tabella['tabella_nome'] }}</div>
|
|
</div>
|
|
<div class="text-right">
|
|
<div class="text-xs text-gray-500">Totale tabella</div>
|
|
<div class="text-lg font-semibold text-gray-900">{{ number_format($tabella['total_preventivo'], 2, ',', '.') }} €</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full text-sm">
|
|
<thead>
|
|
<tr class="text-gray-500">
|
|
<th class="text-left py-1">Voce</th>
|
|
<th class="text-right py-1">Preventivo</th>
|
|
<th class="text-right py-1">Quota unità</th>
|
|
<th class="text-right py-1">Prop.</th>
|
|
<th class="text-right py-1">Inquilino</th>
|
|
<th class="text-right py-1">% Inq.</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y">
|
|
@foreach($tabella['voci'] as $voce)
|
|
<tr>
|
|
<td class="py-1 text-gray-800">{{ $voce['codice'] }} · {{ $voce['descrizione'] }}</td>
|
|
<td class="py-1 text-right text-gray-900">{{ number_format($voce['importo_preventivato'] ?? 0, 2, ',', '.') }} €</td>
|
|
<td class="py-1 text-right text-gray-900">{{ number_format($voce['quota_unita'] ?? 0, 2, ',', '.') }} €</td>
|
|
<td class="py-1 text-right text-gray-900">{{ number_format($voce['importo_proprietario'] ?? 0, 2, ',', '.') }} €</td>
|
|
<td class="py-1 text-right text-gray-900">{{ number_format($voce['importo_inquilino'] ?? 0, 2, ',', '.') }} €</td>
|
|
<td class="py-1 text-right text-gray-700">{{ number_format($voce['percentuale_inquilino'] ?? 0, 2, ',', '.') }} %</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div class="mt-3 grid grid-cols-1 md:grid-cols-3 gap-3 text-sm">
|
|
<div class="rounded border bg-white p-3">
|
|
<div class="text-gray-500">Millesimi unità / tabella</div>
|
|
<div class="font-semibold text-gray-900">{{ number_format($tabella['unit_millesimi'], 3, ',', '.') }} / {{ number_format($tabella['tabella_millesimi'], 3, ',', '.') }}</div>
|
|
</div>
|
|
<div class="rounded border bg-white p-3">
|
|
<div class="text-gray-500">Quota unità</div>
|
|
<div class="font-semibold text-gray-900">{{ number_format($tabella['quota_unit'], 2, ',', '.') }} €</div>
|
|
</div>
|
|
<div class="rounded border bg-white p-3">
|
|
<div class="text-gray-500">Riparto proprietario / inquilino</div>
|
|
<div class="font-semibold text-gray-900">{{ number_format($tabella['importo_proprietario'], 2, ',', '.') }} € / {{ number_format($tabella['importo_inquilino'], 2, ',', '.') }} €</div>
|
|
<div class="text-xs text-gray-500">% inquilino: {{ number_format($tabella['percentuale_inquilino'] ?? 0, 2, ',', '.') }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</x-filament::section>
|
|
@endif
|
|
|
|
<x-filament::section>
|
|
<div class="flex items-center gap-2 text-sm font-semibold text-gray-900 mb-3">
|
|
<x-filament::icon icon="heroicon-o-banknotes" class="h-5 w-5 text-emerald-600" />
|
|
<span>Voci di spesa per tabella (prop. / inq.)</span>
|
|
</div>
|
|
@if(empty($ripartizioniPerTabella))
|
|
<div class="text-sm text-gray-500">Nessuna ripartizione registrata per questa unità.</div>
|
|
@else
|
|
<div class="space-y-3">
|
|
@foreach($ripartizioniPerTabella as $tabella)
|
|
<div class="rounded-2xl border bg-gray-50 overflow-hidden">
|
|
<div class="flex items-center gap-2 bg-white px-3 py-2 border-b">
|
|
<span class="inline-flex items-center rounded-full border border-primary-200 bg-primary-50 px-2 py-0.5 text-xs font-semibold text-primary-700">{{ $tabella['tabella_codice'] }}</span>
|
|
<span class="text-sm font-semibold text-gray-900">{{ $tabella['tabella_nome'] }}</span>
|
|
</div>
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full text-sm">
|
|
<thead>
|
|
<tr class="text-gray-500 border-b">
|
|
<th class="text-left py-2 px-2">Voce</th>
|
|
<th class="text-center py-2 px-2">Gestione</th>
|
|
<th class="text-center py-2 px-2">Calcolo</th>
|
|
<th class="text-right py-2 px-2">% applicata</th>
|
|
<th class="text-right py-2 px-2">Quota finale</th>
|
|
<th class="text-right py-2 px-2">% inquilino</th>
|
|
<th class="text-right py-2 px-2">Prop.</th>
|
|
<th class="text-right py-2 px-2">Inq.</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y">
|
|
@foreach($tabella['righe'] as $r)
|
|
<tr>
|
|
<td class="py-2 px-2 text-gray-900 font-semibold">{{ $r['voce_codice'] ?? '—' }} {{ $r['voce_descrizione'] ?? '' }}</td>
|
|
<td class="py-2 px-2 text-center text-gray-700">{{ $r['tipo_gestione'] ?? '—' }}</td>
|
|
<td class="py-2 px-2 text-center text-gray-700">{{ $r['calcolo'] ?? '—' }}</td>
|
|
<td class="py-2 px-2 text-right text-gray-900">{{ number_format($r['percentuale_applicata'] ?? 0, 2, ',', '.') }}%</td>
|
|
<td class="py-2 px-2 text-right text-gray-900">{{ number_format($r['quota_finale'] ?? 0, 4, ',', '.') }}</td>
|
|
<td class="py-2 px-2 text-right text-gray-900">{{ number_format($r['percentuale_inquilino'] ?? 0, 2, ',', '.') }}%</td>
|
|
<td class="py-2 px-2 text-right text-gray-900">{{ number_format($r['importo_proprietario'] ?? 0, 4, ',', '.') }}</td>
|
|
<td class="py-2 px-2 text-right text-gray-900">{{ number_format($r['importo_inquilino'] ?? 0, 4, ',', '.') }}</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
@endif
|
|
</x-filament::section>
|
|
</div>
|
|
@endif
|
|
|
|
@if($tab === 'estratto')
|
|
@php
|
|
$rateCondomini = $rateEmessePerCategoria['condomini'] ?? [];
|
|
$rateInquilini = $rateEmessePerCategoria['inquilini'] ?? [];
|
|
$hasRate = (! empty($rateCondomini)) || (! empty($rateInquilini));
|
|
|
|
$compactRateRows = $estrattoCompattoRateRows ?? [];
|
|
$compactIncassi = $estrattoCompattoIncassi ?? [];
|
|
|
|
$sumBlk = function (array $items, string $field): float {
|
|
$s = 0.0;
|
|
foreach ($items as $it) {
|
|
$s += (float) ($it[$field] ?? 0);
|
|
}
|
|
return $s;
|
|
};
|
|
|
|
$totCAddeb = $sumBlk($rateCondomini, 'totale_addebitato');
|
|
$totCPag = $sumBlk($rateCondomini, 'totale_pagato');
|
|
$totCRes = $sumBlk($rateCondomini, 'residuo');
|
|
|
|
$totIAddeb = $sumBlk($rateInquilini, 'totale_addebitato');
|
|
$totIPag = $sumBlk($rateInquilini, 'totale_pagato');
|
|
$totIRes = $sumBlk($rateInquilini, 'residuo');
|
|
|
|
$tipoSel = $estrattoTipo ?? 'condomini';
|
|
$itemsSel = $tipoSel === 'inquilini' ? $rateInquilini : $rateCondomini;
|
|
|
|
$selectedRole = $tipoSel === 'inquilini' ? 'I' : 'C';
|
|
$compactRateRows = array_values(array_filter($compactRateRows, function (array $row) use ($selectedRole, $tipoSel): bool {
|
|
$tipo = strtoupper(trim((string) ($row['tipo'] ?? '')));
|
|
if ($tipo === '') {
|
|
return $tipoSel === 'condomini';
|
|
}
|
|
return $tipo === $selectedRole;
|
|
}));
|
|
$compactIncassi = array_values(array_filter($compactIncassi, function (array $row) use ($selectedRole, $tipoSel): bool {
|
|
$tipo = strtoupper(trim((string) ($row['tipo'] ?? '')));
|
|
if ($tipo === '') {
|
|
return $tipoSel === 'condomini';
|
|
}
|
|
return $tipo === $selectedRole;
|
|
}));
|
|
|
|
if (! $hasRate) {
|
|
$totCAddeb = (float) collect($estrattoCompattoRateRows ?? [])->filter(fn (array $row): bool => strtoupper((string) ($row['tipo'] ?? 'C')) !== 'I')->sum('dovuto');
|
|
$totCPag = (float) collect($estrattoCompattoIncassi ?? [])->filter(fn (array $row): bool => strtoupper((string) ($row['tipo'] ?? 'C')) !== 'I')->sum('importo');
|
|
$totCRes = $totCAddeb - $totCPag;
|
|
$totIAddeb = (float) collect($estrattoCompattoRateRows ?? [])->filter(fn (array $row): bool => strtoupper((string) ($row['tipo'] ?? '')) === 'I')->sum('dovuto');
|
|
$totIPag = (float) collect($estrattoCompattoIncassi ?? [])->filter(fn (array $row): bool => strtoupper((string) ($row['tipo'] ?? '')) === 'I')->sum('importo');
|
|
$totIRes = $totIAddeb - $totIPag;
|
|
}
|
|
@endphp
|
|
|
|
<x-filament::section>
|
|
<div class="flex items-center gap-2 text-sm font-semibold text-gray-900 mb-3">
|
|
<x-filament::icon icon="heroicon-o-document-text" class="h-5 w-5 text-primary-600" />
|
|
<span>Estratto conto unità</span>
|
|
</div>
|
|
|
|
<div class="rounded-2xl border bg-white p-3 mb-4">
|
|
<div class="text-sm font-semibold text-gray-900 mb-2">Situazione rate & incassi</div>
|
|
@php
|
|
$movimenti = [];
|
|
$seenRateKeys = [];
|
|
foreach ($compactRateRows as $r) {
|
|
$rateKey = implode('|', [
|
|
(string) ($r['gestione'] ?? ''),
|
|
(string) ($r['tipo'] ?? ''),
|
|
(string) ($r['data_emissione'] ?? ''),
|
|
(string) ($r['descrizione'] ?? ''),
|
|
(string) ($r['avviso'] ?? ''),
|
|
number_format((float) ($r['dovuto'] ?? 0), 2, '.', ''),
|
|
number_format((float) ($r['pagato'] ?? 0), 2, '.', ''),
|
|
]);
|
|
if (isset($seenRateKeys[$rateKey])) {
|
|
continue;
|
|
}
|
|
$seenRateKeys[$rateKey] = true;
|
|
|
|
$dovuto = (float) ($r['dovuto'] ?? 0);
|
|
$pagato = (float) ($r['pagato'] ?? 0);
|
|
$residuo = (float) ($r['residuo'] ?? ($dovuto - $pagato));
|
|
if (abs($dovuto) < 0.00001 && abs($pagato) < 0.00001 && abs($residuo) < 0.00001) {
|
|
continue;
|
|
}
|
|
|
|
$movimenti[] = [
|
|
'tipo' => 'rata',
|
|
'soggetto_tipo' => $r['tipo'] ?? null,
|
|
'gestione' => $r['gestione'] ?? null,
|
|
'data' => $r['data_emissione'] ?? null,
|
|
'data_pagamento' => $r['data_pagamento'] ?? null,
|
|
'descrizione' => $r['descrizione'] ?? null,
|
|
'ref' => !empty($r['numero_ricevuta']) ? ('Ric. ' . $r['numero_ricevuta']) : (!empty($r['avviso']) ? ('Avv. ' . $r['avviso']) : null),
|
|
'dovuto' => $dovuto,
|
|
'residuo' => $residuo,
|
|
'incasso' => $pagato,
|
|
];
|
|
}
|
|
|
|
if (empty($movimenti)) {
|
|
$seenIncassoKeys = [];
|
|
foreach ($compactIncassi as $i) {
|
|
$incasso = (float) ($i['importo'] ?? 0);
|
|
if (abs($incasso) < 0.00001) {
|
|
continue;
|
|
}
|
|
|
|
$incassoKey = implode('|', [
|
|
(string) ($i['tipo'] ?? ''),
|
|
(string) ($i['data'] ?? ''),
|
|
(string) ($i['descrizione'] ?? ''),
|
|
(string) ($i['n_ricevuta'] ?? ''),
|
|
number_format($incasso, 2, '.', ''),
|
|
]);
|
|
if (isset($seenIncassoKeys[$incassoKey])) {
|
|
continue;
|
|
}
|
|
$seenIncassoKeys[$incassoKey] = true;
|
|
|
|
$movimenti[] = [
|
|
'tipo' => 'incasso',
|
|
'soggetto_tipo' => $i['tipo'] ?? null,
|
|
'gestione' => $i['gestione'] ?? null,
|
|
'data' => $i['data'] ?? null,
|
|
'data_pagamento' => $i['data'] ?? null,
|
|
'descrizione' => $i['descrizione'] ?? null,
|
|
'ref' => !empty($i['n_ricevuta']) ? ('Ric. ' . $i['n_ricevuta']) : null,
|
|
'dovuto' => null,
|
|
'residuo' => null,
|
|
'incasso' => $incasso,
|
|
];
|
|
}
|
|
}
|
|
|
|
foreach ($estrattoConguagliIniziali ?? [] as $c) {
|
|
$importoConguaglio = (float) ($c['importo'] ?? 0);
|
|
if (abs($importoConguaglio) < 0.00001) {
|
|
continue;
|
|
}
|
|
$movimenti[] = [
|
|
'tipo' => 'conguaglio',
|
|
'soggetto_tipo' => $selectedRole,
|
|
'gestione' => $c['gestione_label'] ?? null,
|
|
'data' => $c['data'] ?? null,
|
|
'data_pagamento' => null,
|
|
'descrizione' => $c['descrizione'] ?? null,
|
|
'ref' => trim((string) (($c['gestione_label'] ?? '') . ' ' . ($c['tipo'] ?? ''))),
|
|
'dovuto' => $importoConguaglio,
|
|
'residuo' => $importoConguaglio,
|
|
'incasso' => null,
|
|
];
|
|
}
|
|
usort($movimenti, function ($a, $b) {
|
|
$da = $a['data'] ? \Carbon\Carbon::createFromFormat('d/m/Y', $a['data'])->timestamp : 0;
|
|
$db = $b['data'] ? \Carbon\Carbon::createFromFormat('d/m/Y', $b['data'])->timestamp : 0;
|
|
return $da <=> $db;
|
|
});
|
|
|
|
$movimentiByGestione = [];
|
|
foreach ($movimenti as $m) {
|
|
$gestioneLabel = trim((string) ($m['gestione'] ?? ''));
|
|
$anno = null;
|
|
if ($gestioneLabel === '' && ! empty($m['data'])) {
|
|
try {
|
|
$anno = \Carbon\Carbon::createFromFormat('d/m/Y', $m['data'])->format('Y');
|
|
} catch (\Throwable $e) {
|
|
$anno = null;
|
|
}
|
|
}
|
|
$key = $gestioneLabel !== '' ? $gestioneLabel : ($anno ?: 'Senza data');
|
|
$movimentiByGestione[$key][] = $m;
|
|
}
|
|
@endphp
|
|
|
|
@if(empty($movimenti))
|
|
<div class="text-sm text-gray-500">Nessuna rata o incasso disponibile.</div>
|
|
@else
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full text-xs">
|
|
<thead>
|
|
<tr class="text-gray-500 border-b">
|
|
<th class="text-left py-2 pr-3">Data</th>
|
|
<th class="text-left py-2 pr-3">Tipo</th>
|
|
<th class="text-left py-2 pr-3">Descrizione</th>
|
|
<th class="text-left py-2 pr-3">Rif.</th>
|
|
<th class="text-right py-2 pr-3">Dovuto</th>
|
|
<th class="text-right py-2 pr-3">Pagato</th>
|
|
<th class="text-right py-2 pr-0">Residuo</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y">
|
|
@php
|
|
$totDovutoAll = 0.0;
|
|
$totIncassoAll = 0.0;
|
|
@endphp
|
|
@foreach($movimentiByGestione as $gestione => $rows)
|
|
<tr class="bg-gray-50">
|
|
<td class="py-2 pr-3 text-gray-700 font-semibold" colspan="7">Gestione {{ $gestione }}</td>
|
|
</tr>
|
|
@php
|
|
$totDovuto = 0.0;
|
|
$totIncasso = 0.0;
|
|
@endphp
|
|
@foreach($rows as $m)
|
|
@php
|
|
$totDovuto += (float) ($m['dovuto'] ?? 0);
|
|
$totIncasso += (float) ($m['incasso'] ?? 0);
|
|
@endphp
|
|
<tr>
|
|
<td class="py-2 pr-3 text-gray-700">{{ $m['data'] ?? '—' }}</td>
|
|
<td class="py-2 pr-3 text-gray-700">
|
|
{{ $m['tipo'] === 'rata' ? 'Rata' : ($m['tipo'] === 'conguaglio' ? 'Conguaglio' : 'Incasso') }}
|
|
</td>
|
|
<td class="py-2 pr-3 text-gray-900">
|
|
<div>{{ $m['descrizione'] ?? '—' }}</div>
|
|
@if(!empty($m['data_pagamento']) && $m['tipo'] !== 'incasso')
|
|
<div class="text-[11px] text-gray-500">Pagato il {{ $m['data_pagamento'] }}</div>
|
|
@endif
|
|
</td>
|
|
<td class="py-2 pr-3 text-gray-700">{{ $m['ref'] !== '' ? $m['ref'] : '—' }}</td>
|
|
<td class="py-2 pr-3 text-right text-gray-900 tabular-nums">
|
|
{{ $m['dovuto'] !== null ? number_format($m['dovuto'], 2, ',', '.') . ' €' : '—' }}
|
|
</td>
|
|
<td class="py-2 pr-3 text-right text-gray-900 tabular-nums">
|
|
{{ $m['incasso'] !== null ? number_format($m['incasso'], 2, ',', '.') . ' €' : '—' }}
|
|
</td>
|
|
<td class="py-2 pr-0 text-right text-gray-900 tabular-nums">
|
|
{{ $m['residuo'] !== null ? number_format($m['residuo'], 2, ',', '.') . ' €' : '—' }}
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
@php
|
|
$totDovutoAll += $totDovuto;
|
|
$totIncassoAll += $totIncasso;
|
|
$saldo = $totDovuto - $totIncasso;
|
|
@endphp
|
|
<tr class="bg-gray-50">
|
|
<td class="py-2 pr-3 text-gray-700 font-semibold" colspan="4">Subtotale gestione</td>
|
|
<td class="py-2 pr-3 text-right text-gray-900 font-semibold tabular-nums">{{ number_format($totDovuto, 2, ',', '.') }} €</td>
|
|
<td class="py-2 pr-3 text-right text-gray-900 font-semibold tabular-nums">{{ number_format($totIncasso, 2, ',', '.') }} €</td>
|
|
<td class="py-2 pr-0 text-right text-gray-900 font-semibold tabular-nums">Saldo {{ number_format($saldo, 2, ',', '.') }} €</td>
|
|
</tr>
|
|
@endforeach
|
|
@php
|
|
$saldoAll = $totDovutoAll - $totIncassoAll;
|
|
@endphp
|
|
<tr class="bg-primary-50">
|
|
<td class="py-2 pr-3 text-primary-700 font-semibold" colspan="4">Totale generale</td>
|
|
<td class="py-2 pr-3 text-right text-primary-700 font-semibold tabular-nums">{{ number_format($totDovutoAll, 2, ',', '.') }} €</td>
|
|
<td class="py-2 pr-3 text-right text-primary-700 font-semibold tabular-nums">{{ number_format($totIncassoAll, 2, ',', '.') }} €</td>
|
|
<td class="py-2 pr-0 text-right text-primary-700 font-semibold tabular-nums">Saldo {{ number_format($saldoAll, 2, ',', '.') }} €</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
@if(! $hasRate)
|
|
<div class="text-sm text-gray-500">Nessuna rata emessa trovata per questa unità.</div>
|
|
@else
|
|
<div class="grid gap-3 md:grid-cols-2">
|
|
<button type="button"
|
|
wire:click="setEstrattoTipo('condomini')"
|
|
class="rounded-2xl border p-4 text-left transition {{ $tipoSel === 'condomini' ? 'border-primary-300 bg-primary-50' : 'bg-gray-50 hover:border-gray-200' }}">
|
|
<div class="text-xs text-gray-500">CONDOMINO</div>
|
|
<div class="text-sm font-semibold text-gray-900">Addebito {{ number_format($totCAddeb, 2, ',', '.') }} €</div>
|
|
<div class="text-xs text-gray-600">Pagato {{ number_format($totCPag, 2, ',', '.') }} € · Residuo {{ number_format($totCRes, 2, ',', '.') }} €</div>
|
|
</button>
|
|
|
|
<button type="button"
|
|
wire:click="setEstrattoTipo('inquilini')"
|
|
class="rounded-2xl border p-4 text-left transition {{ $tipoSel === 'inquilini' ? 'border-primary-300 bg-primary-50' : 'bg-gray-50 hover:border-gray-200' }}">
|
|
<div class="text-xs text-gray-500">INQUILINO</div>
|
|
<div class="text-sm font-semibold text-gray-900">Addebito {{ number_format($totIAddeb, 2, ',', '.') }} €</div>
|
|
<div class="text-xs text-gray-600">Pagato {{ number_format($totIPag, 2, ',', '.') }} € · Residuo {{ number_format($totIRes, 2, ',', '.') }} €</div>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="mt-4 rounded-2xl border bg-gray-50 p-3">
|
|
<div class="mb-2 text-sm font-semibold text-gray-900">
|
|
{{ $tipoSel === 'inquilini' ? 'Inquilino / altro' : 'Condomino (proprietari)' }} ({{ count($itemsSel) }})
|
|
</div>
|
|
|
|
@if(empty($itemsSel))
|
|
<div class="text-sm text-gray-500">Nessuna rata per questa categoria.</div>
|
|
@else
|
|
<div class="overflow-x-auto">
|
|
<table class="min-w-full text-sm">
|
|
<thead>
|
|
<tr class="text-gray-500 border-b">
|
|
<th class="text-left py-2 pr-3">Soggetto</th>
|
|
<th class="text-right py-2 pr-3">N.</th>
|
|
<th class="text-right py-2 pr-3">Addebito</th>
|
|
<th class="text-right py-2 pr-3">Pagato</th>
|
|
<th class="text-right py-2 pr-3">Residuo</th>
|
|
<th class="text-right py-2 pr-3">Scadute</th>
|
|
<th class="text-right py-2 pr-0">Scheda</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody class="divide-y">
|
|
@foreach($itemsSel as $r)
|
|
@php
|
|
$sid = (int) ($r['soggetto_id'] ?? 0);
|
|
$schedaUrl = null;
|
|
if ($sid > 0) {
|
|
$base = \App\Filament\Pages\Contabilita\EstrattoContoSoggetto::getUrl(panel: 'admin-filament', parameters: ['record' => $sid]);
|
|
$schedaUrl = $base . '?' . http_build_query([
|
|
'vista' => 'unita',
|
|
'unita_id' => (int) ($this->unita?->id ?? 0),
|
|
]);
|
|
}
|
|
@endphp
|
|
<tr>
|
|
<td class="py-2 pr-3">
|
|
<div class="font-semibold text-gray-900">{{ $r['nome'] ?? '—' }}</div>
|
|
<div class="text-xs text-gray-500">CF: {{ $r['codice_fiscale'] ?? '—' }}</div>
|
|
</td>
|
|
<td class="py-2 pr-3 text-right text-gray-900">{{ $r['numero_rate'] ?? 0 }}</td>
|
|
<td class="py-2 pr-3 text-right text-gray-900">{{ number_format((float) ($r['totale_addebitato'] ?? 0), 2, ',', '.') }} €</td>
|
|
<td class="py-2 pr-3 text-right text-gray-900">{{ number_format((float) ($r['totale_pagato'] ?? 0), 2, ',', '.') }} €</td>
|
|
<td class="py-2 pr-3 text-right text-gray-900">{{ number_format((float) ($r['residuo'] ?? 0), 2, ',', '.') }} €</td>
|
|
<td class="py-2 pr-3 text-right text-gray-900">{{ $r['scadute'] ?? 0 }}</td>
|
|
<td class="py-2 pr-0 text-right">
|
|
@if($schedaUrl)
|
|
<a class="fi-btn fi-btn-color-gray fi-btn-size-xs" href="{{ $schedaUrl }}">
|
|
<span class="fi-btn-label">Apri</span>
|
|
</a>
|
|
@else
|
|
<span class="text-xs text-gray-400">—</span>
|
|
@endif
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@endif
|
|
|
|
<div class="mt-3">
|
|
<a class="fi-btn fi-btn-color-gray fi-btn-size-sm" href="{{ \App\Filament\Pages\Contabilita\RateEmesseArchivio::getUrl(panel: 'admin-filament') }}">
|
|
<span class="fi-btn-label">Apri archivio Rate emesse</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</x-filament::section>
|
|
@endif
|
|
|
|
</div>
|
|
</x-filament::section>
|
|
@endif
|
|
</div>
|
|
</x-filament-panels::page>
|