netgescon-day0/resources/views/filament/pages/contabilita/debiti-pagare-hub.blade.php

315 lines
22 KiB
PHP

<x-filament-panels::page>
<div class="mx-auto max-w-7xl space-y-4">
<x-filament.components.page-breadcrumbs
:breadcrumbs="[
['label' => 'Contabilità', 'url' => null],
['label' => 'Hub Pagamenti', 'url' => null],
]"
/>
@php
$stabile = $this->getActiveStabile();
@endphp
@if(! $stabile)
<x-filament::section>
<div class="text-sm text-gray-600 dark:text-gray-400">Seleziona uno stabile per vedere l'Hub Pagamenti.</div>
</x-filament::section>
@else
<!-- Info stabile attivo -->
<x-filament::section>
<div class="flex flex-wrap items-start justify-between gap-3">
<div class="space-y-1">
<div class="text-sm text-gray-500">Stabile attivo</div>
<div class="text-lg font-semibold text-gray-900 dark:text-gray-100">
{{ $stabile->codice_operatore ?? $stabile->codice_stabile ?? '' }} — {{ $stabile->denominazione ?? 'Stabile' }}
</div>
</div>
<div class="text-right">
<div class="text-xs text-gray-500">IBAN principale</div>
<div class="text-sm font-medium text-gray-900 dark:text-gray-100">{{ $stabile->iban_principale ?? '' }}</div>
</div>
</div>
</x-filament::section>
<!-- Navigazione Tab Premium -->
<div class="border-b border-gray-200 dark:border-gray-800">
<nav class="-mb-px flex space-x-8" aria-label="Tabs">
<button type="button"
wire:click="setTab('debiti')"
class="whitespace-nowrap border-b-2 py-4 px-1 text-sm font-medium transition-all {{ $activeTab === 'debiti' ? 'border-cyan-500 text-cyan-600 dark:text-cyan-400' : 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700' }}">
Da Pagare (Scadenze)
</button>
<button type="button"
wire:click="setTab('movimenti')"
class="whitespace-nowrap border-b-2 py-4 px-1 text-sm font-medium transition-all {{ $activeTab === 'movimenti' ? 'border-cyan-500 text-cyan-600 dark:text-cyan-400' : 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700' }}">
Movimenti Bancari (Quadratura)
</button>
<button type="button"
wire:click="setTab('stato_debiti')"
class="whitespace-nowrap border-b-2 py-4 px-1 text-sm font-medium transition-all {{ $activeTab === 'stato_debiti' ? 'border-cyan-500 text-cyan-600 dark:text-cyan-400' : 'border-transparent text-gray-500 hover:border-gray-300 hover:text-gray-700' }}">
Stato Debiti a Data
</button>
</nav>
</div>
<!-- Tab 1: Da Pagare -->
@if($activeTab === 'debiti')
<x-filament::section>
<x-slot name="heading">
<div class="flex items-center justify-between">
<span>Fatture Fornitori in Scadenza</span>
<span class="rounded-full bg-cyan-100 dark:bg-cyan-900/30 px-3 py-1 text-xs font-semibold text-cyan-800 dark:text-cyan-400">
{{ count($debiti) }} scadenze pendenti
</span>
</div>
</x-slot>
<x-slot name="description">
Copia rapidamente l'IBAN e la causale con tag `FAT-ID:{id}` per effettuare i bonifici e consentire la riconciliazione automatica degli estratti conto.
</x-slot>
<div class="overflow-x-auto rounded-lg border border-gray-200 dark:border-gray-800">
<table class="min-w-full divide-y divide-gray-200 text-sm dark:divide-gray-800">
<thead class="bg-gray-50 text-left text-xs font-semibold text-gray-600 dark:bg-gray-900 dark:text-gray-300">
<tr>
<th class="px-4 py-3">Fornitore & Scadenza</th>
<th class="px-4 py-3 text-right">Netto da Pagare</th>
<th class="px-4 py-3">IBAN Beneficiario</th>
<th class="px-4 py-3">Causale Bonifico (Max 140 car.)</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100 dark:divide-gray-800">
@forelse($debiti as $d)
<tr class="hover:bg-cyan-50/20 dark:hover:bg-cyan-950/10 transition-colors">
<td class="px-4 py-3 align-top">
<div class="font-medium text-gray-900 dark:text-gray-100">{{ $d['fornitore_ragione_sociale'] }}</div>
<div class="mt-0.5 text-xs text-gray-500">
Doc. n. <span class="font-semibold">{{ $d['numero_documento'] }}</span> del {{ $d['data_documento'] }} (ID: #{{ $d['id'] }})
</div>
</td>
<td class="px-4 py-3 text-right font-semibold text-gray-900 dark:text-gray-100 align-top whitespace-nowrap">
{{ number_format($d['netto_da_pagare'], 2, ',', '.') }}
</td>
<td class="px-4 py-3 align-top whitespace-nowrap">
@if($d['iban'])
<div class="flex items-center gap-2">
<code class="rounded bg-gray-100 dark:bg-gray-800 px-2 py-1 text-xs font-semibold text-cyan-800 dark:text-cyan-400">
{{ $d['iban'] }}
</code>
<button type="button"
onclick="copyTextToClipboard(this, '{{ $d['iban'] }}')"
class="inline-flex items-center rounded-md bg-white dark:bg-gray-850 px-2 py-1 text-xs font-medium text-cyan-800 dark:text-cyan-400 ring-1 ring-inset ring-cyan-300 dark:ring-cyan-800 hover:bg-cyan-50/30 transition shadow-sm">
<span>Copia</span>
</button>
</div>
@else
<span class="text-xs text-amber-600 font-semibold bg-amber-50 dark:bg-amber-950/20 px-2 py-1 rounded">IBAN non registrato</span>
@endif
</td>
<td class="px-4 py-3 align-top">
<div class="flex items-start gap-2">
<div class="flex-1 max-w-xs text-xs bg-gray-50 dark:bg-gray-900 px-2 py-1 rounded border border-gray-100 dark:border-gray-800 break-all select-all font-mono">
{{ $d['descrizione_bonifico'] }}
</div>
<button type="button"
onclick="copyTextToClipboard(this, '{{ addslashes($d['descrizione_bonifico']) }}')"
class="inline-flex items-center rounded-md bg-white dark:bg-gray-850 px-2 py-1 text-xs font-medium text-cyan-800 dark:text-cyan-400 ring-1 ring-inset ring-cyan-300 dark:ring-cyan-800 hover:bg-cyan-50/30 transition shadow-sm">
<span>Copia</span>
</button>
</div>
</td>
</tr>
@empty
<tr>
<td colspan="4" class="px-4 py-6 text-center text-gray-500">
Nessun debito da pagare trovato per questo stabile.
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</x-filament::section>
@endif
<!-- Tab 2: Movimenti Bancari -->
@if($activeTab === 'movimenti')
<x-filament::section>
<x-slot name="heading">Quadratura Movimenti Bancari</x-slot>
<x-slot name="description">
Monitora l'estratto conto importato. I movimenti quadrati sono associati alla prima nota o al pagamento delle fatture, mentre quelli da quadrare indicano i flussi ancora da registrare.
</x-slot>
<div class="overflow-x-auto rounded-lg border border-gray-200 dark:border-gray-800">
<table class="min-w-full divide-y divide-gray-200 text-sm dark:divide-gray-800">
<thead class="bg-gray-50 text-left text-xs font-semibold text-gray-600 dark:bg-gray-900 dark:text-gray-300">
<tr>
<th class="px-4 py-3">Data</th>
<th class="px-4 py-3">Descrizione Movimento</th>
<th class="px-4 py-3 text-right">Importo</th>
<th class="px-4 py-3">Stato Riconciliazione</th>
<th class="px-4 py-3">Note / Collegamenti</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100 dark:divide-gray-800">
@forelse($movimenti as $m)
<tr class="hover:bg-cyan-50/20 dark:hover:bg-cyan-950/10 transition-colors">
<td class="px-4 py-3 align-top whitespace-nowrap">{{ $m['data'] }}</td>
<td class="px-4 py-3 align-top">
<div class="font-medium text-gray-900 dark:text-gray-100">{{ $m['descrizione'] }}</div>
</td>
<td class="px-4 py-3 text-right font-semibold align-top whitespace-nowrap {{ $m['importo'] < 0 ? 'text-red-600 dark:text-red-400' : 'text-green-600 dark:text-green-400' }}">
€ {{ number_format($m['importo'], 2, ',', '.') }}
</td>
<td class="px-4 py-3 align-top whitespace-nowrap">
@if($m['stato'] === 'quadrato')
<span class="inline-flex items-center gap-1.5 rounded-full bg-emerald-100 dark:bg-emerald-900/30 px-2 py-1 text-xs font-semibold text-emerald-800 dark:text-emerald-400">
<span class="h-1.5 w-1.5 rounded-full bg-emerald-500"></span>
Quadrato
</span>
@else
<span class="inline-flex items-center gap-1.5 rounded-full bg-amber-100 dark:bg-amber-900/30 px-2 py-1 text-xs font-semibold text-amber-800 dark:text-amber-400">
<span class="h-1.5 w-1.5 rounded-full bg-amber-500"></span>
Da quadrare
</span>
@endif
</td>
<td class="px-4 py-3 align-top text-xs text-gray-500">
@if($m['stato'] === 'quadrato')
@if($m['invoice_id'])
<span class="font-semibold text-gray-700 dark:text-gray-300">Pagata Fattura #{{ $m['invoice_number'] }}</span>
@if($m['fornitore'])
di <span class="font-medium">{{ $m['fornitore'] }}</span>
@endif
@else
<span class="italic text-gray-400">Registrato in prima nota</span>
@endif
@else
<span class="text-amber-700 dark:text-amber-500 leading-normal">{{ $m['advice'] }}</span>
@endif
</td>
</tr>
@empty
<tr>
<td colspan="5" class="px-4 py-6 text-center text-gray-500">
Nessun movimento bancario trovato.
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</x-filament::section>
@endif
<!-- Tab 3: Stato Debiti a Data -->
@if($activeTab === 'stato_debiti')
<x-filament::section>
<x-slot name="heading">
<div class="flex items-center justify-between">
<span>Situazione Debiti ad una Data Specifica</span>
<div class="flex items-center gap-2">
<label for="targetDate" class="text-xs text-gray-500">Analizza alla data:</label>
<input type="date"
id="targetDate"
wire:model.live="targetDate"
class="rounded-md border-gray-300 dark:border-gray-700 bg-white dark:bg-gray-800 text-xs text-gray-900 dark:text-gray-100 shadow-sm focus:border-cyan-500 focus:ring-cyan-500" />
</div>
</div>
</x-slot>
<x-slot name="description">
Questo report mostra tutti i debiti (fatture fornitori) che erano aperti alla data indicata (es. data di fine gestione) e indica quando sono stati pagati (data di chiusura del debito), consentendo di analizzare i pagamenti avvenuti dopo il termine.
</x-slot>
<!-- Card Riepilogativa Saldo Debiti -->
<div class="mb-4 grid grid-cols-1 gap-4 sm:grid-cols-2">
<div class="rounded-lg border border-gray-200 dark:border-gray-800 bg-gray-50/50 dark:bg-gray-900/50 p-4">
<div class="text-sm font-medium text-gray-500">Esposizione Debitoria Complessiva alla data</div>
<div class="mt-2 text-2xl font-bold text-gray-900 dark:text-gray-100">
€ {{ number_format($totaleDebitiStorici, 2, ',', '.') }}
</div>
<div class="mt-1 text-xs text-gray-400">Somma delle fatture con data documento antecedente o uguale al {{ \Illuminate\Support\Carbon::parse($targetDate)->format('d/m/Y') }} e non ancora liquidate a quella data.</div>
</div>
</div>
<div class="overflow-x-auto rounded-lg border border-gray-200 dark:border-gray-800">
<table class="min-w-full divide-y divide-gray-200 text-sm dark:divide-gray-800">
<thead class="bg-gray-50 text-left text-xs font-semibold text-gray-600 dark:bg-gray-900 dark:text-gray-300">
<tr>
<th class="px-4 py-3">Fornitore</th>
<th class="px-4 py-3">Dettagli Fattura</th>
<th class="px-4 py-3 text-right">Importo Residuo</th>
<th class="px-4 py-3">Stato Corrente</th>
<th class="px-4 py-3">Data Chiusura Debito</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-100 dark:divide-gray-800">
@forelse($debitiStorici as $ds)
<tr class="hover:bg-cyan-50/20 dark:hover:bg-cyan-950/10 transition-colors">
<td class="px-4 py-3 align-top font-medium text-gray-900 dark:text-gray-100">{{ $ds['fornitore'] }}</td>
<td class="px-4 py-3 align-top">
Doc. n. <span class="font-semibold">{{ $ds['numero_documento'] }}</span> del {{ $ds['data_documento'] }}
</td>
<td class="px-4 py-3 text-right font-semibold text-gray-900 dark:text-gray-100 align-top whitespace-nowrap">
€ {{ number_format($ds['netto_da_pagare'], 2, ',', '.') }}
</td>
<td class="px-4 py-3 align-top whitespace-nowrap">
@if($ds['stato_corrente'] === 'pagato')
<span class="rounded bg-emerald-100 dark:bg-emerald-900/30 px-2 py-0.5 text-xs font-semibold text-emerald-800 dark:text-emerald-400">
Pagato oggi
</span>
@else
<span class="rounded bg-amber-100 dark:bg-amber-900/30 px-2 py-0.5 text-xs font-semibold text-amber-800 dark:text-amber-400">
In attesa
</span>
@endif
</td>
<td class="px-4 py-3 align-top font-medium whitespace-nowrap">
@if($ds['data_chiusura'] === 'Ancora aperto')
<span class="text-amber-600 dark:text-amber-500 bg-amber-50 dark:bg-amber-950/20 px-2 py-0.5 rounded text-xs">Ancora aperto</span>
@else
<span class="text-green-700 dark:text-green-400 bg-green-50 dark:bg-green-950/20 px-2 py-0.5 rounded text-xs">
Chiuso il {{ $ds['data_chiusura'] }}
</span>
@endif
</td>
</tr>
@empty
<tr>
<td colspan="5" class="px-4 py-6 text-center text-gray-500">
Nessun debito aperto rilevato alla data del {{ \Illuminate\Support\Carbon::parse($targetDate)->format('d/m/Y') }}.
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</x-filament::section>
@endif
@endif
</div>
<script>
function copyTextToClipboard(button, text) {
navigator.clipboard.writeText(text).then(() => {
const span = button.querySelector('span');
const originalText = span.textContent;
span.textContent = 'Copiato!';
button.classList.remove('text-cyan-800', 'ring-cyan-300');
button.classList.add('text-green-700', 'ring-green-400', 'bg-green-50');
setTimeout(() => {
span.textContent = originalText;
button.classList.add('text-cyan-800', 'ring-cyan-300');
button.classList.remove('text-green-700', 'ring-green-400', 'bg-green-50');
}, 1200);
}).catch(err => {
console.error('Could not copy text: ', err);
});
}
</script>
</x-filament-panels::page>