90f9857b06
API CI/CD / Validate (composer + pint) (push) Successful in 3m7s
API CI/CD / Test (PHPUnit) (push) Failing after 5m46s
API CI/CD / Build frontend assets (push) Successful in 1m2s
API CI/CD / Security audit (push) Failing after 49s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
124 lines
4.0 KiB
PHP
124 lines
4.0 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Family;
|
|
|
|
use App\Http\Controllers\Api\Core\BaseApiController;
|
|
use App\Http\Requests\Families\FamilyAdminCardRequest;
|
|
use App\Http\Requests\Families\FamilyAdminIndexRequest;
|
|
use App\Http\Requests\Families\FamilyAdminSearchRequest;
|
|
use App\Http\Requests\Families\FamilyComposeEmailRequest;
|
|
use App\Http\Resources\Families\FamilyResource;
|
|
use App\Http\Resources\Families\FamilySearchItemResource;
|
|
use App\Models\Configuration;
|
|
use App\Services\Families\FamilyNotificationService;
|
|
use App\Services\Families\FamilyQueryService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
class FamilyAdminController extends BaseApiController
|
|
{
|
|
public function __construct(
|
|
private FamilyQueryService $queryService,
|
|
private FamilyNotificationService $notificationService
|
|
) {
|
|
parent::__construct();
|
|
}
|
|
|
|
public function index(FamilyAdminIndexRequest $request): JsonResponse
|
|
{
|
|
$payload = $request->validated();
|
|
$schoolYear = $this->requestedSchoolYear($request, $payload);
|
|
|
|
$data = $this->queryService->adminIndexData(
|
|
$payload['student_id'] ?? null,
|
|
$payload['guardian_id'] ?? null,
|
|
$schoolYear
|
|
);
|
|
|
|
return $this->success([
|
|
'student' => $data['student'],
|
|
'families' => FamilyResource::collection($data['families']),
|
|
'guardians' => $data['guardians'],
|
|
'students' => $data['students'],
|
|
'searchStudents' => $data['searchStudents'],
|
|
'searchGuardians' => $data['searchGuardians'],
|
|
'resolved_student_id' => $data['resolved_student_id'],
|
|
]);
|
|
}
|
|
|
|
public function search(FamilyAdminSearchRequest $request): JsonResponse
|
|
{
|
|
$payload = $request->validated();
|
|
$items = $this->queryService->searchSuggestions(
|
|
(string) $payload['q'],
|
|
(int) ($payload['limit'] ?? 8)
|
|
);
|
|
|
|
return $this->success([
|
|
'items' => FamilySearchItemResource::collection($items),
|
|
]);
|
|
}
|
|
|
|
public function card(FamilyAdminCardRequest $request): JsonResponse
|
|
{
|
|
$payload = $request->validated();
|
|
$schoolYear = $this->requestedSchoolYear($request, $payload);
|
|
|
|
$family = $this->queryService->familyCard(
|
|
$payload['student_id'] ?? null,
|
|
$payload['guardian_id'] ?? null,
|
|
$payload['family_id'] ?? null,
|
|
$schoolYear
|
|
);
|
|
|
|
if (! $family) {
|
|
return $this->error('Family not found.', Response::HTTP_NOT_FOUND);
|
|
}
|
|
|
|
return $this->success(new FamilyResource($family));
|
|
}
|
|
|
|
private function requestedSchoolYear($request, array $payload): string
|
|
{
|
|
$candidates = [
|
|
$payload['school_year'] ?? null,
|
|
$request->query('school_year'),
|
|
$request->header('X-School-Year'),
|
|
$request->header('X-Selected-School-Year'),
|
|
Configuration::getConfig('school_year'),
|
|
];
|
|
|
|
foreach ($candidates as $candidate) {
|
|
$value = trim((string) ($candidate ?? ''));
|
|
if ($value !== '') {
|
|
return $value;
|
|
}
|
|
}
|
|
|
|
return '';
|
|
}
|
|
|
|
public function composeEmail(FamilyComposeEmailRequest $request): JsonResponse
|
|
{
|
|
$payload = $request->validated();
|
|
|
|
$ok = $this->notificationService->sendComposeEmail(
|
|
(string) $payload['recipient'],
|
|
(string) $payload['subject'],
|
|
(string) $payload['html_message'],
|
|
$payload['profile'] ?? null,
|
|
$payload['reply_to_email'] ?? null,
|
|
$payload['reply_to_name'] ?? null
|
|
);
|
|
|
|
if (! $ok) {
|
|
Log::warning('Compose email failed for family admin', ['recipient' => $payload['recipient']]);
|
|
|
|
return $this->error('Unable to send email.', Response::HTTP_INTERNAL_SERVER_ERROR);
|
|
}
|
|
|
|
return $this->success(['recipient' => $payload['recipient']], 'Email sent.');
|
|
}
|
|
}
|