*/ public array $debiti = []; /** @var array */ public array $movimenti = []; /** @var array */ public array $debitiStorici = []; public float $totaleDebitiStorici = 0.0; public static function canAccess(): bool { $user = Auth::user(); if (! $user instanceof User) { return false; } if ($user->hasAnyRole(['super-admin', 'admin'])) { return true; } return $user->can('contabilita.prima-nota') || $user->can('contabilita.fatture-fornitori'); } public function getActiveStabile(): ?Stabile { $user = Auth::user(); if (! $user instanceof User) { return null; } return StabileContext::getActiveStabile($user); } public function mount(): void { $stabile = $this->getActiveStabile(); if ($stabile) { $gestioneId = $this->resolveActiveGestioneId((int) $stabile->id); if ($gestioneId) { $gestione = DB::table('gestioni_contabili')->where('id', $gestioneId)->first(); if ($gestione && $gestione->data_fine) { $this->targetDate = $gestione->data_fine; } } } if (! $this->targetDate) { $this->targetDate = now()->format('Y-12-31'); } $this->loadTabContent(); } public function setTab(string $tab): void { $this->activeTab = $tab; $this->loadTabContent(); } public function updatedTargetDate(): void { $this->loadTabContent(); } public function loadTabContent(): void { if ($this->activeTab === 'debiti') { $this->loadDebiti(); } elseif ($this->activeTab === 'movimenti') { $this->loadMovimenti(); } elseif ($this->activeTab === 'stato_debiti') { $this->loadDebitiStorici(); } } public function loadDebiti(): void { $user = Auth::user(); if (! $user instanceof User) { return; } $stabileId = StabileContext::resolveActiveStabileId($user); if (! $stabileId || ! Schema::hasTable('contabilita_fatture_fornitori')) { $this->debiti = []; return; } $select = [ 'f.id', 'f.numero_documento', 'f.data_documento', 'f.totale', 'f.netto_da_pagare', 'f.stato', 'f.fornitore_id', 'f.fattura_elettronica_id', ]; $query = DB::table('contabilita_fatture_fornitori as f') ->where('f.stabile_id', $stabileId) ->where(function ($q) { $q->where('f.stato', '!=', 'pagato') ->orWhereNull('f.stato'); }); if (Schema::hasTable('fornitori')) { $query->leftJoin('fornitori as forn', 'forn.id', '=', 'f.fornitore_id'); $select[] = 'forn.ragione_sociale as fornitore_ragione_sociale'; $select[] = 'forn.iban as fornitore_iban'; } if (Schema::hasTable('fatture_elettroniche')) { $query->leftJoin('fatture_elettroniche as fe', 'fe.id', '=', 'f.fattura_elettronica_id'); $select[] = 'fe.pagamento_iban as fe_pagamento_iban'; } $dbRows = $query->select($select) ->orderBy('f.data_documento') ->orderBy('f.id') ->get(); $this->debiti = []; foreach ($dbRows as $row) { $iban = null; if (isset($row->fe_pagamento_iban) && $row->fe_pagamento_iban) { $iban = $row->fe_pagamento_iban; } if (! $iban && isset($row->fornitore_iban)) { $iban = $row->fornitore_iban; } $id = (int) $row->id; $fornitoreName = $row->fornitore_ragione_sociale ?? 'Fornitore Sconosciuto'; $numDoc = $row->numero_documento ?? 'N/D'; $prefix = "FAT-ID:{$id} "; $suffix = " N.{$numDoc}"; $avail = 140 - strlen($prefix) - strlen($suffix); $cleanName = substr($fornitoreName, 0, max(0, $avail)); $descrizione = $prefix . $cleanName . $suffix; $this->debiti[] = [ 'id' => $id, 'numero_documento' => $numDoc, 'data_documento' => $row->data_documento ? Carbon::parse($row->data_documento)->format('d/m/Y') : '—', 'totale' => (float) $row->totale, 'netto_da_pagare' => (float) ($row->netto_da_pagare ?? $row->totale), 'fornitore_ragione_sociale' => $fornitoreName, 'iban' => $iban ? strtoupper(str_replace(' ', '', $iban)) : null, 'descrizione_bonifico' => $descrizione, ]; } } public function loadMovimenti(): void { $user = Auth::user(); if (! $user instanceof User) { return; } $stabileId = StabileContext::resolveActiveStabileId($user); if (! $stabileId || ! Schema::hasTable('contabilita_movimenti_banca')) { $this->movimenti = []; return; } $query = DB::table('contabilita_movimenti_banca as m') ->where('m.stabile_id', $stabileId); if (Schema::hasTable('contabilita_fatture_fornitori')) { $query->leftJoin('contabilita_fatture_fornitori as f', 'f.movimento_pagamento_id', '=', 'm.id'); } if (Schema::hasTable('fornitori')) { $query->leftJoin('fornitori as forn', 'forn.id', '=', 'm.fornitore_id'); } $select = [ 'm.id', 'm.data', 'm.descrizione', 'm.descrizione_estesa', 'm.importo', 'm.registrazione_id', 'm.causale', ]; if (Schema::hasTable('contabilita_fatture_fornitori')) { $select[] = 'f.id as invoice_id'; $select[] = 'f.numero_documento as invoice_number'; } if (Schema::hasTable('fornitori')) { $select[] = 'forn.ragione_sociale as fornitore_ragione_sociale'; } $rows = $query->select($select) ->orderByDesc('m.data') ->orderByDesc('m.id') ->get(); $this->movimenti = []; foreach ($rows as $r) { $invId = isset($r->invoice_id) ? $r->invoice_id : null; $invNum = isset($r->invoice_number) ? $r->invoice_number : null; $forn = isset($r->fornitore_ragione_sociale) ? $r->fornitore_ragione_sociale : null; $isReconciled = ! empty($r->registrazione_id) || ! empty($invId); $advice = ''; if (! $isReconciled) { if ((float) $r->importo < 0) { if (in_array((string) $r->causale, ['198', '219', '048', '208'], true)) { $advice = 'Spesa bancaria diretta. Configura la regola interbancaria per registrarla in prima nota.'; } else { $advice = 'Uscita bancaria. Registra la fattura fornitore corrispondente o riconcilia manualmente.'; } } else { $advice = 'Entrata/Incasso rate. Riconcilia con le rate o gli incassi del condominio.'; } } $this->movimenti[] = [ 'id' => (int) $r->id, 'data' => $r->data ? Carbon::parse($r->data)->format('d/m/Y') : '—', 'descrizione' => $r->descrizione ?: 'Movimento banca', 'importo' => (float) $r->importo, 'stato' => $isReconciled ? 'quadrato' : 'da_quadrare', 'invoice_id' => $invId, 'invoice_number' => $invNum, 'fornitore' => $forn, 'advice' => $advice, ]; } } public function loadDebitiStorici(): void { $user = Auth::user(); if (! $user instanceof User) { return; } $stabileId = StabileContext::resolveActiveStabileId($user); if (! $stabileId || ! Schema::hasTable('contabilita_fatture_fornitori') || ! $this->targetDate) { $this->debitiStorici = []; $this->totaleDebitiStorici = 0.0; return; } $query = DB::table('contabilita_fatture_fornitori as f') ->where('f.stabile_id', $stabileId) ->where('f.data_documento', '<=', $this->targetDate) ->where(function ($q) { $q->where('f.stato', '!=', 'pagato') ->orWhereNull('f.stato') ->orWhereNull('f.data_pagamento') ->orWhere('f.data_pagamento', '>', $this->targetDate); }); if (Schema::hasTable('fornitori')) { $query->leftJoin('fornitori as forn', 'forn.id', '=', 'f.fornitore_id'); } $select = [ 'f.id', 'f.numero_documento', 'f.data_documento', 'f.totale', 'f.netto_da_pagare', 'f.stato', 'f.data_pagamento', ]; if (Schema::hasTable('fornitori')) { $select[] = 'forn.ragione_sociale as fornitore_ragione_sociale'; } $rows = $query->select($select) ->orderBy('f.data_documento') ->orderBy('f.id') ->get(); $this->debitiStorici = []; $this->totaleDebitiStorici = 0.0; foreach ($rows as $row) { $tot = (float) $row->totale; $due = (float) ($row->netto_da_pagare ?? $row->totale); $this->totaleDebitiStorici += $due; $chiusoAl = 'Ancora aperto'; if ($row->stato === 'pagato' && $row->data_pagamento) { $chiusoAl = Carbon::parse($row->data_pagamento)->format('d/m/Y'); } $this->debitiStorici[] = [ 'id' => (int) $row->id, 'numero_documento' => $row->numero_documento ?? 'N/D', 'data_documento' => $row->data_documento ? Carbon::parse($row->data_documento)->format('d/m/Y') : '—', 'totale' => $tot, 'netto_da_pagare' => $due, 'fornitore' => $row->fornitore_ragione_sociale ?? 'Fornitore Sconosciuto', 'stato_corrente' => $row->stato ?? 'N/D', 'data_chiusura' => $chiusoAl, ]; } } private function resolveActiveGestioneId(int $stabileId): ?int { $anno = \App\Support\AnnoGestioneContext::resolveActiveAnno(); $tipo = \App\Support\GestioneContext::resolveActiveGestione(); $match = DB::table('gestioni_contabili') ->where('stabile_id', $stabileId) ->where('anno_gestione', $anno) ->where('tipo_gestione', $tipo) ->where('stato', 'aperta') ->orderByDesc('gestione_attiva') ->orderByDesc('id') ->first(); if (! $match) { $match = DB::table('gestioni_contabili') ->where('stabile_id', $stabileId) ->where('stato', 'aperta') ->orderByDesc('gestione_attiva') ->orderByDesc('id') ->first(); } return $match ? (int) $match->id : null; } }