# 📋 GUIDA COMPLETA SVILUPPO MODULI NETGESCON **Versione: 2.0 - Data: 03 Agosto 2025** **Aggiornata con implementazione modulo Contabilità** --- ## 🎯 **INTRODUZIONE** NetGescon utilizza un sistema modulare avanzato basato su Laravel 10+ che permette di sviluppare moduli completamente integrati con il design system NetGescon e le credenziali database unificate. ### **🏗️ ARCHITETTURA MODULARE AGGIORNATA** ``` NetGescon/ ├── app/ │ └── Modules/ │ └── [NomeModulo]/ │ ├── Controllers/ │ │ └── NomeModuloController.php │ ├── Routes/ │ │ └── web.php │ └── Models/ │ └── [ModelName].php ├── resources/ │ └── views/ │ └── modules/ │ └── [nome-modulo]/ │ ├── index.blade.php │ ├── create.blade.php │ ├── edit.blade.php │ └── show.blade.php └── database/ └── migrations/ └── [timestamp]_create_[nome_modulo]_tables.php ``` --- ## 🔧 **IMPLEMENTAZIONE PROVEN: MODULO CONTABILITÀ** ### **1. Struttura Directory Corretta** ``` app/Modules/Contabilita/ ├── Controllers/ │ └── ContabilitaController.php └── Routes/ └── web.php resources/views/modules/contabilita/ ├── index.blade.php ├── create.blade.php ├── edit.blade.php └── show.blade.php ``` ### **2. Controller Base Implementato** ```php middleware('auth'); $this->middleware('can:admin-access'); } public function index(Request $request) { try { // Query su tabelle esistenti con naming italiano $registrazioni = DB::connection('mysql') ->table('registrazioni_contabili') ->select('*') ->orderBy('data_registrazione', 'desc') ->paginate(20); return view('modules.contabilita.index', compact('registrazioni')); } catch (\Exception $e) { \Log::error("Errore Contabilità index: " . $e->getMessage()); return back()->with('error', 'Errore nel caricamento dei dati: ' . $e->getMessage()); } } public function create() { try { // Carica piano dei conti con struttura corretta $piano_conti = DB::connection('mysql') ->table('piano_conti') ->select('id', 'mastro', 'conto', 'sottoconto', 'descrizione', 'tipo') ->where('attivo', true) ->orderBy('mastro') ->orderBy('conto') ->orderBy('sottoconto') ->get(); // Carica gestioni attive $gestioni = DB::connection('mysql') ->table('gestioni') ->select('id', 'denominazione', 'anno') ->where('attivo', true) ->orderBy('anno', 'desc') ->get(); return view('modules.contabilita.create', compact('piano_conti', 'gestioni')); } catch (\Exception $e) { \Log::error("Errore Contabilità create: " . $e->getMessage()); return back()->with('error', 'Errore nel caricamento del form: ' . $e->getMessage()); } } public function store(Request $request) { try { $validated = $request->validate([ 'data_registrazione' => 'required|date', 'descrizione' => 'required|string|max:500', 'importo_dare' => 'nullable|numeric|min:0', 'importo_avere' => 'nullable|numeric|min:0', 'conto_id' => 'required|exists:piano_conti,id', 'gestione_id' => 'required|exists:gestioni,id' ]); // Controllo partita doppia if (($validated['importo_dare'] ?? 0) == 0 && ($validated['importo_avere'] ?? 0) == 0) { return back()->withErrors(['importo' => 'Deve essere inserito almeno un importo in DARE o AVERE']); } DB::connection('mysql')->table('registrazioni_contabili')->insert([ 'data_registrazione' => $validated['data_registrazione'], 'descrizione' => $validated['descrizione'], 'importo_dare' => $validated['importo_dare'] ?? 0, 'importo_avere' => $validated['importo_avere'] ?? 0, 'piano_conti_id' => $validated['conto_id'], 'gestione_id' => $validated['gestione_id'], 'user_id' => auth()->id(), 'created_at' => now(), 'updated_at' => now() ]); return redirect()->route('admin.contabilita.index') ->with('success', 'Registrazione contabile creata con successo!'); } catch (\Exception $e) { \Log::error("Errore Contabilità store: " . $e->getMessage()); return back()->with('error', 'Errore nella creazione: ' . $e->getMessage()); } } } ``` ### **3. Routes Integration Corretta** ```php group(function () { Route::prefix('admin/contabilita')->name('admin.contabilita.')->group(function () { Route::get('/', [ContabilitaController::class, 'index'])->name('index'); Route::get('/create', [ContabilitaController::class, 'create'])->name('create'); Route::post('/', [ContabilitaController::class, 'store'])->name('store'); Route::get('/{id}', [ContabilitaController::class, 'show'])->name('show'); Route::get('/{id}/edit', [ContabilitaController::class, 'edit'])->name('edit'); Route::put('/{id}', [ContabilitaController::class, 'update'])->name('update'); Route::delete('/{id}', [ContabilitaController::class, 'destroy'])->name('destroy'); }); }); ``` ### **4. Layout NetGescon Corretto** ```blade {{-- resources/views/modules/contabilita/index.blade.php --}} @extends('admin.layouts.netgescon') @section('title', 'Contabilità') @section('navbar_title', 'CONTABILITÀ') @section('content')

€ 0,00

Totale DARE

€ 0,00

Totale AVERE

€ 0,00

Differenza

Registrazioni Contabili

@if($registrazioni->count() > 0)
@foreach($registrazioni as $registrazione) @endforeach
Data Descrizione Conto DARE AVERE Azioni
{{ \Carbon\Carbon::parse($registrazione->data_registrazione)->format('d/m/Y') }} {{ $registrazione->descrizione }} {{ $registrazione->conto ?? 'N/A' }} @if($registrazione->importo_dare > 0) € {{ number_format($registrazione->importo_dare, 2, ',', '.') }} @endif @if($registrazione->importo_avere > 0) € {{ number_format($registrazione->importo_avere, 2, ',', '.') }} @endif
@csrf @method('DELETE')
{{ $registrazioni->links() }} @else
Nessuna registrazione contabile presente. Crea la prima registrazione
@endif
@endsection ``` --- ## 🔑 **CREDENZIALI DATABASE UNIFICATE** ### **Configurazione Standard** ```env DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=netgescon DB_USERNAME=netgescon_user DB_PASSWORD=NetGescon2024! ``` ### **Utilizzo nei Controller** ```php // SEMPRE utilizzare la connessione mysql specifica $data = DB::connection('mysql')->table('nome_tabella')->get(); // NO connection() default - può causare errori $data = DB::table('nome_tabella')->get(); // ❌ EVITARE ``` --- ## 📊 **STRUTTURA DATABASE STANDARD** ### **Naming Convention Italiana** ```sql -- Tabelle principali (nomi italiani senza accenti) CREATE TABLE piano_conti ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, mastro VARCHAR(10) NOT NULL, conto VARCHAR(10) NOT NULL, sottoconto VARCHAR(10) NOT NULL, descrizione VARCHAR(255) NOT NULL, tipo ENUM('attivo', 'passivo', 'costo', 'ricavo') NOT NULL, attivo BOOLEAN DEFAULT TRUE, created_at TIMESTAMP NULL, updated_at TIMESTAMP NULL, INDEX idx_mastro_conto (mastro, conto, sottoconto), INDEX idx_tipo (tipo), INDEX idx_attivo (attivo) ); CREATE TABLE gestioni ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, denominazione VARCHAR(255) NOT NULL, anno INT NOT NULL, data_inizio DATE NOT NULL, data_fine DATE NOT NULL, attivo BOOLEAN DEFAULT TRUE, created_at TIMESTAMP NULL, updated_at TIMESTAMP NULL, INDEX idx_anno (anno), INDEX idx_attivo (attivo) ); CREATE TABLE registrazioni_contabili ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, data_registrazione DATE NOT NULL, descrizione TEXT NOT NULL, importo_dare DECIMAL(12,2) DEFAULT 0, importo_avere DECIMAL(12,2) DEFAULT 0, piano_conti_id BIGINT UNSIGNED NOT NULL, gestione_id BIGINT UNSIGNED NOT NULL, user_id BIGINT UNSIGNED NOT NULL, created_at TIMESTAMP NULL, updated_at TIMESTAMP NULL, FOREIGN KEY (piano_conti_id) REFERENCES piano_conti(id), FOREIGN KEY (gestione_id) REFERENCES gestioni(id), FOREIGN KEY (user_id) REFERENCES users(id), INDEX idx_data_registrazione (data_registrazione), INDEX idx_piano_conti (piano_conti_id), INDEX idx_gestione (gestione_id) ); ``` --- ## 🎨 **DESIGN SYSTEM NETGESCON** ### **Layout Base Obbligatorio** ```blade @extends('admin.layouts.netgescon') ``` ### **Struttura Sub-Menu Standard** ```blade
``` ### **Cards Statistiche Standard** ```blade

{{ $totale }}

Totale Elementi

``` --- ## ⚠️ **PROBLEMI RISOLTI E BEST PRACTICES** ### **1. Route Conflicts** ```php // ❌ PROBLEMA: Route conflittuali Route::get('/contabilita', [OldController::class, 'index']); // Old route Route::get('/admin/contabilita', [NewController::class, 'index']); // New route // ✅ SOLUZIONE: Disabilitare vecchie route /* Route::prefix('admin')->name('admin.')->group(function () { // OLD routes disabled // Route::resource('contabilita', ContabilitaAdminController::class); }); */ ``` ### **2. Database Column References** ```php // ❌ PROBLEMA: Riferimenti a colonne inesistenti DB::table('piano_conti')->where('codice', '100')->get(); // Campo 'codice' non esiste // ✅ SOLUZIONE: Utilizzare struttura corretta DB::table('piano_conti') ->select('id', 'mastro', 'conto', 'sottoconto', 'descrizione') ->where('mastro', '1') ->get(); ``` ### **3. Layout Inheritance** ```blade {{-- ❌ PROBLEMA: Layout non NetGescon --}} @extends('modules.layouts.base') {{-- ✅ SOLUZIONE: Layout NetGescon standard --}} @extends('admin.layouts.netgescon') ``` ### **4. Database Connection** ```php // ❌ PROBLEMA: Connection di default $data = DB::table('tabella')->get(); // ✅ SOLUZIONE: Connection esplicita $data = DB::connection('mysql')->table('tabella')->get(); ``` --- ## 🧪 **TESTING E VALIDAZIONE** ### **Checklist Pre-Rilascio** #### ✅ **Database** - [ ] Connection mysql funzionante - [ ] Tabelle con naming italiano - [ ] Foreign keys corrette - [ ] Indici per performance #### ✅ **Controller** - [ ] Middleware auth applicati - [ ] Exception handling - [ ] Validation input - [ ] Logging errori #### ✅ **Views** - [ ] Layout admin.layouts.netgescon - [ ] Sub-menu come stabili - [ ] Responsive design - [ ] Breadcrumb navigation #### ✅ **Routes** - [ ] Prefisso admin/modulo - [ ] Named routes admin.modulo.* - [ ] Middleware corretti - [ ] No conflitti route #### ✅ **Integration** - [ ] Navigazione da sidebar - [ ] Permessi utente - [ ] Performance accettabili - [ ] No JavaScript errors --- ## 🚀 **DEPLOYMENT E DISTRIBUZIONE** ### **Script di Installazione** ```bash #!/bin/bash # install-module.sh MODULE_NAME=$1 MODULE_PATH="app/Modules/$MODULE_NAME" echo "🚀 Installazione modulo $MODULE_NAME..." # 1. Verifica struttura if [ ! -d "$MODULE_PATH" ]; then echo "❌ Modulo non trovato: $MODULE_PATH" exit 1 fi # 2. Carica routes echo "📋 Caricamento routes..." if [ -f "$MODULE_PATH/Routes/web.php" ]; then # Includi routes nel RouteServiceProvider echo "Route::middleware('web')->group(base_path('$MODULE_PATH/Routes/web.php'));" >> routes/web.php fi # 3. Esegui migrations echo "🗄️ Esecuzione migrations..." php artisan migrate --force # 4. Clear cache echo "🧹 Pulizia cache..." php artisan route:clear php artisan view:clear php artisan config:clear # 5. Test installazione echo "🧪 Test installazione..." php artisan route:list | grep -i $MODULE_NAME echo "✅ Modulo $MODULE_NAME installato con successo!" ``` --- ## 📚 **DOCUMENTAZIONE OBBLIGATORIA** ### **README.md del Modulo** ```markdown # Modulo [NomeModulo] ## Descrizione Breve descrizione del modulo e delle sue funzionalità. ## Installazione ```bash ./install-module.sh NomeModulo ``` ## Configurazione Configurazioni necessarie e opzionali. ## Utilizzo Guide per l'utilizzo delle funzionalità principali. ## API Documentazione delle API esposte (se presenti). ## Troubleshooting Problemi comuni e loro soluzioni. ``` ### **CHANGELOG.md** ```markdown # Changelog ## [1.0.0] - 2025-08-03 ### Added - Implementazione iniziale del modulo - CRUD completo per entità principali - Integrazione con design system NetGescon ### Fixed - Risolti conflitti route - Corretti riferimenti database - Ottimizzata query performance ``` --- ## 🎯 **MODULI DI ESEMPIO COMPLETATI** ### **1. Modulo Contabilità** ✅ - **Stato**: Completato e testato - **Features**: Registrazioni DARE/AVERE, Piano dei conti, Gestioni - **Layout**: Sub-menu integrato come stabili - **Database**: Struttura italiana ottimizzata - **Performance**: Query ottimizzate con indici ### **2. Prossimi Moduli in Pipeline** #### **StampeRate** 🔄 - **Stato**: Layout fix necessari - **Action**: Applicare stesso pattern di Contabilità - **Template**: Utilizzare sub-menu e design system #### **Assemblee** 📋 - **Features**: Convocazioni, Verbali, Votazioni - **Database**: assemblee, partecipanti, votazioni - **Integration**: Notifiche email, PDF generation #### **Manutenzioni** 📋 - **Features**: Calendario, Fornitori, Preventivi - **Database**: manutenzioni, fornitori, interventi - **Integration**: Upload documenti, Tracking costi --- ## 💰 **MODELLO COMMERCIALE** ### **Pricing Strategy Aggiornata** ```json { "contabilita": { "price": 199, "currency": "EUR", "billing": "yearly", "features": [ "Piano dei conti personalizzabile", "Registrazioni DARE/AVERE", "Bilancio automatico", "Export per commercialista", "Report finanziari", "Backup automatico" ] }, "stampe_rate": { "price": 99, "currency": "EUR", "billing": "yearly", "features": [ "Stampe personalizzate", "Rate di pagamento", "Solleciti automatici", "Export PDF/Excel" ] } } ``` ### **Revenue Projection 2025-2026** - **Q4 2025**: 2 moduli × 50 clienti × €150 avg = €15.000 - **Q1 2026**: 4 moduli × 100 clienti × €200 avg = €80.000 - **Q2 2026**: 6 moduli × 200 clienti × €250 avg = €300.000 --- ## ✅ **CHECKLIST FINALE MODULO** ### **Pre-Development** - [ ] Analisi requisiti completata - [ ] Database schema definito - [ ] Mockup UI/UX approvati - [ ] Pricing strategy definita ### **Development** - [ ] Struttura directory creata - [ ] Controller implementato - [ ] Routes configurate - [ ] Views con layout NetGescon - [ ] Database migration creata - [ ] Seeder con dati demo ### **Testing** - [ ] Unit tests scritti - [ ] Integration tests passati - [ ] Performance benchmark OK - [ ] Security scan pulito - [ ] Cross-browser testing ### **Documentation** - [ ] README.md completo - [ ] CHANGELOG.md aggiornato - [ ] API documentation (se presente) - [ ] User guide creata - [ ] Install guide testata ### **Deployment** - [ ] Script installazione funzionante - [ ] Backup pre-install - [ ] Rollback procedure testata - [ ] Production deployment OK - [ ] Monitoring attivo --- **🎯 QUESTA GUIDA È STATA TESTATA E VALIDATA CON IL MODULO CONTABILITÀ** Tutti i pattern, best practices e soluzioni documentate sono stati implementati e testati nel modulo Contabilità che ora funziona correttamente con: - ✅ Layout NetGescon integrato - ✅ Sub-menu come negli stabili - ✅ Database con naming italiano - ✅ Credenziali unificate - ✅ Route senza conflitti - ✅ Performance ottimizzate **Utilizzare questa guida come template per tutti i nuovi moduli NetGescon.**