DONE: membership application to generate letter along with member_number and attach to email, change to dropdown for company or job selection, redesign profile ui, change to incremental ids for jobs; WIP: member digital card

This commit is contained in:
ISMAIL MASSERAN
2026-07-06 09:37:08 +08:00
parent e77712105c
commit 61345e9cf0
59 changed files with 1538 additions and 9156 deletions
@@ -17,6 +17,7 @@ use Modules\MembershipApplication\Enums\ManagementDecision;
use Modules\MembershipApplication\Http\Requests\AssignReferencesRequest;
use Modules\MembershipApplication\Http\Requests\BatchCompleteRequest;
use Modules\MembershipApplication\Http\Requests\BoardReviewRequest;
use Modules\MembershipApplication\Http\Requests\CompleteMembershipApplicationRequest;
use Modules\MembershipApplication\Http\Requests\GenerateResultLetterRequest;
use Modules\MembershipApplication\Http\Requests\ManagementReviewRequest;
use Modules\MembershipApplication\Http\Requests\UpdateMembershipApplicationRequest;
@@ -180,18 +181,19 @@ class MembershipApplicationController extends Controller
]);
}
public function complete(Request $request, MembershipApplication $membershipApplication): JsonResponse
public function complete(CompleteMembershipApplicationRequest $request, MembershipApplication $membershipApplication): JsonResponse
{
$this->authorize('complete', $membershipApplication);
$application = $this->membershipApplicationService->complete(
$membershipApplication,
$request->user()
$request->user(),
$request->validated('board_meeting_reference'),
);
$message = $application->board_result === BoardResult::Pass->value
? 'Permohonan selesai. Akaun ahli telah dicipta dan e-mel dihantar.'
: 'Permohonan selesai. E-mel keputusan dihantar.';
? 'Permohonan selesai. Surat keputusan dijana, akaun ahli dicipta dan e-mel dihantar.'
: 'Permohonan selesai. Surat keputusan dijana dan e-mel dihantar.';
return response()->json([
'success' => true,
@@ -206,7 +208,8 @@ class MembershipApplicationController extends Controller
$result = $this->membershipApplicationService->completeBatch(
$request->validated('application_ids'),
$request->user()
$request->user(),
$request->validated('board_meeting_reference'),
);
$succeededCount = count($result['succeeded']);
@@ -245,6 +248,22 @@ class MembershipApplicationController extends Controller
return $this->documentService->downloadDocument($document->id);
}
public function deleteDocument(MembershipApplication $membershipApplication, string $documentId): JsonResponse
{
$this->authorize('update', $membershipApplication);
$application = $this->membershipApplicationService->deleteDocument(
$membershipApplication,
$documentId,
);
return response()->json([
'success' => true,
'message' => 'Lampiran pentadbir berjaya dipadam.',
'data' => new MembershipApplicationResource($application),
]);
}
public function generateResultLetter(GenerateResultLetterRequest $request, MembershipApplication $membershipApplication,): JsonResponse {
$this->authorize('generateResultLetter', $membershipApplication);
@@ -19,6 +19,7 @@ class BatchCompleteRequest extends FormRequest
return [
'application_ids' => 'required|array|min:1|max:100',
'application_ids.*' => 'required|uuid|distinct|exists:membership_applications,id',
'board_meeting_reference' => 'required|string|max:255',
];
}
@@ -33,6 +34,8 @@ class BatchCompleteRequest extends FormRequest
'application_ids.max' => 'Maksimum 100 permohonan setiap batch.',
'application_ids.*.exists' => 'Salah satu permohonan tidak dijumpai.',
'application_ids.*.distinct' => 'Permohonan duplikat tidak dibenarkan.',
'board_meeting_reference.required' => 'Rujukan mesyuarat lembaga diperlukan.',
'board_meeting_reference.max' => 'Rujukan mesyuarat lembaga tidak boleh melebihi 255 aksara.',
];
}
}
@@ -0,0 +1,34 @@
<?php
namespace Modules\MembershipApplication\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CompleteMembershipApplicationRequest extends FormRequest
{
public function authorize(): bool
{
return true;
}
/**
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
*/
public function rules(): array
{
return [
'board_meeting_reference' => 'required|string|max:255',
];
}
/**
* @return array<string, string>
*/
public function messages(): array
{
return [
'board_meeting_reference.required' => 'Rujukan mesyuarat lembaga diperlukan.',
'board_meeting_reference.max' => 'Rujukan mesyuarat lembaga tidak boleh melebihi 255 aksara.',
];
}
}
@@ -48,7 +48,7 @@ class StoreMembershipApplicationRequest extends FormRequest
'documents.ic_copy' => 'required|file|mimes:pdf,jpg,jpeg,png|max:10240',
'documents.photo' => 'nullable|file|mimes:jpg,jpeg,png|max:10240',
'documents.salary_slip' => 'nullable|file|mimes:pdf,jpg,jpeg,png|max:10240',
'documents.employer_letter' => 'nullable|file|mimes:pdf,jpg,jpeg,png|max:10240',
'documents.employer_letter' => 'required|file|mimes:pdf,jpg,jpeg,png|max:10240',
];
}
@@ -89,6 +89,8 @@ class StoreMembershipApplicationRequest extends FormRequest
'documents.ic_copy.required' => 'Salinan kad pengenalan diperlukan.',
'documents.ic_copy.mimes' => 'Salinan kad pengenalan mestilah PDF, JPG, JPEG atau PNG.',
'documents.employer_letter.required' => 'Surat pengesahan majikan diperlukan.',
'documents.employer_letter.mimes' => 'Surat pengesahan majikan mestilah PDF, JPG, JPEG atau PNG.',
];
}
}
@@ -4,6 +4,7 @@ namespace Modules\MembershipApplication\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
use Modules\MembershipApplication\Entities\MembershipApplication;
class UploadMembershipApplicationDocumentRequest extends FormRequest
{
@@ -18,7 +19,13 @@ class UploadMembershipApplicationDocumentRequest extends FormRequest
public function rules(): array
{
return [
'type' => ['required', Rule::in(['ic_copy', 'photo', 'salary_slip', 'employer_letter'])],
'type' => ['required', Rule::in([
'ic_copy',
'photo',
'salary_slip',
'employer_letter',
MembershipApplication::ADMIN_ATTACHMENT_DOCUMENT_TYPE,
])],
'file' => [
'required',
'file',