netgescon-day0/routes/web.php

788 lines
60 KiB
PHP
Executable File

<?php
use App\Http\Controllers\Admin\AcquaRipartizionePrintController;
use App\Http\Controllers\Admin\ApiTokenController;
use App\Http\Controllers\Admin\BilancioController;
use App\Http\Controllers\Admin\DashboardController;
use App\Http\Controllers\Admin\DatiBancariController;
use App\Http\Controllers\Admin\DocumentoCollegatoController;
use App\Http\Controllers\Admin\DocumentoController;
use App\Http\Controllers\Admin\FilamentBridgeController;
use App\Http\Controllers\Admin\FornitoreController;
use App\Http\Controllers\Admin\GestioneAttivaController;
use App\Http\Controllers\Admin\ImpostazioniController;
use App\Http\Controllers\Admin\InsurancePolicyAssetViewController;
use App\Http\Controllers\Admin\PianoRateizzazioneController;
use App\Http\Controllers\Admin\PreventivoController;
use App\Http\Controllers\Admin\RataController;
use App\Http\Controllers\Admin\RipartizioneSpesaController;
use App\Http\Controllers\Admin\RubricaUniversaleController;
use App\Http\Controllers\Admin\SoggettoController;
use App\Http\Controllers\Admin\StabileAttivoController;
use App\Http\Controllers\Admin\StabileController;
use App\Http\Controllers\Admin\TicketAttachmentViewController;
use App\Http\Controllers\Admin\TicketController;
use App\Http\Controllers\Admin\TicketInterventoController;
use App\Http\Controllers\Admin\UnitaImmobiliareController;
use App\Http\Controllers\Admin\VoceSpesaController;
use App\Http\Controllers\Condomino\AnagrafeController as CondominoAnagrafeController;
use App\Http\Controllers\Condomino\DashboardController as CondominoDashboardController;
use App\Http\Controllers\Condomino\DocumentoController as CondominoDocumentoController;
use App\Http\Controllers\Condomino\TicketController as CondominoTicketController;
use App\Http\Controllers\Condomino\UnitaController as CondominoUnitaController;
use App\Http\Controllers\Fornitore\TicketOperativoController as FornitoreTicketOperativoController;
use App\Http\Controllers\Integrations\GoogleOAuthController;
use App\Http\Controllers\ProfileController;
use App\Http\Controllers\SuperAdmin\AmministratoreController as SuperAdminAmministratoreController;
use App\Http\Controllers\SuperAdmin\CategoriaTicketController;
use App\Http\Controllers\SuperAdmin\DiagnosticaFattureElettronicheController;
use App\Http\Controllers\SuperAdmin\UserController as SuperAdminUserController;
use App\Models\TicketIntervento;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
// --- Public Routes ---
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}/vota', [\App\Http\Controllers\Condomino\AssembleaConvocazioneController::class, 'vota'])->name('public.assemblea.vota');
Route::get('/public/assemblea/{token}/poll', [\App\Http\Controllers\Condomino\AssembleaConvocazioneController::class, 'pollVotazioneAttiva'])->name('public.assemblea.poll');
Route::get('/', function () {
return redirect('/admin-filament');
});
Route::prefix('public/amazon')->name('public.amazon.')->group(function () {
Route::get('/', [\App\Http\Controllers\PublicAccess\AmazonReferralController::class, 'index'])->name('index');
Route::get('/go', [\App\Http\Controllers\PublicAccess\AmazonReferralController::class, 'go'])->name('go');
});
Route::middleware('signed')->prefix('public/letture-acqua')->name('public.water-reading.')->group(function () {
Route::get('/', [\App\Http\Controllers\PublicAccess\WaterReadingRequestController::class, 'show'])->name('show');
Route::post('/', [\App\Http\Controllers\PublicAccess\WaterReadingRequestController::class, 'store'])->name('store');
});
// --- Authenticated Routes ---
Route::middleware(['auth', 'verified'])->group(function () {
// OAuth Google (Calendar / Rubrica)
Route::middleware(['role:super-admin|admin|amministratore|fornitore'])
->prefix('oauth/google')
->name('oauth.google.')
->group(function () {
Route::get('/redirect', [GoogleOAuthController::class, 'redirect'])->name('redirect');
Route::get('/callback', [GoogleOAuthController::class, 'callback'])->name('callback');
Route::post('/disconnect', [GoogleOAuthController::class, 'disconnect'])->name('disconnect');
});
// Generic Dashboard (redirects to the correct panel based on role)
Route::get('/dashboard', function () {
if (Auth::check()) {
$user = Auth::user();
if ($user instanceof \App\Models\User && $user->hasRole('super-admin')) {
return redirect('/admin-filament');
}
if ($user instanceof \App\Models\User && ($user->hasRole('amministratore') || $user->hasRole('admin'))) {
return redirect('/admin-filament');
}
if ($user instanceof \App\Models\User && $user->hasRole('collaboratore')) {
// Collaboratore (profilo 4) condivide la dashboard admin ma con meno permessi
return redirect('/admin-filament');
}
if ($user instanceof \App\Models\User && ($user->hasRole('condomino') || $user->hasRole('inquilino'))) {
return redirect()->route('condomino.dashboard');
}
if ($user instanceof \App\Models\User && $user->hasRole('fornitore')) {
return redirect()->to(\App\Filament\Pages\Fornitore\TicketOperativi::getUrl(panel: 'admin-filament'));
}
}
// Fallback ad una semplice dashboard neutra se manca ruolo/vista
return view('dashboard');
})->name('dashboard');
// Profile Routes
Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
Route::post('/profile/two-factor/enable', [ProfileController::class, 'twoFactorEnable'])->name('profile.two-factor.enable');
Route::post('/profile/two-factor/confirm', [ProfileController::class, 'twoFactorConfirm'])->name('profile.two-factor.confirm');
Route::post('/profile/two-factor/disable', [ProfileController::class, 'twoFactorDisable'])->name('profile.two-factor.disable');
// --- SUPER-ADMIN PANEL ---
Route::middleware(['role:super-admin'])->prefix('superadmin')->name('superadmin.')->group(function () {
Route::get('/', function () {
return redirect('/admin-filament');
})->name('dashboard');
// Gestione utenti
Route::resource('users', SuperAdminUserController::class)->except(['show']);
Route::patch('users/{user}/update-role', [SuperAdminUserController::class, 'updateRole'])->name('users.updateRole');
Route::get('users/{user}/impersonate', [SuperAdminUserController::class, 'impersonate'])->name('users.impersonate');
Route::post('users/{user}/approve', [SuperAdminUserController::class, 'approve'])->name('users.approve');
Route::post('users/{user}/reject', [SuperAdminUserController::class, 'reject'])->name('users.reject');
Route::post('users/{user}/toggle-active', [SuperAdminUserController::class, 'toggleActive'])->name('users.toggle-active');
Route::post('users/{user}/assign-plan', [SuperAdminUserController::class, 'assignPlan'])->name('users.assign-plan');
// Impostazioni Sistema
Route::get('impostazioni', [\App\Http\Controllers\SuperAdmin\ImpostazioniController::class, 'index'])->name('impostazioni.index');
Route::post('impostazioni', [\App\Http\Controllers\SuperAdmin\ImpostazioniController::class, 'store'])->name('impostazioni.store');
Route::post('impostazioni/theme', [\App\Http\Controllers\SuperAdmin\ImpostazioniController::class, 'theme'])->name('impostazioni.theme');
// Gestione Amministratori
Route::resource('amministratori', SuperAdminAmministratoreController::class)
->except(['show'])
->parameters(['amministratori' => 'amministratore']);
// Azioni rapide Amministratori (toggle import, provision DB)
Route::post('amministratori/{amministratore}/toggle-import', [SuperAdminAmministratoreController::class, 'toggleImportAbility'])
->name('amministratori.toggle-import');
Route::post('amministratori/{amministratore}/provision-db', [SuperAdminAmministratoreController::class, 'provisionDatabase'])
->name('amministratori.provision-db');
// Gestione Categorie Ticket
Route::resource('categorie-ticket', CategoriaTicketController::class)->except(['show']);
// Gestione Stabili (ora anche per super-admin)
Route::resource('stabili', StabileController::class)
->parameters(['stabili' => 'stabile']);
Route::get('stabili/{stabile}/tabs/{tab}', [StabileController::class, 'getTab'])->name('stabili.tabs');
Route::get('stabili/{stabile}/unita-immobiliari', [StabileController::class, 'getUnitaImmobiliari'])->name('stabili.unita_immobiliari');
Route::resource('stabili.unitaImmobiliari', UnitaImmobiliareController::class)->shallow();
Route::resource('unitaImmobiliari', UnitaImmobiliareController::class)->only(['edit', 'update', 'destroy']);
// Gestione Palazzine per Super Admin
Route::resource('palazzine', \App\Http\Controllers\Admin\PalazzineController::class);
Route::get('palazzine/{palazzina}/genera-unita', [\App\Http\Controllers\Admin\PalazzineController::class, 'generaUnita'])->name('palazzine.genera-unita');
Route::get('palazzine/{palazzina}/anteprima-generazione', [\App\Http\Controllers\Admin\PalazzineController::class, 'anteprimaGenerazione'])->name('palazzine.anteprima-generazione');
Route::resource('soggetti', SoggettoController::class)->parameters(['soggetti' => 'soggetto']);
Route::resource('fornitori', FornitoreController::class);
Route::resource('tickets', TicketController::class);
Route::post('tickets/{ticket}/close', [TicketController::class, 'close'])->name('tickets.close');
Route::post('tickets/{ticket}/insurance/open', [TicketController::class, 'openInsuranceClaim'])->name('tickets.insurance.open');
Route::post('tickets/{ticket}/email-message', [TicketController::class, 'storeEmailMessage'])->name('tickets.email-message.store');
Route::get('tickets/attachments/{attachment}/view', [TicketAttachmentViewController::class, 'show'])->name('tickets.attachments.view');
Route::get('insurance-policies/{policy}/assets/{asset}', [InsurancePolicyAssetViewController::class, 'show'])->name('insurance.policies.assets.view');
Route::post('tickets/{ticket}/interventi', [TicketInterventoController::class, 'store'])->name('tickets.interventi.store');
Route::post('tickets/{ticket}/interventi/{intervento}/verify', [TicketInterventoController::class, 'verify'])->name('tickets.interventi.verify');
Route::post('tickets/{ticket}/interventi/{intervento}/invoice', [TicketInterventoController::class, 'invoice'])->name('tickets.interventi.invoice');
Route::post('tickets/{ticket}/interventi/{intervento}/close', [TicketInterventoController::class, 'close'])->name('tickets.interventi.close');
Route::resource('documenti', DocumentoController::class)->except(['edit', 'update']);
// Diagnostica
Route::get('/diagnostica', function () {
return view('superadmin.diagnostica');
})->name('diagnostica');
Route::get('/diagnostica-menu', function () {
return view('superadmin.diagnostica_menu');
})->name('diagnostica_menu');
Route::get('/diagnostica-fatture-elettroniche', [DiagnosticaFattureElettronicheController::class, 'index'])
->name('diagnostica_fatture_elettroniche');
});
Route::middleware(['role:super-admin|admin|amministratore|collaboratore|fornitore'])->prefix('admin')->name('admin.')->group(function () {
// Fatture elettroniche ricevute (azioni)
Route::get('acqua-ripartizione/print', [AcquaRipartizionePrintController::class, 'print'])->name('acqua-ripartizione.print');
Route::get('acqua-ripartizione/pdf', [AcquaRipartizionePrintController::class, 'pdf'])->name('acqua-ripartizione.pdf');
Route::get('fatture-elettroniche/{fattura}/download-xml', [\App\Http\Controllers\Admin\FattureElettronicheRicevuteController::class, 'downloadXml'])
->name('fatture-elettroniche.download-xml');
Route::get('fatture-elettroniche/{fattura}/download-pdf', [\App\Http\Controllers\Admin\FattureElettronicheRicevuteController::class, 'downloadPdf'])
->name('fatture-elettroniche.download-pdf');
});
// --- ADMIN / AMMINISTRATORE PANEL ---
Route::middleware(['role:super-admin|admin|amministratore|collaboratore'])->prefix('admin')->name('admin.')->group(function () {
// Dashboard dell'amministratore
if ((bool) config('netgescon.ui.force_filament', false)) {
Route::redirect('/', '/admin-filament')->name('dashboard');
Route::redirect('/mobile', '/admin-filament/supporto/ticket-mobile')->name('mobile');
Route::redirect('/tickets-mobile', '/admin-filament/supporto/ticket-mobile')->name('tickets.mobile');
} else {
Route::get('/', [DashboardController::class, 'index'])->name('dashboard');
Route::get('/mobile', [\App\Http\Controllers\Admin\MobileHubController::class, 'index'])->name('mobile');
Route::get('/tickets-mobile', [\App\Http\Controllers\Admin\MobileHubController::class, 'index'])->name('tickets.mobile');
}
// Bridge UI classica -> Filament (imposta stabile attivo e redirige)
Route::get('filament/stabili/{stabile}', [FilamentBridgeController::class, 'openStabile'])
->name('filament.stabili.open');
// Dashboard per categorie del menu
Route::prefix('dashboards')->name('dashboards.')->group(function () {
Route::get('/stabili', [\App\Http\Controllers\Admin\CategoryDashboardController::class, 'stabili'])->name('stabili');
Route::get('/condomini', [\App\Http\Controllers\Admin\CategoryDashboardController::class, 'condomini'])->name('condomini');
Route::get('/amministrazione', [\App\Http\Controllers\Admin\CategoryDashboardController::class, 'amministrazione'])->name('amministrazione');
Route::get('/contabilita', [\App\Http\Controllers\Admin\CategoryDashboardController::class, 'contabilita'])->name('contabilita');
Route::get('/economica', [\App\Http\Controllers\Admin\CategoryDashboardController::class, 'economica'])->name('economica');
Route::get('/supporto', [\App\Http\Controllers\Admin\CategoryDashboardController::class, 'supporto'])->name('supporto');
});
// Demo anagrafica unica (dati da staging condomin)
Route::get('/anagrafica/demo', [\App\Http\Controllers\Admin\AnagraficaDemoController::class, 'show'])->name('anagrafica.demo');
// Rubrica Unica NetGescon
Route::prefix('rubrica')->name('rubrica.')->group(function () {
Route::get('/', [\App\Http\Controllers\Admin\RubricaUnicaController::class, 'index'])->name('index');
Route::get('/create', [\App\Http\Controllers\Admin\RubricaUnicaController::class, 'create'])->name('create');
Route::post('/', [\App\Http\Controllers\Admin\RubricaUnicaController::class, 'store'])->name('store');
Route::get('/{persona}', [\App\Http\Controllers\Admin\RubricaUnicaController::class, 'show'])->name('show');
Route::get('/{persona}/edit', [\App\Http\Controllers\Admin\RubricaUnicaController::class, 'edit'])->name('edit');
Route::put('/{persona}', [\App\Http\Controllers\Admin\RubricaUnicaController::class, 'update'])->name('update');
Route::get('/search/api', [\App\Http\Controllers\Admin\RubricaUnicaController::class, 'apiSearch'])->name('api.search');
Route::post('/merge', [\App\Http\Controllers\Admin\RubricaUnicaController::class, 'merge'])->name('merge');
});
// Gestione Relazioni Persona-Unità Immobiliare
Route::prefix('persona-unita')->name('persona-unita.')->group(function () {
Route::get('/', [\App\Http\Controllers\Admin\PersonaUnitaController::class, 'index'])->name('index');
Route::get('/create', [\App\Http\Controllers\Admin\PersonaUnitaController::class, 'create'])->name('create');
Route::post('/', [\App\Http\Controllers\Admin\PersonaUnitaController::class, 'store'])->name('store');
Route::get('/{personaUnita}', [\App\Http\Controllers\Admin\PersonaUnitaController::class, 'show'])->name('show');
Route::get('/{personaUnita}/edit', [\App\Http\Controllers\Admin\PersonaUnitaController::class, 'edit'])->name('edit');
Route::put('/{personaUnita}', [\App\Http\Controllers\Admin\PersonaUnitaController::class, 'update'])->name('update');
Route::delete('/{personaUnita}', [\App\Http\Controllers\Admin\PersonaUnitaController::class, 'destroy'])->name('destroy');
// API Routes
Route::get('/api/unita-by-persona/{persona}', [\App\Http\Controllers\Admin\PersonaUnitaController::class, 'getUnitaByPersona'])->name('api.unita-by-persona');
Route::get('/api/persone-by-unita/{unita}', [\App\Http\Controllers\Admin\PersonaUnitaController::class, 'getPersoneByUnita'])->name('api.persone-by-unita');
});
// Gestione Tabelle Millesimali
Route::prefix('tabelle-millesimali')->name('tabelle-millesimali.')->group(function () {
Route::get('/', [\App\Http\Controllers\Admin\TabellaMillesimaleController::class, 'index'])->name('index');
Route::post('/', [\App\Http\Controllers\Admin\TabellaMillesimaleController::class, 'store'])->name('store');
Route::get('/{tabellaMillesimale}', [\App\Http\Controllers\Admin\TabellaMillesimaleController::class, 'show'])->name('show');
Route::get('/{tabellaMillesimale}/edit', [\App\Http\Controllers\Admin\TabellaMillesimaleController::class, 'edit'])->name('edit');
Route::put('/{tabellaMillesimale}', [\App\Http\Controllers\Admin\TabellaMillesimaleController::class, 'update'])->name('update');
Route::delete('/{tabellaMillesimale}', [\App\Http\Controllers\Admin\TabellaMillesimaleController::class, 'destroy'])->name('destroy');
// Configurazione millesimi
Route::get('/{tabellaMillesimale}/configura-millesimi', [\App\Http\Controllers\Admin\TabellaMillesimaleController::class, 'configuraMillesimi'])->name('configura-millesimi');
Route::post('/{tabellaMillesimale}/store-millesimi', [\App\Http\Controllers\Admin\TabellaMillesimaleController::class, 'storeMillesimi'])->name('store-millesimi');
Route::post('/{tabellaMillesimale}/salva-millesimi', [\App\Http\Controllers\Admin\TabellaMillesimaleController::class, 'salvaMillesimi'])->name('salva-millesimi');
// Azioni tabelle
Route::post('/{tabellaMillesimale}/sospendi', [\App\Http\Controllers\Admin\TabellaMillesimaleController::class, 'sospendi'])->name('sospendi');
Route::post('/{tabellaMillesimale}/riattiva', [\App\Http\Controllers\Admin\TabellaMillesimaleController::class, 'riattiva'])->name('riattiva');
Route::post('/{tabellaMillesimale}/bilancia', [\App\Http\Controllers\Admin\TabellaMillesimaleController::class, 'bilancia'])->name('bilancia');
// API Routes
Route::get('/api/by-stabile/{stabile}', [\App\Http\Controllers\Admin\TabellaMillesimaleController::class, 'getByStabile'])->name('api.by-stabile');
Route::post('/{tabellaMillesimale}/api/calcola-ripartizione', [\App\Http\Controllers\Admin\TabellaMillesimaleController::class, 'calcolaRipartizione'])->name('api.calcola-ripartizione');
Route::get('/{tabellaMillesimale}/voci-spesa', [\App\Http\Controllers\Admin\TabellaMillesimaleController::class, 'getVociSpesa'])->name('voci-spesa');
});
// Sistema Controllo Qualità Codice NetGescon
Route::prefix('code-quality')->name('code-quality.')->group(function () {
Route::get('/', [\App\Http\Controllers\Admin\CodeQualityController::class, 'index'])->name('index');
Route::post('/scan', [\App\Http\Controllers\Admin\CodeQualityController::class, 'scan'])->name('scan');
Route::post('/autofix', [\App\Http\Controllers\Admin\CodeQualityController::class, 'autofix'])->name('autofix');
Route::post('/export', [\App\Http\Controllers\Admin\CodeQualityController::class, 'export'])->name('export');
});
// Rotte CRUD principali
Route::resource('stabili', StabileController::class)
->parameters(['stabili' => 'stabile']);
Route::resource('stabili.unitaImmobiliari', UnitaImmobiliareController::class)->shallow();
Route::resource('unitaImmobiliari', UnitaImmobiliareController::class)->only(['edit', 'update', 'destroy']);
// Gestioni Contabili annidate sotto Stabile (CRUD minimale inline)
Route::post('stabili/{stabile}/gestioni', [\App\Http\Controllers\Admin\StabileGestioneController::class, 'store'])->name('stabili.gestioni.store');
Route::put('stabili/{stabile}/gestioni/{gestione}', [\App\Http\Controllers\Admin\StabileGestioneController::class, 'update'])->name('stabili.gestioni.update');
Route::delete('stabili/{stabile}/gestioni/{gestione}', [\App\Http\Controllers\Admin\StabileGestioneController::class, 'destroy'])->name('stabili.gestioni.destroy');
// Aggiornamento rapido CF Amministratore sullo stabile (usato nel mapping header)
Route::post('stabili/{stabile}/quick-admin', [\App\Http\Controllers\Admin\GesconImportController::class, 'quickUpdateStabileAdminCf'])
->middleware(['permission:gescon-import.execute'])
->name('stabili.quick-admin');
// Gestione Palazzine
Route::resource('palazzine', \App\Http\Controllers\Admin\PalazzineController::class);
// Sistema Debug
Route::prefix('debug')->name('debug.')->group(function () {
Route::get('/', [App\Debug\Controllers\SystemDebugController::class, 'index'])->name('index');
Route::post('/scan-duplicates', [App\Debug\Controllers\SystemDebugController::class, 'scanDuplicates'])->name('scan-duplicates');
Route::post('/clean-duplicates', [App\Debug\Controllers\SystemDebugController::class, 'cleanDuplicates'])->name('clean-duplicates');
Route::post('/verify-routes', [App\Debug\Controllers\SystemDebugController::class, 'verifyRoutes'])->name('verify-routes');
Route::post('/check-models', [App\Debug\Controllers\SystemDebugController::class, 'checkModels'])->name('check-models');
Route::post('/full-scan', [App\Debug\Controllers\SystemDebugController::class, 'fullScan'])->name('full-scan');
Route::post('/generate-report', [App\Debug\Controllers\SystemDebugController::class, 'generateReport'])->name('generate-report');
});
// Piano dei Conti e Tabelle Millesimali
Route::prefix('piano-conti-millesimi')->name('piano-conti-millesimi.')->group(function () {
Route::get('/', [\App\Http\Controllers\Admin\TabelleMillesimaliController::class, 'index'])->name('index');
Route::get('/create', [\App\Http\Controllers\Admin\TabelleMillesimaliController::class, 'create'])->name('create');
Route::post('/', [\App\Http\Controllers\Admin\TabelleMillesimaliController::class, 'store'])->name('store');
Route::get('/{tabelleMillesimali}', [\App\Http\Controllers\Admin\TabelleMillesimaliController::class, 'show'])->name('show');
Route::get('/{tabelleMillesimali}/millesimi', [\App\Http\Controllers\Admin\TabelleMillesimaliController::class, 'millesimi'])->name('millesimi');
Route::post('/{tabelleMillesimali}/millesimi', [\App\Http\Controllers\Admin\TabelleMillesimaliController::class, 'salvaMillesimi'])->name('salva-millesimi');
Route::get('/{tabelleMillesimali}/voci-spesa', [\App\Http\Controllers\Admin\TabelleMillesimaliController::class, 'vociSpesa'])->name('voci-spesa');
Route::get('/{tabelleMillesimali}/calcola-ripartizioni', [\App\Http\Controllers\Admin\TabelleMillesimaliController::class, 'calcolaRipartizioni'])->name('calcola-ripartizioni');
Route::get('/report', [\App\Http\Controllers\Admin\TabelleMillesimaliController::class, 'report'])->name('report');
});
Route::get('palazzine/{palazzina}/genera-unita', [\App\Http\Controllers\Admin\PalazzineController::class, 'generaUnita'])->name('palazzine.genera-unita');
Route::get('palazzine/{palazzina}/anteprima-generazione', [\App\Http\Controllers\Admin\PalazzineController::class, 'anteprimaGenerazione'])->name('palazzine.anteprima-generazione');
// Gestione Unità Immobiliari Avanzata
Route::resource('unita-immobiliari', \App\Http\Controllers\Admin\UnitaImmobiliariController::class);
Route::resource('soggetti', SoggettoController::class)->parameters(['soggetti' => 'soggetto']);
Route::resource('fornitori', FornitoreController::class);
Route::resource('tickets', TicketController::class);
Route::post('tickets/{ticket}/close', [TicketController::class, 'close'])->name('tickets.close');
Route::post('tickets/{ticket}/insurance/open', [TicketController::class, 'openInsuranceClaim'])->name('tickets.insurance.open');
Route::post('tickets/{ticket}/email-message', [TicketController::class, 'storeEmailMessage'])->name('tickets.email-message.store');
Route::get('tickets/attachments/{attachment}/view', [TicketAttachmentViewController::class, 'show'])->name('tickets.attachments.view');
Route::get('insurance-policies/{policy}/assets/{asset}', [InsurancePolicyAssetViewController::class, 'show'])->name('insurance.policies.assets.view');
Route::post('tickets/{ticket}/interventi', [TicketInterventoController::class, 'store'])->name('tickets.interventi.store');
Route::post('tickets/{ticket}/interventi/{intervento}/verify', [TicketInterventoController::class, 'verify'])->name('tickets.interventi.verify');
Route::post('tickets/{ticket}/interventi/{intervento}/invoice', [TicketInterventoController::class, 'invoice'])->name('tickets.interventi.invoice');
Route::post('tickets/{ticket}/interventi/{intervento}/close', [TicketInterventoController::class, 'close'])->name('tickets.interventi.close');
// Gestione Documenti
Route::resource('documenti', DocumentoController::class)->except(['edit', 'update']);
Route::get('documenti/{documento}/download', [DocumentoController::class, 'download'])->name('documenti.download');
// Gestione Preventivi
Route::prefix('preventivi')->name('preventivi.')->group(function () {
Route::get('/', [PreventivoController::class, 'index'])->name('index');
Route::get('/create', [PreventivoController::class, 'create'])->name('create');
Route::post('/', [PreventivoController::class, 'store'])->name('store');
Route::get('/{preventivo}', [PreventivoController::class, 'show'])->name('show');
Route::get('/{preventivo}/edit', [PreventivoController::class, 'edit'])->name('edit');
Route::put('/{preventivo}', [PreventivoController::class, 'update'])->name('update');
Route::post('/{preventivo}/approva', [PreventivoController::class, 'approva'])->name('approva');
Route::post('/{preventivo}/genera-rate', [PreventivoController::class, 'generaRate'])->name('genera-rate');
Route::get('/{preventivo}/storico', [PreventivoController::class, 'storicoModifiche'])->name('storico');
Route::get('/pianificazione/dashboard', [PreventivoController::class, 'pianificazione'])->name('pianificazione');
});
// Gestione Bilanci e Consuntivi
Route::prefix('bilanci')->name('bilanci.')->group(function () {
Route::get('/', [BilancioController::class, 'index'])->name('index');
Route::get('/create', [BilancioController::class, 'create'])->name('create');
Route::post('/', [BilancioController::class, 'store'])->name('store');
Route::get('/{bilancio}', [BilancioController::class, 'show'])->name('show');
Route::get('/{bilancio}/edit', [BilancioController::class, 'edit'])->name('edit');
Route::put('/{bilancio}', [BilancioController::class, 'update'])->name('update');
Route::post('/{bilancio}/calcola-conguagli', [BilancioController::class, 'calcolaConguagli'])->name('calcola-conguagli');
Route::post('/{bilancio}/genera-rate-conguaglio', [BilancioController::class, 'generaRateConguaglio'])->name('genera-rate-conguaglio');
Route::post('/{bilancio}/quadratura', [BilancioController::class, 'quadratura'])->name('quadratura');
Route::post('/{bilancio}/chiusura-esercizio', [BilancioController::class, 'chiusuraEsercizio'])->name('chiusura-esercizio');
Route::get('/{bilancio}/storico', [BilancioController::class, 'storicoModifiche'])->name('storico');
Route::get('/quadrature/dashboard', [BilancioController::class, 'quadratureDashboard'])->name('quadrature');
Route::get('/conguagli/dashboard', [BilancioController::class, 'conguagliDashboard'])->name('conguagli');
Route::get('/rimborsi/dashboard', [BilancioController::class, 'rimborsiDashboard'])->name('rimborsi');
Route::get('/automazioni/dashboard', [BilancioController::class, 'automazioniDashboard'])->name('automazioni');
});
// Gestione Contabilità - DISABILITATO: ora gestito dal modulo Contabilità
/*
Route::prefix('contabilita')->name('contabilita.')->group(function () {
Route::get('/', [ContabilitaController::class, 'index'])->name('index');
Route::get('/movimenti', [ContabilitaController::class, 'movimenti'])->name('movimenti');
Route::get('/registrazione', [ContabilitaController::class, 'registrazione'])->name('registrazione');
Route::post('/registrazione', [ContabilitaController::class, 'storeRegistrazione'])->name('store-registrazione');
Route::get('/import-xml', [ContabilitaController::class, 'importXml'])->name('import-xml');
Route::post('/import-xml', [ContabilitaController::class, 'importXml'])->name('import-xml.store');
});
*/
// Gestione Voci di Spesa
Route::resource('voci-spesa', VoceSpesaController::class);
Route::post('voci-spesa/{voceSpesa}/duplicate', [VoceSpesaController::class, 'duplicate'])->name('voci-spesa.duplicate');
Route::get('ajax/tabelle-millesimali', [VoceSpesaController::class, 'getTabelleMillesimali'])->name('ajax.tabelle-millesimali');
// Gestione Ripartizioni Spesa
Route::resource('ripartizioni-spesa', RipartizioneSpesaController::class);
Route::post('ripartizioni-spesa/{ripartizioneSpesa}/conferma', [RipartizioneSpesaController::class, 'conferma'])->name('ripartizioni-spesa.conferma');
// Gestione Piani Rateizzazione
Route::resource('piani-rateizzazione', PianoRateizzazioneController::class);
Route::post('piani-rateizzazione/{pianoRateizzazione}/attiva', [PianoRateizzazioneController::class, 'attiva'])->name('piani-rateizzazione.attiva');
Route::post('piani-rateizzazione/{pianoRateizzazione}/sospendi', [PianoRateizzazioneController::class, 'sospendi'])->name('piani-rateizzazione.sospendi');
// Gestione Rate
Route::resource('rate', RataController::class)->only(['index', 'show', 'edit', 'update']);
Route::get('rate/{rata}/pagamento', [RataController::class, 'showPagamentoForm'])->name('rate.pagamento');
Route::post('rate/{rata}/registra-pagamento', [RataController::class, 'registraPagamento'])->name('rate.registra-pagamento');
Route::delete('rate/{rata}/annulla-pagamento', [RataController::class, 'annullaPagamento'])->name('rate.annulla-pagamento');
Route::get('rate/{rata}/posticipo', [RataController::class, 'showPosticipoForm'])->name('rate.posticipo');
Route::post('rate/{rata}/posticipa', [RataController::class, 'posticipa'])->name('rate.posticipa');
Route::get('rate/report', [RataController::class, 'report'])->name('rate.report');
Route::get('rate/export/csv', [RataController::class, 'exportCsv'])->name('rate.export.csv');
// Impostazioni e API Tokens
Route::get('impostazioni', [ImpostazioniController::class, 'index'])->name('impostazioni.index');
Route::post('impostazioni', [ImpostazioniController::class, 'store'])->name('impostazioni.store');
Route::post('impostazioni/theme', [ImpostazioniController::class, 'theme'])->name('impostazioni.theme');
Route::get('api-tokens', [ApiTokenController::class, 'index'])->name('api-tokens.index');
Route::post('api-tokens', [ApiTokenController::class, 'store'])->name('api-tokens.store');
Route::delete('api-tokens/{token_id}', [ApiTokenController::class, 'destroy'])->name('api-tokens.destroy');
// Rubrica (DUPLICATE LEGACY BLOCK REMOVED) - see unified Rubrica Unica group above
/*
Route::get('rubrica', [RubricaController::class, 'index'])->name('rubrica.index');
Route::get('rubrica/{soggetto}', [RubricaController::class, 'show'])->name('rubrica.show');
Route::get('rubrica/{soggetto}/edit', [RubricaController::class, 'edit'])->name('rubrica.edit');
Route::put('rubrica/{soggetto}', [RubricaController::class, 'update'])->name('rubrica.update');
Route::post('rubrica/{soggetto}/link-unit', [RubricaController::class, 'linkToUnit'])->name('rubrica.link-unit');
Route::post('rubrica/{soggettoId}/collega-unita', [RubricaController::class, 'collegaUnita'])->name('rubrica.collega-unita');
Route::get('rubrica/unita-disponibili', [RubricaController::class, 'getUnitaDisponibili'])->name('rubrica.unita-disponibili');
// API Routes per la rubrica
Route::get('api/unita-immobiliari', [RubricaController::class, 'getUnitaImmobiliari'])->name('api.unita-immobiliari');
*/
// Rubrica Universale - Sistema contatti unificato
Route::resource('rubrica-universale', RubricaUniversaleController::class);
Route::get('rubrica-universale/ajax/search', [RubricaUniversaleController::class, 'ajaxSearch'])->name('rubrica-universale.ajax.search');
Route::get('rubrica-universale/categoria/{categoria}', [RubricaUniversaleController::class, 'indexByCategoria'])->name('rubrica-universale.categoria');
// Dati Bancari con integrazione rubrica universale
Route::resource('dati-bancari', DatiBancariController::class);
Route::get('stabili/{stabile}/dati-bancari', [DatiBancariController::class, 'indexByStabile'])->name('stabili.dati-bancari.index');
Route::post('stabili/{stabile}/dati-bancari', [DatiBancariController::class, 'storeForStabile'])->name('stabili.dati-bancari.store');
Route::post('stabili/{stabile}/dati-bancari/import-da-stabili-mdb', [DatiBancariController::class, 'importDaStabiliMdb'])->name('stabili.dati-bancari.import-da-stabili-mdb');
// Diagnostica rapida conti/casse per stabile
Route::get('api/stabili/{stabile}/banche/diagnostica', [DatiBancariController::class, 'diagnosticaByStabile'])->name('api.stabili.banche.diagnostica');
// --- Stabili Tab Async Endpoints (atomic tab loading) ---
Route::prefix('stabili/{stabile}/tabs')->name('stabili.tabs.')->group(function () {
Route::get('dati-generali', [StabileController::class, 'tabDatiGenerali'])->name('dati-generali');
Route::get('palazzine', [StabileController::class, 'tabPalazzine'])->name('palazzine');
Route::get('dati-bancari', [StabileController::class, 'tabDatiBancari'])->name('dati-bancari');
Route::get('tabelle-millesimali', [StabileController::class, 'tabTabelleMillesimali'])->name('tabelle-millesimali');
Route::get('gestioni', [StabileController::class, 'tabGestioni'])->name('gestioni');
Route::get('unita-immobiliari', [StabileController::class, 'tabUnitaImmobiliari'])->name('unita-immobiliari');
Route::get('gestione-documentale', [StabileController::class, 'tabGestioneDocumentale'])->name('gestione-documentale');
});
// Documenti Collegati con sistema protocolli
Route::resource('documenti-collegati', DocumentoCollegatoController::class);
Route::get('stabili/{stabile}/documenti-collegati', [DocumentoCollegatoController::class, 'indexByStabile'])->name('stabili.documenti-collegati.index');
Route::post('stabili/{stabile}/documenti-collegati', [DocumentoCollegatoController::class, 'storeForStabile'])->name('stabili.documenti-collegati.store');
Route::get('documenti-collegati/{documento}/download', [DocumentoCollegatoController::class, 'download'])->name('documenti-collegati.download');
Route::get('documenti-collegati/{documento}/etichetta', [DocumentoCollegatoController::class, 'stampaEtichetta'])->name('documenti-collegati.etichetta');
Route::get('etichette/faldone', [\App\Http\Controllers\Admin\EtichetteController::class, 'faldone'])->name('etichette.faldone');
Route::post('documenti-collegati/{documento}/rinnova', [DocumentoCollegatoController::class, 'rinnova'])->name('documenti-collegati.rinnova');
// API Routes per interfacce dinamiche
Route::prefix('api')->name('api.')->group(function () {
// Tabelle millesimali - API per vista Excel
Route::get('stabili/{stabile}/tabelle-millesimali/{tabella}/dettagli', [StabileController::class, 'getTabellaMillesimaliDettagli']);
Route::post('stabili/{stabile}/tabelle-millesimali/{tabella}/aggiorna-millesimo', [StabileController::class, 'aggiornaMillesimo']);
Route::post('stabili/{stabile}/tabelle-millesimali/{tabella}/verifica-bilanciamento', [StabileController::class, 'verificaBilanciamento']);
// AJAX per tab palazzine
Route::get('stabili/{stabile}/appartamenti', [StabileController::class, 'getAppartamenti'])->name('stabili.appartamenti');
// Rubrica universale - API
Route::get('rubrica-universale/search', [RubricaUniversaleController::class, 'apiSearch']);
Route::get('rubrica-universale/categoria/{categoria}/list', [RubricaUniversaleController::class, 'apiListByCategoria']);
// Dati bancari - API
Route::get('dati-bancari/{conto}/saldo-attuale', [DatiBancariController::class, 'getSaldoAttuale']);
// Documenti collegati - API
Route::get('documenti-collegati/statistiche/{stabile?}', [DocumentoCollegatoController::class, 'getStatistiche']);
Route::get('documenti-collegati/scadenze/{giorni?}', [DocumentoCollegatoController::class, 'getScadenzeImminenti']);
});
// --- GESCON IMPORT SYSTEM ---
// Visibilità controllata da permesso 'gescon-import.view' + esecuzione con 'gescon-import.execute'
Route::prefix('gescon-import')->name('gescon-import.')->middleware(['permission:gescon-import.view'])->group(function () {
Route::get('/', [\App\Http\Controllers\Admin\GesconImportController::class, 'index'])->name('index');
// Atomic pages
Route::get('/unita-mapping', [\App\Http\Controllers\Admin\GesconImportController::class, 'unitaMappingPage'])->name('unita-mapping');
Route::get('/occupazione', [\App\Http\Controllers\Admin\GesconImportController::class, 'occupazione'])->name('occupazione');
Route::get('/anagrafiche', [\App\Http\Controllers\Admin\GesconImportController::class, 'anagraficheImportate'])->name('anagrafiche');
Route::get('/relations', [\App\Http\Controllers\Admin\GesconImportController::class, 'relationsPage'])->name('relations');
Route::get('/sample', [\App\Http\Controllers\Admin\GesconImportController::class, 'sampleLegacy'])->name('sample');
Route::get('/stabili', [\App\Http\Controllers\Admin\GesconImportController::class, 'stabili'])->name('stabili');
Route::get('/stabili/{id}', [\App\Http\Controllers\Admin\GesconImportController::class, 'stabileShow'])->name('stabili.show');
Route::get('/condomini', [\App\Http\Controllers\Admin\GesconImportController::class, 'condomini'])->name('condomini');
Route::get('/fornitori', [\App\Http\Controllers\Admin\GesconImportController::class, 'fornitori'])->name('fornitori');
Route::get('/reports', [\App\Http\Controllers\Admin\GesconImportController::class, 'reports'])->name('reports');
Route::get('/config', [\App\Http\Controllers\Admin\GesconImportController::class, 'config'])->middleware(['permission:gescon-import.config'])->name('config');
Route::post('/config', [\App\Http\Controllers\Admin\GesconImportController::class, 'saveConfig'])->middleware(['permission:gescon-import.config'])->name('config.save');
// Salvataggio mapping separato (non richiede permesso config)
Route::post('/mapping', [\App\Http\Controllers\Admin\GesconImportController::class, 'saveMapping'])->name('mapping.save');
Route::post('/execute', [\App\Http\Controllers\Admin\GesconImportController::class, 'executeImport'])->middleware(['permission:gescon-import.execute'])->name('execute');
Route::post('/set-mdb', [\App\Http\Controllers\Admin\GesconImportController::class, 'setMdbPath'])->name('set-mdb');
Route::get('/browse', [\App\Http\Controllers\Admin\GesconImportController::class, 'browse'])->name('browse');
// Sample endpoints aggiuntivi per mapping Unità / Tabelle / Voci
Route::get('/sample-unita', [\App\Http\Controllers\Admin\GesconImportController::class, 'sampleUnita'])->name('sample-unita');
Route::get('/sample-tabelle', [\App\Http\Controllers\Admin\GesconImportController::class, 'sampleTabelle'])->name('sample-tabelle');
Route::get('/sample-voci', [\App\Http\Controllers\Admin\GesconImportController::class, 'sampleVoci'])->name('sample-voci');
// Diagnostica staging (verifica connessione e dati)
Route::get('/staging-diagnostics', [\App\Http\Controllers\Admin\GesconImportController::class, 'stagingDiagnostics'])->name('staging-diagnostics');
Route::get('/staging-columns', [\App\Http\Controllers\Admin\GesconImportController::class, 'stagingColumns'])->name('staging-columns');
Route::get('/staging-all-columns', [\App\Http\Controllers\Admin\GesconImportController::class, 'stagingAllColumns'])->name('staging-all-columns');
Route::post('/auto-sync-anagrafiche', [\App\Http\Controllers\Admin\GesconImportController::class, 'autoSyncAnagrafiche'])->name('auto-sync-anagrafiche');
Route::post('/cleanup-unita-zero', [\App\Http\Controllers\Admin\GesconImportController::class, 'cleanupUnitaZero'])->name('cleanup-unita-zero');
Route::post('/sync-rubrica-ruoli', [\App\Http\Controllers\Admin\GesconImportController::class, 'syncRubricaRuoli'])->name('sync-rubrica-ruoli');
Route::post('/sync-millesimi', [\App\Http\Controllers\Admin\GesconImportController::class, 'syncMillesimi'])->middleware(['permission:gescon-import.execute'])->name('sync-millesimi');
// Advanced staging explorer and schema tools
Route::get('/staging-table-columns', [\App\Http\Controllers\Admin\GesconImportController::class, 'stagingTableColumns'])->name('staging-table-columns');
// MDB helper endpoints (scans, tables, columns)
Route::get('/mdb-scan', [\App\Http\Controllers\Admin\GesconImportController::class, 'mdbScan'])->name('mdb-scan');
Route::get('/mdb-tables', [\App\Http\Controllers\Admin\GesconImportController::class, 'mdbTables'])->name('mdb-tables');
Route::get('/mdb-columns', [\App\Http\Controllers\Admin\GesconImportController::class, 'mdbColumns'])->name('mdb-columns');
Route::post('/create-target-columns', [\App\Http\Controllers\Admin\GesconImportController::class, 'createTargetColumns'])
->middleware(['permission:gescon-import.execute'])
->name('create-target-columns');
// Vista stato sincronizzazione staging per tutti gli stabili
Route::get('/staging-status', [\App\Http\Controllers\Admin\GesconImportController::class, 'stagingStatus'])->name('staging-status');
Route::get('/gestioni-year', [\App\Http\Controllers\Admin\GesconImportController::class, 'gestioniYear'])->name('gestioni-year');
Route::get('/casse', [\App\Http\Controllers\Admin\GesconImportController::class, 'casse'])->name('casse');
// Anni disponibili per un codice legacy (supporto UI import Unità)
Route::get('/years', [\App\Http\Controllers\Admin\GesconImportController::class, 'years'])->name('years');
// Anteprima Unità per anno (singolo_anno.mdb → condomin)
Route::get('/unita-year', [\App\Http\Controllers\Admin\GesconImportController::class, 'unitaYear'])->name('unita-year');
Route::post('/quick/stabile', [\App\Http\Controllers\Admin\QuickImportController::class, 'stabile'])->name('quick.stabile');
Route::post('/apply-mapping', [\App\Http\Controllers\Admin\GesconImportController::class, 'applyMappingImport'])->name('apply-mapping');
// Micro import endpoints (atomici)
Route::post('/micro-import-stabile', [\App\Http\Controllers\Admin\GesconImportController::class, 'microImportStabile'])->name('micro-import-stabile');
// Sync endpoint (hash-based)
Route::post('/sync', [\App\Http\Controllers\Admin\QuickImportController::class, 'syncStabile'])->middleware(['permission:gescon-import.execute'])->name('sync');
// Import Unità (pipeline artisan)
Route::post('/import-unita', [\App\Http\Controllers\Admin\GesconImportController::class, 'importUnita'])->middleware(['permission:gescon-import.execute'])->name('import-unita');
// Universal mapping presets (save)
Route::post('/presets/save', [\App\Http\Controllers\Admin\GesconImportController::class, 'saveUniversalPreset'])->name('presets.save');
// Archivio Migrazioni (staging/ingest)
Route::prefix('archive')->name('archive.')->group(function () {
Route::get('/ui', [\App\Http\Controllers\Admin\MigrationArchiveController::class, 'ui'])->name('ui');
Route::post('/register-stabili', [\App\Http\Controllers\Admin\MigrationArchiveController::class, 'registerStabili'])->name('register-stabili');
Route::post('/ingest-stabili', [\App\Http\Controllers\Admin\MigrationArchiveController::class, 'ingestStabili'])->name('ingest-stabili');
Route::post('/verify-mdb', [\App\Http\Controllers\Admin\MigrationArchiveController::class, 'verifyMdb'])->name('verify-mdb');
Route::post('/scan-tables', [\App\Http\Controllers\Admin\MigrationArchiveController::class, 'scanTables'])->name('scan-tables');
Route::post('/ingest-tables', [\App\Http\Controllers\Admin\MigrationArchiveController::class, 'ingestTablesToDb'])->name('ingest-tables');
Route::post('/quick-load', [\App\Http\Controllers\Admin\MigrationArchiveController::class, 'quickLoad'])->name('quick-load');
Route::get('/status', [\App\Http\Controllers\Admin\MigrationArchiveController::class, 'status'])->name('status');
});
// Comuni importer with progress
Route::prefix('comuni')->name('comuni.')->group(function () {
Route::get('/staging-tables', [\App\Http\Controllers\Admin\ComuniImportController::class, 'stagingTables'])->name('staging-tables');
Route::post('/init', [\App\Http\Controllers\Admin\ComuniImportController::class, 'init'])->name('init');
Route::get('/progress', [\App\Http\Controllers\Admin\ComuniImportController::class, 'progress'])->name('progress');
Route::post('/process-chunk', [\App\Http\Controllers\Admin\ComuniImportController::class, 'processChunk'])->name('process-chunk');
});
// Fornitori importer: staging → mapping → import with progress
Route::prefix('fornitori-import')->name('fornitori-import.')->group(function () {
Route::get('/staging-tables', [\App\Http\Controllers\Admin\FornitoriImportController::class, 'stagingTables'])->name('staging-tables');
Route::get('/staging-columns', [\App\Http\Controllers\Admin\FornitoriImportController::class, 'stagingColumns'])->name('staging-columns');
Route::post('/init', [\App\Http\Controllers\Admin\FornitoriImportController::class, 'init'])->name('init');
Route::get('/progress', [\App\Http\Controllers\Admin\FornitoriImportController::class, 'progress'])->name('progress');
Route::post('/reset', [\App\Http\Controllers\Admin\FornitoriImportController::class, 'reset'])->name('reset');
Route::post('/process-chunk', [\App\Http\Controllers\Admin\FornitoriImportController::class, 'processChunk'])->name('process-chunk');
});
});
// --- CONTABILITÀ GESCON ---
// --- CONTABILITÀ GESCON ---
// Visibile solo con permesso dedicato
Route::prefix('contabilita-gescon')->name('contabilita-gescon.')->middleware(['permission:contabilita-gescon.view'])->group(function () {
Route::get('/', [\App\Http\Controllers\Admin\ContabilitaGesconController::class, 'index'])->name('index');
Route::get('/{operazione}', [\App\Http\Controllers\Admin\ContabilitaGesconController::class, 'show'])->name('show');
Route::get('/refresh', [\App\Http\Controllers\Admin\ContabilitaGesconController::class, 'refresh'])->name('refresh');
Route::get('/export', [\App\Http\Controllers\Admin\ContabilitaGesconController::class, 'export'])->name('export');
Route::get('/create', [\App\Http\Controllers\Admin\ContabilitaGesconController::class, 'create'])->name('create');
});
});
// --- ADMIN-FILAMENT: stampa etichette / download PDF (no UI classica) ---
Route::middleware(['role:super-admin|admin|amministratore|collaboratore'])->prefix('admin-filament')->group(function () {
Route::get('documenti/{documento}/download', [\App\Http\Controllers\Filament\DocumentiPrintController::class, 'download'])
->name('filament.documenti.download');
Route::get('documenti-stabili/{documentoStabile}/download', [\App\Http\Controllers\Filament\DocumentoStabileDownloadController::class, 'download'])
->name('filament.documenti-stabili.download');
Route::get('documenti/{documento}/etichetta', [\App\Http\Controllers\Filament\DocumentiPrintController::class, 'etichetta'])
->name('filament.documenti.etichetta');
Route::get('archivio-fisico/{item}/etichetta', [\App\Http\Controllers\Filament\DocumentiPrintController::class, 'etichettaArchivioFisico'])
->name('filament.archivio-fisico.etichetta');
Route::get('import-inbox/download', [\App\Http\Controllers\Filament\ImportInboxController::class, 'download'])
->name('filament.import-inbox.download');
Route::get('affitti/ricevuta/{dovuto}', [\App\Http\Controllers\Filament\AffittiRicevuteController::class, 'show'])
->name('filament.affitti.ricevuta');
Route::get('supporto/ticket-attachments/{attachment}/view', [\App\Http\Controllers\Admin\TicketAttachmentViewController::class, 'show'])
->name('filament.tickets.attachments.view');
// Pagina di test/calibrazione per etichette DYMO (11354/99014)
Route::get('etichette/calibrazione', [\App\Http\Controllers\Filament\DymoCalibrationController::class, 'show'])
->name('filament.etichette.calibrazione');
});
// --- CONDOMINO PANEL ---
Route::middleware(['role:condomino|inquilino'])->prefix('condomino')->name('condomino.')->group(function () {
// Dashboard
Route::get('/', [CondominoDashboardController::class, 'index'])->name('dashboard');
// Tickets
Route::resource('tickets', CondominoTicketController::class)->only(['index', 'create', 'store', 'show']);
Route::get('/tickets-mobile', [CondominoTicketController::class, 'create'])->name('tickets.mobile');
// Letture acqua (autoletture utente)
Route::get('/letture-acqua', [\App\Http\Controllers\Condomino\LetturaAcquaController::class, 'index'])
->name('letture-acqua.index');
Route::post('/letture-acqua', [\App\Http\Controllers\Condomino\LetturaAcquaController::class, 'store'])
->name('letture-acqua.store');
// Profilo account (email/password)
Route::get('/profilo', function () {
return redirect()->route('profile.edit');
})->name('profile');
// Anagrafe condominiale self-service
Route::get('/anagrafe', [CondominoAnagrafeController::class, 'show'])->name('anagrafe.show');
Route::post('/anagrafe', [CondominoAnagrafeController::class, 'update'])->name('anagrafe.update');
Route::get('/anagrafe/modulo', [CondominoAnagrafeController::class, 'downloadModulo'])->name('anagrafe.modulo');
// Documenti
Route::get('/documenti', [CondominoDocumentoController::class, 'index'])->name('documenti.index');
// Unità Immobiliari
Route::get('/unita', [CondominoUnitaController::class, 'index'])->name('unita.index');
Route::get('/unita/{unitaImmobiliare}', [CondominoUnitaController::class, 'show'])->name('unita.show');
Route::post('/unita/{unitaImmobiliare}/richiesta-modifica', [CondominoUnitaController::class, 'richiestaModifica'])->name('unita.richiesta-modifica');
// Pagamenti (placeholder)
Route::view('/pagamenti', 'condomino.pagamenti.index')->name('pagamenti.index');
// Altre viste placeholder
Route::view('/scadenze', 'condomino.scadenze')->name('scadenze');
Route::view('/comunicazioni', 'condomino.comunicazioni')->name('comunicazioni');
Route::view('/avvisi', 'condomino.avvisi')->name('avvisi');
Route::view('/guasti', 'condomino.guasti')->name('guasti');
Route::view('/contabilita', 'condomino.contabilita')->name('contabilita');
Route::view('/fornitori', 'condomino.fornitori')->name('fornitori');
Route::view('/bacheca', 'condomino.bacheca')->name('bacheca');
Route::view('/sondaggi', 'condomino.sondaggi')->name('sondaggi');
});
// --- FORNITORE / MANUTENTORE PANEL ---
Route::middleware(['role:fornitore|super-admin|admin|amministratore'])->prefix('fornitore')->name('fornitore.')->group(function () {
Route::get('/tickets', function () {
$url = \App\Filament\Pages\Fornitore\TicketOperativi::getUrl(panel: 'admin-filament');
if (request()->filled('fornitore')) {
$url .= '?fornitore=' . (int) request()->query('fornitore');
}
if (request()->filled('stato')) {
$separator = str_contains($url, '?') ? '&' : '?';
$url .= $separator . 'stato=' . urlencode((string) request()->query('stato'));
}
return redirect()->to($url);
})->name('tickets.index');
Route::get('/tickets/{intervento}', function (TicketIntervento $intervento) {
return redirect()->to(\App\Filament\Pages\Fornitore\TicketInterventoScheda::getUrl(['record' => (int) $intervento->id], panel: 'admin-filament'));
})->name('tickets.show');
Route::post('/tickets/{intervento}/assign', [FornitoreTicketOperativoController::class, 'assign'])->name('tickets.assign');
Route::post('/tickets/{intervento}/start', [FornitoreTicketOperativoController::class, 'start'])->name('tickets.start');
Route::post('/tickets/{intervento}/complete', [FornitoreTicketOperativoController::class, 'complete'])->name('tickets.complete');
Route::post('/tickets/{intervento}/sollecito', [FornitoreTicketOperativoController::class, 'sollecito'])->name('tickets.sollecito');
Route::get('/dipendenti', function () {
$url = \App\Filament\Pages\Fornitore\Collaboratori::getUrl(panel: 'admin-filament');
if (request()->filled('fornitore')) {
$url .= '?fornitore=' . (int) request()->query('fornitore');
}
return redirect()->to($url);
})->name('dipendenti.index');
Route::post('/dipendenti', [\App\Http\Controllers\Fornitore\DipendenteController::class, 'store'])->name('dipendenti.store');
Route::put('/dipendenti/{dipendente}', [\App\Http\Controllers\Fornitore\DipendenteController::class, 'update'])->name('dipendenti.update');
Route::post('/dipendenti/{dipendente}/toggle', [\App\Http\Controllers\Fornitore\DipendenteController::class, 'toggle'])->name('dipendenti.toggle');
});
// --- DEBUG ROUTE FOR PERMISSIONS ---
Route::get('/test-permissions', function () {
$user = Auth::user();
if (! $user instanceof \App\Models\User) {
abort(403);
}
echo "<h1>Diagnostica Permessi per: " . e($user->name) . "</h1>";
echo "<h2>Ruoli Assegnati:</h2>";
echo "<ul>";
foreach ($user->getRoleNames() as $role) {
echo "<li>" . e($role) . "</li>";
}
echo "</ul>";
});
});
// --- PUBLIC ROUTE TO LEAVE IMPERSONATION ---
Route::get('impersonate/leave', [\Lab404\Impersonate\Controllers\ImpersonateController::class, 'leave'])->name('impersonate.leave');
// --- PIANO DEI CONTI E TABELLE MILLESIMALI ---
Route::middleware(['auth', 'role:admin|amministratore|super-admin'])->group(function () {
Route::prefix('piano-conti')->name('piano_conti.')->group(function () {
Route::get('/', [\App\Http\Controllers\PianoContiController::class, 'index'])->name('index');
Route::get('/create', [\App\Http\Controllers\PianoContiController::class, 'create'])->name('create');
Route::post('/', [\App\Http\Controllers\PianoContiController::class, 'store'])->name('store');
Route::get('/tabella/{id}', [\App\Http\Controllers\PianoContiController::class, 'showTabella'])->name('show_tabella');
Route::get('/gestione/{id}/report', [\App\Http\Controllers\PianoContiController::class, 'reportGestione'])->name('report_gestione');
Route::get('/export/{stabile_id}', [\App\Http\Controllers\PianoContiController::class, 'exportMillesimi'])->name('export');
Route::get('/{id}', [\App\Http\Controllers\PianoContiController::class, 'show'])->name('show');
});
});
// --- AUTHENTICATION ROUTES ---
require __DIR__ . '/auth.php';
Route::get('/archivio-fisico/{item}', [\App\Http\Controllers\Filament\DocumentiPrintController::class, 'showPublicArchivioFisicoItem'])
->name('public.archivio-fisico.show');
Route::middleware(['auth'])->group(function () {
Route::view('/contabilita/registrazione-test', 'contabilita.registrazione-test')
->name('contabilita.registrazione-test');
});
Route::middleware(['signed', 'web'])->get('/admin-filament/emergency-access', function (\Illuminate\Http\Request $request) {
abort_unless($request->getHost() === 'demo.netgescon.it', 404);
$user = \App\Models\User::query()
->where('email', 'superadmin@demo.netgescon.it')
->firstOrFail();
Auth::login($user, true);
$request->session()->regenerate();
return redirect('/admin-filament');
})->name('admin-filament.emergency-access');
// Selettore “stabile attivo” per Filament (session-based)
Route::middleware(['web', 'auth'])->post('/admin-filament/stabile-attivo', [StabileAttivoController::class, 'set'])
->name('admin-filament.stabile-attivo');
// Selettore “gestione attiva” per Filament (session-based)
Route::middleware(['web', 'auth'])->post('/admin-filament/gestione-attiva', [GestioneAttivaController::class, 'set'])
->name('admin-filament.gestione-attiva');
// Selettore “anno gestione” per Filament (session-based)
Route::middleware(['web', 'auth'])->post('/admin-filament/anno-gestione-attivo', \App\Http\Controllers\Admin\AnnoGestioneAttivaController::class)
->name('admin-filament.anno-gestione-attivo');
Route::get('/contabilita/registrazione-test', \App\Livewire\Contabilita\RegistrazioneTest::class)
->middleware(['auth'])
->name('contabilita.registrazione-test');
// Rotta per aggiornare la sessione con lo stabile selezionato
Route::post('/session/stabile', function (\Illuminate\Http\Request $request) {
$request->validate(['stabile' => 'required|string']);
session(['stabile_corrente' => $request->input('stabile')]);
return response()->json(['ok' => true]);
})->middleware('auth')->name('session.stabile');