hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore']); } public function mount(): void { $this->mountInteractsWithTable(); } protected function getTableQuery(): Builder { $user = Auth::user(); if (! $user instanceof User) { return UnitaImmobiliare::query()->whereRaw('1 = 0'); } $activeStabileId = StabileContext::resolveActiveStabileId($user); if (! $activeStabileId) { return UnitaImmobiliare::query()->whereRaw('1 = 0'); } $today = now()->toDateString(); $rubricaNameSubquery = "(\n" . " SELECT MIN(\n" . " CASE\n" . " WHEN ru.tipo_contatto = 'persona_giuridica' THEN ru.ragione_sociale\n" . " ELSE CONCAT_WS(' ', ru.nome, ru.cognome)\n" . " END\n" . " )\n" . " FROM rubrica_ruoli rr\n" . " JOIN rubrica_universale ru ON ru.id = rr.rubrica_id\n" . " WHERE rr.unita_immobiliare_id = unita_immobiliari.id\n" . " AND rr.is_attivo = 1\n" . " AND (rr.data_inizio IS NULL OR rr.data_inizio <= ?)\n" . " AND (rr.data_fine IS NULL OR rr.data_fine >= ?)\n" . ")"; $nominativoSortExpr = "COALESCE(\n" . " CASE\n" . " WHEN unita_immobiliari.denominazione IS NULL THEN NULL\n" . " WHEN TRIM(unita_immobiliari.denominazione) = '' THEN NULL\n" . " WHEN LOWER(TRIM(unita_immobiliari.denominazione)) = 'area condominiale' THEN NULL\n" . " ELSE unita_immobiliari.denominazione\n" . " END,\n" . " $rubricaNameSubquery,\n" . " unita_immobiliari.codice_unita\n" . ")"; $stabileCols = ['id', 'codice_stabile', 'cod_stabile']; if (DbSchema::hasColumn('stabili', 'codice_operatore')) { $stabileCols[] = 'codice_operatore'; } return UnitaImmobiliare::query() ->where('stabile_id', $activeStabileId) ->with([ 'stabile' => function ($q) use ($stabileCols) { $q->select($stabileCols); }, 'rubricaRuoliAttivi.contatto:id,tipo_contatto,ragione_sociale,nome,cognome,codice_fiscale', 'soggetti:id,nome,cognome,ragione_sociale,codice_fiscale', ]) ->orderBy('palazzina') ->orderBy('scala') ->orderByRaw("CASE WHEN unita_immobiliari.interno IS NULL OR unita_immobiliari.interno = '' THEN 1 ELSE 0 END") ->orderByRaw("CASE WHEN unita_immobiliari.interno REGEXP '^[0-9]+' THEN CAST(unita_immobiliari.interno AS UNSIGNED) ELSE 999999 END") ->orderBy('interno') ->orderBy('id'); } public function getUnitaCount(): int { $user = Auth::user(); if (! $user instanceof User) { return 0; } $activeStabileId = StabileContext::resolveActiveStabileId($user); if (! $activeStabileId) { return 0; } return UnitaImmobiliare::query() ->where('stabile_id', $activeStabileId) ->count(); } public function table(Table $table): Table { $unitaPageUrl = UnitaImmobiliarePage::getUrl(panel: 'admin-filament'); return $table ->striped() ->columns([ TextColumn::make('codice_unita') ->label('Codice') ->searchable() ->sortable() ->formatStateUsing(function ($state, UnitaImmobiliare $record): string { $code = trim((string) ($state ?? '')); if ($code === '') { return '—'; } $legacy = trim((string) ($record->stabile?->codice_stabile ?? '')); $mnemo = trim((string) ($record->stabile?->codice_operatore ?? $record->stabile?->cod_stabile ?? '')); if ($legacy !== '' && $mnemo !== '' && str_starts_with($code, $legacy . '-')) { return $mnemo . substr($code, strlen($legacy)); } return $code; }), TextColumn::make('denominazione') ->label('Soggetti / Nominativi (C o I)') ->html() ->searchable(query: function (Builder $query, string $search): Builder { $s = trim($search); if ($s === '') { return $query; } return $query ->where(function (Builder $q) use ($s): void { $q->where('denominazione', 'like', '%' . $s . '%') ->orWhereHas('rubricaRuoliAttivi.contatto', function (Builder $qq) use ($s): void { $qq->where('ragione_sociale', 'like', '%' . $s . '%') ->orWhere('nome', 'like', '%' . $s . '%') ->orWhere('cognome', 'like', '%' . $s . '%') ->orWhere('codice_fiscale', 'like', '%' . $s . '%'); }) ->orWhereHas('soggetti', function (Builder $qq) use ($s): void { $qq->where('ragione_sociale', 'like', '%' . $s . '%') ->orWhere('cognome', 'like', '%' . $s . '%') ->orWhere('nome', 'like', '%' . $s . '%') ->orWhere('codice_fiscale', 'like', '%' . $s . '%'); }); }); }) ->sortable(query: function (Builder $query, string $direction): Builder { $today = now()->toDateString(); $rubricaNameSubquery = "(\n" . " SELECT MIN(\n" . " CASE\n" . " WHEN ru.tipo_contatto = 'persona_giuridica' THEN ru.ragione_sociale\n" . " ELSE CONCAT_WS(' ', ru.nome, ru.cognome)\n" . " END\n" . " )\n" . " FROM rubrica_ruoli rr\n" . " JOIN rubrica_universale ru ON ru.id = rr.rubrica_id\n" . " WHERE rr.unita_immobiliare_id = unita_immobiliari.id\n" . " AND rr.is_attivo = 1\n" . " AND (rr.data_inizio IS NULL OR rr.data_inizio <= ?)\n" . " AND (rr.data_fine IS NULL OR rr.data_fine >= ?)\n" . ")"; $nominativoSortExpr = "COALESCE(\n" . " CASE\n" . " WHEN unita_immobiliari.denominazione IS NULL THEN NULL\n" . " WHEN TRIM(unita_immobiliari.denominazione) = '' THEN NULL\n" . " WHEN LOWER(TRIM(unita_immobiliari.denominazione)) = 'area condominiale' THEN NULL\n" . " ELSE unita_immobiliari.denominazione\n" . " END,\n" . " $rubricaNameSubquery,\n" . " unita_immobiliari.codice_unita\n" . ")"; return $query->orderByRaw($nominativoSortExpr . ' ' . $direction, [$today, $today]); }) ->state(function (UnitaImmobiliare $record): string { $den = trim((string) ($record->denominazione ?? '')); $isArea = $den !== '' && preg_match('/^\s*area\s+condominiale\s*$/i', $den); if ($isArea) { return 'Area condominiale'; } $condomini = []; $inquilini = []; $altri = []; $ruoli = $record->rubricaRuoliAttivi ?? collect(); foreach ($ruoli as $ruolo) { $nome = $ruolo->contatto?->nome_completo ?? '—'; $cf = $ruolo->contatto?->codice_fiscale ? " ({$ruolo->contatto->codice_fiscale})" : ''; $roleLabel = strtolower(trim((string) $ruolo->ruolo_standard)); if (in_array($roleLabel, ['condomino', 'proprietario', 'comproprietario', 'nudo_proprietario', 'usufruttuario', 'usufrutto'], true)) { $condomini[] = "C" . e($nome) . "" . e($cf); } elseif (in_array($roleLabel, ['inquilino', 'locatario', 'conduttore'], true)) { $inquilini[] = "I" . e($nome) . "" . e($cf); } else { $altri[] = "" . e(ucfirst($ruolo->ruolo_standard ?: 'Soggetto')) . "" . e($nome) . "" . e($cf); } } // Fallback proprietari da soggetti (relazione diretta) if (empty($condomini)) { $soggetti = $record->soggetti ?? collect(); foreach ($soggetti as $s) { $nome = $s->ragione_sociale ?: trim($s->nome . ' ' . $s->cognome); $cf = $s->codice_fiscale ? " ({$s->codice_fiscale})" : ''; if ($nome !== '') { $condomini[] = "C" . e($nome) . "" . e($cf); } } } if ($den !== '' && empty($condomini) && empty($inquilini) && empty($altri)) { return '' . e($den) . ''; } $all = array_merge($condomini, $inquilini, $altri); if (empty($all)) { return '—'; } return '