double lesson sorted, now electives
This commit is contained in:
parent
1295752cb1
commit
debb478acf
8
db/migrations/019_create_schedule_teachers_table.sql
Normal file
8
db/migrations/019_create_schedule_teachers_table.sql
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS schedule_teachers (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
schedule_id INT NOT NULL,
|
||||||
|
teacher_id INT NOT NULL,
|
||||||
|
FOREIGN KEY (schedule_id) REFERENCES schedules(id) ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY (teacher_id) REFERENCES teachers(id) ON DELETE CASCADE,
|
||||||
|
UNIQUE KEY (schedule_id, teacher_id)
|
||||||
|
);
|
||||||
@ -5,7 +5,9 @@ require_once 'db/config.php';
|
|||||||
|
|
||||||
// --- Database Fetch Functions ---
|
// --- Database Fetch Functions ---
|
||||||
function get_teachers($pdo, $school_id) {
|
function get_teachers($pdo, $school_id) {
|
||||||
return $pdo->prepare("SELECT * FROM teachers WHERE school_id = ? ORDER BY name")->execute([$school_id])->fetchAll(PDO::FETCH_ASSOC);
|
$stmt = $pdo->prepare("SELECT * FROM teachers WHERE school_id = ? ORDER BY name");
|
||||||
|
$stmt->execute([$school_id]);
|
||||||
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
}
|
}
|
||||||
|
|
||||||
function get_timeslots($pdo) {
|
function get_timeslots($pdo) {
|
||||||
@ -24,7 +26,8 @@ function get_teacher_schedule($pdo, $teacher_id, $school_id) {
|
|||||||
s.is_horizontal_elective
|
s.is_horizontal_elective
|
||||||
FROM schedules s
|
FROM schedules s
|
||||||
JOIN classes c ON s.class_id = c.id
|
JOIN classes c ON s.class_id = c.id
|
||||||
WHERE s.teacher_id = :teacher_id AND s.school_id = :school_id
|
JOIN schedule_teachers st ON s.id = st.schedule_id
|
||||||
|
WHERE st.teacher_id = :teacher_id AND c.school_id = :school_id
|
||||||
");
|
");
|
||||||
$stmt->execute([':teacher_id' => $teacher_id, ':school_id' => $school_id]);
|
$stmt->execute([':teacher_id' => $teacher_id, ':school_id' => $school_id]);
|
||||||
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|||||||
@ -290,7 +290,8 @@ function generate_timetable($workloads, $classes, $days_of_week, $periods_per_da
|
|||||||
'teacher_name' => count($teachers_to_place) > 1 ? 'Multiple' : $lesson['component_lessons'][0]['teacher_name'],
|
'teacher_name' => count($teachers_to_place) > 1 ? 'Multiple' : $lesson['component_lessons'][0]['teacher_name'],
|
||||||
'is_double' => $is_double,
|
'is_double' => $is_double,
|
||||||
'is_elective' => $lesson['type'] === 'elective',
|
'is_elective' => $lesson['type'] === 'elective',
|
||||||
'is_horizontal_elective' => $lesson['type'] === 'horizontal_elective'
|
'is_horizontal_elective' => $lesson['type'] === 'horizontal_elective',
|
||||||
|
'component_lessons' => $lesson['component_lessons']
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($is_double) {
|
if ($is_double) {
|
||||||
@ -314,31 +315,56 @@ function generate_timetable($workloads, $classes, $days_of_week, $periods_per_da
|
|||||||
// --- Timetable Persistence ---
|
// --- Timetable Persistence ---
|
||||||
function save_timetable($pdo, $class_timetables, $timeslots) {
|
function save_timetable($pdo, $class_timetables, $timeslots) {
|
||||||
$pdo->exec('TRUNCATE TABLE schedules');
|
$pdo->exec('TRUNCATE TABLE schedules');
|
||||||
|
$pdo->exec('TRUNCATE TABLE schedule_teachers');
|
||||||
|
|
||||||
$stmt = $pdo->prepare(
|
$stmt = $pdo->prepare(
|
||||||
'INSERT INTO schedules (class_id, day_of_week, timeslot_id, subject_id, teacher_id, lesson_display_name, teacher_display_name, is_double, is_elective, is_horizontal_elective) ' .
|
'INSERT INTO schedules (class_id, day_of_week, timeslot_id, subject_id, lesson_display_name, teacher_display_name, is_double, is_elective, is_horizontal_elective) ' .
|
||||||
'VALUES (:class_id, :day_of_week, :timeslot_id, :subject_id, :teacher_id, :lesson_display_name, :teacher_display_name, :is_double, :is_elective, :is_horizontal_elective)'
|
'VALUES (:class_id, :day_of_week, :timeslot_id, :subject_id, :lesson_display_name, :teacher_display_name, :is_double, :is_elective, :is_horizontal_elective)'
|
||||||
|
);
|
||||||
|
$teacher_stmt = $pdo->prepare(
|
||||||
|
'INSERT INTO schedule_teachers (schedule_id, teacher_id) VALUES (:schedule_id, :teacher_id)'
|
||||||
);
|
);
|
||||||
|
|
||||||
$lesson_periods = array_values(array_filter($timeslots, function($ts) { return !$ts['is_break']; }));
|
$lesson_periods = array_values(array_filter($timeslots, function($ts) { return !$ts['is_break']; }));
|
||||||
|
|
||||||
foreach ($class_timetables as $class_id => $day_schedule) {
|
foreach ($class_timetables as $class_id => $day_schedule) {
|
||||||
foreach ($day_schedule as $day_idx => $period_schedule) {
|
foreach ($day_schedule as $day_idx => $period_schedule) {
|
||||||
|
$processed_periods = [];
|
||||||
foreach ($period_schedule as $period_idx => $lesson) {
|
foreach ($period_schedule as $period_idx => $lesson) {
|
||||||
if ($lesson) {
|
if ($lesson && !in_array($period_idx, $processed_periods)) {
|
||||||
if (!isset($lesson_periods[$period_idx])) continue;
|
if (!isset($lesson_periods[$period_idx])) continue;
|
||||||
$timeslot_id = $lesson_periods[$period_idx]['id'];
|
$timeslot_id = $lesson_periods[$period_idx]['id'];
|
||||||
|
|
||||||
$stmt->execute([
|
$stmt->execute([
|
||||||
':class_id' => $class_id,
|
':class_id' => $class_id,
|
||||||
':day_of_week' => $day_idx,
|
':day_of_week' => $day_idx,
|
||||||
':timeslot_id' => $timeslot_id,
|
':timeslot_id' => $timeslot_id,
|
||||||
':subject_id' => $lesson['subject_id'],
|
':subject_id' => $lesson['subject_id'],
|
||||||
':teacher_id' => $lesson['teacher_id'],
|
|
||||||
':lesson_display_name' => $lesson['subject_name'],
|
':lesson_display_name' => $lesson['subject_name'],
|
||||||
':teacher_display_name' => $lesson['teacher_name'],
|
':teacher_display_name' => $lesson['teacher_name'],
|
||||||
':is_double' => (int)$lesson['is_double'],
|
':is_double' => (int)$lesson['is_double'],
|
||||||
':is_elective' => (int)$lesson['is_elective'],
|
':is_elective' => (int)$lesson['is_elective'],
|
||||||
':is_horizontal_elective' => (int)$lesson['is_horizontal_elective']
|
':is_horizontal_elective' => (int)$lesson['is_horizontal_elective']
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
$schedule_id = $pdo->lastInsertId();
|
||||||
|
|
||||||
|
if (!empty($lesson['component_lessons'])) {
|
||||||
|
$teacher_ids = array_unique(array_column($lesson['component_lessons'], 'teacher_id'));
|
||||||
|
foreach ($teacher_ids as $teacher_id) {
|
||||||
|
if ($teacher_id) {
|
||||||
|
$teacher_stmt->execute([
|
||||||
|
':schedule_id' => $schedule_id,
|
||||||
|
':teacher_id' => $teacher_id
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$processed_periods[] = $period_idx;
|
||||||
|
if ($lesson['is_double']) {
|
||||||
|
$processed_periods[] = $period_idx + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -350,6 +376,11 @@ function get_timetable_from_db($pdo, $classes, $timeslots) {
|
|||||||
$saved_lessons = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$saved_lessons = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
if (empty($saved_lessons)) return [];
|
if (empty($saved_lessons)) return [];
|
||||||
|
|
||||||
|
// Get teacher associations
|
||||||
|
$schedule_teachers_stmt = $pdo->query('SELECT st.schedule_id, t.name, t.id FROM schedule_teachers st JOIN teachers t ON st.teacher_id = t.id');
|
||||||
|
$schedule_teachers = $schedule_teachers_stmt->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
|
||||||
$days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'];
|
$days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'];
|
||||||
$periods = array_filter($timeslots, function($ts) { return !$ts['is_break']; });
|
$periods = array_filter($timeslots, function($ts) { return !$ts['is_break']; });
|
||||||
$periods_per_day = count($periods);
|
$periods_per_day = count($periods);
|
||||||
@ -373,16 +404,29 @@ function get_timetable_from_db($pdo, $classes, $timeslots) {
|
|||||||
if (!isset($timeslot_id_to_period_idx[$timeslot_id]) || !isset($class_timetables[$class_id])) continue;
|
if (!isset($timeslot_id_to_period_idx[$timeslot_id]) || !isset($class_timetables[$class_id])) continue;
|
||||||
$period_idx = $timeslot_id_to_period_idx[$timeslot_id];
|
$period_idx = $timeslot_id_to_period_idx[$timeslot_id];
|
||||||
|
|
||||||
$class_timetables[$class_id][$day_idx][$period_idx] = [
|
$teachers_for_lesson = $schedule_teachers[$lesson['id']] ?? [];
|
||||||
|
$teacher_name = $lesson['teacher_display_name'];
|
||||||
|
if (count($teachers_for_lesson) > 1) {
|
||||||
|
$teacher_name = 'Multiple';
|
||||||
|
} elseif (count($teachers_for_lesson) === 1) {
|
||||||
|
$teacher_name = $teachers_for_lesson[0]['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$lesson_data = [
|
||||||
'id' => $lesson['id'],
|
'id' => $lesson['id'],
|
||||||
'subject_id' => $lesson['subject_id'],
|
'subject_id' => $lesson['subject_id'],
|
||||||
'teacher_id' => $lesson['teacher_id'],
|
|
||||||
'subject_name' => $lesson['lesson_display_name'],
|
'subject_name' => $lesson['lesson_display_name'],
|
||||||
'teacher_name' => $lesson['teacher_display_name'],
|
'teacher_name' => $teacher_name,
|
||||||
'is_double' => (bool)$lesson['is_double'],
|
'is_double' => (bool)$lesson['is_double'],
|
||||||
'is_elective' => (bool)$lesson['is_elective'],
|
'is_elective' => (bool)$lesson['is_elective'],
|
||||||
'is_horizontal_elective' => (bool)$lesson['is_horizontal_elective']
|
'is_horizontal_elective' => (bool)$lesson['is_horizontal_elective']
|
||||||
];
|
];
|
||||||
|
|
||||||
|
$class_timetables[$class_id][$day_idx][$period_idx] = $lesson_data;
|
||||||
|
if ($lesson_data['is_double'] && isset($class_timetables[$class_id][$day_idx][$period_idx + 1])) {
|
||||||
|
$class_timetables[$class_id][$day_idx][$period_idx + 1] = $lesson_data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $class_timetables;
|
return $class_timetables;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user