'super@verde.local'], [ 'phone' => '+639000000000', 'password' => $password, 'first_name' => 'System', 'last_name' => 'Super Admin', 'role' => 'super_admin', 'status' => User::STATUS_ACTIVE, 'tenant_id' => null, 'email_verified_at' => now(), ] ); $super->syncRoles(['super_admin']); $lguConfigs = [ ['code' => 'SPB', 'name' => 'San Pascual, Batangas'], ['code' => 'BAU', 'name' => 'Bauan, Batangas'], ]; foreach ($lguConfigs as $index => $config) { $tenant = Tenant::firstOrCreate( ['code' => $config['code']], [ 'name' => $config['name'], 'status' => Tenant::STATUS_ACTIVE, 'qr_retail_price_centavos' => 1000, 'uuid' => (string) Str::uuid(), ] ); Tenancy::setCurrent($tenant); $this->seedTenantData($tenant, $password, $index); } } private function seedTenantData(Tenant $tenant, string $password, int $lguIndex): void { // 1. Multiple Admins for ($i = 1; $i <= 2; $i++) { $admin = User::firstOrCreate( ['email' => "admin{$i}.{$tenant->code}@verde.local"], [ 'phone' => "+63900{$lguIndex}00000{$i}", 'password' => $password, 'first_name' => "Verde", 'last_name' => "Admin {$i} ({$tenant->code})", 'role' => User::ROLE_ADMIN, 'status' => User::STATUS_ACTIVE, 'tenant_id' => $tenant->id, 'email_verified_at' => now(), ] ); $admin->syncRoles([User::ROLE_ADMIN]); } // 2. Geography $barangay = Barangay::where('name', 'like', '%Poblacion%')->first() ?? Barangay::first(); $dop = DropOffPoint::firstOrCreate( ['name' => "{$tenant->code} Main Plaza"], [ 'uuid' => (string) Str::uuid(), 'tenant_id' => $tenant->id, 'code' => "DOP-{$tenant->code}-001", 'barangay_id' => $barangay->id, 'address_line' => 'City Center', 'coordinates' => new Point(14.65 + ($lguIndex * 0.1), 121.06, 4326), ] ); $dumpsite = Dumpsite::firstOrCreate( ['name' => "{$tenant->code} Sanitary Landfill"], [ 'uuid' => (string) Str::uuid(), 'tenant_id' => $tenant->id, 'code' => "DS-{$tenant->code}-001", 'address_line' => 'Waste Management Zone', 'coordinates' => new Point(14.67 + ($lguIndex * 0.1), 121.08, 4326), ] ); // 3. Operational Staff (2 Drivers, 2 Helpers, 2 Scanners) for ($i = 1; $i <= 2; $i++) { $driver = $this->createStaff("driver{$i}.{$tenant->code}@verde.local", "+63918{$lguIndex}00000{$i}", "Driver", "{$i}", User::ROLE_DRIVER, $tenant, $password); DriverProfile::updateOrCreate(['user_id' => $driver->id], ['license_number' => "L-{$tenant->code}-{$i}", 'verification_status' => 'approved', 'verified_at' => now()]); $helper = $this->createStaff("helper{$i}.{$tenant->code}@verde.local", "+63919{$lguIndex}00000{$i}", "Helper", "{$i}", User::ROLE_HELPER, $tenant, $password); HelperProfile::updateOrCreate(['user_id' => $helper->id], ['verification_status' => 'approved', 'verified_at' => now()]); $scanner = $this->createStaff("scanner{$i}.{$tenant->code}@verde.local", "+63920{$lguIndex}00000{$i}", "Scanner", "{$i}", User::ROLE_SCANNER, $tenant, $password); ScannerProfile::updateOrCreate(['user_id' => $scanner->id], ['verification_status' => 'approved', 'verified_at' => now()]); // 4. Assets & Teams $truck = Truck::create([ 'plate_number' => "VRD-{$tenant->code}-{$i}", 'uuid' => (string) Str::uuid(), 'tenant_id' => $tenant->id, 'model' => 'Isuzu Elf', 'capacity_kg' => 3000, 'status' => Truck::STATUS_ACTIVE, ]); $team = CollectionTeam::create([ 'name' => "{$tenant->code} Crew {$i}", 'uuid' => (string) Str::uuid(), 'tenant_id' => $tenant->id, 'driver_id' => $driver->id, 'scanner_id' => $scanner->id, 'truck_id' => $truck->id, 'status' => CollectionTeam::STATUS_ACTIVE, ]); TeamMember::create(['team_id' => $team->id, 'user_id' => $helper->id, 'role_in_team' => 'helper', 'assigned_from' => now()]); // 5. Routes & Dynamic Trips $route = CollectionRoute::create([ 'uuid' => (string) Str::uuid(), 'tenant_id' => $tenant->id, 'code' => "RT-{$tenant->code}-{$i}", 'name' => "{$tenant->code} Route {$i}", 'default_dumpsite_id' => $dumpsite->id, 'default_team_id' => $team->id, 'status' => CollectionRoute::STATUS_ACTIVE, ]); RouteStop::create(['route_id' => $route->id, 'drop_off_point_id' => $dop->id, 'sequence' => 1, 'estimated_duration_at_stop_minutes' => 15]); // Seed Trips for different time periods $tripScenarios = [ ['date' => now(), 'status' => Trip::STATUS_IN_PROGRESS, 'label' => 'Today'], ['date' => now()->subDay(), 'status' => Trip::STATUS_COMPLETED, 'label' => 'Yesterday'], ['date' => now()->subMonth(), 'status' => Trip::STATUS_COMPLETED, 'label' => 'Last Month'], ['date' => now()->subMonths(2), 'status' => Trip::STATUS_COMPLETED, 'label' => 'Historical'], ]; foreach ($tripScenarios as $scenario) { $tripDate = $scenario['date']; $isCompleted = $scenario['status'] === Trip::STATUS_COMPLETED; $trip = Trip::create([ 'uuid' => (string) Str::uuid(), 'tenant_id' => $tenant->id, 'trip_number' => "TRIP-{$tenant->code}-{$i}-" . $tripDate->format('Ymd'), 'route_id' => $route->id, 'team_id' => $team->id, 'truck_id' => $truck->id, 'dumpsite_id' => $dumpsite->id, 'scheduled_date' => $tripDate->format('Y-m-d'), 'status' => $scenario['status'], 'current_load_kg' => $isCompleted ? rand(1500, 2800) : 0, 'actual_start_time' => $isCompleted ? $tripDate->copy()->setHour(8) : ($scenario['label'] === 'Today' ? now()->subHours(2) : null), 'actual_end_time' => $isCompleted ? $tripDate->copy()->setHour(14) : null, ]); TripStop::create([ 'trip_id' => $trip->id, 'drop_off_point_id' => $dop->id, 'sequence' => 1, 'status' => $isCompleted ? 'completed' : 'pending', 'total_scans' => $isCompleted ? rand(50, 100) : 0, 'estimated_load_added_kg' => $isCompleted ? rand(500, 800) : 0, ]); } } // 6. Multiple Stores for ($i = 1; $i <= 2; $i++) { $storeOwner = $this->createStaff("store{$i}.{$tenant->code}@verde.local", "+63921{$lguIndex}00000{$i}", "Store", "Owner {$i}", User::ROLE_STORE_PARTNER, $tenant, $password); StorePartnerProfile::updateOrCreate(['user_id' => $storeOwner->id], ['business_name' => "Store {$i} - {$tenant->code}", 'verification_status' => 'approved', 'verified_at' => now()]); $store = PartnerStore::create([ 'owner_user_id' => $storeOwner->id, 'uuid' => (string) Str::uuid(), 'tenant_id' => $tenant->id, 'business_name' => "Store {$i} - {$tenant->code}", 'business_permit_number' => "BP-{$tenant->code}-{$i}", 'address_line' => "Market St {$i}", 'barangay_id' => $barangay->id, 'coordinates' => new Point(14.651 + ($i * 0.001), 121.061, 4326), 'status' => PartnerStore::STATUS_ACTIVE, ]); StoreInventory::create(['store_id' => $store->id, 'current_code_balance' => 100]); } } private function createStaff($email, $phone, $first, $last, $role, $tenant, $password): User { $u = User::create([ 'email' => $email, 'phone' => $phone, 'password' => $password, 'first_name' => $first, 'last_name' => $last, 'role' => $role, 'status' => User::STATUS_ACTIVE, 'tenant_id' => $tenant->id, 'email_verified_at' => now(), ]); $u->syncRoles([$role]); NotificationPreference::firstOrCreate(['user_id' => $u->id]); return $u; } }