209 lines
8.6 KiB
PHP
209 lines
8.6 KiB
PHP
<?php
|
|
namespace App\Filament\Pages\Gescon;
|
|
|
|
use App\Models\Stabile;
|
|
use App\Models\TabellaMillesimale;
|
|
use App\Support\StabileContext;
|
|
use BackedEnum;
|
|
use Filament\Pages\Page;
|
|
use Illuminate\Support\Facades\Auth;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use UnitEnum;
|
|
|
|
/**
|
|
* Classe AuditQuadraturePage
|
|
* Espone in-line esclusivamente gli errori e le discrepanze rilevate nel confronto tra il legacy e NetGescon.
|
|
*/
|
|
class AuditQuadraturePage extends Page
|
|
{
|
|
protected static ?string $navigationLabel = 'Audit e Revisione';
|
|
|
|
protected static ?string $title = 'Audit e Revisione';
|
|
|
|
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-shield-check';
|
|
|
|
protected static UnitEnum|string|null $navigationGroup = 'GESCON';
|
|
|
|
protected static ?int $navigationSort = 90;
|
|
|
|
protected static ?string $slug = 'gescon/audit-quadrature';
|
|
|
|
protected string $view = 'filament.pages.gescon.audit-quadrature';
|
|
|
|
/**
|
|
* Ritorna l'elenco deterministico delle discrepanze rilevate tra il database legacy di staging e NetGescon
|
|
*/
|
|
public function getDiscrepanciesProperty(): array
|
|
{
|
|
$user = Auth::user();
|
|
$stabileId = StabileContext::resolveActiveStabileId($user);
|
|
if (!$stabileId) {
|
|
return [
|
|
'has_active_stabile' => false,
|
|
'missing_units' => [],
|
|
'tabelle_sbilanciate' => [],
|
|
'discrepanze_assemblee' => [],
|
|
];
|
|
}
|
|
|
|
$stabile = Stabile::find($stabileId);
|
|
$stabileCode = $stabile?->codice_stabile;
|
|
|
|
// 1. Audit delle Unità Mancanti 1:1
|
|
$missingUnits = [];
|
|
if ($stabileCode && Schema::connection('gescon_import')->hasTable('condomin')) {
|
|
$legacyUnits = DB::connection('gescon_import')->table('condomin')
|
|
->where('cod_stabile', $stabileCode)
|
|
->get(['cod_cond', 'interno', 'scala', 'cognome', 'nome']);
|
|
|
|
foreach ($legacyUnits as $lu) {
|
|
$exists = DB::table('unita_immobiliari')
|
|
->where('stabile_id', $stabileId)
|
|
->where('legacy_cond_id', $lu->cod_cond)
|
|
->exists();
|
|
|
|
if (!$exists) {
|
|
$missingUnits[] = [
|
|
'cod_cond' => $lu->cod_cond,
|
|
'nominativo' => trim(($lu->nome ?? '') . ' ' . ($lu->cognome ?? '')) ?: 'N/D',
|
|
'scala' => $lu->scala ?: 'N/D',
|
|
'interno' => $lu->interno ?: 'N/D',
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
// 2. Sbilanciamento millesimale delle tabelle
|
|
$tabelleSbilanciate = [];
|
|
$tabelle = TabellaMillesimale::where('stabile_id', $stabileId)->get();
|
|
foreach ($tabelle as $t) {
|
|
$sommaMillesimi = DB::table('dettaglio_millesimi')
|
|
->where('tabella_millesimale_id', $t->id)
|
|
->sum('millesimi');
|
|
|
|
$expected = (float) $t->totale_millesimi;
|
|
if (abs($sommaMillesimi - $expected) > 0.01) {
|
|
$legacyYear = $t->meta_legacy['legacy_year'] ?? null;
|
|
$totMmLegacy = null;
|
|
if ($stabileCode && $legacyYear && Schema::connection('gescon_import')->hasTable('tabelle_millesimali')) {
|
|
$totMmLegacyRaw = DB::connection('gescon_import')->table('tabelle_millesimali')
|
|
->where('cod_stabile', $stabileCode)
|
|
->where('legacy_year', $legacyYear)
|
|
->where('codice_tabella', $t->codice_tabella)
|
|
->value('totale_millesimi');
|
|
|
|
if ($totMmLegacyRaw > 9999) {
|
|
$totMmLegacy = $totMmLegacyRaw / 10000.0;
|
|
} else {
|
|
$totMmLegacy = $totMmLegacyRaw;
|
|
}
|
|
}
|
|
|
|
$tabelleSbilanciate[] = [
|
|
'codice' => $t->codice_tabella,
|
|
'denominazione' => $t->denominazione,
|
|
'anno_gestione' => $t->anno_gestione ?? ($t->meta_legacy['legacy_year'] ?? 'N/D'),
|
|
'somma_reale' => $sommaMillesimi,
|
|
'atteso_db' => $expected,
|
|
'atteso_legacy' => $totMmLegacy ?: $expected,
|
|
'differenza' => abs($sommaMillesimi - $expected),
|
|
];
|
|
}
|
|
}
|
|
|
|
// 3. Discrepanze sul calcolo delle teste e dei millesimi presenti nell'assemblea
|
|
$discrepanzeAssemblee = [];
|
|
if ($stabileCode && Schema::connection('gescon_import')->hasTable('pres_assemblee')) {
|
|
$legacyPresRows = DB::connection('gescon_import')->table('pres_assemblee')
|
|
->where('cod_stabile', $stabileCode)
|
|
->get();
|
|
|
|
$tabAId = DB::table('tabelle_millesimali')
|
|
->where('stabile_id', $stabileId)
|
|
->where('codice_tabella', 'TAB.A')
|
|
->value('id');
|
|
|
|
foreach ($legacyPresRows as $pr) {
|
|
$idCond = $pr->id_condomino ?? null;
|
|
$millesimiLegacy = (float) ($pr->millesimi ?? 0);
|
|
|
|
$unit = DB::table('unita_immobiliari')
|
|
->where('stabile_id', $stabileId)
|
|
->where('legacy_cond_id', $idCond)
|
|
->first();
|
|
|
|
if (!$unit) {
|
|
continue;
|
|
}
|
|
|
|
$unitMillesimi = 0.0;
|
|
if ($tabAId) {
|
|
$unitMillesimi = (float) DB::table('dettaglio_millesimi')
|
|
->where('tabella_millesimale_id', $tabAId)
|
|
->where('unita_immobiliare_id', $unit->id)
|
|
->value('millesimi');
|
|
}
|
|
|
|
if (abs($unitMillesimi - $millesimiLegacy) > 0.01) {
|
|
$discrepanzeAssemblee[] = [
|
|
'anno' => $pr->legacy_year ?? 'N/D',
|
|
'assemblea' => $pr->num_assemblea ?? 'N/D',
|
|
'unita' => $unit->codice_unita ?: $unit->id,
|
|
'legacy_cond_id' => $idCond,
|
|
'millesimi_db' => $unitMillesimi,
|
|
'millesimi_legacy' => $millesimiLegacy,
|
|
'p_d_a' => $pr->p_d_a ?? 'N/D',
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
// 4. Audit delle Anomalie Anagrafiche e dei Record Orfani
|
|
$anagraficheAnomale = [];
|
|
if ($stabileCode && Schema::connection('gescon_import')->hasTable('condomin')) {
|
|
$condominRows = DB::connection('gescon_import')->table('condomin')
|
|
->where('cod_stabile', $stabileCode)
|
|
->get();
|
|
|
|
foreach ($condominRows as $cr) {
|
|
$cf = trim($cr->cond_cod_fisc ?? $cr->codice_fiscale ?? '');
|
|
$nome = trim(($cr->nome ?? '') . ' ' . ($cr->cognome ?? ''));
|
|
|
|
if (empty($cf) && !empty($nome)) {
|
|
$anagraficheAnomale[] = [
|
|
'tipo' => 'Codice Fiscale Mancante',
|
|
'dettaglio' => "Unità Int. {$cr->interno} (Scala {$cr->scala}) - Nominativo: {$nome}",
|
|
'istruzioni' => "CRITICO: Inserire il Codice Fiscale valido negli archivi legacy."
|
|
];
|
|
}
|
|
|
|
if ($cr->cod_cond) {
|
|
$hasPeriodo = DB::table('unita_anagrafica_periodo as uap')
|
|
->join('unita_immobiliari as ui', 'ui.id', '=', 'uap.unita_immobiliare_id')
|
|
->where('ui.stabile_id', $stabileId)
|
|
->where('ui.legacy_cond_id', $cr->cod_cond)
|
|
->exists();
|
|
|
|
if (!$hasPeriodo && !empty($nome)) {
|
|
$anagraficheAnomale[] = [
|
|
'tipo' => 'Associazione Timeline Mancante',
|
|
'dettaglio' => "Nominativo: {$nome} (Cod. Cond: {$cr->cod_cond}) - Unità Int. {$cr->interno} (Scala {$cr->scala})",
|
|
'istruzioni' => "CRITICO: Periodo di occupazione mancante. Creare manualmente la relazione timeline per evitare errori di quadratura contabile."
|
|
];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return [
|
|
'has_active_stabile' => true,
|
|
'stabile_nome' => $stabile?->denominazione,
|
|
'missing_units' => $missingUnits,
|
|
'tabelle_sbilanciate' => $tabelleSbilanciate,
|
|
'discrepanze_assemblee' => array_slice($discrepanzeAssemblee, 0, 100),
|
|
'anagrafiche_anomale' => $anagraficheAnomale,
|
|
];
|
|
}
|
|
}
|