File "auto_assign.php"
Full path: /home2/santhos2/public_html/bharath-coe.firstmatrix.in.net/api/invigilation_duties/auto_assign.php
File size: 7.58 KiB (7766 bytes)
MIME-type: text/x-php
Charset: utf-8
<?php
require_once '../../config/config.php';
header('Content-Type: application/json');
function respond($ok, $msg, $extra = []) {
echo json_encode(($ok ? ['status' => 'success'] : ['status' => 'error']) + ['message' => $msg] + $extra);
exit;
}
try {
$academicYearId = (int)($_POST['academic_year_id'] ?? 0);
$examId = (int)($_POST['exam_id'] ?? 0);
$examTypeId = (int)($_POST['exam_type_id'] ?? 0);
if ($academicYearId <= 0 || $examId <= 0 || $examTypeId <= 0) {
respond(false, 'Academic Year ID, Exam ID, and Exam Type ID are required');
}
// Get all hall allocations for the exam
$allocationsStmt = $pdo->prepare("
SELECT ha.allocation_id, ha.hall_id, ha.num_students,
h.hall_name, h.capacity,
et.exam_date, et.session
FROM hall_allocations ha
JOIN halls h ON ha.hall_id = h.hall_id
JOIN exam_timetable et ON ha.timetable_id = et.timetable_id
WHERE ha.exam_id = ? AND ha.academic_year_id = ? AND ha.exam_type_id = ?
ORDER BY et.exam_date, et.session, h.hall_name
");
$allocationsStmt->execute([$examId, $academicYearId, $examTypeId]);
$allocations = $allocationsStmt->fetchAll(PDO::FETCH_ASSOC);
if (empty($allocations)) {
respond(false, 'No hall allocations found for this exam');
}
// Get staff with roles
$staffStmt = $pdo->prepare("
SELECT s.staff_id, s.first_name, s.last_name, s.staff_code,
GROUP_CONCAT(sr.role_name) as roles
FROM staff s
LEFT JOIN staff_role_assignments sra ON s.staff_id = sra.staff_id
LEFT JOIN staff_roles sr ON sra.role_id = sr.role_id
WHERE s.status = 'Active'
GROUP BY s.staff_id
HAVING roles IS NOT NULL
");
$staffStmt->execute();
$staff = $staffStmt->fetchAll(PDO::FETCH_ASSOC);
// Separate staff by roles
$invigilators = [];
$valuators = [];
$squadMembers = [];
foreach ($staff as $member) {
$roles = explode(',', $member['roles']);
foreach ($roles as $role) {
$role = trim($role);
if ($role === 'Invigilator') {
$invigilators[] = $member;
} elseif ($role === 'Valuator') {
$valuators[] = $member;
} elseif ($role === 'Squad') {
$squadMembers[] = $member;
}
}
}
$assignedDuties = 0;
$assignedSquads = 0;
$errors = [];
// Process each allocation
foreach ($allocations as $allocation) {
$hallId = $allocation['hall_id'];
$examDate = $allocation['exam_date'];
$session = $allocation['session'];
$allocationId = $allocation['allocation_id'];
$numStudents = $allocation['num_students'];
// Clear existing duties for this allocation
$pdo->prepare("DELETE FROM invigilation_duties WHERE allocation_id = ?")->execute([$allocationId]);
// Assign Chief Invigilator (Valuator role)
if (!empty($valuators)) {
$chiefInvigilator = $valuators[array_rand($valuators)];
try {
$dutyStmt = $pdo->prepare("
INSERT INTO invigilation_duties
(hall_id, exam_date, session, staff_id, role, allocation_id, status)
VALUES (?, ?, ?, ?, 'Chief Invigilator', ?, 'Assigned')
");
$dutyStmt->execute([$hallId, $examDate, $session, $chiefInvigilator['staff_id'], $allocationId]);
$assignedDuties++;
} catch (Exception $e) {
$errors[] = "Failed to assign Chief Invigilator for {$allocation['hall_name']}: " . $e->getMessage();
}
}
// Assign Invigilators based on hall capacity
$requiredInvigilators = max(1, ceil($numStudents / 30)); // 1 invigilator per 30 students
$assignedInvigilators = 0;
foreach ($invigilators as $invigilator) {
if ($assignedInvigilators >= $requiredInvigilators) break;
// Check if staff already assigned to this date/session
$checkStmt = $pdo->prepare("
SELECT duty_id FROM invigilation_duties
WHERE exam_date = ? AND session = ? AND staff_id = ?
");
$checkStmt->execute([$examDate, $session, $invigilator['staff_id']]);
if ($checkStmt->fetch()) continue;
try {
$dutyStmt = $pdo->prepare("
INSERT INTO invigilation_duties
(hall_id, exam_date, session, staff_id, role, allocation_id, status)
VALUES (?, ?, ?, ?, 'Invigilator', ?, 'Assigned')
");
$dutyStmt->execute([$hallId, $examDate, $session, $invigilator['staff_id'], $allocationId]);
$assignedInvigilators++;
$assignedDuties++;
} catch (Exception $e) {
$errors[] = "Failed to assign Invigilator for {$allocation['hall_name']}: " . $e->getMessage();
}
}
// Assign Squad members (no specific hall assignment, just date/session)
foreach ($squadMembers as $squadMember) {
// Check if already assigned to squad for this date/session
$checkStmt = $pdo->prepare("
SELECT squad_id FROM squads
WHERE exam_date = ? AND session = ? AND staff_id = ?
");
$checkStmt->execute([$examDate, $session, $squadMember['staff_id']]);
if ($checkStmt->fetch()) continue;
try {
$squadStmt = $pdo->prepare("
INSERT INTO squads
(squad_name, exam_date, session, staff_id, status)
VALUES (?, ?, ?, ?, 'Active')
");
$squadName = "Squad {$examDate} {$session}";
$squadStmt->execute([$squadName, $examDate, $session, $squadMember['staff_id']]);
$assignedSquads++;
} catch (Exception $e) {
$errors[] = "Failed to assign Squad member for {$examDate} {$session}: " . $e->getMessage();
}
}
}
$debugInfo = [];
$debugInfo[] = "Processed " . count($allocations) . " hall allocations";
$debugInfo[] = "Available Invigilators: " . count($invigilators);
$debugInfo[] = "Available Valuators: " . count($valuators);
$debugInfo[] = "Available Squad Members: " . count($squadMembers);
$debugInfo[] = "Assigned Duties: " . $assignedDuties;
$debugInfo[] = "Assigned Squad Members: " . $assignedSquads;
// Add detailed staff information for debugging
if (count($valuators) === 0) {
$debugInfo[] = "No Valuators found - check if staff have 'Valuator' role assigned";
}
if (count($squadMembers) === 0) {
$debugInfo[] = "No Squad members found - check if staff have 'Squad' role assigned";
}
if (count($invigilators) === 0) {
$debugInfo[] = "No Invigilators found - check if staff have 'Invigilator' role assigned";
}
if (!empty($errors)) {
$debugInfo[] = "Errors: " . implode('; ', $errors);
}
respond(true, 'Invigilation duties and squads assigned successfully', [
'assigned_duties' => $assignedDuties,
'assigned_squads' => $assignedSquads,
'allocations_processed' => count($allocations),
'debug_info' => $debugInfo,
'errors' => $errors
]);
} catch (Exception $e) {
respond(false, $e->getMessage());
}
?>