context->getSchoolYear(); $semester = $this->context->getSemester(); return response()->json([ 'ok' => true, 'schoolYear' => $schoolYear, 'semester' => $semester, 'retailors' => $this->retailors->listRetailors(), 'staff' => ExpenseStaffResource::collection($this->staff->listStaffUsers()), ]); } public function index(): JsonResponse { $rows = $this->queryService->listAll(); $rows = array_map(function ($row) { $row['receipt_url'] = $this->receiptService->receiptUrl($row['receipt_path'] ?? null); return $row; }, $rows); return response()->json([ 'ok' => true, 'expenses' => ExpenseResource::collection($rows), ]); } public function show(int $id): JsonResponse { $row = $this->queryService->findById($id); if (!$row) { return response()->json(['ok' => false, 'message' => 'Expense not found.'], 404); } $row['receipt_url'] = $this->receiptService->receiptUrl($row['receipt_path'] ?? null); return response()->json([ 'ok' => true, 'expense' => new ExpenseResource($row), ]); } public function store(StoreExpenseRequest $request): JsonResponse { $payload = $request->validated(); $userId = (int) (auth()->id() ?? 0); $receiptName = null; if ($request->hasFile('receipt')) { $receiptName = $this->receiptService->storeReceipt($request->file('receipt')); } $isDonation = $payload['category'] === 'Donation'; $expense = $this->writeService->store([ 'category' => $payload['category'], 'amount' => $payload['amount'], 'receipt_path' => $receiptName, 'description' => $payload['description'] ?? null, 'retailor' => $payload['retailor'] ?? null, 'date_of_purchase' => $payload['date_of_purchase'], 'purchased_by' => (int) $payload['purchased_by'], 'added_by' => $userId, 'status' => $isDonation ? 'approved' : 'pending', 'status_reason' => $isDonation ? 'Marked as Donation (non-reimbursable).' : null, 'approved_by' => $isDonation ? $userId : null, 'school_year' => $payload['school_year'] ?? null, 'semester' => $payload['semester'] ?? null, ]); return response()->json([ 'ok' => true, 'expense' => new ExpenseResource($expense->toArray()), ], 201); } public function update(UpdateExpenseRequest $request, int $id): JsonResponse { $expense = Expense::query()->find($id); if (!$expense) { return response()->json(['ok' => false, 'message' => 'Expense not found.'], 404); } $payload = $request->validated(); $userId = (int) (auth()->id() ?? 0); $receiptName = $expense->receipt_path; if ($request->hasFile('receipt')) { $receiptName = $this->receiptService->storeReceipt($request->file('receipt')); } if (!empty($payload['remove_receipt'])) { $receiptName = null; } $category = $payload['category']; $isDonation = $category === 'Donation'; $updateData = [ 'category' => $category, 'amount' => $payload['amount'], 'description' => $payload['description'] ?? null, 'retailor' => $payload['retailor'] ?? null, 'date_of_purchase' => $payload['date_of_purchase'], 'purchased_by' => (int) $payload['purchased_by'], 'receipt_path' => $receiptName, 'updated_by' => $userId, ]; if ($isDonation) { $updateData['status'] = 'approved'; $updateData['status_reason'] = 'Marked as Donation (non-reimbursable).'; $updateData['approved_by'] = $userId ?: null; $updateData['reimbursement_id'] = null; } elseif (($expense->category ?? '') === 'Donation') { $updateData['status_reason'] = null; $updateData['approved_by'] = $expense->approved_by; $updateData['status'] = $expense->status ?? 'pending'; } $updated = $this->writeService->update($expense, $updateData); return response()->json([ 'ok' => true, 'expense' => new ExpenseResource($updated->toArray()), ]); } public function updateStatus(UpdateExpenseStatusRequest $request, int $id): JsonResponse { $expense = Expense::query()->find($id); if (!$expense) { return response()->json(['ok' => false, 'message' => 'Expense not found.'], 404); } $payload = $request->validated(); $userId = (int) (auth()->id() ?? 0); $updated = $this->statusService->updateStatus($expense, $payload['status'], $payload['reason'] ?? '', $userId); return response()->json([ 'ok' => true, 'expense' => new ExpenseResource($updated->toArray()), ]); } }