296 lines
18 KiB
PHP
Executable File
296 lines
18 KiB
PHP
Executable File
<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' => 'Fatture fornitori', 'url' => \App\Filament\Pages\Contabilita\FattureFornitoriArchivio::getUrl(panel: 'admin-filament')],
|
|
['label' => 'Registrazione', 'url' => null],
|
|
]"
|
|
/>
|
|
|
|
<div class="grid grid-cols-1 gap-4 lg:grid-cols-12">
|
|
<div class="lg:col-span-9 space-y-4">
|
|
@php($hdr = $this->getHeaderSummary())
|
|
@php($delta = (float) ($hdr['delta'] ?? 0))
|
|
@php($deltaOk = $delta == 0.0)
|
|
@php($linkedFe = $this->getLinkedFatturaElettronica())
|
|
@php($linkedFeDetails = $linkedFe ? $this->getLinkedFeXmlDetails() : [])
|
|
<x-filament::section>
|
|
<div class="space-y-3">
|
|
<div>
|
|
{{ $this->getSchema('top') }}
|
|
</div>
|
|
|
|
<div>
|
|
{{ $this->getSchema('header') }}
|
|
</div>
|
|
</div>
|
|
</x-filament::section>
|
|
|
|
<x-filament::section>
|
|
<x-slot name="heading">
|
|
<div class="flex flex-wrap items-center justify-between gap-2">
|
|
<div>Righe fattura</div>
|
|
</div>
|
|
</x-slot>
|
|
{{ $this->getSchema('form') }}
|
|
</x-filament::section>
|
|
|
|
<x-filament::section>
|
|
<x-slot name="heading">Totali</x-slot>
|
|
<div class="grid grid-cols-1 gap-3 md:grid-cols-6">
|
|
<div class="rounded-lg border bg-gray-50 p-3">
|
|
<div class="text-xs text-gray-500">Imponibile</div>
|
|
<div class="mt-1 text-lg font-semibold">€ {{ number_format((float) ($hdr['imponibile'] ?? 0), 2, ',', '.') }}</div>
|
|
</div>
|
|
<div class="rounded-lg border bg-gray-50 p-3">
|
|
<div class="text-xs text-gray-500">IVA</div>
|
|
<div class="mt-1 text-lg font-semibold">€ {{ number_format((float) ($hdr['iva'] ?? 0), 2, ',', '.') }}</div>
|
|
</div>
|
|
<div class="rounded-lg border bg-gray-50 p-3">
|
|
<div class="text-xs text-gray-500">Totale documento</div>
|
|
<div class="mt-1 text-lg font-semibold">€ {{ number_format((float) ($hdr['totale'] ?? 0), 2, ',', '.') }}</div>
|
|
</div>
|
|
<div class="rounded-lg border bg-gray-50 p-3">
|
|
<div class="text-xs text-gray-500">Ritenuta (RA)</div>
|
|
<div class="mt-1 text-lg font-semibold">€ {{ number_format((float) ($hdr['ra'] ?? 0), 2, ',', '.') }}</div>
|
|
</div>
|
|
<div class="rounded-lg border bg-gray-50 p-3">
|
|
<div class="text-xs text-gray-500">Netto da pagare</div>
|
|
<div class="mt-1 text-lg font-semibold">€ {{ number_format((float) ($hdr['netto'] ?? 0), 2, ',', '.') }}</div>
|
|
</div>
|
|
<div class="rounded-lg border p-3 {{ $deltaOk ? 'bg-success-50 border-success-200' : 'bg-danger-50 border-danger-200' }}">
|
|
<div class="text-xs text-gray-500">Quadratura (delta)</div>
|
|
<div class="mt-1 text-lg font-semibold {{ $deltaOk ? 'text-success-700' : 'text-danger-700' }}">€ {{ number_format($delta, 2, ',', '.') }}</div>
|
|
<div class="text-xs text-gray-500">Somma righe: € {{ number_format((float) ($hdr['somma_righe'] ?? 0), 2, ',', '.') }}</div>
|
|
</div>
|
|
</div>
|
|
</x-filament::section>
|
|
|
|
</div>
|
|
|
|
<div class="lg:col-span-3 space-y-4 lg:sticky lg:top-4 lg:self-start">
|
|
<x-filament::section>
|
|
<x-slot name="heading">Funzioni base</x-slot>
|
|
<div class="space-y-2">
|
|
<x-filament::button color="primary" wire:click="save" :disabled="!$deltaOk" class="w-full">Memorizza</x-filament::button>
|
|
<x-filament::button color="gray" tag="a" :href="\App\Filament\Pages\Contabilita\FattureFornitoriArchivio::getUrl(panel: 'admin-filament')" class="w-full">Archivio</x-filament::button>
|
|
<x-filament::button color="gray" tag="a" :href="\App\Filament\Pages\Contabilita\FatturaFornitoreScheda::getUrl(panel: 'admin-filament')" class="w-full">Nuova</x-filament::button>
|
|
</div>
|
|
</x-filament::section>
|
|
|
|
@if($linkedFe)
|
|
<x-filament::section>
|
|
<x-slot name="heading">PDF (da FE)</x-slot>
|
|
|
|
<div class="space-y-2">
|
|
<div class="flex items-center justify-between gap-2 text-sm">
|
|
<div class="text-gray-500">FE #{{ $linkedFe->id }}</div>
|
|
<div class="flex items-center gap-2">
|
|
<x-filament::button
|
|
size="sm"
|
|
color="primary"
|
|
x-data
|
|
x-on:click="$dispatch('open-modal', { id: 'linked-fe-pdf-modal' })"
|
|
>
|
|
Apri
|
|
</x-filament::button>
|
|
<a class="underline" href="{{ route('admin.fatture-elettroniche.download-pdf', ['fattura' => $linkedFe->id]) }}">Scarica</a>
|
|
</div>
|
|
</div>
|
|
|
|
<x-filament::modal id="linked-fe-pdf-modal" width="7xl">
|
|
<x-slot name="heading">PDF fattura (FE #{{ $linkedFe->id }})</x-slot>
|
|
<div class="overflow-hidden rounded-lg border border-gray-200 dark:border-gray-800">
|
|
<iframe
|
|
title="PDF fattura"
|
|
class="h-[80vh] w-full"
|
|
src="{{ route('admin.fatture-elettroniche.download-pdf', ['fattura' => $linkedFe->id]) }}?inline=1"
|
|
></iframe>
|
|
</div>
|
|
</x-filament::modal>
|
|
</div>
|
|
</x-filament::section>
|
|
@endif
|
|
|
|
<x-filament::section>
|
|
<x-slot name="heading">Prima nota</x-slot>
|
|
<div class="space-y-2">
|
|
<x-filament::button color="primary" wire:click="generaPrimaNota" :disabled="!$record || $record?->registrazione_id" class="w-full">Crea primanota</x-filament::button>
|
|
<x-filament::button color="gray" disabled class="w-full">Abbina primanota</x-filament::button>
|
|
<x-filament::button color="gray" disabled class="w-full">Assegna contropartite</x-filament::button>
|
|
</div>
|
|
</x-filament::section>
|
|
|
|
@php($gestioneTipoSelected = $this->getSelectedGestioneTipo())
|
|
@if($gestioneTipoSelected === 'ordinaria')
|
|
@php($tabs = $this->getTabelleMillesimaliByTipo('ordinaria'))
|
|
|
|
<x-filament::section>
|
|
<x-slot name="heading">Tabelle (Ordinarie)</x-slot>
|
|
|
|
<div class="space-y-3">
|
|
@forelse($tabs as $t)
|
|
@php($voci = $this->getVociSpesaByTabellaMillesimale((int) ($t['id'] ?? 0)))
|
|
<div class="rounded-lg border border-gray-200 dark:border-gray-800">
|
|
<div class="px-3 py-2 text-sm font-semibold text-gray-900 dark:text-gray-100">
|
|
{{ $t['label'] ?? ('Tabella #' . ($t['id'] ?? '')) }}
|
|
</div>
|
|
<div class="border-t border-gray-200 dark:border-gray-800">
|
|
<ul class="divide-y text-sm">
|
|
@forelse($voci as $v)
|
|
<li class="px-3 py-2 text-gray-900 dark:text-gray-100">{{ $v['label'] ?? ('Voce #' . ($v['id'] ?? '')) }}</li>
|
|
@empty
|
|
<li class="px-3 py-2 text-gray-500">Nessuna voce collegata a questa tabella.</li>
|
|
@endforelse
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
@empty
|
|
<div class="text-sm text-gray-500">Nessuna tabella ordinaria trovata.</div>
|
|
@endforelse
|
|
</div>
|
|
</x-filament::section>
|
|
@elseif($gestioneTipoSelected === 'riscaldamento')
|
|
@php($tabs = $this->getTabelleMillesimaliByTipo('riscaldamento'))
|
|
|
|
<x-filament::section>
|
|
<x-slot name="heading">Tabelle (Riscaldamento)</x-slot>
|
|
|
|
<div class="space-y-3">
|
|
@forelse($tabs as $t)
|
|
@php($voci = $this->getVociSpesaByTabellaMillesimale((int) ($t['id'] ?? 0)))
|
|
<div class="rounded-lg border border-gray-200 dark:border-gray-800">
|
|
<div class="px-3 py-2 text-sm font-semibold text-gray-900 dark:text-gray-100">
|
|
{{ $t['label'] ?? ('Tabella #' . ($t['id'] ?? '')) }}
|
|
</div>
|
|
<div class="border-t border-gray-200 dark:border-gray-800">
|
|
<ul class="divide-y text-sm">
|
|
@forelse($voci as $v)
|
|
<li class="px-3 py-2 text-gray-900 dark:text-gray-100">{{ $v['label'] ?? ('Voce #' . ($v['id'] ?? '')) }}</li>
|
|
@empty
|
|
<li class="px-3 py-2 text-gray-500">Nessuna voce collegata a questa tabella.</li>
|
|
@endforelse
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
@empty
|
|
<div class="text-sm text-gray-500">Nessuna tabella riscaldamento trovata.</div>
|
|
@endforelse
|
|
</div>
|
|
</x-filament::section>
|
|
@elseif($gestioneTipoSelected === 'straordinaria')
|
|
@php($straTabs = $this->getStraordinarieLegacyTabelleList())
|
|
|
|
<x-filament::section>
|
|
<x-slot name="heading">Tabelle (Straordinarie)</x-slot>
|
|
|
|
<div class="space-y-3">
|
|
@forelse($straTabs as $s)
|
|
@php($nStra = (int) ($s['n_stra'] ?? 0))
|
|
@php($voci = $nStra > 0 ? $this->getVociSpesaByNumeroStraordinaria($nStra) : [])
|
|
|
|
<div class="rounded-lg border border-gray-200 dark:border-gray-800">
|
|
<div class="px-3 py-2 text-sm font-semibold text-gray-900 dark:text-gray-100">
|
|
{{ $s['titolo'] ?? ('Straordinaria #' . $nStra) }}
|
|
</div>
|
|
<div class="border-t border-gray-200 dark:border-gray-800">
|
|
<ul class="divide-y text-sm">
|
|
@forelse($voci as $v)
|
|
<li class="px-3 py-2 text-gray-900 dark:text-gray-100">{{ $v['label'] ?? ('Voce #' . ($v['id'] ?? '')) }}</li>
|
|
@empty
|
|
<li class="px-3 py-2 text-gray-500">Nessuna voce collegata a questa straordinaria.</li>
|
|
@endforelse
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
@empty
|
|
<div class="text-sm text-gray-500">Nessuna tabella straordinaria trovata (gescon_import.straordinarie).</div>
|
|
@endforelse
|
|
</div>
|
|
</x-filament::section>
|
|
@endif
|
|
|
|
@php($fornitoreOverview = $this->getFornitoreOverview())
|
|
@if($fornitoreOverview)
|
|
<x-filament::section>
|
|
<x-slot name="heading">Fornitore (saldo)</x-slot>
|
|
|
|
<div class="space-y-3">
|
|
<div class="grid grid-cols-1 gap-2">
|
|
<div class="rounded-lg border bg-gray-50 p-3">
|
|
<div class="text-xs text-gray-500">Aperto (netto)</div>
|
|
<div class="mt-1 text-lg font-semibold">€ {{ number_format((float) ($fornitoreOverview['aperto_netto'] ?? 0), 2, ',', '.') }}</div>
|
|
</div>
|
|
<div class="grid grid-cols-2 gap-2">
|
|
<div class="rounded-lg border bg-gray-50 p-3">
|
|
<div class="text-xs text-gray-500">Totale (netto)</div>
|
|
<div class="mt-1 text-sm font-semibold">€ {{ number_format((float) ($fornitoreOverview['tot_netto'] ?? 0), 2, ',', '.') }}</div>
|
|
</div>
|
|
<div class="rounded-lg border bg-gray-50 p-3">
|
|
<div class="text-xs text-gray-500">Pagato (netto)</div>
|
|
<div class="mt-1 text-sm font-semibold">€ {{ number_format((float) ($fornitoreOverview['pagato_netto'] ?? 0), 2, ',', '.') }}</div>
|
|
</div>
|
|
</div>
|
|
@if(!empty($fornitoreOverview['ultima_data_documento']))
|
|
<div class="text-xs text-gray-500">Ultima fattura: <span class="font-semibold text-gray-700">{{ $fornitoreOverview['ultima_data_documento'] }}</span></div>
|
|
@endif
|
|
</div>
|
|
|
|
@if(!empty($fornitoreOverview['ultime_note']) && is_array($fornitoreOverview['ultime_note']))
|
|
<div>
|
|
<div class="text-xs text-gray-500 mb-1">Note recenti</div>
|
|
<div class="space-y-2">
|
|
@foreach($fornitoreOverview['ultime_note'] as $n)
|
|
<div class="rounded-lg border bg-gray-50 p-2">
|
|
<div class="text-xs text-gray-500">
|
|
#{{ $n['id'] ?? '—' }}
|
|
@if(!empty($n['data_documento']))
|
|
· {{ $n['data_documento'] }}
|
|
@endif
|
|
</div>
|
|
<div class="text-sm font-medium text-gray-800">{{ $n['note'] ?? '' }}</div>
|
|
</div>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
</x-filament::section>
|
|
@endif
|
|
|
|
@php($suggerimentiVoci = $this->getSuggerimentiVociSpesa())
|
|
@if(count($suggerimentiVoci) > 0)
|
|
<x-filament::section>
|
|
<x-slot name="heading">Voci spesa consigliate (ARERA)</x-slot>
|
|
|
|
<div class="space-y-2">
|
|
<p class="text-xs text-gray-500">Seleziona una voce per applicarla o aggiungerla alle righe della fattura.</p>
|
|
<div class="flex flex-col gap-2">
|
|
@foreach($suggerimentiVoci as $v)
|
|
<button
|
|
type="button"
|
|
wire:click="applicaVoceSpesaSuggerita({{ (int) $v['id'] }})"
|
|
class="flex items-center justify-between text-left text-xs p-2 rounded border bg-gray-50 dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-700 w-full transition"
|
|
>
|
|
<div class="truncate">
|
|
<span class="font-semibold text-gray-900 dark:text-gray-100">{{ $v['codice'] }}</span>
|
|
<span class="text-gray-600 dark:text-gray-400">— {{ $v['descrizione'] }}</span>
|
|
</div>
|
|
@if($v['is_default'])
|
|
<span class="ml-2 inline-flex items-center rounded-full bg-emerald-100 dark:bg-emerald-900/30 px-1.5 py-0.5 text-[9px] font-semibold text-emerald-800 dark:text-emerald-300">Default</span>
|
|
@else
|
|
<x-filament::icon icon="heroicon-m-plus-circle" class="w-4 h-4 text-gray-400" />
|
|
@endif
|
|
</button>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
</x-filament::section>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</x-filament-panels::page>
|
|
|