# 📄 SPECIFICHE STAMPE - NetGesCon Laravel

**📅 Creato**: 9 Luglio 2025  
**🎯 Scopo**: Specifiche per creazione moduli stampa PDF  
**👥 Team**: Michele + Sviluppatori esterni  
**📋 Status**: Template e specifiche  

---

## 🎯 **OBIETTIVO STAMPE**

### 📄 **Moduli PDF da Implementare**
Sistema di stampe PDF per documenti condominiali con:
- **Template personalizzabili** per ogni amministratore
- **Dati compilati** automaticamente da NetGesCon
- **Logo e intestazioni** configurabili
- **Firme digitali** e timbri
- **Invio automatico** email/PEC
- **Archiviazione** documenti generati

---

## 🏗️ **ARCHITETTURA STAMPE**

### 📁 **Struttura File**
```
netgescon-laravel/
├── resources/views/stampe/
│   ├── templates/
│   │   ├── base.blade.php           # Template base comune
│   │   ├── intestazione.blade.php   # Header personalizzabile
│   │   └── footer.blade.php         # Footer con firme
│   ├── documenti/
│   │   ├── assemblea/
│   │   │   ├── convocazione.blade.php
│   │   │   ├── verbale.blade.php
│   │   │   └── foglio-presenze.blade.php
│   │   ├── contabilita/
│   │   │   ├── estratto-conto.blade.php
│   │   │   ├── bilancio.blade.php
│   │   │   ├── rendiconto.blade.php
│   │   │   └── sollecito-pagamento.blade.php
│   │   ├── contratti/
│   │   │   ├── contratto-locazione.blade.php
│   │   │   ├── disdetta.blade.php
│   │   │   └── rinnovo.blade.php
│   │   └── comunicazioni/
│   │       ├── avviso-lavori.blade.php
│   │       ├── comunicazione-generica.blade.php
│   │       └── bollettino-informativo.blade.php
├── app/Services/
│   ├── StampaService.php            # Service principale
│   ├── PdfGeneratorService.php      # Generazione PDF
│   └── TemplateService.php          # Gestione template
├── storage/stampe/
│   ├── generated/                   # PDF generati
│   ├── templates/                   # Template personalizzati
│   └── assets/                      # Logo, firme, timbri
```

### ⚙️ **Tecnologie**
```php
// Package consigliati
"dompdf/dompdf": "^2.0",           // PDF generation
"barryvdh/laravel-dompdf": "^2.0", // Laravel integration
"intervention/image": "^2.7",       // Image manipulation
"spatie/laravel-pdf": "^1.0"       // Alternative PDF
```

---

## 📋 **DOCUMENTI PRIORITARI**

### 🏠 **1. Assemblee Condominiali**

#### **📄 Convocazione Assemblea**
```php
// Dati richiesti da NetGesCon
$dati_convocazione = [
    'condominio' => [
        'denominazione' => 'Condominio Verdi',
        'indirizzo' => 'Via Giuseppe Verdi 12, Milano',
        'codice_fiscale' => '80012345678'
    ],
    'amministratore' => [
        'nome_completo' => 'Dott. Mario Rossi',
        'indirizzo_studio' => 'Via Roma 1, Milano',
        'telefono' => '+39 02 1234567',
        'email' => 'admin@studio.com',
        'pec' => 'admin@pec.studio.com'
    ],
    'assemblea' => [
        'data_prima_convocazione' => '2024-03-15 18:00',
        'data_seconda_convocazione' => '2024-03-15 19:00',
        'luogo' => 'Sala riunioni - Via Verdi 12',
        'ordine_giorno' => [
            '1. Approvazione verbale assemblea precedente',
            '2. Relazione amministratore gestione 2023',
            '3. Approvazione bilancio consuntivo 2023',
            '4. Approvazione bilancio preventivo 2024',
            '5. Nomina amministratore e determinazione compenso',
            '6. Lavori manutenzione straordinaria tetto',
            '7. Varie ed eventuali'
        ]
    ],
    'condomini' => [
        [
            'nome_completo' => 'Mario Bianchi',
            'unita' => 'Appartamento 1',
            'millesimi' => 95,
            'indirizzo_corrispondenza' => 'Via Verdi 12, Milano'
        ],
        // ... altri condomini
    ],
    'allegati' => [
        'bilancio_consuntivo_2023.pdf',
        'bilancio_preventivo_2024.pdf',
        'preventivo_lavori_tetto.pdf'
    ]
];
```

#### **📋 Verbale Assemblea**
```php
$dati_verbale = [
    'assemblea' => [
        'data' => '2024-03-15 18:30',
        'presidente' => 'Mario Bianchi',
        'segretario' => 'Dott. Mario Rossi (Amministratore)',
        'tipo_convocazione' => 'prima', // prima|seconda
        'millesimi_presenti' => 650,    // su 1000
        'millesimi_rappresentati' => 750,
        'validita' => true
    ],
    'presenze' => [
        [
            'condomino' => 'Mario Bianchi',
            'unita' => 'Appartamento 1', 
            'millesimi' => 95,
            'presente' => true,
            'rappresentato_da' => null
        ],
        [
            'condomino' => 'Giulia Verdi',
            'unita' => 'Appartamento 3',
            'millesimi' => 105,  
            'presente' => false,
            'rappresentato_da' => 'Mario Bianchi'
        ]
    ],
    'deliberazioni' => [
        [
            'numero' => 1,
            'oggetto' => 'Approvazione verbale assemblea precedente',
            'votazione' => [
                'favorevoli' => 650,
                'contrari' => 0,
                'astenuti' => 100
            ],
            'esito' => 'approvata',
            'note' => ''
        ]
    ]
];
```

### 💰 **2. Documenti Contabili**

#### **💳 Estratto Conto Condomino**
```php
$dati_estratto = [
    'periodo' => [
        'data_inizio' => '2024-01-01',
        'data_fine' => '2024-12-31',
        'gestione' => 'Gestione Ordinaria 2024'
    ],
    'condomino' => [
        'nome_completo' => 'Mario Bianchi',
        'codice_fiscale' => 'BNCMRA70A01F205X',
        'unita' => 'Appartamento 1',
        'millesimi_proprieta' => 95,
        'millesimi_riscaldamento' => 145
    ],
    'movimenti' => [
        [
            'data' => '2024-01-15',
            'descrizione' => 'Rata I trimestre 2024',
            'dare' => 350.00,
            'avere' => 0.00,
            'saldo' => 350.00
        ],
        [
            'data' => '2024-01-20',
            'descrizione' => 'Pagamento rata trimestrale',
            'dare' => 0.00,
            'avere' => 350.00,
            'saldo' => 0.00
        ]
    ],
    'ripartizioni' => [
        'spese_generali' => [
            'pulizie' => 85.50,
            'ascensore' => 57.00,
            'giardino' => 28.50,
            'amministrazione' => 42.75
        ],
        'spese_riscaldamento' => [
            'gas_metano' => 195.30,
            'manutenzione_caldaia' => 34.80
        ]
    ],
    'saldo_finale' => [
        'precedente' => 150.00,
        'movimenti_periodo' => -25.50,
        'finale' => 124.50,
        'tipo' => 'credito' // credito|debito
    ]
];
```

#### **📊 Bilancio Consuntivo**
```php
$dati_bilancio = [
    'esercizio' => '2024',
    'periodo' => '01/01/2024 - 31/12/2024',
    'entrate' => [
        'categorie' => [
            'rate_condominiali' => [
                'preventivo' => 16800.00,
                'consuntivo' => 16950.00,
                'scostamento' => 150.00
            ],
            'interessi_mora' => [
                'preventivo' => 0.00,
                'consuntivo' => 45.30,
                'scostamento' => 45.30
            ]
        ],
        'totale_preventivo' => 16800.00,
        'totale_consuntivo' => 16995.30,
        'totale_scostamento' => 195.30
    ],
    'uscite' => [
        'categorie' => [
            'pulizie' => [
                'preventivo' => 3600.00,
                'consuntivo' => 3480.00,
                'scostamento' => -120.00,
                'dettaglio' => [
                    'Pulizie Srl - Servizio annuale' => 3480.00
                ]
            ],
            'riscaldamento' => [
                'preventivo' => 4500.00,
                'consuntivo' => 4650.30,
                'scostamento' => 150.30,
                'dettaglio' => [
                    'Eni Gas - Consumo annuale' => 4200.30,
                    'Tecnico caldaia - Manutenzione' => 450.00
                ]
            ]
        ],
        'totale_preventivo' => 15800.00,
        'totale_consuntivo' => 15234.80,
        'totale_scostamento' => -565.20
    ],
    'risultato' => [
        'avanzo_precedente' => 1200.00,
        'avanzo_esercizio' => 1760.50,
        'fondo_cassa' => 2960.50
    ]
];
```

### 📝 **3. Comunicazioni**

#### **🔧 Avviso Lavori**
```php
$dati_avviso_lavori = [
    'lavori' => [
        'tipo' => 'Rifacimento tetto',
        'descrizione' => 'Sostituzione completa manto di copertura e impermeabilizzazione',
        'data_inizio' => '2024-06-01',
        'data_fine_prevista' => '2024-08-31',
        'orario' => '08:00 - 17:00 (Lunedì-Venerdì)',
        'ditta_esecutrice' => 'Edilizia Moderna Srl'
    ],
    'informazioni' => [
        'accesso_condomini' => 'Garantito tramite scala di sicurezza',
        'rumori' => 'Previsti rumori nelle ore 08:00-12:00 e 14:00-17:00',
        'parcheggio' => 'Riduzione posti auto per cantiere (2 posti su 6)',
        'contatti_emergenza' => '+39 333 1234567 (Capo cantiere)'
    ],
    'precauzioni' => [
        'Evitare stendere panni nei balconi esposti',
        'Tenere chiuse finestre mansarda durante i lavori',
        'Segnalare immediatamente eventuali infiltrazioni'
    ]
];
```

---

## 🎨 **TEMPLATE DESIGN**

### 📄 **Template Base** 
```blade
{{-- resources/views/stampe/templates/base.blade.php --}}
<!DOCTYPE html>
<html lang="it">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ $documento_tipo }} - {{ $condominio_denominazione }}</title>
    <style>
        @page {
            margin: 2cm 1.5cm;
            @top-left { content: "{{ $documento_tipo }}"; }
            @top-right { content: "Pag. " counter(page); }
            @bottom-center { content: "{{ $amministratore_nome }} - {{ $amministratore_telefono }}"; }
        }
        
        body {
            font-family: 'DejaVu Sans', Arial, sans-serif;
            font-size: 11pt;
            line-height: 1.4;
            color: #333;
        }
        
        .intestazione {
            text-align: center;
            border-bottom: 2px solid #0066cc;
            padding-bottom: 15px;
            margin-bottom: 20px;
        }
        
        .logo {
            float: left;
            max-height: 60px;
        }
        
        .dati-amministratore {
            float: right;
            text-align: right;
            font-size: 9pt;
        }
        
        .titolo-documento {
            font-size: 16pt;
            font-weight: bold;
            margin: 20px 0;
            color: #0066cc;
        }
        
        .contenuto {
            clear: both;
            margin: 20px 0;
        }
        
        .tabella {
            width: 100%;
            border-collapse: collapse;
            margin: 15px 0;
        }
        
        .tabella th,
        .tabella td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
        }
        
        .tabella th {
            background-color: #f5f5f5;
            font-weight: bold;
        }
        
        .firma {
            text-align: right;
            margin-top: 40px;
            page-break-inside: avoid;
        }
        
        .totali {
            font-weight: bold;
            background-color: #f0f8ff;
        }
        
        .evidenziato {
            background-color: #fffacd;
            padding: 10px;
            border-left: 4px solid #ffd700;
        }
    </style>
</head>
<body>
    @include('stampe.templates.intestazione')
    
    <div class="contenuto">
        @yield('contenuto')
    </div>
    
    @include('stampe.templates.footer')
</body>
</html>
```

### 🏢 **Intestazione Personalizzabile**
```blade
{{-- resources/views/stampe/templates/intestazione.blade.php --}}
<div class="intestazione">
    @if($amministratore_logo)
        <img src="{{ $amministratore_logo }}" class="logo" alt="Logo">
    @endif
    
    <div class="dati-amministratore">
        <strong>{{ $amministratore_nome }}</strong><br>
        {{ $amministratore_indirizzo }}<br>
        Tel: {{ $amministratore_telefono }}<br>
        @if($amministratore_email)
            Email: {{ $amministratore_email }}<br>
        @endif
        @if($amministratore_pec)
            PEC: {{ $amministratore_pec }}<br>
        @endif
        @if($amministratore_partita_iva)
            P.IVA: {{ $amministratore_partita_iva }}
        @endif
    </div>
    
    <div style="clear: both;"></div>
    
    <h1 class="titolo-documento">{{ $documento_tipo }}</h1>
    
    <div class="dati-condominio">
        <strong>{{ $condominio_denominazione }}</strong><br>
        {{ $condominio_indirizzo }}<br>
        @if($condominio_codice_fiscale)
            C.F.: {{ $condominio_codice_fiscale }}
        @endif
    </div>
</div>
```

---

## 🔧 **IMPLEMENTAZIONE SERVIZI**

### 📄 **StampaService principale**
```php
<?php
// app/Services/StampaService.php

namespace App\Services;

use App\Models\Stabile;
use App\Models\Amministratore;
use Barryvdh\DomPDF\Facade\Pdf;

class StampaService
{
    public function __construct(
        private PdfGeneratorService $pdfGenerator,
        private TemplateService $templateService
    ) {}
    
    /**
     * Genera convocazione assemblea
     */
    public function generaConvocazioneAssemblea(
        Assemblea $assemblea,
        array $opzioni = []
    ): string {
        $dati = $this->preparaDatiConvocazione($assemblea);
        
        return $this->pdfGenerator->genera(
            'stampe.documenti.assemblea.convocazione',
            $dati,
            $opzioni
        );
    }
    
    /**
     * Genera estratto conto condomino
     */
    public function generaEstrattoConto(
        Soggetto $condomino,
        Carbon $dataInizio,
        Carbon $dataFine,
        array $opzioni = []
    ): string {
        $dati = $this->preparaDatiEstrattoConto(
            $condomino, 
            $dataInizio, 
            $dataFine
        );
        
        return $this->pdfGenerator->genera(
            'stampe.documenti.contabilita.estratto-conto',
            $dati,
            $opzioni
        );
    }
    
    /**
     * Genera bilancio consuntivo
     */
    public function generaBilancioConsuntivo(
        Bilancio $bilancio,
        array $opzioni = []
    ): string {
        $dati = $this->preparaDatiBilancio($bilancio);
        
        return $this->pdfGenerator->genera(
            'stampe.documenti.contabilita.bilancio',
            $dati,
            $opzioni
        );
    }
    
    private function preparaDatiConvocazione(Assemblea $assemblea): array
    {
        return [
            'documento_tipo' => 'CONVOCAZIONE ASSEMBLEA CONDOMINIALE',
            'condominio' => [
                'denominazione' => $assemblea->stabile->denominazione,
                'indirizzo' => $assemblea->stabile->indirizzo_completo,
                'codice_fiscale' => $assemblea->stabile->codice_fiscale
            ],
            'amministratore' => $this->getDatiAmministratore($assemblea->stabile),
            'assemblea' => [
                'data_prima_convocazione' => $assemblea->data_prima_convocazione,
                'data_seconda_convocazione' => $assemblea->data_seconda_convocazione,
                'luogo' => $assemblea->luogo,
                'ordine_giorno' => $assemblea->ordine_giorno
            ],
            'condomini' => $this->getCondominiConMillesimi($assemblea->stabile),
            'data_generazione' => now()->format('d/m/Y H:i')
        ];
    }
}
```

### 🎨 **PdfGeneratorService**
```php
<?php
// app/Services/PdfGeneratorService.php

namespace App\Services;

use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Support\Facades\Storage;

class PdfGeneratorService  
{
    public function genera(
        string $template,
        array $dati,
        array $opzioni = []
    ): string {
        // Opzioni default
        $opzioni = array_merge([
            'format' => 'A4',
            'orientation' => 'portrait',
            'margin_top' => 20,
            'margin_right' => 15,
            'margin_bottom' => 20,
            'margin_left' => 15,
            'font_size' => 11,
            'font_family' => 'DejaVu Sans'
        ], $opzioni);
        
        // Genera PDF
        $pdf = Pdf::loadView($template, $dati)
            ->setPaper($opzioni['format'], $opzioni['orientation'])
            ->setOptions([
                'dpi' => 150,
                'defaultFont' => $opzioni['font_family'],
                'isHtml5ParserEnabled' => true,
                'isRemoteEnabled' => true
            ]);
        
        // Salva file
        $filename = $this->generaNomeFile($dati, $template);
        $path = "stampe/generated/{$filename}";
        
        Storage::put($path, $pdf->output());
        
        return $path;
    }
    
    private function generaNomeFile(array $dati, string $template): string
    {
        $timestamp = now()->format('Y-m-d_H-i-s');
        $tipo_documento = str_replace(['stampe.documenti.', '.'], ['', '_'], $template);
        $condominio = str_slug($dati['condominio']['denominazione'] ?? 'documento');
        
        return "{$tipo_documento}_{$condominio}_{$timestamp}.pdf";
    }
}
```

---

## 📧 **INTEGRAZIONE EMAIL**

### 📨 **Invio Automatico**
```php
// app/Mail/DocumentoCondominialeGenerated.php

namespace App\Mail;

use Illuminate\Mail\Mailable;

class DocumentoCondominialeGenerated extends Mailable
{
    public function __construct(
        private string $tipoDocumento,
        private string $pathDocumento,
        private array $destinatari
    ) {}
    
    public function build()
    {
        return $this->view('emails.documento-generato')
                    ->subject("Nuovo documento: {$this->tipoDocumento}")
                    ->attach(storage_path("app/{$this->pathDocumento}"));
    }
}
```

---

## 🔧 **CONTROLLER INTEGRATION**

### 📋 **StampeController**
```php
<?php
// app/Http/Controllers/Admin/StampeController.php

namespace App\Http\Controllers\Admin;

use App\Services\StampaService;

class StampeController extends Controller
{
    public function __construct(private StampaService $stampaService) {}
    
    public function convocazioneAssemblea(Assemblea $assemblea)
    {
        $pathPdf = $this->stampaService->generaConvocazioneAssemblea($assemblea);
        
        return response()->download(storage_path("app/{$pathPdf}"));
    }
    
    public function estrattoContoCondomino(Request $request)
    {
        $request->validate([
            'condomino_id' => 'required|exists:soggetti,id',
            'data_inizio' => 'required|date',
            'data_fine' => 'required|date|after:data_inizio'
        ]);
        
        $condomino = Soggetto::findOrFail($request->condomino_id);
        $pathPdf = $this->stampaService->generaEstrattoConto(
            $condomino,
            Carbon::parse($request->data_inizio),
            Carbon::parse($request->data_fine)
        );
        
        return response()->download(storage_path("app/{$pathPdf}"));
    }
}
```

---

## 📊 **CONFIGURAZIONE AMMINISTRATORI**

### ⚙️ **Template Personalizzabili**
```php
// app/Models/AmministratoreTemplate.php

class AmministratoreTemplate extends Model
{
    protected $fillable = [
        'amministratore_id',
        'tipo_documento',
        'template_html',
        'css_personalizzato',
        'logo_path',
        'firma_digitale_path',
        'attivo'
    ];
    
    protected $casts = [
        'attivo' => 'boolean'
    ];
}
```

---

## 🚀 **DEPLOYMENT STAMPE**

### 📦 **Package Installation**
```bash
# Install PDF packages
composer require barryvdh/laravel-dompdf
composer require intervention/image

# Publish config
php artisan vendor:publish --provider="Barryvdh\DomPDF\ServiceProvider"

# Create directories
mkdir -p storage/stampe/{generated,templates,assets}

# Set permissions
chmod -R 775 storage/stampe/
```

### ⚙️ **Configuration**
```php
// config/dompdf.php
return [
    'show_warnings' => false,
    'public_path' => public_path(),
    'convert_entities' => true,
    'options' => [
        'font_dir' => storage_path('fonts/'),
        'font_cache' => storage_path('fonts/'),
        'temp_dir' => sys_get_temp_dir(),
        'chroot' => realpath(base_path()),
        'allowed_protocols' => [
            'file://' => ['rules' => []],
            'http://' => ['rules' => []],
            'https://' => ['rules' => []]
        ],
        'log_output_file' => null,
        'enable_font_subsetting' => false,
        'pdf_backend' => 'CPDF',
        'default_media_type' => 'screen',
        'default_paper_size' => 'a4',
        'default_paper_orientation' => 'portrait',
        'default_font' => 'DejaVu Sans',
        'dpi' => 96,
        'enable_php' => false,
        'enable_javascript' => true,
        'enable_remote' => true,
        'font_height_ratio' => 1.1,
        'enable_html5_parser' => true
    ]
];
```

---

## 📞 **DELIVERABLE PER SVILUPPATORI**

### 📋 **Cosa Fornire**
1. **📁 Templates Blade** completi per ogni documento
2. **🎨 CSS Styles** responsive e print-friendly  
3. **📊 Data Structure** per ogni tipo documento
4. **🔧 Service Classes** per generazione PDF
5. **📧 Email Integration** per invio automatico
6. **⚙️ Admin Interface** per configurazione template
7. **📝 Documentation** completa utilizzo
8. **🧪 Test Cases** per ogni documento

### 📊 **Specifiche Tecniche**
- **Format**: PDF/A per archiviazione a lungo termine
- **Resolution**: 150 DPI per stampa professionale
- **Fonts**: DejaVu Sans (supporto caratteri speciali)
- **Size**: Ottimizzazione file <2MB per documento
- **Accessibility**: PDF accessibile screen reader
- **Security**: Protezione copia/modifica se richiesta

---

*📄 Specifiche complete per implementazione sistema stampe*  
*🔄 Aggiornare dopo implementazione con feedback reale*  
*📞 Coordinamento con team sviluppo esterno consigliato*
