init backend presensi

This commit is contained in:
mwpn
2026-03-05 14:37:36 +07:00
commit b4fda6b9c9
319 changed files with 27261 additions and 0 deletions

View File

@@ -0,0 +1,149 @@
<?php
namespace App\Modules\Academic\Controllers;
use App\Core\BaseApiController;
use App\Modules\Academic\Models\LessonSlotModel;
use App\Modules\Academic\Models\ScheduleModel;
use CodeIgniter\HTTP\ResponseInterface;
/**
* Weekly Schedule Management API (ADMIN only).
*/
class ScheduleManagementController extends BaseApiController
{
protected ScheduleModel $scheduleModel;
protected LessonSlotModel $lessonSlotModel;
public function __construct()
{
$this->scheduleModel = new ScheduleModel();
$this->lessonSlotModel = new LessonSlotModel();
}
/**
* GET /api/academic/schedules/class/{classId}
* Returns weekly schedule grid: slots with days 15, each cell schedule or null.
*/
public function getByClass($classId): ResponseInterface
{
$classId = (int) $classId;
$slots = $this->lessonSlotModel->where('is_active', 1)->orderBy('slot_number', 'ASC')->findAll();
$rows = $this->scheduleModel->where('class_id', $classId)->findAll();
$bySlotDay = [];
foreach ($rows as $row) {
$slotId = $row->lesson_slot_id ?? 0;
$day = (int) $row->day_of_week;
if ($slotId && $day >= 1 && $day <= 7) {
$bySlotDay[$slotId][$day] = $this->scheduleToArray($row);
}
}
$grid = [];
foreach ($slots as $slot) {
$slotId = (int) $slot->id;
$days = [];
for ($d = 1; $d <= 5; $d++) {
$days[$d] = $bySlotDay[$slotId][$d] ?? null;
}
$grid[] = [
'lesson_slot_id' => $slotId,
'slot_number' => (int) $slot->slot_number,
'start_time' => (string) $slot->start_time,
'end_time' => (string) $slot->end_time,
'days' => $days,
];
}
return $this->successResponse($grid, 'Weekly schedule');
}
/**
* POST /api/academic/schedules/bulk-save
* Body: { class_id, schedules: [ { day_of_week, lesson_slot_id, subject_id, teacher_user_id [, room] }, ... ] }
* Deletes existing schedules for class then inserts new ones in a transaction.
*/
public function bulkSave(): ResponseInterface
{
$input = $this->request->getJSON(true) ?? [];
$classId = (int) ($input['class_id'] ?? 0);
$items = $input['schedules'] ?? [];
if ($classId <= 0) {
return $this->errorResponse('class_id is required and must be positive', null, null, 422);
}
if (!is_array($items)) {
return $this->errorResponse('schedules must be an array', null, null, 422);
}
$db = \Config\Database::connect();
$db->transStart();
try {
$this->scheduleModel->where('class_id', $classId)->delete();
$this->scheduleModel->skipValidation(true);
foreach ($items as $item) {
$day = (int) ($item['day_of_week'] ?? 0);
$slot = (int) ($item['lesson_slot_id'] ?? 0);
$subj = (int) ($item['subject_id'] ?? 0);
$teacher = (int) ($item['teacher_user_id'] ?? 0);
if ($day < 1 || $day > 7 || $slot <= 0 || $subj <= 0) {
$db->transRollback();
return $this->errorResponse('Each schedule must have day_of_week (1-7), lesson_slot_id, subject_id', null, null, 422);
}
$data = [
'class_id' => $classId,
'subject_id' => $subj,
'teacher_user_id' => $teacher ?: null,
'lesson_slot_id' => $slot,
'day_of_week' => $day,
'room' => isset($item['room']) ? (string) $item['room'] : null,
'is_active' => 1,
];
if ($this->scheduleModel->insert($data) === false) {
$db->transRollback();
return $this->errorResponse('Failed to insert schedule', null, null, 422);
}
}
$this->scheduleModel->skipValidation(false);
$db->transComplete();
} catch (\Throwable $e) {
if ($db->transStatus() === false) {
$db->transRollback();
}
return $this->errorResponse($e->getMessage(), null, null, 500);
}
if ($db->transStatus() === false) {
return $this->errorResponse('Database transaction failed', null, null, 500);
}
return $this->successResponse(null, 'Schedules saved');
}
protected function scheduleToArray($schedule): array
{
if (is_array($schedule)) {
return [
'id' => (int) ($schedule['id'] ?? 0),
'class_id' => (int) ($schedule['class_id'] ?? 0),
'subject_id' => (int) ($schedule['subject_id'] ?? 0),
'teacher_user_id' => isset($schedule['teacher_user_id']) ? (int) $schedule['teacher_user_id'] : null,
'lesson_slot_id' => (int) ($schedule['lesson_slot_id'] ?? 0),
'day_of_week' => (int) ($schedule['day_of_week'] ?? 0),
'room' => isset($schedule['room']) ? (string) $schedule['room'] : null,
];
}
return [
'id' => (int) $schedule->id,
'class_id' => (int) $schedule->class_id,
'subject_id' => (int) $schedule->subject_id,
'teacher_user_id' => $schedule->teacher_user_id !== null ? (int) $schedule->teacher_user_id : null,
'lesson_slot_id' => (int) $schedule->lesson_slot_id,
'day_of_week' => (int) $schedule->day_of_week,
'room' => $schedule->room !== null ? (string) $schedule->room : null,
];
}
}