Files
prn2026/app/Services/Admin/Management/AdminRepresentativeService.php
2026-06-03 08:51:22 +08:00

112 lines
4.4 KiB
PHP

<?php
namespace App\Services\Admin\Management;
use App\Models\Election;
use App\Models\JkmRepresentative;
use App\Models\KkmRepresentative;
use App\Models\PoliceEscort;
use App\Models\PusatMengundi;
use App\Models\SaluranMengundi;
use App\Models\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
class AdminRepresentativeService
{
public function __construct(
private readonly AdminPostCloseNoteService $postCloseNoteService,
) {}
/**
* @param array<string, mixed> $data
*/
public function store(User $actor, array $data): Model
{
return DB::transaction(function () use ($actor, $data): Model {
$election = Election::query()->findOrFail($data['election_id']);
$this->postCloseNoteService->requireIfClosed($election, $data['note'] ?? null);
/** @var PusatMengundi $pusat */
$pusat = PusatMengundi::query()->findOrFail($data['pusat_mengundi_id']);
if ((int) $pusat->election_id !== (int) $election->id) {
throw new \InvalidArgumentException('Pusat Mengundi tidak berada dalam pilihanraya yang sama.');
}
if (! empty($data['saluran_mengundi_id'])) {
/** @var SaluranMengundi $saluran */
$saluran = SaluranMengundi::query()->findOrFail($data['saluran_mengundi_id']);
if ((int) $saluran->pusat_mengundi_id !== (int) $pusat->id) {
throw new \InvalidArgumentException('Saluran Mengundi tidak berada di bawah Pusat Mengundi yang dipilih.');
}
}
$payload = [
'election_id' => $election->id,
'pusat_mengundi_id' => $pusat->id,
'name' => $data['name'],
'ic_number' => $data['ic_number'] ?? null,
'phone_number' => $data['phone_number'] ?? null,
'notes' => $data['notes'] ?? null,
];
$type = (string) $data['type'];
$representative = match ($type) {
'police' => PoliceEscort::query()->create([
...$payload,
'saluran_mengundi_id' => $data['saluran_mengundi_id'] ?? null,
'rank' => $data['rank'] ?? null,
'station' => $data['station'] ?? null,
]),
'kkm' => KkmRepresentative::query()->create([
...$payload,
'agency' => $data['agency'] ?? null,
]),
'jkm' => JkmRepresentative::query()->create([
...$payload,
'agency' => $data['agency'] ?? null,
]),
default => throw new \InvalidArgumentException('Jenis wakil agensi tidak sah.'),
};
$this->postCloseNoteService->recordIfClosed($election, $representative, $actor, $data['note'] ?? null, 'admin_representative_after_close');
activity('admin_management')
->performedOn($representative)
->causedBy($actor)
->withProperties(['type' => $type])
->log('representative_created_by_admin');
return $representative;
});
}
public function delete(Model $representative, User $actor, ?string $note = null): void
{
DB::transaction(function () use ($representative, $actor, $note): void {
$election = match (true) {
$representative instanceof PoliceEscort => $representative->election,
$representative instanceof KkmRepresentative => $representative->election,
$representative instanceof JkmRepresentative => $representative->election,
default => null,
};
if (! $election instanceof Election) {
throw new \InvalidArgumentException('Pilihanraya wakil agensi tidak sah.');
}
$this->postCloseNoteService->requireIfClosed($election, $note);
$this->postCloseNoteService->recordIfClosed($election, $representative, $actor, $note, 'admin_representative_delete_after_close');
activity('admin_management')
->performedOn($representative)
->causedBy($actor)
->withProperties(['note' => $note])
->log('representative_deleted_by_admin');
$representative->delete();
});
}
}