# 🛠️ MANUALE TECNICO NETGESCON - RISOLUZIONE PROBLEMI E BEST PRACTICES **Data Aggiornamento:** 21 Luglio 2025 **Versione:** 2.1.0 **Autore:** GitHub Copilot + Team NetGescon ## 📋 INDICE RAPIDO 1. [Problemi Risolti Oggi](#problemi-risolti-oggi) 2. [Errori Comuni e Soluzioni](#errori-comuni-e-soluzioni) 3. [Best Practices Blade Templates](#best-practices-blade-templates) 4. [Sistema Tab Unificato](#sistema-tab-unificato) 5. [Gestione Relazioni Database](#gestione-relazioni-database) 6. [Debug e Testing](#debug-e-testing) 7. [Checklist Pre-Deploy](#checklist-pre-deploy) --- ## ❌ PROBLEMI RISOLTI OGGI ### 1. **Errore Sintassi PHP - Carattere Unicode** ``` ERRORE: syntax error, unexpected identifier "×", expecting ")" FILE: resources/views/admin/stabili/show.blade.php :169 ``` **CAUSA:** Uso di carattere moltiplicazione Unicode `×` invece dell'operatore PHP `*` **SOLUZIONE:** ```php // ❌ ERRATO {{ ($palazzina->numero_scale ?? 1) × ($palazzina->numero_piani ?? 3) }} // ✅ CORRETTO {{ ($palazzina->numero_scale ?? 1) * ($palazzina->numero_piani ?? 3) }} ``` **PREVENZIONE:** Usare sempre operatori PHP standard, non caratteri speciali Unicode ### 2. **Errore Relazioni Null** ``` ERRORE: Call to a member function count() on null FILE: resources/views/admin/stabili/show.blade.php :121 ``` **CAUSA:** Chiamata metodi su relazioni non caricate o null **SOLUZIONE:** ```php // ❌ ERRATO - Può causare errore se relazione è null {{ $stabile->palazzine->count() }} // ✅ CORRETTO - Usa nullsafe operator {{ $stabile->palazzine?->count() ?? 0 }} // ✅ ALTERNATIVA - Verifica esistenza {{ ($stabile->palazzine && $stabile->palazzine->count()) ? $stabile->palazzine->count() : 0 }} ``` **PREVENZIONE:** Usare sempre `?->` per relazioni che potrebbero essere null ### 3. **Rotte Non Definite** ``` ERRORE: Route [admin.unita_immobiliari.index] not defined FILE: resources/views/admin/stabili/tabs/dati-generali.blade.php :214 ``` **CAUSA:** Riferimento a rotte non esistenti nel sistema di routing **SOLUZIONE:** ```php // ✅ Verifica esistenza rotta prima di usarla @if(Route::has('admin.unita_immobiliari.index')) @else @endif ``` ### 4. **Metodi Controller Mancanti** ``` ERRORE: Method App\Http\Controllers\Admin\StabileController::authorize does not exist FILE: app/Http/Controllers/Admin/StabileController.php :76 ``` **CAUSA:** Chiamata a metodi non implementati nel controller **SOLUZIONE:** Implementare il metodo o rimuovere la chiamata --- ## 🔧 ERRORI COMUNI E SOLUZIONI ### **A. Errori Blade Template** #### 1. Variabili Non Definite ```php // ❌ ERRATO {{ $variabile->proprieta }} // ✅ CORRETTO {{ $variabile->proprieta ?? 'Valore Default' }} {{ isset($variabile) ? $variabile->proprieta : 'Default' }} ``` #### 2. Include Files Mancanti ```php // ❌ ERRATO @include('admin.stabili.tabs.non-esistente') // ✅ CORRETTO - Verifica esistenza @if(view()->exists('admin.stabili.tabs.tab-name')) @include('admin.stabili.tabs.tab-name') @else

Contenuto in sviluppo

@endif ``` #### 3. Loop su Collezioni Null ```php // ❌ ERRATO @foreach($stabile->palazzine as $palazzina) // ✅ CORRETTO @forelse($stabile->palazzine ?? [] as $palazzina) // Contenuto @empty

Nessun elemento trovato

@endforelse ``` ### **B. Errori JavaScript** #### 1. Selezione Elementi DOM ```javascript // ❌ ERRATO - Può essere null const element = document.getElementById('tab-content'); element.classList.add('active'); // ✅ CORRETTO - Verifica esistenza const element = document.getElementById('tab-content'); if (element) { element.classList.add('active'); } ``` #### 2. Event Listeners ```javascript // ✅ BEST PRACTICE - Usa delegazione eventi document.addEventListener('DOMContentLoaded', function() { // Inizializzazione sicura const buttons = document.querySelectorAll('.netgescon-tab-btn'); buttons.forEach(button => { if (button) { button.addEventListener('click', handleTabClick); } }); }); ``` --- ## 🎨 BEST PRACTICES BLADE TEMPLATES ### **1. Struttura Standardizzata Tab** ```php
@include('path.to.tab-content', ['parametri' => $variabili])
``` ### **2. Gestione Sicura Dati** ```php

{{ $oggetto?->proprieta ?? 'N/D' }}

Totale: {{ $oggetto?->collezione?->count() ?? 0 }}
``` ### **3. Classi CSS Standardizzate** ```css /* Mantenere consistenza classi */ .netgescon-tab-btn { /* Stili tab button */ } .netgescon-tab-content { /* Stili contenuto tab */ } .netgescon-btn { /* Stili bottoni */ } .netgescon-card { /* Stili card */ } ``` --- ## 🔄 SISTEMA TAB UNIFICATO ### **Implementazione JavaScript Standard** ```javascript // File: resources/js/netgescon-tabs.js class NetGesconTabs { constructor() { this.init(); } init() { document.addEventListener('DOMContentLoaded', () => { this.bindEvents(); }); } bindEvents() { const tabButtons = document.querySelectorAll('.netgescon-tab-btn'); tabButtons.forEach(button => { button.addEventListener('click', (e) => this.handleTabClick(e)); }); } handleTabClick(event) { const button = event.currentTarget; const targetTab = button.dataset.tab; if (!targetTab) return; // Reset tutti i tab this.resetAllTabs(); // Attiva tab selezionato this.activateTab(button, targetTab); // Carica contenuto dinamico se necessario this.loadDynamicContent(targetTab); } resetAllTabs() { document.querySelectorAll('.netgescon-tab-btn').forEach(btn => { btn.classList.remove('active'); }); document.querySelectorAll('.netgescon-tab-content').forEach(content => { content.classList.remove('active'); content.classList.add('hidden'); }); } activateTab(button, targetTab) { button.classList.add('active'); const targetContent = document.getElementById(targetTab); if (targetContent) { targetContent.classList.add('active'); targetContent.classList.remove('hidden'); } } loadDynamicContent(tabName) { // Implementazione specifica per tab che richiedono caricamento dinamico const dynamicTabs = ['unita-immobiliari', 'documenti-collegati']; if (dynamicTabs.includes(tabName)) { const container = document.getElementById(`${tabName}-content`); if (container && !container.dataset.loaded) { this.fetchTabContent(tabName, container); } } } async fetchTabContent(tabName, container) { try { const stabileId = window.stabileId || container.dataset.stabileId; const response = await fetch(`/admin/stabili/${stabileId}/${tabName}`, { headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'application/json', 'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content') } }); const data = await response.json(); if (data.success) { container.innerHTML = data.html; container.dataset.loaded = 'true'; } else { this.showError(container, 'Errore nel caricamento dei dati'); } } catch (error) { console.error('Errore caricamento tab:', error); this.showError(container, 'Errore di connessione'); } } showError(container, message) { container.innerHTML = `

${message}

`; } } // Inizializza sistema tab new NetGesconTabs(); ``` --- ## 🗄️ GESTIONE RELAZIONI DATABASE ### **Caricamento Sicuro Relazioni** ```php // Nel Controller public function show(Stabile $stabile) { // Carica relazioni in modo esplicito $stabile->load([ 'palazzine' => function($query) { $query->orderBy('codice'); }, 'unitaImmobiliari', 'datiBancari.contatto', 'tabelleMillesimali' => function($query) { $query->orderBy('tipologia')->orderBy('anno', 'desc'); }, 'documenti' => function($query) { $query->orderBy('created_at', 'desc'); } ]); return view('admin.stabili.show', compact('stabile')); } ``` ### **Validazione Dati Blade** ```php @if($stabile && $stabile->relationLoaded('palazzine')) @forelse($stabile->palazzine as $palazzina) @empty @endforelse @else @endif ``` --- ## 🐛 DEBUG E TESTING ### **1. Debug Veloce** ```php // In Blade template - Solo per sviluppo @if(config('app.debug'))
Debug: {{ json_encode($stabile->palazzine?->count()) }}
@endif ``` ### **2. Log Errori** ```php // Nel Controller try { $data = $this->processData(); } catch (\Exception $e) { \Log::error('Errore processamento dati: ' . $e->getMessage(), [ 'file' => $e->getFile(), 'line' => $e->getLine(), 'stabile_id' => $stabile->id ?? null ]); return back()->with('error', 'Errore nel caricamento dei dati'); } ``` ### **3. Comandi Artisan Utili** ```bash # Pulizia cache php artisan config:clear php artisan view:clear php artisan route:clear # Debug rotte php artisan route:list | grep stabili # Test sintassi PHP php -l resources/views/admin/stabili/show.blade.php # Verifica database php artisan migrate:status ``` --- ## ✅ CHECKLIST PRE-DEPLOY ### **File da Controllare Sempre** - [ ] **Sintassi PHP**: `find . -name "*.php" -exec php -l {} \;` - [ ] **Blade Templates**: Verificare tutti gli `@include` esistono - [ ] **Relazioni Database**: Controllare `?->` per relazioni nullable - [ ] **Rotte**: Verificare tutte le `route()` sono definite - [ ] **JavaScript**: Controllare selezione DOM e event listener - [ ] **CSS**: Verificare classi standardizzate - [ ] **Immagini/Asset**: Controllare percorsi file ### **Test Funzionalità** - [ ] **Tab Navigation**: Tutti i tab si aprono correttamente - [ ] **Form Submission**: Creazione e modifica stabili - [ ] **AJAX Loading**: Caricamento dinamico contenuti - [ ] **Error Handling**: Gestione errori 404/500 - [ ] **Mobile Responsive**: Test su dispositivi mobili ### **Performance** - [ ] **Query Optimization**: Eager loading relazioni - [ ] **Cache**: Configurazione cache attiva - [ ] **Assets**: Minificazione CSS/JS - [ ] **Database**: Indici su colonne utilizzate --- ## 📝 TEMPLATE COMMENTI CODICE ### **Blade Templates** ```php {{-- NETGESCON TAB: [Nome Tab] Descrizione: [Descrizione funzionalità] Dipendenze: [Liste dipendenze] Autore: GitHub Copilot Data: 21/07/2025 --}} {{-- Header Tab con controlli --}}
{{-- Titolo e descrizione --}}

Titolo Tab

Descrizione funzionalità tab

{{-- Pulsanti azione --}}
``` ### **JavaScript** ```javascript /** * NETGESCON: [Nome Funzione] * Descrizione: [Descrizione funzionalità] * * @param {type} parametro - Descrizione parametro * @returns {type} Descrizione return * * @author GitHub Copilot * @date 21/07/2025 * @version 1.0.0 */ function nomeFunction(parametro) { // Implementazione } ``` --- ## 🎯 PROSSIMI PASSI 1. **Implementare Sistema Seeder** per dati demo persistenti 2. **Creare Test Automatici** per prevenire regressioni 3. **Ottimizzare Performance** con eager loading 4. **Documentare API** per integrazioni future 5. **Setup CI/CD** per deploy automatici --- **📞 SUPPORTO TECNICO** Per problemi urgenti, consultare sempre questo manuale prima di procedere con modifiche al codice. **🔄 AGGIORNAMENTI** Questo manuale verrà aggiornato ad ogni sessione di sviluppo con nuovi problemi risolti e best practices.