129 lines
5.2 KiB
PHP
129 lines
5.2 KiB
PHP
<?php
|
|
|
|
namespace App\Filament\Pages\Contabilita;
|
|
|
|
use App\Models\User;
|
|
use App\Support\StabileContext;
|
|
use BackedEnum;
|
|
use Filament\Notifications\Notification;
|
|
use Filament\Pages\Page;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema as DbSchema;
|
|
use UnitEnum;
|
|
|
|
class RiscossioneAggregata extends Page
|
|
{
|
|
protected static ?string $navigationLabel = 'Riscossione (aggregata)';
|
|
|
|
protected static ?string $title = 'Riscossione aggregata';
|
|
|
|
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-document-text';
|
|
|
|
protected static UnitEnum|string|null $navigationGroup = 'Stabile';
|
|
|
|
protected static ?int $navigationSort = 46;
|
|
|
|
protected static ?string $slug = 'contabilita/riscossione-aggregata';
|
|
|
|
protected string $view = 'filament.pages.contabilita.riscossione-aggregata';
|
|
|
|
/** @var array<int, array<string, mixed>> */
|
|
public array $condomini = [];
|
|
|
|
/** @var array<int, array<string, mixed>> */
|
|
public array $inquilini = [];
|
|
|
|
public static function canAccess(): bool
|
|
{
|
|
$user = Auth::user();
|
|
|
|
return $user instanceof User
|
|
&& $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore']);
|
|
}
|
|
|
|
public function mount(): void
|
|
{
|
|
$user = Auth::user();
|
|
if (! $user instanceof User) {
|
|
abort(403);
|
|
}
|
|
|
|
$stabileId = StabileContext::resolveActiveStabileId($user);
|
|
if (! $stabileId) {
|
|
Notification::make()
|
|
->title('Stabile non selezionato')
|
|
->body('Seleziona uno stabile per consultare la riscossione aggregata.')
|
|
->warning()
|
|
->send();
|
|
return;
|
|
}
|
|
|
|
if (! DbSchema::hasTable('rate_emesse')) {
|
|
return;
|
|
}
|
|
|
|
// Foglio riscossione: aggrega per soggetto, mantenendo la distinzione C/I in base alla presenza di un diritto su quella unità.
|
|
$proprietaSub = DB::table('proprieta')
|
|
->selectRaw('unita_immobiliare_id, soggetto_id, MAX(id) as proprieta_match_id')
|
|
->groupBy('unita_immobiliare_id', 'soggetto_id');
|
|
|
|
$rows = DB::table('rate_emesse as r')
|
|
->join('unita_immobiliari as u', 'u.id', '=', 'r.unita_immobiliare_id')
|
|
->join('soggetti as s', 's.id', '=', 'r.soggetto_responsabile_id')
|
|
->leftJoinSub($proprietaSub, 'p', function ($join) {
|
|
$join->on('p.unita_immobiliare_id', '=', 'r.unita_immobiliare_id')
|
|
->on('p.soggetto_id', '=', 'r.soggetto_responsabile_id');
|
|
})
|
|
->where('u.stabile_id', (int) $stabileId)
|
|
->selectRaw('r.soggetto_responsabile_id as soggetto_id')
|
|
// max(p.id) serve solo a derivare il tipo C/I in modo compatibile con ONLY_FULL_GROUP_BY.
|
|
->selectRaw('MAX(p.proprieta_match_id) as proprieta_match_id')
|
|
->selectRaw('MAX(s.ragione_sociale) as ragione_sociale')
|
|
->selectRaw('MAX(s.nome) as nome')
|
|
->selectRaw('MAX(s.cognome) as cognome')
|
|
->selectRaw('MAX(s.codice_fiscale) as codice_fiscale')
|
|
->selectRaw('COUNT(DISTINCT r.numero_rata_progressivo) as n_avvisi')
|
|
->selectRaw('COUNT(*) as n_righe')
|
|
->selectRaw('COUNT(DISTINCT r.unita_immobiliare_id) as n_unita')
|
|
->selectRaw('COALESCE(SUM(r.importo_addebitato_soggetto), 0) as totale_addebitato')
|
|
->selectRaw('COALESCE(SUM(r.importo_pagato), 0) as totale_pagato')
|
|
->groupBy('r.soggetto_responsabile_id')
|
|
->orderByDesc(DB::raw('COALESCE(SUM(r.importo_addebitato_soggetto), 0) - COALESCE(SUM(r.importo_pagato), 0)'))
|
|
->limit(2000)
|
|
->get();
|
|
|
|
$mapped = $rows
|
|
->map(function ($r): array {
|
|
$addebitato = (float) ($r->totale_addebitato ?? 0);
|
|
$pagato = (float) ($r->totale_pagato ?? 0);
|
|
$residuo = $addebitato - $pagato;
|
|
|
|
$ragione = trim((string) ($r->ragione_sociale ?? ''));
|
|
$nome = trim((string) ($r->nome ?? ''));
|
|
$cognome = trim((string) ($r->cognome ?? ''));
|
|
$full = trim($nome . ' ' . $cognome);
|
|
$nominativo = $ragione !== '' ? $ragione : ($full !== '' ? $full : ('Soggetto #' . (int) ($r->soggetto_id ?? 0)));
|
|
|
|
$tipo = empty($r->proprieta_match_id) ? 'I' : 'C';
|
|
|
|
return [
|
|
'tipo' => $tipo,
|
|
'soggetto_id' => (int) ($r->soggetto_id ?? 0),
|
|
'nominativo' => $nominativo !== '' ? $nominativo : '—',
|
|
'codice_fiscale' => (string) ($r->codice_fiscale ?? ''),
|
|
'n_avvisi' => (int) ($r->n_avvisi ?? 0),
|
|
'n_righe' => (int) ($r->n_righe ?? 0),
|
|
'n_unita' => (int) ($r->n_unita ?? 0),
|
|
'totale_addebitato' => $addebitato,
|
|
'totale_pagato' => $pagato,
|
|
'residuo' => $residuo,
|
|
];
|
|
})
|
|
->all();
|
|
|
|
$this->condomini = array_values(array_filter($mapped, fn(array $x) => ($x['tipo'] ?? 'I') === 'C'));
|
|
$this->inquilini = array_values(array_filter($mapped, fn(array $x) => ($x['tipo'] ?? 'I') !== 'C'));
|
|
}
|
|
}
|