Files
mykopkb-be/Modules/Investment/Http/Controllers/InvestmentController.php
T

211 lines
6.9 KiB
PHP

<?php
namespace Modules\Investment\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Services\DocumentService;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\UploadedFile;
use Modules\Investment\Entities\Investment;
use Modules\Investment\Http\Requests\ManualInvestmentRequest;
use Modules\Investment\Services\InvestmentPostingService;
use Modules\Investment\Services\InvestmentSummaryService;
use Modules\Investment\Transformers\InvestmentResource;
use Symfony\Component\HttpFoundation\StreamedResponse;
class InvestmentController extends Controller
{
use AuthorizesRequests;
public function __construct(
protected InvestmentPostingService $postingService,
protected InvestmentSummaryService $summaryService,
protected DocumentService $documentService,
) {}
public function summary(Request $request): JsonResponse
{
$this->authorize('viewOwnSummary', Investment::class);
$summary = $this->summaryService->getMemberSummary($request->user()->id);
return response()->json([
'success' => true,
'data' => $summary,
'message' => 'Ringkasan pelaburan berjaya dimuatkan',
]);
}
public function index(Request $request): JsonResponse
{
$this->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',
'documents',
])
->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();
$documents = collect($request->file('documents', []))
->filter(fn ($file) => $file instanceof UploadedFile)
->values()
->all();
$investment = $this->postingService->postManualInvestment(
$validated['user_id'],
$validated['investment_type_id'],
$validated['amount'],
$validated['remarks'] ?? null,
$request->user(),
);
foreach ($documents as $file) {
$this->documentService->validateFile($file);
$this->documentService->uploadDocument($investment, $file, 'attachment');
}
$investment->loadMissing([
'user:id,name,email,ic_number,member_number',
'investmentType:id,code,name',
'account',
'documents',
]);
return response()->json([
'success' => true,
'data' => new InvestmentResource($investment),
'message' => 'Pelaburan manual berjaya direkodkan',
], 201);
}
public function downloadDocument(string $id, string $documentId): StreamedResponse|JsonResponse
{
$this->authorize('view', Investment::class);
$investment = Investment::query()->find($id);
if (! $investment) {
return response()->json([
'success' => false,
'message' => 'Pelaburan tidak dijumpai.',
], 404);
}
$document = $investment->documents()->find($documentId);
if (! $document) {
return response()->json([
'success' => false,
'message' => 'Dokumen tidak dijumpai.',
], 404);
}
return $this->documentService->downloadDocument($document->id);
}
}