cleanupSampleData(); $election = Election::query()->firstOrNew(['code' => 'PRN2026']); if (! $election->exists) { $election->public_uuid = (string) Str::uuid(); } $election->forceFill([ 'name' => 'Pilihanraya Negeri 2026', 'status' => 'active', 'starts_at' => now()->toDateString(), 'polling_date' => now()->addWeeks(4)->toDateString(), ])->save(); $election->settings()->updateOrCreate( ['election_id' => $election->id], [ 'registration_start_date' => now()->toDateString(), 'registration_end_date' => now()->addWeeks(3)->toDateString(), 'polling_date' => $election->polling_date, 'is_registration_open' => true, 'is_registration_open_override' => null, 'is_attendance_active' => false, ], ); $dun = Dun::query()->updateOrCreate( ['election_id' => $election->id, 'code' => 'N49'], ['name' => 'Kota Iskandar'], ); $pusat = new PusatMengundi; $pusat->public_uuid = (string) Str::uuid(); $pusat->forceFill([ 'election_id' => $election->id, 'code' => 'PM001', 'dun_id' => $dun->id, 'name' => 'SK Seri Contoh', 'address' => 'Jalan Contoh 1, 43000 Kajang, Selangor', ])->save(); $pusat->forceFill([ 'registration_url' => url('/pohon/'.$pusat->public_uuid), ])->save(); $this->seedSaluran($election, $pusat); $this->seedQuotas($election, $pusat); $this->seedOperationalUsersAndAssignments($election, $pusat); $pusat->wheelchairAllocation()->updateOrCreate( ['election_id' => $election->id], [ 'allocated_quantity' => 2, 'notes' => 'Sample allocation for Phase 2.', ], ); } private function cleanupSampleData(): void { $election = Election::query()->where('code', 'PRN2026')->first(); if (! $election) { return; } PositionQuota::query()->where('election_id', $election->id)->forceDelete(); SaluranMengundi::query()->where('election_id', $election->id)->forceDelete(); PusatMengundi::query()->where('election_id', $election->id)->forceDelete(); } private function seedSaluran(Election $election, PusatMengundi $pusat): void { foreach (range(1, 3) as $number) { $pusat->saluranMengundis()->updateOrCreate( ['number' => (string) $number], [ 'election_id' => $election->id, 'name' => null, 'voter_count' => 450 + ($number * 25), ], ); } } private function seedQuotas(Election $election, PusatMengundi $pusat): void { $positions = Position::query()->whereIn('code', [ 'PPM', 'PAPM', 'KTM', 'KPDP', 'KP', 'POLIS', 'CALON_TAMBAHAN', ])->get()->keyBy('code'); PositionQuota::query()->updateOrCreate( [ 'election_id' => $election->id, 'pusat_mengundi_id' => $pusat->id, 'saluran_mengundi_id' => null, 'position_id' => $positions['PPM']->id, ], ['quota' => 1], ); PositionQuota::query()->updateOrCreate( [ 'election_id' => $election->id, 'pusat_mengundi_id' => $pusat->id, 'saluran_mengundi_id' => null, 'position_id' => $positions['PAPM']->id, ], ['quota' => 3], ); /** @var Collection $salurans */ $salurans = $pusat->saluranMengundis()->get(); foreach ($salurans as $saluran) { foreach ([ 'KTM' => 1, 'KPDP' => 1, 'KP' => 4, 'POLIS' => 1, 'CALON_TAMBAHAN' => 1, ] as $code => $quota) { PositionQuota::query()->updateOrCreate( [ 'election_id' => $election->id, 'pusat_mengundi_id' => $pusat->id, 'saluran_mengundi_id' => $saluran->id, 'position_id' => $positions[$code]->id, ], ['quota' => $quota], ); } } } private function seedOperationalUsersAndAssignments(Election $election, PusatMengundi $pusat): void { $ppm = $this->seedUser('PPM Contoh', 'ppm@prn.local', ['PPM', 'KTM']); $ktm = $this->seedUser('KTM Contoh', 'ktm@prn.local', ['KTM']); $this->seedUser('Admin Kewangan Contoh', 'kewangan@prn.local', ['Admin Kewangan']); $positions = Position::query()->whereIn('code', ['PPM', 'KTM'])->get()->keyBy('code'); /** @var SaluranMengundi $saluranPertama */ $saluranPertama = $pusat->saluranMengundis()->where('number', '1')->firstOrFail(); /** @var SaluranMengundi $saluranKedua */ $saluranKedua = $pusat->saluranMengundis()->where('number', '2')->firstOrFail(); StaffAssignment::query()->updateOrCreate( [ 'election_id' => $election->id, 'user_id' => $ppm->id, 'position_id' => $positions['PPM']->id, 'pusat_mengundi_id' => $pusat->id, 'saluran_mengundi_id' => null, ], [ 'status' => 'active', 'assigned_at' => now(), 'source' => 'sample_seed', ], ); StaffAssignment::query()->updateOrCreate( [ 'election_id' => $election->id, 'user_id' => $ppm->id, 'position_id' => $positions['KTM']->id, 'pusat_mengundi_id' => $pusat->id, 'saluran_mengundi_id' => $saluranPertama->id, ], [ 'status' => 'active', 'assigned_at' => now(), 'source' => 'sample_seed_dual_role', ], ); StaffAssignment::query()->updateOrCreate( [ 'election_id' => $election->id, 'user_id' => $ktm->id, 'position_id' => $positions['KTM']->id, 'pusat_mengundi_id' => $pusat->id, 'saluran_mengundi_id' => $saluranKedua->id, ], [ 'status' => 'active', 'assigned_at' => now(), 'source' => 'sample_seed', ], ); } /** * @param array $roles */ private function seedUser(string $name, string $email, array $roles): User { $user = User::query()->firstOrCreate( ['email' => $email], [ 'name' => $name, 'password' => Hash::make('password'), 'email_verified_at' => now(), ], ); if ($user->email_verified_at === null) { $user->forceFill(['email_verified_at' => now()])->save(); } $user->syncRoles($roles); return $user; } }