320 lines
12 KiB
PHP
320 lines
12 KiB
PHP
<?php
|
|
|
|
namespace Modules\MembershipApplication\Http\Controllers;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Services\DocumentService;
|
|
use App\Services\LetterService;
|
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Http\Response;
|
|
use Modules\MembershipApplication\Entities\MembershipApplication;
|
|
use Modules\MembershipApplication\Enums\ApplicationStatus;
|
|
use Modules\MembershipApplication\Enums\BoardDecision;
|
|
use Modules\MembershipApplication\Enums\BoardResult;
|
|
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;
|
|
use Modules\MembershipApplication\Http\Requests\UploadMembershipApplicationDocumentRequest;
|
|
use Modules\MembershipApplication\Services\MembershipApplicationService;
|
|
use Modules\MembershipApplication\Transformers\MembershipApplicationDocumentResource;
|
|
use Modules\MembershipApplication\Transformers\MembershipApplicationListResource;
|
|
use Modules\MembershipApplication\Transformers\MembershipApplicationResource;
|
|
use Symfony\Component\HttpFoundation\StreamedResponse;
|
|
|
|
class MembershipApplicationController extends Controller
|
|
{
|
|
use AuthorizesRequests;
|
|
|
|
public function __construct(
|
|
protected MembershipApplicationService $membershipApplicationService,
|
|
protected DocumentService $documentService,
|
|
protected LetterService $letterService,
|
|
) {}
|
|
|
|
public function index(Request $request): JsonResponse
|
|
{
|
|
$this->authorize('viewAny', MembershipApplication::class);
|
|
|
|
$perPage = min((int) $request->get('per_page', 10), 100);
|
|
$search = (string) ($request->get('search', '') ?? '');
|
|
$status = $request->get('status');
|
|
$sortBy = (string) ($request->get('sort_by', 'submitted_at') ?? 'submitted_at');
|
|
$sortOrder = (string) ($request->get('sort_order', 'desc') ?? 'desc');
|
|
|
|
$applications = $this->membershipApplicationService->getPaginatedList(
|
|
$perPage,
|
|
$search,
|
|
$status,
|
|
$sortBy,
|
|
$sortOrder
|
|
);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => MembershipApplicationListResource::collection($applications->items()),
|
|
'pagination' => [
|
|
'current_page' => $applications->currentPage(),
|
|
'per_page' => $applications->perPage(),
|
|
'total' => $applications->total(),
|
|
'last_page' => $applications->lastPage(),
|
|
'from' => $applications->firstItem(),
|
|
'to' => $applications->lastItem(),
|
|
'has_more_pages' => $applications->hasMorePages(),
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function show(MembershipApplication $membershipApplication): JsonResponse
|
|
{
|
|
$this->authorize('view', $membershipApplication);
|
|
|
|
$application = $this->membershipApplicationService->getByIdWithRelations($membershipApplication->id);
|
|
|
|
if (! $application) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Permohonan tidak dijumpai.',
|
|
], 404);
|
|
}
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => new MembershipApplicationResource($application),
|
|
]);
|
|
}
|
|
|
|
public function update(UpdateMembershipApplicationRequest $request, MembershipApplication $membershipApplication): JsonResponse
|
|
{
|
|
$this->authorize('update', $membershipApplication);
|
|
|
|
$application = $this->membershipApplicationService->update(
|
|
$membershipApplication,
|
|
$request->validated(),
|
|
);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Permohonan keahlian berjaya dikemaskini.',
|
|
'data' => new MembershipApplicationResource($application),
|
|
]);
|
|
}
|
|
|
|
public function uploadDocument(UploadMembershipApplicationDocumentRequest $request, MembershipApplication $membershipApplication): JsonResponse
|
|
{
|
|
$this->authorize('update', $membershipApplication);
|
|
|
|
$application = $this->membershipApplicationService->uploadDocument(
|
|
$membershipApplication,
|
|
$request->validated('type'),
|
|
$request->file('file'),
|
|
);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Dokumen berjaya dimuat naik.',
|
|
'data' => new MembershipApplicationResource($application),
|
|
]);
|
|
}
|
|
|
|
public function managementReview(ManagementReviewRequest $request, MembershipApplication $membershipApplication): JsonResponse {
|
|
$this->authorize('managementReview', $membershipApplication);
|
|
|
|
$application = $this->membershipApplicationService->managementReview(
|
|
$membershipApplication,
|
|
ManagementDecision::from($request->validated('decision')),
|
|
$request->validated('remarks'),
|
|
$request->user()
|
|
);
|
|
|
|
$message = $application->status === ApplicationStatus::PendingBoard
|
|
? 'Permohonan diluluskan dan dihantar ke lembaga.'
|
|
: 'Permohonan ditolak.';
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => $message,
|
|
'data' => new MembershipApplicationResource($application),
|
|
]);
|
|
}
|
|
|
|
public function boardReview(BoardReviewRequest $request, MembershipApplication $membershipApplication): JsonResponse {
|
|
$this->authorize('boardReview', $membershipApplication);
|
|
|
|
$application = $this->membershipApplicationService->boardReview(
|
|
$membershipApplication,
|
|
BoardDecision::from($request->validated('decision')),
|
|
$request->validated('remarks'),
|
|
$request->user()
|
|
);
|
|
|
|
$message = $application->board_result === BoardResult::Pass->value
|
|
? 'Permohonan lulus semakan lembaga.'
|
|
: 'Permohonan gagal semakan lembaga.';
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => $message,
|
|
'data' => new MembershipApplicationResource($application),
|
|
]);
|
|
}
|
|
|
|
public function assignReferences(AssignReferencesRequest $request, MembershipApplication $membershipApplication): JsonResponse {
|
|
$this->authorize('assignReferences', $membershipApplication);
|
|
|
|
$application = $this->membershipApplicationService->assignReferences(
|
|
$membershipApplication,
|
|
$request->validated(),
|
|
$request->user()
|
|
);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Pencadang dan penyokong berjaya dikemaskini.',
|
|
'data' => new MembershipApplicationResource($application),
|
|
]);
|
|
}
|
|
|
|
public function complete(CompleteMembershipApplicationRequest $request, MembershipApplication $membershipApplication): JsonResponse
|
|
{
|
|
$this->authorize('complete', $membershipApplication);
|
|
|
|
$application = $this->membershipApplicationService->complete(
|
|
$membershipApplication,
|
|
$request->user(),
|
|
$request->validated('board_meeting_reference'),
|
|
);
|
|
|
|
$message = $application->board_result === BoardResult::Pass->value
|
|
? '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,
|
|
'message' => $message,
|
|
'data' => new MembershipApplicationResource($application),
|
|
]);
|
|
}
|
|
|
|
public function batchComplete(BatchCompleteRequest $request): JsonResponse
|
|
{
|
|
$this->authorize('completeBatch', MembershipApplication::class);
|
|
|
|
$result = $this->membershipApplicationService->completeBatch(
|
|
$request->validated('application_ids'),
|
|
$request->user(),
|
|
$request->validated('board_meeting_reference'),
|
|
);
|
|
|
|
$succeededCount = count($result['succeeded']);
|
|
$failedCount = count($result['failed']);
|
|
|
|
if ($succeededCount === 0) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'message' => 'Tiada permohonan berjaya diselesaikan.',
|
|
'data' => [
|
|
'succeeded' => [],
|
|
'failed' => $result['failed'],
|
|
],
|
|
], 422);
|
|
}
|
|
|
|
$message = $failedCount > 0
|
|
? "{$succeededCount} permohonan berjaya, {$failedCount} gagal."
|
|
: "{$succeededCount} permohonan berjaya diselesaikan.";
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => $message,
|
|
'data' => [
|
|
'succeeded' => MembershipApplicationResource::collection($result['succeeded']),
|
|
'failed' => $result['failed'],
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function downloadDocument(MembershipApplication $membershipApplication, string $documentId): StreamedResponse {
|
|
$this->authorize('view', $membershipApplication);
|
|
|
|
$document = $membershipApplication->documents()->findOrFail($documentId);
|
|
|
|
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);
|
|
|
|
$application = $this->membershipApplicationService->generateResultLetter(
|
|
$membershipApplication,
|
|
$request->validated('board_meeting_reference'),
|
|
);
|
|
|
|
$resultLetter = $application->documents
|
|
->firstWhere('type', MembershipApplication::RESULT_LETTER_DOCUMENT_TYPE);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Surat keputusan berjaya dijana.',
|
|
'data' => [
|
|
'application' => new MembershipApplicationResource($application),
|
|
'document' => $resultLetter
|
|
? new MembershipApplicationDocumentResource($resultLetter)
|
|
: null,
|
|
],
|
|
]);
|
|
}
|
|
|
|
public function approvedLetter(Request $request, MembershipApplication $membershipApplication): Response
|
|
{
|
|
$this->authorize('view', $membershipApplication);
|
|
|
|
$application = $this->membershipApplicationService->getByIdWithRelations($membershipApplication->id);
|
|
|
|
if (! $application) {
|
|
abort(404, 'Permohonan tidak dijumpai.');
|
|
}
|
|
|
|
$boardMeetingReference = (string) $request->query(
|
|
'board_meeting_reference',
|
|
'Mesyuarat Lembaga',
|
|
);
|
|
|
|
$view = 'membershipapplication::pdf.approved-letter';
|
|
$data = $this->membershipApplicationService->getResultLetterViewData(
|
|
$application,
|
|
$boardMeetingReference,
|
|
);
|
|
$format = $request->query('format', 'html');
|
|
$filename = 'surat-keputusan-'.$application->application_number.'.pdf';
|
|
|
|
if ($format === 'pdf') {
|
|
return $this->letterService->pdfResponse($view, $data, $filename);
|
|
}
|
|
|
|
return $this->letterService->htmlResponse($view, $data);
|
|
}
|
|
}
|