109 lines
3.9 KiB
PHP
109 lines
3.9 KiB
PHP
<?php
|
|
|
|
namespace App\Modules\Dashboard\Controllers;
|
|
|
|
use App\Core\BaseApiController;
|
|
use App\Modules\Academic\Models\ClassModel;
|
|
use App\Modules\Academic\Models\ScheduleModel;
|
|
use App\Modules\Academic\Models\SubjectModel;
|
|
use App\Modules\Auth\Entities\Role;
|
|
use App\Modules\Auth\Services\AuthService;
|
|
use App\Modules\Attendance\Models\QrAttendanceTokenModel;
|
|
use CodeIgniter\HTTP\ResponseInterface;
|
|
|
|
/**
|
|
* Generate QR token untuk absen mapel (guru tampilkan QR, siswa scan).
|
|
* POST /api/dashboard/qr-attendance/generate
|
|
* Body: { schedule_id: number }
|
|
*/
|
|
class QrAttendanceController extends BaseApiController
|
|
{
|
|
protected AuthService $authService;
|
|
|
|
public function __construct()
|
|
{
|
|
$this->authService = new AuthService();
|
|
}
|
|
|
|
/**
|
|
* Generate token untuk schedule_id. Hanya guru mapel jadwal tersebut / admin / wali kelas.
|
|
*/
|
|
public function generate(): ResponseInterface
|
|
{
|
|
$user = $this->authService->currentUser();
|
|
if (!$user) {
|
|
return $this->errorResponse('Unauthorized', null, null, 401);
|
|
}
|
|
|
|
$payload = $this->request->getJSON(true) ?? [];
|
|
$scheduleId = (int) ($payload['schedule_id'] ?? 0);
|
|
if ($scheduleId < 1) {
|
|
return $this->errorResponse('schedule_id wajib diisi', null, null, 400);
|
|
}
|
|
|
|
$scheduleModel = new ScheduleModel();
|
|
$schedule = $scheduleModel->getScheduleWithSlot($scheduleId);
|
|
if (!$schedule) {
|
|
return $this->errorResponse('Jadwal tidak ditemukan', null, null, 404);
|
|
}
|
|
|
|
if (!$this->canAccessSchedule($schedule, $user)) {
|
|
return $this->errorResponse('Anda tidak punya akses untuk jadwal ini', null, null, 403);
|
|
}
|
|
|
|
$qrModel = new QrAttendanceTokenModel();
|
|
$token = $qrModel->generateForSchedule($scheduleId, (int) $user['id']);
|
|
if (!$token) {
|
|
return $this->errorResponse('Gagal generate token', null, null, 500);
|
|
}
|
|
|
|
$subjectName = '-';
|
|
$className = '-';
|
|
if (!empty($schedule['subject_id'])) {
|
|
$subject = (new SubjectModel())->find($schedule['subject_id']);
|
|
$subjectName = $subject ? (string) $subject->name : '-';
|
|
}
|
|
if (!empty($schedule['class_id'])) {
|
|
$class = (new ClassModel())->find($schedule['class_id']);
|
|
$className = $class ? (trim($class->grade . ' ' . $class->major . ' ' . $class->name) ?: ('Kelas #' . $class->id)) : '-';
|
|
}
|
|
|
|
$expiresAt = date('Y-m-d H:i:s', strtotime('+' . QrAttendanceTokenModel::VALID_MINUTES . ' minutes'));
|
|
|
|
$data = [
|
|
'token' => $token,
|
|
'expires_at' => $expiresAt,
|
|
'schedule_id' => $scheduleId,
|
|
'subject_name' => $subjectName,
|
|
'class_name' => $className,
|
|
'valid_minutes' => QrAttendanceTokenModel::VALID_MINUTES,
|
|
];
|
|
|
|
return $this->successResponse($data, 'QR token berhasil dibuat. Tampilkan QR untuk siswa scan.');
|
|
}
|
|
|
|
protected function canAccessSchedule(array $schedule, array $user): bool
|
|
{
|
|
$roleCodes = array_column($user['roles'] ?? [], 'role_code');
|
|
if (in_array(Role::CODE_ADMIN, $roleCodes, true) || in_array(Role::CODE_GURU_BK, $roleCodes, true)) {
|
|
return true;
|
|
}
|
|
$classId = (int) ($schedule['class_id'] ?? 0);
|
|
if (in_array(Role::CODE_WALI_KELAS, $roleCodes, true)) {
|
|
$row = \Config\Database::connect()
|
|
->table('classes')
|
|
->select('id')
|
|
->where('id', $classId)
|
|
->where('wali_user_id', $user['id'])
|
|
->get()
|
|
->getRow();
|
|
return $row !== null;
|
|
}
|
|
if (in_array(Role::CODE_GURU_MAPEL, $roleCodes, true)) {
|
|
$teacherUserId = (int) ($schedule['teacher_user_id'] ?? 0);
|
|
return $teacherUserId === (int) $user['id'];
|
|
}
|
|
return false;
|
|
}
|
|
}
|