Files
alrahma_sunday_school_api/app/Http/Controllers/Api/Parents/ParentController.php
T
2026-06-11 11:46:12 -04:00

313 lines
10 KiB
PHP

<?php
namespace App\Http\Controllers\Api\Parents;
use App\Http\Controllers\Api\Core\BaseApiController;
use App\Http\Requests\Parents\ParentAttendanceRequest;
use App\Http\Requests\Parents\ParentEmergencyContactRequest;
use App\Http\Requests\Parents\ParentEnrollmentActionRequest;
use App\Http\Requests\Parents\ParentEnrollmentRequest;
use App\Http\Requests\Parents\ParentEventParticipationRequest;
use App\Http\Requests\Parents\ParentInvoiceRequest;
use App\Http\Requests\Parents\ParentProfileUpdateRequest;
use App\Http\Requests\Parents\ParentRegistrationRequest;
use App\Http\Requests\Parents\ParentStudentUpdateRequest;
use App\Http\Resources\Invoices\InvoiceResource;
use App\Http\Resources\Parents\ParentAttendanceResource;
use App\Http\Resources\Parents\ParentEmergencyContactResource;
use App\Http\Resources\Parents\ParentStudentResource;
use App\Services\Parents\ParentAttendanceService;
use App\Services\Parents\ParentEmergencyContactService;
use App\Services\Parents\ParentEnrollmentService;
use App\Services\Parents\ParentEventParticipationService;
use App\Services\Parents\ParentInvoiceService;
use App\Services\Parents\ParentProfileService;
use App\Services\Parents\ParentRegistrationService;
use Illuminate\Http\JsonResponse;
class ParentController extends BaseApiController
{
public function __construct(
private ParentAttendanceService $attendanceService,
private ParentInvoiceService $invoiceService,
private ParentEnrollmentService $enrollmentService,
private ParentRegistrationService $registrationService,
private ParentEmergencyContactService $emergencyContactService,
private ParentProfileService $profileService,
private ParentEventParticipationService $eventService
) {
parent::__construct();
}
public function attendance(ParentAttendanceRequest $request): JsonResponse
{
$guard = $this->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;
}
}