Files
presensi/app/Modules/Academic/Controllers/ScheduleManagementController.php
2026-03-05 14:37:36 +07:00

150 lines
5.8 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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,
];
}
}