update api and add more features
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api\Parents;
|
||||
|
||||
use App\Http\Controllers\Api\Core\BaseApiController;
|
||||
use App\Http\Requests\Promotions\ParentEnrollmentStepRequest;
|
||||
use App\Http\Requests\Promotions\ParentPromotionOverviewRequest;
|
||||
use App\Http\Resources\Promotions\StudentPromotionResource;
|
||||
use App\Models\Student;
|
||||
use App\Models\StudentPromotionRecord;
|
||||
use App\Services\Promotions\PromotionEnrollmentService;
|
||||
use App\Services\Promotions\PromotionQueryService;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Parent portal endpoints for the promotion + enrollment workflow
|
||||
* (plan section 12). The parent sees the promoted level and can step
|
||||
* through the enrollment checklist defined in plan section 8.
|
||||
*/
|
||||
class ParentPromotionController extends BaseApiController
|
||||
{
|
||||
public function __construct(
|
||||
private PromotionEnrollmentService $service,
|
||||
private PromotionQueryService $query
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
public function overview(ParentPromotionOverviewRequest $request): JsonResponse
|
||||
{
|
||||
$guard = $this->parentIdOrUnauthorized();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$data = $this->service->overviewForParent(
|
||||
$guard,
|
||||
$request->validated()['next_school_year'] ?? null
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'records' => $data['records'],
|
||||
'next_school_year' => $data['next_school_year'],
|
||||
'message' => $data['message'],
|
||||
]);
|
||||
}
|
||||
|
||||
public function show(int $promotionId): JsonResponse
|
||||
{
|
||||
$guard = $this->parentIdOrUnauthorized();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$record = $this->loadOwnedRecord($promotionId, $guard);
|
||||
if ($record instanceof JsonResponse) {
|
||||
return $record;
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => new StudentPromotionResource($this->query->detail($record)),
|
||||
]);
|
||||
}
|
||||
|
||||
public function start(int $promotionId): JsonResponse
|
||||
{
|
||||
$guard = $this->parentIdOrUnauthorized();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$record = $this->loadOwnedRecord($promotionId, $guard);
|
||||
if ($record instanceof JsonResponse) {
|
||||
return $record;
|
||||
}
|
||||
|
||||
try {
|
||||
$updated = $this->service->startEnrollment($record, $guard, $guard);
|
||||
} catch (\RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], Response::HTTP_CONFLICT);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => new StudentPromotionResource($this->query->detail($updated->refresh())),
|
||||
]);
|
||||
}
|
||||
|
||||
public function updateSteps(ParentEnrollmentStepRequest $request, int $promotionId): JsonResponse
|
||||
{
|
||||
$guard = $this->parentIdOrUnauthorized();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$record = $this->loadOwnedRecord($promotionId, $guard);
|
||||
if ($record instanceof JsonResponse) {
|
||||
return $record;
|
||||
}
|
||||
|
||||
try {
|
||||
$updated = $this->service->updateSteps($record, $guard, $request->steps(), $guard);
|
||||
} catch (\RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], Response::HTTP_CONFLICT);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => new StudentPromotionResource($this->query->detail($updated->refresh())),
|
||||
]);
|
||||
}
|
||||
|
||||
public function submit(int $promotionId): JsonResponse
|
||||
{
|
||||
$guard = $this->parentIdOrUnauthorized();
|
||||
if ($guard instanceof JsonResponse) {
|
||||
return $guard;
|
||||
}
|
||||
|
||||
$record = $this->loadOwnedRecord($promotionId, $guard);
|
||||
if ($record instanceof JsonResponse) {
|
||||
return $record;
|
||||
}
|
||||
|
||||
try {
|
||||
$updated = $this->service->submitEnrollment($record, $guard, $guard);
|
||||
} catch (\RuntimeException $e) {
|
||||
return response()->json(['ok' => false, 'message' => $e->getMessage()], Response::HTTP_CONFLICT);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'ok' => true,
|
||||
'data' => new StudentPromotionResource($this->query->detail($updated->refresh())),
|
||||
]);
|
||||
}
|
||||
|
||||
private function loadOwnedRecord(int $promotionId, int $parentId): StudentPromotionRecord|JsonResponse
|
||||
{
|
||||
$record = StudentPromotionRecord::query()->find($promotionId);
|
||||
if (!$record) {
|
||||
return response()->json(['ok' => false, 'message' => 'Promotion record not found.'], Response::HTTP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$owns = (int) $record->parent_id === $parentId;
|
||||
if (!$owns) {
|
||||
$studentParentId = (int) (Student::query()
|
||||
->where('id', $record->student_id)
|
||||
->value('parent_id') ?? 0);
|
||||
$owns = $studentParentId === $parentId;
|
||||
}
|
||||
if (!$owns) {
|
||||
return response()->json(['ok' => false, 'message' => 'You are not authorised to view this promotion record.'], Response::HTTP_FORBIDDEN);
|
||||
}
|
||||
return $record;
|
||||
}
|
||||
|
||||
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.'], Response::HTTP_UNAUTHORIZED);
|
||||
}
|
||||
return $parentId;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user