112 lines
4.4 KiB
PHP
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();
|
|
});
|
|
}
|
|
}
|