/home/techb158/workloadmatch.com/Manager/Inc
Edit: /home/techb158/workloadmatch.com/Manager/Inc/CombinedScheduler.php (8130B)
db = $db;
$this->engine = new ScheduleEngine($db);
$this->generator = new ScheduleGenerator($db);
$this->assignmentEngine = new TeacherAssignmentEngine($db);
$this->aiOptimizer = new AIScheduleOptimizer($db);
}
public function setProvider(ProviderInterface $provider): void {
$this->aiOptimizer->setProvider($provider);
}
public function hasProvider(): bool {
return $this->aiOptimizer->hasProvider();
}
public function generateAndAssign(
int $programId,
int $groupId,
string $startDate,
?string $endDate = null,
array $selectedCourses = [],
array $priorityCourses = [],
bool $saveToDb = false,
bool $useAi = true
): array {
$scheduleResult = $this->generateSchedule($programId, $groupId, $startDate, $endDate, $selectedCourses, $priorityCourses, $useAi);
$savedEntries = [];
if ($saveToDb && !empty($scheduleResult['schedule'])) {
$savedEntries = $this->saveScheduleToDb($scheduleResult['schedule'], $programId, $groupId);
}
$assignmentResults = [];
if ($saveToDb && !empty($savedEntries)) {
$assignmentResults = $this->assignmentEngine->assignTeachers($programId, $groupId);
}
return [
'schedule_result' => $scheduleResult,
'saved_entries' => $savedEntries,
'assignment_results' => $assignmentResults,
'ai_generated' => $scheduleResult['ai_generated'] ?? false,
];
}
private function generateSchedule(int $programId, int $groupId, string $startDate, ?string $endDate, array $selectedCourses, array $priorityCourses, bool $useAi): array {
if ($useAi && $this->aiOptimizer->hasProvider()) {
return $this->aiOptimizer->optimize($programId, $groupId, $startDate, $endDate, $selectedCourses, $priorityCourses);
}
return $this->generator->generate($programId, $groupId, $startDate, $endDate, $selectedCourses, $priorityCourses);
}
private function saveScheduleToDb(array $schedule, int $programId, int $groupId): array {
$courseNames = $this->engine->getCourseNames();
$courseHours = [];
$res = $this->db->query("SELECT Course_ID, Course_Time, Course_Name FROM Courses");
while ($row = $res->fetch_assoc()) {
$courseHours[$row['Course_ID']] = $row;
}
$saved = [];
$groupSlots = [];
$stmt = $this->db->prepare("SELECT Group_Slot_ID, Time_Slot, Time_From, Time_To FROM group_slot_mapping WHERE Group_ID = ?");
$stmt->bind_param("i", $groupId);
$stmt->execute();
$groupSlots = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
$stmt->close();
$slotLookup = [];
foreach ($groupSlots as $gs) {
$slotLookup[trim($gs['Time_Slot'])] = $gs;
}
$grouped = [];
foreach ($schedule as $entry) {
$date = $entry['Date'];
$slot = $entry['Slot'];
$courseId = $entry['Course_ID'];
$slotName = $slot;
$numericSlot = filter_var($slot, FILTER_SANITIZE_NUMBER_INT);
if ($numericSlot) {
$slotIndex = (int)$numericSlot - 1;
$groupInfo = $this->engine->getGroupInfo($groupId);
if ($groupInfo) {
$slotLabels = explode(',', $groupInfo['Time_Slot']);
$slotName = trim($slotLabels[$slotIndex] ?? $slot);
}
}
$groupKey = "$courseId-$groupId-$slotName";
if (!isset($grouped[$groupKey])) {
$grouped[$groupKey] = [
'course_id' => $courseId,
'group_id' => $groupId,
'time_slot' => $slotName,
'dates' => [],
'start_date' => $date,
'end_date' => $date,
];
}
$grouped[$groupKey]['dates'][] = $date;
if ($date < $grouped[$groupKey]['start_date']) $grouped[$groupKey]['start_date'] = $date;
if ($date > $grouped[$groupKey]['end_date']) $grouped[$groupKey]['end_date'] = $date;
}
foreach ($grouped as $key => $g) {
$courseId = $g['course_id'];
$slotName = $g['time_slot'];
$startDate = $g['start_date'];
$endDate = $g['end_date'];
$courseData = $courseHours[$courseId] ?? ['Course_Time' => 0, 'Course_Name' => ''];
$courseName = $courseData['Course_Name'];
$courseTime = (int)$courseData['Course_Time'];
$reserveCourse = 0;
$groupSlotId = 0;
$startTime = '08:30:00';
$endTime = '12:30:00';
if (isset($slotLookup[trim($slotName)])) {
$gs = $slotLookup[trim($slotName)];
$groupSlotId = (int)$gs['Group_Slot_ID'];
$startTime = $gs['Time_From'];
$endTime = $gs['Time_To'];
}
$stmt = $this->db->prepare("
SELECT Schedule_ID FROM course_group_schedule_main
WHERE Program_ID = ? AND Course_ID = ? AND Group_ID = ? AND Time_Slot = ?
AND Start_Date = ? AND End_Date = ? AND Start_Time = ? AND End_Time = ?
");
$stmt->bind_param('iiisssss', $programId, $courseId, $groupId, $slotName, $startDate, $endDate, $startTime, $endTime);
$stmt->execute();
$existing = $stmt->get_result()->fetch_assoc();
$stmt->close();
$mainScheduleId = $existing ? (int)$existing['Schedule_ID'] : null;
if (!$mainScheduleId) {
$stmt = $this->db->prepare("
INSERT INTO course_group_schedule_main
(Program_ID, Course_ID, Group_ID, Time_Slot_ID, Course_Hours, Reserve_Course, Time_Slot,
Start_Date, End_Date, Start_Time, End_Time, Assigned, Last_Updated)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, NOW())
");
$stmt->bind_param('iiiiissssss', $programId, $courseId, $groupId, $groupSlotId, $courseTime, $reserveCourse, $slotName, $startDate, $endDate, $startTime, $endTime);
$stmt->execute();
$mainScheduleId = (int)$stmt->insert_id;
$stmt->close();
}
foreach ($g['dates'] as $date) {
$stmt = $this->db->prepare("
INSERT INTO schedule_course_for_group
(Schedule_ID, Program_ID, Course_ID, Group_ID, Group_Slot_ID, Course_Hours, Course_Name,
Reserve_Course, Time_Slot, Start_Date, End_Date, Start_Time, End_Time, Assigned, Last_Updated)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0, NOW())
");
$stmt->bind_param('iiiiiisssssss', $mainScheduleId, $programId, $courseId, $groupId, $groupSlotId, $courseTime, $courseName, $reserveCourse, $slotName, $date, $date, $startTime, $endTime);
$stmt->execute();
$saved[] = [
'schedule_id' => $mainScheduleId,
'session_id' => (int)$stmt->insert_id,
'course_id' => $courseId,
'date' => $date,
'slot' => $slotName,
];
$stmt->close();
}
}
return $saved;
}
}