++ Primo Caricamento
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Migration: crea la tabella customers
|
||||
//
|
||||
// Cos'è una migration?
|
||||
// È un file PHP che descrive modifiche al database in forma di codice.
|
||||
// Invece di scrivere SQL manualmente, usi il fluent Schema Builder di Laravel.
|
||||
//
|
||||
// Vantaggi:
|
||||
// - Versioning: le migration sono versionabili su Git come il codice
|
||||
// - Reversibilità: ogni migration ha un metodo down() per annullare
|
||||
// - Collaborazione: tutti i dev usano lo stesso DB schema
|
||||
//
|
||||
// Esecuzione:
|
||||
// php artisan migrate → esegue up() delle migration non ancora eseguite
|
||||
// php artisan migrate:rollback → esegue down() dell'ultima batch
|
||||
// php artisan migrate:fresh → CANCELLA tutto e ricrea (solo in development!)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
// up(): eseguita da "php artisan migrate" → crea/modifica strutture
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('customers', function (Blueprint $table) {
|
||||
// id(): crea colonna "id" bigint UNSIGNED AUTO_INCREMENT PRIMARY KEY
|
||||
$table->id();
|
||||
|
||||
// Dati anagrafici
|
||||
$table->string('name'); // Ragione sociale / nome
|
||||
$table->string('email')->unique(); // Email (univoca)
|
||||
$table->string('phone', 50)->nullable(); // Telefono
|
||||
$table->string('city', 100)->nullable(); // Città
|
||||
$table->string('address')->nullable(); // Indirizzo completo
|
||||
$table->string('vat_number', 20)->nullable(); // Partita IVA
|
||||
$table->string('fiscal_code', 20)->nullable(); // Codice fiscale
|
||||
|
||||
// Tipo cliente: "privato" o "azienda"
|
||||
// enum() limita i valori accettati a livello DB
|
||||
$table->enum('type', ['privato', 'azienda'])->default('azienda');
|
||||
|
||||
// Stato nel ciclo di vita commerciale
|
||||
$table->enum('status', ['attivo', 'inattivo', 'prospect'])->default('prospect');
|
||||
|
||||
// Dati commerciali
|
||||
$table->decimal('contract_value', 10, 2)->default(0); // Valore contratto annuo
|
||||
$table->text('notes')->nullable(); // Note libere
|
||||
|
||||
// timestamps(): crea created_at e updated_at (gestiti automaticamente da Eloquent)
|
||||
$table->timestamps();
|
||||
|
||||
// softDeletes(): aggiunge colonna deleted_at per il Soft Delete
|
||||
// I clienti "eliminati" hanno deleted_at valorizzato, non sono rimossi dal DB
|
||||
$table->softDeletes();
|
||||
|
||||
// Indici per velocizzare le ricerche più comuni
|
||||
$table->index('status');
|
||||
$table->index('type');
|
||||
$table->index('city');
|
||||
});
|
||||
}
|
||||
|
||||
// down(): eseguita da "php artisan migrate:rollback" → annulla la migration
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('customers');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// Migration: crea la tabella settings
|
||||
//
|
||||
// La tabella `settings` implementa il pattern "key-value store":
|
||||
// ogni riga è un'impostazione dell'applicazione modificabile via Admin.
|
||||
//
|
||||
// Schema:
|
||||
// id → chiave primaria
|
||||
// key → identificatore univoco dell'impostazione (es. "items_per_page")
|
||||
// value → valore come stringa (il tipo è gestito da SettingService)
|
||||
// label → nome leggibile per l'interfaccia admin
|
||||
// group → raggruppamento per il pannello (es. "Azienda", "Visualizzazione")
|
||||
// type → tipo dato per il cast corretto (string, integer, boolean, text)
|
||||
// timestamps → created_at e updated_at
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
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('settings', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
// Chiave univoca: identifica univocamente l'impostazione
|
||||
$table->string('key')->unique();
|
||||
|
||||
// Valore come testo (può essere lungo, es. messaggi)
|
||||
$table->text('value')->nullable();
|
||||
|
||||
// Metadati per il pannello admin
|
||||
$table->string('label')->nullable(); // Nome leggibile
|
||||
$table->string('group')->default('Generale'); // Gruppo
|
||||
$table->string('type')->default('string'); // Tipo PHP
|
||||
|
||||
$table->timestamps();
|
||||
|
||||
// Indice sul gruppo per caricare le impostazioni per sezione
|
||||
$table->index('group');
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('settings');
|
||||
}
|
||||
};
|
||||
53
database/seeders/CustomerSeeder.php
Normal file
53
database/seeders/CustomerSeeder.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// CustomerSeeder — Genera clienti di esempio per lo sviluppo
|
||||
//
|
||||
// Usa Faker (libreria inclusa in Laravel) per generare dati realistici
|
||||
// in italiano. Questi dati servono per testare l'interfaccia.
|
||||
//
|
||||
// ⚠️ Non eseguire in produzione! Solo per sviluppo e staging.
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
use App\Models\Customer;
|
||||
use Faker\Factory as Faker;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class CustomerSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
// Faker con locale italiano: nomi, città, ecc. italiani
|
||||
$faker = Faker::create('it_IT');
|
||||
|
||||
$types = ['privato', 'azienda'];
|
||||
$statuses = ['attivo', 'inattivo', 'prospect'];
|
||||
$cities = ['Roma', 'Milano', 'Napoli', 'Torino', 'Bologna', 'Firenze', 'Venezia', 'Genova', 'Palermo', 'Bari'];
|
||||
|
||||
// Crea 30 clienti di esempio
|
||||
for ($i = 0; $i < 30; $i++) {
|
||||
$type = $faker->randomElement($types);
|
||||
$name = $type === 'azienda'
|
||||
? $faker->company()
|
||||
: $faker->name();
|
||||
|
||||
Customer::create([
|
||||
'name' => $name,
|
||||
'email' => $faker->unique()->safeEmail(),
|
||||
'phone' => $faker->phoneNumber(),
|
||||
'city' => $faker->randomElement($cities),
|
||||
'address' => $faker->streetAddress(),
|
||||
'vat_number' => $type === 'azienda' ? 'IT' . $faker->numerify('###########') : null,
|
||||
'fiscal_code' => $faker->numerify('??????????##??##??###?'),
|
||||
'type' => $type,
|
||||
'status' => $faker->randomElement($statuses),
|
||||
'contract_value' => $faker->randomFloat(2, 500, 50000),
|
||||
'notes' => $faker->optional(0.4)->paragraph(),
|
||||
]);
|
||||
}
|
||||
|
||||
$this->command->info('✓ 30 clienti di esempio inseriti.');
|
||||
}
|
||||
}
|
||||
31
database/seeders/DatabaseSeeder.php
Normal file
31
database/seeders/DatabaseSeeder.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// DatabaseSeeder — Entry point di tutti i seeder
|
||||
//
|
||||
// Un Seeder popola il database con dati iniziali o di test.
|
||||
// Il DatabaseSeeder è il punto di ingresso; chiama gli altri seeder
|
||||
// nell'ordine corretto (rispettando le foreign key).
|
||||
//
|
||||
// Esecuzione:
|
||||
// php artisan db:seed → esegue solo DatabaseSeeder
|
||||
// php artisan db:seed --class=CustomerSeeder → esegue solo quello
|
||||
// php artisan migrate:fresh --seed → ricrea tutto e semina
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class DatabaseSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
// L'ordine conta: settings prima (nessuna dipendenza),
|
||||
// poi customers (dipende da nulla, ma logicamente dopo la config)
|
||||
$this->call([
|
||||
SettingSeeder::class,
|
||||
CustomerSeeder::class,
|
||||
]);
|
||||
}
|
||||
}
|
||||
50
database/seeders/SettingSeeder.php
Normal file
50
database/seeders/SettingSeeder.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
// SettingSeeder — Popola la tabella settings con i valori di default
|
||||
//
|
||||
// Questo seeder legge i default da config/settings.php e li inserisce
|
||||
// nel database al primo avvio.
|
||||
//
|
||||
// È idempotente: puoi eseguirlo più volte senza duplicati (usa updateOrCreate)
|
||||
// ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class SettingSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
$defaults = config('settings.defaults', []);
|
||||
$descriptions = config('settings.descriptions', []);
|
||||
$types = config('settings.types', []);
|
||||
$groups = config('settings.groups', []);
|
||||
|
||||
// Costruisce una mappa chiave → gruppo
|
||||
$keyToGroup = [];
|
||||
foreach ($groups as $groupName => $keys) {
|
||||
foreach ($keys as $key) {
|
||||
$keyToGroup[$key] = $groupName;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($defaults as $key => $value) {
|
||||
// updateOrCreate: se esiste già una riga con quell'key, la aggiorna;
|
||||
// altrimenti la crea. Perfetto per rieseguire il seeder in sicurezza.
|
||||
Setting::updateOrCreate(
|
||||
['key' => $key],
|
||||
[
|
||||
'value' => is_bool($value) ? ($value ? '1' : '0') : (string) $value,
|
||||
'label' => $descriptions[$key] ?? $key,
|
||||
'group' => $keyToGroup[$key] ?? 'Generale',
|
||||
'type' => $types[$key] ?? 'string',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
$this->command->info('✓ Impostazioni di default inserite nella tabella settings.');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user