validated(); $result = $this->charges->listForParent( (int) $payload['parent_id'], $payload['school_year'] ?? null ); return response()->json([ 'ok' => true, 'charges' => new ChargeListResource($result), ]); } public function storeExtra(StoreExtraChargeRequest $request): JsonResponse { $guard = $this->authenticatedUserIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $payload = $request->validated(); $payload['created_by'] = $guard; try { $result = $this->charges->createExtraCharge($payload); } catch (\Throwable $e) { Log::error('Store extra charge failed', ['exception' => $e]); return response()->json(['ok' => false, 'message' => 'Unable to create extra charge.'], 500); } $status = isset($result['error']) && $result['error'] === 'duplicate_charge' ? 409 : (($result['ok'] ?? false) ? 201 : 422); return response()->json([ 'ok' => (bool) ($result['ok'] ?? false), 'charge' => new ChargeActionResource($result), ], $status); } public function storeEvent(StoreEventChargeRequest $request): JsonResponse { $guard = $this->authenticatedUserIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $payload = $request->validated(); $payload['created_by'] = $guard; try { $result = $this->charges->createEventCharge($payload); } catch (\Throwable $e) { Log::error('Store event charge failed', ['exception' => $e]); return response()->json(['ok' => false, 'message' => 'Unable to create event charge.'], 500); } $status = isset($result['error']) && $result['error'] === 'duplicate_charge' ? 409 : (($result['ok'] ?? false) ? 201 : 422); return response()->json([ 'ok' => (bool) ($result['ok'] ?? false), 'charge' => new ChargeActionResource($result), ], $status); } public function cancelExtra(int $id): JsonResponse { $result = $this->charges->cancelExtraCharge($id); $status = ($result['ok'] ?? false) ? 200 : 422; return response()->json([ 'ok' => (bool) ($result['ok'] ?? false), 'charge' => new ChargeActionResource($result), ], $status); } public function applyExtra(ApplyExtraChargeRequest $request, int $id): JsonResponse { $payload = $request->validated(); $result = $this->charges->applyExtraCharge($id, (int) $payload['invoice_id']); $status = ($result['ok'] ?? false) ? 200 : 422; return response()->json([ 'ok' => (bool) ($result['ok'] ?? false), 'charge' => new ChargeActionResource($result), ], $status); } public function cancelEvent(Request $request, int $id): JsonResponse { $issueCredit = $request->boolean('issue_credit', true); $result = $this->charges->cancelEventCharge($id, $issueCredit); $status = ($result['ok'] ?? false) ? 200 : 422; return response()->json([ 'ok' => (bool) ($result['ok'] ?? false), 'charge' => new ChargeActionResource($result), ], $status); } public function markEventPaid(MarkEventChargePaidRequest $request, int $id): JsonResponse { $payload = $request->validated(); $result = $this->charges->markEventChargePaid( $id, (bool) $payload['paid'], isset($payload['payment_id']) ? (int) $payload['payment_id'] : null ); $status = ($result['ok'] ?? false) ? 200 : 422; return response()->json([ 'ok' => (bool) ($result['ok'] ?? false), 'charge' => new ChargeActionResource($result), ], $status); } private function authenticatedUserIdOrUnauthorized(): int|JsonResponse { $userId = (int) (auth()->id() ?? 0); if ($userId <= 0) { return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401); } return $userId; } }