'boolean', 'superficie_totale' => 'decimal:2', 'mq_giardino_comune' => 'decimal:2', 'mq_terrazza_comune' => 'decimal:2', 'ha_ascensore' => 'boolean', 'ha_montacarichi' => 'boolean', 'ha_videocitofono' => 'boolean', 'ha_impianto_allarme' => 'boolean', 'accessibile_disabili' => 'boolean', 'ha_giardino_comune' => 'boolean', 'ha_terrazza_comune' => 'boolean', 'ha_locale_caldaia' => 'boolean', 'ha_locale_contatori' => 'boolean', 'ha_locale_bici' => 'boolean', 'ha_lavanderia' => 'boolean', 'attiva' => 'boolean', ]; /** * Relazione con Stabile */ public function stabile(): BelongsTo { return $this->belongsTo(Stabile::class); } /** * Relazione con Unità Immobiliari */ public function unitaImmobiliari(): HasMany { return $this->hasMany(UnitaImmobiliare::class); } /** * Relazione con utente creatore */ public function createdBy(): BelongsTo { return $this->belongsTo(User::class, 'created_by'); } /** * Relazione con utente modificatore */ public function updatedBy(): BelongsTo { return $this->belongsTo(User::class, 'updated_by'); } /** * Scope per palazzine attive */ public function scopeAttive($query) { return $query->where('attiva', true); } /** * Scope per stabile */ public function scopePerStabile($query, $stabileId) { return $query->where('stabile_id', $stabileId); } /** * Calcola il numero totale di piani */ public function getNumeroTotalePianiAttribute() { $piani = $this->numero_piani_fuori_terra + $this->numero_piani_interrati; return $this->ha_piano_terra ? $piani + 1 : $piani; } /** * Calcola il numero teorico di unità immobiliari */ public function getNumeroTeoricoUnitaAttribute() { return $this->numero_scale * $this->numero_totale_piani * $this->appartamenti_per_piano; } /** * Calcola il numero effettivo di unità immobiliari */ public function getNumeroEffettivoUnitaAttribute() { return $this->unitaImmobiliari()->count(); } /** * Verifica se la palazzina ha l'ascensore */ public function hasAscensore() { return $this->ha_ascensore && $this->numero_ascensori > 0; } /** * Calcola la superficie totale degli spazi comuni */ public function getSuperficieSpaziFomuniAttribute() { $superficie = 0; if ($this->ha_giardino_comune) { $superficie += $this->mq_giardino_comune ?? 0; } if ($this->ha_terrazza_comune) { $superficie += $this->mq_terrazza_comune ?? 0; } return $superficie; } /** * Genera automaticamente le unità immobiliari per questa palazzina */ public function generaUnitaImmobiliari() { $unita = []; // Ciclo per ogni scala for ($scala = 1; $scala <= $this->numero_scale; $scala++) { // Calcola i piani da generare $pianiDaGenerare = []; // Piani interrati for ($piano = -$this->numero_piani_interrati; $piano < 0; $piano++) { $pianiDaGenerare[] = $piano; } // Piano terra (se presente) if ($this->ha_piano_terra) { $pianiDaGenerare[] = 0; } // Piani superiori for ($piano = 1; $piano <= $this->numero_piani_fuori_terra; $piano++) { $pianiDaGenerare[] = $piano; } // Genera unità per ogni piano foreach ($pianiDaGenerare as $piano) { for ($interno = 1; $interno <= $this->appartamenti_per_piano; $interno++) { $codiceUnita = sprintf( '%s-%d-%s-%02d', $this->codice_palazzina, $scala, $piano < 0 ? "({$piano})" : $piano, $interno ); $unita[] = [ 'stabile_id' => $this->stabile_id, 'palazzina_id' => $this->id, 'codice_unita' => $codiceUnita, 'palazzina' => $this->codice_palazzina, 'scala' => (string)$scala, 'piano' => $piano, 'interno' => sprintf('%02d', $interno), 'denominazione' => "Unità {$codiceUnita}", 'millesimi_generali' => round(1000 / $this->numero_teorico_unita, 3), 'created_at' => now(), 'updated_at' => now(), ]; } } } return $unita; } /** * Esegue la generazione automatica delle unità immobiliari */ public function eseguiGenerazioneUnita() { $unita = $this->generaUnitaImmobiliari(); // Elimina le unità esistenti per questa palazzina $this->unitaImmobiliari()->delete(); // Inserisce le nuove unità foreach ($unita as $unitaData) { UnitaImmobiliare::create($unitaData); } return count($unita); } }