netgescon-master/docs/02-architettura-laravel/specifiche/LARAVEL_FORMS_DOCUMENTATION.md
Pikappa2 480e7eafbd 🎯 NETGESCON - Setup iniziale repository completo
📋 Commit iniziale con:
-  Documentazione unificata in docs/
-  Codice Laravel in netgescon-laravel/
-  Script automazione in scripts/
-  Configurazione sync rsync
-  Struttura organizzata e pulita

🔄 Versione: 2025.07.19-1644
🎯 Sistema pronto per Git distribuito
2025-07-19 16:44:47 +02:00

13 KiB

📋 NetGesCon Laravel - Documentazione Maschere e Interfacce

📍 STATO DEL PROGETTO

  • Fase: Business Logic Core completata
  • Prossima fase: Sviluppo interfacce utente responsive
  • Livello: Pronto per sviluppo controller e viste

🎯 STRUTTURA VERIFICATA - COLLEGAMENTI FUNZIONALI

Voci di Spesa → Tabelle Millesimali

Le voci di spesa sono correttamente collegate al sistema millesimale:

// VoceSpesa.php - Relazione con tabella millesimale
public function tabellaMillesimaleDefault()
{
    return $this->belongsTo(TabellaMillesimale::class, 'tabella_millesimale_default_id');
}

// Collegamento alla ripartizione spese
public function ripartizioniSpese()
{
    return $this->hasMany(RipartizioneSpese::class);
}

Workflow Completo di Ripartizione

  1. Voce Spesa → definisce la spesa e tabella millesimale di default
  2. Ripartizione Spese → calcola la ripartizione per ogni unità
  3. Dettaglio Ripartizione → importo specifico per ogni unità
  4. Piano Rateizzazione → gestione pagamenti dilazionati
  5. Rate → singole scadenze di pagamento

🎨 STANDARDIZZAZIONE SVILUPPO UI

1. Struttura Base per Maschere Laravel

A. Layout Base Responsive

// resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html lang="it">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>@yield('title', 'NetGesCon')</title>
    
    <!-- Bootstrap 5 + Custom CSS -->
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="{{ asset('css/netgescon.css') }}" rel="stylesheet">
    
    <!-- Font Awesome -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
</head>
<body>
    <nav class="navbar navbar-expand-lg navbar-dark bg-primary">
        <div class="container">
            <a class="navbar-brand" href="{{ route('dashboard') }}">
                <i class="fas fa-building"></i> NetGesCon
            </a>
            <!-- Navigation menu -->
        </div>
    </nav>

    <div class="container-fluid mt-4">
        <div class="row">
            <div class="col-md-2">
                @include('partials.sidebar')
            </div>
            <div class="col-md-10">
                @yield('content')
            </div>
        </div>
    </div>

    <!-- Scripts -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
    <script src="{{ asset('js/netgescon.js') }}"></script>
    @yield('scripts')
</body>
</html>

B. Componenti Standard per Form

// resources/views/components/form-input.blade.php
@props(['name', 'label', 'type' => 'text', 'required' => false, 'value' => ''])

<div class="mb-3">
    <label for="{{ $name }}" class="form-label">
        {{ $label }}
        @if($required)
            <span class="text-danger">*</span>
        @endif
    </label>
    <input 
        type="{{ $type }}" 
        class="form-control @error($name) is-invalid @enderror" 
        id="{{ $name }}" 
        name="{{ $name }}" 
        value="{{ old($name, $value) }}"
        @if($required) required @endif
    >
    @error($name)
        <div class="invalid-feedback">{{ $message }}</div>
    @enderror
</div>

C. Componente Select per Relazioni

// resources/views/components/form-select.blade.php
@props(['name', 'label', 'options' => [], 'selected' => '', 'required' => false])

<div class="mb-3">
    <label for="{{ $name }}" class="form-label">
        {{ $label }}
        @if($required)
            <span class="text-danger">*</span>
        @endif
    </label>
    <select 
        class="form-select @error($name) is-invalid @enderror" 
        id="{{ $name }}" 
        name="{{ $name }}"
        @if($required) required @endif
    >
        <option value="">-- Seleziona --</option>
        @foreach($options as $key => $value)
            <option value="{{ $key }}" @if(old($name, $selected) == $key) selected @endif>
                {{ $value }}
            </option>
        @endforeach
    </select>
    @error($name)
        <div class="invalid-feedback">{{ $message }}</div>
    @enderror
</div>

🏗️ ARCHITETTURA CONTROLLER E VISTE

1. Controller Standard Pattern

A. Controller Base per Gestione CRUD

// app/Http/Controllers/BaseController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

abstract class BaseController extends Controller
{
    protected $model;
    protected $viewPath;
    protected $routePrefix;

    public function index(Request $request)
    {
        $query = $this->model::query();
        
        // Filtri standard
        if ($request->has('search')) {
            $query = $this->applySearch($query, $request->search);
        }
        
        if ($request->has('stabile_id')) {
            $query->where('stabile_id', $request->stabile_id);
        }
        
        $items = $query->paginate(20);
        
        return view("{$this->viewPath}.index", compact('items'));
    }

    abstract protected function applySearch($query, $search);
    
    public function create()
    {
        return view("{$this->viewPath}.create", $this->getFormData());
    }

    public function store(Request $request)
    {
        $this->validateRequest($request);
        
        DB::beginTransaction();
        try {
            $item = $this->model::create($request->validated());
            DB::commit();
            
            return redirect()
                ->route("{$this->routePrefix}.show", $item)
                ->with('success', 'Elemento creato con successo');
        } catch (\Exception $e) {
            DB::rollBack();
            return back()->with('error', 'Errore durante la creazione: ' . $e->getMessage());
        }
    }

    abstract protected function validateRequest(Request $request);
    abstract protected function getFormData();
}

B. Controller Specifico per Voci di Spesa

// app/Http/Controllers/VoceSpesaController.php
<?php

namespace App\Http\Controllers;

use App\Models\VoceSpesa;
use App\Models\Stabile;
use App\Models\TabellaMillesimale;
use Illuminate\Http\Request;

class VoceSpesaController extends BaseController
{
    protected $model = VoceSpesa::class;
    protected $viewPath = 'voci_spesa';
    protected $routePrefix = 'voci-spesa';

    protected function applySearch($query, $search)
    {
        return $query->where(function($q) use ($search) {
            $q->where('codice', 'LIKE', "%{$search}%")
              ->orWhere('descrizione', 'LIKE', "%{$search}%");
        });
    }

    protected function validateRequest(Request $request)
    {
        return $request->validate([
            'stabile_id' => 'required|exists:stabili,id',
            'descrizione' => 'required|string|max:255',
            'tipo_gestione' => 'required|in:ordinaria,straordinaria,speciale',
            'categoria' => 'required|string',
            'tabella_millesimale_default_id' => 'nullable|exists:tabelle_millesimali,id',
            'ritenuta_acconto_default' => 'nullable|numeric|between:0,100',
            'attiva' => 'boolean',
            'ordinamento' => 'nullable|integer'
        ]);
    }

    protected function getFormData()
    {
        return [
            'stabili' => Stabile::pluck('denominazione', 'id'),
            'tabelleMillesimali' => TabellaMillesimale::pluck('denominazione', 'id'),
            'categorie' => VoceSpesa::getCategorieStandard(),
            'tipiGestione' => VoceSpesa::getTipiGestione()
        ];
    }
}

🎯 MASCHERE PRINCIPALI DA IMPLEMENTARE

1. Gestione Voci di Spesa

  • Lista: Filtri per stabile, categoria, tipo gestione
  • Dettaglio: Visualizzazione completa con storico ripartizioni
  • Creazione/Modifica: Form con validazione e selezione tabella millesimale

2. Gestione Ripartizione Spese

  • Wizard di Ripartizione: Step-by-step per calcolo automatico
  • Anteprima Ripartizione: Visualizzazione prima della conferma
  • Gestione Esenzioni: Interfaccia per escludere unità specifiche

3. Gestione Rate

  • Piano Rateizzazione: Creazione piani di pagamento
  • Calendario Scadenze: Vista calendario con rate in scadenza
  • Gestione Pagamenti: Registrazione e storico pagamenti

4. Dashboard Amministratore

  • Riepilogo Finanziario: Grafici e statistiche
  • Scadenze Imminenti: Alert per rate in scadenza
  • Stato Ripartizioni: Monitoraggio ripartizioni aperte

🔧 STRUMENTI E INTEGRAZIONI

1. Validazione Client-Side

// public/js/netgescon.js
class NetgesconValidator {
    static validateRipartizione(form) {
        const importo = parseFloat(form.importo_totale.value);
        const tabellaId = form.tabella_millesimale_id.value;
        
        if (importo <= 0) {
            this.showError('L\'importo deve essere maggiore di zero');
            return false;
        }
        
        if (!tabellaId) {
            this.showError('Seleziona una tabella millesimale');
            return false;
        }
        
        return true;
    }
    
    static showError(message) {
        // Implementazione notifica errore
    }
}

2. API JSON per Interazioni Ajax

// app/Http/Controllers/Api/RipartizioneSpesaController.php
public function calcolaAnteprima(Request $request)
{
    $voceSpesa = VoceSpesa::find($request->voce_spesa_id);
    $importoTotale = $request->importo_totale;
    
    $ripartizione = new RipartizioneSpese();
    $anteprima = $ripartizione->calcolaAnteprimaRipartizione(
        $voceSpesa, 
        $importoTotale, 
        $request->tabella_millesimale_id
    );
    
    return response()->json([
        'success' => true,
        'anteprima' => $anteprima,
        'totale_calcolato' => $anteprima->sum('importo_calcolato')
    ]);
}

🎨 TEMI CSS PERSONALIZZATI

1. Variabili CSS NetGesCon

/* public/css/netgescon.css */
:root {
    --primary-color: #2c3e50;
    --secondary-color: #3498db;
    --success-color: #27ae60;
    --warning-color: #f39c12;
    --danger-color: #e74c3c;
    --light-bg: #f8f9fa;
    --dark-text: #2c3e50;
}

.card-netgescon {
    border: none;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

.btn-netgescon {
    border-radius: 6px;
    padding: 8px 16px;
    font-weight: 500;
}

.table-netgescon {
    border-collapse: separate;
    border-spacing: 0;
}

.table-netgescon th {
    background-color: var(--light-bg);
    border-bottom: 2px solid var(--primary-color);
    font-weight: 600;
}

🔌 PLUGIN SYSTEM ARCHITECTURE

1. Struttura Base per Plugin

// app/Plugins/PluginInterface.php
interface PluginInterface
{
    public function register(): void;
    public function boot(): void;
    public function getMenuItems(): array;
    public function getRoutes(): array;
    public function getViews(): array;
}

// app/Plugins/BasePlugin.php
abstract class BasePlugin implements PluginInterface
{
    protected $name;
    protected $version;
    protected $description;
    
    public function register(): void
    {
        // Registrazione servizi base
    }
    
    abstract public function boot(): void;
}

2. Plugin Manager

// app/Services/PluginManager.php
class PluginManager
{
    protected $plugins = [];
    
    public function loadPlugin($pluginClass)
    {
        $plugin = new $pluginClass();
        $plugin->register();
        $plugin->boot();
        
        $this->plugins[] = $plugin;
    }
    
    public function getMenuItems()
    {
        $items = [];
        foreach ($this->plugins as $plugin) {
            $items = array_merge($items, $plugin->getMenuItems());
        }
        return $items;
    }
}

📊 PROSSIMI STEP IMPLEMENTATIVI

Fase 1: Implementazione Controller e Viste Base

  1. Creazione controller per VoceSpesa, RipartizioneSpese, Rate
  2. Implementazione viste index, create, edit, show
  3. Configurazione rotte e middleware

Fase 2: Interfacce Avanzate

  1. Wizard ripartizione spese con preview
  2. Dashboard amministratore con grafici
  3. Calendario scadenze interattivo

Fase 3: Integrazioni

  1. Sistema notifiche (email, SMS)
  2. Export PDF/Excel
  3. API REST per app mobile

🎯 CHECKLIST SVILUPPO

Backend

  • Modelli Eloquent completi
  • Relazioni verificate
  • Migration funzionali
  • Controller CRUD
  • Validazione form
  • API endpoints

Frontend

  • Layout responsive
  • Componenti riutilizzabili
  • Validazione client-side
  • Interfacce wizard
  • Dashboard grafici

Integrazioni

  • Sistema notifiche
  • Export documenti
  • Plugin system
  • Mobile API

Aggiornato: 2025-01-27
Versione: 1.0
Prossimo update: Dopo implementazione primi controller