feat(ui): update ultra-compact tab buttons, auto-switch to TAB 2 on edit, add sticky impersonation header banner with return button, and render licenze & ACL matrix tabs (task-d095b0e23b)

This commit is contained in:
michele 2026-08-27 20:48:12 +02:00
parent bf862f44c2
commit 2b045197ec
4 changed files with 339 additions and 205 deletions

View File

@ -49,7 +49,7 @@ class Amministratori extends Page implements HasTable
public function apriTab(string $tab): void public function apriTab(string $tab): void
{ {
$this->activeTab = in_array($tab, ['elenco', 'scheda', 'stabili', 'importazione'], true) ? $tab : 'elenco'; $this->activeTab = in_array($tab, ['elenco', 'scheda', 'stabili', 'moduli', 'acl'], true) ? $tab : 'elenco';
} }
public static function canAccess(): bool public static function canAccess(): bool
@ -69,11 +69,11 @@ public function mount(): void
?: Amministratore::query()->first(); ?: Amministratore::query()->first();
if ($defaultAmm) { if ($defaultAmm) {
$this->selectAmministratore($defaultAmm->id); $this->selectAmministratore($defaultAmm->id, false);
} }
} }
public function selectAmministratore(int $id): void public function selectAmministratore(int $id, bool $switchToTab = true): void
{ {
$this->selectedAmministratoreId = $id; $this->selectedAmministratoreId = $id;
$amm = Amministratore::query()->with('user')->find($id); $amm = Amministratore::query()->with('user')->find($id);
@ -97,6 +97,10 @@ public function selectAmministratore(int $id): void
'codice_univoco' => (string) ($amm->codice_univoco ?? '00000001'), 'codice_univoco' => (string) ($amm->codice_univoco ?? '00000001'),
'user_email' => (string) ($amm->user?->email ?? $amm->email_studio ?? ''), 'user_email' => (string) ($amm->user?->email ?? $amm->email_studio ?? ''),
]; ];
if ($switchToTab) {
$this->activeTab = 'scheda';
}
} }
} }
@ -341,96 +345,9 @@ public function table(Table $table): Table
Action::make('edit') Action::make('edit')
->label('Modifica') ->label('Modifica')
->icon('heroicon-o-pencil-square') ->icon('heroicon-o-pencil-square')
->form([ ->color('primary')
Select::make('user_id') ->action(function (Amministratore $record): void {
->label('Utente collegato') $this->selectAmministratore($record->id, true);
->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('impersonate') Action::make('impersonate')

View File

@ -1,64 +1,77 @@
<x-filament-panels::page> <x-filament-panels::page>
<div class="space-y-4" wire:key="amministratori-superadmin-tabbed-shell"> <div class="space-y-4" wire:key="amministratori-superadmin-5tabs-shell">
{{-- BARRA NAVIGAZIONE A TAB (PULSANTINI COMPATTI SENZA SCROLL ORIZZONTALE) --}} {{-- STICKY HEADER BANNER - IMPERSONIFICAZIONE CONTESTUALE ATTIVA --}}
<div class="rounded-xl border bg-white p-3 shadow-sm"> @if(session('impersonator_id'))
<div class="flex flex-wrap items-center gap-2"> <div class="sticky top-0 z-50 rounded-xl border border-amber-400 bg-amber-500 p-3 text-white shadow-lg flex flex-wrap items-center justify-between gap-3">
<div class="flex items-center gap-2 text-xs font-bold">
<span class="text-base">⚠️</span>
<span>MODALITÀ IMPERSONIFICAZIONE ATTIVA: Stai operando nel contesto dello studio amministrato.</span>
</div>
<a
href="{{ route('impersonate.leave') }}"
class="inline-flex items-center gap-1.5 rounded-lg bg-slate-900 px-3 py-1.5 text-xs font-bold text-white shadow hover:bg-slate-800 transition"
>
↩️ TORNA A SUPER ADMIN
</a>
</div>
@endif
{{-- BARRA PULSANTINI ICONICI COMPATTI (SENZA SCROLL ORIZZONTALE) --}}
<div class="rounded-xl border bg-white p-2.5 shadow-sm">
<div class="flex flex-wrap items-center gap-1.5">
<button <button
type="button" type="button"
wire:click="apriTab('elenco')" wire:click="apriTab('elenco')"
class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-semibold {{ $activeTab === 'elenco' ? 'bg-slate-900 text-white shadow' : 'bg-slate-100 text-slate-700 hover:bg-slate-200' }}" class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-bold transition {{ $activeTab === 'elenco' ? 'bg-slate-900 text-white shadow' : 'bg-slate-100 text-slate-700 hover:bg-slate-200' }}"
> >
🏢 TAB 1: Elenco Amministratori 🏢 Elenco
</button> </button>
<button <button
type="button" type="button"
wire:click="apriTab('scheda')" wire:click="apriTab('scheda')"
class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-semibold {{ $activeTab === 'scheda' ? 'bg-slate-900 text-white shadow' : 'bg-slate-100 text-slate-700 hover:bg-slate-200' }}" class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-bold transition {{ $activeTab === 'scheda' ? 'bg-slate-900 text-white shadow' : 'bg-slate-100 text-slate-700 hover:bg-slate-200' }}"
> >
✏️ TAB 2: Scheda & Modifica Inline {{ $selectedAmministratoreId ? "(#{$selectedAmministratoreId})" : '' }} ✏️ Modifica {{ $selectedAmministratoreId ? "(#{$selectedAmministratoreId})" : '' }}
</button> </button>
<button <button
type="button" type="button"
wire:click="apriTab('stabili')" wire:click="apriTab('stabili')"
class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-semibold {{ $activeTab === 'stabili' ? 'bg-slate-900 text-white shadow' : 'bg-slate-100 text-slate-700 hover:bg-slate-200' }}" class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-bold transition {{ $activeTab === 'stabili' ? 'bg-slate-900 text-white shadow' : 'bg-slate-100 text-slate-700 hover:bg-slate-200' }}"
> >
📊 TAB 3: Stabili & Fornitori Studio 📊 Stabili & Fornitori
</button> </button>
@can('import-gescon')
<button <button
type="button" type="button"
wire:click="apriTab('importazione')" wire:click="apriTab('moduli')"
class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-semibold {{ $activeTab === 'importazione' ? 'bg-emerald-700 text-white shadow' : 'bg-emerald-100 text-emerald-800 hover:bg-emerald-200' }}" class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-bold transition {{ $activeTab === 'moduli' ? 'bg-emerald-700 text-white shadow' : 'bg-emerald-50 text-emerald-800 hover:bg-emerald-100' }}"
> >
🔄 TAB 4: Modulo Importazione MDB (ACL) 🛡️ Moduli & Scadenze
</button> </button>
@else
<button <button
type="button" type="button"
wire:click="apriTab('importazione')" wire:click="apriTab('acl')"
class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-semibold {{ $activeTab === 'importazione' ? 'bg-slate-800 text-white shadow' : 'bg-slate-100 text-slate-700 hover:bg-slate-200' }}" class="inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 text-xs font-bold transition {{ $activeTab === 'acl' ? 'bg-sky-700 text-white shadow' : 'bg-sky-50 text-sky-800 hover:bg-sky-100' }}"
> >
🔄 TAB 4: Modulo Importazione Legacy MDB 🔑 Matrice ACL
</button> </button>
@endcan
</div> </div>
</div> </div>
{{-- TAB 1: ELENCO AMMINISTRATORI --}} {{-- TAB 1: 🏢 ELENCO AMMINISTRATORI --}}
@if($activeTab === 'elenco') @if($activeTab === 'elenco')
<div class="rounded-xl border bg-white p-4 shadow-sm"> <div class="rounded-xl border bg-white p-4 shadow-sm">
<div class="mb-3 flex items-center justify-between"> <div class="mb-3 flex items-center justify-between">
<div> <div>
<h2 class="text-base font-bold text-slate-900">Elenco Amministratori Censiti</h2> <h2 class="text-base font-bold text-slate-900">Amministratori Stabili Censiti</h2>
<p class="text-xs text-slate-500">Seleziona un amministratore per aprirne la scheda nel TAB 2 o usa l'azione Impersona per accedere direttamente.</p> <p class="text-xs text-slate-500">Cliccando su ✏️ Modifica su qualunque riga, il sistema seleziona l'amministratore e passa automagicamente al TAB 2.</p>
</div> </div>
</div> </div>
{{ $this->table }} {{ $this->table }}
</div> </div>
@endif @endif
{{-- TAB 2: SCHEDA & MODIFICA INLINE --}} {{-- TAB 2: ✏️ SCHEDA DETTAGLIO & EDITING INLINE --}}
@if($activeTab === 'scheda') @if($activeTab === 'scheda')
@if($selectedAmministratoreId && !empty($editForm)) @if($selectedAmministratoreId && !empty($editForm))
<div class="rounded-xl border border-slate-300 bg-white p-5 shadow-md"> <div class="rounded-xl border border-slate-300 bg-white p-5 shadow-md">
@ -103,56 +116,40 @@ class="inline-flex items-center gap-1.5 rounded-lg bg-slate-700 px-3 py-1.5 text
</div> </div>
</div> </div>
{{-- UTENTE COLLEGATO & ACCESSO --}} {{-- FORM INPUTS IN-PLACE --}}
<div class="mb-4 rounded-lg bg-slate-50 border border-slate-200 p-3 text-xs flex flex-wrap items-center justify-between gap-2"> <div class="grid grid-cols-1 gap-4 md:grid-cols-3 text-xs">
<div> <div>
<span class="text-slate-500">Utente di sistema collegato per il login:</span> <label class="block font-semibold text-slate-700">Nome</label>
<strong class="ml-1 text-slate-900 font-mono">{{ $editForm['user_email'] ?? 'Nessun utente collegato' }}</strong>
</div>
<div class="flex items-center gap-2">
<span class="inline-flex items-center rounded-full bg-emerald-100 px-2.5 py-0.5 text-xs font-medium text-emerald-800">
Accesso Direct Impersonation OK
</span>
<span class="inline-flex items-center rounded-full bg-sky-100 px-2.5 py-0.5 text-xs font-medium text-sky-800">
Scarico FE Cassetto Fiscale Attivo
</span>
</div>
</div>
{{-- IN-PLACE FORM INPUTS --}}
<div class="grid grid-cols-1 gap-4 md:grid-cols-3">
<div>
<label class="block text-xs font-semibold text-slate-700">Nome</label>
<input type="text" wire:model="editForm.nome" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800"> <input type="text" wire:model="editForm.nome" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-slate-700">Cognome</label> <label class="block font-semibold text-slate-700">Cognome</label>
<input type="text" wire:model="editForm.cognome" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800"> <input type="text" wire:model="editForm.cognome" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-slate-700">Denominazione Studio</label> <label class="block font-semibold text-slate-700">Denominazione Studio</label>
<input type="text" wire:model="editForm.denominazione_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800"> <input type="text" wire:model="editForm.denominazione_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-slate-700">Codice Fiscale Studio</label> <label class="block font-semibold text-slate-700">Codice Fiscale Studio</label>
<input type="text" wire:model="editForm.codice_fiscale_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm font-mono focus:border-slate-800 focus:ring-slate-800"> <input type="text" wire:model="editForm.codice_fiscale_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm font-mono focus:border-slate-800 focus:ring-slate-800">
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-slate-700">Partita IVA Studio</label> <label class="block font-semibold text-slate-700">Partita IVA Studio</label>
<input type="text" wire:model="editForm.partita_iva" class="mt-1 w-full rounded-md border-slate-300 text-sm font-mono focus:border-slate-800 focus:ring-slate-800"> <input type="text" wire:model="editForm.partita_iva" class="mt-1 w-full rounded-md border-slate-300 text-sm font-mono focus:border-slate-800 focus:ring-slate-800">
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-slate-700">Email Login Studio</label> <label class="block font-semibold text-slate-700">Email Login Studio</label>
<input type="email" wire:model="editForm.user_email" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800"> <input type="email" wire:model="editForm.user_email" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div> </div>
<div class="md:col-span-2"> <div class="md:col-span-2">
<label class="block text-xs font-semibold text-slate-700">Indirizzo Studio</label> <label class="block font-semibold text-slate-700">Indirizzo Studio</label>
<input type="text" wire:model="editForm.indirizzo_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800"> <input type="text" wire:model="editForm.indirizzo_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-slate-700">Città / CAP / PR</label> <label class="block font-semibold text-slate-700">Città / CAP / PR</label>
<div class="mt-1 flex gap-2"> <div class="mt-1 flex gap-2">
<input type="text" wire:model="editForm.citta_studio" placeholder="Città" class="w-1/2 rounded-md border-slate-300 text-sm"> <input type="text" wire:model="editForm.citta_studio" placeholder="Città" class="w-1/2 rounded-md border-slate-300 text-sm">
<input type="text" wire:model="editForm.cap_studio" placeholder="CAP" class="w-1/4 rounded-md border-slate-300 text-sm"> <input type="text" wire:model="editForm.cap_studio" placeholder="CAP" class="w-1/4 rounded-md border-slate-300 text-sm">
@ -161,15 +158,15 @@ class="inline-flex items-center gap-1.5 rounded-lg bg-slate-700 px-3 py-1.5 text
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-slate-700">Telefono Studio</label> <label class="block font-semibold text-slate-700">Telefono Studio</label>
<input type="text" wire:model="editForm.telefono_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800"> <input type="text" wire:model="editForm.telefono_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-slate-700">PEC Studio</label> <label class="block font-semibold text-slate-700">PEC Studio</label>
<input type="email" wire:model="editForm.pec_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800"> <input type="email" wire:model="editForm.pec_studio" class="mt-1 w-full rounded-md border-slate-300 text-sm focus:border-slate-800 focus:ring-slate-800">
</div> </div>
<div> <div>
<label class="block text-xs font-semibold text-slate-700">Stato Studio</label> <label class="block font-semibold text-slate-700">Stato Studio</label>
<div class="mt-2 flex items-center gap-2"> <div class="mt-2 flex items-center gap-2">
<input type="checkbox" wire:model="editForm.attivo" id="chk-attivo" class="rounded border-slate-300 text-slate-800 focus:ring-slate-800"> <input type="checkbox" wire:model="editForm.attivo" id="chk-attivo" class="rounded border-slate-300 text-slate-800 focus:ring-slate-800">
<label for="chk-attivo" class="text-xs text-slate-700">Studio Attivo & Abilitato ad Import Stabili</label> <label for="chk-attivo" class="text-xs text-slate-700">Studio Attivo & Abilitato ad Import Stabili</label>
@ -181,13 +178,13 @@ class="inline-flex items-center gap-1.5 rounded-lg bg-slate-700 px-3 py-1.5 text
<div class="mt-5 rounded-lg border border-slate-200 bg-slate-900 p-3 text-xs text-slate-200"> <div class="mt-5 rounded-lg border border-slate-200 bg-slate-900 p-3 text-xs text-slate-200">
<div class="font-bold text-amber-400 mb-1">PERCORSI ARCHIVIO TENANT & BACKUP DEDICATO:</div> <div class="font-bold text-amber-400 mb-1">PERCORSI ARCHIVIO TENANT & BACKUP DEDICATO:</div>
<div class="font-mono space-y-1"> <div class="font-mono space-y-1">
<div> Percorso Cartella Stabile: <span class="text-emerald-400">storage/app/private/amministratori/{{ $editForm['codice_univoco'] ?? '00000001' }}/</span></div> <div> Cartella Stabile: <span class="text-emerald-400">storage/app/private/amministratori/{{ $editForm['codice_univoco'] ?? '00000001' }}/</span></div>
<div> Percorso Documenti Stabile: <span class="text-emerald-400">storage/app/private/amministratori/{{ $editForm['codice_univoco'] ?? '00000001' }}/documenti/</span></div> <div> Documenti: <span class="text-emerald-400">storage/app/private/amministratori/{{ $editForm['codice_univoco'] ?? '00000001' }}/documenti/</span></div>
<div> Percorso Backup SQLite DB: <span class="text-emerald-400">storage/app/private/amministratori/{{ $editForm['codice_univoco'] ?? '00000001' }}/database/backups/</span></div> <div> Backups SQLite: <span class="text-emerald-400">storage/app/private/amministratori/{{ $editForm['codice_univoco'] ?? '00000001' }}/database/backups/</span></div>
</div> </div>
</div> </div>
{{-- SALVATAGGIO IN-PLACE --}} {{-- PULSANTI DI AZIONE --}}
<div class="mt-5 flex flex-wrap items-center justify-between gap-3 border-t pt-4"> <div class="mt-5 flex flex-wrap items-center justify-between gap-3 border-t pt-4">
<button <button
type="button" type="button"
@ -201,65 +198,169 @@ class="inline-flex items-center rounded-lg bg-emerald-700 px-4 py-2 text-xs font
wire:click="impersonaSelected" wire:click="impersonaSelected"
class="inline-flex items-center gap-1 rounded-lg bg-amber-500 px-4 py-2 text-xs font-bold text-white hover:bg-amber-600 shadow" class="inline-flex items-center gap-1 rounded-lg bg-amber-500 px-4 py-2 text-xs font-bold text-white hover:bg-amber-600 shadow"
> >
IMPERSONA SENZA PASSWORD IMPERSONA STUDIO {{ strtoupper($editForm['cognome'] ?? '') }}
</button> </button>
</div> </div>
</div> </div>
@else @else
<div class="rounded-xl border bg-white p-8 text-center text-slate-500"> <div class="rounded-xl border bg-white p-8 text-center text-slate-500 text-sm">
Nessun amministratore selezionato. Torna al TAB 1 per selezionare una scheda. Nessun amministratore selezionato. Seleziona una riga nel TAB 1 per aprire la scheda qui.
</div> </div>
@endif @endif
@endif @endif
{{-- TAB 3: STABILI & FORNITORI STUDIO --}} {{-- TAB 3: 📊 STABILI & FORNITORI ASSEGNATI --}}
@if($activeTab === 'stabili') @if($activeTab === 'stabili')
<div class="rounded-xl border bg-white p-5 shadow-sm space-y-4"> <div class="rounded-xl border bg-white p-5 shadow-sm space-y-4">
<h3 class="text-base font-bold text-slate-900">Stabili & Fornitori dello Studio (#{{ $selectedAmministratoreId }})</h3> <h3 class="text-base font-bold text-slate-900">Stabili & Fornitori dello Studio (#{{ $selectedAmministratoreId }})</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 text-xs"> <div class="grid grid-cols-1 md:grid-cols-2 gap-4 text-xs">
<div class="rounded-lg border bg-slate-50 p-4"> <div class="rounded-lg border bg-slate-50 p-4">
<h4 class="font-bold text-slate-800 mb-2">Stabili Amministrati dallo Studio:</h4> <h4 class="font-bold text-slate-800 mb-2">🏢 Stabili Condominiali Gestiti:</h4>
<ul class="space-y-1 font-mono text-slate-700"> <ul class="space-y-1 font-mono text-slate-700">
<li> Stabile 0013 - CATONE 34 / GERMANICO 85</li> <li> Stabile 0010 - CATONE 34 / GERMANICO 85</li>
<li> Stabile 0017 - OTTAVIANO 105 / GIULIO CESARE</li> <li> Stabile 0013 - OTTAVIANO 105 / GIULIO CESARE</li>
<li> Stabile 0018 - GRACCHI 6</li>
<li> Stabile 0016 - GERMANICO 96</li> <li> Stabile 0016 - GERMANICO 96</li>
<li> Stabile 0018 - GRACCHI 6</li>
</ul> </ul>
</div> </div>
<div class="rounded-lg border bg-slate-50 p-4"> <div class="rounded-lg border bg-slate-50 p-4">
<h4 class="font-bold text-slate-800 mb-2">Fornitori Accreditati per lo Studio (#13 Cecilia Tordini):</h4> <h4 class="font-bold text-slate-800 mb-2">🛠️ Fornitori Accreditati per lo Studio:</h4>
<div class="text-slate-700"> <div class="text-slate-700">
Totale <strong>370 fornitori</strong> censiti ed isolati in via esclusiva per lo studio di Cecilia Tordini. Totale <strong>370 fornitori</strong> censiti ed isolati in via esclusiva per lo studio di Cecilia Tordini (#13).
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@endif @endif
{{-- TAB 4: MODULO IMPORTAZIONE MDB (ACL: import-gescon) --}} {{-- TAB 4: 🛡️ MODULI AVANZATI, LICENZE & DATE SCADENZA STUDIO --}}
@if($activeTab === 'importazione') @if($activeTab === 'moduli')
<div class="rounded-xl border border-emerald-300 bg-white p-5 shadow-sm space-y-4"> <div class="rounded-xl border border-emerald-300 bg-white p-5 shadow-sm space-y-4">
<div class="flex items-center justify-between border-b pb-3"> <div class="flex items-center justify-between border-b pb-3">
<div> <div>
<h3 class="text-base font-bold text-emerald-900">Modulo Importazione MDB Gescon (Autorizzato ACL: import-gescon)</h3> <h3 class="text-base font-bold text-emerald-900">Moduli Applicativi, Licenze & Date Scadenza Studio (#{{ $selectedAmministratoreId }})</h3>
<p class="text-xs text-slate-500">Seleziona e carica gli archivi MDB per la sincronizzazione differenziale dello studio selezionato.</p> <p class="text-xs text-slate-500">Attiva o disabilita le funzionalità avanzate per lo studio e configura la data di scadenza della licenza.</p>
</div> </div>
<span class="rounded-full bg-emerald-100 px-3 py-1 text-xs font-bold text-emerald-800"> <span class="rounded-full bg-emerald-100 px-3 py-1 text-xs font-bold text-emerald-800">
Modulo ACL Attivo SuperAdmin Control Center
</span> </span>
</div> </div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 text-xs"> <div class="space-y-3 text-xs">
<div class="rounded-lg border bg-emerald-50/50 p-4 space-y-2"> <div class="rounded-lg border p-3 flex flex-wrap items-center justify-between gap-2 bg-slate-50">
<label class="block font-bold text-slate-800">1. File Archivio Stabili MDB:</label> <div>
<input type="text" readonly value="/mnt/gescon-archives/gescon/dbc/Stabili.mdb" class="w-full rounded-md border-slate-300 text-xs font-mono bg-slate-100"> <span class="font-bold text-slate-800">📩 Scarico FE Cassetto Fiscale & XML SDI</span>
<button type="button" class="rounded-md bg-slate-800 px-3 py-1.5 text-white font-semibold">🔄 Sincronizza Stabili MDB</button> <div class="text-slate-500">Abilita lo scarico diretto delle fatture elettroniche dal cassetto fiscale dello stabile.</div>
</div>
<div class="flex items-center gap-3">
<span class="font-mono font-bold text-slate-700">Scadenza: 31/12/2027</span>
<button type="button" class="rounded-md bg-emerald-700 px-2.5 py-1 text-white font-bold">Attivo</button>
</div>
</div> </div>
<div class="rounded-lg border bg-emerald-50/50 p-4 space-y-2">
<label class="block font-bold text-slate-800">2. File Archivio Fornitori MDB:</label> <div class="rounded-lg border p-3 flex flex-wrap items-center justify-between gap-2 bg-slate-50">
<input type="text" readonly value="/mnt/gescon-archives/gescon/dbc/Fornitori.mdb" class="w-full rounded-md border-slate-300 text-xs font-mono bg-slate-100"> <div>
<button type="button" class="rounded-md bg-slate-800 px-3 py-1.5 text-white font-semibold">🔄 Sincronizza Fornitori MDB</button> <span class="font-bold text-slate-800">🏦 Integrazione Multi-Banca & Import CBI</span>
<div class="text-slate-500">Importazione ed abbinamento automatico flussi bancari CBI ed estratti conto.</div>
</div>
<div class="flex items-center gap-3">
<span class="font-mono font-bold text-slate-700">Scadenza: 31/12/2027</span>
<button type="button" class="rounded-md bg-emerald-700 px-2.5 py-1 text-white font-bold">Attivo</button>
</div>
</div> </div>
<div class="rounded-lg border p-3 flex flex-wrap items-center justify-between gap-2 bg-slate-50">
<div>
<span class="font-bold text-slate-800">Visure Catastali Sister & Planimetrie</span>
<div class="text-slate-500">Consultazione ed allineamento automatico dei dati catastali consolidati.</div>
</div>
<div class="flex items-center gap-3">
<span class="font-mono font-bold text-slate-700">Scadenza: 30/06/2027</span>
<button type="button" class="rounded-md bg-emerald-700 px-2.5 py-1 text-white font-bold">Attivo</button>
</div>
</div>
<div class="rounded-lg border p-3 flex flex-wrap items-center justify-between gap-2 bg-slate-50">
<div>
<span class="font-bold text-slate-800">🔄 Modulo Importazione Legacy MDB Gescon (import-gescon)</span>
<div class="text-slate-500">Pipeline di importazione Stabili.mdb e Fornitori.mdb per la migrazione.</div>
</div>
<div class="flex items-center gap-3">
<span class="font-mono font-bold text-slate-700">Scadenza: 31/12/2026</span>
<button type="button" class="rounded-md bg-emerald-700 px-2.5 py-1 text-white font-bold">Attivo</button>
</div>
</div>
</div>
<div class="pt-3 border-t">
<button type="button" class="rounded-lg bg-emerald-800 px-4 py-2 text-white text-xs font-bold shadow">
SALVA CONFIGURAZIONE LICENZE & SCADENZE
</button>
</div>
</div>
@endif
{{-- TAB 5: 🔑 MATRICE PERMESSI ACL & VISIBILITÀ MENÙ --}}
@if($activeTab === 'acl')
<div class="rounded-xl border border-sky-300 bg-white p-5 shadow-sm space-y-4">
<div class="flex items-center justify-between border-b pb-3">
<div>
<h3 class="text-base font-bold text-sky-900">Matrice Permessi ACL & Visibilità Menù (PostgreSQL / Laravel Spatie)</h3>
<p class="text-xs text-slate-500">Gestisci i permessi granulari ed i ruoli assegnati all'utente ed ai collaboratori dello studio.</p>
</div>
<span class="rounded-full bg-sky-100 px-3 py-1 text-xs font-bold text-sky-800">
ACL PostgreSQL Powered
</span>
</div>
<div class="rounded-lg border overflow-hidden">
<table class="w-full text-left text-xs">
<thead class="bg-slate-100 font-bold text-slate-800 border-b">
<tr>
<th class="p-3">MENÙ / SEZIONE DI SISTEMA</th>
<th class="p-3">LETTURA</th>
<th class="p-3">MODIFICA</th>
<th class="p-3">CANCELLAZIONE</th>
<th class="p-3">PERMESSO SPATIE</th>
</tr>
</thead>
<tbody class="divide-y font-mono">
<tr class="hover:bg-slate-50">
<td class="p-3 font-sans font-bold text-slate-900">🏢 Anagrafica Stabili & Unità Immobiliare</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-slate-400">[ ] Disabilitato</td>
<td class="p-3 font-mono text-slate-600">manage-stabili</td>
</tr>
<tr class="hover:bg-slate-50">
<td class="p-3 font-sans font-bold text-slate-900">👥 Condomini, Inquilini & Comproprietà</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-slate-400">[ ] Disabilitato</td>
<td class="p-3 font-mono text-slate-600">manage-condomini</td>
</tr>
<tr class="hover:bg-slate-50">
<td class="p-3 font-sans font-bold text-slate-900">🛠️ Anagrafica Fornitori Accreditati</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 font-mono text-slate-600">manage-fornitori</td>
</tr>
<tr class="hover:bg-slate-50">
<td class="p-3 font-sans font-bold text-slate-900">🔄 Modulo Importazione Legacy MDB Gescon</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-emerald-600 font-bold">[X] Abilitato</td>
<td class="p-3 text-slate-400">[ ] Disabilitato</td>
<td class="p-3 font-mono text-slate-600">import-gescon</td>
</tr>
</tbody>
</table>
</div>
<div class="pt-3 border-t">
<button type="button" class="rounded-lg bg-sky-800 px-4 py-2 text-white text-xs font-bold shadow">
SALVA MATRICE PERMESSI ACL
</button>
</div> </div>
</div> </div>
@endif @endif

View File

@ -41,6 +41,20 @@
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Route;
// --- Impersonation Leave Route ---
Route::get('/admin-filament/impersonate/leave', function () {
$impersonatorId = session('impersonator_id');
if ($impersonatorId) {
$superAdmin = \App\Models\User::find($impersonatorId);
if ($superAdmin) {
session()->forget('impersonator_id');
Auth::guard('web')->login($superAdmin, true);
request()->session()->regenerate();
}
}
return redirect('/admin-filament/superadmin/amministratori');
})->name('impersonate.leave');
// --- Public Routes --- // --- Public Routes ---
Route::get('/public/assemblea/{token}', [\App\Http\Controllers\Condomino\AssembleaConvocazioneController::class, 'show'])->name('public.assemblea.show'); Route::get('/public/assemblea/{token}', [\App\Http\Controllers\Condomino\AssembleaConvocazioneController::class, 'show'])->name('public.assemblea.show');
Route::post('/public/assemblea/{token}/ricezione', [\App\Http\Controllers\Condomino\AssembleaConvocazioneController::class, 'confermaRicezione'])->name('public.assemblea.ricezione'); Route::post('/public/assemblea/{token}/ricezione', [\App\Http\Controllers\Condomino\AssembleaConvocazioneController::class, 'confermaRicezione'])->name('public.assemblea.ricezione');
@ -55,6 +69,37 @@
Route::post('/public/anagrafica/aggiornamento', [\App\Http\Controllers\AnagraficaAggiornamentoController::class, 'store'])->name('anagrafica.update.store'); Route::post('/public/anagrafica/aggiornamento', [\App\Http\Controllers\AnagraficaAggiornamentoController::class, 'store'])->name('anagrafica.update.store');
Route::get('/public/anagrafica/aggiornamento/{token}/pdf', [\App\Http\Controllers\AnagraficaAggiornamentoController::class, 'exportPdf'])->name('anagrafica.update.pdf'); Route::get('/public/anagrafica/aggiornamento/{token}/pdf', [\App\Http\Controllers\AnagraficaAggiornamentoController::class, 'exportPdf'])->name('anagrafica.update.pdf');
Route::get('/public/amazon', function () {
return response()->json([
'status' => 'success',
'service' => 'Amazon Product Advertising API 5.0 (PA-API v5)',
'portal' => 'https://programma-affiliazione.amazon.it/',
'documentation_url' => 'https://webservices.amazon.com/paapi5/documentation/',
'endpoints' => [
'base_url' => 'https://webservices.amazon.it',
'search_items' => 'https://webservices.amazon.it/paapi5/searchitems',
'get_items' => 'https://webservices.amazon.it/paapi5/getitems',
'get_variations' => 'https://webservices.amazon.it/paapi5/getvariations',
],
'authentication' => [
'type' => 'AWS Signature Version 4 (AWS4-HMAC-SHA256)',
'note' => 'NON usare OAuth 2.0 / Bearer Tokens (causa errore 403/404). Occorre firmare con AWS SigV4.',
'required_headers' => [
'Content-Type' => 'application/json; charset=UTF-8',
'Content-Encoding' => 'amz-1.0',
'X-Amz-Target' => 'com.amazon.paapi5.v1.ProductAdvertisingAPIv1.SearchItems',
'X-Amz-Date' => 'YYYYMMDDTHHMMSSZ',
'Authorization' => 'AWS4-HMAC-SHA256 Credential=YOUR_ACCESS_KEY/YYYYMMDD/eu-west-1/ProductAdvertisingAPI/aws4_request, SignedHeaders=..., Signature=...'
]
],
'official_sdks' => [
'python' => 'paapi5-python-sdk',
'php' => 'paapi5-php-sdk',
'nodejs' => 'paapi5-nodejs-sdk'
]
]);
});
Route::get('/', function () { Route::get('/', function () {
return redirect('/admin-filament'); return redirect('/admin-filament');
}); });

View File

@ -1,6 +1,16 @@
# ASCII Wireframe - Gestione Amministratori Stabili con Menu a Tab (/admin-filament/superadmin/amministratori) # ASCII Wireframe - Gestione Amministratori SuperAdmin con Menu a TAB Compatti, Sticky Header Banner & Matrice ACL
## 1. TAB 1: ELENCO AMMINISTRATORI CENSITI ## 0. STICKY HEADER BANNER - IMPERSONIFICAZIONE CONTESTUALE ATTIVA (Visibile in ogni pagina quando si opera come Amministratore)
```text
+-------------------------------------------------------------------------------------------------------------------+
| ⚠️ MODALITÀ IMPERSONIFICAZIONE ATTIVA: Stai operando come STUDIO TORDINI CECILIA (ID #13) [ ↩️ TORNA A SUPER ADMIN ]|
+-------------------------------------------------------------------------------------------------------------------+
```
---
## 1. TAB 1: 🏢 ELENCO AMMINISTRATORI (Comandi Iconici Ultra-Compatti Senza Scroll Orizzontale)
```text ```text
+-------------------------------------------------------------------------------------------------------------------+ +-------------------------------------------------------------------------------------------------------------------+
@ -8,37 +18,38 @@ ## 1. TAB 1: ELENCO AMMINISTRATORI CENSITI
+-------------------------------------------------------------------------------------------------------------------+ +-------------------------------------------------------------------------------------------------------------------+
| PATH: Home > Super Admin > Gestione Amministratori Stabili | | PATH: Home > Super Admin > Gestione Amministratori Stabili |
+-------------------------------------------------------------------------------------------------------------------+ +-------------------------------------------------------------------------------------------------------------------+
| NAVIGAZIONE A TAB SEPARATI: | | BARRA PULSANTINI ICONICI COMPATTI (SENZA SCROLL ORIZZONTALE): |
| [ TAB 1: ELENCO AMMINISTRATORI (Attivo) ] [ TAB 2: SCHEDA & MODIFICA ] [ TAB 3: STABILI & FORNITORI ] | | [ 🏢 Elenco ] [ ✏️ Modifica (#13) ] [ 📊 Stabili ] [ 🛡️ Moduli & Scadenze ] [ 🔑 Matrice ACL ] |
| [ TAB 4: MODULO IMPORTAZIONE MDB (ACL: import-gescon) ] |
+-------------------------------------------------------------------------------------------------------------------+ +-------------------------------------------------------------------------------------------------------------------+
| | | |
| [ + NUOVO AMMINISTRATORE ] [ 🔄 IMPORTA DA STABILI.MDB ] [ 🔍 Cerca per Nome, Cognome, CF, Studio... ] | | [ + NUOVO ] [ 🔄 IMPORTA MDB ] [ 🔍 Cerca per Nome, Cognome, CF, Studio... ] |
| | | |
| +----+----------+---------------------------+---------------------------------+---------+------------+------------+ | +----+----------+---------------------------+---------------------------------+---------+------------+------------+
| | ID | CODICE | NOMINATIVO AMMINISTRATORE | STUDIO / INTESTAZIONE | STABILI | FE CASSETTO| AZIONI | | | ID | CODICE | NOMINATIVO AMMINISTRATORE | STUDIO / INTESTAZIONE | STABILI | FE CASSETTO| AZIONI |
| +----+----------+---------------------------+---------------------------------+---------+------------+------------+ | +----+----------+---------------------------+---------------------------------+---------+------------+------------+
| | 13 | 00000001 | Tordini Cecilia | Studio Tordini Cecilia | 12 | [Attivo] | [Apri Tab2]| | | 13 | 00000001 | Tordini Cecilia | Studio Tordini Cecilia | 12 | [Attivo] | [Modifica] |
| | | | (cecilia.tordini@gmail.com)| | | | [⚡Impersona| | | | | (cecilia.tordini@gmail.com)| | | | [⚡Impersona|
| | 14 | 00000002 | BARONE MICHELE | Studio BARONE MICHELE | 8 | [Attivo] | [Apri Tab2]| | | 14 | 00000002 | BARONE MICHELE | Studio BARONE MICHELE | 8 | [Attivo] | [Modifica] |
| | | | | | | | [⚡Impersona| | | | | | | | | [⚡Impersona|
| | 15 | 00000003 | Conforti Ignazio Vittorio | Studio Conforti Ignazio | 14 | [Attivo] | [Apri Tab2]| | | 15 | 00000003 | Conforti Ignazio Vittorio | Studio Conforti Ignazio | 14 | [Attivo] | [Modifica] |
| | 16 | 00000004 | Roscioli Anna Maria | Studio Roscioli Anna Maria | 6 | [Attivo] | [Apri Tab2]| | | 16 | 00000004 | Roscioli Anna Maria | Studio Roscioli Anna Maria | 6 | [Attivo] | [Modifica] |
| +----+----------+---------------------------+---------------------------------+---------+------------+------------+ | +----+----------+---------------------------+---------------------------------+---------+------------+------------+
| Mostrati 4 di 4 amministratori censiti negli archivi di sistema | | * NOTA: Cliccando su [✏️ Modifica], il sistema seleziona l'amministratore e passa IMMEDIATAMENTE al TAB 2. |
+-------------------------------------------------------------------------------------------------------------------+ +-------------------------------------------------------------------------------------------------------------------+
``` ```
## 2. TAB 2: SCHEDA DETTAGLIO & EDITING IN-PLACE (AMMINISTRATORE SELEZIONATO: #13 TORDINI CECILIA) ---
## 2. TAB 2: ✏️ SCHEDA & MODIFICA INLINE (Automagicamente Attivato al Click su Modifica)
```text ```text
+-------------------------------------------------------------------------------------------------------------------+ +-------------------------------------------------------------------------------------------------------------------+
| NAVIGAZIONE A TAB SEPARATI: | | BARRA PULSANTINI ICONICI COMPATTI: |
| [ TAB 1: ELENCO AMMINISTRATORI ] [ TAB 2: SCHEDA & MODIFICA (Attivo: #13) ] [ TAB 3: STABILI & FORNITORI ] | | [ 🏢 Elenco ] [ ✏️ Modifica (Attivo: #13 Tordini Cecilia) ] [ 📊 Stabili ] [ 🛡️ Moduli ] [ 🔑 ACL ] |
+-------------------------------------------------------------------------------------------------------------------+ +-------------------------------------------------------------------------------------------------------------------+
| DETTAGLIO SCHEDA AMMINISTRATORE (#13 TORDINI CECILIA) | | SCHEDA ANAGRAFICA ED IN-PLACE EDITING (#13 TORDINI CECILIA) |
| | | |
| UTENTE DI SISTEMA COLLEGATO: cecilia.tordini@gmail.com (Ruoli: Amministratore, Admin) | | UTENTE LOGIN COLLEGATO: cecilia.tordini@gmail.com (Stato: Attivo - Password Configurata) |
| | | |
| [ Nome: Cecilia ] [ Cognome: Tordini ] | | [ Nome: Cecilia ] [ Cognome: Tordini ] |
| [ Denominazione Studio: Studio Tordini Cecilia ] | | [ Denominazione Studio: Studio Tordini Cecilia ] |
@ -47,31 +58,91 @@ ## 2. TAB 2: SCHEDA DETTAGLIO & EDITING IN-PLACE (AMMINISTRATORE SELEZIONATO: #1
| [ Email Login: cecilia.tordini@gmail.com ] [ PEC: cecilia.tordini@pec.it ] | | [ Email Login: cecilia.tordini@gmail.com ] [ PEC: cecilia.tordini@pec.it ] |
| [ Telefono Studio: 06-12345678 ] [ Cellulare Studio: 335-1234567 ] | | [ Telefono Studio: 06-12345678 ] [ Cellulare Studio: 335-1234567 ] |
| | | |
| PERCORSI ARCHIVIO TENANT & BACKUP DEDICATO (CANONICO SYSTEM HASH): | | PERCORSI ARCHIVIO TENANT CANONICI: |
| • Percorso Cartella Stabile: storage/app/private/amministratori/00000001/ | | • Cartella Stabile: storage/app/private/amministratori/00000001/ |
| • Percorso Documenti Stabile: storage/app/private/amministratori/00000001/documenti/ | | • Documenti: storage/app/private/amministratori/00000001/documenti/ |
| • Percorso Backup SQLite DB: storage/app/private/amministratori/00000001/database/backups/ | | • Backups SQLite: storage/app/private/amministratori/00000001/database/backups/ |
| | | |
| PULSANTI DI AZIONE COMPATTI (SENZA SCROLL ORIZZONTALE): | | PULSANTI DI AZIONE RAPIDA: |
| [ ✓ SALVA SCHEDA ] [ ⚡ IMPERSONA SENZA PASSWORD ] [ 📧 INVIA CREDIENZIALI ] [ 🔑 RESET PASSWORD ] | | [ ✓ SALVA SCHEDA ] [ ⚡ IMPERSONA STUDIO ] [ 📧 INVIA CREDIENZIALI ] [ 🔑 RESET PASSWORD ] |
+-------------------------------------------------------------------------------------------------------------------+ +-------------------------------------------------------------------------------------------------------------------+
``` ```
## 3. TAB 4: MODULO IMPORTAZIONE LEGACY MDB (SCOPED ALL'AMMINISTRATORE - ACL: import-gescon) ---
## 3. TAB 3: 📊 STABILI & FORNITORI ASSEGNATI ALLO STUDIO (#13)
```text ```text
+-------------------------------------------------------------------------------------------------------------------+ +-------------------------------------------------------------------------------------------------------------------+
| NAVIGAZIONE A TAB SEPARATI: | | BARRA PULSANTINI ICONICI COMPATTI: |
| [ TAB 1: ELENCO ] [ TAB 2: SCHEDA ] [ TAB 3: STABILI & FORNITORI ] [ TAB 4: MODULO IMPORTAZIONE MDB (Attivo) ]| | [ 🏢 Elenco ] [ ✏️ Modifica ] [ 📊 Stabili (Attivo: #13 Tordini Cecilia) ] [ 🛡️ Moduli ] [ 🔑 ACL ] |
+-------------------------------------------------------------------------------------------------------------------+ +-------------------------------------------------------------------------------------------------------------------+
| SELEZIONE E CARICAMENTO ARCHIVI LEGACY MDB PER LO STUDIO: TORDINI CECILIA (#13) | | STABILI E ARCHIVIO FORNITORI RISERVATI DELLO STUDIO #13 |
| | | |
| 1. FILE ARCHIVIO STABILI: [ /mnt/gescon-archives/gescon/dbc/Stabili.mdb ▾ ] [ 🔄 AVVIA IMPORT STABILI ] | | 🏢 STABILI CONDOMINIALI GESTITI (12 STABILI): |
| 2. FILE ARCHIVIO FORNITORI: [ /mnt/gescon-archives/gescon/dbc/Fornitori.mdb ▾ ] [ 🔄 AVVIA IMPORT FORNITORI ] | | +------+-----------------------------------------------+-------------------+-----------------------------------+ |
| | COD. | DENOMINAZIONE STABILE | CODICE FISCALE | BANCA PRINCIPALE & IBAN | |
| +------+-----------------------------------------------+-------------------+-----------------------------------+ |
| | 0010 | CATONE 34 - GERMANICO 85 - GRACCHI 32 | 80123456789 | SAN PAOLO: IT26Z03069050771... | |
| | 0013 | OTTAVIANO 105 - GIULIO CESARE 171 | 80987654321 | SAN PAOLO: IT26Z03069050771... | |
| | 0016 | GERMANICO 96 | 97112233445 | FUCINO: IT48W0312403203... | |
| +------+-----------------------------------------------+-------------------+-----------------------------------+ |
| | | |
| STATO IMPORTAZIONE ARCHIVIO STUDIO TORDINI CECILIA: | | 🛠️ FORNITORI ACCREDITATI ESCLUSIVI PER LO STUDIO: |
| • Stabili importati e collegati: 12 stabili condominiali | | • Totale Fornitori Censiti: 370 ditte / professionisti (Isolati per lo studio di Cecilia Tordini) |
| • Fornitori accreditati per lo studio: 387 ditte/professionisti (Trib 1019/1020 ok) | | • Matching Fatture Elettroniche (FE): Attivo tramite Codice Fiscale Stabile / P.IVA Fornitore |
| • Modalità Coesistenza: Dual-Run Incrementale (Sorgente autoritativa: Legacy MDB -> NetGescon DB) | +-------------------------------------------------------------------------------------------------------------------+
```
---
## 4. TAB 4: 🛡️ MODULI AVANZATI, LICENZE & DATE DI SCADENZA STUDIO
```text
+-------------------------------------------------------------------------------------------------------------------+
| BARRA PULSANTINI ICONICI COMPATTI: |
| [ 🏢 Elenco ] [ ✏️ Modifica ] [ 📊 Stabili ] [ 🛡️ Moduli & Scadenze (Attivo: #13) ] [ 🔑 ACL ] |
+-------------------------------------------------------------------------------------------------------------------+
| GESTIONE MODULI ABILITATI E DATE DI SCADENZA LICENZA STUDIO #13 |
| |
| +-----------------------------------------------+----------+--------------------+--------------------------------+ |
| | MODULO / ABILITAZIONE APPLICATIVA | STATO | DATA SCADENZA | AZIONE SUPERADMIN | |
| +-----------------------------------------------+----------+--------------------+--------------------------------+ |
| | 📩 Scarico FE Cassetto Fiscale & XML SDI | [Attivo] | 31/12/2027 | [Rinnova] [Disabilita] | |
| | 🏦 Integrazione Multi-Banca & Import CBI | [Attivo] | 31/12/2027 | [Rinnova] [Disabilita] | |
| | 📑 Visure Catastali Sister & Planimetrie | [Attivo] | 30/06/2027 | [Rinnova] [Disabilita] | |
| | 📞 Integrazione Centralino PBX / CTI | [Disab.] | --/--/---- | [Attiva Modulo] | |
| | 📊 Consuntivi & Bilanci Straordinari Multi-Anno| [Attivo] | Illimitato | [Gestisci Scadenza] | |
| | 🔄 Pipeline Importazione Legacy MDB Gescon | [Attivo] | 31/12/2026 | [Rinnova Permesso] | |
| +-----------------------------------------------+----------+--------------------+--------------------------------+ |
| |
| [ ✓ SALVA CONFIGURAZIONE MODULI & SCADENZE ] |
+-------------------------------------------------------------------------------------------------------------------+
```
---
## 5. TAB 5: 🔑 MATRICE PERMESSI ACL & VISIBILITÀ MENÙ (PostgreSQL / Laravel Spatie)
```text
+-------------------------------------------------------------------------------------------------------------------+
| BARRA PULSANTINI ICONICI COMPATTI: |
| [ 🏢 Elenco ] [ ✏️ Modifica ] [ 📊 Stabili ] [ 🛡️ Moduli ] [ 🔑 Matrice ACL (Attivo: #13) ] |
+-------------------------------------------------------------------------------------------------------------------+
| CONFIGURAZIONE ACL PERMESSI E VISIBILITÀ MENÙ DI SISTEMA PER STUDIO #13 |
| |
| MATRICE PERMESSI MODULARI (SPATIE ACL SU POSTGRESQL DB): |
| +-----------------------------------------------+---------------------------------------------------------------+ |
| | MENÙ / SEZIONE DI SISTEMA | PERMESSI ASSEGNATI ALL'UTENTE COLLABORATORE STUDIO | |
| +-----------------------------------------------+---------------------------------------------------------------+ |
| | 🏢 Anagrafica Stabili & Unità Immobiliare | [X] Lettura [X] Modifica [ ] Cancellazione | |
| | 👥 Condomini, Inquilini & Comproprietà | [X] Lettura [X] Modifica [ ] Gestione Quote | |
| | 🛠️ Anagrafica Fornitori Accreditati | [X] Lettura [X] Modifica [X] Inserimento Nuovo | |
| | 📄 Fatture Elettroniche & Registri | [X] Lettura [X] Import FE [ ] Approvazione Pagamento | |
| | 🏛️ Tabelle Millesimali & Voci di Spesa | [X] Lettura [ ] Modifica Millesimi | |
| | 🔄 Modulo Importazione Legacy MDB (import-gescon)| [X] Abilitato per Import Stabili e Fornitori MDB | |
| +-----------------------------------------------+---------------------------------------------------------------+ |
| |
| [ ✓ AGGIORNA E SALVA MATRICE PERMESSI ACL ] |
+-------------------------------------------------------------------------------------------------------------------+ +-------------------------------------------------------------------------------------------------------------------+
``` ```