netgescon-day0/app/Console/Commands/CreateStabileStructure.php

657 lines
22 KiB
PHP
Executable File

<?php
namespace App\Console\Commands;
use App\Models\Amministratore;
use App\Models\Stabile;
use App\Services\DatabaseManagerService;
use App\Services\TenantArchivePathService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
class CreateStabileStructure extends Command
{
protected $signature = 'netgescon:create-stabile-structure {admin_code : Codice amministratore} {stabile_code : Codice stabile} {--force : Forza ricreazione}';
protected $description = 'Crea struttura completa per stabile (database + cartelle)';
protected DatabaseManagerService $dbManager;
protected TenantArchivePathService $tenantArchivePath;
public function __construct(DatabaseManagerService $dbManager, TenantArchivePathService $tenantArchivePath)
{
parent::__construct();
$this->dbManager = $dbManager;
$this->tenantArchivePath = $tenantArchivePath;
}
public function handle(): int
{
$adminCode = $this->argument('admin_code');
$stabileCode = $this->argument('stabile_code');
$force = $this->option('force');
$this->info("🏗️ Creazione struttura stabile: {$stabileCode} (Admin: {$adminCode})");
// Trova amministratore
$amministratore = Amministratore::where('codice_amministratore', $adminCode)
->orWhere('codice_univoco', $adminCode)
->first();
if (! $amministratore) {
$this->error("❌ Amministratore {$adminCode} non trovato");
return 1;
}
// Trova stabile
$stabile = $amministratore->stabili()->where('codice_stabile', $stabileCode)->first();
if (! $stabile) {
$this->error("❌ Stabile {$stabileCode} non trovato per amministratore {$adminCode}");
return 1;
}
// Verifica se struttura esiste già
if ($stabile->database_dedicato && ! $force) {
$this->warn("⚠️ Struttura stabile già esistente. Usa --force per ricreare");
return 0;
}
// 1. Crea database dedicato stabile
$this->info("💾 Creazione database dedicato stabile...");
$dbResult = $this->dbManager->createStabileDatabase($stabile);
if (! $dbResult['success']) {
$this->error("❌ Errore creazione database: " . $dbResult['error']);
return 1;
}
$this->info("✅ Database stabile creato: " . $dbResult['database_name']);
// 2. Crea struttura cartelle dettagliata
$this->info("📁 Creazione struttura cartelle stabile...");
$this->createDetailedStabileStructure($stabile);
// 3. Crea configurazioni specifiche
$this->info("⚙️ Creazione configurazioni stabile...");
$this->createStabileConfigurations($stabile);
// 4. Popola database con dati iniziali
$this->info("📊 Popolamento database iniziale...");
$this->populateStabileDatabase($stabile);
$this->info("🎉 Struttura stabile {$stabileCode} creata con successo!");
return 0;
}
private function createDetailedStabileStructure(Stabile $stabile): void
{
$basePath = $this->tenantArchivePath->stabileRelativePath($stabile);
$folders = [
// Documenti amministrativi
'documenti/amministrazione/delibere',
'documenti/amministrazione/comunicazioni',
'documenti/amministrazione/relazioni_annuali',
'documenti/amministrazione/regolamenti',
// Assemblee
'documenti/assemblee/convocazioni',
'documenti/assemblee/verbali',
'documenti/assemblee/allegati',
'documenti/assemblee/presenze',
// Contratti e fornitori
'documenti/contratti/manutenzione',
'documenti/contratti/pulizie',
'documenti/contratti/utenze',
'documenti/contratti/assicurazioni',
'documenti/contratti/altri_servizi',
// Contabilità dettagliata
'contabilita/fatture/entrate/quote_condominiali',
'contabilita/fatture/entrate/altre_entrate',
'contabilita/fatture/uscite/ordinarie',
'contabilita/fatture/uscite/straordinarie',
'contabilita/fatture/uscite/utenze',
'contabilita/ricevute/pagamenti',
'contabilita/ricevute/incassi',
'contabilita/bilanci/preventivi',
'contabilita/bilanci/consuntivi',
'contabilita/ripartizioni/spese_ordinarie',
'contabilita/ripartizioni/spese_straordinarie',
// Proprietari e unità
'anagrafica/proprietari/documenti_identita',
'anagrafica/proprietari/contratti_compravendita',
'anagrafica/proprietari/deleghe',
'anagrafica/unita/planimetrie',
'anagrafica/unita/modifiche_interne',
'anagrafica/unita/certificazioni',
// Manutenzioni
'manutenzioni/ordinarie/ascensori',
'manutenzioni/ordinarie/impianti_elettrici',
'manutenzioni/ordinarie/impianti_idrici',
'manutenzioni/ordinarie/pulizie',
'manutenzioni/straordinarie/progetti',
'manutenzioni/straordinarie/preventivi',
'manutenzioni/straordinarie/collaudi',
// Database e backup
'database/backups/daily',
'database/backups/weekly',
'database/backups/monthly',
'database/exports/contabilita',
'database/exports/anagrafica',
'database/scripts',
// Report specifici
'reports/situazione_contabile/mensili',
'reports/situazione_contabile/annuali',
'reports/morosi',
'reports/movimenti',
'reports/assemblee',
'reports/manutenzioni',
// Corrispondenza
'corrispondenza/inviate',
'corrispondenza/ricevute',
'corrispondenza/enti_pubblici',
'corrispondenza/condomini',
// Archivio temporale
'archivio/per_anno',
'archivio/fatture_pagate',
'archivio/pratiche_chiuse',
'archivio/assemblee_passate',
// File temporanei
'temp/upload',
'temp/processing',
'temp/import_export',
'temp/generazione_report',
// Log specifici stabile
'logs/accessi_condomini',
'logs/operazioni_contabili',
'logs/modifiche_anagrafica',
'logs/backup_restore',
];
foreach ($folders as $folder) {
Storage::disk('local')->makeDirectory("{$basePath}/{$folder}");
}
// File informativi per cartelle principali
$infoFiles = [
'documenti/README.md' => $this->generateDocumentiReadme($stabile),
'contabilita/README.md' => $this->generateContabilitaReadme($stabile),
'anagrafica/README.md' => $this->generateAnagraficaReadme($stabile),
'manutenzioni/README.md' => $this->generateManutenzioniReadme($stabile),
];
foreach ($infoFiles as $file => $content) {
Storage::disk('local')->put("{$basePath}/{$file}", $content);
}
}
private function createStabileConfigurations(Stabile $stabile): void
{
$basePath = $this->tenantArchivePath->stabileRelativePath($stabile);
// 1. Configurazione principale stabile
$config = [
'stabile' => [
'codice' => $stabile->codice_stabile,
'denominazione' => $stabile->denominazione,
'indirizzo_completo' => $stabile->indirizzo . ', ' . $stabile->cap . ' ' . $stabile->citta . ' (' . $stabile->provincia . ')',
'amministratore' => [
'codice' => $stabile->amministratore->codice_univoco,
'nome_completo' => $stabile->amministratore->nome_completo,
'studio' => $stabile->amministratore->denominazione_studio,
],
'database_dedicato' => $stabile->database_dedicato,
'created_at' => $stabile->created_at->toISOString(),
'version' => '2.1.0',
],
'database' => [
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => $stabile->database_dedicato,
'backup_path' => 'database/backups',
'retention_days' => 90,
],
'backup' => [
'enabled' => true,
'frequency' => 'daily',
'time' => '03:00',
'retention_days' => 90,
'include_files' => true,
'include_database' => true,
'compress' => true,
],
'folders' => [
'documenti' => 'documenti',
'contabilita' => 'contabilita',
'anagrafica' => 'anagrafica',
'manutenzioni' => 'manutenzioni',
'database' => 'database',
'reports' => 'reports',
'corrispondenza' => 'corrispondenza',
'archivio' => 'archivio',
'temp' => 'temp',
'logs' => 'logs',
],
'contabilita' => [
'anno_contabile' => date('Y'),
'moneta' => 'EUR',
'arrotondamento' => 2,
'iva_default' => 22,
'millesimi_totali' => 1000,
],
'anagrafica' => [
'validazione_cf' => true,
'richiedi_documenti' => true,
'privacy_gdpr' => true,
],
'reports' => [
'automatici' => true,
'frequenza_mensili' => true,
'email_notifiche' => true,
'formato_default' => 'pdf',
],
];
Storage::disk('local')->put(
"{$basePath}/stabile_config.json",
json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
);
// 2. README principale stabile
$readme = $this->generateStabileReadme($stabile);
Storage::disk('local')->put("{$basePath}/README.md", $readme);
// 3. Script manutenzione stabile
$maintenanceScript = $this->generateStabileMaintenanceScript($stabile);
Storage::disk('local')->put("{$basePath}/scripts/maintenance.sh", $maintenanceScript);
// 4. Log iniziale
$logEntry = date('Y-m-d H:i:s') . " - Struttura stabile {$stabile->codice_stabile} creata\n";
Storage::disk('local')->put("{$basePath}/logs/creation.log", $logEntry);
}
private function populateStabileDatabase(Stabile $stabile): void
{
try {
$connection = $this->dbManager->getStabileConnection($stabile);
// Inserisci record stabile di riferimento nella tabella interna
$connection->table('stabili_ref')->updateOrInsert(
['codice_stabile' => $stabile->codice_stabile],
[
'denominazione' => $stabile->denominazione,
'indirizzo' => $stabile->indirizzo,
'cap' => $stabile->cap,
'citta' => $stabile->citta,
'provincia' => $stabile->provincia,
'amministratore_codice' => $stabile->amministratore->codice_univoco,
'updated_at' => now(),
'created_at' => now(),
]
);
$this->info("✅ Database stabile popolato con dati iniziali");
} catch (\Exception $e) {
$this->error("⚠️ Errore popolamento database: " . $e->getMessage());
}
}
private function generateStabileReadme(Stabile $stabile): string
{
return "# 🏢 Stabile: {$stabile->denominazione}
## 📋 Informazioni Generali
- **Codice Stabile**: `{$stabile->codice_stabile}`
- **Denominazione**: {$stabile->denominazione}
- **Indirizzo**: {$stabile->indirizzo}, {$stabile->cap} {$stabile->citta} ({$stabile->provincia})
- **Amministratore**: {$stabile->amministratore->nome_completo}
- **Studio**: {$stabile->amministratore->denominazione_studio}
- **Database Dedicato**: `{$stabile->database_dedicato}`
- **Creato**: {$stabile->created_at->format('d/m/Y H:i')}
## 📁 Struttura Archivio Stabile
### 📄 Documenti Amministrativi
- `documenti/amministrazione/` - Delibere, comunicazioni, relazioni
- `documenti/assemblee/` - Convocazioni, verbali, allegati
- `documenti/contratti/` - Contratti di servizio e manutenzione
### 💰 Contabilità
- `contabilita/fatture/entrate/` - Quote condominiali e altre entrate
- `contabilita/fatture/uscite/` - Spese ordinarie, straordinarie, utenze
- `contabilita/bilanci/` - Preventivi e consuntivi
- `contabilita/ripartizioni/` - Ripartizioni spese per condomino
### 👥 Anagrafica
- `anagrafica/proprietari/` - Documenti proprietari
- `anagrafica/unita/` - Planimetrie e certificazioni unità
### 🔧 Manutenzioni
- `manutenzioni/ordinarie/` - Manutenzioni periodiche
- `manutenzioni/straordinarie/` - Progetti e interventi straordinari
### 💾 Database e Backup
- `database/backups/daily/` - Backup giornalieri
- `database/backups/weekly/` - Backup settimanali
- `database/backups/monthly/` - Backup mensili
- `database/exports/` - Esportazioni dati
### 📊 Reports
- `reports/situazione_contabile/` - Report contabili
- `reports/morosi/` - Elenchi morosi
- `reports/movimenti/` - Report movimenti
- `reports/assemblee/` - Report assemblee
### 📬 Corrispondenza
- `corrispondenza/inviate/` - Comunicazioni inviate
- `corrispondenza/ricevute/` - Comunicazioni ricevute
- `corrispondenza/enti_pubblici/` - Corrispondenza istituzionale
### 📚 Archivio
- `archivio/per_anno/` - Archivio temporale
- `archivio/fatture_pagate/` - Fatture saldate
- `archivio/pratiche_chiuse/` - Pratiche concluse
## 🔧 Funzionalità Specifiche
### 💾 Database Dedicato
- **Nome**: `{$stabile->database_dedicato}`
- **Backup**: Automatici giornalieri
- **Isolamento**: Completo da altri stabili
- **Migrazione**: Supportata via package
### 📊 Contabilità Integrata
- Gestione completa entrate/uscite
- Ripartizioni automatiche per millesimi
- Bilanci preventivi e consuntivi
- Report morosi automatici
### 👥 Gestione Condomini
- Anagrafica completa proprietari
- Storico variazioni proprietà
- Gestione deleghe e rappresentanze
- Privacy GDPR compliant
### 🏗️ Manutenzioni
- Programmazione interventi
- Gestione preventivi e collaudi
- Storico manutenzioni
- Scadenzari automatici
## ⚙️ Configurazioni
### 🔄 Backup Automatici
- **Frequenza**: Giornaliera alle 03:00
- **Retention**: 90 giorni
- **Includes**: Database + Files
- **Compressione**: Abilitata
### 💰 Impostazioni Contabili
- **Anno Contabile**: " . date('Y') . "
- **Moneta**: EUR
- **Arrotondamento**: 2 decimali
- **IVA Default**: 22%
- **Millesimi Totali**: 1000
## 🚀 Comandi Utili
### Backup Stabile
```bash
php artisan netgescon:backup-stabile {$stabile->amministratore->codice_univoco} {$stabile->codice_stabile}
```
### Migrazione Stabile
```bash
php artisan netgescon:migrate-stabile {$stabile->codice_stabile}
```
### Report Contabile
```bash
php artisan netgescon:report-stabile {$stabile->codice_stabile} --type=contabile
```
### Manutenzione
```bash
bash scripts/maintenance.sh
```
---
*Struttura generata automaticamente da NetGescon v2.1.0*
*Stabile: {$stabile->denominazione}*
*Amministratore: {$stabile->amministratore->nome_completo}*
";
}
private function generateDocumentiReadme(Stabile $stabile): string
{
return "# 📄 Documenti Stabile: {$stabile->denominazione}
## 📋 Organizzazione Documenti
### 🏛️ Amministrazione
- **delibere/** - Delibere assembleari
- **comunicazioni/** - Comunicazioni ufficiali
- **relazioni_annuali/** - Relazioni amministratore
- **regolamenti/** - Regolamenti condominiali
### 🗳️ Assemblee
- **convocazioni/** - Convocazioni assemblee
- **verbali/** - Verbali assemblee
- **allegati/** - Allegati alle assemblee
- **presenze/** - Fogli presenze
### 📝 Contratti
- **manutenzione/** - Contratti manutenzione
- **pulizie/** - Contratti pulizie
- **utenze/** - Contratti utenze
- **assicurazioni/** - Polizze assicurative
- **altri_servizi/** - Altri contratti
## 📁 Naming Convention
### Delibere
`YYYY-MM-DD_delibera_numero_oggetto.pdf`
### Verbali
`YYYY-MM-DD_verbale_assemblea_[ordinaria|straordinaria].pdf`
### Contratti
`YYYY-MM-DD_contratto_[fornitore]_[servizio].pdf`
## 🔐 Note Sicurezza
- File sensibili: protezione password
- Backup automatici
- Versionamento documenti
- Log accessi
";
}
private function generateContabilitaReadme(Stabile $stabile): string
{
return "# 💰 Contabilità Stabile: {$stabile->denominazione}
## 📊 Struttura Contabile
### 💵 Entrate
- **quote_condominiali/** - Bollettini quote
- **altre_entrate/** - Entrate varie
### 💸 Uscite
- **ordinarie/** - Spese ordinarie
- **straordinarie/** - Spese straordinarie
- **utenze/** - Bollette utenze
### 🧾 Ricevute
- **pagamenti/** - Ricevute pagamenti
- **incassi/** - Ricevute incassi
### 📈 Bilanci
- **preventivi/** - Bilanci preventivi
- **consuntivi/** - Bilanci consuntivi
### ⚖️ Ripartizioni
- **spese_ordinarie/** - Ripartizioni ordinarie
- **spese_straordinarie/** - Ripartizioni straordinarie
## 📁 Naming Convention
### Fatture
`YYYY-MM-DD_fattura_[numero]_[fornitore].pdf`
### Bollettini
`YYYY-MM_bollettino_quote_[tipologia].pdf`
### Bilanci
`YYYY_bilancio_[preventivo|consuntivo].pdf`
## 📊 Report Automatici
- Situazione contabile mensile
- Elenco morosi
- Movimenti per periodo
- Ripartizioni spese
";
}
private function generateAnagraficaReadme(Stabile $stabile): string
{
return "# 👥 Anagrafica Stabile: {$stabile->denominazione}
## 📋 Gestione Proprietari
### 🆔 Documenti Identità
- **documenti_identita/** - Copie documenti
- **contratti_compravendita/** - Atti compravendita
- **deleghe/** - Deleghe e procure
### 🏠 Unità Immobiliari
- **planimetrie/** - Planimetrie catastali
- **modifiche_interne/** - Modifiche interne
- **certificazioni/** - Certificazioni energetiche
## 📁 Naming Convention
### Proprietari
`[cognome]_[nome]_[tipo_documento]_YYYY-MM-DD.pdf`
### Unità
`unita_[numero]_[tipo_documento]_YYYY-MM-DD.pdf`
## 🔐 Privacy GDPR
- Consenso trattamento dati
- Protezione dati sensibili
- Diritto cancellazione
- Log accessi dati
";
}
private function generateManutenzioniReadme(Stabile $stabile): string
{
return "# 🔧 Manutenzioni Stabile: {$stabile->denominazione}
## 🛠️ Tipologie Manutenzione
### 🔄 Ordinarie
- **ascensori/** - Manutenzioni ascensori
- **impianti_elettrici/** - Impianti elettrici
- **impianti_idrici/** - Impianti idrici
- **pulizie/** - Servizi pulizie
### ⚡ Straordinarie
- **progetti/** - Progetti interventi
- **preventivi/** - Preventivi lavori
- **collaudi/** - Collaudi finali
## 📁 Naming Convention
### Manutenzioni Ordinarie
`YYYY-MM-DD_manutenzione_[impianto]_[ditta].pdf`
### Progetti
`YYYY_progetto_[descrizione]_[tecnico].pdf`
### Collaudi
`YYYY-MM-DD_collaudo_[intervento]_[ente].pdf`
## 📅 Scadenzari
- Manutenzioni periodiche
- Certificazioni obbligatorie
- Controlli di legge
- Revisioni contrattuali
";
}
private function generateStabileMaintenanceScript(Stabile $stabile): string
{
$adminCode = $stabile->amministratore->codice_univoco;
$stabileCode = $stabile->codice_stabile;
return "#!/bin/bash
# Script manutenzione stabile {$stabileCode}
# Amministratore: {$adminCode}
ADMIN_CODE=\"{$adminCode}\"
STABILE_CODE=\"{$stabileCode}\"
BASE_PATH=\"/var/www/netgescon/storage/app/amministratori/\$ADMIN_CODE/stabili/\$STABILE_CODE\"
LOG_FILE=\"\$BASE_PATH/logs/maintenance.log\"
echo \"🏢 Avvio manutenzione stabile \$STABILE_CODE\" | tee -a \$LOG_FILE
# Pulizia file temporanei vecchi (> 3 giorni)
echo \"🗑️ Pulizia file temporanei...\" | tee -a \$LOG_FILE
find \"\$BASE_PATH/temp\" -type f -mtime +3 -delete 2>/dev/null
find \"\$BASE_PATH/temp\" -type d -empty -delete 2>/dev/null
# Pulizia log vecchi (> 180 giorni)
echo \"📝 Pulizia log vecchi...\" | tee -a \$LOG_FILE
find \"\$BASE_PATH/logs\" -name \"*.log\" -mtime +180 -delete 2>/dev/null
# Pulizia backup vecchi (> 90 giorni)
echo \"💾 Pulizia backup vecchi...\" | tee -a \$LOG_FILE
find \"\$BASE_PATH/database/backups\" -name \"*.sql\" -mtime +90 -delete 2>/dev/null
# Backup database stabile
echo \"💾 Backup database stabile...\" | tee -a \$LOG_FILE
BACKUP_DIR=\"\$BASE_PATH/database/backups/daily\"
BACKUP_FILE=\"backup_stabile_\${STABILE_CODE}_\$(date +%Y-%m-%d_%H-%M-%S).sql\"
mkdir -p \"\$BACKUP_DIR\"
mysqldump -h127.0.0.1 -uroot -p\${MYSQL_ROOT_PASSWORD} netgescon_stabile_\${STABILE_CODE} > \"\$BACKUP_DIR/\$BACKUP_FILE\" 2>/dev/null
if [ \$? -eq 0 ]; then
echo \"✅ Backup database creato: \$BACKUP_FILE\" | tee -a \$LOG_FILE
gzip \"\$BACKUP_DIR/\$BACKUP_FILE\"
else
echo \"❌ Errore backup database\" | tee -a \$LOG_FILE
fi
# Verifica integrità database
echo \"🔍 Verifica integrità database...\" | tee -a \$LOG_FILE
TABLES_COUNT=\$(mysql -h127.0.0.1 -uroot -p\${MYSQL_ROOT_PASSWORD} -e \"SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='netgescon_stabile_\${STABILE_CODE}'\" | tail -1)
echo \"📊 Tabelle database: \$TABLES_COUNT\" | tee -a \$LOG_FILE
# Calcola statistiche
TOTAL_SIZE=\$(du -sh \"\$BASE_PATH\" | cut -f1)
FILE_COUNT=\$(find \"\$BASE_PATH\" -type f | wc -l)
DOC_COUNT=\$(find \"\$BASE_PATH/documenti\" -name \"*.pdf\" | wc -l 2>/dev/null || echo 0)
echo \"📊 Statistiche stabile:\" | tee -a \$LOG_FILE
echo \" 📁 File totali: \$FILE_COUNT\" | tee -a \$LOG_FILE
echo \" 📄 Documenti PDF: \$DOC_COUNT\" | tee -a \$LOG_FILE
echo \" 💽 Spazio totale: \$TOTAL_SIZE\" | tee -a \$LOG_FILE
echo \"✅ Manutenzione stabile completata: \$(date)\" | tee -a \$LOG_FILE
echo \"\" >> \$LOG_FILE
";
}
}