107 lines
3.7 KiB
PHP
107 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Public;
|
|
|
|
use App\Models\Application;
|
|
use App\Models\Position;
|
|
use App\Models\PusatMengundi;
|
|
use Illuminate\Http\UploadedFile;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
use RuntimeException;
|
|
|
|
class PublicApplicationSubmissionService
|
|
{
|
|
/**
|
|
* @param array<string, mixed> $data
|
|
*/
|
|
public function submit(PusatMengundi $pusatMengundi, array $data): Application
|
|
{
|
|
return DB::transaction(function () use ($pusatMengundi, $data): Application {
|
|
$position = Position::query()
|
|
->where('code', $data['requested_position_code'])
|
|
->where('is_public_applyable', true)
|
|
->firstOrFail();
|
|
|
|
$application = Application::query()->create([
|
|
'election_id' => $pusatMengundi->election_id,
|
|
'pusat_mengundi_id' => $pusatMengundi->id,
|
|
'selected_ktm_assignment_id' => in_array($position->code, ['KP', 'KPDP'], true)
|
|
? $data['selected_ktm_assignment_id']
|
|
: null,
|
|
'public_uuid' => (string) Str::uuid(),
|
|
'source' => 'public',
|
|
'status' => 'submitted',
|
|
'name' => $data['name'],
|
|
'ic_number' => $data['ic_number'],
|
|
'phone_number' => $data['phone_number'],
|
|
'email' => $data['email'] ?? null,
|
|
'address' => $data['address'],
|
|
'requested_position_id' => $position->id,
|
|
'bank_name' => $data['bank_name'],
|
|
'bank_account_number' => $data['bank_account_number'],
|
|
]);
|
|
|
|
$this->storeDocument($application, 'ic_document', $data['ic_document']);
|
|
$this->storeDocument($application, 'bank_statement', $data['bank_statement']);
|
|
|
|
$application->statusHistories()->create([
|
|
'to_status' => 'submitted',
|
|
'note' => 'Public QR application submitted.',
|
|
'metadata' => [
|
|
'source' => 'public',
|
|
'requested_position_code' => $position->code,
|
|
],
|
|
]);
|
|
|
|
$application->bankVerification()->create([
|
|
'status' => 'pending',
|
|
]);
|
|
|
|
activity('public_application')
|
|
->performedOn($application)
|
|
->withProperties([
|
|
'pusat_mengundi_id' => $pusatMengundi->id,
|
|
'requested_position_code' => $position->code,
|
|
'document_types' => ['ic_document', 'bank_statement'],
|
|
])
|
|
->log('application_submitted');
|
|
|
|
return $application;
|
|
});
|
|
}
|
|
|
|
private function storeDocument(Application $application, string $documentType, mixed $file): void
|
|
{
|
|
if (! $file instanceof UploadedFile) {
|
|
throw new RuntimeException('Invalid uploaded file.');
|
|
}
|
|
|
|
$path = $file->storeAs(
|
|
'applications/'.$application->public_uuid,
|
|
$documentType.'-'.$file->hashName(),
|
|
'local',
|
|
);
|
|
|
|
if (! is_string($path)) {
|
|
throw new RuntimeException('Document upload failed.');
|
|
}
|
|
|
|
$application->documents()->create([
|
|
'document_type' => $documentType,
|
|
'disk' => 'local',
|
|
'path' => $path,
|
|
'original_name' => $file->getClientOriginalName(),
|
|
'mime_type' => $file->getClientMimeType() ?: $file->getMimeType(),
|
|
'size' => $file->getSize(),
|
|
]);
|
|
|
|
activity('public_application')
|
|
->performedOn($application)
|
|
->withProperties([
|
|
'document_type' => $documentType,
|
|
])
|
|
->log('application_document_uploaded');
|
|
}
|
|
}
|