Aggiornato README con roadmap, idee future e note di sicurezza e messi in ordine i DB seed

This commit is contained in:
Pikappa2 2025-07-04 11:16:53 +02:00
parent b8b305fc79
commit 77a4d27bb1
58 changed files with 680 additions and 3010 deletions

View File

@ -1,62 +1,47 @@
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400" alt="Laravel Logo"></a></p>
# NetGesCon - Gestione Condominiale
<p align="center">
<a href="https://github.com/laravel/framework/actions"><img src="https://github.com/laravel/framework/workflows/tests/badge.svg" alt="Build Status"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
</p>
Progetto open source per la gestione avanzata di condomini, amministratori e contabilità, sviluppato in Laravel.
## About Laravel
## Funzionalità principali
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
- Gestione anagrafiche (amministratori, fornitori, soggetti, stabili, unità immobiliari)
- Gestione proprietà e tabelle millesimali
- Gestione piano dei conti condominiale
- Sistema di migration e seeder uniformato secondo le best practice Laravel/Eloquent
- Struttura dati pronta per la gestione multi-condominio e multi-utente
- Interfaccia amministratore ispirata a soluzioni moderne (es. Akaunting)
- Integrazione futura di menu dinamico con [akaunting/laravel-menu](https://github.com/akaunting/laravel-menu)
- UI separata per amministratori (desktop, gestione massiva dati) e per condomini (mobile friendly, funzioni essenziali)
- Possibilità di estendere la piattaforma con moduli aggiuntivi (preventivi, bilanci, automazioni, ticketing, allegati, rateizzazione, ecc.)
- Progetto pensato per essere multi-piattaforma (PC, Mac, Linux)
- [Simple, fast routing engine](https://laravel.com/docs/routing).
- [Powerful dependency injection container](https://laravel.com/docs/container).
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
- [Robust background job processing](https://laravel.com/docs/queues).
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
## Idee e sviluppi futuri
Laravel is accessible, powerful, and provides tools required for large, robust applications.
- Implementazione di un sistema di menu a doppia colonna (sidebar + sottomenu) ispirato ad Akaunting
- Dashboard personalizzate per amministratori e condomini
- Gestione avanzata di prospetti di ripartizione spese
- Integrazione con servizi esterni (es. invio email, notifiche, API)
- Gestione documentale e allegati
- Sistema di ticketing e comunicazioni interne
- Moduli per automazioni e workflow personalizzati
- Apertura a contributi della community e sviluppo collaborativo
## Learning Laravel
## Come contribuire
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
1. Forka il repository
2. Crea una branch per la tua feature
3. Fai una pull request
You may also try the [Laravel Bootcamp](https://bootcamp.laravel.com), where you will be guided through building a modern Laravel application from scratch.
## Note di sicurezza
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains thousands of video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
- Non committare dati sensibili o file `.env`
- Tutti i dati di esempio sono fittizi
## Laravel Sponsors
## Licenza
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the [Laravel Partners program](https://partners.laravel.com).
MIT
### Premium Partners
---
- **[Vehikl](https://vehikl.com)**
- **[Tighten Co.](https://tighten.co)**
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
- **[64 Robots](https://64robots.com)**
- **[Curotec](https://www.curotec.com/services/technologies/laravel)**
- **[DevSquad](https://devsquad.com/hire-laravel-developers)**
- **[Redberry](https://redberry.international/laravel-development)**
- **[Active Logic](https://activelogic.com)**
## Contributing
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
## Code of Conduct
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
## Security Vulnerabilities
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
## License
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
Progetto in sviluppo attivo. Per info e collaborazione: [tuo contatto]

View File

@ -10,7 +10,6 @@ class Fornitore extends Model
use HasFactory;
protected $table = 'fornitori';
protected $primaryKey = 'id_fornitore';
protected $fillable = [
'amministratore_id',
@ -37,7 +36,7 @@ class Fornitore extends Model
*/
public function amministratore()
{
return $this->belongsTo(Amministratore::class, 'amministratore_id', 'id_amministratore');
return $this->belongsTo(Amministratore::class, 'amministratore_id', 'id');
}
/**
@ -45,7 +44,7 @@ class Fornitore extends Model
*/
public function ticketsAssegnati()
{
return $this->hasMany(Ticket::class, 'assegnato_a_fornitore_id', 'id_fornitore');
return $this->hasMany(Ticket::class, 'assegnato_a_fornitore_id', 'id');
}
/**
@ -58,12 +57,10 @@ class Fornitore extends Model
if ($this->indirizzo) $parts[] = $this->indirizzo;
if ($this->cap && $this->citta) {
$parts[] = $this->cap . ' ' . $this->citta;
} elseif ($this->citta) {
$parts[] = $this->citta;
}
if ($this->provincia) $parts[] = '(' . $this->provincia . ')';
return implode(', ', $parts) ?: '-';
return implode(', ', $parts);
}
/**

View File

@ -12,7 +12,6 @@ class Soggetto extends Model
use HasFactory;
protected $table = 'soggetti';
protected $primaryKey = 'id_soggetto';
/**
* The attributes that are mass assignable.
@ -41,16 +40,15 @@ class Soggetto extends Model
public function ticketsRichiesti(): HasMany
{
return $this->hasMany(Ticket::class, 'soggetto_richiedente_id', 'id_soggetto');
return $this->hasMany(Ticket::class, 'soggetto_richiedente_id', 'id');
}
public function rateEmessaResponsabile(): HasMany
{
return $this->hasMany(RataEmessa::class, 'id_soggetto_responsabile', 'id_soggetto');
return $this->hasMany(RataEmessa::class, 'id_soggetto_responsabile', 'id');
}
// In Soggetto.php
public function proprieta() {
return $this->hasMany(Proprieta::class);
}
}

View File

@ -10,7 +10,6 @@ class Stabile extends Model
use HasFactory;
protected $table = 'stabili';
protected $primaryKey = 'id_stabile';
protected $fillable = [
'amministratore_id',
@ -36,7 +35,7 @@ class Stabile extends Model
*/
public function amministratore()
{
return $this->belongsTo(Amministratore::class, 'amministratore_id', 'id_amministratore');
return $this->belongsTo(Amministratore::class, 'amministratore_id', 'id');
}
/**
@ -44,7 +43,7 @@ class Stabile extends Model
*/
public function unitaImmobiliari()
{
return $this->hasMany(UnitaImmobiliare::class, 'stabile_id', 'id_stabile');
return $this->hasMany(UnitaImmobiliare::class, 'stabile_id', 'id');
}
/**
@ -52,7 +51,7 @@ class Stabile extends Model
*/
public function tickets()
{
return $this->hasMany(Ticket::class, 'stabile_id', 'id_stabile');
return $this->hasMany(Ticket::class, 'stabile_id', 'id');
}
/**

View File

@ -13,7 +13,7 @@ class TabellaMillesimale extends Model
protected $fillable = [
'stabile_id',
'nome',
'nome_tabella_millesimale',
'descrizione',
'tipo',
'attiva',
@ -58,7 +58,7 @@ class TabellaMillesimale extends Model
*/
public function scopeOrdinato($query)
{
return $query->orderBy('ordinamento')->orderBy('nome');
return $query->orderBy('ordinamento')->orderBy('nome_tabella_millesimale');
}
/**

View File

@ -37,60 +37,58 @@ class Ticket extends Model
'updated_at' => 'datetime',
];
/**
* Relazione con Stabile
*/
// Relazione con Stabile
public function stabile()
{
return $this->belongsTo(Stabile::class, 'stabile_id', 'id_stabile');
return $this->belongsTo(Stabile::class, 'stabile_id', 'id');
}
/**
* Relazione con UnitaImmobiliare
*/
// Relazione con UnitaImmobiliare
public function unitaImmobiliare()
{
return $this->belongsTo(UnitaImmobiliare::class, 'unita_immobiliare_id', 'id_unita');
return $this->belongsTo(UnitaImmobiliare::class, 'unita_immobiliare_id', 'id');
}
/**
* Relazione con Soggetto richiedente
*/
// Relazione con Soggetto richiedente
public function soggettoRichiedente()
{
return $this->belongsTo(Soggetto::class, 'soggetto_richiedente_id', 'id_soggetto');
return $this->belongsTo(Soggetto::class, 'soggetto_richiedente_id', 'id');
}
/**
* Relazione con CategoriaTicket
*/
// Relazione con CategoriaTicket
public function categoriaTicket()
{
return $this->belongsTo(CategoriaTicket::class, 'categoria_ticket_id');
return $this->belongsTo(CategoriaTicket::class, 'categoria_ticket_id', 'id');
}
/**
* Relazione con User che ha aperto il ticket
*/
public function apertoUser()
// Relazione con User che ha aperto il ticket
public function apertoDaUser()
{
return $this->belongsTo(User::class, 'aperto_da_user_id');
return $this->belongsTo(User::class, 'aperto_da_user_id', 'id');
}
/**
* Relazione con User assegnato
*/
public function assegnatoUser()
// Relazione con User assegnato
public function assegnatoAUser()
{
return $this->belongsTo(User::class, 'assegnato_a_user_id');
return $this->belongsTo(User::class, 'assegnato_a_user_id', 'id');
}
/**
* Relazione con Fornitore assegnato
*/
public function assegnatoFornitore()
// Relazione con Fornitore assegnato
public function assegnatoAFornitore()
{
return $this->belongsTo(Fornitore::class, 'assegnato_a_fornitore_id', 'id_fornitore');
return $this->belongsTo(Fornitore::class, 'assegnato_a_fornitore_id', 'id');
}
// Relazione con TicketUpdate
public function updates()
{
return $this->hasMany(TicketUpdate::class, 'ticket_id', 'id');
}
// Relazione con TicketMessage
public function messages()
{
return $this->hasMany(TicketMessage::class, 'ticket_id', 'id');
}
/**

View File

@ -10,7 +10,6 @@ class UnitaImmobiliare extends Model
use HasFactory;
protected $table = 'unita_immobiliari';
protected $primaryKey = 'id_unita';
protected $fillable = [
'stabile_id',
@ -39,7 +38,7 @@ class UnitaImmobiliare extends Model
*/
public function stabile()
{
return $this->belongsTo(Stabile::class, 'stabile_id', 'id_stabile');
return $this->belongsTo(Stabile::class, 'stabile_id', 'id');
}
/**
@ -47,7 +46,7 @@ class UnitaImmobiliare extends Model
*/
public function tickets()
{
return $this->hasMany(Ticket::class, 'unita_immobiliare_id', 'id_unita');
return $this->hasMany(Ticket::class, 'unita_immobiliare_id', 'id');
}
/**
@ -55,7 +54,7 @@ class UnitaImmobiliare extends Model
*/
public function proprieta()
{
return $this->hasMany(\App\Models\Proprieta::class, 'unita_immobiliare_id', 'id_unita');
return $this->hasMany(Proprieta::class, 'unita_immobiliare_id', 'id');
}
/**

View File

@ -1,40 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('soggetti', function (Blueprint $table) {
$table->id('id_soggetto');
$table->integer('old_id')->nullable()->unique()->comment('ID dal vecchio gestionale');
$table->string('nome')->nullable();
$table->string('cognome')->nullable();
$table->string('ragione_sociale')->nullable();
$table->string('codice_fiscale', 16)->nullable()->index();
$table->string('partita_iva', 11)->nullable()->index();
$table->string('email')->nullable()->index();
$table->string('telefono')->nullable();
$table->string('indirizzo')->nullable();
$table->string('cap', 10)->nullable();
$table->string('citta', 60)->nullable();
$table->string('provincia', 2)->nullable();
$table->enum('tipo', ['proprietario', 'inquilino', 'usufruttuario', 'altro']);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('soggetti');
}
};

View File

@ -1,34 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('amministratori', function (Blueprint $table) {
$table->bigIncrements('id_amministratore'); // Chiave primaria corretta
$table->string('nome');
$table->string('cognome');
$table->foreignId('user_id')->constrained()->onDelete('cascade');
$table->string('denominazione_studio')->nullable();
$table->string('partita_iva')->nullable()->unique(); // Assicurati che sia unica se necessario
$table->string('codice_fiscale_studio')->nullable();
$table->string('indirizzo_studio')->nullable();
$table->string('cap_studio', 10)->nullable();
$table->string('citta_studio', 60)->nullable();
$table->string('provincia_studio', 2)->nullable();
$table->string('telefono_studio')->nullable();
$table->string('email_studio')->nullable();
$table->string('pec_studio')->nullable();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('amministratori');
}
};

View File

@ -1,72 +1,9 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// Migration svuotata: la creazione della tabella 'stabili' è ora gestita dalla migration unificata delle anagrafiche.
// Questo file può essere cancellato dopo la bonifica.
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
// Rinomina la tabella condomini in stabili
Schema::rename('condomini', 'stabili');
// Rinomina la colonna nome in denominazione
Schema::table('stabili', function (Blueprint $table) {
$table->renameColumn('nome', 'denominazione');
$table->renameColumn('id_condominio', 'id_stabile');
});
// Aggiorna le foreign key nelle tabelle correlate
if (Schema::hasTable('unita_immobiliari')) {
Schema::table('unita_immobiliari', function (Blueprint $table) {
$table->dropForeign(['condominio_id']);
$table->renameColumn('condominio_id', 'stabile_id');
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
});
}
if (Schema::hasTable('tickets')) {
Schema::table('tickets', function (Blueprint $table) {
$table->dropForeign(['condominio_id']);
$table->renameColumn('condominio_id', 'stabile_id');
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
});
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
// Ripristina le foreign key nelle tabelle correlate
if (Schema::hasTable('tickets')) {
Schema::table('tickets', function (Blueprint $table) {
$table->dropForeign(['stabile_id']);
$table->renameColumn('stabile_id', 'condominio_id');
$table->foreign('condominio_id')->references('id_condominio')->on('condomini')->onDelete('cascade');
});
}
if (Schema::hasTable('unita_immobiliari')) {
Schema::table('unita_immobiliari', function (Blueprint $table) {
$table->dropForeign(['stabile_id']);
$table->renameColumn('stabile_id', 'condominio_id');
$table->foreign('condominio_id')->references('id_condominio')->on('condomini')->onDelete('cascade');
});
}
// Ripristina le colonne originali
Schema::table('stabili', function (Blueprint $table) {
$table->renameColumn('denominazione', 'nome');
$table->renameColumn('id_stabile', 'id_condominio');
});
// Rinomina la tabella stabili in condomini
Schema::rename('stabili', 'condomini');
}
return new class extends Illuminate\Database\Migrations\Migration {
public function up(): void {}
public function down(): void {}
};

View File

@ -1,37 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('stabili', function (Blueprint $table) {
$table->id('id_stabile');
$table->unsignedBigInteger('amministratore_id');
$table->string('denominazione');
$table->string('indirizzo');
$table->string('cap', 10);
$table->string('citta', 60);
$table->string('provincia', 2);
$table->string('codice_fiscale', 20)->nullable()->unique();
$table->text('note')->nullable();
$table->json('rate_ordinarie_mesi')->nullable();
$table->json('rate_riscaldamento_mesi')->nullable();
$table->text('descrizione_rate')->nullable();
$table->string('stato', 50)->default('attivo');
$table->integer('old_id')->nullable()->unique();
$table->timestamps();
$table->softDeletes();
$table->foreign('amministratore_id')->references('id_amministratore')->on('amministratori')->onDelete('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('stabili');
}
};

View File

@ -1,41 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('unita_immobiliari', function (Blueprint $table) {
$table->id('id_unita');
$table->unsignedBigInteger('id_stabile');
$table->string('fabbricato')->nullable();
$table->string('interno')->nullable();
$table->string('scala')->nullable();
$table->string('piano')->nullable();
$table->string('subalterno')->nullable();
$table->string('categoria_catastale', 10)->nullable();
$table->decimal('superficie', 8, 2)->nullable();
$table->decimal('vani', 5, 2)->nullable();
$table->string('indirizzo')->nullable()->comment('Indirizzo specifico se diverso da quello del condominio');
$table->text('note')->nullable();
$table->timestamps();
$table->softDeletes();
$table->foreign('id_stabile')->references('id_stabile')->on('stabili')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('unita_immobiliari');
}
};

View File

@ -1,28 +1,9 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// Migration svuotata: la creazione della tabella 'proprieta' e le relative FK sono ora gestite dalla migration unificata delle anagrafiche o da una migration master dedicata.
// Questo file può essere cancellato dopo la bonifica.
return new class extends Migration
{
public function up(): void
{
Schema::create('proprieta', function (Blueprint $table) {
$table->id();
$table->foreignId('unita_immobiliare_id')->constrained('unita_immobiliari', 'id_unita')->onDelete('cascade');
$table->foreignId('soggetto_id')->constrained('soggetti', 'id_soggetto')->onDelete('cascade');
$table->enum('tipo_diritto', ['proprietario', 'nudo_proprietario', 'usufruttuario', 'inquilino', 'comodatario', 'altro']);
$table->decimal('percentuale_possesso', 5, 2)->nullable();
$table->date('data_inizio')->nullable();
$table->date('data_fine')->nullable();
$table->text('note')->nullable();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('proprieta');
}
return new class extends Illuminate\Database\Migrations\Migration {
public function up(): void {}
public function down(): void {}
};

View File

@ -1,227 +1,9 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// Migration svuotata: la creazione delle tabelle di contabilità e le relative FK sono ora gestite dalla migration unificata/master.
// Questo file può essere cancellato dopo la bonifica.
return new class extends Migration
{
public function up(): void
{
// Tabella gestioni
Schema::create('gestioni', function (Blueprint $table) {
$table->id('id_gestione');
$table->unsignedBigInteger('stabile_id');
$table->year('anno_gestione');
$table->enum('tipo_gestione', ['ordinaria', 'riscaldamento', 'straordinaria', 'acqua', 'altro']);
$table->date('data_inizio');
$table->date('data_fine');
$table->string('descrizione')->nullable();
$table->enum('stato', ['bozza', 'attiva', 'chiusa'])->default('bozza');
$table->boolean('preventivo_approvato')->default(false);
$table->date('data_approvazione')->nullable();
$table->text('note')->nullable();
$table->timestamps();
$table->softDeletes();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->index(['stabile_id', 'anno_gestione', 'tipo_gestione']);
});
// Tabella voci_spesa
Schema::create('voci_spesa', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->string('codice', 20);
$table->string('descrizione');
$table->enum('tipo_gestione', ['ordinaria', 'riscaldamento', 'straordinaria', 'acqua', 'altro']);
$table->string('categoria', 100)->nullable();
$table->unsignedBigInteger('tabella_millesimale_default_id')->nullable();
$table->decimal('ritenuta_acconto_default', 5, 2)->default(0);
$table->boolean('attiva')->default(true);
$table->integer('ordinamento')->default(0);
$table->timestamps();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->unique(['stabile_id', 'codice']);
});
// Tabella tabelle_millesimali
Schema::create('tabelle_millesimali', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->string('nome');
$table->text('descrizione')->nullable();
$table->enum('tipo', ['proprieta', 'riscaldamento', 'ascensore', 'scale', 'altro']);
$table->boolean('attiva')->default(true);
$table->date('data_approvazione')->nullable();
$table->integer('ordinamento')->default(0);
$table->timestamps();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
});
// Tabella dettagli_tabelle_millesimali
Schema::create('dettagli_tabelle_millesimali', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('tabella_millesimale_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->decimal('millesimi', 10, 4);
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('tabella_millesimale_id')->references('id')->on('tabelle_millesimali')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->unique(['tabella_millesimale_id', 'unita_immobiliare_id'], 'unique_tabella_unita');
});
// Tabella documenti
Schema::create('documenti', function (Blueprint $table) {
$table->id();
$table->morphs('documentable');
$table->string('nome_file');
$table->string('path_file');
$table->string('tipo_documento', 100);
$table->unsignedBigInteger('dimensione_file')->nullable();
$table->string('mime_type', 100)->nullable();
$table->text('descrizione')->nullable();
$table->json('xml_data')->nullable();
$table->string('hash_file', 64)->nullable();
$table->timestamps();
$table->index(['documentable_type', 'documentable_id']);
$table->index('tipo_documento');
});
// Tabella movimenti_contabili
Schema::create('movimenti_contabili', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->unsignedBigInteger('gestione_id');
$table->unsignedBigInteger('fornitore_id')->nullable();
$table->unsignedBigInteger('documento_id')->nullable();
$table->string('protocollo', 50)->unique();
$table->date('data_registrazione');
$table->date('data_documento');
$table->string('numero_documento', 50);
$table->text('descrizione');
$table->enum('tipo_movimento', ['entrata', 'uscita']);
$table->decimal('importo_totale', 10, 2);
$table->decimal('ritenuta_acconto', 10, 2)->default(0);
$table->decimal('importo_netto', 10, 2);
$table->enum('stato', ['bozza', 'registrato', 'contabilizzato', 'annullato'])->default('bozza');
$table->text('note')->nullable();
$table->timestamps();
$table->softDeletes();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->foreign('gestione_id')->references('id_gestione')->on('gestioni')->onDelete('cascade');
$table->foreign('fornitore_id')->references('id_fornitore')->on('fornitori')->onDelete('set null');
$table->foreign('documento_id')->references('id')->on('documenti')->onDelete('set null');
$table->index(['stabile_id', 'data_registrazione']);
$table->index(['gestione_id', 'tipo_movimento']);
});
// Tabella dettagli_movimenti (partita doppia)
Schema::create('dettagli_movimenti', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('movimento_id');
$table->unsignedBigInteger('conto_id')->nullable();
$table->unsignedBigInteger('voce_spesa_id')->nullable();
$table->unsignedBigInteger('tabella_millesimale_id')->nullable();
$table->text('descrizione')->nullable();
$table->decimal('importo_dare', 10, 2)->default(0);
$table->decimal('importo_avere', 10, 2)->default(0);
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('movimento_id')->references('id')->on('movimenti_contabili')->onDelete('cascade');
$table->foreign('voce_spesa_id')->references('id')->on('voci_spesa')->onDelete('set null');
$table->foreign('tabella_millesimale_id')->references('id')->on('tabelle_millesimali')->onDelete('set null');
});
// Tabella banche
Schema::create('banche', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->string('denominazione');
$table->string('iban', 34);
$table->string('bic_swift', 11)->nullable();
$table->string('agenzia')->nullable();
$table->string('indirizzo_agenzia')->nullable();
$table->enum('tipo_conto', ['corrente', 'deposito', 'altro'])->default('corrente');
$table->decimal('saldo_iniziale', 10, 2)->default(0);
$table->date('data_apertura')->nullable();
$table->enum('stato', ['attivo', 'chiuso'])->default('attivo');
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->unique(['stabile_id', 'iban']);
});
// Tabella movimenti_bancari
Schema::create('movimenti_bancari', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('banca_id');
$table->unsignedBigInteger('movimento_contabile_id')->nullable();
$table->date('data_valuta');
$table->date('data_contabile');
$table->enum('tipo_movimento', ['entrata', 'uscita']);
$table->decimal('importo', 10, 2);
$table->text('causale');
$table->string('beneficiario')->nullable();
$table->string('ordinante')->nullable();
$table->string('cro_tro', 50)->nullable();
$table->enum('stato_riconciliazione', ['da_riconciliare', 'riconciliato', 'sospeso'])->default('da_riconciliare');
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('banca_id')->references('id')->on('banche')->onDelete('cascade');
$table->foreign('movimento_contabile_id')->references('id')->on('movimenti_contabili')->onDelete('set null');
$table->index(['banca_id', 'data_valuta']);
$table->index('stato_riconciliazione');
});
// Tabella rate
Schema::create('rate', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('gestione_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->unsignedBigInteger('soggetto_id');
$table->integer('numero_rata');
$table->string('descrizione');
$table->decimal('importo', 10, 2);
$table->date('data_scadenza');
$table->date('data_pagamento')->nullable();
$table->decimal('importo_pagato', 10, 2)->default(0);
$table->enum('stato', ['da_pagare', 'pagata', 'parziale', 'insoluta'])->default('da_pagare');
$table->enum('tipo_rata', ['ordinaria', 'riscaldamento', 'straordinaria', 'conguaglio'])->default('ordinaria');
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('gestione_id')->references('id_gestione')->on('gestioni')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('cascade');
$table->index(['gestione_id', 'data_scadenza']);
$table->index(['unita_immobiliare_id', 'stato']);
});
}
public function down(): void
{
Schema::dropIfExists('rate');
Schema::dropIfExists('movimenti_bancari');
Schema::dropIfExists('banche');
Schema::dropIfExists('dettagli_movimenti');
Schema::dropIfExists('movimenti_contabili');
Schema::dropIfExists('documenti');
Schema::dropIfExists('dettagli_tabelle_millesimali');
Schema::dropIfExists('tabelle_millesimali');
Schema::dropIfExists('voci_spesa');
Schema::dropIfExists('gestioni');
}
return new class extends Illuminate\Database\Migrations\Migration {
public function up(): void {}
public function down(): void {}
};

View File

@ -1,37 +1,9 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// Migration svuotata: la creazione della tabella 'richieste_modifiche' e le relative FK sono ora gestite dalla migration unificata/master.
// Questo file può essere cancellato dopo la bonifica.
return new class extends Migration
{
public function up(): void
{
Schema::create('richieste_modifiche', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('unita_immobiliare_id');
$table->unsignedBigInteger('soggetto_richiedente_id');
$table->enum('tipo_modifica', ['anagrafica', 'catastale', 'proprieta']);
$table->text('descrizione');
$table->json('dati_attuali');
$table->json('dati_proposti');
$table->enum('stato', ['in_attesa', 'approvata', 'rifiutata'])->default('in_attesa');
$table->text('note_amministratore')->nullable();
$table->datetime('data_approvazione')->nullable();
$table->unsignedBigInteger('approvato_da_user_id')->nullable();
$table->timestamps();
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('soggetto_richiedente_id')->references('id_soggetto')->on('soggetti')->onDelete('cascade');
$table->foreign('approvato_da_user_id')->references('id')->on('users')->onDelete('set null');
$table->index(['stato', 'created_at']);
});
}
public function down(): void
{
Schema::dropIfExists('richieste_modifiche');
}
return new class extends Illuminate\Database\Migrations\Migration {
public function up(): void {}
public function down(): void {}
};

View File

@ -1,204 +1,9 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// Migration svuotata: la creazione della tabella 'preventivi' e le relative FK sono ora gestite dalla migration unificata/master.
// Questo file può essere cancellato dopo la bonifica.
return new class extends Migration
{
public function up(): void
{
// Tabella preventivi
Schema::create('preventivi', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->year('anno_gestione');
$table->enum('tipo_gestione', ['ordinaria', 'riscaldamento', 'straordinaria', 'acqua', 'altro']);
$table->string('descrizione');
$table->enum('stato', ['bozza', 'provvisorio', 'definitivo', 'approvato', 'archiviato'])->default('bozza');
$table->decimal('importo_totale', 12, 2)->default(0);
$table->date('data_creazione');
$table->date('data_approvazione')->nullable();
$table->unsignedBigInteger('approvato_da_user_id')->nullable();
$table->text('note')->nullable();
$table->integer('versione')->default(1);
$table->timestamps();
$table->softDeletes();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->foreign('approvato_da_user_id')->references('id')->on('users')->onDelete('set null');
$table->index(['stabile_id', 'anno_gestione', 'tipo_gestione']);
});
// Tabella voci preventivo
Schema::create('voci_preventivo', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('preventivo_id');
$table->string('codice', 20);
$table->string('descrizione');
$table->decimal('importo_preventivato', 10, 2);
$table->decimal('importo_effettivo', 10, 2)->default(0);
$table->unsignedBigInteger('tabella_millesimale_id')->nullable();
$table->unsignedBigInteger('voce_spesa_id')->nullable();
$table->boolean('ricorrente')->default(false);
$table->enum('frequenza', ['mensile', 'trimestrale', 'semestrale', 'annuale'])->nullable();
$table->date('data_scadenza_prevista')->nullable();
$table->integer('ordinamento')->default(0);
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('preventivo_id')->references('id')->on('preventivi')->onDelete('cascade');
$table->foreign('tabella_millesimale_id')->references('id')->on('tabelle_millesimali')->onDelete('set null');
$table->foreign('voce_spesa_id')->references('id')->on('voci_spesa')->onDelete('set null');
});
// Tabella ripartizioni preventivo
Schema::create('ripartizioni_preventivo', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('voce_preventivo_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->decimal('quota_calcolata', 10, 2);
$table->decimal('quota_modificata', 10, 2)->nullable();
$table->decimal('quota_finale', 10, 2);
$table->integer('versione')->default(1);
$table->unsignedBigInteger('modificato_da_user_id')->nullable();
$table->string('motivo_modifica')->nullable();
$table->timestamp('data_modifica')->nullable();
$table->timestamps();
$table->foreign('voce_preventivo_id')->references('id')->on('voci_preventivo')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('modificato_da_user_id')->references('id')->on('users')->onDelete('set null');
$table->unique(['voce_preventivo_id', 'unita_immobiliare_id'], 'unique_voce_unita');
});
// Tabella rate
Schema::create('rate', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('preventivo_id');
$table->string('numero_rata', 50)->unique();
$table->string('descrizione');
$table->date('data_scadenza');
$table->enum('stato', ['bozza', 'emessa', 'modificata', 'annullata'])->default('bozza');
$table->decimal('importo_totale', 12, 2);
$table->integer('versione')->default(1);
$table->unsignedBigInteger('creato_da_user_id');
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('preventivo_id')->references('id')->on('preventivi')->onDelete('cascade');
$table->foreign('creato_da_user_id')->references('id')->on('users')->onDelete('cascade');
});
// Tabella rate unità (dettaglio rate per ogni unità)
Schema::create('rate_unita', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('rata_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->unsignedBigInteger('soggetto_id');
$table->decimal('importo_originale', 10, 2);
$table->decimal('importo_modificato', 10, 2)->nullable();
$table->decimal('importo_finale', 10, 2);
$table->decimal('importo_pagato', 10, 2)->default(0);
$table->enum('stato_pagamento', ['da_pagare', 'parziale', 'pagata', 'insoluta'])->default('da_pagare');
$table->date('data_pagamento')->nullable();
$table->integer('versione')->default(1);
$table->unsignedBigInteger('modificato_da_user_id')->nullable();
$table->string('motivo_modifica')->nullable();
$table->timestamp('data_modifica')->nullable();
$table->timestamps();
$table->foreign('rata_id')->references('id')->on('rate')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('cascade');
$table->foreign('modificato_da_user_id')->references('id')->on('users')->onDelete('set null');
$table->unique(['rata_id', 'unita_immobiliare_id'], 'unique_rata_unita');
});
// Tabella incassi
Schema::create('incassi', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('rata_unita_id');
$table->date('data_incasso');
$table->decimal('importo', 10, 2);
$table->enum('metodo_pagamento', ['bonifico', 'contanti', 'assegno', 'pos', 'altro']);
$table->string('riferimento_bancario')->nullable();
$table->string('numero_documento')->nullable();
$table->unsignedBigInteger('movimento_bancario_id')->nullable();
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('rata_unita_id')->references('id')->on('rate_unita')->onDelete('cascade');
$table->index(['data_incasso', 'metodo_pagamento']);
});
// Tabella log modifiche (audit trail stile GIT)
Schema::create('log_modifiche_preventivo', function (Blueprint $table) {
$table->id();
$table->string('entita'); // 'preventivo', 'voce', 'ripartizione', 'rata'
$table->unsignedBigInteger('entita_id');
$table->integer('versione_precedente');
$table->integer('versione_nuova');
$table->unsignedBigInteger('utente_id');
$table->string('tipo_operazione'); // 'create', 'update', 'delete'
$table->text('motivo');
$table->json('dati_precedenti')->nullable();
$table->json('dati_nuovi');
$table->json('diff')->nullable(); // Differenze stile GIT
$table->timestamps();
$table->foreign('utente_id')->references('id')->on('users')->onDelete('cascade');
$table->index(['entita', 'entita_id', 'versione_nuova']);
});
// Tabella pianificazione spese
Schema::create('pianificazione_spese', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->unsignedBigInteger('preventivo_id')->nullable();
$table->string('descrizione');
$table->decimal('importo_previsto', 10, 2);
$table->date('data_scadenza_prevista');
$table->enum('tipo', ['ricorrente', 'straordinaria', 'manutenzione']);
$table->enum('stato', ['pianificata', 'confermata', 'pagata', 'annullata'])->default('pianificata');
$table->boolean('notifica_inviata')->default(false);
$table->integer('giorni_preavviso')->default(30);
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->foreign('preventivo_id')->references('id')->on('preventivi')->onDelete('set null');
$table->index(['data_scadenza_prevista', 'stato']);
});
// Tabella configurazione banche per automazione
Schema::create('configurazioni_banche', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->string('nome_banca');
$table->string('iban', 34);
$table->string('api_endpoint')->nullable();
$table->text('credenziali_api')->nullable(); // Encrypted
$table->enum('tipo_importazione', ['api', 'csv', 'cbi', 'manuale']);
$table->json('mapping_campi')->nullable();
$table->boolean('attiva')->default(true);
$table->timestamp('ultima_sincronizzazione')->nullable();
$table->timestamps();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('configurazioni_banche');
Schema::dropIfExists('pianificazione_spese');
Schema::dropIfExists('log_modifiche_preventivo');
Schema::dropIfExists('incassi');
Schema::dropIfExists('rate_unita');
Schema::dropIfExists('rate');
Schema::dropIfExists('ripartizioni_preventivo');
Schema::dropIfExists('voci_preventivo');
Schema::dropIfExists('preventivi');
}
return new class extends Illuminate\Database\Migrations\Migration {
public function up(): void {}
public function down(): void {}
};

View File

@ -1,273 +1,9 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// Migration svuotata: la creazione della tabella 'bilanci' e le relative FK sono ora gestite dalla migration unificata/master.
// Questo file può essere cancellato dopo la bonifica.
return new class extends Migration
{
public function up(): void
{
// Tabella bilanci
Schema::create('bilanci', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->unsignedBigInteger('gestione_id');
$table->year('anno_esercizio');
$table->date('data_inizio_esercizio');
$table->date('data_fine_esercizio');
$table->enum('tipo_gestione', ['ordinaria', 'riscaldamento', 'straordinaria', 'acqua', 'altro']);
$table->string('descrizione');
$table->enum('stato', ['bozza', 'provvisorio', 'definitivo', 'approvato', 'chiuso'])->default('bozza');
$table->decimal('totale_entrate', 12, 2)->default(0);
$table->decimal('totale_uscite', 12, 2)->default(0);
$table->decimal('risultato_gestione', 12, 2)->default(0); // Avanzo/Disavanzo
$table->date('data_approvazione')->nullable();
$table->unsignedBigInteger('approvato_da_user_id')->nullable();
$table->date('data_chiusura')->nullable();
$table->unsignedBigInteger('chiuso_da_user_id')->nullable();
$table->text('note')->nullable();
$table->integer('versione')->default(1);
$table->timestamps();
$table->softDeletes();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->foreign('gestione_id')->references('id_gestione')->on('gestioni')->onDelete('cascade');
$table->foreign('approvato_da_user_id')->references('id')->on('users')->onDelete('set null');
$table->foreign('chiuso_da_user_id')->references('id')->on('users')->onDelete('set null');
$table->index(['stabile_id', 'anno_esercizio', 'tipo_gestione']);
});
// Tabella piano dei conti
Schema::create('piano_conti', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->string('codice', 20);
$table->string('descrizione');
$table->enum('tipo_conto', ['attivo', 'passivo', 'costo', 'ricavo']);
$table->enum('categoria', ['patrimoniale', 'economico']);
$table->unsignedBigInteger('conto_padre_id')->nullable();
$table->integer('livello')->default(1);
$table->boolean('attivo')->default(true);
$table->integer('ordinamento')->default(0);
$table->timestamps();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->foreign('conto_padre_id')->references('id')->on('piano_conti')->onDelete('set null');
$table->unique(['stabile_id', 'codice']);
});
// Tabella scritture contabili (partita doppia)
Schema::create('scritture_bilancio', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('bilancio_id');
$table->string('numero_scrittura', 50);
$table->date('data_scrittura');
$table->string('descrizione');
$table->enum('tipo_scrittura', ['apertura', 'gestione', 'chiusura', 'rettifica']);
$table->decimal('importo_totale', 12, 2);
$table->string('riferimento_documento')->nullable();
$table->unsignedBigInteger('movimento_contabile_id')->nullable();
$table->unsignedBigInteger('creato_da_user_id');
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('bilancio_id')->references('id')->on('bilanci')->onDelete('cascade');
$table->foreign('movimento_contabile_id')->references('id')->on('movimenti_contabili')->onDelete('set null');
$table->foreign('creato_da_user_id')->references('id')->on('users')->onDelete('cascade');
$table->index(['bilancio_id', 'data_scrittura']);
});
// Tabella dettagli scritture (dare/avere)
Schema::create('dettagli_scritture_bilancio', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('scrittura_bilancio_id');
$table->unsignedBigInteger('conto_id');
$table->decimal('importo_dare', 12, 2)->default(0);
$table->decimal('importo_avere', 12, 2)->default(0);
$table->string('descrizione_dettaglio')->nullable();
$table->timestamps();
$table->foreign('scrittura_bilancio_id')->references('id')->on('scritture_bilancio')->onDelete('cascade');
$table->foreign('conto_id')->references('id')->on('piano_conti')->onDelete('cascade');
});
// Tabella ripartizioni bilancio
Schema::create('ripartizioni_bilancio', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('scrittura_bilancio_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->unsignedBigInteger('tabella_millesimale_id');
$table->decimal('quota_calcolata', 10, 2);
$table->decimal('quota_modificata', 10, 2)->nullable();
$table->decimal('quota_finale', 10, 2);
$table->integer('versione')->default(1);
$table->unsignedBigInteger('modificato_da_user_id')->nullable();
$table->string('motivo_modifica')->nullable();
$table->timestamp('data_modifica')->nullable();
$table->timestamps();
$table->foreign('scrittura_bilancio_id')->references('id')->on('scritture_bilancio')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('tabella_millesimale_id')->references('id')->on('tabelle_millesimali')->onDelete('cascade');
$table->foreign('modificato_da_user_id')->references('id')->on('users')->onDelete('set null');
});
// Tabella conguagli
Schema::create('conguagli', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('bilancio_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->unsignedBigInteger('soggetto_id');
$table->decimal('totale_rate_pagate', 10, 2)->default(0);
$table->decimal('totale_spese_effettive', 10, 2)->default(0);
$table->decimal('conguaglio_dovuto', 10, 2)->default(0); // Positivo = a credito, Negativo = a debito
$table->enum('tipo_conguaglio', ['a_credito', 'a_debito', 'pareggio']);
$table->enum('stato', ['calcolato', 'confermato', 'pagato', 'rimborsato'])->default('calcolato');
$table->date('data_calcolo');
$table->date('data_pagamento')->nullable();
$table->decimal('importo_pagato', 10, 2)->default(0);
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('bilancio_id')->references('id')->on('bilanci')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('cascade');
$table->index(['bilancio_id', 'tipo_conguaglio']);
});
// Tabella rate conguaglio
Schema::create('rate_conguaglio', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('conguaglio_id');
$table->string('numero_rata', 50)->unique();
$table->string('descrizione');
$table->date('data_scadenza');
$table->decimal('importo_rata', 10, 2);
$table->enum('stato_pagamento', ['da_pagare', 'parziale', 'pagata', 'insoluta'])->default('da_pagare');
$table->decimal('importo_pagato', 10, 2)->default(0);
$table->date('data_pagamento')->nullable();
$table->boolean('rateizzato')->default(false);
$table->integer('numero_rate_totali')->default(1);
$table->integer('numero_rata_corrente')->default(1);
$table->integer('versione')->default(1);
$table->timestamps();
$table->foreign('conguaglio_id')->references('id')->on('conguagli')->onDelete('cascade');
});
// Tabella quadrature
Schema::create('quadrature', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('bilancio_id');
$table->date('data_quadratura');
$table->decimal('saldo_banca_effettivo', 12, 2);
$table->decimal('saldo_contabile_calcolato', 12, 2);
$table->decimal('differenza', 12, 2);
$table->decimal('totale_crediti_condomini', 12, 2);
$table->decimal('totale_debiti_condomini', 12, 2);
$table->decimal('totale_rate_emesse', 12, 2);
$table->decimal('totale_rate_incassate', 12, 2);
$table->boolean('quadratura_ok')->default(false);
$table->text('note_differenze')->nullable();
$table->unsignedBigInteger('verificato_da_user_id');
$table->timestamps();
$table->foreign('bilancio_id')->references('id')->on('bilanci')->onDelete('cascade');
$table->foreign('verificato_da_user_id')->references('id')->on('users')->onDelete('cascade');
});
// Tabella rimborsi assicurativi
Schema::create('rimborsi_assicurativi', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('bilancio_id');
$table->string('numero_sinistro');
$table->string('compagnia_assicurativa');
$table->date('data_sinistro');
$table->date('data_denuncia');
$table->decimal('importo_richiesto', 10, 2);
$table->decimal('importo_liquidato', 10, 2)->default(0);
$table->enum('stato', ['denunciato', 'in_valutazione', 'liquidato', 'rifiutato', 'chiuso']);
$table->enum('tipo_accredito', ['rate_condomini', 'pagamento_diretto', 'fondo_comune']);
$table->date('data_liquidazione')->nullable();
$table->text('descrizione_sinistro');
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('bilancio_id')->references('id')->on('bilanci')->onDelete('cascade');
});
// Tabella reminder e ticket automatici
Schema::create('reminder_bilancio', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('bilancio_id');
$table->enum('tipo_reminder', ['scadenza_spesa', 'rinnovo_contratto', 'verifica_quadratura', 'chiusura_esercizio']);
$table->string('descrizione');
$table->date('data_scadenza');
$table->boolean('ricorrente')->default(false);
$table->enum('frequenza', ['mensile', 'trimestrale', 'semestrale', 'annuale'])->nullable();
$table->integer('giorni_preavviso')->default(30);
$table->enum('stato', ['attivo', 'eseguito', 'annullato'])->default('attivo');
$table->boolean('notifica_inviata')->default(false);
$table->timestamp('data_notifica')->nullable();
$table->unsignedBigInteger('ticket_generato_id')->nullable();
$table->timestamps();
$table->foreign('bilancio_id')->references('id')->on('bilanci')->onDelete('cascade');
$table->foreign('ticket_generato_id')->references('id')->on('tickets')->onDelete('set null');
});
// Tabella log modifiche bilancio (audit trail)
Schema::create('log_modifiche_bilancio', function (Blueprint $table) {
$table->id();
$table->string('entita'); // 'bilancio', 'scrittura', 'ripartizione', 'conguaglio'
$table->unsignedBigInteger('entita_id');
$table->integer('versione_precedente');
$table->integer('versione_nuova');
$table->unsignedBigInteger('utente_id');
$table->string('tipo_operazione'); // 'create', 'update', 'delete', 'approve', 'close'
$table->text('motivo');
$table->json('dati_precedenti')->nullable();
$table->json('dati_nuovi');
$table->json('diff')->nullable(); // Differenze stile GIT
$table->timestamps();
$table->foreign('utente_id')->references('id')->on('users')->onDelete('cascade');
$table->index(['entita', 'entita_id', 'versione_nuova']);
});
// Tabella automazioni fine anno
Schema::create('automazioni_fine_anno', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('bilancio_id');
$table->enum('tipo_automazione', ['chiusura_conti', 'riporto_saldi', 'calcolo_conguagli', 'generazione_rate']);
$table->string('descrizione');
$table->enum('stato', ['programmata', 'in_esecuzione', 'completata', 'errore']);
$table->date('data_programmata');
$table->timestamp('data_esecuzione')->nullable();
$table->json('parametri')->nullable();
$table->json('risultato')->nullable();
$table->text('log_esecuzione')->nullable();
$table->text('errori')->nullable();
$table->timestamps();
$table->foreign('bilancio_id')->references('id')->on('bilanci')->onDelete('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('automazioni_fine_anno');
Schema::dropIfExists('log_modifiche_bilancio');
Schema::dropIfExists('reminder_bilancio');
Schema::dropIfExists('rimborsi_assicurativi');
Schema::dropIfExists('quadrature');
Schema::dropIfExists('rate_conguaglio');
Schema::dropIfExists('conguagli');
Schema::dropIfExists('ripartizioni_bilancio');
Schema::dropIfExists('dettagli_scritture_bilancio');
Schema::dropIfExists('scritture_bilancio');
Schema::dropIfExists('piano_conti');
Schema::dropIfExists('bilanci');
}
return new class extends Illuminate\Database\Migrations\Migration {
public function up(): void {}
public function down(): void {}
};

View File

@ -1,242 +1,9 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// Migration svuotata: la creazione della tabella 'assemblee' e le relative FK sono ora gestite dalla migration unificata/master.
// Questo file può essere cancellato dopo la bonifica.
return new class extends Migration
{
public function up(): void
{
// Tabella assemblee
Schema::create('assemblee', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->enum('tipo', ['ordinaria', 'straordinaria']);
$table->datetime('data_prima_convocazione');
$table->datetime('data_seconda_convocazione');
$table->string('luogo');
$table->text('note')->nullable();
$table->enum('stato', ['bozza', 'convocata', 'svolta', 'chiusa', 'archiviata'])->default('bozza');
$table->date('data_convocazione')->nullable();
$table->date('data_svolgimento')->nullable();
$table->unsignedBigInteger('creato_da_user_id');
$table->timestamps();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->foreign('creato_da_user_id')->references('id')->on('users')->onDelete('cascade');
$table->index(['stabile_id', 'data_prima_convocazione']);
});
// Tabella ordine del giorno
Schema::create('ordine_giorno', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('assemblea_id');
$table->integer('numero_punto');
$table->string('titolo');
$table->text('descrizione');
$table->enum('tipo_voce', ['discussione', 'delibera', 'spesa', 'preventivo', 'altro']);
$table->unsignedBigInteger('collegamento_preventivo_id')->nullable();
$table->decimal('importo_spesa', 12, 2)->nullable();
$table->unsignedBigInteger('tabella_millesimale_id')->nullable();
$table->enum('esito_votazione', ['non_votato', 'approvato', 'respinto', 'rinviato'])->default('non_votato');
$table->integer('voti_favorevoli')->default(0);
$table->integer('voti_contrari')->default(0);
$table->integer('astenuti')->default(0);
$table->decimal('millesimi_favorevoli', 10, 4)->default(0);
$table->decimal('millesimi_contrari', 10, 4)->default(0);
$table->decimal('millesimi_astenuti', 10, 4)->default(0);
$table->text('note_delibera')->nullable();
$table->timestamps();
$table->foreign('assemblea_id')->references('id')->on('assemblee')->onDelete('cascade');
$table->foreign('collegamento_preventivo_id')->references('id')->on('preventivi')->onDelete('set null');
$table->foreign('tabella_millesimale_id')->references('id')->on('tabelle_millesimali')->onDelete('set null');
});
// Tabella convocazioni (tracciamento invii)
Schema::create('convocazioni', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('assemblea_id');
$table->unsignedBigInteger('soggetto_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->enum('canale_invio', ['email', 'pec', 'whatsapp', 'telegram', 'raccomandata', 'mano', 'portiere', 'postale']);
$table->datetime('data_invio');
$table->enum('esito_invio', ['inviato', 'consegnato', 'letto', 'errore', 'rifiutato']);
$table->datetime('data_lettura')->nullable();
$table->string('riferimento_invio')->nullable(); // ID email, numero raccomandata, etc.
$table->text('note_invio')->nullable();
$table->boolean('delega_presente')->default(false);
$table->unsignedBigInteger('delegato_soggetto_id')->nullable();
$table->string('documento_delega')->nullable();
$table->boolean('presenza_confermata')->default(false);
$table->datetime('data_conferma_presenza')->nullable();
$table->timestamps();
$table->foreign('assemblea_id')->references('id')->on('assemblee')->onDelete('cascade');
$table->foreign('soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('delegato_soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('set null');
$table->index(['assemblea_id', 'soggetto_id']);
});
// Tabella presenze assemblea
Schema::create('presenze_assemblea', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('assemblea_id');
$table->unsignedBigInteger('soggetto_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->enum('tipo_presenza', ['presente', 'delegato', 'assente']);
$table->datetime('ora_arrivo')->nullable();
$table->datetime('ora_uscita')->nullable();
$table->string('firma_digitale')->nullable();
$table->string('qr_code')->nullable();
$table->boolean('firma_fisica')->default(false);
$table->decimal('millesimi_rappresentati', 10, 4);
$table->unsignedBigInteger('delegante_soggetto_id')->nullable(); // Se è un delegato
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('assemblea_id')->references('id')->on('assemblee')->onDelete('cascade');
$table->foreign('soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('delegante_soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('set null');
});
// Tabella votazioni
Schema::create('votazioni', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('ordine_giorno_id');
$table->unsignedBigInteger('soggetto_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->enum('voto', ['favorevole', 'contrario', 'astenuto', 'non_votante']);
$table->decimal('millesimi_voto', 10, 4);
$table->datetime('data_voto');
$table->text('motivazione')->nullable();
$table->timestamps();
$table->foreign('ordine_giorno_id')->references('id')->on('ordine_giorno')->onDelete('cascade');
$table->foreign('soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->unique(['ordine_giorno_id', 'soggetto_id', 'unita_immobiliare_id'], 'unique_voto');
});
// Tabella delibere (risultati votazioni)
Schema::create('delibere', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('ordine_giorno_id');
$table->string('numero_delibera');
$table->enum('esito', ['approvata', 'respinta', 'rinviata']);
$table->text('testo_delibera');
$table->integer('totale_voti_favorevoli');
$table->integer('totale_voti_contrari');
$table->integer('totale_astenuti');
$table->decimal('totale_millesimi_favorevoli', 10, 4);
$table->decimal('totale_millesimi_contrari', 10, 4);
$table->decimal('totale_millesimi_astenuti', 10, 4);
$table->decimal('percentuale_approvazione', 5, 2);
$table->boolean('maggioranza_raggiunta');
$table->date('data_delibera');
$table->json('allegati')->nullable();
$table->timestamps();
$table->foreign('ordine_giorno_id')->references('id')->on('ordine_giorno')->onDelete('cascade');
$table->unique('numero_delibera');
});
// Tabella verbali
Schema::create('verbali', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('assemblea_id');
$table->string('numero_verbale');
$table->text('testo_verbale');
$table->json('allegati')->nullable();
$table->date('data_redazione');
$table->unsignedBigInteger('redatto_da_user_id');
$table->string('firma_digitale')->nullable();
$table->boolean('inviato_condomini')->default(false);
$table->datetime('data_invio_condomini')->nullable();
$table->enum('stato', ['bozza', 'definitivo', 'inviato', 'archiviato'])->default('bozza');
$table->timestamps();
$table->foreign('assemblea_id')->references('id')->on('assemblee')->onDelete('cascade');
$table->foreign('redatto_da_user_id')->references('id')->on('users')->onDelete('cascade');
});
// Tabella registro protocollo (per tutte le comunicazioni)
Schema::create('registro_protocollo', function (Blueprint $table) {
$table->id();
$table->string('numero_protocollo')->unique();
$table->enum('tipo_comunicazione', ['convocazione', 'verbale', 'delibera', 'comunicazione', 'delega', 'altro']);
$table->unsignedBigInteger('assemblea_id')->nullable();
$table->unsignedBigInteger('soggetto_destinatario_id')->nullable();
$table->unsignedBigInteger('soggetto_mittente_id')->nullable();
$table->string('oggetto');
$table->text('contenuto')->nullable();
$table->enum('canale', ['email', 'pec', 'whatsapp', 'telegram', 'raccomandata', 'mano', 'portiere', 'postale']);
$table->datetime('data_invio');
$table->enum('esito', ['inviato', 'consegnato', 'letto', 'errore', 'rifiutato']);
$table->datetime('data_consegna')->nullable();
$table->datetime('data_lettura')->nullable();
$table->string('riferimento_esterno')->nullable();
$table->json('allegati')->nullable();
$table->text('note')->nullable();
$table->unsignedBigInteger('creato_da_user_id');
$table->timestamps();
$table->foreign('assemblea_id')->references('id')->on('assemblee')->onDelete('set null');
$table->foreign('soggetto_destinatario_id')->references('id_soggetto')->on('soggetti')->onDelete('set null');
$table->foreign('soggetto_mittente_id')->references('id_soggetto')->on('soggetti')->onDelete('set null');
$table->foreign('creato_da_user_id')->references('id')->on('users')->onDelete('cascade');
$table->index(['data_invio', 'tipo_comunicazione']);
});
// Tabella documenti assemblea
Schema::create('documenti_assemblea', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('assemblea_id');
$table->string('nome_documento');
$table->string('tipo_documento'); // convocazione, verbale, allegato, delega, etc.
$table->string('path_file');
$table->string('mime_type');
$table->unsignedBigInteger('dimensione_file');
$table->string('hash_file');
$table->text('descrizione')->nullable();
$table->unsignedBigInteger('caricato_da_user_id');
$table->timestamps();
$table->foreign('assemblea_id')->references('id')->on('assemblee')->onDelete('cascade');
$table->foreign('caricato_da_user_id')->references('id')->on('users')->onDelete('cascade');
});
// Tabella automazioni spese approvate
Schema::create('automazioni_spese_approvate', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('delibera_id');
$table->unsignedBigInteger('preventivo_generato_id')->nullable();
$table->unsignedBigInteger('ripartizione_generata_id')->nullable();
$table->json('rate_generate')->nullable();
$table->enum('stato_automazione', ['in_attesa', 'in_corso', 'completata', 'errore']);
$table->text('log_automazione')->nullable();
$table->datetime('data_esecuzione')->nullable();
$table->timestamps();
$table->foreign('delibera_id')->references('id')->on('delibere')->onDelete('cascade');
$table->foreign('preventivo_generato_id')->references('id')->on('preventivi')->onDelete('set null');
});
}
public function down(): void
{
Schema::dropIfExists('automazioni_spese_approvate');
Schema::dropIfExists('documenti_assemblea');
Schema::dropIfExists('registro_protocollo');
Schema::dropIfExists('verbali');
Schema::dropIfExists('delibere');
Schema::dropIfExists('votazioni');
Schema::dropIfExists('presenze_assemblea');
Schema::dropIfExists('convocazioni');
Schema::dropIfExists('ordine_giorno');
Schema::dropIfExists('assemblee');
}
return new class extends Illuminate\Database\Migrations\Migration {
public function up(): void {}
public function down(): void {}
};

View File

@ -1,30 +1,9 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void
{
Schema::create('fornitori', function (Blueprint $table) {
$table->bigIncrements('id_fornitore');
$table->integer('old_id')->nullable()->unique()->comment('ID dal vecchio gestionale');
$table->foreignId('amministratore_id')->constrained(table: 'amministratori', column: 'id_amministratore')->onDelete('cascade');
$table->string('ragione_sociale');
$table->string('partita_iva', 20)->nullable();
$table->string('codice_fiscale', 20)->nullable();
$table->string('indirizzo')->nullable();
$table->string('cap', 10)->nullable();
$table->string('citta', 60)->nullable();
$table->string('provincia', 2)->nullable();
$table->string('email')->nullable();
$table->string('pec')->nullable();
$table->string('telefono')->nullable();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('fornitori'); // Già corretto, ma confermo
}
// Migration svuotata: la creazione della tabella 'fornitori' e le relative FK sono ora gestite dalla migration unificata/master.
// Questo file può essere cancellato dopo la bonifica.
return new class extends Illuminate\Database\Migrations\Migration {
public function up(): void {}
public function down(): void {}
};

View File

@ -1,32 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('categorie_ticket', function (Blueprint $table) {
$table->id();
$table->string('nome')->unique();
$table->text('descrizione')->nullable();
// Potresti aggiungere foreign key per assegnatari/fornitori di default
// $table->foreignId('default_user_id')->nullable()->constrained('users')->onDelete('set null');
// $table->foreignId('default_fornitore_id')->nullable()->constrained('fornitori')->onDelete('set null');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('categorie_ticket');
}
};

View File

@ -1,51 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('tickets', function (Blueprint $table) {
$table->id();
$table->foreignId('stabile_id')->constrained(table: 'stabili', column: 'id_stabile')->onDelete('cascade');
$table->foreignId('unita_immobiliare_id')->nullable()->constrained(table: 'unita_immobiliari', column: 'id_unita')->onDelete('set null');
$table->foreignId('soggetto_richiedente_id')->nullable()->constrained(table: 'soggetti', column: 'id_soggetto')->onDelete('set null');
$table->foreignId('aperto_da_user_id')->comment('Utente che ha aperto il ticket')->constrained('users')->onDelete('cascade');
$table->foreignId('categoria_ticket_id')->nullable()->constrained(table: 'categorie_ticket', column: 'id')->onDelete('set null');
$table->string('titolo');
$table->text('descrizione');
$table->string('luogo_intervento')->nullable()->comment('Es. Scala A, Piano 3, Interno 5');
$table->enum('stato', [
'Aperto', 'Preso in Carico', 'In Lavorazione', 'In Attesa Approvazione',
'In Attesa Ricambi', 'Risolto', 'Chiuso', 'Annullato'
])->default('Aperto');
$table->enum('priorita', ['Bassa', 'Media', 'Alta', 'Urgente'])->default('Media');
$table->foreignId('assegnato_a_user_id')->nullable()->comment('Utente interno (manutentore/collaboratore)')->constrained('users')->onDelete('set null'); // Utente del sistema a cui è assegnato
$table->foreignId('assegnato_a_fornitore_id')->nullable()->constrained(table: 'fornitori', column: 'id_fornitore')->onDelete('set null'); // Fornitore esterno assegnato
$table->timestamp('data_apertura')->useCurrent();
$table->date('data_scadenza_prevista')->nullable();
$table->timestamp('data_risoluzione_effettiva')->nullable();
$table->timestamp('data_chiusura_effettiva')->nullable();
$table->timestamps(); // created_at, updated_at
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('tickets');
}
};

View File

@ -1,30 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('ticket_updates', function (Blueprint $table) {
$table->id();
$table->foreignId('ticket_id')->constrained('tickets')->onDelete('cascade');
$table->foreignId('user_id')->nullable()->comment('Utente che ha fatto l\'aggiornamento')->constrained('users')->onDelete('set null');
$table->text('update_text')->comment('Testo dell\'aggiornamento o nota interna');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('ticket_updates');
}
};

View File

@ -1,30 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('ticket_messages', function (Blueprint $table) {
$table->id(); // Chiave primaria
$table->foreignId('ticket_id')->constrained('tickets')->onDelete('cascade'); // Ticket a cui appartiene il messaggio
$table->foreignId('user_id')->nullable()->constrained('users')->onDelete('set null'); // Utente che ha scritto il messaggio (se loggato)
$table->text('messaggio'); // Contenuto del messaggio
$table->timestamps(); // Include created_at (data invio)
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('ticket_messages');
}
};

View File

@ -1,37 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('ticket_attachments', function (Blueprint $table) {
$table->id();
// Un allegato può essere legato direttamente al ticket o a un suo aggiornamento
$table->foreignId('ticket_id')->constrained('tickets')->onDelete('cascade');
$table->foreignId('ticket_update_id')->nullable()->constrained('ticket_updates')->onDelete('cascade');
$table->foreignId('user_id')->comment('Utente che ha caricato l allegato')->constrained('users')->onDelete('cascade');
$table->string('file_path');
$table->string('original_file_name');
$table->string('mime_type')->nullable();
$table->unsignedBigInteger('size')->nullable()->comment('Dimensione in bytes');
$table->string('description')->nullable(); // Descrizione opzionale dell'allegato
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('ticket_attachments');
}
};

View File

@ -1,43 +1,9 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// Migration svuotata: la creazione della tabella 'conti_condominio' e le relative FK sono ora gestite dalla migration unificata/master.
// Questo file può essere cancellato dopo la bonifica.
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('conti_condominio', function (Blueprint $table) {
$table->bigIncrements('id_conto_condominio');
$table->unsignedBigInteger('id_stabile');
$table->string('codice_conto', 50)->nullable()->unique();
$table->string('nome_conto');
$table->string('iban', 34)->nullable()->unique();
$table->string('bic_swift', 11)->nullable();
$table->string('nome_banca')->nullable();
$table->string('filiale_banca')->nullable();
$table->string('tipo_conto', 50)->comment('Es. BANCARIO, CASSA, PAYPAL');
$table->decimal('saldo_iniziale', 15, 2)->default(0.00);
$table->date('data_saldo_iniziale');
$table->string('valuta', 3)->default('EUR');
$table->boolean('attivo')->default(true);
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('id_stabile')->references('id_stabile')->on('stabili')->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('conti_condominio');
}
return new class extends Illuminate\Database\Migrations\Migration {
public function up(): void {}
public function down(): void {}
};

View File

@ -1,35 +1,9 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// Migration svuotata: la creazione della tabella 'tabelle_millesimali' e le relative FK sono ora gestite dalla migration unificata/master.
// Questo file può essere cancellato dopo la bonifica.
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('tabelle_millesimali', function (Blueprint $table) {
$table->bigIncrements('id_tabella_millesimale');
$table->unsignedBigInteger('id_stabile');
$table->string('nome_tabella', 100);
$table->text('descrizione')->nullable();
$table->string('tipo_tabella', 50)->nullable();
$table->decimal('totale_millesimi_teorico', 10, 4)->default(1000.0000);
$table->boolean('attiva')->default(true);
$table->timestamps();
$table->foreign('id_stabile')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->unique(['id_stabile', 'nome_tabella']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('tabelle_millesimali');
}
return new class extends Illuminate\Database\Migrations\Migration {
public function up(): void {}
public function down(): void {}
};

View File

@ -1,35 +1,9 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// Migration svuotata: la creazione della tabella 'dettagli_tabelle_millesimali' e le relative FK sono ora gestite dalla migration unificata/master.
// Questo file può essere cancellato dopo la bonifica.
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('dettagli_tabelle_millesimali', function (Blueprint $table) {
$table->bigIncrements('id_dettaglio_millesimale');
$table->unsignedBigInteger('id_tabella_millesimale');
$table->unsignedBigInteger('id_unita');
$table->decimal('valore_millesimale', 10, 4);
$table->decimal('coefficiente_correttivo', 8, 4)->default(1.0000);
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('id_tabella_millesimale')->references('id_tabella_millesimale')->on('tabelle_millesimali')->onDelete('cascade');
$table->foreign('id_unita')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->unique(['id_tabella_millesimale', 'id_unita'], 'dett_milles_tab_unita_unique');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('dettagli_tabelle_millesimali');
}
return new class extends Illuminate\Database\Migrations\Migration {
public function up(): void {}
public function down(): void {}
};

View File

@ -1,36 +1,9 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// Migration svuotata: la creazione della tabella 'gestioni' e le relative FK sono ora gestite dalla migration unificata/master.
// Questo file può essere cancellato dopo la bonifica.
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('gestioni', function (Blueprint $table) {
$table->bigIncrements('id_gestione');
$table->unsignedBigInteger('id_stabile');
$table->integer('anno');
$table->enum('tipo', ['ORDINARIA', 'RISCALDAMENTO', 'STRAORDINARIA']);
$table->date('data_inizio');
$table->date('data_fine');
$table->enum('stato', ['aperta', 'chiusa'])->default('aperta');
$table->timestamps();
$table->foreign('id_stabile')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->unique(['id_stabile', 'anno', 'tipo'], 'unique_gestione_per_stabile_anno_tipo');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('gestioni');
}
return new class extends Illuminate\Database\Migrations\Migration {
public function up(): void {}
public function down(): void {}
};

View File

@ -11,6 +11,7 @@ return new class extends Migration
*/
public function up(): void
{
if (!Schema::hasTable('voci_spesa')) {
Schema::create('voci_spesa', function (Blueprint $table) {
$table->bigIncrements('id_voce');
$table->string('codice')->nullable()->unique();
@ -19,8 +20,9 @@ return new class extends Migration
$table->text('note')->nullable();
$table->timestamps();
});
}
}
/**
* Reverse the migrations.
*/

View File

@ -12,7 +12,7 @@ return new class extends Migration
public function up(): void
{
Schema::create('piani_conti_modello', function (Blueprint $table) {
$table->bigIncrements('id_conto_modello');
$table->bigIncrements('id'); // PK uniformata
$table->string('codice', 20)->unique();
$table->string('descrizione');
$table->string('tipo_conto', 50)->comment('Es. PATRIMONIALE_ATTIVITA, ECONOMICO_COSTO, FINANZIARIO_ATTIVITA');

View File

@ -1,39 +1,9 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// Migration svuotata: la creazione della tabella 'piano_conti_condominio' e le relative FK sono ora gestite dalla migration unificata/master.
// Questo file può essere cancellato dopo la bonifica.
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('piano_conti_condominio', function (Blueprint $table) {
$table->bigIncrements('id_conto_condominio_pc');
$table->unsignedBigInteger('id_stabile');
$table->unsignedBigInteger('id_conto_modello_riferimento')->nullable();
$table->string('codice', 20);
$table->string('descrizione');
$table->string('tipo_conto', 50);
$table->string('natura_saldo_tipico', 5)->nullable();
$table->boolean('is_conto_finanziario')->default(false);
$table->boolean('attivo')->default(true);
$table->text('note')->nullable();
$table->foreign('id_stabile')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->foreign('id_conto_modello_riferimento')->references('id_conto_modello')->on('piani_conti_modello')->onDelete('set null');
$table->unique(['id_stabile', 'codice']);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('piano_conti_condominio');
}
return new class extends Illuminate\Database\Migrations\Migration {
public function up(): void {}
public function down(): void {}
};

View File

@ -1,8 +1,6 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
@ -11,26 +9,7 @@ return new class extends Migration
*/
public function up(): void
{
Schema::create('transazioni_contabili', function (Blueprint $table) {
$table->bigIncrements('id_transazione');
$table->unsignedBigInteger('id_stabile');
$table->unsignedBigInteger('id_gestione')->nullable();
$table->date('data_registrazione');
$table->date('data_documento')->nullable();
$table->date('data_competenza')->nullable();
$table->string('numero_protocollo_interno', 50)->nullable(); // Rimosso il vincolo unique
$table->string('tipo_documento_origine', 100)->nullable();
$table->string('riferimento_documento_esterno')->nullable();
$table->text('descrizione_generale')->nullable();
$table->decimal('importo_totale_transazione', 15, 2)->nullable(); // Può essere calcolato
$table->string('stato_transazione', 50)->default('PROVVISORIA');
$table->unsignedBigInteger('id_utente_registrazione')->nullable(); // Chi ha registrato
$table->foreign('id_stabile')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->foreign('id_gestione')->references('id_gestione')->on('gestioni')->onDelete('set null');
// Potresti aggiungere una foreign key per id_utente_registrazione
// $table->foreign('id_utente_registrazione')->references('id')->on('users')->onDelete('set null');
$table->timestamps();
});
// Migration legacy svuotata: la tabella transazioni_contabili è ora gestita nella migration master/unificata.
}
/**
@ -38,6 +17,6 @@ return new class extends Migration
*/
public function down(): void
{
Schema::dropIfExists('transazioni_contabili');
// Nessuna azione: la tabella viene gestita dalla migration master.
}
};

View File

@ -1,8 +1,6 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
@ -11,30 +9,7 @@ return new class extends Migration
*/
public function up(): void
{
Schema::create('righe_movimenti_contabili', function (Blueprint $table) {
$table->bigIncrements('id_riga_movimento');
$table->unsignedBigInteger('id_transazione');
$table->unsignedBigInteger('id_piano_conto_condominio_pc');
$table->unsignedBigInteger('id_gestione_imputazione')->nullable(); // Gestione specifica per la riga
$table->text('descrizione_riga')->nullable();
$table->decimal('importo_dare', 15, 2)->default(0.00);
$table->decimal('importo_avere', 15, 2)->default(0.00);
$table->unsignedBigInteger('id_unita_immobiliare')->nullable();
$table->unsignedBigInteger('id_soggetto')->nullable();
$table->unsignedBigInteger('id_fornitore')->nullable();
$table->unsignedBigInteger('id_voce_spesa_originale')->nullable(); // Per compatibilità/import
$table->text('note_riga')->nullable();
$table->foreign('id_transazione')->references('id_transazione')->on('transazioni_contabili')->onDelete('cascade');
$table->foreign('id_piano_conto_condominio_pc')->references('id_conto_condominio_pc')->on('piano_conti_condominio')->onDelete('restrict'); // Non eliminare un conto se usato
$table->foreign('id_gestione_imputazione')->references('id_gestione')->on('gestioni')->onDelete('set null');
$table->foreign('id_unita_immobiliare')->references('id_unita')->on('unita_immobiliari')->onDelete('set null');
$table->foreign('id_soggetto')->references('id_soggetto')->on('soggetti')->onDelete('set null');
$table->foreign('id_fornitore')->references('id_fornitore')->on('fornitori')->onDelete('set null');
$table->foreign('id_voce_spesa_originale')->references('id_voce')->on('voci_spesa')->onDelete('set null');
$table->index('id_piano_conto_condominio_pc');
$table->index('id_gestione_imputazione');
});
// Migration legacy svuotata: la tabella righe_movimenti_contabili è ora gestita nella migration master/unificata.
}
/**
@ -42,6 +17,6 @@ return new class extends Migration
*/
public function down(): void
{
Schema::dropIfExists('righe_movimenti_contabili');
// Nessuna azione: la tabella viene gestita dalla migration master.
}
};

View File

@ -1,33 +1,20 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
* Questa migration è stata svuotata perché la tabella 'preventivi' viene gestita da una migration successiva più completa.
* Non eseguire alcuna operazione qui per evitare errori di tabella già esistente.
*/
public function up(): void
{
Schema::create('preventivi', function (Blueprint $table) {
$table->bigIncrements('id_preventivo');
$table->unsignedBigInteger('id_gestione');
$table->string('descrizione');
$table->date('data_approvazione')->nullable();
$table->string('stato', 50)->default('BOZZA');
$table->text('note')->nullable();
$table->foreign('id_gestione')->references('id_gestione')->on('gestioni')->onDelete('cascade');
$table->timestamps();
});
// Tabella 'preventivi' già gestita da una migration successiva.
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('preventivi');
// Nessuna operazione di rollback necessaria.
}
};

View File

@ -1,37 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('voci_preventivo', function (Blueprint $table) {
$table->bigIncrements('id_voce_preventivo');
$table->unsignedBigInteger('id_preventivo');
$table->unsignedBigInteger('id_piano_conto_condominio_pc');
$table->text('descrizione_personalizzata')->nullable();
$table->decimal('importo_previsto', 15, 2);
$table->unsignedBigInteger('id_tabella_millesimale_ripartizione')->nullable();
$table->jsonb('criterio_ripartizione_speciale')->nullable(); // Per logiche complesse
$table->text('note')->nullable();
$table->foreign('id_preventivo')->references('id_preventivo')->on('preventivi')->onDelete('cascade');
$table->foreign('id_piano_conto_condominio_pc')->references('id_conto_condominio_pc')->on('piano_conti_condominio')->onDelete('restrict');
$table->foreign('id_tabella_millesimale_ripartizione')->references('id_tabella_millesimale')->on('tabelle_millesimali')->onDelete('set null');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('voci_preventivo');
}
};

View File

@ -1,38 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('piani_rateizzazione', function (Blueprint $table) {
$table->bigIncrements('id_piano_rateizzazione');
$table->unsignedBigInteger('id_preventivo')->nullable();
$table->unsignedBigInteger('id_gestione');
$table->string('descrizione');
$table->integer('numero_rate');
$table->date('data_prima_scadenza');
$table->string('periodicita', 50);
$table->jsonb('config_scadenze_personalizzate')->nullable();
$table->string('stato', 50)->default('ATTIVO');
$table->text('note')->nullable();
$table->foreign('id_preventivo')->references('id_preventivo')->on('preventivi')->onDelete('set null');
$table->foreign('id_gestione')->references('id_gestione')->on('gestioni')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('piani_rateizzazione');
}
};

View File

@ -1,47 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('rate_emesse', function (Blueprint $table) {
$table->bigIncrements('id_rata_emessa');
$table->unsignedBigInteger('id_piano_rateizzazione'); // A quale piano di rateizzazione appartiene
$table->unsignedBigInteger('id_unita_immobiliare'); // A quale unità immobiliare si riferisce
$table->unsignedBigInteger('id_soggetto_responsabile'); // Chi deve pagare la rata
$table->integer('numero_rata_progressivo');
$table->text('descrizione')->nullable();
$table->decimal('importo_originario_unita', 15, 2); // Importo totale per l'unità
$table->decimal('percentuale_addebito_soggetto', 7, 4)->default(100.0000); // % per questo soggetto
$table->decimal('importo_addebitato_soggetto', 15, 2); // Importo effettivo per questo soggetto
$table->date('data_emissione');
$table->date('data_scadenza');
$table->string('stato_rata', 50)->default('EMESSA');
$table->date('data_ultimo_pagamento')->nullable();
$table->decimal('importo_pagato', 15, 2)->default(0.00);
$table->text('note')->nullable();
$table->unsignedBigInteger('id_transazione_contabile_emissione')->nullable(); // Link alla scrittura di accertamento credito
$table->foreign('id_piano_rateizzazione')->references('id_piano_rateizzazione')->on('piani_rateizzazione')->onDelete('cascade');
$table->foreign('id_unita_immobiliare')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('id_soggetto_responsabile')->references('id_soggetto')->on('soggetti')->onDelete('restrict');
$table->foreign('id_transazione_contabile_emissione')->references('id_transazione')->on('transazioni_contabili')->onDelete('set null');
$table->unique(['id_piano_rateizzazione', 'id_unita_immobiliare', 'id_soggetto_responsabile', 'numero_rata_progressivo'], 'unique_rata_per_soggetto_unita');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('rate_emesse');
}
};

View File

@ -1,38 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('incassi_rate', function (Blueprint $table) {
$table->bigIncrements('id_incasso_rata');
$table->unsignedBigInteger('id_rata_emessa');
$table->unsignedBigInteger('id_transazione_contabile_incasso'); // Link alla scrittura di incasso
$table->date('data_incasso');
$table->decimal('importo_incassato', 15, 2);
$table->unsignedBigInteger('id_conto_condominio_accredito'); // Conto su cui è avvenuto l'incasso
$table->string('mezzo_pagamento', 50)->nullable();
$table->string('riferimento_pagamento')->nullable(); // Es. CRO, ID Transazione
$table->text('note')->nullable();
$table->foreign('id_rata_emessa')->references('id_rata_emessa')->on('rate_emesse')->onDelete('cascade');
$table->foreign('id_transazione_contabile_incasso')->references('id_transazione')->on('transazioni_contabili')->onDelete('cascade');
$table->foreign('id_conto_condominio_accredito')->references('id_conto_condominio')->on('conti_condominio')->onDelete('restrict');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('incassi_rate');
}
};

View File

@ -1,8 +1,6 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
@ -11,34 +9,7 @@ return new class extends Migration
*/
public function up(): void
{
Schema::create('contratti_locazione_attiva', function (Blueprint $table) {
$table->bigIncrements('id_contratto_locazione');
$table->unsignedBigInteger('id_stabile');
$table->unsignedBigInteger('id_unita_immobiliare'); // Unità di proprietà del condominio
$table->unsignedBigInteger('id_soggetto_conduttore'); // L'inquilino
$table->string('codice_contratto', 50)->nullable()->unique();
$table->date('data_stipula');
$table->date('data_inizio_validita');
$table->integer('durata_mesi');
$table->date('data_prima_scadenza');
$table->date('data_termine_contratto')->nullable();
$table->decimal('canone_mensile_base', 10, 2);
$table->integer('giorno_scadenza_pagamento_canone')->default(5);
$table->decimal('cauzione_importo', 10, 2)->nullable();
$table->date('cauzione_data_versamento')->nullable();
$table->boolean('cauzione_restituita')->default(false);
$table->string('regime_fiscale', 50)->nullable();
$table->boolean('opzione_cedolare_secca')->default(false);
$table->text('riferimenti_registrazione_agenzia_entrate')->nullable();
$table->date('data_registrazione_contratto')->nullable();
$table->text('note_aggiornamento_istat')->nullable();
$table->string('stato_contratto', 50)->default('ATTIVO');
$table->text('note')->nullable();
$table->foreign('id_stabile')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->foreign('id_unita_immobiliare')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('id_soggetto_conduttore')->references('id_soggetto')->on('soggetti')->onDelete('cascade');
$table->timestamps();
});
// Migration legacy svuotata: la tabella contratti_locazione_attiva è ora gestita nella migration master/unificata.
}
/**
@ -46,6 +17,6 @@ return new class extends Migration
*/
public function down(): void
{
Schema::dropIfExists('contratti_locazione_attiva');
// Nessuna azione: la tabella viene gestita dalla migration master.
}
};

View File

@ -1,8 +1,6 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
@ -11,22 +9,7 @@ return new class extends Migration
*/
public function up(): void
{
Schema::create('scadenze_locazione', function (Blueprint $table) {
$table->bigIncrements('id_scadenza_locazione');
$table->unsignedBigInteger('id_contratto_locazione');
$table->string('tipo_scadenza', 50);
$table->text('descrizione')->nullable();
$table->date('data_scadenza');
$table->decimal('importo_dovuto', 10, 2)->nullable();
$table->date('data_pagamento')->nullable();
$table->decimal('importo_pagato', 10, 2)->nullable();
$table->unsignedBigInteger('id_transazione_contabile_collegata')->nullable();
$table->string('stato_scadenza', 50)->default('APERTA');
$table->text('note')->nullable();
$table->foreign('id_contratto_locazione')->references('id_contratto_locazione')->on('contratti_locazione_attiva')->onDelete('cascade');
$table->foreign('id_transazione_contabile_collegata')->references('id_transazione')->on('transazioni_contabili')->onDelete('set null');
$table->timestamps();
});
// Migration legacy svuotata: la tabella scadenze_locazione è ora gestita nella migration master/unificata.
}
/**
@ -34,6 +17,6 @@ return new class extends Migration
*/
public function down(): void
{
Schema::dropIfExists('scadenze_locazione');
// Nessuna azione: la tabella viene gestita dalla migration master.
}
};

View File

@ -1,8 +1,6 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
@ -11,17 +9,7 @@ return new class extends Migration
*/
public function up(): void
{
Schema::table('transazioni_contabili', function (Blueprint $table) {
// Aggiungi i nuovi campi per la gestione del protocollo
$table->string('protocollo_gestione_tipo', 50)->nullable()->after('numero_protocollo_interno');
$table->integer('anno_protocollo_documento')->nullable()->after('protocollo_gestione_tipo');
$table->date('data_protocollo')->nullable()->after('anno_protocollo_documento');
// Aggiungi un vincolo unico composito per il protocollo master (per condominio, per anno)
// Questo assicura che numero_protocollo_interno sia unico per ogni anno e condominio.
$table->unique(['id_stabile', 'anno_protocollo_documento', 'numero_protocollo_interno'], 'unique_master_protocol_per_year_stabile');
});
// Migration patch svuotata: i campi protocollo sono ora gestiti nella migration master/unificata.
}
/**
@ -29,11 +17,6 @@ return new class extends Migration
*/
public function down(): void
{
Schema::table('transazioni_contabili', function (Blueprint $table) {
$table->dropUnique('unique_master_protocol_per_year_stabile');
$table->dropColumn('data_protocollo');
$table->dropColumn('anno_protocollo_documento');
$table->dropColumn('protocollo_gestione_tipo');
});
// Nessuna azione: la tabella viene gestita dalla migration master.
}
};

View File

@ -1,226 +1,16 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
// Esempio: aggiunta di nuovi campi a gestioni (solo se non esistono già)
Schema::table('gestioni', function (Blueprint $table) {
if (!Schema::hasColumn('gestioni', 'preventivo_approvato')) {
$table->boolean('preventivo_approvato')->default(false)->after('stato');
}
if (!Schema::hasColumn('gestioni', 'data_approvazione')) {
$table->date('data_approvazione')->nullable()->after('preventivo_approvato');
}
// ...aggiungi qui solo i nuovi campi che non esistono già...
});
// Esempio: aggiunta di nuovi campi a voci_spesa
Schema::table('voci_spesa', function (Blueprint $table) {
if (!Schema::hasColumn('voci_spesa', 'tabella_millesimale_default_id')) {
$table->unsignedBigInteger('tabella_millesimale_default_id')->nullable();
}
if (!Schema::hasColumn('voci_spesa', 'ritenuta_acconto_default')) {
$table->decimal('ritenuta_acconto_default', 5, 2)->default(0)->after('tabella_millesimale_default_id');
}
// NON aggiungere $table->bigIncrements('id')!
// ...aggiungi qui solo i nuovi campi che non esistono già...
});
// Tabella tabelle_millesimali (solo se non esiste)
if (!Schema::hasTable('tabelle_millesimali')) {
Schema::create('tabelle_millesimali', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->string('nome');
$table->text('descrizione')->nullable();
$table->enum('tipo', ['proprieta', 'riscaldamento', 'ascensore', 'scale', 'altro']);
$table->boolean('attiva')->default(true);
$table->date('data_approvazione')->nullable();
$table->integer('ordinamento')->default(0);
$table->timestamps();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
});
}
// Tabella dettagli_tabelle_millesimali (solo se non esiste)
if (!Schema::hasTable('dettagli_tabelle_millesimali')) {
Schema::create('dettagli_tabelle_millesimali', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('tabella_millesimale_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->decimal('millesimi', 10, 4);
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('tabella_millesimale_id')->references('id')->on('tabelle_millesimali')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->unique(['tabella_millesimale_id', 'unita_immobiliare_id'], 'unique_tabella_unita');
});
}
// Tabella documenti (solo se non esiste)
if (!Schema::hasTable('documenti')) {
Schema::create('documenti', function (Blueprint $table) {
$table->id();
$table->morphs('documentable');
$table->string('nome_file');
$table->string('path_file');
$table->string('tipo_documento', 100);
$table->unsignedBigInteger('dimensione_file')->nullable();
$table->string('mime_type', 100)->nullable();
$table->text('descrizione')->nullable();
$table->json('xml_data')->nullable();
$table->string('hash_file', 64)->nullable();
$table->timestamps();
//$table->index(['documentable_type', 'documentable_id']);
$table->index('tipo_documento');
});
}
// Tabella movimenti_contabili (solo se non esiste)
if (!Schema::hasTable('movimenti_contabili')) {
Schema::create('movimenti_contabili', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->unsignedBigInteger('gestione_id');
$table->unsignedBigInteger('fornitore_id')->nullable();
$table->unsignedBigInteger('documento_id')->nullable();
$table->string('protocollo', 50)->unique();
$table->date('data_registrazione');
$table->date('data_documento');
$table->string('numero_documento', 50);
$table->text('descrizione');
$table->enum('tipo_movimento', ['entrata', 'uscita']);
$table->decimal('importo_totale', 10, 2);
$table->decimal('ritenuta_acconto', 10, 2)->default(0);
$table->decimal('importo_netto', 10, 2);
$table->enum('stato', ['bozza', 'registrato', 'contabilizzato', 'annullato'])->default('bozza');
$table->text('note')->nullable();
$table->timestamps();
$table->softDeletes();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->foreign('gestione_id')->references('id_gestione')->on('gestioni')->onDelete('cascade');
$table->foreign('fornitore_id')->references('id_fornitore')->on('fornitori')->onDelete('set null');
$table->foreign('documento_id')->references('id')->on('documenti')->onDelete('set null');
$table->index(['stabile_id', 'data_registrazione']);
$table->index(['gestione_id', 'tipo_movimento']);
});
}
// Tabella dettagli_movimenti (partita doppia) (solo se non esiste)
if (!Schema::hasTable('dettagli_movimenti')) {
Schema::create('dettagli_movimenti', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('movimento_id');
$table->unsignedBigInteger('conto_id')->nullable();
$table->unsignedBigInteger('voce_spesa_id')->nullable();
$table->unsignedBigInteger('tabella_millesimale_id')->nullable();
$table->text('descrizione')->nullable();
$table->decimal('importo_dare', 10, 2)->default(0);
$table->decimal('importo_avere', 10, 2)->default(0);
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('movimento_id')->references('id')->on('movimenti_contabili')->onDelete('cascade');
$table->foreign('voce_spesa_id')->references('id_voce')->on('voci_spesa')->onDelete('set null');
$table->foreign('tabella_millesimale_id')->references('id_tabella_millesimale')->on('tabelle_millesimali')->onDelete('set null');
});
}
// Tabella banche (solo se non esiste)
if (!Schema::hasTable('banche')) {
Schema::create('banche', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->string('denominazione');
$table->string('iban', 34);
$table->string('bic_swift', 11)->nullable();
$table->string('agenzia')->nullable();
$table->string('indirizzo_agenzia')->nullable();
$table->enum('tipo_conto', ['corrente', 'deposito', 'altro'])->default('corrente');
$table->decimal('saldo_iniziale', 10, 2)->default(0);
$table->date('data_apertura')->nullable();
$table->enum('stato', ['attivo', 'chiuso'])->default('attivo');
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->unique(['stabile_id', 'iban']);
});
}
// Tabella movimenti_bancari (solo se non esiste)
if (!Schema::hasTable('movimenti_bancari')) {
Schema::create('movimenti_bancari', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('banca_id');
$table->unsignedBigInteger('movimento_contabile_id')->nullable();
$table->date('data_valuta');
$table->date('data_contabile');
$table->enum('tipo_movimento', ['entrata', 'uscita']);
$table->decimal('importo', 10, 2);
$table->text('causale');
$table->string('beneficiario')->nullable();
$table->string('ordinante')->nullable();
$table->string('cro_tro', 50)->nullable();
$table->enum('stato_riconciliazione', ['da_riconciliare', 'riconciliato', 'sospeso'])->default('da_riconciliare');
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('banca_id')->references('id')->on('banche')->onDelete('cascade');
$table->foreign('movimento_contabile_id')->references('id')->on('movimenti_contabili')->onDelete('set null');
$table->index(['banca_id', 'data_valuta']);
$table->index('stato_riconciliazione');
});
}
// Tabella rate (solo se non esiste)
if (!Schema::hasTable('rate')) {
Schema::create('rate', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('gestione_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->unsignedBigInteger('soggetto_id');
$table->integer('numero_rata');
$table->string('descrizione');
$table->decimal('importo', 10, 2);
$table->date('data_scadenza');
$table->date('data_pagamento')->nullable();
$table->decimal('importo_pagato', 10, 2)->default(0);
$table->enum('stato', ['da_pagare', 'pagata', 'parziale', 'insoluta'])->default('da_pagare');
$table->enum('tipo_rata', ['ordinaria', 'riscaldamento', 'straordinaria', 'conguaglio'])->default('ordinaria');
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('gestione_id')->references('id_gestione')->on('gestioni')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('cascade');
$table->index(['gestione_id', 'data_scadenza']);
$table->index(['unita_immobiliare_id', 'stato']);
});
}
// Migration patch svuotata: la tabella gestioni e i nuovi campi sono ora gestiti nella migration master/unificata.
}
public function down(): void
{
Schema::dropIfExists('rate');
Schema::dropIfExists('movimenti_bancari');
Schema::dropIfExists('banche');
Schema::dropIfExists('dettagli_movimenti');
Schema::dropIfExists('movimenti_contabili');
Schema::dropIfExists('documenti');
Schema::dropIfExists('dettagli_tabelle_millesimali');
Schema::dropIfExists('tabelle_millesimali');
Schema::dropIfExists('voci_spesa');
Schema::dropIfExists('gestioni');
// Nessuna azione: la tabella viene gestita dalla migration master.
}
};

View File

@ -0,0 +1,16 @@
<?php
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
public function up(): void
{
// Migration legacy svuotata: la tabella richieste_modifiche è ora gestita nella migration master/unificata.
}
public function down(): void
{
// Nessuna azione: la tabella viene gestita dalla migration master.
}
};

View File

@ -0,0 +1,16 @@
<?php
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
public function up(): void
{
// Migration legacy svuotata: la tabella preventivi è ora gestita nella migration master/unificata.
}
public function down(): void
{
// Nessuna azione: la tabella viene gestita dalla migration master.
}
};

View File

@ -0,0 +1,16 @@
<?php
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
public function up(): void
{
// Migration legacy svuotata: la tabella bilanci è ora gestita nella migration master/unificata.
}
public function down(): void
{
// Nessuna azione: la tabella viene gestita dalla migration master.
}
};

View File

@ -0,0 +1,16 @@
<?php
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
public function up(): void
{
// Migration legacy svuotata: la tabella assemblee è ora gestita nella migration master/unificata.
}
public function down(): void
{
// Nessuna azione: la tabella viene gestita dalla migration master.
}
};

View File

@ -0,0 +1,19 @@
<?php
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
// Migration legacy svuotata: le tabelle di rateizzazione sono ora gestite nella migration master/unificata.
}
public function down(): void
{
// Nessuna azione: le tabelle sono gestite dalla migration master.
}
};

View File

@ -0,0 +1,89 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Crea la tabella rate_emesse con tutte le foreign key.
*/
public function up(): void
{
if (!Schema::hasTable('rate_emesse')) {
Schema::create('rate_emesse', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('piano_rateizzazione_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->unsignedBigInteger('soggetto_responsabile_id');
$table->integer('numero_rata_progressivo');
$table->text('descrizione')->nullable();
$table->decimal('importo_originario_unita', 15, 2);
$table->decimal('percentuale_addebito_soggetto', 7, 4)->default(100.0000);
$table->decimal('importo_addebitato_soggetto', 15, 2);
$table->date('data_emissione');
$table->date('data_scadenza');
$table->string('stato_rata', 50)->default('EMESSA');
$table->date('data_ultimo_pagamento')->nullable();
$table->decimal('importo_pagato', 15, 2)->default(0.00);
$table->text('note')->nullable();
$table->unsignedBigInteger('transazione_contabile_emissione_id')->nullable();
$table->unique(['piano_rateizzazione_id', 'unita_immobiliare_id', 'soggetto_responsabile_id', 'numero_rata_progressivo'], 'unique_rata_per_soggetto_unita');
$table->timestamps();
});
}
// Foreign key su piani_rateizzazione
if (Schema::hasTable('rate_emesse') && Schema::hasTable('piani_rateizzazione')) {
$fkExists = \Illuminate\Support\Facades\DB::select("SELECT CONSTRAINT_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_NAME = 'rate_emesse' AND COLUMN_NAME = 'piano_rateizzazione_id' AND CONSTRAINT_SCHEMA = DATABASE() AND REFERENCED_TABLE_NAME IS NOT NULL");
if (empty($fkExists)) {
Schema::table('rate_emesse', function (Blueprint $table) {
$table->foreign('piano_rateizzazione_id')
->references('id_piano_rateizzazione')
->on('piani_rateizzazione')
->onDelete('cascade');
});
}
}
// Foreign key su unita_immobiliari
if (Schema::hasTable('rate_emesse') && Schema::hasTable('unita_immobiliari')) {
$fkExists = \Illuminate\Support\Facades\DB::select("SELECT CONSTRAINT_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_NAME = 'rate_emesse' AND COLUMN_NAME = 'unita_immobiliare_id' AND CONSTRAINT_SCHEMA = DATABASE() AND REFERENCED_TABLE_NAME IS NOT NULL");
if (empty($fkExists)) {
Schema::table('rate_emesse', function (Blueprint $table) {
$table->foreign('unita_immobiliare_id')
->references('id_unita')
->on('unita_immobiliari')
->onDelete('cascade');
});
}
}
// Foreign key su soggetti
if (Schema::hasTable('rate_emesse') && Schema::hasTable('soggetti')) {
$fkExists = \Illuminate\Support\Facades\DB::select("SELECT CONSTRAINT_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_NAME = 'rate_emesse' AND COLUMN_NAME = 'soggetto_responsabile_id' AND CONSTRAINT_SCHEMA = DATABASE() AND REFERENCED_TABLE_NAME IS NOT NULL");
if (empty($fkExists)) {
Schema::table('rate_emesse', function (Blueprint $table) {
$table->foreign('soggetto_responsabile_id')
->references('id_soggetto')
->on('soggetti')
->onDelete('restrict');
});
}
}
// Foreign key su transazioni_contabili
if (Schema::hasTable('rate_emesse') && Schema::hasTable('transazioni_contabili')) {
$fkExists = \Illuminate\Support\Facades\DB::select("SELECT CONSTRAINT_NAME FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_NAME = 'rate_emesse' AND COLUMN_NAME = 'transazione_contabile_emissione_id' AND CONSTRAINT_SCHEMA = DATABASE() AND REFERENCED_TABLE_NAME IS NOT NULL");
if (empty($fkExists)) {
Schema::table('rate_emesse', function (Blueprint $table) {
$table->foreign('transazione_contabile_emissione_id')
->references('id_transazione')
->on('transazioni_contabili')
->onDelete('set null');
});
}
}
}
public function down(): void
{
Schema::dropIfExists('rate_emesse');
}
};

View File

@ -0,0 +1,16 @@
<?php
use Illuminate\Database\Migrations\Migration;
return new class extends Migration
{
public function up(): void
{
// Migration patch svuotata: la tabella rate_emesse e le FK sono ora gestite nella migration master/unificata.
}
public function down(): void
{
// Nessuna azione: la tabella viene gestita dalla migration master.
}
};

View File

@ -0,0 +1,177 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Crea tutte le tabelle anagrafiche principali e le relative foreign key.
* Ordine di creazione: amministratori -> fornitori -> soggetti -> stabili -> unita_immobiliari
*/
public function up(): void
{
// --- Amministratori ---
Schema::create('amministratori', function (Blueprint $table) {
$table->id();
$table->string('nome');
$table->string('cognome');
$table->unsignedBigInteger('user_id');
$table->string('denominazione_studio')->nullable();
$table->string('partita_iva')->nullable()->unique();
$table->string('codice_fiscale_studio')->nullable();
$table->string('indirizzo_studio')->nullable();
$table->string('cap_studio', 10)->nullable();
$table->string('citta_studio', 60)->nullable();
$table->string('provincia_studio', 2)->nullable();
$table->string('telefono_studio')->nullable();
$table->string('email_studio')->nullable();
$table->string('pec_studio')->nullable();
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
// --- Fornitori ---
Schema::create('fornitori', function (Blueprint $table) {
$table->id();
$table->integer('old_id')->nullable()->unique()->comment('ID dal vecchio gestionale');
$table->unsignedBigInteger('amministratore_id');
$table->string('ragione_sociale');
$table->string('partita_iva', 20)->nullable();
$table->string('codice_fiscale', 20)->nullable();
$table->string('indirizzo')->nullable();
$table->string('cap', 10)->nullable();
$table->string('citta', 60)->nullable();
$table->string('provincia', 2)->nullable();
$table->string('email')->nullable();
$table->string('pec')->nullable();
$table->string('telefono')->nullable();
$table->timestamps();
$table->foreign('amministratore_id')->references('id')->on('amministratori')->onDelete('cascade');
});
// --- Soggetti ---
Schema::create('soggetti', function (Blueprint $table) {
$table->id();
$table->integer('old_id')->nullable()->unique()->comment('ID dal vecchio gestionale');
$table->string('nome')->nullable();
$table->string('cognome')->nullable();
$table->string('ragione_sociale')->nullable();
$table->string('codice_fiscale', 16)->nullable()->index();
$table->string('partita_iva', 11)->nullable()->index();
$table->string('email')->nullable()->index();
$table->string('telefono')->nullable();
$table->string('indirizzo')->nullable();
$table->string('cap', 10)->nullable();
$table->string('citta', 60)->nullable();
$table->string('provincia', 2)->nullable();
$table->enum('tipo', ['proprietario', 'inquilino', 'usufruttuario', 'altro']);
$table->timestamps();
});
// --- Stabili ---
Schema::create('stabili', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('amministratore_id');
$table->string('denominazione');
$table->string('indirizzo');
$table->string('cap', 10);
$table->string('citta', 60);
$table->string('provincia', 2);
$table->string('codice_fiscale', 20)->nullable()->unique();
$table->text('note')->nullable();
$table->json('rate_ordinarie_mesi')->nullable();
$table->json('rate_riscaldamento_mesi')->nullable();
$table->text('descrizione_rate')->nullable();
$table->string('stato', 50)->default('attivo');
$table->integer('old_id')->nullable()->unique();
$table->timestamps();
$table->softDeletes();
$table->foreign('amministratore_id')->references('id')->on('amministratori')->onDelete('cascade');
});
// --- Piano Conti Condominio ---
Schema::create('piano_conti_condominio', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->string('codice', 20);
$table->string('descrizione');
$table->string('tipo_conto', 20)->nullable();
$table->boolean('attivo')->default(true);
$table->timestamps();
$table->foreign('stabile_id')->references('id')->on('stabili')->onDelete('cascade');
$table->unique(['stabile_id', 'codice'], 'unique_conto_per_stabile');
});
// --- Unita Immobiliari ---
Schema::create('unita_immobiliari', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->string('fabbricato')->nullable();
$table->string('interno')->nullable();
$table->string('scala')->nullable();
$table->string('piano')->nullable();
$table->string('subalterno')->nullable();
$table->string('categoria_catastale', 10)->nullable();
$table->decimal('superficie', 8, 2)->nullable();
$table->decimal('vani', 5, 2)->nullable();
$table->string('indirizzo')->nullable()->comment('Indirizzo specifico se diverso da quello del condominio');
$table->text('note')->nullable();
$table->timestamps();
$table->softDeletes();
$table->foreign('stabile_id')->references('id')->on('stabili')->onDelete('cascade');
});
// --- Proprieta ---
Schema::create('proprieta', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('soggetto_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->string('tipo_diritto', 50)->nullable();
$table->decimal('percentuale_possesso', 7, 4)->nullable();
$table->date('data_inizio')->nullable();
$table->date('data_fine')->nullable();
$table->timestamps();
$table->foreign('soggetto_id')->references('id')->on('soggetti')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id')->on('unita_immobiliari')->onDelete('cascade');
$table->unique(['soggetto_id', 'unita_immobiliare_id', 'tipo_diritto'], 'unique_proprieta_per_unita_soggetto');
});
// --- Tabelle Millesimali ---
Schema::create('tabelle_millesimali', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->string('nome_tabella_millesimale');
$table->text('descrizione')->nullable();
$table->timestamps();
$table->foreign('stabile_id')->references('id')->on('stabili')->onDelete('cascade');
$table->unique(['stabile_id', 'nome_tabella_millesimale'], 'unique_tabella_per_stabile');
});
// --- Dettagli Tabelle Millesimali ---
Schema::create('dettagli_tabelle_millesimali', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('tabella_millesimale_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->decimal('millesimi', 10, 4);
$table->timestamps();
$table->foreign('tabella_millesimale_id')->references('id')->on('tabelle_millesimali')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id')->on('unita_immobiliari')->onDelete('cascade');
$table->unique(['tabella_millesimale_id', 'unita_immobiliare_id'], 'unique_tabella_unita');
});
}
public function down(): void
{
Schema::dropIfExists('dettagli_tabelle_millesimali');
Schema::dropIfExists('tabelle_millesimali');
Schema::dropIfExists('proprieta');
Schema::dropIfExists('unita_immobiliari');
Schema::dropIfExists('stabili');
Schema::dropIfExists('soggetti');
Schema::dropIfExists('fornitori');
Schema::dropIfExists('amministratori');
Schema::dropIfExists('piano_conti_condominio');
}
};

View File

@ -7,33 +7,29 @@ use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
* Crea la tabella allegati per la gestione degli allegati generici (morphable).
*/
public function up(): void
{
Schema::create('allegati', function (Blueprint $table) {
$table->bigIncrements('id_allegato');
$table->unsignedBigInteger('id_stabile')->nullable(); // Per scope e pulizia
$table->bigIncrements('id');
$table->unsignedBigInteger('stabile_id')->nullable();
$table->string('nome_file_originale');
$table->string('nome_file_storage')->unique();
$table->text('percorso_file_storage');
$table->string('tipo_mime', 100);
$table->bigInteger('dimensione_byte')->unsigned();
$table->text('descrizione')->nullable();
$table->unsignedBigInteger('allegabile_id'); // ID del record a cui è allegato
$table->string('allegabile_type', 100); // Nome della tabella/entità
$table->unsignedBigInteger('id_utente_caricamento')->nullable(); // Chi ha caricato
$table->unsignedBigInteger('allegabile_id');
$table->string('allegabile_type', 100);
$table->unsignedBigInteger('id_utente_caricamento')->nullable();
$table->string('tags')->nullable();
$table->index(['allegabile_id', 'allegabile_type']);
$table->foreign('id_stabile')->references('id_stabile')->on('stabili')->onDelete('set null');
// Potresti aggiungere una foreign key per id_utente_caricamento se hai una tabella utenti
$table->foreign('stabile_id')->references('id')->on('stabili')->onDelete('set null');
// $table->foreign('id_utente_caricamento')->references('id')->on('users')->onDelete('set null');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('allegati');

View File

@ -1,40 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
if (!Schema::hasTable('richieste_modifiche')) {
Schema::create('richieste_modifiche', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('unita_immobiliare_id');
$table->unsignedBigInteger('soggetto_richiedente_id');
$table->enum('tipo_modifica', ['anagrafica', 'catastale', 'proprieta']);
$table->text('descrizione');
$table->json('dati_attuali');
$table->json('dati_proposti');
$table->enum('stato', ['in_attesa', 'approvata', 'rifiutata'])->default('in_attesa');
$table->text('note_amministratore')->nullable();
$table->datetime('data_approvazione')->nullable();
$table->unsignedBigInteger('approvato_da_user_id')->nullable();
$table->timestamps();
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('soggetto_richiedente_id')->references('id_soggetto')->on('soggetti')->onDelete('cascade');
$table->foreign('approvato_da_user_id')->references('id')->on('users')->onDelete('set null');
$table->index(['stato', 'created_at']);
});
}
// Se servono aggiunte/modifiche, usa Schema::table qui
}
public function down(): void
{
Schema::dropIfExists('richieste_modifiche');
}
};

View File

@ -0,0 +1,100 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Crea tutte le tabelle e relazioni per la gestione dei ticket (categorie, ticket, aggiornamenti, messaggi, allegati).
*/
public function up(): void
{
// --- Categorie Ticket ---
Schema::create('categorie_ticket', function (Blueprint $table) {
$table->id();
$table->string('nome')->unique();
$table->text('descrizione')->nullable();
$table->timestamps();
});
// --- Tickets ---
Schema::create('tickets', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->unsignedBigInteger('unita_immobiliare_id')->nullable();
$table->unsignedBigInteger('soggetto_richiedente_id')->nullable();
$table->unsignedBigInteger('aperto_da_user_id');
$table->unsignedBigInteger('categoria_ticket_id')->nullable();
$table->string('titolo');
$table->text('descrizione');
$table->string('luogo_intervento')->nullable()->comment('Es. Scala A, Piano 3, Interno 5');
$table->enum('stato', [
'Aperto', 'Preso in Carico', 'In Lavorazione', 'In Attesa Approvazione',
'In Attesa Ricambi', 'Risolto', 'Chiuso', 'Annullato'
])->default('Aperto');
$table->enum('priorita', ['Bassa', 'Media', 'Alta', 'Urgente'])->default('Media');
$table->unsignedBigInteger('assegnato_a_user_id')->nullable();
$table->unsignedBigInteger('assegnato_a_fornitore_id')->nullable();
$table->timestamp('data_apertura')->useCurrent();
$table->date('data_scadenza_prevista')->nullable();
$table->timestamp('data_risoluzione_effettiva')->nullable();
$table->timestamp('data_chiusura_effettiva')->nullable();
$table->timestamps();
$table->softDeletes();
$table->foreign('stabile_id')->references('id')->on('stabili')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id')->on('unita_immobiliari')->onDelete('set null');
$table->foreign('soggetto_richiedente_id')->references('id')->on('soggetti')->onDelete('set null');
$table->foreign('aperto_da_user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('categoria_ticket_id')->references('id')->on('categorie_ticket')->onDelete('set null');
$table->foreign('assegnato_a_user_id')->references('id')->on('users')->onDelete('set null');
$table->foreign('assegnato_a_fornitore_id')->references('id')->on('fornitori')->onDelete('set null');
});
// --- Ticket Updates ---
Schema::create('ticket_updates', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('ticket_id');
$table->unsignedBigInteger('user_id')->nullable();
$table->text('update_text')->comment("Testo dell'aggiornamento o nota interna");
$table->timestamps();
$table->foreign('ticket_id')->references('id')->on('tickets')->onDelete('cascade');
$table->foreign('user_id')->references('id')->on('users')->onDelete('set null');
});
// --- Ticket Messages ---
Schema::create('ticket_messages', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('ticket_id');
$table->unsignedBigInteger('user_id')->nullable();
$table->text('messaggio');
$table->timestamps();
$table->foreign('ticket_id')->references('id')->on('tickets')->onDelete('cascade');
$table->foreign('user_id')->references('id')->on('users')->onDelete('set null');
});
// --- Ticket Attachments ---
Schema::create('ticket_attachments', function (Blueprint $table) {
$table->id();
$table->foreignId('ticket_id')->constrained('tickets')->onDelete('cascade');
$table->foreignId('ticket_update_id')->nullable()->constrained('ticket_updates')->onDelete('cascade');
$table->foreignId('user_id')->comment('Utente che ha caricato l allegato')->constrained('users')->onDelete('cascade');
$table->string('file_path');
$table->string('original_file_name');
$table->string('mime_type')->nullable();
$table->unsignedBigInteger('size')->nullable()->comment('Dimensione in bytes');
$table->string('description')->nullable();
$table->timestamps();
});
}
public function down(): void
{
Schema::dropIfExists('ticket_attachments');
Schema::dropIfExists('ticket_messages');
Schema::dropIfExists('ticket_updates');
Schema::dropIfExists('tickets');
Schema::dropIfExists('categorie_ticket');
}
};

View File

@ -1,204 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
if (!Schema::hasTable('preventivi')) {
Schema::create('preventivi', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->year('anno_gestione');
$table->enum('tipo_gestione', ['ordinaria', 'riscaldamento', 'straordinaria', 'acqua', 'altro']);
$table->string('descrizione');
$table->enum('stato', ['bozza', 'provvisorio', 'definitivo', 'approvato', 'archiviato'])->default('bozza');
$table->decimal('importo_totale', 12, 2)->default(0);
$table->date('data_creazione');
$table->date('data_approvazione')->nullable();
$table->unsignedBigInteger('approvato_da_user_id')->nullable();
$table->text('note')->nullable();
$table->integer('versione')->default(1);
$table->timestamps();
$table->softDeletes();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->foreign('approvato_da_user_id')->references('id')->on('users')->onDelete('set null');
$table->index(['stabile_id', 'anno_gestione', 'tipo_gestione']);
});
}
if (!Schema::hasTable('voci_preventivo')) {
Schema::create('voci_preventivo', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('preventivo_id');
$table->string('codice', 20);
$table->string('descrizione');
$table->decimal('importo_preventivato', 10, 2);
$table->decimal('importo_effettivo', 10, 2)->default(0);
$table->unsignedBigInteger('tabella_millesimale_id')->nullable();
$table->unsignedBigInteger('voce_spesa_id')->nullable();
$table->boolean('ricorrente')->default(false);
$table->enum('frequenza', ['mensile', 'trimestrale', 'semestrale', 'annuale'])->nullable();
$table->date('data_scadenza_prevista')->nullable();
$table->integer('ordinamento')->default(0);
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('preventivo_id')->references('id_preventivo')->on('preventivi')->onDelete('set null');
$table->foreign('tabella_millesimale_id')->references('id')->on('tabelle_millesimali')->onDelete('set null');
$table->foreign('voce_spesa_id')->references('id')->on('voci_spesa')->onDelete('set null');
});
}
if (!Schema::hasTable('ripartizioni_preventivo')) {
Schema::create('ripartizioni_preventivo', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('voce_preventivo_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->decimal('quota_calcolata', 10, 2);
$table->decimal('quota_modificata', 10, 2)->nullable();
$table->decimal('quota_finale', 10, 2);
$table->integer('versione')->default(1);
$table->unsignedBigInteger('modificato_da_user_id')->nullable();
$table->string('motivo_modifica')->nullable();
$table->timestamp('data_modifica')->nullable();
$table->timestamps();
$table->foreign('voce_preventivo_id')->references('id_voce_preventivo')->on('voci_preventivo')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('modificato_da_user_id')->references('id')->on('users')->onDelete('set null');
$table->unique(['voce_preventivo_id', 'unita_immobiliare_id'], 'unique_voce_unita');
});
}
if (!Schema::hasTable('rate')) {
Schema::create('rate', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('preventivo_id');
$table->string('numero_rata', 50)->unique();
$table->string('descrizione');
$table->date('data_scadenza');
$table->enum('stato', ['bozza', 'emessa', 'modificata', 'annullata'])->default('bozza');
$table->decimal('importo_totale', 12, 2);
$table->integer('versione')->default(1);
$table->unsignedBigInteger('creato_da_user_id');
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('preventivo_id')->references('id_preventivo')->on('preventivi')->onDelete('cascade');
$table->foreign('creato_da_user_id')->references('id')->on('users')->onDelete('cascade');
});
}
if (!Schema::hasTable('rate_unita')) {
Schema::create('rate_unita', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('rata_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->unsignedBigInteger('soggetto_id');
$table->decimal('importo_originale', 10, 2);
$table->decimal('importo_modificato', 10, 2)->nullable();
$table->decimal('importo_finale', 10, 2);
$table->decimal('importo_pagato', 10, 2)->default(0);
$table->enum('stato_pagamento', ['da_pagare', 'parziale', 'pagata', 'insoluta'])->default('da_pagare');
$table->date('data_pagamento')->nullable();
$table->integer('versione')->default(1);
$table->unsignedBigInteger('modificato_da_user_id')->nullable();
$table->string('motivo_modifica')->nullable();
$table->timestamp('data_modifica')->nullable();
$table->timestamps();
$table->foreign('rata_id')->references('id')->on('rate')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('cascade');
$table->foreign('modificato_da_user_id')->references('id')->on('users')->onDelete('set null');
$table->unique(['rata_id', 'unita_immobiliare_id'], 'unique_rata_unita');
});
}
if (!Schema::hasTable('incassi')) {
Schema::create('incassi', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('rata_unita_id');
$table->date('data_incasso');
$table->decimal('importo', 10, 2);
$table->enum('metodo_pagamento', ['bonifico', 'contanti', 'assegno', 'pos', 'altro']);
$table->string('riferimento_bancario')->nullable();
$table->string('numero_documento')->nullable();
$table->unsignedBigInteger('movimento_bancario_id')->nullable();
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('rata_unita_id')->references('id')->on('rate_unita')->onDelete('cascade');
$table->index(['data_incasso', 'metodo_pagamento']);
});
}
if (!Schema::hasTable('log_modifiche_preventivo')) {
Schema::create('log_modifiche_preventivo', function (Blueprint $table) {
$table->id();
$table->string('entita'); // 'preventivo', 'voce', 'ripartizione', 'rata'
$table->unsignedBigInteger('entita_id');
$table->integer('versione_precedente');
$table->integer('versione_nuova');
$table->unsignedBigInteger('utente_id');
$table->string('tipo_operazione'); // 'create', 'update', 'delete'
$table->text('motivo');
$table->json('dati_precedenti')->nullable();
$table->json('dati_nuovi');
$table->json('diff')->nullable(); // Differenze stile GIT
$table->timestamps();
$table->foreign('utente_id')->references('id')->on('users')->onDelete('cascade');
$table->index(['entita', 'entita_id', 'versione_nuova']);
});
}
if (!Schema::hasTable('pianificazione_spese')) {
Schema::create('pianificazione_spese', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->unsignedBigInteger('preventivo_id')->nullable();
$table->string('descrizione');
$table->decimal('importo_previsto', 10, 2);
$table->date('data_scadenza_prevista');
$table->enum('tipo', ['ricorrente', 'straordinaria', 'manutenzione']);
$table->enum('stato', ['pianificata', 'confermata', 'pagata', 'annullata'])->default('pianificata');
$table->boolean('notifica_inviata')->default(false);
$table->integer('giorni_preavviso')->default(30);
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->foreign('preventivo_id')->references('id_preventivo')->on('preventivi')->onDelete('set null');
$table->index(['data_scadenza_prevista', 'stato']);
});
}
if (!Schema::hasTable('configurazioni_banche')) {
Schema::create('configurazioni_banche', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->string('nome_banca');
$table->string('iban', 34);
$table->string('api_endpoint')->nullable();
$table->text('credenziali_api')->nullable(); // Encrypted
$table->enum('tipo_importazione', ['api', 'csv', 'cbi', 'manuale']);
$table->json('mapping_campi')->nullable();
$table->boolean('attiva')->default(true);
$table->timestamp('ultima_sincronizzazione')->nullable();
$table->timestamps();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
});
}
}
public function down(): void
{
Schema::dropIfExists('configurazioni_banche');
Schema::dropIfExists('pianificazione_spese');
Schema::dropIfExists('log_modifiche_preventivo');
Schema::dropIfExists('incassi');
Schema::dropIfExists('rate_unita');
Schema::dropIfExists('rate');
Schema::dropIfExists('ripartizioni_preventivo');
Schema::dropIfExists('voci_preventivo');
Schema::dropIfExists('preventivi');
}
};

View File

@ -1,285 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
if (!Schema::hasTable('bilanci')) {
Schema::create('bilanci', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->unsignedBigInteger('gestione_id');
$table->year('anno_esercizio');
$table->date('data_inizio_esercizio');
$table->date('data_fine_esercizio');
$table->enum('tipo_gestione', ['ordinaria', 'riscaldamento', 'straordinaria', 'acqua', 'altro']);
$table->string('descrizione');
$table->enum('stato', ['bozza', 'provvisorio', 'definitivo', 'approvato', 'chiuso'])->default('bozza');
$table->decimal('totale_entrate', 12, 2)->default(0);
$table->decimal('totale_uscite', 12, 2)->default(0);
$table->decimal('risultato_gestione', 12, 2)->default(0); // Avanzo/Disavanzo
$table->date('data_approvazione')->nullable();
$table->unsignedBigInteger('approvato_da_user_id')->nullable();
$table->date('data_chiusura')->nullable();
$table->unsignedBigInteger('chiuso_da_user_id')->nullable();
$table->text('note')->nullable();
$table->integer('versione')->default(1);
$table->timestamps();
$table->softDeletes();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->foreign('gestione_id')->references('id_gestione')->on('gestioni')->onDelete('cascade');
$table->foreign('approvato_da_user_id')->references('id')->on('users')->onDelete('set null');
$table->foreign('chiuso_da_user_id')->references('id')->on('users')->onDelete('set null');
$table->index(['stabile_id', 'anno_esercizio', 'tipo_gestione']);
});
}
if (!Schema::hasTable('piano_conti')) {
Schema::create('piano_conti', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->string('codice', 20);
$table->string('descrizione');
$table->enum('tipo_conto', ['attivo', 'passivo', 'costo', 'ricavo']);
$table->enum('categoria', ['patrimoniale', 'economico']);
$table->unsignedBigInteger('conto_padre_id')->nullable();
$table->integer('livello')->default(1);
$table->boolean('attivo')->default(true);
$table->integer('ordinamento')->default(0);
$table->timestamps();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->foreign('conto_padre_id')->references('id')->on('piano_conti')->onDelete('set null');
$table->unique(['stabile_id', 'codice']);
});
}
if (!Schema::hasTable('scritture_bilancio')) {
Schema::create('scritture_bilancio', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('bilancio_id');
$table->string('numero_scrittura', 50);
$table->date('data_scrittura');
$table->string('descrizione');
$table->enum('tipo_scrittura', ['apertura', 'gestione', 'chiusura', 'rettifica']);
$table->decimal('importo_totale', 12, 2);
$table->string('riferimento_documento')->nullable();
$table->unsignedBigInteger('movimento_contabile_id')->nullable();
$table->unsignedBigInteger('creato_da_user_id');
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('bilancio_id')->references('id')->on('bilanci')->onDelete('cascade');
$table->foreign('movimento_contabile_id')->references('id')->on('movimenti_contabili')->onDelete('set null');
$table->foreign('creato_da_user_id')->references('id')->on('users')->onDelete('cascade');
$table->index(['bilancio_id', 'data_scrittura']);
});
}
if (!Schema::hasTable('dettagli_scritture_bilancio')) {
Schema::create('dettagli_scritture_bilancio', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('scrittura_bilancio_id');
$table->unsignedBigInteger('conto_id');
$table->decimal('importo_dare', 12, 2)->default(0);
$table->decimal('importo_avere', 12, 2)->default(0);
$table->string('descrizione_dettaglio')->nullable();
$table->timestamps();
$table->foreign('scrittura_bilancio_id')->references('id')->on('scritture_bilancio')->onDelete('cascade');
$table->foreign('conto_id')->references('id')->on('piano_conti')->onDelete('cascade');
});
}
if (!Schema::hasTable('ripartizioni_bilancio')) {
Schema::create('ripartizioni_bilancio', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('scrittura_bilancio_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->unsignedBigInteger('tabella_millesimale_id');
$table->decimal('quota_calcolata', 10, 2);
$table->decimal('quota_modificata', 10, 2)->nullable();
$table->decimal('quota_finale', 10, 2);
$table->integer('versione')->default(1);
$table->unsignedBigInteger('modificato_da_user_id')->nullable();
$table->string('motivo_modifica')->nullable();
$table->timestamp('data_modifica')->nullable();
$table->timestamps();
$table->foreign('scrittura_bilancio_id')->references('id')->on('scritture_bilancio')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('tabella_millesimale_id')->references('id_tabella_millesimale')->on('tabelle_millesimali')->onDelete('cascade');
$table->foreign('modificato_da_user_id')->references('id')->on('users')->onDelete('set null');
});
}
if (!Schema::hasTable('conguagli')) {
Schema::create('conguagli', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('bilancio_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->unsignedBigInteger('soggetto_id');
$table->decimal('totale_rate_pagate', 10, 2)->default(0);
$table->decimal('totale_spese_effettive', 10, 2)->default(0);
$table->decimal('conguaglio_dovuto', 10, 2)->default(0); // Positivo = a credito, Negativo = a debito
$table->enum('tipo_conguaglio', ['a_credito', 'a_debito', 'pareggio']);
$table->enum('stato', ['calcolato', 'confermato', 'pagato', 'rimborsato'])->default('calcolato');
$table->date('data_calcolo');
$table->date('data_pagamento')->nullable();
$table->decimal('importo_pagato', 10, 2)->default(0);
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('bilancio_id')->references('id')->on('bilanci')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('cascade');
$table->index(['bilancio_id', 'tipo_conguaglio']);
});
}
if (!Schema::hasTable('rate_conguaglio')) {
Schema::create('rate_conguaglio', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('conguaglio_id');
$table->string('numero_rata', 50)->unique();
$table->string('descrizione');
$table->date('data_scadenza');
$table->decimal('importo_rata', 10, 2);
$table->enum('stato_pagamento', ['da_pagare', 'parziale', 'pagata', 'insoluta'])->default('da_pagare');
$table->decimal('importo_pagato', 10, 2)->default(0);
$table->date('data_pagamento')->nullable();
$table->boolean('rateizzato')->default(false);
$table->integer('numero_rate_totali')->default(1);
$table->integer('numero_rata_corrente')->default(1);
$table->integer('versione')->default(1);
$table->timestamps();
$table->foreign('conguaglio_id')->references('id')->on('conguagli')->onDelete('cascade');
});
}
if (!Schema::hasTable('quadrature')) {
Schema::create('quadrature', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('bilancio_id');
$table->date('data_quadratura');
$table->decimal('saldo_banca_effettivo', 12, 2);
$table->decimal('saldo_contabile_calcolato', 12, 2);
$table->decimal('differenza', 12, 2);
$table->decimal('totale_crediti_condomini', 12, 2);
$table->decimal('totale_debiti_condomini', 12, 2);
$table->decimal('totale_rate_emesse', 12, 2);
$table->decimal('totale_rate_incassate', 12, 2);
$table->boolean('quadratura_ok')->default(false);
$table->text('note_differenze')->nullable();
$table->unsignedBigInteger('verificato_da_user_id');
$table->timestamps();
$table->foreign('bilancio_id')->references('id')->on('bilanci')->onDelete('cascade');
$table->foreign('verificato_da_user_id')->references('id')->on('users')->onDelete('cascade');
});
}
if (!Schema::hasTable('rimborsi_assicurativi')) {
Schema::create('rimborsi_assicurativi', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('bilancio_id');
$table->string('numero_sinistro');
$table->string('compagnia_assicurativa');
$table->date('data_sinistro');
$table->date('data_denuncia');
$table->decimal('importo_richiesto', 10, 2);
$table->decimal('importo_liquidato', 10, 2)->default(0);
$table->enum('stato', ['denunciato', 'in_valutazione', 'liquidato', 'rifiutato', 'chiuso']);
$table->enum('tipo_accredito', ['rate_condomini', 'pagamento_diretto', 'fondo_comune']);
$table->date('data_liquidazione')->nullable();
$table->text('descrizione_sinistro');
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('bilancio_id')->references('id')->on('bilanci')->onDelete('cascade');
});
}
if (!Schema::hasTable('reminder_bilancio')) {
Schema::create('reminder_bilancio', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('bilancio_id');
$table->enum('tipo_reminder', ['scadenza_spesa', 'rinnovo_contratto', 'verifica_quadratura', 'chiusura_esercizio']);
$table->string('descrizione');
$table->date('data_scadenza');
$table->boolean('ricorrente')->default(false);
$table->enum('frequenza', ['mensile', 'trimestrale', 'semestrale', 'annuale'])->nullable();
$table->integer('giorni_preavviso')->default(30);
$table->enum('stato', ['attivo', 'eseguito', 'annullato'])->default('attivo');
$table->boolean('notifica_inviata')->default(false);
$table->timestamp('data_notifica')->nullable();
$table->unsignedBigInteger('ticket_generato_id')->nullable();
$table->timestamps();
$table->foreign('bilancio_id')->references('id')->on('bilanci')->onDelete('cascade');
$table->foreign('ticket_generato_id')->references('id')->on('tickets')->onDelete('set null');
});
}
if (!Schema::hasTable('log_modifiche_bilancio')) {
Schema::create('log_modifiche_bilancio', function (Blueprint $table) {
$table->id();
$table->string('entita'); // 'bilancio', 'scrittura', 'ripartizione', 'conguaglio'
$table->unsignedBigInteger('entita_id');
$table->integer('versione_precedente');
$table->integer('versione_nuova');
$table->unsignedBigInteger('utente_id');
$table->string('tipo_operazione'); // 'create', 'update', 'delete', 'approve', 'close'
$table->text('motivo');
$table->json('dati_precedenti')->nullable();
$table->json('dati_nuovi');
$table->json('diff')->nullable(); // Differenze stile GIT
$table->timestamps();
$table->foreign('utente_id')->references('id')->on('users')->onDelete('cascade');
$table->index(['entita', 'entita_id', 'versione_nuova']);
});
}
if (!Schema::hasTable('automazioni_fine_anno')) {
Schema::create('automazioni_fine_anno', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('bilancio_id');
$table->enum('tipo_automazione', ['chiusura_conti', 'riporto_saldi', 'calcolo_conguagli', 'generazione_rate']);
$table->string('descrizione');
$table->enum('stato', ['programmata', 'in_esecuzione', 'completata', 'errore']);
$table->date('data_programmata');
$table->timestamp('data_esecuzione')->nullable();
$table->json('parametri')->nullable();
$table->json('risultato')->nullable();
$table->text('log_esecuzione')->nullable();
$table->text('errori')->nullable();
$table->timestamps();
$table->foreign('bilancio_id')->references('id')->on('bilanci')->onDelete('cascade');
});
}
}
public function down(): void
{
Schema::dropIfExists('automazioni_fine_anno');
Schema::dropIfExists('log_modifiche_bilancio');
Schema::dropIfExists('reminder_bilancio');
Schema::dropIfExists('rimborsi_assicurativi');
Schema::dropIfExists('quadrature');
Schema::dropIfExists('rate_conguaglio');
Schema::dropIfExists('conguagli');
Schema::dropIfExists('ripartizioni_bilancio');
Schema::dropIfExists('dettagli_scritture_bilancio');
Schema::dropIfExists('scritture_bilancio');
Schema::dropIfExists('piano_conti');
Schema::dropIfExists('bilanci');
}
};

View File

@ -1,252 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
if (!Schema::hasTable('assemblee')) {
Schema::create('assemblee', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('stabile_id');
$table->enum('tipo', ['ordinaria', 'straordinaria']);
$table->datetime('data_prima_convocazione');
$table->datetime('data_seconda_convocazione');
$table->string('luogo');
$table->text('note')->nullable();
$table->enum('stato', ['bozza', 'convocata', 'svolta', 'chiusa', 'archiviata'])->default('bozza');
$table->date('data_convocazione')->nullable();
$table->date('data_svolgimento')->nullable();
$table->unsignedBigInteger('creato_da_user_id');
$table->timestamps();
$table->foreign('stabile_id')->references('id_stabile')->on('stabili')->onDelete('cascade');
$table->foreign('creato_da_user_id')->references('id')->on('users')->onDelete('cascade');
$table->index(['stabile_id', 'data_prima_convocazione']);
});
}
if (!Schema::hasTable('ordine_giorno')) {
Schema::create('ordine_giorno', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('assemblea_id');
$table->integer('numero_punto');
$table->string('titolo');
$table->text('descrizione');
$table->enum('tipo_voce', ['discussione', 'delibera', 'spesa', 'preventivo', 'altro']);
$table->unsignedBigInteger('collegamento_preventivo_id')->nullable();
$table->decimal('importo_spesa', 12, 2)->nullable();
$table->unsignedBigInteger('tabella_millesimale_id')->nullable();
$table->enum('esito_votazione', ['non_votato', 'approvato', 'respinto', 'rinviato'])->default('non_votato');
$table->integer('voti_favorevoli')->default(0);
$table->integer('voti_contrari')->default(0);
$table->integer('astenuti')->default(0);
$table->decimal('millesimi_favorevoli', 10, 4)->default(0);
$table->decimal('millesimi_contrari', 10, 4)->default(0);
$table->decimal('millesimi_astenuti', 10, 4)->default(0);
$table->text('note_delibera')->nullable();
$table->timestamps();
$table->foreign('assemblea_id')->references('id')->on('assemblee')->onDelete('cascade');
$table->foreign('collegamento_preventivo_id')->references('id_preventivo')->on('preventivi')->onDelete('set null');
$table->foreign('tabella_millesimale_id')->references('id_tabella_millesimale')->on('tabelle_millesimali')->onDelete('set null');
});
}
if (!Schema::hasTable('convocazioni')) {
Schema::create('convocazioni', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('assemblea_id');
$table->unsignedBigInteger('soggetto_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->enum('canale_invio', ['email', 'pec', 'whatsapp', 'telegram', 'raccomandata', 'mano', 'portiere', 'postale']);
$table->datetime('data_invio');
$table->enum('esito_invio', ['inviato', 'consegnato', 'letto', 'errore', 'rifiutato']);
$table->datetime('data_lettura')->nullable();
$table->string('riferimento_invio')->nullable(); // ID email, numero raccomandata, etc.
$table->text('note_invio')->nullable();
$table->boolean('delega_presente')->default(false);
$table->unsignedBigInteger('delegato_soggetto_id')->nullable();
$table->string('documento_delega')->nullable();
$table->boolean('presenza_confermata')->default(false);
$table->datetime('data_conferma_presenza')->nullable();
$table->timestamps();
$table->foreign('assemblea_id')->references('id')->on('assemblee')->onDelete('cascade');
$table->foreign('soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('delegato_soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('set null');
$table->index(['assemblea_id', 'soggetto_id']);
});
}
if (!Schema::hasTable('presenze_assemblea')) {
Schema::create('presenze_assemblea', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('assemblea_id');
$table->unsignedBigInteger('soggetto_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->enum('tipo_presenza', ['presente', 'delegato', 'assente']);
$table->datetime('ora_arrivo')->nullable();
$table->datetime('ora_uscita')->nullable();
$table->string('firma_digitale')->nullable();
$table->string('qr_code')->nullable();
$table->boolean('firma_fisica')->default(false);
$table->decimal('millesimi_rappresentati', 10, 4);
$table->unsignedBigInteger('delegante_soggetto_id')->nullable(); // Se è un delegato
$table->text('note')->nullable();
$table->timestamps();
$table->foreign('assemblea_id')->references('id')->on('assemblee')->onDelete('cascade');
$table->foreign('soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->foreign('delegante_soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('set null');
});
}
if (!Schema::hasTable('votazioni')) {
Schema::create('votazioni', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('ordine_giorno_id');
$table->unsignedBigInteger('soggetto_id');
$table->unsignedBigInteger('unita_immobiliare_id');
$table->enum('voto', ['favorevole', 'contrario', 'astenuto', 'non_votante']);
$table->decimal('millesimi_voto', 10, 4);
$table->datetime('data_voto');
$table->text('motivazione')->nullable();
$table->timestamps();
$table->foreign('ordine_giorno_id')->references('id')->on('ordine_giorno')->onDelete('cascade');
$table->foreign('soggetto_id')->references('id_soggetto')->on('soggetti')->onDelete('cascade');
$table->foreign('unita_immobiliare_id')->references('id_unita')->on('unita_immobiliari')->onDelete('cascade');
$table->unique(['ordine_giorno_id', 'soggetto_id', 'unita_immobiliare_id'], 'unique_voto');
});
}
if (!Schema::hasTable('delibere')) {
Schema::create('delibere', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('ordine_giorno_id');
$table->string('numero_delibera');
$table->enum('esito', ['approvata', 'respinta', 'rinviata']);
$table->text('testo_delibera');
$table->integer('totale_voti_favorevoli');
$table->integer('totale_voti_contrari');
$table->integer('totale_astenuti');
$table->decimal('totale_millesimi_favorevoli', 10, 4);
$table->decimal('totale_millesimi_contrari', 10, 4);
$table->decimal('totale_millesimi_astenuti', 10, 4);
$table->decimal('percentuale_approvazione', 5, 2);
$table->boolean('maggioranza_raggiunta');
$table->date('data_delibera');
$table->json('allegati')->nullable();
$table->timestamps();
$table->foreign('ordine_giorno_id')->references('id')->on('ordine_giorno')->onDelete('cascade');
$table->unique('numero_delibera');
});
}
if (!Schema::hasTable('verbali')) {
Schema::create('verbali', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('assemblea_id');
$table->string('numero_verbale');
$table->text('testo_verbale');
$table->json('allegati')->nullable();
$table->date('data_redazione');
$table->unsignedBigInteger('redatto_da_user_id');
$table->string('firma_digitale')->nullable();
$table->boolean('inviato_condomini')->default(false);
$table->datetime('data_invio_condomini')->nullable();
$table->enum('stato', ['bozza', 'definitivo', 'inviato', 'archiviato'])->default('bozza');
$table->timestamps();
$table->foreign('assemblea_id')->references('id')->on('assemblee')->onDelete('cascade');
$table->foreign('redatto_da_user_id')->references('id')->on('users')->onDelete('cascade');
});
}
if (!Schema::hasTable('registro_protocollo')) {
Schema::create('registro_protocollo', function (Blueprint $table) {
$table->id();
$table->string('numero_protocollo')->unique();
$table->enum('tipo_comunicazione', ['convocazione', 'verbale', 'delibera', 'comunicazione', 'delega', 'altro']);
$table->unsignedBigInteger('assemblea_id')->nullable();
$table->unsignedBigInteger('soggetto_destinatario_id')->nullable();
$table->unsignedBigInteger('soggetto_mittente_id')->nullable();
$table->string('oggetto');
$table->text('contenuto')->nullable();
$table->enum('canale', ['email', 'pec', 'whatsapp', 'telegram', 'raccomandata', 'mano', 'portiere', 'postale']);
$table->datetime('data_invio');
$table->enum('esito', ['inviato', 'consegnato', 'letto', 'errore', 'rifiutato']);
$table->datetime('data_consegna')->nullable();
$table->datetime('data_lettura')->nullable();
$table->string('riferimento_esterno')->nullable();
$table->json('allegati')->nullable();
$table->text('note')->nullable();
$table->unsignedBigInteger('creato_da_user_id');
$table->timestamps();
$table->foreign('assemblea_id')->references('id')->on('assemblee')->onDelete('set null');
$table->foreign('soggetto_destinatario_id')->references('id_soggetto')->on('soggetti')->onDelete('set null');
$table->foreign('soggetto_mittente_id')->references('id_soggetto')->on('soggetti')->onDelete('set null');
$table->foreign('creato_da_user_id')->references('id')->on('users')->onDelete('cascade');
$table->index(['data_invio', 'tipo_comunicazione']);
});
}
if (!Schema::hasTable('documenti_assemblea')) {
Schema::create('documenti_assemblea', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('assemblea_id');
$table->string('nome_documento');
$table->string('tipo_documento'); // convocazione, verbale, allegato, delega, etc.
$table->string('path_file');
$table->string('mime_type');
$table->unsignedBigInteger('dimensione_file');
$table->string('hash_file');
$table->text('descrizione')->nullable();
$table->unsignedBigInteger('caricato_da_user_id');
$table->timestamps();
$table->foreign('assemblea_id')->references('id')->on('assemblee')->onDelete('cascade');
$table->foreign('caricato_da_user_id')->references('id')->on('users')->onDelete('cascade');
});
}
if (!Schema::hasTable('automazioni_spese_approvate')) {
Schema::create('automazioni_spese_approvate', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('delibera_id');
$table->unsignedBigInteger('preventivo_generato_id')->nullable();
$table->unsignedBigInteger('ripartizione_generata_id')->nullable();
$table->json('rate_generate')->nullable();
$table->enum('stato_automazione', ['in_attesa', 'in_corso', 'completata', 'errore']);
$table->text('log_automazione')->nullable();
$table->datetime('data_esecuzione')->nullable();
$table->timestamps();
$table->foreign('delibera_id')->references('id')->on('delibere')->onDelete('cascade');
$table->foreign('preventivo_generato_id')->references('id_preventivo')->on('preventivi')->onDelete('set null');
});
}
}
public function down(): void
{
Schema::dropIfExists('automazioni_spese_approvate');
Schema::dropIfExists('documenti_assemblea');
Schema::dropIfExists('registro_protocollo');
Schema::dropIfExists('verbali');
Schema::dropIfExists('delibere');
Schema::dropIfExists('votazioni');
Schema::dropIfExists('presenze_assemblea');
Schema::dropIfExists('convocazioni');
Schema::dropIfExists('ordine_giorno');
Schema::dropIfExists('assemblee');
}
};

View File

@ -113,7 +113,7 @@ class TestSetupSeeder extends Seeder
// 5. Crea Unità Immobiliari di Test
$unita1 = UnitaImmobiliare::firstOrCreate(
['id_stabile' => $stabile->id_stabile, 'interno' => '1', 'scala' => 'A', 'fabbricato' => 'Principale'],
['stabile_id' => $stabile->id, 'interno' => '1', 'scala' => 'A', 'fabbricato' => 'Principale'],
[
@ -127,7 +127,7 @@ class TestSetupSeeder extends Seeder
]
);
$unita2 = UnitaImmobiliare::firstOrCreate(
['id_stabile' => $stabile->id_stabile, 'interno' => '2', 'scala' => 'A', 'fabbricato' => 'Principale'],
['stabile_id' => $stabile->id, 'interno' => '2', 'scala' => 'A', 'fabbricato' => 'Principale'],
[
'piano' => '1',
'subalterno' => '2',
@ -147,25 +147,53 @@ class TestSetupSeeder extends Seeder
$this->command->info('Soggetti di Test creati.');
// 7. Collega Soggetti alle Unità (Proprieta)
Proprieta::firstOrCreate(['soggetto_id' => $soggettoProprietario1->id_soggetto, 'unita_immobiliare_id' => $unita1->id_unita], ['tipo_diritto' => 'proprietario', 'percentuale_possesso' => 100.00, 'data_inizio' => '2020-01-01']);
Proprieta::firstOrCreate(['soggetto_id' => $soggettoProprietario1->id_soggetto, 'unita_immobiliare_id' => $unita2->id_unita], ['tipo_diritto' => 'nudo_proprietario', 'percentuale_possesso' => 100.00, 'data_inizio' => '2022-03-01']);
Proprieta::firstOrCreate(['soggetto_id' => $soggettoProprietario2->id_soggetto, 'unita_immobiliare_id' => $unita2->id_unita], ['tipo_diritto' => 'usufruttuario', 'percentuale_possesso' => 100.00, 'data_inizio' => '2022-03-01']);
Proprieta::firstOrCreate(['soggetto_id' => $soggettoInquilino->id_soggetto, 'unita_immobiliare_id' => $unita1->id_unita], ['tipo_diritto' => 'inquilino', 'percentuale_possesso' => 100.00, 'data_inizio' => '2023-06-15']);
Proprieta::firstOrCreate([
'soggetto_id' => $soggettoProprietario1->id ?? $soggettoProprietario1->id_soggetto,
'unita_immobiliare_id' => $unita1->id ?? $unita1->id_unita
], [
'tipo_diritto' => 'proprietario',
'percentuale_possesso' => 100.00,
'data_inizio' => '2020-01-01'
]);
Proprieta::firstOrCreate([
'soggetto_id' => $soggettoProprietario1->id ?? $soggettoProprietario1->id_soggetto,
'unita_immobiliare_id' => $unita2->id ?? $unita2->id_unita
], [
'tipo_diritto' => 'nudo_proprietario',
'percentuale_possesso' => 100.00,
'data_inizio' => '2022-03-01'
]);
Proprieta::firstOrCreate([
'soggetto_id' => $soggettoProprietario2->id ?? $soggettoProprietario2->id_soggetto,
'unita_immobiliare_id' => $unita2->id ?? $unita2->id_unita
], [
'tipo_diritto' => 'usufruttuario',
'percentuale_possesso' => 100.00,
'data_inizio' => '2022-03-01'
]);
Proprieta::firstOrCreate([
'soggetto_id' => $soggettoInquilino->id ?? $soggettoInquilino->id_soggetto,
'unita_immobiliare_id' => $unita1->id ?? $unita1->id_unita
], [
'tipo_diritto' => 'inquilino',
'percentuale_possesso' => 100.00,
'data_inizio' => '2023-06-15'
]);
$this->command->info('Relazioni Soggetto-Unità create.');
// 8. Crea una Tabella Millesimale di Test
$tabellaA = TabellaMillesimale::firstOrCreate(
['id_stabile' => $stabile->id_stabile, 'nome_tabella' => 'Tabella A - Proprietà'],
['stabile_id' => $stabile->id, 'nome_tabella_millesimale' => 'Tabella A - Proprietà'],
['descrizione' => 'Ripartizione spese in base ai millesimi di proprietà generale.']
);
// Fix: recupera la chiave primaria corretta se non presente
if (!$tabellaA->id_tabella_millesimale) {
if (!$tabellaA->id) {
// Prova a ricaricare dal DB se firstOrCreate restituisce un oggetto senza la chiave primaria
$tabellaA = TabellaMillesimale::where('id_stabile', $stabile->id_stabile)
->where('nome_tabella', 'Tabella A - Proprietà')
$tabellaA = TabellaMillesimale::where('stabile_id', $stabile->id)
->where('nome_tabella_millesimale', 'Tabella A - Proprietà')
->first();
}
if (!$tabellaA || !$tabellaA->id_tabella_millesimale) {
if (!$tabellaA || !$tabellaA->id) {
$this->command->error('Errore: la tabella millesimale non è stata creata correttamente!');
return;
}
@ -173,29 +201,29 @@ class TestSetupSeeder extends Seeder
// 9. Crea Dettagli Millesimali per le unità
DettaglioTabellaMillesimale::firstOrCreate(
['id_tabella_millesimale' => $tabellaA->id_tabella_millesimale, 'id_unita' => $unita1->id_unita],
['valore_millesimale' => 500.0000]
['tabella_millesimale_id' => $tabellaA->id, 'unita_immobiliare_id' => $unita1->id ?? $unita1->id_unita],
['millesimi' => 500.0000]
);
DettaglioTabellaMillesimale::firstOrCreate(
['id_tabella_millesimale' => $tabellaA->id_tabella_millesimale, 'id_unita' => $unita2->id_unita],
['valore_millesimale' => 500.0000]
['tabella_millesimale_id' => $tabellaA->id, 'unita_immobiliare_id' => $unita2->id ?? $unita2->id_unita],
['millesimi' => 500.0000]
);
$this->command->info('Dettagli Millesimali creati.');
/*// 10. Crea una Gestione di Test
$gestione2024 = Gestione::firstOrCreate(
['id_stabile' => $stabile->id_stabile, 'anno' => 2024, 'tipo' => 'ORDINARIA'],
['stabile_id' => $stabile->id, 'anno' => 2024, 'tipo' => 'ORDINARIA'],
['data_inizio' => '2024-01-01', 'data_fine' => '2024-12-31', 'stato' => 'aperta']
);
$this->command->info('Gestione di Test creata.');*/
// 11. Crea un Piano dei Conti per lo Stabile (esempio base)
$contoPulizie = PianoContiCondominio::firstOrCreate(
['id_stabile' => $stabile->id_stabile, 'codice' => 'SP.PUL'],
['stabile_id' => $stabile->id, 'codice' => 'SP.PUL'],
['descrizione' => 'Spese di Pulizia Scale', 'tipo_conto' => 'ECONOMICO_COSTO']
);
$contoAssicurazione = PianoContiCondominio::firstOrCreate(
['id_stabile' => $stabile->id_stabile, 'codice' => 'SP.ASS'],
['stabile_id' => $stabile->id, 'codice' => 'SP.ASS'],
['descrizione' => 'Assicurazione Fabbricato', 'tipo_conto' => 'ECONOMICO_COSTO']
);
$this->command->info('Piano dei Conti di Test creato.');

View File

@ -140,10 +140,6 @@ Route::middleware(['auth', 'verified'])->group(function () {
// Documenti
Route::get('/documenti', [CondominoDocumentoController::class, 'index'])->name('documenti.index');
<<<<<<< HEAD
Route::get('/documenti/{documento}/download', [CondominoDocumentoController::class, 'download'])->name('documenti.download');
=======
>>>>>>> e913d05 (Primo commit dal server Linux: progetto funzionante e aggiornato)
// Unità Immobiliari
Route::get('/unita', [CondominoUnitaController::class, 'index'])->name('unita.index');
@ -181,9 +177,6 @@ Route::middleware(['auth', 'verified'])->group(function () {
Route::get('impersonate/leave', [\Lab404\Impersonate\Controllers\ImpersonateController::class, 'leave'])->name('impersonate.leave');
// --- AUTHENTICATION ROUTES ---
<<<<<<< HEAD
require __DIR__.'/auth.php';
=======
require __DIR__.'/auth.php';
Route::middleware(['auth'])->group(function () {
@ -193,4 +186,3 @@ Route::middleware(['auth'])->group(function () {
Route::get('/contabilita/registrazione-test', \App\Livewire\Contabilita\RegistrazioneTest::class)
->middleware(['auth'])
->name('contabilita.registrazione-test');
>>>>>>> e913d05 (Primo commit dal server Linux: progetto funzionante e aggiornato)