220 lines
7.5 KiB
PHP
220 lines
7.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api\Badges;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Services\Badges\BadgeFormDataService;
|
|
use App\Services\Badges\BadgePdfService;
|
|
use App\Services\Badges\BadgePrintLogService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use Throwable;
|
|
|
|
class BadgeController extends Controller
|
|
{
|
|
public function __construct(
|
|
protected BadgePdfService $badgePdfService,
|
|
protected BadgePrintLogService $badgePrintLogService,
|
|
protected BadgeFormDataService $badgeFormDataService
|
|
) {}
|
|
|
|
public function generatePdf(Request $request)
|
|
{
|
|
$guard = $this->authenticatedUserIdOrUnauthorized();
|
|
if ($guard instanceof JsonResponse) {
|
|
return $guard;
|
|
}
|
|
|
|
$validator = Validator::make($request->all(), [
|
|
'user_ids' => ['nullable', 'array'],
|
|
'user_ids.*' => ['integer', 'exists:users,id'],
|
|
'student_ids' => ['nullable', 'array'],
|
|
'student_ids.*' => ['integer', 'exists:students,id'],
|
|
'school_year' => ['nullable', 'string', 'max:50'],
|
|
'roles' => ['nullable', 'array'],
|
|
'classes' => ['nullable', 'array'],
|
|
]);
|
|
|
|
$validator->after(function ($validator): void {
|
|
$data = $validator->getData();
|
|
$users = array_values(array_filter((array) ($data['user_ids'] ?? []), static fn ($v) => (int) $v > 0));
|
|
$students = array_values(array_filter((array) ($data['student_ids'] ?? []), static fn ($v) => (int) $v > 0));
|
|
if ($users === [] && $students === []) {
|
|
$validator->errors()->add('user_ids', 'Provide at least one user id or student id.');
|
|
}
|
|
});
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json([
|
|
'message' => 'Validation failed.',
|
|
'errors' => $validator->errors(),
|
|
], 422);
|
|
}
|
|
|
|
$data = $validator->validated();
|
|
|
|
return $this->badgePdfService->generate(
|
|
studentIds: $data['student_ids'] ?? [],
|
|
userIds: $data['user_ids'] ?? [],
|
|
schoolYear: $data['school_year'] ?? null,
|
|
rolesMap: $data['roles'] ?? [],
|
|
classesMap: $data['classes'] ?? [],
|
|
actorId: $guard
|
|
);
|
|
}
|
|
|
|
public function printStatus(Request $request): JsonResponse
|
|
{
|
|
try {
|
|
return response()->json([
|
|
'ok' => true,
|
|
'data' => $this->badgePrintLogService->getStatus(
|
|
$this->parseCombinedBadgeIds($request),
|
|
$request->input('school_year')
|
|
),
|
|
]);
|
|
} catch (Throwable) {
|
|
return response()->json([
|
|
'ok' => false,
|
|
'error' => 'Failed to query status',
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
public function logPrint(Request $request): JsonResponse
|
|
{
|
|
try {
|
|
$guard = $this->authenticatedUserIdOrUnauthorized();
|
|
if ($guard instanceof JsonResponse) {
|
|
return $guard;
|
|
}
|
|
|
|
$validator = Validator::make($request->all(), [
|
|
'user_ids' => ['nullable', 'array'],
|
|
'user_ids.*' => ['integer', 'exists:users,id'],
|
|
'student_ids' => ['nullable', 'array'],
|
|
'student_ids.*' => ['integer', 'exists:students,id'],
|
|
'school_year' => ['nullable', 'string', 'max:50'],
|
|
'roles' => ['nullable', 'array'],
|
|
'classes' => ['nullable', 'array'],
|
|
]);
|
|
|
|
$validator->after(function ($validator): void {
|
|
$data = $validator->getData();
|
|
$users = array_values(array_filter((array) ($data['user_ids'] ?? []), static fn ($v) => (int) $v > 0));
|
|
$students = array_values(array_filter((array) ($data['student_ids'] ?? []), static fn ($v) => (int) $v > 0));
|
|
if ($users === [] && $students === []) {
|
|
$validator->errors()->add('user_ids', 'Provide at least one user id or student id.');
|
|
}
|
|
});
|
|
|
|
if ($validator->fails()) {
|
|
return response()->json([
|
|
'message' => 'Validation failed.',
|
|
'errors' => $validator->errors(),
|
|
], 422);
|
|
}
|
|
|
|
$data = $validator->validated();
|
|
|
|
$inserted = $this->badgePrintLogService->log(
|
|
userIds: array_values(array_unique(array_merge(
|
|
$data['user_ids'] ?? [],
|
|
$data['student_ids'] ?? []
|
|
))),
|
|
actorId: $guard,
|
|
schoolYear: $data['school_year'] ?? null,
|
|
rolesMap: $data['roles'] ?? [],
|
|
classesMap: $data['classes'] ?? []
|
|
);
|
|
|
|
return response()->json([
|
|
'ok' => true,
|
|
'inserted' => $inserted,
|
|
]);
|
|
} catch (Throwable $e) {
|
|
return response()->json([
|
|
'ok' => false,
|
|
'error' => $e->getMessage(),
|
|
], 500);
|
|
}
|
|
}
|
|
|
|
public function formData(Request $request): JsonResponse
|
|
{
|
|
return response()->json([
|
|
'ok' => true,
|
|
'data' => $this->badgeFormDataService->build(
|
|
schoolYear: $request->input('school_year'),
|
|
selectedUserIds: $this->parseStaffUserIds($request),
|
|
selectedStudentIds: $this->parseStudentIds($request),
|
|
activeRole: $request->input('active_role')
|
|
),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Staff user IDs for the badge picker (`users.id`).
|
|
*
|
|
* @return int[]
|
|
*/
|
|
private function parseStaffUserIds(Request $request): array
|
|
{
|
|
$ids = $request->input('user_ids', $request->query('user_ids', []));
|
|
|
|
if (is_string($ids)) {
|
|
$ids = array_filter(array_map('trim', explode(',', $ids)), 'strlen');
|
|
} elseif (! is_array($ids)) {
|
|
$ids = $ids ? [$ids] : [];
|
|
}
|
|
|
|
$ids = array_values(array_unique(array_map(static fn ($v) => (int) $v, $ids)));
|
|
|
|
return array_values(array_filter($ids, static fn ($v) => $v > 0));
|
|
}
|
|
|
|
/**
|
|
* Combined `users.id` and `students.id` for print-status (same numeric space as stored in logs).
|
|
*
|
|
* @return int[]
|
|
*/
|
|
private function parseCombinedBadgeIds(Request $request): array
|
|
{
|
|
return array_values(array_unique(array_merge(
|
|
$this->parseStaffUserIds($request),
|
|
$this->parseStudentIds($request)
|
|
)));
|
|
}
|
|
|
|
/**
|
|
* Student primary keys (`students.id`) from query or body.
|
|
*
|
|
* @return int[]
|
|
*/
|
|
private function parseStudentIds(Request $request): array
|
|
{
|
|
$ids = $request->input('student_ids', $request->query('student_ids', []));
|
|
|
|
if (is_string($ids)) {
|
|
$ids = array_filter(array_map('trim', explode(',', $ids)), 'strlen');
|
|
} elseif (! is_array($ids)) {
|
|
$ids = $ids ? [$ids] : [];
|
|
}
|
|
|
|
$ids = array_values(array_unique(array_map(static fn ($v) => (int) $v, $ids)));
|
|
|
|
return array_values(array_filter($ids, static fn ($v) => $v > 0));
|
|
}
|
|
|
|
private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
|
|
{
|
|
$userId = (int) (auth()->id() ?? 0);
|
|
if ($userId <= 0) {
|
|
return response()->json(['ok' => false, 'message' => 'Unauthorized.'], 401);
|
|
}
|
|
|
|
return $userId;
|
|
}
|
|
}
|