321 lines
10 KiB
Markdown
321 lines
10 KiB
Markdown
# 🔗 TABELLE COLLEGATE
|
|
## Tabelle business collegate agli stabili e amministratori
|
|
|
|
---
|
|
|
|
## 🎯 **PRINCIPIO ARCHITETTURALE**
|
|
|
|
### **Isolamento Multi-Tenant**:
|
|
Tutte le tabelle in questa sezione sono **filtrate per amministratore** tramite:
|
|
- **Collegamento diretto** → `amministratore_id`
|
|
- **Collegamento indiretto** → tramite `stabile_id` → `stabili.amministratore_id`
|
|
|
|
### **Catena di Isolamento**:
|
|
```
|
|
amministratori (codice 8 cifre)
|
|
↓
|
|
stabili (amministratore_id)
|
|
↓
|
|
gestioni (stabile_id)
|
|
↓
|
|
unita_immobiliari (stabile_id)
|
|
soggetti (stabile_id)
|
|
contabilita (gestione_id)
|
|
documenti (stabile_id)
|
|
```
|
|
|
|
---
|
|
|
|
## 📂 **TABELLE IN QUESTA SEZIONE**
|
|
|
|
### **🏢 `stabili.md`** - ✅ COMPLETATO
|
|
- **Scopo**: Edifici e condomini gestiti
|
|
- **Collegamento**: `amministratore_id` diretto
|
|
- **Funzionalità**: Dati catastali, mandati, configurazioni
|
|
- **File**: `/02-tabelle-collegate/stabili.md`
|
|
|
|
### **📅 `gestioni.md`** - 🚧 DA CREARE
|
|
- **Scopo**: Periodi amministrativi per stabile
|
|
- **Collegamento**: `stabile_id` → isolamento automatico
|
|
- **Funzionalità**: Anno gestione, budget, chiusura conti
|
|
- **File**: `/02-tabelle-collegate/gestioni.md`
|
|
|
|
### **🏠 `unita-immobiliari.md`** - 📋 DA CREARE
|
|
- **Scopo**: Appartamenti e locali per stabile
|
|
- **Collegamento**: `stabile_id` → isolamento automatico
|
|
- **Funzionalità**: Dati catastali, millesimi, proprietari
|
|
- **File**: `/02-tabelle-collegate/unita-immobiliari.md`
|
|
|
|
### **👤 `soggetti.md`** - 📋 DA CREARE
|
|
- **Scopo**: Anagrafica persone e aziende per stabile
|
|
- **Collegamento**: `stabile_id` → isolamento automatico
|
|
- **Funzionalità**: Proprietari, inquilini, fornitori
|
|
- **File**: `/02-tabelle-collegate/soggetti.md`
|
|
|
|
### **💰 `contabilita.md`** - 📋 DA CREARE
|
|
- **Scopo**: Movimenti contabili per gestione
|
|
- **Collegamento**: `gestione_id` → `stabile_id` → isolamento automatico
|
|
- **Funzionalità**: Piano conti, registrazioni, bilanci
|
|
- **File**: `/02-tabelle-collegate/contabilita.md`
|
|
|
|
### **📄 `documenti.md`** - 📋 DA CREARE
|
|
- **Scopo**: Sistema documentale per stabile
|
|
- **Collegamento**: `stabile_id` → isolamento automatico
|
|
- **Funzionalità**: Upload, categorizzazione, versioning
|
|
- **File**: `/02-tabelle-collegate/documenti.md`
|
|
|
|
---
|
|
|
|
## 🔄 **FLUSSO CREAZIONE DATI**
|
|
|
|
### **Step 1: Crea Stabile**
|
|
```php
|
|
// Amministratore crea nuovo stabile
|
|
$stabile = Stabile::create([
|
|
'amministratore_id' => auth()->user()->amministratore_id, // Auto-assegnato
|
|
'denominazione' => 'Condominio Rosa',
|
|
'indirizzo' => 'Via Roma 123',
|
|
// ... altri campi
|
|
]);
|
|
```
|
|
|
|
### **Step 2: Crea Gestione**
|
|
```php
|
|
// Stabile ha gestioni annuali
|
|
$gestione = $stabile->gestioni()->create([
|
|
'anno_gestione' => 2024,
|
|
'data_inizio' => '2024-01-01',
|
|
'data_fine' => '2024-12-31',
|
|
// ... amministratore_id automaticamente ereditato
|
|
]);
|
|
```
|
|
|
|
### **Step 3: Crea Unità**
|
|
```php
|
|
// Stabile ha unità immobiliari
|
|
$unita = $stabile->unitaImmobiliari()->create([
|
|
'interno' => 'A1',
|
|
'piano' => 1,
|
|
'categoria' => 'A/2',
|
|
// ... amministratore_id automaticamente ereditato
|
|
]);
|
|
```
|
|
|
|
### **Step 4: Collega Soggetti**
|
|
```php
|
|
// Unità ha proprietari/inquilini
|
|
$proprietario = $stabile->soggetti()->create([
|
|
'nome' => 'Mario',
|
|
'cognome' => 'Rossi',
|
|
'tipo_soggetto' => 'proprietario',
|
|
// ... amministratore_id automaticamente ereditato
|
|
]);
|
|
|
|
$unita->soggetti()->attach($proprietario->id, [
|
|
'tipo_rapporto' => 'proprietario',
|
|
'quota_proprieta' => 100.00
|
|
]);
|
|
```
|
|
|
|
---
|
|
|
|
## 🔍 **QUERY PATTERNS COMUNI**
|
|
|
|
### **Dati per Dashboard Amministratore**:
|
|
```php
|
|
$amministratore = auth()->user()->amministratore;
|
|
|
|
$stats = [
|
|
// Stabili
|
|
'stabili_totali' => $amministratore->stabili()->count(),
|
|
'stabili_attivi' => $amministratore->stabili()->active()->count(),
|
|
|
|
// Unità aggregate da tutti gli stabili
|
|
'unita_totali' => DB::table('unita_immobiliari')
|
|
->join('stabili', 'unita_immobiliari.stabile_id', '=', 'stabili.id')
|
|
->where('stabili.amministratore_id', $amministratore->id)
|
|
->count(),
|
|
|
|
// Gestioni attive
|
|
'gestioni_attive' => DB::table('gestioni')
|
|
->join('stabili', 'gestioni.stabile_id', '=', 'stabili.id')
|
|
->where('stabili.amministratore_id', $amministratore->id)
|
|
->where('gestioni.is_active', true)
|
|
->count(),
|
|
|
|
// Incassi mensili (ultimo mese)
|
|
'incassi_ultimo_mese' => DB::table('contabilita_registrazioni')
|
|
->join('gestioni', 'contabilita_registrazioni.gestione_id', '=', 'gestioni.id')
|
|
->join('stabili', 'gestioni.stabile_id', '=', 'stabili.id')
|
|
->where('stabili.amministratore_id', $amministratore->id)
|
|
->where('contabilita_registrazioni.tipo_movimento', 'entrata')
|
|
->whereBetween('contabilita_registrazioni.data_registrazione', [
|
|
now()->subMonth()->startOfMonth(),
|
|
now()->subMonth()->endOfMonth()
|
|
])
|
|
->sum('contabilita_registrazioni.importo'),
|
|
];
|
|
```
|
|
|
|
### **Ricerca Cross-Tabelle**:
|
|
```php
|
|
// Cerca in tutti i dati dell'amministratore
|
|
public function searchGlobale(Request $request)
|
|
{
|
|
$term = $request->input('search');
|
|
$amministratore = auth()->user()->amministratore;
|
|
|
|
$results = [
|
|
'stabili' => $amministratore->stabili()
|
|
->where('denominazione', 'like', "%{$term}%")
|
|
->limit(5)
|
|
->get(),
|
|
|
|
'unita' => DB::table('unita_immobiliari')
|
|
->join('stabili', 'unita_immobiliari.stabile_id', '=', 'stabili.id')
|
|
->where('stabili.amministratore_id', $amministratore->id)
|
|
->where('unita_immobiliari.interno', 'like', "%{$term}%")
|
|
->limit(5)
|
|
->get(),
|
|
|
|
'soggetti' => DB::table('soggetti')
|
|
->join('stabili', 'soggetti.stabile_id', '=', 'stabili.id')
|
|
->where('stabili.amministratore_id', $amministratore->id)
|
|
->where(function($query) use ($term) {
|
|
$query->where('soggetti.nome', 'like', "%{$term}%")
|
|
->orWhere('soggetti.cognome', 'like', "%{$term}%");
|
|
})
|
|
->limit(5)
|
|
->get(),
|
|
];
|
|
|
|
return response()->json($results);
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🗄️ **BACKUP PER AMMINISTRATORE**
|
|
|
|
### **Script Backup Completo**:
|
|
```bash
|
|
#!/bin/bash
|
|
|
|
# Backup completo dati amministratore
|
|
ADMIN_CODE="A1B2C3D4"
|
|
BACKUP_DATE=$(date +%Y%m%d_%H%M%S)
|
|
BACKUP_FILE="backup_${ADMIN_CODE}_${BACKUP_DATE}.sql"
|
|
|
|
# Header del backup
|
|
echo "-- Backup NetGescon Amministratore: $ADMIN_CODE" > $BACKUP_FILE
|
|
echo "-- Data: $(date)" >> $BACKUP_FILE
|
|
echo "-- ====================================" >> $BACKUP_FILE
|
|
|
|
# Backup amministratore
|
|
mysqldump -u netgescon_user -p netgescon amministratori \
|
|
--where="codice_univoco='$ADMIN_CODE'" >> $BACKUP_FILE
|
|
|
|
# Backup stabili
|
|
mysqldump -u netgescon_user -p netgescon stabili \
|
|
--where="amministratore_id IN (SELECT id FROM amministratori WHERE codice_univoco='$ADMIN_CODE')" \
|
|
--no-create-info >> $BACKUP_FILE
|
|
|
|
# Backup gestioni
|
|
mysqldump -u netgescon_user -p netgescon gestioni \
|
|
--where="stabile_id IN (SELECT id FROM stabili WHERE amministratore_id IN (SELECT id FROM amministratori WHERE codice_univoco='$ADMIN_CODE'))" \
|
|
--no-create-info >> $BACKUP_FILE
|
|
|
|
# Backup unità immobiliari
|
|
mysqldump -u netgescon_user -p netgescon unita_immobiliari \
|
|
--where="stabile_id IN (SELECT id FROM stabili WHERE amministratore_id IN (SELECT id FROM amministratori WHERE codice_univoco='$ADMIN_CODE'))" \
|
|
--no-create-info >> $BACKUP_FILE
|
|
|
|
echo "✅ Backup completato: $BACKUP_FILE"
|
|
```
|
|
|
|
---
|
|
|
|
## 🔧 **MIDDLEWARE GLOBALE**
|
|
|
|
### **TenantScope per tutte le tabelle**:
|
|
```php
|
|
// Nel AppServiceProvider o TenantServiceProvider
|
|
public function boot()
|
|
{
|
|
// Scope automatico per tutte le tabelle collegate
|
|
if (auth()->check() && auth()->user()->amministratore_id) {
|
|
$amministratoreId = auth()->user()->amministratore_id;
|
|
|
|
// Tabelle con amministratore_id diretto
|
|
Stabile::addGlobalScope('tenant', function ($query) use ($amministratoreId) {
|
|
$query->where('amministratore_id', $amministratoreId);
|
|
});
|
|
|
|
// Tabelle con collegamento indiretto via stabili
|
|
Gestione::addGlobalScope('tenant', function ($query) use ($amministratoreId) {
|
|
$query->whereHas('stabile', function($q) use ($amministratoreId) {
|
|
$q->where('amministratore_id', $amministratoreId);
|
|
});
|
|
});
|
|
|
|
UnitaImmobiliare::addGlobalScope('tenant', function ($query) use ($amministratoreId) {
|
|
$query->whereHas('stabile', function($q) use ($amministratoreId) {
|
|
$q->where('amministratore_id', $amministratoreId);
|
|
});
|
|
});
|
|
|
|
// ... altri scope
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 **FOREIGN KEY CONSTRAINTS**
|
|
|
|
### **Integrità Referenziale**:
|
|
```sql
|
|
-- Tutte le tabelle collegate hanno cascade appropriato
|
|
ALTER TABLE gestioni
|
|
ADD CONSTRAINT fk_gestioni_stabile
|
|
FOREIGN KEY (stabile_id) REFERENCES stabili(id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE unita_immobiliari
|
|
ADD CONSTRAINT fk_unita_stabile
|
|
FOREIGN KEY (stabile_id) REFERENCES stabili(id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE soggetti
|
|
ADD CONSTRAINT fk_soggetti_stabile
|
|
FOREIGN KEY (stabile_id) REFERENCES stabili(id) ON DELETE CASCADE;
|
|
|
|
-- Eliminando uno stabile = tutti i dati collegati vengono eliminati
|
|
-- Eliminando un amministratore = tutti i suoi stabili + dati vengono eliminati
|
|
```
|
|
|
|
---
|
|
|
|
## 🎯 **ORDINE DI LETTURA CONSIGLIATO**
|
|
|
|
### **Per Implementazione Completa**:
|
|
1. **✅ `stabili.md`** → Già completato, base per tutto
|
|
2. **🚧 `gestioni.md`** → Prossimo, periodi amministrativi
|
|
3. **📋 `unita-immobiliari.md`** → Appartamenti/locali
|
|
4. **📋 `soggetti.md`** → Anagrafica persone
|
|
5. **📋 `contabilita.md`** → Movimenti contabili
|
|
6. **📋 `documenti.md`** → Sistema documentale
|
|
|
|
### **Ogni file contiene**:
|
|
- ✅ **Struttura SQL** completa
|
|
- ✅ **Migration Laravel** pronta
|
|
- ✅ **Model Eloquent** con relazioni
|
|
- ✅ **Seeder** con dati demo
|
|
- ✅ **Query patterns** e esempi
|
|
- ✅ **Validation** e form requests
|
|
|
|
---
|
|
|
|
**🎯 TABELLE COLLEGATE ORGANIZZATE**
|
|
**Tutte filtrate per amministratore - isolamento dati garantito**
|
|
|
|
**📖 Prossimo step: Creare `gestioni.md` per periodi amministrativi**
|