940afe9319
API CI/CD / Validate (composer + pint) (push) Successful in 2m7s
API CI/CD / Test (PHPUnit) (push) Failing after 2m23s
API CI/CD / Build frontend assets (push) Successful in 2m18s
API CI/CD / Security audit (push) Successful in 31s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
321 lines
11 KiB
PHP
321 lines
11 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();
|
|
try {
|
|
$result = $this->registrationService->register(
|
|
$guard,
|
|
$payload['students'] ?? [],
|
|
$payload['emergency_contacts'] ?? []
|
|
);
|
|
} catch (\RuntimeException $e) {
|
|
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
|
|
}
|
|
|
|
$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;
|
|
}
|
|
|
|
try {
|
|
$this->registrationService->deleteStudent($guard, $studentId);
|
|
} catch (\RuntimeException $e) {
|
|
return response()->json(['ok' => false, 'message' => $e->getMessage()], 422);
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|