249 lines
7.9 KiB
PHP
249 lines
7.9 KiB
PHP
<?php
|
|
|
|
namespace Database\Seeders;
|
|
|
|
use App\Models\Dun;
|
|
use App\Models\Election;
|
|
use App\Models\Position;
|
|
use App\Models\PositionQuota;
|
|
use App\Models\PusatMengundi;
|
|
use App\Models\SaluranMengundi;
|
|
use App\Models\StaffAssignment;
|
|
use App\Models\User;
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
use Illuminate\Database\Seeder;
|
|
use Illuminate\Support\Facades\Hash;
|
|
use Illuminate\Support\Str;
|
|
|
|
class SampleElectionSeeder extends Seeder
|
|
{
|
|
/**
|
|
* Seed sample election hierarchy for development and tests.
|
|
*/
|
|
public function run(): void
|
|
{
|
|
$this->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<int, SaluranMengundi> $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<int, string> $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;
|
|
}
|
|
}
|