DONE: fix naming, add transaction for completion of membership application (#12)

Co-authored-by: ISMAIL MASSERAN <topaz@ISMAILs-Macbook.local>
Reviewed-on: KoPKB/My-KOPKB#12
This commit is contained in:
2026-07-15 11:35:45 +08:00
parent b05d04ca78
commit 3c52667eb5
4 changed files with 35 additions and 16 deletions
+8 -3
View File
@@ -4,6 +4,7 @@ APP_KEY=base64:XdMAy5IbQMHsTrp1N7Tn/LIJC4SKenN8CfhYLt1s3tk=
APP_DEBUG=false APP_DEBUG=false
APP_TIMEZONE=Asia/Kuala_Lumpur APP_TIMEZONE=Asia/Kuala_Lumpur
APP_URL=https://api.koppkb.com APP_URL=https://api.koppkb.com
FRONTEND_URL=https://mykopkb.koppkb.com
APP_LOCALE=en APP_LOCALE=en
APP_FALLBACK_LOCALE=en APP_FALLBACK_LOCALE=en
@@ -91,11 +92,15 @@ ENABLE_API_KEY_AUTH=true
API_VALID_KEYS=86f58825e5c1e0872d8786092d47e3bd,6461fc5390660c55dc47bdfcd85ed9ae API_VALID_KEYS=86f58825e5c1e0872d8786092d47e3bd,6461fc5390660c55dc47bdfcd85ed9ae
API_LOG_KEY_USAGE=true API_LOG_KEY_USAGE=true
PUBLIC_PROFILE_TOKEN_TTL_DAYS=7 AUTH_COOKIE_NAME=auth_token
FRONTEND_URL=https://mykopkb.koppkb.com AUTH_COOKIE_LIFETIME=360
AUTH_COOKIE_SECURE=true
AUTH_COOKIE_SAME_SITE=lax
AUTH_COOKIE_EXPOSE_TOKEN=false
BROWSERSHOT_NO_SANDBOX=true BROWSERSHOT_NO_SANDBOX=true
PUBLIC_PROFILE_TOKEN_TTL_DAYS=7 PUBLIC_PROFILE_TOKEN_TTL_DAYS=3
EMAIL_VERIFICATION_EXPIRE_MINUTES=60 EMAIL_VERIFICATION_EXPIRE_MINUTES=60
EMAIL_VERIFICATION_REDIRECT_PATH=/profile-overview-2 EMAIL_VERIFICATION_REDIRECT_PATH=/profile-overview-2
@@ -69,4 +69,13 @@ class MembershipApplicationReview extends Model
return BoardDecision::tryFrom($this->decision); return BoardDecision::tryFrom($this->decision);
} }
public function completionDecision(): ?BoardDecision
{
if ($this->stage !== ReviewStage::Completion) {
return null;
}
return BoardDecision::tryFrom($this->decision);
}
} }
@@ -6,4 +6,5 @@ enum ReviewStage: string
{ {
case Management = 'MANAGEMENT'; case Management = 'MANAGEMENT';
case Board = 'BOARD'; case Board = 'BOARD';
case Completion = 'COMPLETION';
} }
@@ -254,12 +254,8 @@ class MembershipApplicationService
}); });
} }
public function complete( public function complete(MembershipApplication $application, User $processedBy, string $boardMeetingReference, string $boardMeetingDate,): MembershipApplication
MembershipApplication $application, {
User $processedBy,
string $boardMeetingReference,
string $boardMeetingDate,
): MembershipApplication {
if ($application->status !== ApplicationStatus::PendingNotification) { if ($application->status !== ApplicationStatus::PendingNotification) {
throw ValidationException::withMessages([ throw ValidationException::withMessages([
'status' => ['Permohonan ini tidak boleh diselesaikan pada masa ini.'], 'status' => ['Permohonan ini tidak boleh diselesaikan pada masa ini.'],
@@ -272,7 +268,7 @@ class MembershipApplicationService
]); ]);
} }
return DB::transaction(function () use ($application, $boardMeetingReference, $boardMeetingDate) { return DB::transaction(function () use ($application, $processedBy, $boardMeetingReference, $boardMeetingDate) {
$plainPassword = null; $plainPassword = null;
if ($application->board_result === BoardResult::Pass->value && ! $application->user_id) { if ($application->board_result === BoardResult::Pass->value && ! $application->user_id) {
@@ -286,6 +282,18 @@ class MembershipApplicationService
$this->sendResultNotification($application, $resultLetter, $plainPassword); $this->sendResultNotification($application, $resultLetter, $plainPassword);
$application->reviews()->create([
'stage' => ReviewStage::Completion,
'decision' => $application->board_result,
'remarks' => sprintf(
'Rujukan mesyuarat lembaga: %s, Tarikh mesyuarat: %s',
$boardMeetingReference,
$boardMeetingDate,
),
'reviewer_id' => $processedBy->id,
'reviewed_at' => now(),
]);
$application->update([ $application->update([
'status' => ApplicationStatus::Completed, 'status' => ApplicationStatus::Completed,
'completed_at' => now()->toDateTimeString(), 'completed_at' => now()->toDateTimeString(),
@@ -302,12 +310,8 @@ class MembershipApplicationService
* failed: list<array{id: string, application_number: string|null, message: string}> * failed: list<array{id: string, application_number: string|null, message: string}>
* } * }
*/ */
public function completeBatch( public function completeBatch(array $applicationIds, User $processedBy, string $boardMeetingReference, string $boardMeetingDate): array
array $applicationIds, {
User $processedBy,
string $boardMeetingReference,
string $boardMeetingDate,
): array {
$succeeded = []; $succeeded = [];
$failed = []; $failed = [];