Files
backend/database/seeders/DemoSeeder.php
T
2026-06-28 12:29:53 +02:00

297 lines
11 KiB
PHP

<?php
namespace Database\Seeders;
use App\Models\Establishment;
use App\Models\Machine;
use App\Models\MachineIntegration;
use App\Models\Organization;
use App\Models\PricingRule;
use App\Models\Promotion;
use App\Models\Supervisor;
use App\Models\User;
use App\Models\Wallet;
use Illuminate\Database\Seeder;
/**
* Jeu de données de démonstration pour Laverie Connectée.
*
* Crée organisations, établissements, superviseurs, utilisateurs,
* machines simulées, tarifs et promotions actives.
*/
class DemoSeeder extends Seeder
{
/** Mot de passe commun pour tous les comptes de démo. */
private const DEMO_PASSWORD = 'password';
public function run(): void
{
$simulatedProvider = config('laverie.simulation.provider_name', 'simulated');
// --- Organisations ---
$orgCentre = Organization::create([
'name' => 'Laverie du Centre',
'code' => 'LDC',
'is_active' => true,
]);
$orgExpress = Organization::create([
'name' => 'Laverie Express',
'code' => 'LEX',
'is_active' => true,
]);
// --- Établissements (2 pour org1, 1 pour org2) ---
$estCentreVille = Establishment::create([
'organization_id' => $orgCentre->id,
'name' => 'Laverie Centre-Ville',
'address' => '12 rue de la République',
'city' => 'Lyon',
'zip_code' => '69002',
'latitude' => 45.7578137,
'longitude' => 4.8320114,
'timezone' => 'Europe/Paris',
'is_active' => true,
]);
$estPartDieu = Establishment::create([
'organization_id' => $orgCentre->id,
'name' => 'Laverie Part-Dieu',
'address' => '45 avenue du Général Leclerc',
'city' => 'Lyon',
'zip_code' => '69003',
'latitude' => 45.7601061,
'longitude' => 4.8566930,
'timezone' => 'Europe/Paris',
'is_active' => true,
]);
$estExpressNord = Establishment::create([
'organization_id' => $orgExpress->id,
'name' => 'Laverie Express Nord',
'address' => '8 boulevard de la Croix-Rousse',
'city' => 'Lyon',
'zip_code' => '69004',
'latitude' => 45.7740000,
'longitude' => 4.8325000,
'timezone' => 'Europe/Paris',
'is_active' => true,
]);
// --- Superviseurs ---
$this->createSupervisor(
organizationId: $orgCentre->id,
establishmentId: null,
firstName: 'Admin',
lastName: 'Plateforme',
email: 'platform_admin@laverie.local',
role: 'platform_admin',
);
$this->createSupervisor(
organizationId: $orgCentre->id,
establishmentId: null,
firstName: 'Pierre',
lastName: 'Moreau',
email: 'owner1@laverie.local',
role: 'owner',
);
$this->createSupervisor(
organizationId: $orgCentre->id,
establishmentId: $estCentreVille->id,
firstName: 'Sophie',
lastName: 'Bernard',
email: 'manager1@laverie.local',
role: 'manager',
);
$this->createSupervisor(
organizationId: $orgExpress->id,
establishmentId: null,
firstName: 'Marc',
lastName: 'Lefèvre',
email: 'owner2@laverie.local',
role: 'owner',
);
// --- Utilisateurs finaux avec portefeuille (20 € chacun) ---
$demoUsers = [
['first_name' => 'Marie', 'last_name' => 'Dupont', 'email' => 'marie.dupont@demo.local'],
['first_name' => 'Jean', 'last_name' => 'Martin', 'email' => 'jean.martin@demo.local'],
['first_name' => 'Lucie', 'last_name' => 'Petit', 'email' => 'lucie.petit@demo.local'],
['first_name' => 'Thomas', 'last_name' => 'Roux', 'email' => 'thomas.roux@demo.local'],
['first_name' => 'Emma', 'last_name' => 'Girard', 'email' => 'emma.girard@demo.local'],
];
$users = collect($demoUsers)->map(function (array $data) {
$user = User::create([
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
'email' => $data['email'],
'password' => self::DEMO_PASSWORD,
'locale' => 'fr',
'is_active' => true,
'email_verified_at' => now(),
]);
Wallet::create([
'user_id' => $user->id,
'currency' => 'EUR',
'current_balance' => 20.00,
'status' => 'active',
]);
return $user;
});
// --- Machines (10 au total, statuts variés) ---
$machineDefinitions = [
// Laverie Centre-Ville (4 machines)
['establishment' => $estCentreVille, 'name' => 'Lave-linge 1', 'type' => 'washer_small', 'status' => 'available'],
['establishment' => $estCentreVille, 'name' => 'Lave-linge 2', 'type' => 'washer_large', 'status' => 'running', 'user' => $users[0]],
['establishment' => $estCentreVille, 'name' => 'Sèche-linge 1', 'type' => 'dryer_small', 'status' => 'reserved'],
['establishment' => $estCentreVille, 'name' => 'Sèche-linge 2', 'type' => 'dryer_large', 'status' => 'maintenance'],
// Laverie Part-Dieu (3 machines)
['establishment' => $estPartDieu, 'name' => 'Lave-linge A', 'type' => 'washer_small', 'status' => 'available'],
['establishment' => $estPartDieu, 'name' => 'Lave-linge B', 'type' => 'washer_large', 'status' => 'offline'],
['establishment' => $estPartDieu, 'name' => 'Sèche-linge A', 'type' => 'dryer_small', 'status' => 'error'],
// Laverie Express Nord (3 machines)
['establishment' => $estExpressNord, 'name' => 'Express Lave 1', 'type' => 'washer_small', 'status' => 'available'],
['establishment' => $estExpressNord, 'name' => 'Express Lave 2', 'type' => 'washer_large', 'status' => 'running', 'user' => $users[1]],
['establishment' => $estExpressNord, 'name' => 'Express Sèche 1', 'type' => 'dryer_large', 'status' => 'available'],
];
$machineIndex = 1;
foreach ($machineDefinitions as $definition) {
$machine = Machine::create([
'establishment_id' => $definition['establishment']->id,
'name' => $definition['name'],
'type' => $definition['type'],
'qr_code' => 'LAVERIE-DEMO-'.str_pad((string) $machineIndex, 3, '0', STR_PAD_LEFT),
'status' => $definition['status'],
'current_user_id' => isset($definition['user']) ? $definition['user']->id : null,
'cycle_started_at' => $definition['status'] === 'running' ? now()->subMinutes(15) : null,
'cycle_ends_at' => $definition['status'] === 'running' ? now()->addMinutes(27) : null,
'last_heartbeat_at' => $definition['status'] === 'offline' ? now()->subHours(2) : now()->subMinutes(2),
]);
MachineIntegration::create([
'machine_id' => $machine->id,
'provider' => $simulatedProvider,
'external_machine_id' => 'SIM-'.$machine->uuid,
'external_site_id' => 'SITE-'.$definition['establishment']->uuid,
'mode' => 'simulated',
'config' => [
'cycle_duration_seconds' => config('laverie.simulation.cycle_duration_seconds', 30),
],
'is_active' => true,
]);
$machineIndex++;
}
// --- Règles tarifaires (4 € lavage, 3 € séchage) par établissement ---
foreach ([$estCentreVille, $estPartDieu, $estExpressNord] as $establishment) {
PricingRule::create([
'establishment_id' => $establishment->id,
'machine_type' => 'washer_small',
'day_type' => 'all',
'slot_start' => '00:00:00',
'slot_end' => '23:59:59',
'price' => 4.00,
'label' => 'Lavage standard',
'requires_app' => false,
'priority' => 100,
'is_active' => true,
]);
PricingRule::create([
'establishment_id' => $establishment->id,
'machine_type' => 'washer_large',
'day_type' => 'all',
'slot_start' => '00:00:00',
'slot_end' => '23:59:59',
'price' => 4.00,
'label' => 'Lavage grand tambour',
'requires_app' => false,
'priority' => 100,
'is_active' => true,
]);
PricingRule::create([
'establishment_id' => $establishment->id,
'machine_type' => 'dryer_small',
'day_type' => 'all',
'slot_start' => '00:00:00',
'slot_end' => '23:59:59',
'price' => 3.00,
'label' => 'Séchage standard',
'requires_app' => false,
'priority' => 100,
'is_active' => true,
]);
PricingRule::create([
'establishment_id' => $establishment->id,
'machine_type' => 'dryer_large',
'day_type' => 'all',
'slot_start' => '00:00:00',
'slot_end' => '23:59:59',
'price' => 3.00,
'label' => 'Sèche-linge grand tambour',
'requires_app' => false,
'priority' => 100,
'is_active' => true,
]);
}
// --- Promotions actives (2) ---
Promotion::create([
'establishment_id' => $estCentreVille->id,
'machine_type' => 'washer_small',
'discount_type' => 'percent',
'discount_value' => 10.00,
'starts_at' => now()->subDays(7),
'ends_at' => now()->addDays(30),
'description' => 'Offre de bienvenue : -10 % sur les lavages petit tambour',
'is_active' => true,
]);
Promotion::create([
'establishment_id' => $estExpressNord->id,
'machine_type' => 'all',
'discount_type' => 'fixed',
'discount_value' => 0.50,
'starts_at' => now()->subDays(3),
'ends_at' => now()->addDays(14),
'description' => 'Happy hour Express : 0,50 € de réduction sur tous les cycles',
'is_active' => true,
]);
}
/**
* Crée un superviseur avec mot de passe de démonstration.
*/
private function createSupervisor(
int $organizationId,
?int $establishmentId,
string $firstName,
string $lastName,
string $email,
string $role,
): Supervisor {
return Supervisor::create([
'organization_id' => $organizationId,
'establishment_id' => $establishmentId,
'first_name' => $firstName,
'last_name' => $lastName,
'email' => $email,
'password' => self::DEMO_PASSWORD,
'role' => $role,
'is_active' => true,
]);
}
}