authorize('viewAny', Investment::class); $perPage = min((int) $request->get('per_page', 10), 1000); $sortBy = (string) $request->get('sort_by', 'created_at'); $sortOrder = strtolower((string) $request->get('sort_order', 'desc')) === 'asc' ? 'asc' : 'desc'; $allowedSort = [ 'created_at', 'amount', 'status', 'source', 'reference_no', 'completed_at', ]; if (! in_array($sortBy, $allowedSort, true)) { $sortBy = 'created_at'; } $query = Investment::query() ->with([ 'user:id,name,email,ic_number,member_number', 'investmentType:id,code,name', ]) ->orderBy($sortBy, $sortOrder); if ($search = trim((string) $request->get('search', ''))) { $query->where(function ($q) use ($search) { $q->where('reference_no', 'ILIKE', "%{$search}%") ->orWhere('remarks', 'ILIKE', "%{$search}%") ->orWhereHas('user', function ($userQuery) use ($search) { $userQuery->where('name', 'ILIKE', "%{$search}%") ->orWhere('email', 'ILIKE', "%{$search}%") ->orWhere('ic_number', 'ILIKE', "%{$search}%"); }) ->orWhereHas('investmentType', function ($typeQuery) use ($search) { $typeQuery->where('name', 'ILIKE', "%{$search}%") ->orWhere('code', 'ILIKE', "%{$search}%"); }); }); } if ($status = $request->query('status')) { $query->where('status', $status); } if ($source = $request->query('source')) { $query->where('source', $source); } if ($userId = $request->query('user_id')) { $query->where('user_id', $userId); } if ($typeId = $request->query('investment_type_id')) { $query->where('investment_type_id', $typeId); } $investments = $query->paginate($perPage); return response()->json([ 'success' => true, 'data' => InvestmentResource::collection($investments->items()), 'pagination' => [ 'current_page' => $investments->currentPage(), 'per_page' => $investments->perPage(), 'total' => $investments->total(), 'last_page' => $investments->lastPage(), 'from' => $investments->firstItem(), 'to' => $investments->lastItem(), 'has_more_pages' => $investments->hasMorePages(), ], 'message' => 'Pelaburan berjaya dimuatkan', ]); } public function show(string $id): JsonResponse { $this->authorize('view', Investment::class); $investment = Investment::query() ->with([ 'user:id,name,email,ic_number,member_number', 'account', 'investmentType', 'createdBy:id,name,email', 'approvedBy:id,name,email', 'ledgerEntries', 'payment.billplzTransaction', ]) ->find($id); if (! $investment) { return response()->json([ 'success' => false, 'message' => 'Pelaburan tidak dijumpai.', ], 404); } return response()->json([ 'success' => true, 'data' => new InvestmentResource($investment), 'message' => 'Pelaburan berjaya dimuatkan', ]); } public function storeManual(ManualInvestmentRequest $request): JsonResponse { $this->authorize('createManual', Investment::class); $validated = $request->validated(); $investment = $this->postingService->postManualInvestment( $validated['user_id'], $validated['investment_type_id'], $validated['amount'], $validated['remarks'] ?? null, $request->user(), ); $investment->loadMissing([ 'user:id,name,email,ic_number,member_number', 'investmentType:id,code,name', 'account', ]); return response()->json([ 'success' => true, 'data' => new InvestmentResource($investment), 'message' => 'Pelaburan manual berjaya direkodkan', ], 201); } }