parentIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $data = $this->attendanceService->listAttendance($guard, $request->validated()['school_year'] ?? null); return response()->json([ 'ok' => true, 'attendance' => ParentAttendanceResource::collection($data['attendance']), 'schoolYears' => $data['schoolYears'], 'selectedYear' => $data['selectedYear'], ]); } public function invoices(ParentInvoiceRequest $request): JsonResponse { $guard = $this->parentIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $schoolYear = $request->validated()['school_year'] ?? null; $rows = $this->invoiceService->listInvoices($guard, $schoolYear); return response()->json([ 'ok' => true, 'invoices' => InvoiceResource::collection($rows), ]); } public function enrollments(ParentEnrollmentRequest $request): JsonResponse { $guard = $this->parentIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $data = $this->enrollmentService->overview($guard, $request->validated()['school_year'] ?? null); return response()->json([ 'ok' => true, 'students' => ParentStudentResource::collection($data['students']), 'schoolYears' => $data['schoolYears'], 'selectedYear' => $data['selectedYear'], 'withdrawalDeadline' => $data['withdrawalDeadline'], 'lastDayOfRegistration' => $data['lastDayOfRegistration'], 'schoolStartDate' => $data['schoolStartDate'], ]); } public function updateEnrollments(ParentEnrollmentActionRequest $request): JsonResponse { $guard = $this->parentIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $payload = $request->validated(); $result = $this->enrollmentService->updateEnrollment( $guard, $payload['enroll'] ?? [], $payload['withdraw'] ?? [] ); return response()->json([ 'ok' => true, 'enrolled' => $result['enrolled'], 'withdrawn' => $result['withdrawn'], ]); } public function registration(): JsonResponse { $guard = $this->parentIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $data = $this->registrationService->overview($guard); return response()->json([ 'ok' => true, 'parent' => $data['parent'], 'existingKids' => ParentStudentResource::collection($data['existingKids']), 'emergencies' => ParentEmergencyContactResource::collection($data['emergencies']), 'maxChilds' => $data['maxChilds'], 'maxEmergency' => $data['maxEmergency'], 'lastDayOfRegistration' => $data['lastDayOfRegistration'], 'registrationAgeDeadline' => $data['registrationAgeDeadline'], ]); } public function storeRegistration(ParentRegistrationRequest $request): JsonResponse { $guard = $this->parentIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $payload = $request->validated(); $result = $this->registrationService->register( $guard, $payload['students'] ?? [], $payload['emergency_contacts'] ?? [] ); $createdCount = count($result['created_student_ids']); $skipped = $result['skipped'] ?? []; return response()->json([ 'ok' => true, 'created_student_ids' => $result['created_student_ids'], 'skipped' => $skipped, ], $createdCount > 0 ? 201 : 200); } public function updateStudent(ParentStudentUpdateRequest $request, int $studentId): JsonResponse { $guard = $this->parentIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $this->registrationService->updateStudent($guard, $studentId, $request->validated()); return response()->json(['ok' => true]); } public function deleteStudent(int $studentId): JsonResponse { $guard = $this->parentIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $this->registrationService->deleteStudent($guard, $studentId); return response()->json(['ok' => true]); } public function emergencyContacts(): JsonResponse { $guard = $this->parentIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $rows = $this->emergencyContactService->list($guard); return response()->json([ 'ok' => true, 'contacts' => ParentEmergencyContactResource::collection($rows), ]); } public function storeEmergencyContact(ParentEmergencyContactRequest $request): JsonResponse { $guard = $this->parentIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $contact = $this->emergencyContactService->store($guard, $request->validated()); return response()->json([ 'ok' => true, 'contact' => new ParentEmergencyContactResource($contact), ], 201); } public function updateEmergencyContact(ParentEmergencyContactRequest $request, int $contactId): JsonResponse { $guard = $this->parentIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $contact = $this->emergencyContactService->update($guard, $contactId, $request->validated()); return response()->json([ 'ok' => true, 'contact' => new ParentEmergencyContactResource($contact), ]); } public function profile(): JsonResponse { $guard = $this->parentIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $profile = $this->profileService->getProfile($guard); return response()->json([ 'ok' => true, 'profile' => $profile, ]); } public function updateProfile(ParentProfileUpdateRequest $request): JsonResponse { $guard = $this->parentIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $profile = $this->profileService->updateProfile($guard, $request->validated()); return response()->json([ 'ok' => true, 'profile' => $profile, ]); } public function events(): JsonResponse { $guard = $this->parentIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $data = $this->eventService->overview($guard); return response()->json([ 'ok' => true, 'activeEvents' => $data['activeEvents'], 'charges' => $data['charges'], 'yourStudents' => $data['yourStudents'], ]); } public function updateParticipation(ParentEventParticipationRequest $request): JsonResponse { $guard = $this->parentIdOrUnauthorized(); if ($guard instanceof JsonResponse) { return $guard; } $this->eventService->updateParticipation($guard, $request->validated()['participation'] ?? []); return response()->json(['ok' => true]); } /** * @return int|JsonResponse Effective primary-parent user id, or 401 JSON for this controller's legacy `{ ok }` shape. * * `parent.access` middleware resolves second parents (user_type=secondary) * and authorized users (user_type=tertiary) to their primary parent and * stashes the result as `primary_parent_id` on the request. If we are * called outside that middleware we fall back to the authenticated id. */ private function parentIdOrUnauthorized(): int|JsonResponse { $request = request(); $primary = (int) ($request?->attributes?->get('primary_parent_id') ?? 0); if ($primary > 0) { return $primary; } $parentId = (int) (auth()->id() ?? 0); if ($parentId <= 0) { return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401); } return $parentId; } }