netgescon-master/app/Models/Stabile.php
Pikappa2 f45845ba3c feat: Complete NetGesCon modernization - all core systems implemented
MAJOR IMPLEMENTATION COMPLETED:
 Modern database structure with Laravel best practices
 Complete Eloquent relationships (Amministratore→Stabili→Movements)
 8-character alphanumeric codes system (ADM, ANA, MOV, ALL prefixes)
 Multi-database architecture for administrators
 Complete property management (anagrafica_condominiale, diritti_reali, contratti)
 Distribution system for multi-server deployment
 Universal responsive UI with permission-based sidebar

NEW MODELS & MIGRATIONS:
- AnagraficaCondominiale: Complete person/entity management
- ContattoAnagrafica: Multi-contact system with usage flags
- DirittoReale: Property rights with quotas and percentages
- ContrattoLocazione: Rental contracts with landlord/tenant
- TipoUtilizzo: Property usage types (residential, commercial, etc.)
- Enhanced Stabile: Cadastral data, SDI, rate configuration
- Enhanced UnitaImmobiliare: Modern structure with backward compatibility

SERVICES & CONTROLLERS:
- DistributionService: Multi-server deployment and migration
- FileManagerController: Administrator folder management
- DistributionController: API for server-to-server communication
- MultiDatabaseService: Dynamic database connections

READY FOR PRODUCTION:
 Database schema: Complete and tested
 Models relationships: All working and verified
 Code generation: Automatic 8-char codes implemented
 Testing: Successful data creation confirmed
 Documentation: Complete internal technical docs

NEXT PHASE: Millésimal tables, expense categories, cost distribution engine
2025-07-08 16:24:03 +02:00

284 lines
8.4 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Stabile extends Model
{
use HasFactory;
protected $table = 'stabili';
protected $fillable = [
'amministratore_id',
'denominazione',
'codice_fiscale',
'cod_fisc_amministratore',
'indirizzo',
'citta',
'cap',
'provincia',
'note',
'old_id',
'stato',
// Nuovi campi per i dati catastali
'codice_catastale_comune',
'foglio',
'particella',
'subalterno',
'sezione',
// Nuovi campi per dati SDI
'codice_destinatario_sdi',
'pec_amministratore',
'pec_condominio',
// Nuovi campi per gestione rate
'numero_rate_ordinarie',
'mesi_rate_ordinarie',
'numero_rate_straordinarie',
'mesi_rate_straordinarie',
// Altri campi
'anno_costruzione',
'numero_piani',
'numero_unita',
'superficie_totale',
'tipo_riscaldamento',
'tipo_acqua',
'presenza_ascensore',
'numero_ascensori',
'presenza_giardino',
'presenza_piscina',
'presenza_garage',
'numero_garage',
'codice_interno',
'registro_anagrafe',
'documenti_path',
'attivo'
];
protected $casts = [
'created_at' => 'datetime',
'updated_at' => 'datetime',
'anno_costruzione' => 'integer',
'numero_piani' => 'integer',
'numero_unita' => 'integer',
'superficie_totale' => 'decimal:2',
'numero_ascensori' => 'integer',
'numero_garage' => 'integer',
'numero_rate_ordinarie' => 'integer',
'numero_rate_straordinarie' => 'integer',
'presenza_ascensore' => 'boolean',
'presenza_giardino' => 'boolean',
'presenza_piscina' => 'boolean',
'presenza_garage' => 'boolean',
'registro_anagrafe' => 'boolean',
'attivo' => 'boolean',
'mesi_rate_ordinarie' => 'array',
'mesi_rate_straordinarie' => 'array'
];
/**
* Relazione con Amministratore
*/
public function amministratore()
{
return $this->belongsTo(Amministratore::class, 'amministratore_id', 'id');
}
/**
* Relazione con UnitaImmobiliari
*/
public function unitaImmobiliari()
{
return $this->hasMany(UnitaImmobiliare::class, 'stabile_id', 'id');
}
/**
* Relazione con Tickets
*/
public function tickets()
{
return $this->hasMany(Ticket::class, 'stabile_id', 'id');
}
/**
* Scope per stabili attivi
*/
public function scopeAttivi($query)
{
return $query->where('attivo', true);
}
/**
* Scope per stabili per amministratore
*/
public function scopeByAmministratore($query, $amministratoreId)
{
return $query->where('amministratore_id', $amministratoreId);
}
/**
* Accessor per il nome completo dell'indirizzo
*/
public function getIndirizzoCompletoAttribute()
{
return $this->indirizzo . ', ' . $this->cap . ' ' . $this->citta .
($this->provincia ? ' (' . $this->provincia . ')' : '');
}
/**
* Accessor per i dati catastali
*/
public function getDatiCatastaliAttribute()
{
return [
'codice_comune' => $this->codice_catastale_comune,
'foglio' => $this->foglio,
'particella' => $this->particella,
'subalterno' => $this->subalterno,
'sezione' => $this->sezione
];
}
/**
* Accessor per i dati SDI
*/
public function getDatiSdiAttribute()
{
return [
'codice_destinatario' => $this->codice_destinatario_sdi,
'pec_amministratore' => $this->pec_amministratore,
'pec_condominio' => $this->pec_condominio
];
}
/**
* Accessor per la configurazione rate ordinarie
*/
public function getConfigurazioneRateOrdinarieAttribute()
{
return [
'numero_rate' => $this->numero_rate_ordinarie,
'mesi' => $this->mesi_rate_ordinarie
];
}
/**
* Accessor per la configurazione rate straordinarie
*/
public function getConfigurazioneRateStraordinarieAttribute()
{
return [
'numero_rate' => $this->numero_rate_straordinarie,
'mesi' => $this->mesi_rate_straordinarie
];
}
/**
* Accessor per le caratteristiche dello stabile
*/
public function getCaratteristicheAttribute()
{
return [
'anno_costruzione' => $this->anno_costruzione,
'numero_piani' => $this->numero_piani,
'numero_unita' => $this->numero_unita,
'superficie_totale' => $this->superficie_totale,
'tipo_riscaldamento' => $this->tipo_riscaldamento,
'tipo_acqua' => $this->tipo_acqua,
'presenza_ascensore' => $this->presenza_ascensore,
'numero_ascensori' => $this->numero_ascensori,
'presenza_giardino' => $this->presenza_giardino,
'presenza_piscina' => $this->presenza_piscina,
'presenza_garage' => $this->presenza_garage,
'numero_garage' => $this->numero_garage
];
}
/**
* Metodo per ottenere tutte le anagrafiche associate
*/
public function getAnagraficheAssociate()
{
return AnagraficaCondominiale::whereHas('dirittiReali.unitaImmobiliare', function ($query) {
$query->where('stabile_id', $this->id);
})->orWhereHas('contrattiLocazione.unitaImmobiliare', function ($query) {
$query->where('stabile_id', $this->id);
})->distinct()->get();
}
/**
* Metodo per ottenere i proprietari dello stabile
*/
public function getProprietari()
{
return AnagraficaCondominiale::whereHas('dirittiReali', function ($query) {
$query->where('tipo_diritto', 'proprieta')
->whereNull('data_fine')
->whereHas('unitaImmobiliare', function ($q) {
$q->where('stabile_id', $this->id);
});
})->distinct()->get();
}
/**
* Metodo per ottenere gli inquilini dello stabile
*/
public function getInquilini()
{
return AnagraficaCondominiale::whereHas('contrattiLocazione', function ($query) {
$query->where('stato', 'attivo')
->whereDate('data_inizio', '<=', now())
->where(function ($q) {
$q->whereNull('data_fine')
->orWhereDate('data_fine', '>=', now());
})
->whereHas('unitaImmobiliare', function ($q) {
$q->where('stabile_id', $this->id);
});
})->distinct()->get();
}
/**
* Metodo per calcolare il totale millesimi
*/
public function getTotaleMillesimi($tipo = 'proprieta')
{
$campo = 'millesimi_' . $tipo;
return $this->unitaImmobiliari()->where('attiva', true)->sum($campo);
}
/**
* Metodo per verificare la coerenza dei millesimi
*/
public function verificaMillesimi($tipo = 'proprieta')
{
$totale = $this->getTotaleMillesimi($tipo);
return abs($totale - 1000) < 0.001; // Tolleranza per errori di arrotondamento
}
/**
* Metodo per ottenere le statistiche dello stabile
*/
public function getStatistiche()
{
$unita = $this->unitaImmobiliari()->where('attiva', true);
return [
'totale_unita' => $unita->count(),
'unita_in_locazione' => $unita->whereHas('contrattiLocazione', function ($query) {
$query->where('stato', 'attivo')
->whereDate('data_inizio', '<=', now())
->where(function ($q) {
$q->whereNull('data_fine')
->orWhereDate('data_fine', '>=', now());
});
})->count(),
'superficie_totale' => $unita->sum('superficie_commerciale'),
'totale_millesimi_proprieta' => $this->getTotaleMillesimi('proprieta'),
'totale_proprietari' => $this->getProprietari()->count(),
'totale_inquilini' => $this->getInquilini()->count()
];
}
}