netgescon-day0/app/Filament/Pages/SuperAdmin/Amministratori.php

296 lines
16 KiB
PHP

<?php
namespace App\Filament\Pages\SuperAdmin;
use App\Models\Amministratore;
use App\Models\User;
use BackedEnum;
use Filament\Actions\Action;
use Filament\Pages\Page;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Toggle;
use Filament\Forms\Components\DatePicker;
use Filament\Tables\Columns\IconColumn;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Concerns\InteractsWithTable;
use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Carbon;
use UnitEnum;
class Amministratori extends Page implements HasTable
{
use InteractsWithTable;
protected static ?string $navigationLabel = 'Amministratori';
protected static ?string $title = 'Gestione amministratori';
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-building-office';
protected static UnitEnum|string|null $navigationGroup = 'Super Admin';
protected static ?int $navigationSort = 2;
protected static ?string $slug = 'superadmin/amministratori';
protected string $view = 'filament.pages.gescon.table';
public static function canAccess(): bool
{
$user = Auth::user();
return $user instanceof User
&& $user->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();
}),
]);
}
}