*/ protected array $emissionStatsCache = []; public function mount(): void { $this->mountInteractsWithTable(); } protected function getTableQuery(): Builder { $user = Auth::user(); if (! $user instanceof User) { return RateEmissione::query()->whereRaw('1 = 0'); } $stabile = StabileContext::getActiveStabile($user); $codStabile = $stabile?->codice_stabile ?? $stabile?->cod_stabile; if (! $codStabile) { return RateEmissione::query()->whereRaw('1 = 0'); } return RateEmissione::query() ->where('cod_stabile', (string) $codStabile) ->orderBy('numero_emissione') ->orderBy('data_emissione'); } public function table(Table $table): Table { return $table ->striped() ->paginated() ->paginationPageOptions([10, 25, 50, 100]) ->defaultPaginationPageOption(10) ->recordUrl(function (RateEmissione $record): string { return RateEmesseArchivio::getUrl( panel: 'admin-filament', parameters: [ 'tab' => 'dettaglio', 'emissione_gen' => $record->id, ], ); }) ->filters([ SelectFilter::make('anno_emissione') ->label('Gestione') ->options(function (): array { $user = Auth::user(); if (! $user instanceof User) { return []; } $stabile = StabileContext::getActiveStabile($user); $codStabile = $stabile?->codice_stabile ?? $stabile?->cod_stabile; if (! $codStabile) { return []; } return RateEmissione::query() ->where('cod_stabile', (string) $codStabile) ->whereNotNull('anno_emissione') ->select('anno_emissione') ->distinct() ->orderByDesc('anno_emissione') ->pluck('anno_emissione', 'anno_emissione') ->all(); }) ->query(function (Builder $query, array $data): Builder { $anno = $data['value'] ?? null; if (blank($anno)) { return $query; } return $query->where('anno_emissione', (string) $anno); }), ]) ->columns([ TextColumn::make('data_emissione') ->label('Emissione') ->date('d/m/Y') ->url(function (RateEmissione $record): string { return RateEmesseArchivio::getUrl( panel: 'admin-filament', parameters: [ 'tab' => 'dettaglio', 'emissione_gen' => $record->id, ], ); }) ->sortable(), TextColumn::make('data_scadenza') ->label('Scadenza') ->date('d/m/Y') ->sortable(), TextColumn::make('numero_emissione') ->label('N. Emissione') ->sortable(), TextColumn::make('anno_emissione') ->label('Gestione') ->sortable(), TextColumn::make('descrizione') ->label('Descrizione') ->wrap() ->searchable(), TextColumn::make('numero_rate') ->label('N. rate') ->alignRight() ->state(function (RateEmissione $record): int { $n = (int) ($record->numero_rate ?? 0); return $n > 0 ? $n : $this->getEmissionStats($record)['count']; }), TextColumn::make('totale_rate') ->label('Totale') ->alignRight() ->money('EUR', locale: 'it') ->state(fn(RateEmissione $record): float => $this->getEmissionStats($record)['total']), TextColumn::make('gestione_tipo') ->label('Gestione') ->toggleable(isToggledHiddenByDefault: true), TextColumn::make('gestione_periodo') ->label('Periodo') ->wrap() ->toggleable(isToggledHiddenByDefault: true), ]) ->defaultSort('numero_emissione', 'asc'); } /** * Statistiche su righe rate NG (rate_emesse) collegate all'emissione tramite (data_emissione, data_scadenza). * Cache per evitare doppie query durante il rendering delle colonne. * * @return array{count:int, total:float} */ protected function getEmissionStats(RateEmissione $record): array { $id = (int) $record->getKey(); if (isset($this->emissionStatsCache[$id])) { return $this->emissionStatsCache[$id]; } $user = Auth::user(); if (! $user instanceof User) { return $this->emissionStatsCache[$id] = ['count' => 0, 'total' => 0.0]; } $activeStabileId = StabileContext::resolveActiveStabileId($user); if (! $activeStabileId) { return $this->emissionStatsCache[$id] = ['count' => 0, 'total' => 0.0]; } $q = RataEmessaNg::query() ->whereHas('pianoRateizzazione', fn(Builder $sub) => $sub->where('stabile_id', (int) $activeStabileId)); // Preferisci match per numero emissione e anno (tracciati nelle note durante import EMES_DET). // Le date possono coincidere tra emissioni diverse. $numeroEmissione = (int) ($record->numero_emissione ?? 0); if ($numeroEmissione > 0) { $q->whereRaw( "SUBSTRING_INDEX(SUBSTRING_INDEX(note, 'n_emissione=', -1), '|', 1) = ?", [(string) $numeroEmissione] ); $anno = trim((string) ($record->anno_emissione ?? '')); if ($anno !== '') { $q->whereRaw( "SUBSTRING_INDEX(SUBSTRING_INDEX(note, 'anno_emissione=', -1), '|', 1) = ?", [$anno] ); } } else { if ($record->data_emissione) { $q->whereDate('data_emissione', $record->data_emissione); } if ($record->data_scadenza) { $q->whereDate('data_scadenza', $record->data_scadenza); } } $row = $q ->selectRaw('COUNT(*) AS c, COALESCE(SUM(importo_addebitato_soggetto), 0) AS t') ->first(); return $this->emissionStatsCache[$id] = [ 'count' => (int) ($row?->c ?? 0), 'total' => (float) ($row?->t ?? 0), ]; } public function render() { return view('filament.pages.contabilita.components.rate-emesse-emissioni-table'); } public function makeFilamentTranslatableContentDriver(): ?TranslatableContentDriver { return null; } }