📋 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
13 KiB
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
- Voce Spesa → definisce la spesa e tabella millesimale di default
- Ripartizione Spese → calcola la ripartizione per ogni unità
- Dettaglio Ripartizione → importo specifico per ogni unità
- Piano Rateizzazione → gestione pagamenti dilazionati
- 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
- Creazione controller per VoceSpesa, RipartizioneSpese, Rate
- Implementazione viste index, create, edit, show
- Configurazione rotte e middleware
Fase 2: Interfacce Avanzate
- Wizard ripartizione spese con preview
- Dashboard amministratore con grafici
- Calendario scadenze interattivo
Fase 3: Integrazioni
- Sistema notifiche (email, SMS)
- Export PDF/Excel
- 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