> */ public array $fornitori = []; /** @var array> */ public array $stabili = []; /** @var array> */ public array $contattiPrincipali = []; /** @var array> */ public array $ruoliAttivi = []; /** @var array> */ public array $cronistoriaRuoli = []; public int $adminId = 0; public ?int $prevRecordId = null; public ?int $nextRecordId = null; public int $navPerPage = 25; public int $navPage = 1; public int $navPages = 1; /** @var array */ public array $adminStabileIds = []; public function mount(int | string $record): void { $user = Auth::user(); if (! $user instanceof User) { abort(403); } if (! $user->hasAnyRole(['super-admin', 'admin', 'amministratore', 'collaboratore'])) { abort(403); } $this->rubrica = RubricaUniversale::query()->findOrFail((int) $record); $activeStabile = StabileContext::getActiveStabile($user); $adminId = (int) ($activeStabile?->amministratore_id ?: 0); $this->adminId = $adminId; $stabiliAdminIds = []; if (! $user->hasRole('super-admin') && $adminId > 0) { $stabiliAdminIds = Stabile::query() ->where('amministratore_id', $adminId) ->pluck('id') ->map(fn($id) => (int) $id) ->all(); } $this->adminStabileIds = $stabiliAdminIds; $this->initArchivioNavigation(); $this->fornitori = Fornitore::query() ->where('amministratore_id', $adminId) ->where('rubrica_id', (int) $this->rubrica->id) ->orderBy('ragione_sociale') ->limit(50) ->get(['id', 'codice_univoco', 'ragione_sociale', 'partita_iva', 'codice_fiscale']) ->map(fn(Fornitore $f) => [ 'id' => (int) $f->id, 'codice' => (string) ($f->codice_univoco ?? ''), 'nome' => (string) ($f->ragione_sociale ?: trim((string) ($f->cognome ?? '') . ' ' . (string) ($f->nome ?? ''))), 'piva' => (string) ($f->partita_iva ?? ''), 'cf' => (string) ($f->codice_fiscale ?? ''), ]) ->all(); $ruoliQuery = RubricaRuolo::query() ->with(['stabile', 'unitaImmobiliare.stabile']) ->where('rubrica_id', (int) $this->rubrica->id); if (! $user->hasRole('super-admin') && ! empty($stabiliAdminIds)) { $ruoliQuery->where(function ($q) use ($stabiliAdminIds) { $q->whereNull('stabile_id') ->orWhereIn('stabile_id', $stabiliAdminIds); }); } $ruoli = $ruoliQuery ->orderByDesc('is_attivo') ->orderByDesc('is_preferito') ->orderByDesc('data_inizio') ->orderByDesc('id') ->limit(200) ->get(); $labels = self::getRuoliLabels(); $this->ruoliAttivi = $ruoli ->filter(fn(RubricaRuolo $r) => (bool) $r->is_attivo) ->map(function (RubricaRuolo $r) use ($labels) { $stabile = $r->stabile ?: $r->unitaImmobiliare?->stabile; $ruoloKey = (string) ($r->ruolo_standard ?? 'altro'); $ruoloLabel = (string) ($labels[$ruoloKey] ?? $ruoloKey); if (! empty($r->ruolo_custom)) { $ruoloLabel .= ' (' . (string) $r->ruolo_custom . ')'; } return [ 'ruolo' => $ruoloLabel, 'stabile_codice' => (string) ($stabile?->codice_operatore ?? $stabile?->codice_stabile ?? ''), 'stabile_nome' => (string) ($stabile?->denominazione ?? ''), 'unita_id' => (int) ($r->unitaImmobiliare?->id ?? 0), 'unita_codice' => (string) ($r->unitaImmobiliare?->codice_unita ?? ''), 'unita_nome' => (string) ($r->unitaImmobiliare?->denominazione ?? ''), 'preferito' => (bool) ($r->is_preferito ?? false), ]; }) ->values() ->all(); $this->cronistoriaRuoli = $ruoli ->map(function (RubricaRuolo $r) use ($labels) { $stabile = $r->stabile ?: $r->unitaImmobiliare?->stabile; $unita = $r->unitaImmobiliare; $ruoloKey = (string) ($r->ruolo_standard ?? 'altro'); $ruoloLabel = (string) ($labels[$ruoloKey] ?? $ruoloKey); if (! empty($r->ruolo_custom)) { $ruoloLabel .= ' (' . (string) $r->ruolo_custom . ')'; } return [ 'ruolo' => $ruoloLabel, 'data_inizio' => optional($r->data_inizio)->format('d/m/Y'), 'data_fine' => $r->data_fine ? optional($r->data_fine)->format('d/m/Y') : null, 'attivo' => (bool) ($r->is_attivo ?? true), 'preferito' => (bool) ($r->is_preferito ?? false), 'stabile_codice' => (string) ($stabile?->codice_operatore ?? $stabile?->codice_stabile ?? ''), 'stabile_nome' => (string) ($stabile?->denominazione ?? ''), 'unita_id' => (int) ($unita?->id ?? 0), 'unita_codice' => (string) ($unita?->codice_unita ?? ''), 'unita_nome' => (string) ($unita?->denominazione ?? ''), ]; }) ->all(); // Collegamenti stabili: includi sia stabili con rubrica_id diretto sia stabili legati tramite ruoli. $stabiliIds = []; foreach ($ruoli as $r) { $sid = (int) ($r->stabile_id ?? 0); if ($sid <= 0) { $sid = (int) ($r->unitaImmobiliare?->stabile_id ?? 0); } if ($sid > 0) { $stabiliIds[] = $sid; } } $stabiliIds = array_values(array_unique($stabiliIds)); $stabiliQuery = Stabile::query()->where('amministratore_id', $adminId); if (! empty($stabiliIds)) { $stabiliQuery->where(function (Builder $q) use ($stabiliIds): void { $q->whereIn('id', $stabiliIds) ->orWhere('rubrica_id', (int) $this->rubrica->id); }); } else { $stabiliQuery->where('rubrica_id', (int) $this->rubrica->id); } $this->stabili = $stabiliQuery ->orderBy('codice_stabile') ->limit(100) ->get(['id', 'codice_stabile', 'cod_stabile', 'denominazione', 'codice_fiscale']) ->map(fn(Stabile $s) => [ 'id' => (int) $s->id, 'codice' => (string) ($s->codice_operatore ?? $s->codice_stabile ?? ''), 'nome' => (string) ($s->denominazione ?? ''), 'cf' => (string) ($s->codice_fiscale ?? ''), ]) ->all(); // Contatti principali (per mostrarli velocemente nella scheda): prende canali principali + fallback ai campi telefono/email. $principali = RubricaContattoCanale::query() ->where('rubrica_id', (int) $this->rubrica->id) ->orderByDesc('is_principale') ->orderByDesc('data_inizio') ->orderByDesc('id') ->limit(20) ->get(); $this->contattiPrincipali = $principali ->map(fn(RubricaContattoCanale $c) => [ 'tipo' => (string) ($c->tipo ?? 'altro'), 'etichetta' => (string) ($c->etichetta ?? ''), 'valore' => (string) ($c->valore ?? ''), 'principale' => (bool) ($c->is_principale ?? false), ]) ->all(); } private function initArchivioNavigation(): void { $pp = (int) request()->query('pp', 25); if ($pp <= 0) { $pp = 25; } if (! in_array($pp, [10, 25, 50, 100], true)) { $pp = 25; } $this->navPerPage = $pp; if ($this->adminId <= 0) { $this->prevRecordId = null; $this->nextRecordId = null; $this->navPage = 1; $this->navPages = 1; return; } $base = RubricaUniversale::query()->where('amministratore_id', $this->adminId); $total = (clone $base)->count(); $this->navPages = max(1, (int) ceil($total / $this->navPerPage)); $before = (clone $base) ->where($this->whereBeforeCurrent()) ->count(); $position = $before + 1; $this->navPage = max(1, (int) ceil($position / $this->navPerPage)); $this->prevRecordId = (clone $base) ->where($this->whereBeforeCurrent()) ->tap(fn(Builder $q) => $this->applySort($q, 'desc')) ->value('id'); $this->nextRecordId = (clone $base) ->where($this->whereAfterCurrent()) ->tap(fn(Builder $q) => $this->applySort($q, 'asc')) ->value('id'); } private function applySort(Builder $query, string $direction): void { $dir = strtolower($direction) === 'desc' ? 'DESC' : 'ASC'; $query ->orderByRaw("COALESCE(ragione_sociale, '') {$dir}") ->orderByRaw("COALESCE(cognome, '') {$dir}") ->orderByRaw("COALESCE(nome, '') {$dir}") ->orderBy('id', $dir); } private function whereBeforeCurrent(): \Closure { $ragione = (string) ($this->rubrica->ragione_sociale ?? ''); $cognome = (string) ($this->rubrica->cognome ?? ''); $nome = (string) ($this->rubrica->nome ?? ''); $id = (int) $this->rubrica->id; return function (Builder $q) use ($ragione, $cognome, $nome, $id): void { $q->whereRaw("COALESCE(ragione_sociale, '') < ?", [$ragione]) ->orWhere(function (Builder $q) use ($ragione, $cognome): void { $q->whereRaw("COALESCE(ragione_sociale, '') = ?", [$ragione]) ->whereRaw("COALESCE(cognome, '') < ?", [$cognome]); }) ->orWhere(function (Builder $q) use ($ragione, $cognome, $nome): void { $q->whereRaw("COALESCE(ragione_sociale, '') = ?", [$ragione]) ->whereRaw("COALESCE(cognome, '') = ?", [$cognome]) ->whereRaw("COALESCE(nome, '') < ?", [$nome]); }) ->orWhere(function (Builder $q) use ($ragione, $cognome, $nome, $id): void { $q->whereRaw("COALESCE(ragione_sociale, '') = ?", [$ragione]) ->whereRaw("COALESCE(cognome, '') = ?", [$cognome]) ->whereRaw("COALESCE(nome, '') = ?", [$nome]) ->where('id', '<', $id); }); }; } private function whereAfterCurrent(): \Closure { $ragione = (string) ($this->rubrica->ragione_sociale ?? ''); $cognome = (string) ($this->rubrica->cognome ?? ''); $nome = (string) ($this->rubrica->nome ?? ''); $id = (int) $this->rubrica->id; return function (Builder $q) use ($ragione, $cognome, $nome, $id): void { $q->whereRaw("COALESCE(ragione_sociale, '') > ?", [$ragione]) ->orWhere(function (Builder $q) use ($ragione, $cognome): void { $q->whereRaw("COALESCE(ragione_sociale, '') = ?", [$ragione]) ->whereRaw("COALESCE(cognome, '') > ?", [$cognome]); }) ->orWhere(function (Builder $q) use ($ragione, $cognome, $nome): void { $q->whereRaw("COALESCE(ragione_sociale, '') = ?", [$ragione]) ->whereRaw("COALESCE(cognome, '') = ?", [$cognome]) ->whereRaw("COALESCE(nome, '') > ?", [$nome]); }) ->orWhere(function (Builder $q) use ($ragione, $cognome, $nome, $id): void { $q->whereRaw("COALESCE(ragione_sociale, '') = ?", [$ragione]) ->whereRaw("COALESCE(cognome, '') = ?", [$cognome]) ->whereRaw("COALESCE(nome, '') = ?", [$nome]) ->where('id', '>', $id); }); }; } public function getPrevUrl(): ?string { if (! $this->prevRecordId) { return null; } return self::getUrl(['record' => $this->prevRecordId], panel: 'admin-filament') . '?pp=' . $this->navPerPage; } public function getNextUrl(): ?string { if (! $this->nextRecordId) { return null; } return self::getUrl(['record' => $this->nextRecordId], panel: 'admin-filament') . '?pp=' . $this->navPerPage; } public function getPrevPageUrl(): ?string { $target = $this->navPage - 1; if ($target < 1) { return null; } return $this->getPageUrl($target); } public function getNextPageUrl(): ?string { $target = $this->navPage + 1; if ($target > $this->navPages) { return null; } return $this->getPageUrl($target); } public function getPageUrl(int $page): ?string { if ($this->adminId <= 0) { return null; } $page = max(1, min($page, $this->navPages)); $offset = ($page - 1) * $this->navPerPage; $base = RubricaUniversale::query() ->where('amministratore_id', $this->adminId); $this->applySort($base, 'asc'); $id = (int) ($base->skip($offset)->take(1)->value('id') ?? 0); if ($id <= 0) { return null; } return self::getUrl(['record' => $id], panel: 'admin-filament') . '?pp=' . $this->navPerPage; } public function getPerPageUrl(int $perPage): string { if (! in_array($perPage, [10, 25, 50, 100], true)) { $perPage = 25; } return self::getUrl(['record' => (int) $this->rubrica->id], panel: 'admin-filament') . '?pp=' . $perPage; } protected function getHeaderActions(): array { return [ Action::make('titolo') ->label('Titolo') ->icon('heroicon-o-tag') ->form([ Select::make('titolo_id') ->label('Titolo') ->native(false) ->searchable() ->options(fn() => $this->getTitoliOptions()), ]) ->fillForm(fn(): array=> [ 'titolo_id' => $this->rubrica->titolo_id ? (int) $this->rubrica->titolo_id : null, ]) ->action(function (array $data): void { $titoloId = isset($data['titolo_id']) && is_numeric($data['titolo_id']) ? (int) $data['titolo_id'] : null; $this->rubrica->titolo_id = $titoloId; $this->rubrica->data_ultima_modifica = now()->toDateString(); $this->rubrica->modificato_da = Auth::id(); $this->rubrica->save(); $this->mount((int) $this->rubrica->id); Notification::make() ->title('Titolo aggiornato') ->success() ->send(); }), Action::make('contatti') ->label('Contatti') ->icon('heroicon-o-phone') ->modalWidth('7xl') ->form([ Repeater::make('canali') ->label('Contatti aggiuntivi') ->defaultItems(0) ->reorderable(true) ->schema([ Hidden::make('id'), Select::make('tipo') ->label('Tipo') ->options([ 'telefono' => 'Telefono', 'cellulare' => 'Cellulare', 'email' => 'Email', 'pec' => 'PEC', 'fax' => 'Fax', 'sito_web' => 'Sito web', 'altro' => 'Altro', ]) ->native(false) ->required() ->columnSpan(2), TextInput::make('etichetta') ->label('Etichetta') ->maxLength(50) ->columnSpan(2), TextInput::make('valore') ->label('Valore') ->required() ->maxLength(255) ->columnSpan(4), Toggle::make('is_principale') ->label('Principale') ->default(false) ->columnSpan(2), Select::make('stabile_id') ->label('Stabile (opzionale)') ->native(false) ->searchable() ->options(fn() => $this->getStabiliOptions()) ->reactive() ->afterStateUpdated(fn($set) => $set('unita_immobiliare_id', null)) ->columnSpan(3), Select::make('unita_immobiliare_id') ->label('Unità (opzionale)') ->native(false) ->searchable() ->options(fn($get) => $this->getUnitaOptions($get('stabile_id'))) ->columnSpan(3), DatePicker::make('data_inizio') ->label('Data inizio') ->columnSpan(2), DatePicker::make('data_fine') ->label('Data fine') ->columnSpan(2), TextInput::make('note') ->label('Note') ->maxLength(255) ->columnSpan(12), ]) ->columns(12), ]) ->fillForm(function (): array { $canali = RubricaContattoCanale::query() ->where('rubrica_id', (int) $this->rubrica->id) ->orderByDesc('is_principale') ->orderByDesc('data_inizio') ->orderByDesc('id') ->limit(200) ->get(); return [ 'canali' => $canali->map(fn(RubricaContattoCanale $c) => [ 'id' => (int) $c->id, 'tipo' => (string) ($c->tipo ?? 'altro'), 'etichetta' => (string) ($c->etichetta ?? ''), 'valore' => (string) ($c->valore ?? ''), 'is_principale' => (bool) ($c->is_principale ?? false), 'stabile_id' => $c->stabile_id ? (int) $c->stabile_id : null, 'unita_immobiliare_id' => $c->unita_immobiliare_id ? (int) $c->unita_immobiliare_id : null, 'data_inizio' => $c->data_inizio?->format('Y-m-d'), 'data_fine' => $c->data_fine?->format('Y-m-d'), 'note' => (string) (($c->meta['note'] ?? null) ?: ''), ])->all(), ]; }) ->action(function (array $data): void { /** @var array> $rows */ $rows = $data['canali'] ?? []; $rows = is_array($rows) ? array_values($rows) : []; DB::transaction(function () use ($rows): void { $keepIds = []; foreach ($rows as $row) { $id = (int) ($row['id'] ?? 0); $tipo = (string) ($row['tipo'] ?? 'altro'); if ($tipo === '') { $tipo = 'altro'; } $attrs = [ 'rubrica_id' => (int) $this->rubrica->id, 'tipo' => $tipo, 'etichetta' => ! empty($row['etichetta']) ? (string) $row['etichetta'] : null, 'valore' => ! empty($row['valore']) ? (string) $row['valore'] : null, 'is_principale' => (bool) ($row['is_principale'] ?? false), 'stabile_id' => ! empty($row['stabile_id']) ? (int) $row['stabile_id'] : null, 'unita_immobiliare_id' => ! empty($row['unita_immobiliare_id']) ? (int) $row['unita_immobiliare_id'] : null, 'data_inizio' => $row['data_inizio'] ?? null, 'data_fine' => $row['data_fine'] ?? null, 'meta' => [ 'note' => ! empty($row['note']) ? (string) $row['note'] : null, ], ]; if ($id > 0) { $existing = RubricaContattoCanale::query() ->where('id', $id) ->where('rubrica_id', (int) $this->rubrica->id) ->first(); if ($existing) { $existing->fill($attrs); $existing->save(); $keepIds[] = (int) $existing->id; continue; } } $created = RubricaContattoCanale::query()->create($attrs); $keepIds[] = (int) $created->id; } $deleteQuery = RubricaContattoCanale::query()->where('rubrica_id', (int) $this->rubrica->id); if (! empty($keepIds)) { $deleteQuery->whereNotIn('id', $keepIds); } $deleteQuery->delete(); }); $this->mount((int) $this->rubrica->id); Notification::make() ->title('Contatti aggiornati') ->success() ->send(); }), Action::make('riferimenti_chiamata') ->label('Riferimenti chiamata') ->icon('heroicon-o-phone-arrow-up-right') ->form([ Select::make('tipo_utenza_call') ->label('Profilo chiamante') ->native(false) ->options([ 'condomino' => 'Condomino', 'inquilino' => 'Inquilino', 'fornitore' => 'Fornitore', 'amministratore' => 'Amministratore', 'altro' => 'Altro', ]), TextInput::make('riferimento_stabile') ->label('Riferimento stabile') ->maxLength(255), TextInput::make('riferimento_unita') ->label('Riferimento unità') ->maxLength(255), TextInput::make('note_segreteria') ->label('Note segreteria') ->maxLength(2000), ]) ->fillForm(fn(): array=> [ 'tipo_utenza_call' => $this->rubrica->tipo_utenza_call, 'riferimento_stabile' => $this->rubrica->riferimento_stabile, 'riferimento_unita' => $this->rubrica->riferimento_unita, 'note_segreteria' => $this->rubrica->note_segreteria, ]) ->action(function (array $data): void { $this->rubrica->tipo_utenza_call = ! empty($data['tipo_utenza_call']) ? (string) $data['tipo_utenza_call'] : null; $this->rubrica->riferimento_stabile = ! empty($data['riferimento_stabile']) ? (string) $data['riferimento_stabile'] : null; $this->rubrica->riferimento_unita = ! empty($data['riferimento_unita']) ? (string) $data['riferimento_unita'] : null; $this->rubrica->note_segreteria = ! empty($data['note_segreteria']) ? (string) $data['note_segreteria'] : null; $this->rubrica->data_ultima_modifica = now()->toDateString(); $this->rubrica->modificato_da = Auth::id(); $this->rubrica->save(); $this->mount((int) $this->rubrica->id); Notification::make() ->title('Riferimenti chiamata aggiornati') ->success() ->send(); }), Action::make('ruoli_legami') ->label('Ruoli / legami') ->icon('heroicon-o-link') ->modalWidth('7xl') ->form([ Repeater::make('ruoli') ->label('Ruoli e legami') ->defaultItems(0) ->reorderable(true) ->schema([ Hidden::make('id'), Select::make('ruolo_standard') ->label('Ruolo') ->options(self::getRuoliLabels()) ->required() ->native(false) ->default('altro') ->columnSpan(2), TextInput::make('ruolo_custom') ->label('Ruolo custom') ->maxLength(255) ->columnSpan(2), Select::make('stabile_id') ->label('Stabile') ->native(false) ->searchable() ->options(fn() => $this->getStabiliOptions()) ->reactive() ->afterStateUpdated(fn($set) => $set('unita_immobiliare_id', null)) ->columnSpan(3), Select::make('unita_immobiliare_id') ->label('Unità') ->native(false) ->searchable() ->options(fn($get) => $this->getUnitaOptions($get('stabile_id'))) ->columnSpan(3), DatePicker::make('data_inizio') ->label('Data inizio') ->columnSpan(2), DatePicker::make('data_fine') ->label('Data fine') ->columnSpan(2), Toggle::make('is_preferito') ->label('Preferito') ->default(false) ->columnSpan(2), Toggle::make('is_attivo') ->label('Attivo') ->default(true) ->columnSpan(2), ]) ->columns(12), ]) ->fillForm(function (): array { $ruoli = RubricaRuolo::query() ->where('rubrica_id', (int) $this->rubrica->id) ->orderByDesc('is_attivo') ->orderByDesc('is_preferito') ->orderByDesc('data_inizio') ->orderByDesc('id') ->limit(200) ->get(); return [ 'ruoli' => $ruoli->map(fn(RubricaRuolo $r) => [ 'id' => (int) $r->id, 'ruolo_standard' => (string) ($r->ruolo_standard ?? 'altro'), 'ruolo_custom' => (string) ($r->ruolo_custom ?? ''), 'stabile_id' => $r->stabile_id ? (int) $r->stabile_id : null, 'unita_immobiliare_id' => $r->unita_immobiliare_id ? (int) $r->unita_immobiliare_id : null, 'data_inizio' => $r->data_inizio?->format('Y-m-d'), 'data_fine' => $r->data_fine?->format('Y-m-d'), 'is_preferito' => (bool) ($r->is_preferito ?? false), 'is_attivo' => (bool) ($r->is_attivo ?? true), ])->all(), ]; }) ->action(function (array $data): void { /** @var array> $rows */ $rows = $data['ruoli'] ?? []; $rows = is_array($rows) ? array_values($rows) : []; DB::transaction(function () use ($rows): void { $keepIds = []; foreach ($rows as $row) { $id = (int) ($row['id'] ?? 0); $ruoloStandard = (string) ($row['ruolo_standard'] ?? 'altro'); $attrs = [ 'rubrica_id' => (int) $this->rubrica->id, 'ruolo_standard' => $ruoloStandard ?: 'altro', 'ruolo_custom' => ! empty($row['ruolo_custom']) ? (string) $row['ruolo_custom'] : null, 'stabile_id' => ! empty($row['stabile_id']) ? (int) $row['stabile_id'] : null, 'unita_immobiliare_id' => ! empty($row['unita_immobiliare_id']) ? (int) $row['unita_immobiliare_id'] : null, 'data_inizio' => $row['data_inizio'] ?? null, 'data_fine' => $row['data_fine'] ?? null, 'is_preferito' => (bool) ($row['is_preferito'] ?? false), 'is_attivo' => (bool) ($row['is_attivo'] ?? true), ]; if ($id > 0) { $existing = RubricaRuolo::query() ->where('id', $id) ->where('rubrica_id', (int) $this->rubrica->id) ->first(); if ($existing) { $existing->fill($attrs); $existing->save(); $keepIds[] = (int) $existing->id; continue; } } $created = RubricaRuolo::query()->create($attrs); $keepIds[] = (int) $created->id; } $deleteQuery = RubricaRuolo::query()->where('rubrica_id', (int) $this->rubrica->id); if (! empty($keepIds)) { $deleteQuery->whereNotIn('id', $keepIds); } $deleteQuery->delete(); }); $this->mount((int) $this->rubrica->id); Notification::make() ->title('Ruoli / legami aggiornati') ->success() ->send(); }), Action::make('torna') ->label('Torna') ->icon('heroicon-o-arrow-left') ->url(fn() => AnagraficaUnica::getUrl(panel: 'admin-filament')), ]; } public function getUrlUnita(?int $unitaId): ?string { if (! $unitaId) { return null; } if (! class_exists(\App\Filament\Pages\UnitaImmobiliarePage::class)) { return null; } return \App\Filament\Pages\UnitaImmobiliarePage::getUrl(panel: 'admin-filament') . '?unita_id=' . (int) $unitaId . '&back=' . urlencode((string) request()->getRequestUri()); } /** @return array */ protected static function getRuoliLabels(): array { return [ 'super_admin' => 'Super admin', 'amministratore' => 'Amministratore', 'condomino' => 'Condomino', 'inquilino' => 'Inquilino', 'fornitore' => 'Fornitore', 'manutentore' => 'Manutentore', 'banca' => 'Banca', 'assicurazione' => 'Assicurazione', 'collaboratore' => 'Collaboratore', 'tester' => 'Tester', 'ospite' => 'Ospite', 'altro' => 'Altro', ]; } /** @return array */ protected function getStabiliOptions(): array { $query = Stabile::query(); $user = Auth::user(); $isSuperAdmin = $user instanceof User && method_exists($user, 'hasRole') ? (bool) $user->hasRole('super-admin') : false; if (! $isSuperAdmin && $this->adminId > 0) { $query->where('amministratore_id', $this->adminId); } return $query ->orderBy('codice_stabile') ->limit(200) ->get(['id', 'codice_stabile', 'denominazione']) ->mapWithKeys(fn(Stabile $s) => [ (int) $s->id => trim((string) ($s->codice_operatore ?? $s->codice_stabile ?? '') . ' - ' . (string) ($s->denominazione ?? 'Stabile')), ]) ->all(); } /** @return array */ protected function getTitoliOptions(): array { if (! Schema::hasTable('titoli')) { return []; } return Titolo::query() ->orderBy('ordine') ->orderBy('nome') ->get(['id', 'nome', 'sigla']) ->mapWithKeys(fn(Titolo $t) => [ (int) $t->id => trim((string) ($t->sigla ?: $t->nome)), ]) ->all(); } /** @return array */ protected function getUnitaOptions($stabileId): array { $stabileId = (int) ($stabileId ?? 0); if ($stabileId <= 0) { return []; } $query = UnitaImmobiliare::query()->where('stabile_id', $stabileId); return $query ->orderBy('palazzina_id') ->orderBy('scala') ->orderBy('piano') ->orderBy('interno') ->orderBy('id') ->limit(1000) ->get(['id', 'codice_unita', 'denominazione', 'scala', 'piano', 'interno']) ->mapWithKeys(function (UnitaImmobiliare $u) { $codice = $u->codice_unita ?: ('ID ' . $u->id); $nome = $u->denominazione ?: 'Unità'; $pos = trim('Scala ' . ($u->scala ?? '-') . ' · Piano ' . ($u->piano ?? '-') . ' · Int. ' . ($u->interno ?? '-')); return [(int) $u->id => trim($codice . ' — ' . $nome . ' (' . $pos . ')')]; }) ->all(); } }