hasAnyRole(['super-admin', 'admin']) && Schema::hasTable('amministratori'); } public function mount(): void { $this->mountInteractsWithTable(); } protected function getTableQuery(): Builder { return Amministratore::query()->withCount('stabili'); } public function table(Table $table): Table { return $table ->striped() ->defaultSort('id', 'desc') ->columns([ TextColumn::make('id')->label('ID')->sortable(), TextColumn::make('codice_univoco')->label('Codice')->searchable()->sortable(), TextColumn::make('nome')->label('Nome')->searchable()->sortable(), TextColumn::make('cognome')->label('Cognome')->searchable()->sortable(), TextColumn::make('stabili_count')->label('Stabili')->sortable(), TextColumn::make('denominazione_studio')->label('Studio')->searchable()->toggleable(), TextColumn::make('email_studio')->label('Email')->searchable()->toggleable(isToggledHiddenByDefault: true), TextColumn::make('pec_studio')->label('PEC')->searchable()->toggleable(isToggledHiddenByDefault: true), IconColumn::make('attivo')->label('Attivo')->boolean()->sortable()->toggleable(), IconColumn::make('abilita_import_stabili')->label('Import')->boolean()->sortable()->toggleable(isToggledHiddenByDefault: true), TextColumn::make('fe_cassetto_status') ->label('FE Stato') ->state(function (Amministratore $record): string { if (! (bool) ($record->fe_cassetto_enabled ?? false)) { return 'Disabilitato'; } $expiresAt = $record->fe_cassetto_expires_at; if ($expiresAt instanceof Carbon && $expiresAt->startOfDay()->lt(now()->startOfDay())) { return 'Scaduto'; } return 'Attivo'; }) ->badge() ->color(function (Amministratore $record): string { if (! (bool) ($record->fe_cassetto_enabled ?? false)) { return 'gray'; } $expiresAt = $record->fe_cassetto_expires_at; if ($expiresAt instanceof Carbon && $expiresAt->startOfDay()->lt(now()->startOfDay())) { return 'danger'; } return 'success'; }) ->sortable(), IconColumn::make('fe_cassetto_enabled')->label('FE Abilitato')->boolean()->sortable()->toggleable(), TextColumn::make('fe_cassetto_expires_at')->label('FE Scadenza')->date('d/m/Y')->sortable()->toggleable(isToggledHiddenByDefault: true), TextColumn::make('updated_at')->label('Aggiornato')->dateTime('d/m/Y H:i')->toggleable(isToggledHiddenByDefault: true), ]) ->headerActions([ Action::make('create') ->label('Nuovo') ->icon('heroicon-o-plus') ->form([ Select::make('user_id') ->label('Utente collegato') ->options(fn() => User::query() ->whereDoesntHave('amministratore') ->orderBy('name') ->get() ->mapWithKeys(fn(User $u) => [ $u->id => trim($u->name . ' <' . $u->email . '>'), ]) ->all()) ->searchable() ->required(), TextInput::make('nome')->label('Nome')->required()->maxLength(100), TextInput::make('cognome')->label('Cognome')->required()->maxLength(100), TextInput::make('denominazione_studio')->label('Denominazione studio')->maxLength(255), TextInput::make('partita_iva')->label('Partita IVA')->maxLength(30), TextInput::make('codice_fiscale_studio')->label('Codice fiscale')->maxLength(30), TextInput::make('indirizzo_studio')->label('Indirizzo')->maxLength(255), TextInput::make('cap_studio')->label('CAP')->maxLength(10), TextInput::make('citta_studio')->label('Città')->maxLength(60), TextInput::make('provincia_studio')->label('Provincia')->maxLength(5), TextInput::make('telefono_studio')->label('Telefono')->maxLength(50), TextInput::make('email_studio')->label('Email')->maxLength(255), TextInput::make('pec_studio')->label('PEC')->maxLength(255), Toggle::make('attivo')->label('Attivo')->default(true), Toggle::make('abilita_import_stabili')->label('Abilita import stabili')->default(true), Toggle::make('fe_cassetto_enabled') ->label('Abilita servizio scarico Fatture (Cassetto Fiscale)') ->helperText('Servizio a pagamento: abilita solo per gli amministratori autorizzati.') ->default(false), DatePicker::make('fe_cassetto_expires_at') ->label('Scadenza servizio (opzionale)') ->helperText('Se valorizzata, dopo questa data lo scarico sarà bloccato finché non rinnovato.') ->native(false) ->displayFormat('d/m/Y') ->nullable(), ]) ->action(function (array $data): void { $amm = Amministratore::query()->create([ 'user_id' => (int) ($data['user_id'] ?? 0), 'nome' => trim((string) ($data['nome'] ?? '')), 'cognome' => trim((string) ($data['cognome'] ?? '')), 'denominazione_studio' => (string) ($data['denominazione_studio'] ?? ''), 'partita_iva' => (string) ($data['partita_iva'] ?? ''), 'codice_fiscale_studio' => (string) ($data['codice_fiscale_studio'] ?? ''), 'indirizzo_studio' => (string) ($data['indirizzo_studio'] ?? ''), 'cap_studio' => (string) ($data['cap_studio'] ?? ''), 'citta_studio' => (string) ($data['citta_studio'] ?? ''), 'provincia_studio' => (string) ($data['provincia_studio'] ?? ''), 'telefono_studio' => (string) ($data['telefono_studio'] ?? ''), 'email_studio' => (string) ($data['email_studio'] ?? ''), 'pec_studio' => (string) ($data['pec_studio'] ?? ''), 'attivo' => (bool) ($data['attivo'] ?? true), 'abilita_import_stabili' => (bool) ($data['abilita_import_stabili'] ?? true), 'fe_cassetto_enabled' => (bool) ($data['fe_cassetto_enabled'] ?? false), 'fe_cassetto_expires_at' => $data['fe_cassetto_expires_at'] ?? null, ]); // Best-effort: provisioning cartelle. try { $amm->provisionArchiveIfMissing(); } catch (\Throwable) { } }), ]) ->actions([ Action::make('edit') ->label('Modifica') ->icon('heroicon-o-pencil-square') ->form([ Select::make('user_id') ->label('Utente collegato') ->options(fn(Amministratore $record) => User::query() ->where(function (Builder $q) use ($record) { $q->whereDoesntHave('amministratore') ->orWhere('id', (int) $record->user_id); }) ->orderBy('name') ->get() ->mapWithKeys(fn(User $u) => [ $u->id => trim($u->name . ' <' . $u->email . '>'), ]) ->all()) ->searchable() ->required(), TextInput::make('nome')->label('Nome')->required()->maxLength(100), TextInput::make('cognome')->label('Cognome')->required()->maxLength(100), TextInput::make('denominazione_studio')->label('Denominazione studio')->maxLength(255), TextInput::make('partita_iva')->label('Partita IVA')->maxLength(30), TextInput::make('codice_fiscale_studio')->label('Codice fiscale')->maxLength(30), TextInput::make('indirizzo_studio')->label('Indirizzo')->maxLength(255), TextInput::make('cap_studio')->label('CAP')->maxLength(10), TextInput::make('citta_studio')->label('Città')->maxLength(60), TextInput::make('provincia_studio')->label('Provincia')->maxLength(5), TextInput::make('telefono_studio')->label('Telefono')->maxLength(50), TextInput::make('email_studio')->label('Email')->maxLength(255), TextInput::make('pec_studio')->label('PEC')->maxLength(255), Toggle::make('attivo')->label('Attivo'), Toggle::make('abilita_import_stabili')->label('Abilita import stabili'), Toggle::make('fe_cassetto_enabled') ->label('Abilita servizio scarico Fatture (Cassetto Fiscale)') ->helperText('Servizio a pagamento: abilita solo per gli amministratori autorizzati.'), DatePicker::make('fe_cassetto_expires_at') ->label('Scadenza servizio (opzionale)') ->native(false) ->displayFormat('d/m/Y') ->nullable(), ]) ->fillForm(fn(Amministratore $record): array => [ 'user_id' => (int) $record->user_id, 'nome' => (string) ($record->nome ?? ''), 'cognome' => (string) ($record->cognome ?? ''), 'denominazione_studio' => (string) ($record->denominazione_studio ?? ''), 'partita_iva' => (string) ($record->partita_iva ?? ''), 'codice_fiscale_studio' => (string) ($record->codice_fiscale_studio ?? ''), 'indirizzo_studio' => (string) ($record->indirizzo_studio ?? ''), 'cap_studio' => (string) ($record->cap_studio ?? ''), 'citta_studio' => (string) ($record->citta_studio ?? ''), 'provincia_studio' => (string) ($record->provincia_studio ?? ''), 'telefono_studio' => (string) ($record->telefono_studio ?? ''), 'email_studio' => (string) ($record->email_studio ?? ''), 'pec_studio' => (string) ($record->pec_studio ?? ''), 'attivo' => (bool) ($record->attivo ?? true), 'abilita_import_stabili' => (bool) ($record->abilita_import_stabili ?? true), 'fe_cassetto_enabled' => (bool) ($record->fe_cassetto_enabled ?? false), 'fe_cassetto_expires_at' => $record->fe_cassetto_expires_at?->format('Y-m-d'), ]) ->action(function (Amministratore $record, array $data): void { $update = [ 'user_id' => (int) ($data['user_id'] ?? 0), 'nome' => trim((string) ($data['nome'] ?? '')), 'cognome' => trim((string) ($data['cognome'] ?? '')), 'denominazione_studio' => (string) ($data['denominazione_studio'] ?? ''), 'partita_iva' => (string) ($data['partita_iva'] ?? ''), 'codice_fiscale_studio' => (string) ($data['codice_fiscale_studio'] ?? ''), 'indirizzo_studio' => (string) ($data['indirizzo_studio'] ?? ''), 'cap_studio' => (string) ($data['cap_studio'] ?? ''), 'citta_studio' => (string) ($data['citta_studio'] ?? ''), 'provincia_studio' => (string) ($data['provincia_studio'] ?? ''), 'telefono_studio' => (string) ($data['telefono_studio'] ?? ''), 'email_studio' => (string) ($data['email_studio'] ?? ''), 'pec_studio' => (string) ($data['pec_studio'] ?? ''), 'attivo' => (bool) ($data['attivo'] ?? true), 'abilita_import_stabili' => (bool) ($data['abilita_import_stabili'] ?? true), 'fe_cassetto_enabled' => (bool) ($data['fe_cassetto_enabled'] ?? false), 'fe_cassetto_expires_at' => $data['fe_cassetto_expires_at'] ?? null, ]; $record->fill($update); $record->save(); try { $record->provisionArchiveIfMissing(); } catch (\Throwable) { } }), Action::make('delete') ->label('Elimina') ->icon('heroicon-o-trash') ->color('danger') ->requiresConfirmation() ->action(function (Amministratore $record): void { if ($record->stabili()->exists()) { throw new \RuntimeException('Impossibile eliminare: ci sono stabili collegati.'); } if ($record->fornitori()->exists()) { throw new \RuntimeException('Impossibile eliminare: ci sono fornitori collegati.'); } $record->delete(); }), ]); } }