netgescon-day0/app/Filament/Pages/Fiscale/FiscaleDashboard.php

178 lines
6.7 KiB
PHP

<?php
namespace App\Filament\Pages\Fiscale;
use App\Filament\Pages\Contabilita\RegistroRitenuteAccontoArchivio;
use App\Models\AdempimentoFiscale;
use App\Models\RegistroRitenuteAcconto;
use App\Models\Stabile;
use App\Models\User;
use App\Support\StabileContext;
use BackedEnum;
use Filament\Pages\Page;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use UnitEnum;
class FiscaleDashboard extends Page
{
protected static ?string $navigationLabel = 'Cruscotto Fiscale';
protected static ?string $title = 'Cruscotto fiscale';
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-receipt-percent';
protected static UnitEnum|string|null $navigationGroup = 'Fiscale';
protected static ?int $navigationSort = 1;
protected static ?string $slug = 'fiscale/cruscotto';
protected string $view = 'filament.pages.fiscale.cruscotto';
public ?Stabile $stabileAttivo = null;
public int $annoFiscale;
public array $summary = [];
public Collection $adempimentiInScadenza;
public array $templates = [];
public static function canAccess(): bool
{
$user = Auth::user();
if (! $user instanceof User) {
return false;
}
if ($user->hasAnyRole(['super-admin', 'admin'])) {
return true;
}
return $user->hasAnyRole(['amministratore', 'collaboratore']);
}
public function mount(): void
{
$this->annoFiscale = (int) now()->format('Y');
$this->adempimentiInScadenza = collect();
$user = Auth::user();
if (! $user instanceof User) {
return;
}
$activeId = StabileContext::resolveActiveStabileId($user);
if (! $activeId) {
$this->stabileAttivo = null;
$this->summary = $this->emptySummary();
$this->templates = $this->defaultTemplates();
return;
}
$this->stabileAttivo = StabileContext::accessibleStabili($user)->firstWhere('id', $activeId);
$this->summary = $this->buildSummary($activeId, $this->annoFiscale);
$this->adempimentiInScadenza = AdempimentoFiscale::query()
->where('stabile_id', $activeId)
->orderByRaw('CASE WHEN scadenza IS NULL THEN 1 ELSE 0 END')
->orderBy('scadenza')
->limit(12)
->get();
$this->templates = $this->defaultTemplates();
}
public static function getRegistroRaUrl(): string
{
return RegistroRitenuteAccontoArchivio::getUrl(panel: 'admin-filament');
}
protected function emptySummary(): array
{
return [
'ritenute_count' => 0,
'ritenute_da_versare' => 0,
'detrazioni_count' => 0,
'straordinarie_fiscali' => 0,
'adempimenti_count' => 0,
'adempimenti_aperti' => 0,
];
}
protected function buildSummary(int $stabileId, int $annoFiscale): array
{
$summary = $this->emptySummary();
$summary['ritenute_count'] = RegistroRitenuteAcconto::query()
->whereHas('gestione', fn($q) => $q->where('stabile_id', $stabileId))
->where('anno_dichiarazione', $annoFiscale)
->count();
$summary['ritenute_da_versare'] = RegistroRitenuteAcconto::query()
->whereHas('gestione', fn($q) => $q->where('stabile_id', $stabileId))
->where('anno_dichiarazione', $annoFiscale)
->whereIn('stato_versamento', ['da_versare', 'scaduto', 'ritardo'])
->count();
if (Schema::hasTable('detrazioni_fiscali_dom')) {
$summary['detrazioni_count'] = DB::table('detrazioni_fiscali_dom as dfd')
->leftJoin('gestioni_contabili as gc', 'gc.id', '=', 'dfd.gestione_id')
->where(function ($q) use ($stabileId): void {
$q->where('gc.stabile_id', $stabileId);
if (Schema::hasColumn('detrazioni_fiscali_dom', 'stabile_id')) {
$q->orWhere('dfd.stabile_id', $stabileId);
}
})
->where(function ($q) use ($annoFiscale): void {
$q->whereYear('dfd.created_at', $annoFiscale);
if (Schema::hasColumn('detrazioni_fiscali_dom', 'anno_fiscale')) {
$q->orWhere('dfd.anno_fiscale', $annoFiscale);
}
if (Schema::hasColumn('detrazioni_fiscali_dom', 'legacy_rif')) {
$q->orWhere('dfd.legacy_rif', 'like', $annoFiscale . '%');
}
})
->count();
}
if (Schema::hasTable('lavori_straordinari')) {
$summary['straordinarie_fiscali'] = DB::table('lavori_straordinari as ls')
->join('gestioni_contabili as gc', 'gc.id', '=', 'ls.gestione_id')
->where('gc.stabile_id', $stabileId)
->where('gc.anno_gestione', $annoFiscale)
->whereNotNull('ls.gestione_id')
->where('ls.note_json', 'like', '%"is_fiscal_declaration":true%')
->count();
}
$summary['adempimenti_count'] = AdempimentoFiscale::query()
->where('stabile_id', $stabileId)
->count();
$summary['adempimenti_aperti'] = AdempimentoFiscale::query()
->where('stabile_id', $stabileId)
->whereNotIn('stato', ['completato', 'annullato'])
->count();
return $summary;
}
protected function defaultTemplates(): array
{
return [
['tipo' => 'ritenuta_acconto', 'titolo' => 'Ritenute d\'acconto', 'descrizione' => 'Versamenti, F24, CU e quadratura come sostituto d\'imposta.'],
['tipo' => 'certificazione_detrazione', 'titolo' => 'Certificazioni detrazioni fiscali', 'descrizione' => 'Invio certificazioni e archivio documentale per lavori agevolati.'],
['tipo' => 'quadro_ac', 'titolo' => 'Quadro AC amministratore', 'descrizione' => 'Raccolta dati e controllo annuale dei fornitori e compensi rilevanti.'],
['tipo' => 'dichiarazione_770', 'titolo' => 'Modello 770', 'descrizione' => 'Preparazione dichiarazione, quadratura ritenute e storico invii.'],
['tipo' => 'rendita_condominiale', 'titolo' => 'Rendite condominiali e affitti', 'descrizione' => 'Monitoraggio rendite, contratti, certificazioni e imponibili collegati.'],
['tipo' => 'compenso_amministratore', 'titolo' => 'Compensi amministratore', 'descrizione' => 'Preventivo, rinnovi annuali e voci addebitabili per servizi e pratiche.'],
];
}
}