fix is_active student flag and apply it in all pages
This commit is contained in:
@@ -98,6 +98,6 @@ class Autoload extends AutoloadConfig
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
public $helpers = ['url', 'form', 'pbkdf2', 'document', 'time', 'api', 'global_config'];
|
||||
public $helpers = ['url', 'form', 'pbkdf2', 'document', 'time', 'api', 'global_config', 'student_status'];
|
||||
|
||||
}
|
||||
|
||||
@@ -2135,6 +2135,31 @@ class AdministratorController extends BaseController
|
||||
->getResultArray();
|
||||
}
|
||||
|
||||
$enrollmentStatusByStudentId = [];
|
||||
$studentIds = array_values(array_unique(array_filter(array_map(
|
||||
static fn (array $row): int => (int) ($row['id'] ?? 0),
|
||||
$students
|
||||
))));
|
||||
if ($selectedYear !== '' && !empty($studentIds)) {
|
||||
$enrollmentRows = $db->table('enrollments')
|
||||
->select('student_id, enrollment_status')
|
||||
->whereIn('student_id', $studentIds)
|
||||
->where('school_year', $selectedYear)
|
||||
->orderBy('student_id', 'ASC')
|
||||
->orderBy('updated_at', 'DESC')
|
||||
->orderBy('enrollment_date', 'DESC')
|
||||
->orderBy('id', 'DESC')
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
foreach ($enrollmentRows as $enrollmentRow) {
|
||||
$studentId = (int) ($enrollmentRow['student_id'] ?? 0);
|
||||
if ($studentId > 0 && !isset($enrollmentStatusByStudentId[$studentId])) {
|
||||
$enrollmentStatusByStudentId[$studentId] = (string) ($enrollmentRow['enrollment_status'] ?? '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// === Inject current-year class_section_name from student_class and replace grade ===
|
||||
foreach ($students as $i => $row) {
|
||||
$sid = (int) ($row['id'] ?? 0);
|
||||
@@ -2142,9 +2167,11 @@ class AdministratorController extends BaseController
|
||||
$classSectionName = (string) ($this->studentClassModel->getClassSectionNameByStudentId($sid, $selectedYear) ?? '');
|
||||
|
||||
$students[$i]['class_section_name'] = $classSectionName;
|
||||
$students[$i]['enrollment_status'] = $enrollmentStatusByStudentId[$sid] ?? '';
|
||||
} else {
|
||||
// Keep keys consistent even if id missing
|
||||
$students[$i]['class_section_name'] = '';
|
||||
$students[$i]['enrollment_status'] = '';
|
||||
}
|
||||
|
||||
$studentYear = trim((string) ($row['school_year'] ?? ''));
|
||||
|
||||
@@ -267,9 +267,9 @@ public function showUpdateAttendanceForm()
|
||||
$currentSunday = $sundayDates[2];
|
||||
|
||||
// Students roster for this section/year/semester (try section code, then PK fallback)
|
||||
$students = $this->studentModel->getByClassAndYear($class_section_id, $schoolYear, $semester);
|
||||
$students = $this->studentModel->getActiveByClassAndYear($class_section_id, $schoolYear, $semester);
|
||||
if (empty($students) && $classSectionPk > 0 && $classSectionPk !== $class_section_id) {
|
||||
$students = $this->studentModel->getByClassAndYear($classSectionPk, $schoolYear, $semester);
|
||||
$students = $this->studentModel->getActiveByClassAndYear($classSectionPk, $schoolYear, $semester);
|
||||
}
|
||||
|
||||
// Build student attendance rows
|
||||
@@ -598,11 +598,12 @@ public function showUpdateAttendanceForm()
|
||||
$seenStudentIds[$studentId] = true;
|
||||
|
||||
$student = $this->studentModel
|
||||
->select('id, firstname, lastname, school_id')
|
||||
->select('id, firstname, lastname, school_id, is_active')
|
||||
->where('id', $studentId)
|
||||
->where('is_active', 1)
|
||||
->first();
|
||||
if (!$student) continue;
|
||||
$student['enrollment_status'] = $sc['enrollment_status'] ?? '';
|
||||
$student['is_withdrawn'] = (int)($sc['is_withdrawn'] ?? 0);
|
||||
|
||||
$studentsBySection[$secCode][] = $student;
|
||||
$hasRoster = true;
|
||||
@@ -1027,9 +1028,11 @@ public function showUpdateAttendanceForm()
|
||||
continue;
|
||||
}
|
||||
$student = $this->studentModel
|
||||
->select('id, firstname, lastname, school_id')
|
||||
->select('id, firstname, lastname, school_id, is_active')
|
||||
->find($studentId);
|
||||
if (!$student) continue;
|
||||
$student['enrollment_status'] = $sc['enrollment_status'] ?? '';
|
||||
$student['is_withdrawn'] = (int)($sc['is_withdrawn'] ?? 0);
|
||||
|
||||
$studentsBySection[$secCode][] = $student;
|
||||
$hasRoster = true;
|
||||
@@ -1603,7 +1606,7 @@ public function showUpdateAttendanceForm()
|
||||
|
||||
// optional score updates (never bubble)
|
||||
try {
|
||||
$studentUserInfo = $this->studentModel->getStudentInfoByClassSectionId(
|
||||
$studentUserInfo = $this->studentModel->getActiveStudentInfoByClassSectionId(
|
||||
$classSectionId,
|
||||
$semester,
|
||||
$schoolYear
|
||||
@@ -1722,6 +1725,19 @@ public function showUpdateAttendanceForm()
|
||||
$semester = (string)($this->semester ?? '');
|
||||
$schoolYear = (string)($this->schoolYear ?? '');
|
||||
|
||||
$activeStudents = $this->studentModel->getActiveByClassAndYear($classSectionId, $schoolYear, $semester);
|
||||
$activeStudentIds = array_fill_keys(array_map(static fn(array $row): int => (int)($row['id'] ?? 0), $activeStudents), true);
|
||||
$attendanceData = array_values(array_filter($attendanceData, static function ($row) use ($activeStudentIds): bool {
|
||||
$sid = (int)($row['student_id'] ?? 0);
|
||||
return $sid > 0 && isset($activeStudentIds[$sid]);
|
||||
}));
|
||||
|
||||
if (empty($attendanceData)) {
|
||||
return redirect()->to('/teacher/showupdate_attendance?class_section_id=' . $classSectionId)
|
||||
->with('status', 'error')
|
||||
->with('message', 'No active student attendance data provided.');
|
||||
}
|
||||
|
||||
// Existing attendance rows for today (used to lock parent/admin submissions)
|
||||
$existingRows = $this->attendanceDataModel
|
||||
->where('class_section_id', $classSectionId)
|
||||
@@ -2027,7 +2043,7 @@ public function showUpdateAttendanceForm()
|
||||
}
|
||||
|
||||
try {
|
||||
$studentUserInfo = $this->studentModel->getStudentInfoByClassSectionId($classSectionId, $this->semester, $this->schoolYear);
|
||||
$studentUserInfo = $this->studentModel->getActiveStudentInfoByClassSectionId($classSectionId, $this->semester, $this->schoolYear);
|
||||
$this->semesterScoreService->updateScoresForStudents($studentUserInfo);
|
||||
} catch (\Throwable $e) {
|
||||
// ignore
|
||||
|
||||
@@ -386,12 +386,14 @@ class CompetitionScoresController extends BaseController
|
||||
return 0;
|
||||
}
|
||||
|
||||
$builder = $this->db->table($this->classStudentTable)
|
||||
$builder = $this->db->table($this->classStudentTable . ' cs')
|
||||
->select('COUNT(*) AS total')
|
||||
->where('class_section_id', $classSectionId);
|
||||
->join('students s', 's.id = cs.student_id', 'inner')
|
||||
->where('cs.class_section_id', $classSectionId)
|
||||
->where('s.is_active', 1);
|
||||
|
||||
if ($schoolYear && $this->db->fieldExists('school_year', $this->classStudentTable)) {
|
||||
$builder->where('school_year', $schoolYear);
|
||||
$builder->where('cs.school_year', $schoolYear);
|
||||
}
|
||||
|
||||
$row = $builder->get()->getRowArray();
|
||||
@@ -407,7 +409,8 @@ class CompetitionScoresController extends BaseController
|
||||
$builder = $this->db->table('students s')
|
||||
->select('s.id, s.school_id, s.firstname, s.lastname')
|
||||
->join($this->classStudentTable . ' cs', 'cs.student_id = s.id', 'inner')
|
||||
->where('cs.class_section_id', $classSectionId);
|
||||
->where('cs.class_section_id', $classSectionId)
|
||||
->where('s.is_active', 1);
|
||||
|
||||
$hasSchoolYear = $this->db->fieldExists('school_year', $this->classStudentTable);
|
||||
if ($hasSchoolYear && !empty($competition['school_year'])) {
|
||||
|
||||
@@ -131,6 +131,7 @@ class FinalController extends BaseController
|
||||
)
|
||||
->join('(' . $latestFinalSub . ') fl', 'fl.student_id = s.id', 'left', false)
|
||||
->join('final_exam fe', 'fe.id = fl.max_id', 'left')
|
||||
->where('s.is_active', 1)
|
||||
->orderBy('s.lastname', 'ASC')
|
||||
->orderBy('s.firstname', 'ASC');
|
||||
|
||||
|
||||
@@ -521,6 +521,9 @@ class GradingController extends BaseController
|
||||
'school_id' => $r['school_id'] ?? null,
|
||||
'firstname' => $r['firstname'] ?? null,
|
||||
'lastname' => $r['lastname'] ?? null,
|
||||
'is_active' => (int)($r['is_active'] ?? 1),
|
||||
'enrollment_status' => $r['enrollment_status'] ?? '',
|
||||
'is_withdrawn' => (int)($r['is_withdrawn'] ?? 0),
|
||||
'class_id' => $classId,
|
||||
'ptap' => is_null($ptapScore) ? null : round((float) $ptapScore, 2),
|
||||
'semester_score' => is_null($semesterScore) ? null : round((float) $semesterScore, 2),
|
||||
@@ -997,11 +1000,16 @@ class GradingController extends BaseController
|
||||
private function fetchActiveStudentsWithSection(string $schoolYear): array
|
||||
{
|
||||
return $this->db->table('students s')
|
||||
->select('s.id AS student_id, s.school_id, s.firstname, s.lastname, sc.class_section_id, cs.class_section_name, c.class_name')
|
||||
->select('s.id AS student_id, s.school_id, s.firstname, s.lastname, s.is_active, sc.class_section_id, cs.class_section_name, c.class_name, e.enrollment_status, e.is_withdrawn')
|
||||
->join('student_class sc', 'sc.student_id = s.id AND sc.school_year = ' . $this->db->escape($schoolYear), 'left')
|
||||
->join('enrollments e', 'e.student_id = s.id AND e.school_year = ' . $this->db->escape($schoolYear), 'left')
|
||||
->join('`classSection` cs', 'cs.class_section_id = sc.class_section_id', 'left')
|
||||
->join('classes c', 'c.id = cs.class_id', 'left')
|
||||
->where('s.is_active', 1)
|
||||
->groupStart()
|
||||
->where('s.is_active', 1)
|
||||
->orWhere("LOWER(TRIM(e.enrollment_status)) IN ('denied','withdrawn','widthran','widthrawan','withdrawan','waitlist')", null, false)
|
||||
->orWhere('e.is_withdrawn', 1)
|
||||
->groupEnd()
|
||||
->orderBy('s.lastname', 'ASC')
|
||||
->orderBy('s.firstname', 'ASC')
|
||||
->get()
|
||||
@@ -1032,13 +1040,18 @@ class GradingController extends BaseController
|
||||
}
|
||||
|
||||
$rows = $this->db->table('placement_scores ps')
|
||||
->select('ps.batch_id, ps.score, s.school_id, s.firstname, s.lastname, cs.class_section_name, c.class_name')
|
||||
->select('ps.batch_id, ps.student_id, ps.score, s.school_id, s.firstname, s.lastname, s.is_active, e.enrollment_status, e.is_withdrawn, cs.class_section_name, c.class_name')
|
||||
->join('students s', 's.id = ps.student_id', 'inner')
|
||||
->join('student_class sc', 'sc.student_id = s.id AND sc.school_year = ' . $this->db->escape($schoolYear), 'left')
|
||||
->join('enrollments e', 'e.student_id = s.id AND e.school_year = ' . $this->db->escape($schoolYear), 'left')
|
||||
->join('`classSection` cs', 'cs.class_section_id = sc.class_section_id', 'left')
|
||||
->join('classes c', 'c.id = cs.class_id', 'left')
|
||||
->whereIn('ps.batch_id', $batchIds)
|
||||
->where('s.is_active', 1)
|
||||
->groupStart()
|
||||
->where('s.is_active', 1)
|
||||
->orWhere("LOWER(TRIM(e.enrollment_status)) IN ('denied','withdrawn','widthran','widthrawan','withdrawan','waitlist')", null, false)
|
||||
->orWhere('e.is_withdrawn', 1)
|
||||
->groupEnd()
|
||||
->orderBy('ps.batch_id', 'ASC')
|
||||
->orderBy('s.lastname', 'ASC')
|
||||
->orderBy('s.firstname', 'ASC')
|
||||
@@ -1621,6 +1634,9 @@ public function belowSixty()
|
||||
's.school_id',
|
||||
's.firstname',
|
||||
's.lastname',
|
||||
's.is_active',
|
||||
'e.enrollment_status',
|
||||
'e.is_withdrawn',
|
||||
'pl.level AS placement_level',
|
||||
|
||||
// Prefer business-id match; fall back to pk match
|
||||
@@ -1640,6 +1656,11 @@ public function belowSixty()
|
||||
->distinct()
|
||||
->join('`classSection` cs', 'cs.class_section_id = sc.class_section_id', 'left')
|
||||
->join('students s', 's.id = sc.student_id', 'inner')
|
||||
->join(
|
||||
'enrollments e',
|
||||
"e.student_id = s.id AND e.school_year = {$yrEsc}",
|
||||
'left'
|
||||
)
|
||||
->join(
|
||||
'placement_levels pl',
|
||||
'pl.student_id = s.id',
|
||||
@@ -1665,7 +1686,11 @@ public function belowSixty()
|
||||
'left'
|
||||
)
|
||||
->where('sc.school_year', $schoolYear)
|
||||
->where('s.is_active', 1); // Exclude removed/inactive students
|
||||
->groupStart()
|
||||
->where('s.is_active', 1)
|
||||
->orWhere("LOWER(TRIM(e.enrollment_status)) IN ('denied','withdrawn','widthran','widthrawan','withdrawan','waitlist')", null, false)
|
||||
->orWhere('e.is_withdrawn', 1)
|
||||
->groupEnd();
|
||||
|
||||
return $builder
|
||||
->orderBy('cs.class_id', 'ASC')
|
||||
@@ -1800,6 +1825,7 @@ public function belowSixty()
|
||||
->select('s.school_id')
|
||||
->select('s.firstname')
|
||||
->select('s.lastname')
|
||||
->select('MAX(s.is_active) AS is_active', false)
|
||||
->select('cs.class_section_name')
|
||||
->select("'year' AS semester", false)
|
||||
->select("MAX(CASE WHEN LOWER(TRIM(ss.semester)) = 'fall' THEN ss.homework_avg END) AS fall_homework_avg", false)
|
||||
@@ -1856,9 +1882,15 @@ public function belowSixty()
|
||||
MAX(CASE WHEN LOWER(TRIM(ss.semester)) = 'fall' THEN ss.final_exam_score END)
|
||||
+ MAX(CASE WHEN LOWER(TRIM(ss.semester)) = 'spring' THEN ss.final_exam_score END)
|
||||
) / 2 AS final_exam_score", false)
|
||||
->select('MAX(e.enrollment_status) AS enrollment_status, MAX(e.is_withdrawn) AS is_withdrawn', false)
|
||||
->join('students s', 's.id = ss.student_id', 'inner')
|
||||
->join('enrollments e', 'e.student_id = s.id AND e.school_year = ' . $this->db->escape($schoolYear), 'left')
|
||||
->join('classSection cs', 'cs.class_section_id = ss.class_section_id', 'left')
|
||||
->where('s.is_active', 1)
|
||||
->groupStart()
|
||||
->where('s.is_active', 1)
|
||||
->orWhere("LOWER(TRIM(e.enrollment_status)) IN ('denied','withdrawn','widthran','widthrawan','withdrawan','waitlist')", null, false)
|
||||
->orWhere('e.is_withdrawn', 1)
|
||||
->groupEnd()
|
||||
->where('ss.school_year', $schoolYear)
|
||||
->where('ss.semester_score IS NOT NULL', null, false)
|
||||
->where("LOWER(TRIM(ss.semester)) IN ('fall', 'spring')", null, false)
|
||||
@@ -1888,6 +1920,7 @@ public function belowSixty()
|
||||
's.school_id',
|
||||
's.firstname',
|
||||
's.lastname',
|
||||
's.is_active',
|
||||
'cs.class_section_name',
|
||||
'ss.semester',
|
||||
'ss.homework_avg',
|
||||
@@ -1899,10 +1932,17 @@ public function belowSixty()
|
||||
'ss.midterm_exam_score',
|
||||
'ss.final_exam_score',
|
||||
'ss.semester_score',
|
||||
'e.enrollment_status',
|
||||
'e.is_withdrawn',
|
||||
])
|
||||
->join('students s', 's.id = ss.student_id', 'inner')
|
||||
->join('enrollments e', 'e.student_id = s.id AND e.school_year = ' . $this->db->escape($schoolYear), 'left')
|
||||
->join('classSection cs', 'cs.class_section_id = ss.class_section_id', 'left')
|
||||
->where('s.is_active', 1)
|
||||
->groupStart()
|
||||
->where('s.is_active', 1)
|
||||
->orWhere("LOWER(TRIM(e.enrollment_status)) IN ('denied','withdrawn','widthran','widthrawan','withdrawan','waitlist')", null, false)
|
||||
->orWhere('e.is_withdrawn', 1)
|
||||
->groupEnd()
|
||||
->where('ss.school_year', $schoolYear)
|
||||
->where('ss.semester_score IS NOT NULL', null, false)
|
||||
->where('ss.semester_score <', 60)
|
||||
@@ -2014,10 +2054,15 @@ public function belowSixty()
|
||||
'ss.semester_score',
|
||||
])
|
||||
->join('students s', 's.id = ss.student_id', 'inner')
|
||||
->join('enrollments e', 'e.student_id = s.id AND e.school_year = ' . $this->db->escape($schoolYear), 'left')
|
||||
->join('classSection cs', 'cs.class_section_id = ss.class_section_id', 'left')
|
||||
->where('ss.school_year', $schoolYear)
|
||||
->where('ss.student_id', $studentId)
|
||||
->where('s.is_active', 1)
|
||||
->groupStart()
|
||||
->where('s.is_active', 1)
|
||||
->orWhere("LOWER(TRIM(e.enrollment_status)) IN ('denied','withdrawn','widthran','widthrawan','withdrawan','waitlist')", null, false)
|
||||
->orWhere('e.is_withdrawn', 1)
|
||||
->groupEnd()
|
||||
->where("LOWER(TRIM(ss.semester))", $semesterKey)
|
||||
->get()
|
||||
->getRowArray();
|
||||
@@ -2354,13 +2399,21 @@ public function belowSixty()
|
||||
's.lastname',
|
||||
's.age',
|
||||
's.school_id',
|
||||
's.is_active',
|
||||
'cs.class_section_name',
|
||||
'e.enrollment_status',
|
||||
'e.is_withdrawn',
|
||||
'LOWER(TRIM(ss.semester)) AS sem_key',
|
||||
'ss.semester_score',
|
||||
])
|
||||
->join('students s', 's.id = ss.student_id', 'inner')
|
||||
->join('enrollments e', 'e.student_id = s.id AND e.school_year = ' . $this->db->escape($schoolYear), 'left')
|
||||
->join('classSection cs', 'cs.class_section_id = ss.class_section_id', 'left')
|
||||
->where('s.is_active', 1)
|
||||
->groupStart()
|
||||
->where('s.is_active', 1)
|
||||
->orWhere("LOWER(TRIM(e.enrollment_status)) IN ('denied','withdrawn','widthran','widthrawan','withdrawan','waitlist')", null, false)
|
||||
->orWhere('e.is_withdrawn', 1)
|
||||
->groupEnd()
|
||||
->where('ss.school_year', $schoolYear)
|
||||
->whereIn('LOWER(TRIM(ss.semester))', ['fall', 'spring'])
|
||||
->where('ss.semester_score IS NOT NULL', null, false)
|
||||
@@ -3404,16 +3457,24 @@ public function allDecisions()
|
||||
's.lastname',
|
||||
's.gender',
|
||||
's.dob',
|
||||
's.is_active',
|
||||
'ss.class_section_id',
|
||||
'cs.class_section_name',
|
||||
'c.class_name',
|
||||
'e.enrollment_status',
|
||||
'e.is_withdrawn',
|
||||
'LOWER(TRIM(ss.semester)) AS sem_key',
|
||||
'ss.semester_score',
|
||||
])
|
||||
->join('students s', 's.id = ss.student_id', 'inner')
|
||||
->join('enrollments e', 'e.student_id = s.id AND e.school_year = ' . $this->db->escape($schoolYear), 'left')
|
||||
->join('classSection cs', 'cs.class_section_id = ss.class_section_id', 'left')
|
||||
->join('classes c', 'c.id = cs.class_id', 'left')
|
||||
->where('s.is_active', 1)
|
||||
->groupStart()
|
||||
->where('s.is_active', 1)
|
||||
->orWhere("LOWER(TRIM(e.enrollment_status)) IN ('denied','withdrawn','widthran','widthrawan','withdrawan','waitlist')", null, false)
|
||||
->orWhere('e.is_withdrawn', 1)
|
||||
->groupEnd()
|
||||
->where('ss.school_year', $schoolYear)
|
||||
->whereIn('LOWER(TRIM(ss.semester))', ['fall', 'spring'])
|
||||
->where('ss.semester_score IS NOT NULL', null, false)
|
||||
@@ -3440,6 +3501,9 @@ public function allDecisions()
|
||||
'lastname' => $sr['lastname'] ?? '',
|
||||
'gender' => $sr['gender'] ?? '',
|
||||
'dob' => $sr['dob'] ?? '',
|
||||
'is_active' => (int)($sr['is_active'] ?? 1),
|
||||
'enrollment_status' => $sr['enrollment_status'] ?? '',
|
||||
'is_withdrawn' => (int)($sr['is_withdrawn'] ?? 0),
|
||||
'class_section_id' => (int)($sr['class_section_id'] ?? 0),
|
||||
'class_name' => $sr['class_name'] ?? '',
|
||||
'class_section_name' => $sr['class_section_name'] ?? '',
|
||||
@@ -3538,6 +3602,9 @@ public function allDecisions()
|
||||
'lastname' => $info['lastname'],
|
||||
'gender' => $info['gender'] ?? '',
|
||||
'dob' => $info['dob'] ?? '',
|
||||
'is_active' => (int)($info['is_active'] ?? 1),
|
||||
'enrollment_status' => $info['enrollment_status'] ?? '',
|
||||
'is_withdrawn' => (int)($info['is_withdrawn'] ?? 0),
|
||||
'class_section_id' => (int)($info['class_section_id'] ?? 0),
|
||||
'class_name' => $currentClassName,
|
||||
'class_section_name' => $currentClassSectionName,
|
||||
@@ -3615,13 +3682,19 @@ public function generateAllDecisions()
|
||||
's.id AS student_id',
|
||||
's.firstname',
|
||||
's.lastname',
|
||||
's.is_active',
|
||||
'cs.class_section_name',
|
||||
'LOWER(TRIM(ss.semester)) AS sem_key',
|
||||
'ss.semester_score',
|
||||
])
|
||||
->join('students s', 's.id = ss.student_id', 'inner')
|
||||
->join('enrollments e', 'e.student_id = s.id AND e.school_year = ' . $this->db->escape($schoolYear), 'left')
|
||||
->join('classSection cs', 'cs.class_section_id = ss.class_section_id', 'left')
|
||||
->where('s.is_active', 1)
|
||||
->groupStart()
|
||||
->where('s.is_active', 1)
|
||||
->orWhere("LOWER(TRIM(e.enrollment_status)) IN ('denied','withdrawn','widthran','widthrawan','withdrawan','waitlist')", null, false)
|
||||
->orWhere('e.is_withdrawn', 1)
|
||||
->groupEnd()
|
||||
->where('ss.school_year', $schoolYear)
|
||||
->whereIn('LOWER(TRIM(ss.semester))', ['fall', 'spring'])
|
||||
->where('ss.semester_score IS NOT NULL', null, false)
|
||||
|
||||
@@ -176,7 +176,7 @@ class HomeworkController extends BaseController
|
||||
}
|
||||
}
|
||||
}
|
||||
$studentUserInfo = $this->studentModel->getStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
$studentUserInfo = $this->studentModel->getActiveStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
|
||||
// Call the updateScoresForStudents method
|
||||
try {
|
||||
@@ -404,7 +404,7 @@ class HomeworkController extends BaseController
|
||||
return $this->showHomeworkMngt($updatedBy);
|
||||
}
|
||||
|
||||
$studentTeacherInfo = $this->studentModel->getStudentInfoByClassSectionId($classSectionId);
|
||||
$studentTeacherInfo = $this->studentModel->getActiveStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
// Call the updateScoresForStudents method
|
||||
try {
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ class MidtermController extends BaseController
|
||||
true
|
||||
);
|
||||
|
||||
$studentTeacherInfo = $this->studentModel->getStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
$studentTeacherInfo = $this->studentModel->getActiveStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
// Call the updateScoresForStudents method
|
||||
try {
|
||||
|
||||
@@ -155,7 +155,7 @@ class MidtermController extends BaseController
|
||||
|
||||
session()->setFlashdata('status', 'Midterm exam scores updated successfully.');
|
||||
|
||||
$studentTeacherInfo = $this->studentModel->getStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
$studentTeacherInfo = $this->studentModel->getActiveStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
// Call the updateScoresForStudents method
|
||||
try {
|
||||
|
||||
@@ -288,6 +288,7 @@ class MidtermController extends BaseController
|
||||
// Join the "latest midterm per student" subquery, then the actual midterm row
|
||||
->join('(' . $latestMidtermSub . ') ml', 'ml.student_id = s.id', 'left', false)
|
||||
->join('midterm_exam me', 'me.id = ml.max_id', 'left')
|
||||
->where('s.is_active', 1)
|
||||
->orderBy('s.lastname', 'ASC')
|
||||
->orderBy('s.firstname', 'ASC');
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ class ParticipationController extends BaseController
|
||||
true
|
||||
);
|
||||
|
||||
$studentTeacherInfo = $this->studentModel->getStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
$studentTeacherInfo = $this->studentModel->getActiveStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
// Call the updateScoresForStudents method
|
||||
try {
|
||||
|
||||
@@ -156,7 +156,7 @@ class ParticipationController extends BaseController
|
||||
|
||||
session()->setFlashdata('status', 'Participation scores updated successfully.');
|
||||
|
||||
$studentTeacherInfo = $this->studentModel->getStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
$studentTeacherInfo = $this->studentModel->getActiveStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
// Call the updateScoresForStudents method
|
||||
try {
|
||||
|
||||
|
||||
@@ -227,7 +227,7 @@ class ProjectController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
$studentTeacherInfo = $studentModel->getStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
$studentTeacherInfo = $studentModel->getActiveStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
// Call the updateScoresForStudents method
|
||||
try {
|
||||
|
||||
@@ -361,7 +361,7 @@ class ProjectController extends BaseController
|
||||
return $this->showProjectMngt($updatedBy);
|
||||
}
|
||||
|
||||
$studentTeacherInfo = $studentModel->getStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
$studentTeacherInfo = $studentModel->getActiveStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
// Call the updateScoresForStudents method
|
||||
try {
|
||||
|
||||
|
||||
@@ -181,7 +181,7 @@ class QuizController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
$studentTeacherInfo = $this->studentModel->getStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
$studentTeacherInfo = $this->studentModel->getActiveStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
// Call the updateScoresForStudents method
|
||||
try {
|
||||
|
||||
@@ -444,7 +444,7 @@ class QuizController extends BaseController
|
||||
return $this->showQuizMngt();
|
||||
}
|
||||
|
||||
$studentTeacherInfo = $this->studentModel->getStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
$studentTeacherInfo = $this->studentModel->getActiveStudentInfoByClassSectionId($classSectionId, $semester, $schoolYear);
|
||||
// Call the updateScoresForStudents method
|
||||
try {
|
||||
|
||||
|
||||
@@ -217,7 +217,7 @@ class ScoreController extends BaseController
|
||||
$classSectionName = $csRow['class_section_name'] ?? '';
|
||||
log_message('debug', "ScoreController::index teacher {$teacherId} classSection {$classSectionId} semester {$effectiveSemester}");
|
||||
|
||||
$studentTeacherInfo = $this->studentModel->getStudentInfoByClassSectionId(
|
||||
$studentTeacherInfo = $this->studentModel->getActiveStudentInfoByClassSectionId(
|
||||
$classSectionId,
|
||||
$effectiveSemester,
|
||||
$effectiveSchoolYear
|
||||
@@ -1179,7 +1179,7 @@ class ScoreController extends BaseController
|
||||
// Ensure semester_scores are re-calculated when midterm/final exams change.
|
||||
if (in_array(strtolower($table), ['final_exam', 'midterm_exam'], true) && $this->semesterScoreService !== null) {
|
||||
try {
|
||||
$studentTeacherInfo = $this->studentModel->getStudentInfoByClassSectionId(
|
||||
$studentTeacherInfo = $this->studentModel->getActiveStudentInfoByClassSectionId(
|
||||
$classSectionId,
|
||||
$semester,
|
||||
$this->schoolYear
|
||||
|
||||
@@ -2783,13 +2783,23 @@ class StudentController extends BaseController
|
||||
return redirect()->back()->with('error', 'Invalid student id.');
|
||||
}
|
||||
|
||||
$roleRaw = session()->get('role');
|
||||
if (is_array($roleRaw)) {
|
||||
$roleRaw = $roleRaw[0] ?? 'guest';
|
||||
}
|
||||
$role = strtolower((string)($roleRaw ?? 'guest'));
|
||||
$isAdminScoreCardAccess = in_array($role, ['administrator', 'admin', 'principal', 'administrative staff'], true);
|
||||
|
||||
$student = $this->studentModel
|
||||
->select('id, firstname, lastname, school_id')
|
||||
->select('id, firstname, lastname, school_id, is_active')
|
||||
->where('id', $studentId)
|
||||
->first();
|
||||
if (!$student) {
|
||||
return $this->response->setStatusCode(404)->setBody('<div class="p-3 text-danger">Student not found.</div>');
|
||||
}
|
||||
if (!$isAdminScoreCardAccess && (int)($student['is_active'] ?? 0) !== 1) {
|
||||
return redirect()->to('/student/score-card/list')->with('error', 'Student score card is not available.');
|
||||
}
|
||||
|
||||
$rows = $this->db->table('semester_scores ss')
|
||||
->select([
|
||||
@@ -3011,14 +3021,14 @@ class StudentController extends BaseController
|
||||
$schoolYear = $this->currentSchoolYearName((string) ($this->schoolYear ?? ''));
|
||||
$parentId = (int)(session()->get('user_id') ?? 0);
|
||||
if ($parentId > 0 && $schoolYear !== '') {
|
||||
$students = $this->studentModel->getByParentAndYear($parentId, $schoolYear);
|
||||
$students = $this->studentModel->getActiveByParentAndYear($parentId, $schoolYear);
|
||||
}
|
||||
} elseif (in_array($role, ['teacher', 'teacher_assistant', 'teacher_dashboard'], true)) {
|
||||
$schoolYear = $this->currentSchoolYearName((string) ($this->schoolYear ?? ''));
|
||||
$classSectionId = (int)(session()->get('class_section_id') ?? 0);
|
||||
|
||||
if ($classSectionId > 0 && !empty($schoolYear)) {
|
||||
$students = $this->studentModel->getByClassAndYear($classSectionId, $schoolYear);
|
||||
$students = $this->studentModel->getActiveByClassAndYear($classSectionId, $schoolYear);
|
||||
}
|
||||
|
||||
if (empty($students)) {
|
||||
@@ -3039,10 +3049,10 @@ class StudentController extends BaseController
|
||||
$studentClassModel = new \App\Models\StudentClassModel();
|
||||
$rows = $studentClassModel->getStudentsByClassSectionIds($sectionIds, $schoolYear);
|
||||
$unique = [];
|
||||
foreach ($rows as $r) {
|
||||
$sid = (int)($r['student_id'] ?? 0);
|
||||
if ($sid > 0) {
|
||||
$unique[$sid] = [
|
||||
foreach ($rows as $r) {
|
||||
$sid = (int)($r['student_id'] ?? 0);
|
||||
if ($sid > 0 && (int)($r['is_active'] ?? 0) === 1) {
|
||||
$unique[$sid] = [
|
||||
'id' => $sid,
|
||||
'school_id' => $r['school_id'] ?? '',
|
||||
'firstname' => $r['firstname'] ?? '',
|
||||
|
||||
@@ -125,6 +125,9 @@ class TeacherController extends BaseController
|
||||
if (!empty($classSectionIds)) {
|
||||
// 1) Fetch all students for the selected class sections
|
||||
$students = $this->studentClassModel->getStudentsByClassSectionIds($classSectionIds, (string) $this->schoolYear);
|
||||
$students = array_values(array_filter($students, static function (array $student): bool {
|
||||
return (int)($student['is_active'] ?? 0) === 1;
|
||||
}));
|
||||
|
||||
if (!empty($students)) {
|
||||
// 2) Collect unique student IDs
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
if (!function_exists('student_normalized_enrollment_status')) {
|
||||
function student_normalized_enrollment_status(array $student, ?string $schoolYear = null): string
|
||||
{
|
||||
$studentId = (int)($student['student_id'] ?? $student['id'] ?? 0);
|
||||
$status = strtolower(trim((string)($student['enrollment_status'] ?? '')));
|
||||
if ($status === 'widthran' || $status === 'widthrawan' || $status === 'withdrawan' || $status === 'withdrawn student' || (int)($student['is_withdrawn'] ?? 0) === 1) {
|
||||
$status = 'withdrawn';
|
||||
}
|
||||
|
||||
if ($status === '' && $studentId > 0) {
|
||||
$schoolYear = trim((string)($schoolYear ?? ''));
|
||||
if ($schoolYear === '') {
|
||||
try {
|
||||
$schoolYear = (string)((new \App\Models\ConfigurationModel())->getConfig('school_year') ?? '');
|
||||
} catch (\Throwable $e) {
|
||||
$schoolYear = '';
|
||||
}
|
||||
}
|
||||
|
||||
static $statusCache = [];
|
||||
$cacheKey = $studentId . ':' . $schoolYear;
|
||||
if (!array_key_exists($cacheKey, $statusCache)) {
|
||||
$statusCache[$cacheKey] = '';
|
||||
if ($schoolYear !== '') {
|
||||
try {
|
||||
$row = db_connect()->table('enrollments')
|
||||
->select('enrollment_status, is_withdrawn')
|
||||
->where('student_id', $studentId)
|
||||
->where('school_year', $schoolYear)
|
||||
->orderBy('updated_at', 'DESC')
|
||||
->orderBy('enrollment_date', 'DESC')
|
||||
->orderBy('id', 'DESC')
|
||||
->get(1)
|
||||
->getRowArray();
|
||||
$rowStatus = strtolower(trim((string)($row['enrollment_status'] ?? '')));
|
||||
if ($rowStatus === 'widthran' || $rowStatus === 'widthrawan' || $rowStatus === 'withdrawan' || $rowStatus === 'withdrawn student' || (int)($row['is_withdrawn'] ?? 0) === 1) {
|
||||
$rowStatus = 'withdrawn';
|
||||
}
|
||||
$statusCache[$cacheKey] = $rowStatus;
|
||||
} catch (\Throwable $e) {
|
||||
$statusCache[$cacheKey] = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
$status = $statusCache[$cacheKey];
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('student_is_non_active_for_editing')) {
|
||||
function student_is_non_active_for_editing(array $student, ?string $schoolYear = null): bool
|
||||
{
|
||||
$status = student_normalized_enrollment_status($student, $schoolYear);
|
||||
|
||||
if (in_array($status, ['denied', 'withdrawn', 'waitlist'], true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return array_key_exists('is_active', $student) && (int)$student['is_active'] !== 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('student_enrollment_status_button')) {
|
||||
function student_enrollment_status_button(array $student, ?string $schoolYear = null): string
|
||||
{
|
||||
$status = student_normalized_enrollment_status($student, $schoolYear);
|
||||
|
||||
$classes = [
|
||||
'denied' => 'btn-outline-danger',
|
||||
'withdrawn' => 'btn-outline-secondary',
|
||||
'waitlist' => 'btn-outline-warning',
|
||||
];
|
||||
|
||||
if (!isset($classes[$status])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '<div class="mt-1"><span class="btn btn-sm ' . esc($classes[$status], 'attr') . ' disabled py-0 px-2 student-enrollment-status" aria-disabled="true">' . esc(ucwords($status)) . '</span></div>';
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,32 @@ class StudentClassModel extends Model
|
||||
return $this->db->table($this->table);
|
||||
}
|
||||
|
||||
private function includeActiveOrTerminalEnrollment(BaseBuilder $builder, string $schoolYear): BaseBuilder
|
||||
{
|
||||
$terminalStatuses = array_map([$this->db, 'escape'], [
|
||||
'denied',
|
||||
'withdrawn',
|
||||
'widthran',
|
||||
'widthrawan',
|
||||
'withdrawan',
|
||||
'waitlist',
|
||||
]);
|
||||
|
||||
$builder->groupStart()
|
||||
->where('students.is_active', 1);
|
||||
|
||||
if ($schoolYear !== '') {
|
||||
$builder->orWhere(
|
||||
'LOWER(TRIM(enrollments.enrollment_status)) IN (' . implode(',', $terminalStatuses) . ')',
|
||||
null,
|
||||
false
|
||||
)
|
||||
->orWhere('enrollments.is_withdrawn', 1);
|
||||
}
|
||||
|
||||
return $builder->groupEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a fresh builder scoped to active students.
|
||||
*/
|
||||
@@ -131,7 +157,8 @@ class StudentClassModel extends Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active students assigned to a class section.
|
||||
* Get students assigned to a class section, including inactive students with
|
||||
* terminal current-year enrollment statuses.
|
||||
*
|
||||
* student_class is scoped by school year only. It has no semester column.
|
||||
*/
|
||||
@@ -139,7 +166,22 @@ class StudentClassModel extends Model
|
||||
int $classSectionId,
|
||||
?string $schoolYear = null
|
||||
): array {
|
||||
$builder = $this->activeStudentsBuilder()
|
||||
$schoolYear = $schoolYear !== null ? trim($schoolYear) : '';
|
||||
|
||||
$builder = $this->freshBuilder()
|
||||
->select('student_class.*, students.is_active, enrollments.enrollment_status, enrollments.is_withdrawn')
|
||||
->join(
|
||||
'students',
|
||||
'students.id = student_class.student_id',
|
||||
'inner'
|
||||
)
|
||||
->join(
|
||||
'enrollments',
|
||||
$schoolYear !== ''
|
||||
? 'enrollments.student_id = student_class.student_id AND enrollments.school_year = ' . $this->db->escape($schoolYear)
|
||||
: 'enrollments.student_id = student_class.student_id',
|
||||
'left'
|
||||
)
|
||||
->where(
|
||||
'student_class.class_section_id',
|
||||
$classSectionId
|
||||
@@ -150,13 +192,15 @@ class StudentClassModel extends Model
|
||||
false
|
||||
);
|
||||
|
||||
if ($schoolYear !== null && trim($schoolYear) !== '') {
|
||||
if ($schoolYear !== '') {
|
||||
$builder->where(
|
||||
'student_class.school_year',
|
||||
trim($schoolYear)
|
||||
$schoolYear
|
||||
);
|
||||
}
|
||||
|
||||
$this->includeActiveOrTerminalEnrollment($builder, $schoolYear);
|
||||
|
||||
$rows = $builder
|
||||
->orderBy('students.lastname', 'ASC')
|
||||
->orderBy('students.firstname', 'ASC')
|
||||
@@ -195,7 +239,6 @@ class StudentClassModel extends Model
|
||||
'student_class.class_section_id',
|
||||
$classSectionId
|
||||
)
|
||||
->where('students.is_active', 1)
|
||||
->where(
|
||||
'student_class.class_section_id IS NOT NULL',
|
||||
null,
|
||||
@@ -206,9 +249,16 @@ class StudentClassModel extends Model
|
||||
$builder->where(
|
||||
'student_class.school_year',
|
||||
$schoolYear
|
||||
)
|
||||
->join(
|
||||
'enrollments',
|
||||
'enrollments.student_id = student_class.student_id AND enrollments.school_year = ' . $this->db->escape($schoolYear),
|
||||
'left'
|
||||
);
|
||||
}
|
||||
|
||||
$this->includeActiveOrTerminalEnrollment($builder, $schoolYear);
|
||||
|
||||
$rows = $builder
|
||||
->groupBy('student_class.student_id')
|
||||
->get()
|
||||
@@ -364,7 +414,8 @@ class StudentClassModel extends Model
|
||||
}
|
||||
|
||||
/**
|
||||
* Return active students for a set of class-section IDs.
|
||||
* Return students for a set of class-section IDs, including inactive
|
||||
* students with terminal current-year enrollment statuses.
|
||||
*/
|
||||
public function getStudentsByClassSectionIds(
|
||||
array $classSectionIds,
|
||||
@@ -379,37 +430,50 @@ class StudentClassModel extends Model
|
||||
return [];
|
||||
}
|
||||
|
||||
$schoolYear = $schoolYear !== null ? trim($schoolYear) : '';
|
||||
|
||||
$builder = $this->freshBuilder()
|
||||
->select([
|
||||
'students.id AS student_id',
|
||||
'students.firstname',
|
||||
'students.lastname',
|
||||
'students.school_id',
|
||||
'students.is_active',
|
||||
'students.is_new',
|
||||
'students.photo_consent',
|
||||
'students.age',
|
||||
'student_class.school_year',
|
||||
'student_class.class_section_id',
|
||||
'student_class.is_event_only',
|
||||
'enrollments.enrollment_status',
|
||||
'enrollments.is_withdrawn',
|
||||
])
|
||||
->join(
|
||||
'students',
|
||||
'students.id = student_class.student_id',
|
||||
'inner'
|
||||
)
|
||||
->join(
|
||||
'enrollments',
|
||||
$schoolYear !== ''
|
||||
? 'enrollments.student_id = student_class.student_id AND enrollments.school_year = ' . $this->db->escape($schoolYear)
|
||||
: 'enrollments.student_id = student_class.student_id',
|
||||
'left'
|
||||
)
|
||||
->whereIn(
|
||||
'student_class.class_section_id',
|
||||
$classSectionIds
|
||||
)
|
||||
->where('students.is_active', 1);
|
||||
);
|
||||
|
||||
if ($schoolYear !== null && trim($schoolYear) !== '') {
|
||||
if ($schoolYear !== '') {
|
||||
$builder->where(
|
||||
'student_class.school_year',
|
||||
trim($schoolYear)
|
||||
$schoolYear
|
||||
);
|
||||
}
|
||||
|
||||
$this->includeActiveOrTerminalEnrollment($builder, $schoolYear);
|
||||
|
||||
return $builder
|
||||
->orderBy('students.lastname', 'ASC')
|
||||
->orderBy('students.firstname', 'ASC')
|
||||
@@ -504,7 +568,6 @@ class StudentClassModel extends Model
|
||||
'students.id = student_class.student_id',
|
||||
'inner'
|
||||
)
|
||||
->where('students.is_active', 1)
|
||||
->where(
|
||||
'student_class.class_section_id IS NOT NULL',
|
||||
null,
|
||||
@@ -513,12 +576,22 @@ class StudentClassModel extends Model
|
||||
->groupBy('student_class.class_section_id');
|
||||
|
||||
if ($schoolYear !== null && trim($schoolYear) !== '') {
|
||||
$schoolYear = trim($schoolYear);
|
||||
$builder->where(
|
||||
'student_class.school_year',
|
||||
trim($schoolYear)
|
||||
$schoolYear
|
||||
)
|
||||
->join(
|
||||
'enrollments',
|
||||
'enrollments.student_id = student_class.student_id AND enrollments.school_year = ' . $this->db->escape($schoolYear),
|
||||
'left'
|
||||
);
|
||||
} else {
|
||||
$schoolYear = '';
|
||||
}
|
||||
|
||||
$this->includeActiveOrTerminalEnrollment($builder, $schoolYear);
|
||||
|
||||
$rows = $builder
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
+109
-21
@@ -292,25 +292,42 @@ class StudentModel extends Model
|
||||
|
||||
public function getByClassAndYear($class_section_id, $school_year, ?string $semester = null): array
|
||||
{
|
||||
$studentClassModel = new \App\Models\StudentClassModel();
|
||||
$school_year = trim((string) $school_year);
|
||||
|
||||
$builder = $studentClassModel
|
||||
->select('student_id')
|
||||
->where('class_section_id', $class_section_id)
|
||||
->where('school_year', $school_year);
|
||||
$builder = $this->select('students.*, e.enrollment_status, e.is_withdrawn')
|
||||
->join('student_class sc', 'sc.student_id = students.id', 'inner')
|
||||
->join(
|
||||
'enrollments e',
|
||||
'e.student_id = students.id AND e.school_year = ' . $this->db->escape($school_year),
|
||||
'left'
|
||||
)
|
||||
->where('sc.class_section_id', $class_section_id)
|
||||
->where('sc.school_year', $school_year)
|
||||
->groupStart()
|
||||
->where('students.is_active', 1)
|
||||
->orWhere("LOWER(TRIM(e.enrollment_status)) IN ('denied','withdrawn','widthran','widthrawan','withdrawan','waitlist')", null, false)
|
||||
->orWhere('e.is_withdrawn', 1)
|
||||
->groupEnd();
|
||||
|
||||
$studentIds = $builder->findAll();
|
||||
return $builder
|
||||
->distinct()
|
||||
->orderBy('students.firstname', 'ASC')
|
||||
->orderBy('students.lastname', 'ASC')
|
||||
->findAll();
|
||||
}
|
||||
|
||||
$studentIds = array_column($studentIds, 'student_id');
|
||||
public function getActiveByClassAndYear($class_section_id, $school_year, ?string $semester = null): array
|
||||
{
|
||||
$school_year = trim((string) $school_year);
|
||||
|
||||
if (empty($studentIds)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->whereIn('id', $studentIds)
|
||||
->where('is_active', 1)
|
||||
->orderBy('firstname', 'ASC')
|
||||
->orderBy('lastname', 'ASC')
|
||||
return $this->select('students.*')
|
||||
->join('student_class sc', 'sc.student_id = students.id', 'inner')
|
||||
->where('sc.class_section_id', $class_section_id)
|
||||
->where('sc.school_year', $school_year)
|
||||
->where('students.is_active', 1)
|
||||
->distinct()
|
||||
->orderBy('students.firstname', 'ASC')
|
||||
->orderBy('students.lastname', 'ASC')
|
||||
->findAll();
|
||||
}
|
||||
|
||||
@@ -322,12 +339,36 @@ class StudentModel extends Model
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->select('students.id, students.school_id, students.firstname, students.lastname')
|
||||
return $this->select('students.id, students.school_id, students.firstname, students.lastname, students.is_active, e.enrollment_status, e.is_withdrawn')
|
||||
->join('student_class', 'student_class.student_id = students.id', 'inner')
|
||||
->join('enrollments e', 'e.student_id = students.id AND e.school_year = ' . $this->db->escape($schoolYear), 'left')
|
||||
->where('students.parent_id', $parentId)
|
||||
->where('student_class.school_year', $schoolYear)
|
||||
->groupStart()
|
||||
->where('students.is_active', 1)
|
||||
->orWhere("LOWER(TRIM(e.enrollment_status)) IN ('denied','withdrawn','widthran','widthrawan','withdrawan','waitlist')", null, false)
|
||||
->orWhere('e.is_withdrawn', 1)
|
||||
->groupEnd()
|
||||
->groupBy('students.id, students.school_id, students.firstname, students.lastname, students.is_active, e.enrollment_status, e.is_withdrawn')
|
||||
->orderBy('students.lastname', 'ASC')
|
||||
->orderBy('students.firstname', 'ASC')
|
||||
->findAll();
|
||||
}
|
||||
|
||||
public function getActiveByParentAndYear(int $parentId, string $schoolYear): array
|
||||
{
|
||||
$schoolYear = trim($schoolYear);
|
||||
|
||||
if ($parentId <= 0 || $schoolYear === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->select('students.id, students.school_id, students.firstname, students.lastname, students.is_active')
|
||||
->join('student_class', 'student_class.student_id = students.id', 'inner')
|
||||
->where('students.parent_id', $parentId)
|
||||
->where('students.is_active', 1)
|
||||
->where('student_class.school_year', $schoolYear)
|
||||
->groupBy('students.id, students.school_id, students.firstname, students.lastname')
|
||||
->where('students.is_active', 1)
|
||||
->groupBy('students.id, students.school_id, students.firstname, students.lastname, students.is_active')
|
||||
->orderBy('students.lastname', 'ASC')
|
||||
->orderBy('students.firstname', 'ASC')
|
||||
->findAll();
|
||||
@@ -443,16 +484,28 @@ class StudentModel extends Model
|
||||
$builder = $this->builder();
|
||||
|
||||
$builder
|
||||
->select('students.id AS student_id, students.school_id, students.firstname, students.lastname, sc.class_section_id')
|
||||
->select('students.id AS student_id, students.school_id, students.firstname, students.lastname, students.is_active, sc.class_section_id, e.enrollment_status, e.is_withdrawn')
|
||||
->join('student_class sc', 'sc.student_id = students.id', 'inner')
|
||||
->where('sc.class_section_id', $classSectionId)
|
||||
->where('students.is_active', 1);
|
||||
->where('sc.class_section_id', $classSectionId);
|
||||
|
||||
// Optional term scoping (safe no-ops if null)
|
||||
if ($schoolYear !== null) {
|
||||
$builder->where('sc.school_year', $schoolYear);
|
||||
$builder->join(
|
||||
'enrollments e',
|
||||
'e.student_id = students.id AND e.school_year = ' . $this->db->escape($schoolYear),
|
||||
'left'
|
||||
);
|
||||
} else {
|
||||
$builder->join('enrollments e', 'e.student_id = students.id', 'left');
|
||||
}
|
||||
|
||||
$builder->groupStart()
|
||||
->where('students.is_active', 1)
|
||||
->orWhere("LOWER(TRIM(e.enrollment_status)) IN ('denied','withdrawn','widthran','widthrawan','withdrawan','waitlist')", null, false)
|
||||
->orWhere('e.is_withdrawn', 1)
|
||||
->groupEnd();
|
||||
|
||||
// Prevent accidental dupes if student_class has multiple rows
|
||||
$builder->distinct();
|
||||
$builder->orderBy('students.lastname', 'ASC')
|
||||
@@ -472,6 +525,41 @@ class StudentModel extends Model
|
||||
return $results ?: [];
|
||||
}
|
||||
|
||||
public function getActiveStudentInfoByClassSectionId($classSectionId, ?string $semester = null, ?string $schoolYear = null): array
|
||||
{
|
||||
$classSectionId = (int) $classSectionId;
|
||||
if ($classSectionId <= 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$builder = $this->builder();
|
||||
$builder
|
||||
->select('students.id AS student_id, students.school_id, students.firstname, students.lastname, students.is_active, sc.class_section_id')
|
||||
->join('student_class sc', 'sc.student_id = students.id', 'inner')
|
||||
->where('sc.class_section_id', $classSectionId)
|
||||
->where('students.is_active', 1);
|
||||
|
||||
if ($schoolYear !== null) {
|
||||
$builder->where('sc.school_year', $schoolYear);
|
||||
}
|
||||
|
||||
$builder->distinct();
|
||||
$builder->orderBy('students.lastname', 'ASC')
|
||||
->orderBy('students.firstname', 'ASC');
|
||||
|
||||
$results = $builder->get()->getResultArray();
|
||||
|
||||
$userId = (int) (session()->get('user_id') ?? 0);
|
||||
if (!empty($results)) {
|
||||
foreach ($results as &$row) {
|
||||
$row['updated_by'] = $userId;
|
||||
}
|
||||
unset($row);
|
||||
}
|
||||
|
||||
return $results ?: [];
|
||||
}
|
||||
|
||||
|
||||
// In your existing StudentModel
|
||||
public function getStudentBasic(int $studentId): ?array
|
||||
|
||||
@@ -77,7 +77,10 @@
|
||||
<?php foreach ($records as $r): ?>
|
||||
<tr>
|
||||
<td><code><?= esc($r['certificate_number']) ?></code></td>
|
||||
<td><?= esc($r['student_name']) ?></td>
|
||||
<td>
|
||||
<?= esc($r['student_name']) ?>
|
||||
<?= student_enrollment_status_button($r, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($r['grade'] ?? '—') ?></td>
|
||||
<td><?= $r['cert_date'] ? esc(date('m/d/Y', strtotime($r['cert_date']))) : '—' ?></td>
|
||||
<td><?= esc($r['school_year'] ?? '—') ?></td>
|
||||
|
||||
@@ -245,7 +245,10 @@ $decisionBadge = [
|
||||
<?= $isPass ? '' : 'disabled' ?>>
|
||||
</td>
|
||||
|
||||
<td><?= esc($s['firstname']) ?></td>
|
||||
<td>
|
||||
<?= esc($s['firstname']) ?>
|
||||
<?= student_enrollment_status_button($s, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($s['lastname']) ?></td>
|
||||
|
||||
<td class="text-center fw-semibold">
|
||||
@@ -624,4 +627,4 @@ window.showCertificatePdf=function(url,fn){
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
<?= $this->endSection() ?>
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
@@ -82,7 +82,10 @@
|
||||
?>
|
||||
<tr>
|
||||
<td><?= esc($schoolId ?: $studentId) ?></td>
|
||||
<td><?= esc($name !== '' ? $name : ('Student #' . $studentId)) ?></td>
|
||||
<td>
|
||||
<?= esc($name !== '' ? $name : ('Student #' . $studentId)) ?>
|
||||
<?= student_enrollment_status_button($s, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td data-order="<?= esc($val) ?>">
|
||||
<input class="form-control form-control-sm"
|
||||
name="scores[<?= esc($studentId) ?>]"
|
||||
|
||||
@@ -84,7 +84,10 @@
|
||||
<tr class="class-color-<?= esc((string) $colorIndex) ?>">
|
||||
<td><?= esc($classLabel) ?></td>
|
||||
<td><?= esc($row['school_id'] ?? $row['student_id'] ?? '-') ?></td>
|
||||
<td><?= esc($studentLabel) ?></td>
|
||||
<td>
|
||||
<?= esc($studentLabel) ?>
|
||||
<?= student_enrollment_status_button($row, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($photoConsentLabel) ?></td>
|
||||
<td><?= esc($row['rank'] ?? '-') ?></td>
|
||||
<td><?= esc($scoreLabel) ?></td>
|
||||
|
||||
@@ -78,7 +78,10 @@
|
||||
<?php foreach ($students as $s): ?>
|
||||
<tr>
|
||||
<td><?= esc($s['school_id'] ?? '') ?></td>
|
||||
<td><?= esc(($s['firstname'] ?? '') . ' ' . ($s['lastname'] ?? '')) ?></td>
|
||||
<td>
|
||||
<?= esc(($s['firstname'] ?? '') . ' ' . ($s['lastname'] ?? '')) ?>
|
||||
<?= student_enrollment_status_button($s, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ((int)($s['is_active'] ?? 0) === 1): ?>
|
||||
<span class="badge text-bg-success">Active</span>
|
||||
|
||||
@@ -237,7 +237,10 @@
|
||||
<tr>
|
||||
<td><?= $i + 1 ?></td>
|
||||
<td><?= esc($s['school_id']) ?></td>
|
||||
<td><?= esc(trim(($s['firstname'] ?? '') . ' ' . ($s['lastname'] ?? ''))) ?></td>
|
||||
<td>
|
||||
<?= esc(trim(($s['firstname'] ?? '') . ' ' . ($s['lastname'] ?? ''))) ?>
|
||||
<?= student_enrollment_status_button($s, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($s['gender'] ?? '') ?></td>
|
||||
<td><?= esc($s['dob'] ?? '') ?></td>
|
||||
<td><?= esc($s['rfid_tag'] ?? '') ?></td>
|
||||
@@ -375,7 +378,10 @@
|
||||
<tr>
|
||||
<td><?= $i + 1 ?></td>
|
||||
<td><?= esc($s['school_id'] ?? '') ?></td>
|
||||
<td><?= esc(trim(($s['firstname'] ?? '') . ' ' . ($s['lastname'] ?? ''))) ?></td>
|
||||
<td>
|
||||
<?= esc(trim(($s['firstname'] ?? '') . ' ' . ($s['lastname'] ?? ''))) ?>
|
||||
<?= student_enrollment_status_button($s, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($s['dob'] ?? '') ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
|
||||
@@ -72,8 +72,10 @@
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= $sid ?>">
|
||||
<?= esc($student['firstname']) ?>
|
||||
</a>
|
||||
<?= student_enrollment_status_button($student, $selectedYear ?? $schoolYear ?? null) ?>
|
||||
<?php else: ?>
|
||||
<?= esc($student['firstname']) ?>
|
||||
<?= student_enrollment_status_button($student, $selectedYear ?? $schoolYear ?? null) ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -148,6 +148,37 @@
|
||||
</style>
|
||||
<?= $this->endSection() ?>
|
||||
|
||||
<?php
|
||||
$semesterOptions = ['Fall', 'Spring'];
|
||||
$selectedSemester = trim((string)($semester ?? ''));
|
||||
if ($selectedSemester !== '' && !in_array($selectedSemester, $semesterOptions, true)) {
|
||||
$semesterOptions[] = $selectedSemester;
|
||||
}
|
||||
$selectedSchoolYear = trim((string)($schoolYear ?? ''));
|
||||
$selectedClassId = (int)($_GET['class_id'] ?? 0);
|
||||
?>
|
||||
|
||||
<form id="attendanceTermFilter" method="get" action="<?= site_url('administrator/daily_attendance') ?>" class="row g-2 justify-content-center align-items-end mb-3">
|
||||
<input type="hidden" id="attendanceClassIdFilter" name="class_id" value="<?= $selectedClassId > 0 ? $selectedClassId : '' ?>">
|
||||
<div class="col-12 col-sm-5 col-md-3 col-lg-2">
|
||||
<label for="attendanceSemesterFilter" class="form-label mb-1">Semester</label>
|
||||
<select id="attendanceSemesterFilter" name="semester" class="form-select" onchange="this.form.submit()">
|
||||
<?php foreach ($semesterOptions as $option): ?>
|
||||
<option value="<?= esc($option) ?>" <?= $option === $selectedSemester ? 'selected' : '' ?>>
|
||||
<?= esc($option) ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 col-sm-5 col-md-3 col-lg-2">
|
||||
<label for="attendanceSchoolYearFilter" class="form-label mb-1">School Year</label>
|
||||
<input id="attendanceSchoolYearFilter" type="text" name="school_year" class="form-control" value="<?= esc($selectedSchoolYear) ?>" placeholder="YYYY-YYYY">
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button type="submit" class="btn btn-primary">Apply</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- ===================== Global Student Search ===================== -->
|
||||
<div class="row g-2 justify-content-center mb-3">
|
||||
<div class="col-12 col-md-8 col-lg-6">
|
||||
@@ -358,8 +389,11 @@
|
||||
$studentsCountByClassId[$cid] = count($uniq);
|
||||
}
|
||||
|
||||
// Default active tab = first in sorted order (can still be overridden by ?class_id)
|
||||
$defaultId = $sortedClassIds[0] ?? null;
|
||||
// Default active tab = first in sorted order unless ?class_id selects a visible grade.
|
||||
$requestedClassId = (int)($_GET['class_id'] ?? 0);
|
||||
$defaultId = ($requestedClassId > 0 && in_array($requestedClassId, $sortedClassIds, true))
|
||||
? $requestedClassId
|
||||
: ($sortedClassIds[0] ?? null);
|
||||
|
||||
// =====================================================================
|
||||
// NEW UTILITIES (dates pivot logic) — includes "today if Sunday, else next Sunday" column
|
||||
@@ -716,18 +750,20 @@
|
||||
$tAbsent = $summary ? (int)($summary['total_absence'] ?? 0) : 0;
|
||||
|
||||
|
||||
$schoolId = esc($student['school_id']);
|
||||
$fullNameRaw = trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? ''));
|
||||
$fullName = esc($fullNameRaw);
|
||||
$fullNameAttr = esc(strtolower($fullNameRaw));
|
||||
?>
|
||||
<tr
|
||||
data-student-id="<?= (int)$sid ?>"
|
||||
data-school-id="<?= $schoolId ?>"
|
||||
data-student-name="<?= $fullNameAttr ?>"
|
||||
data-student-name-display="<?= esc($fullNameRaw) ?>"
|
||||
data-class-id="<?= (int)$cid ?>"
|
||||
data-grade-label="<?= esc($headerText) ?>">
|
||||
$schoolId = esc($student['school_id']);
|
||||
$fullNameRaw = trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? ''));
|
||||
$fullName = esc($fullNameRaw);
|
||||
$fullNameAttr = esc(strtolower($fullNameRaw));
|
||||
$rowLocked = student_is_non_active_for_editing($student, $schoolYear ?? null);
|
||||
?>
|
||||
<tr class="<?= $rowLocked ? 'table-secondary text-muted' : '' ?>"
|
||||
data-student-id="<?= (int)$sid ?>"
|
||||
data-student-editable="<?= $rowLocked ? '0' : '1' ?>"
|
||||
data-school-id="<?= $schoolId ?>"
|
||||
data-student-name="<?= $fullNameAttr ?>"
|
||||
data-student-name-display="<?= esc($fullNameRaw) ?>"
|
||||
data-class-id="<?= (int)$cid ?>"
|
||||
data-grade-label="<?= esc($headerText) ?>">
|
||||
<td class="school-id-col" style="min-width: <?= (int)$minIdCh ?>ch;"><?= $schoolId ?></td>
|
||||
<td class="student-name-col" style="min-width: <?= (int)$minNameCh ?>ch;">
|
||||
<a
|
||||
@@ -737,6 +773,7 @@
|
||||
title="Open family card">
|
||||
<?= $fullName ?>
|
||||
</a>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
|
||||
<?php foreach ($dateCols as $dcol): ?>
|
||||
@@ -757,12 +794,13 @@
|
||||
<td class="text-center date-col" style="min-width:160px;">
|
||||
<select
|
||||
class="form-select form-select-sm day-select"
|
||||
data-class-id="<?= (int)$cid ?>"
|
||||
data-class-section-id="<?= esc($sectionKey) ?>"
|
||||
data-student-id="<?= (int)$sid ?>"
|
||||
data-school-id="<?= esc($student['school_id']) ?>"
|
||||
data-date="<?= esc($dcol) ?>"
|
||||
aria-label="Attendance on <?= esc($dLabel) ?>">
|
||||
data-class-id="<?= (int)$cid ?>"
|
||||
data-class-section-id="<?= esc($sectionKey) ?>"
|
||||
data-student-id="<?= (int)$sid ?>"
|
||||
data-school-id="<?= esc($student['school_id']) ?>"
|
||||
data-date="<?= esc($dcol) ?>"
|
||||
<?= $rowLocked ? 'disabled aria-disabled="true"' : '' ?>
|
||||
aria-label="Attendance on <?= esc($dLabel) ?>">
|
||||
<?php foreach ($optionDefs as $key => $def): ?>
|
||||
<option value="<?= $key ?>" <?= $key === $val ? 'selected' : '' ?>>
|
||||
<?= esc($def['label']) ?>
|
||||
@@ -865,6 +903,15 @@ $attendanceSaveUrlIndex = '/index.php/' . $savePath; // index.php fallbac
|
||||
|
||||
const TERM_SCHOOL_YEAR = <?= json_encode($schoolYear ?? '') ?>;
|
||||
const TERM_SEMESTER = <?= json_encode($semester ?? '') ?>;
|
||||
|
||||
document.querySelectorAll('#attendanceTabs [data-class-id]').forEach((tab) => {
|
||||
tab.addEventListener('shown.bs.tab', () => {
|
||||
const classIdInput = document.getElementById('attendanceClassIdFilter');
|
||||
if (classIdInput) {
|
||||
classIdInput.value = tab.getAttribute('data-class-id') || '';
|
||||
}
|
||||
});
|
||||
});
|
||||
<?php
|
||||
$___adminName = isset($currentAdminName) && $currentAdminName !== ''
|
||||
? (string)$currentAdminName
|
||||
@@ -1095,8 +1142,15 @@ $attendanceSaveUrlIndex = '/index.php/' . $savePath; // index.php fallbac
|
||||
},
|
||||
};
|
||||
|
||||
async function postAttendanceChange(selEl) {
|
||||
const v = selEl.value;
|
||||
async function postAttendanceChange(selEl) {
|
||||
if (selEl.disabled || selEl.closest('tr')?.dataset.studentEditable === '0') {
|
||||
return {
|
||||
ok: true,
|
||||
skipped: true
|
||||
};
|
||||
}
|
||||
|
||||
const v = selEl.value;
|
||||
if (v === 'none') return {
|
||||
ok: true,
|
||||
skipped: true
|
||||
@@ -1232,9 +1286,10 @@ $attendanceSaveUrlIndex = '/index.php/' . $savePath; // index.php fallbac
|
||||
badge.textContent = meta.short;
|
||||
}
|
||||
|
||||
document.addEventListener('change', async (e) => {
|
||||
const sel = e.target.closest('select.day-select');
|
||||
if (!sel) return;
|
||||
document.addEventListener('change', async (e) => {
|
||||
const sel = e.target.closest('select.day-select');
|
||||
if (!sel) return;
|
||||
if (sel.disabled || sel.closest('tr')?.dataset.studentEditable === '0') return;
|
||||
|
||||
const tr = sel.closest('tr');
|
||||
const prev = sel.getAttribute('data-prev') || sel.value;
|
||||
|
||||
@@ -441,7 +441,10 @@
|
||||
<?php else: ?>
|
||||
<?php foreach ($studentIssueRows as $row): ?>
|
||||
<tr>
|
||||
<td><?= esc($row['name']) ?></td>
|
||||
<td>
|
||||
<?= esc($row['name']) ?>
|
||||
<?= student_enrollment_status_button($row, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($row['section']) ?></td>
|
||||
<td class="text-end"><?= (int)$row['absent'] ?></td>
|
||||
<td class="text-end"><?= (int)$row['late'] ?></td>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
$sid = (int)($s['id'] ?? $s['student_id'] ?? 0);
|
||||
$label = esc(($s['firstname'] ?? '') . ' ' . ($s['lastname'] ?? ''));
|
||||
if ($sid > 0) {
|
||||
return '<a href="#" class="text-decoration-none" data-family-student-id="' . $sid . '">' . $label . '</a>';
|
||||
return '<a href="#" class="text-decoration-none" data-family-student-id="' . $sid . '">' . $label . '</a>' . student_enrollment_status_button(['student_id' => $sid]);
|
||||
}
|
||||
return $label;
|
||||
}, $group['students']);
|
||||
|
||||
@@ -326,7 +326,10 @@ $reasonCodes = is_array($exceptionReasonCodes ?? null) ? $exceptionReasonCodes :
|
||||
$priorityClass = strtolower($priorityValue) === 'high' ? 'bg-danger' : 'bg-secondary';
|
||||
?>
|
||||
<tr>
|
||||
<td><?= esc($flag['student_name'] ?? '') ?></td>
|
||||
<td>
|
||||
<?= esc($flag['student_name'] ?? '') ?>
|
||||
<?= student_enrollment_status_button($flag, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($flag['school_id'] ?? '') ?></td>
|
||||
<td><span class="badge bg-secondary"><?= esc(enrollment_admin_flag_label($flagTypeValue)) ?></span></td>
|
||||
<td><span class="badge <?= esc($priorityClass) ?>"><?= esc(enrollment_admin_priority_label($priorityValue)) ?></span></td>
|
||||
@@ -427,7 +430,10 @@ $reasonCodes = is_array($exceptionReasonCodes ?? null) ? $exceptionReasonCodes :
|
||||
};
|
||||
?>
|
||||
<tr>
|
||||
<td><?= esc($row['student_name'] ?? '') ?></td>
|
||||
<td>
|
||||
<?= esc($row['student_name'] ?? '') ?>
|
||||
<?= student_enrollment_status_button($row, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($row['school_id'] ?? '') ?></td>
|
||||
<td><span class="badge <?= esc($statusClass) ?>"><?= esc($statusValue) ?></span></td>
|
||||
<td><?= esc($decisionValue !== '' ? ucwords(str_replace('_', ' ', $decisionValue)) : 'Pending') ?></td>
|
||||
@@ -539,6 +545,7 @@ $reasonCodes = is_array($exceptionReasonCodes ?? null) ? $exceptionReasonCodes :
|
||||
</td>
|
||||
<td>
|
||||
<?= esc($studentPreview['student_name'] ?? '') ?>
|
||||
<?= student_enrollment_status_button($studentPreview, $schoolYear ?? null) ?>
|
||||
<div class="small text-muted"><?= esc($studentPreview['school_id'] ?? '') ?></div>
|
||||
</td>
|
||||
<td><span class="badge <?= $canEnroll ? 'bg-success' : 'bg-warning text-dark' ?>"><?= esc(enrollment_admin_decision_label($decision)) ?></span></td>
|
||||
@@ -648,6 +655,7 @@ $reasonCodes = is_array($exceptionReasonCodes ?? null) ? $exceptionReasonCodes :
|
||||
<tr>
|
||||
<td>
|
||||
<?= esc($exception['student_name'] ?? '') ?>
|
||||
<?= student_enrollment_status_button($exception, $schoolYear ?? null) ?>
|
||||
<div class="small text-muted"><?= esc($exception['school_id'] ?? '') ?></div>
|
||||
</td>
|
||||
<td><?= esc($exception['parent_name'] ?? '') ?></td>
|
||||
@@ -817,7 +825,10 @@ $reasonCodes = is_array($exceptionReasonCodes ?? null) ? $exceptionReasonCodes :
|
||||
<?php foreach ($auditRows as $row): ?>
|
||||
<tr>
|
||||
<td><?= esc(!empty($row['created_at']) ? local_datetime($row['created_at'], 'm-d-Y H:i') : '') ?></td>
|
||||
<td><?= esc($row['student_name'] ?? '') ?></td>
|
||||
<td>
|
||||
<?= esc($row['student_name'] ?? '') ?>
|
||||
<?= student_enrollment_status_button($row, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc(enrollment_admin_audit_action_label((string) ($row['action'] ?? ''))) ?></td>
|
||||
<td><?= esc($row['performed_by_name'] ?? '') ?></td>
|
||||
<td><?= esc($row['reason'] ?? '') ?></td>
|
||||
|
||||
@@ -348,6 +348,7 @@
|
||||
<td data-sort-value="<?= esc(strtolower($parentColumnName)) ?>"><?= esc($parentColumnName) ?></td>
|
||||
<td data-sort-value="<?= esc(strtolower($displayName)) ?>">
|
||||
<?= esc($displayName) ?>
|
||||
<?= student_enrollment_status_button(['student_id' => $charge['student_id'] ?? 0, 'enrollment_status' => $charge['enrollment_status'] ?? ''], $schoolYear ?? null) ?>
|
||||
<?php if ($externalNote): ?>
|
||||
<small class="text-muted d-block"><?= esc($externalNote) ?></small>
|
||||
<?php endif; ?>
|
||||
|
||||
@@ -19,7 +19,10 @@
|
||||
<div><strong>Students</strong></div>
|
||||
<ul>
|
||||
<?php foreach (($students ?? []) as $student): ?>
|
||||
<li><?= esc(trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? ''))) ?></li>
|
||||
<li>
|
||||
<?= esc(trim(($student['firstname'] ?? '') . ' ' . ($student['lastname'] ?? ''))) ?>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -48,7 +48,10 @@
|
||||
<tbody>
|
||||
<?php foreach ($studentsBySection[$sectionId] as $student): ?>
|
||||
<tr>
|
||||
<td><?= esc($student['firstname'] . ' ' . $student['lastname']) ?></td>
|
||||
<td>
|
||||
<?= esc($student['firstname'] . ' ' . $student['lastname']) ?>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($student['school_id']) ?></td>
|
||||
<td>
|
||||
<?php
|
||||
|
||||
@@ -63,7 +63,10 @@
|
||||
<tr>
|
||||
<td><?= (int)($r['id'] ?? 0) ?></td>
|
||||
<td><?= esc(!empty($r['printed_at']) ? local_datetime($r['printed_at'], 'm-d-Y H:i') : '') ?></td>
|
||||
<td><?= esc($r['student_name'] ?? '') ?></td>
|
||||
<td>
|
||||
<?= esc($r['student_name'] ?? '') ?>
|
||||
<?= student_enrollment_status_button($r, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($r['grade'] ?? '') ?></td>
|
||||
<td><?= esc(!empty($r['slip_date']) ? local_date($r['slip_date'], 'm-d-Y') : '') ?></td>
|
||||
<td><?= esc($r['time_in'] ?? '') ?></td>
|
||||
|
||||
@@ -65,7 +65,10 @@
|
||||
<?php foreach ($results['students'] as $student): ?>
|
||||
<tr>
|
||||
<td><?= esc($student['school_id'] ?? 'N/A') ?></td>
|
||||
<td><?= esc($student['firstname'] ?? 'N/A') ?></td>
|
||||
<td>
|
||||
<?= esc($student['firstname'] ?? 'N/A') ?>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($student['lastname'] ?? 'N/A') ?></td>
|
||||
<td><?= esc($student['dob'] ?? 'N/A') ?></td>
|
||||
</tr>
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)($student['student_id'] ?? 0) ?>">
|
||||
<?= esc($student['name']) ?>
|
||||
</a>
|
||||
<?= student_enrollment_status_button($student, $selectedYear ?? $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($student['age']) ?></td>
|
||||
<td><?= esc($student['registration_grade']) ?></td>
|
||||
|
||||
@@ -156,6 +156,7 @@ $selectedYear = trim((string)($selectedYear ?? ''));
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)($student['id'] ?? 0) ?>">
|
||||
<?= esc($student['firstname']) ?>
|
||||
</a>
|
||||
<?= student_enrollment_status_button($student, $selectedYear) ?>
|
||||
</td>
|
||||
<td>
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)($student['id'] ?? 0) ?>">
|
||||
|
||||
@@ -202,7 +202,10 @@ $warningText = static function (array $warnings): string {
|
||||
<tbody>
|
||||
<?php foreach (($family['student_details'] ?? []) as $detail): ?>
|
||||
<tr>
|
||||
<td><?= esc($detail['student_name'] ?? '') ?></td>
|
||||
<td>
|
||||
<?= esc($detail['student_name'] ?? '') ?>
|
||||
<?= student_enrollment_status_button($detail, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($detail['grade_level'] ?? '') ?></td>
|
||||
<td><?= !empty($detail['billable']) ? 'Yes' : 'No' ?></td>
|
||||
<td><?= esc((string) ($detail['excluded_reason'] ?? '')) ?></td>
|
||||
|
||||
@@ -102,7 +102,10 @@
|
||||
<tbody>
|
||||
<?php foreach ($students as $student): ?>
|
||||
<tr>
|
||||
<td><?= $student['name'] ?></td>
|
||||
<td>
|
||||
<?= esc($student['name'] ?? '') ?>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= $student['total_absences'] ?></td>
|
||||
<td>
|
||||
<?= $student['last_absence'] ? local_date($student['last_absence']['date'], 'm-d-Y') : 'N/A' ?>
|
||||
|
||||
@@ -117,7 +117,10 @@
|
||||
<tbody>
|
||||
<?php foreach ($rows as $r): ?>
|
||||
<tr>
|
||||
<td><?= esc(($r['firstname'] ?? '') . ' ' . ($r['lastname'] ?? '')) ?></td>
|
||||
<td>
|
||||
<?= esc(($r['firstname'] ?? '') . ' ' . ($r['lastname'] ?? '')) ?>
|
||||
<?= student_enrollment_status_button($r, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($r['class_section_name'] ?? '—') ?></td>
|
||||
<td><?= !empty($r['dismiss_time']) ? esc(substr($r['dismiss_time'], 0, 5)) : '—' ?></td>
|
||||
<td style="max-width: 420px; white-space: normal;"><?= esc($r['reason'] ?? '') ?></td>
|
||||
|
||||
@@ -54,7 +54,10 @@
|
||||
<?php foreach ($rows as $r): ?>
|
||||
<tr>
|
||||
<td><?= esc(!empty($r['report_date']) ? local_date($r['report_date'], 'm-d-Y') : '') ?></td>
|
||||
<td><?= esc(($r['firstname'] ?? '') . ' ' . ($r['lastname'] ?? '')) ?></td>
|
||||
<td>
|
||||
<?= esc(($r['firstname'] ?? '') . ' ' . ($r['lastname'] ?? '')) ?>
|
||||
<?= student_enrollment_status_button($r, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($r['class_section_name'] ?? '—') ?></td>
|
||||
<td class="text-capitalize"><?= esc(str_replace('_',' ', $r['type'])) ?></td>
|
||||
<td>
|
||||
|
||||
@@ -119,6 +119,7 @@ $show_actions = false; // notified page hides actions by design
|
||||
title="Open Family Card">
|
||||
<?= esc($studName) ?>
|
||||
</a>
|
||||
<?= student_enrollment_status_button(['student_id' => $studId, 'enrollment_status' => $st['enrollment_status'] ?? ''], $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($className) ?></td>
|
||||
<td data-order="<?= $incidentYmd !== '' ? esc($incidentYmd) : '' ?>">
|
||||
|
||||
@@ -139,6 +139,7 @@ $show_actions = true; // pending page shows actions
|
||||
title="Open Family Card">
|
||||
<?= esc($studName) ?>
|
||||
</a>
|
||||
<?= student_enrollment_status_button(['student_id' => $studId, 'enrollment_status' => $st['enrollment_status'] ?? ''], $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($grade) ?></td>
|
||||
<td><span class="<?= esc($badgeCls) ?>" style="<?= $badgeCss ?>"><?= esc($viTitle) ?></span></td>
|
||||
|
||||
@@ -230,13 +230,18 @@
|
||||
if ($yearVal !== null && $yearVal < 60) {
|
||||
$rowClass = $yearVal < 50 ? 'grade-red' : 'grade-orange';
|
||||
}
|
||||
$badge = $decisionBadge[$decision] ?? null;
|
||||
[$srcCls, $srcLabel] = $sourceBadge[$source] ?? ['bg-light text-muted', $source];
|
||||
$studentName = trim((string)($row['firstname'] ?? '') . ' ' . (string)($row['lastname'] ?? ''));
|
||||
$fmt = fn($v) => is_numeric($v) ? number_format((float)$v, 2) : '—';
|
||||
$badge = $decisionBadge[$decision] ?? null;
|
||||
[$srcCls, $srcLabel] = $sourceBadge[$source] ?? ['bg-light text-muted', $source];
|
||||
$studentName = trim((string)($row['firstname'] ?? '') . ' ' . (string)($row['lastname'] ?? ''));
|
||||
$rowLocked = student_is_non_active_for_editing($row, $schoolYear ?? null);
|
||||
$rowClass = trim($rowClass . ' ' . ($rowLocked ? 'table-secondary text-muted' : ''));
|
||||
$fmt = fn($v) => is_numeric($v) ? number_format((float)$v, 2) : '—';
|
||||
?>
|
||||
<tr class="<?= esc($rowClass) ?>">
|
||||
<td><?= esc($studentName ?: 'N/A') ?></td>
|
||||
<td>
|
||||
<?= esc($studentName ?: 'N/A') ?>
|
||||
<?= student_enrollment_status_button($row, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($row['class_section_name'] ?? '—') ?></td>
|
||||
<td class="text-center"><?= esc($fmt($row['fall_score'] ?? null)) ?></td>
|
||||
<td class="text-center"><?= esc($fmt($row['spring_score'] ?? null)) ?></td>
|
||||
|
||||
@@ -85,12 +85,17 @@ if (empty($schoolYears) && $schoolYear !== '') {
|
||||
}
|
||||
|
||||
$studentName = trim((string)($row['firstname'] ?? '') . ' ' . (string)($row['lastname'] ?? ''));
|
||||
$studentLabel = $studentName !== '' ? $studentName : 'N/A';
|
||||
$isClosed = ($row['status'] ?? 'Open') === 'Closed';
|
||||
?>
|
||||
$studentLabel = $studentName !== '' ? $studentName : 'N/A';
|
||||
$isClosed = ($row['status'] ?? 'Open') === 'Closed';
|
||||
$rowLocked = student_is_non_active_for_editing($row, $schoolYear ?? null);
|
||||
$rowClass = trim($scoreClass . ' ' . ($rowLocked ? 'table-secondary text-muted' : ''));
|
||||
?>
|
||||
|
||||
<tr class="<?= esc($scoreClass) ?>">
|
||||
<td><?= esc($studentLabel) ?></td>
|
||||
<tr class="<?= esc($rowClass) ?>">
|
||||
<td>
|
||||
<?= esc($studentLabel) ?>
|
||||
<?= student_enrollment_status_button($row, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($row['class_section_name'] ?? '—') ?></td>
|
||||
|
||||
<td class="text-center">
|
||||
@@ -124,9 +129,10 @@ if (empty($schoolYears) && $schoolYear !== '') {
|
||||
name="school_year"
|
||||
value="<?= esc((string)$schoolYear) ?>">
|
||||
|
||||
<select name="status"
|
||||
class="form-select form-select-sm"
|
||||
style="width:110px;">
|
||||
<select name="status"
|
||||
class="form-select form-select-sm"
|
||||
<?= $rowLocked ? 'disabled aria-disabled="true"' : '' ?>
|
||||
style="width:110px;">
|
||||
<option value="Open" <?= ($row['status'] ?? 'Open') === 'Open' ? 'selected' : '' ?>>
|
||||
Open
|
||||
</option>
|
||||
@@ -137,12 +143,13 @@ if (empty($schoolYears) && $schoolYear !== '') {
|
||||
|
||||
<input type="text"
|
||||
name="note"
|
||||
class="form-control form-control-sm"
|
||||
style="width:140px;"
|
||||
placeholder="Note (optional)"
|
||||
value="<?= esc((string)($row['note'] ?? '')) ?>">
|
||||
class="form-control form-control-sm"
|
||||
style="width:140px;"
|
||||
placeholder="Note (optional)"
|
||||
<?= $rowLocked ? 'readonly aria-disabled="true"' : '' ?>
|
||||
value="<?= esc((string)($row['note'] ?? '')) ?>">
|
||||
|
||||
<button type="submit" class="btn btn-sm btn-outline-secondary">
|
||||
<button type="submit" class="btn btn-sm btn-outline-secondary" <?= $rowLocked ? 'disabled' : '' ?>>
|
||||
Update
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -176,14 +176,20 @@ if (empty($schoolYears) && $schoolYear !== '') {
|
||||
}
|
||||
|
||||
$studentName = trim((string)($row['firstname'] ?? '') . ' ' . (string)($row['lastname'] ?? ''));
|
||||
$studentLabel = $studentName !== '' ? $studentName : 'N/A';
|
||||
$currentDecision = (string)($row['decision'] ?? '');
|
||||
$currentNotes = (string)($row['decision_notes'] ?? '');
|
||||
$badge = $decisionBadge[$currentDecision] ?? null;
|
||||
?>
|
||||
$studentLabel = $studentName !== '' ? $studentName : 'N/A';
|
||||
$currentDecision = (string)($row['decision'] ?? '');
|
||||
$currentNotes = (string)($row['decision_notes'] ?? '');
|
||||
$badge = $decisionBadge[$currentDecision] ?? null;
|
||||
$rowLocked = student_is_non_active_for_editing($row, $schoolYear ?? null);
|
||||
$rowClass = trim($rowClass . ' ' . ($rowLocked ? 'table-secondary text-muted' : ''));
|
||||
$controlsEditable = $isEditable && !$rowLocked;
|
||||
?>
|
||||
|
||||
<tr class="<?= esc($rowClass) ?>">
|
||||
<td><?= esc($studentLabel) ?></td>
|
||||
<td>
|
||||
<?= esc($studentLabel) ?>
|
||||
<?= student_enrollment_status_button($row, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
|
||||
<td class="text-center"><?= esc((string)($row['age'] ?? '—')) ?></td>
|
||||
|
||||
@@ -219,15 +225,15 @@ if (empty($schoolYears) && $schoolYear !== '') {
|
||||
value="<?= esc((string)$schoolYear) ?>">
|
||||
|
||||
<textarea name="notes"
|
||||
class="form-control form-control-sm decision-notes"
|
||||
rows="3"
|
||||
placeholder="Add comments or rationale…"
|
||||
<?= $isEditable ? '' : 'readonly' ?>><?= esc($currentNotes) ?></textarea>
|
||||
class="form-control form-control-sm decision-notes"
|
||||
rows="3"
|
||||
placeholder="Add comments or rationale…"
|
||||
<?= $controlsEditable ? '' : 'readonly aria-disabled="true"' ?>><?= esc($currentNotes) ?></textarea>
|
||||
|
||||
<div class="d-flex gap-2 mt-2 align-items-center">
|
||||
<select name="decision"
|
||||
class="form-select form-select-sm decision-select flex-grow-1"
|
||||
<?= $isEditable ? '' : 'disabled' ?>>
|
||||
<select name="decision"
|
||||
class="form-select form-select-sm decision-select flex-grow-1"
|
||||
<?= $controlsEditable ? '' : 'disabled aria-disabled="true"' ?>>
|
||||
<?php foreach ($decisionOptions as $val => $label): ?>
|
||||
<option value="<?= esc($val) ?>" <?= $currentDecision === $val ? 'selected' : '' ?>>
|
||||
<?= esc($label) ?>
|
||||
@@ -235,9 +241,9 @@ if (empty($schoolYears) && $schoolYear !== '') {
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
|
||||
<button type="submit"
|
||||
class="btn btn-sm btn-primary"
|
||||
<?= $isEditable ? '' : 'disabled' ?>>
|
||||
<button type="submit"
|
||||
class="btn btn-sm btn-primary"
|
||||
<?= $controlsEditable ? '' : 'disabled' ?>>
|
||||
Save
|
||||
</button>
|
||||
</div>
|
||||
@@ -252,10 +258,10 @@ if (empty($schoolYears) && $schoolYear !== '') {
|
||||
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-outline-primary btn-send-email"
|
||||
data-student-id="<?= (int)($row['student_id'] ?? 0) ?>"
|
||||
data-semester="year"
|
||||
data-school-year="<?= esc((string)$schoolYear) ?>"
|
||||
<?= $isEditable ? '' : 'disabled' ?>>
|
||||
data-student-id="<?= (int)($row['student_id'] ?? 0) ?>"
|
||||
data-semester="year"
|
||||
data-school-year="<?= esc((string)$schoolYear) ?>"
|
||||
<?= $controlsEditable ? '' : 'disabled' ?>>
|
||||
Send Email
|
||||
</button>
|
||||
<?php else: ?>
|
||||
|
||||
@@ -78,16 +78,22 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php $rowNum = 1; ?>
|
||||
<?php foreach ($students as $student): ?>
|
||||
<?php $studentId = $student['student_id']; ?>
|
||||
<tr>
|
||||
<?php $rowNum = 1; ?>
|
||||
<?php foreach ($students as $student): ?>
|
||||
<?php
|
||||
$studentId = $student['student_id'];
|
||||
$rowLocked = student_is_non_active_for_editing($student, $schoolYear ?? null);
|
||||
$rowLockAttr = $scoresLocked ? $lockAttr : ($rowLocked ? 'readonly aria-disabled="true"' : '');
|
||||
$rowButtonLockAttr = ($scoresLocked || $rowLocked) ? 'disabled' : '';
|
||||
?>
|
||||
<tr class="<?= $rowLocked ? 'table-secondary text-muted' : '' ?>">
|
||||
<td><?= $rowNum++ ?></td>
|
||||
<td><?= esc($student['school_id']) ?></td>
|
||||
<td>
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)$studentId ?>">
|
||||
<?= esc($student['firstname']) ?> <?= esc($student['lastname']) ?>
|
||||
</a>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
|
||||
<!-- PTAP Comment and Review -->
|
||||
@@ -102,7 +108,7 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
data-first-name="<?= esc($student['firstname']) ?>"
|
||||
minlength="100"
|
||||
maxlength="350"
|
||||
placeholder="Enter PTAP comment" <?= $lockAttr ?>><?= esc($comments[$studentId]['ptap']['comment'] ?? '') ?></textarea>
|
||||
placeholder="Enter PTAP comment" <?= $rowLockAttr ?>><?= esc($comments[$studentId]['ptap']['comment'] ?? '') ?></textarea>
|
||||
</td>
|
||||
<td class="ptap-review-cell">
|
||||
<div class="d-flex gap-2 align-items-start">
|
||||
@@ -111,13 +117,13 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
name="reviews[<?= $studentId ?>][ptap]"
|
||||
rows="2"
|
||||
class="form-control review-field"
|
||||
placeholder="Enter PTAP review" <?= $lockAttr ?>><?= esc($comments[$studentId]['ptap']['comment_review'] ?? '') ?></textarea>
|
||||
placeholder="Enter PTAP review" <?= $rowLockAttr ?>><?= esc($comments[$studentId]['ptap']['comment_review'] ?? '') ?></textarea>
|
||||
<div class="d-flex flex-column gap-1 align-items-stretch">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-secondary btn-sm copy-ptap-btn"
|
||||
data-copy-source="#<?= esc($ptapCommentId) ?>"
|
||||
data-copy-target="#<?= esc($ptapReviewId) ?>" <?= $lockAttr ?>>
|
||||
data-copy-target="#<?= esc($ptapReviewId) ?>" <?= $rowButtonLockAttr ?>>
|
||||
Paste
|
||||
</button>
|
||||
<div class="small text-muted proofread-status" data-status-for="<?= esc($ptapReviewId) ?>"></div>
|
||||
@@ -144,7 +150,7 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
data-first-name="<?= esc($student['firstname']) ?>"
|
||||
minlength="100"
|
||||
maxlength="350"
|
||||
placeholder="Enter Midterm comment" <?= $lockAttr ?>><?= esc($comments[$studentId]['midterm']['comment'] ?? '') ?></textarea>
|
||||
placeholder="Enter Midterm comment" <?= $rowLockAttr ?>><?= esc($comments[$studentId]['midterm']['comment'] ?? '') ?></textarea>
|
||||
</td>
|
||||
<td>
|
||||
<div class="d-flex gap-2 align-items-start">
|
||||
@@ -156,13 +162,13 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
data-first-name="<?= esc($student['firstname']) ?>"
|
||||
minlength="100"
|
||||
maxlength="350"
|
||||
placeholder="Enter Midterm review" <?= $lockAttr ?>><?= esc($comments[$studentId]['midterm']['comment_review'] ?? '') ?></textarea>
|
||||
placeholder="Enter Midterm review" <?= $rowLockAttr ?>><?= esc($comments[$studentId]['midterm']['comment_review'] ?? '') ?></textarea>
|
||||
<div class="d-flex flex-column gap-1 align-items-stretch">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-secondary btn-sm copy-midterm-btn"
|
||||
data-copy-source="#<?= esc($midCommentId) ?>"
|
||||
data-copy-target="#<?= esc($midReviewId) ?>" <?= $lockAttr ?>>
|
||||
data-copy-target="#<?= esc($midReviewId) ?>" <?= $rowButtonLockAttr ?>>
|
||||
Paste
|
||||
</button>
|
||||
<div class="small text-muted proofread-status" data-status-for="<?= esc($midReviewId) ?>"></div>
|
||||
@@ -187,7 +193,7 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
data-first-name="<?= esc($student['firstname']) ?>"
|
||||
minlength="100"
|
||||
maxlength="350"
|
||||
placeholder="Enter Final comment" <?= $lockAttr ?>><?= esc($comments[$studentId]['final']['comment'] ?? '') ?></textarea>
|
||||
placeholder="Enter Final comment" <?= $rowLockAttr ?>><?= esc($comments[$studentId]['final']['comment'] ?? '') ?></textarea>
|
||||
</td>
|
||||
<td>
|
||||
<div class="d-flex gap-2 align-items-start">
|
||||
@@ -196,13 +202,13 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
name="reviews[<?= $studentId ?>][final]"
|
||||
rows="2"
|
||||
class="form-control review-field"
|
||||
placeholder="Enter Final review" <?= $lockAttr ?>><?= esc($comments[$studentId]['final']['comment_review'] ?? '') ?></textarea>
|
||||
placeholder="Enter Final review" <?= $rowLockAttr ?>><?= esc($comments[$studentId]['final']['comment_review'] ?? '') ?></textarea>
|
||||
<div class="d-flex flex-column gap-1 align-items-stretch">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-secondary btn-sm copy-final-btn"
|
||||
data-copy-source="#<?= esc($finalCommentId) ?>"
|
||||
data-copy-target="#<?= esc($finalReviewId) ?>" <?= $lockAttr ?>>
|
||||
data-copy-target="#<?= esc($finalReviewId) ?>" <?= $rowButtonLockAttr ?>>
|
||||
Paste
|
||||
</button>
|
||||
<div class="small text-muted proofread-status" data-status-for="<?= esc($finalReviewId) ?>"></div>
|
||||
@@ -225,7 +231,7 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
data-first-name="<?= esc($student['firstname']) ?>"
|
||||
minlength="100"
|
||||
maxlength="350"
|
||||
placeholder="Enter Attendance comment" <?= $lockAttr ?>><?= esc($comments[$studentId]['attendance']['comment'] ?? '') ?></textarea>
|
||||
placeholder="Enter Attendance comment" <?= $rowLockAttr ?>><?= esc($comments[$studentId]['attendance']['comment'] ?? '') ?></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
@@ -377,7 +383,7 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
};
|
||||
|
||||
const shouldAutoSave = function(field, value) {
|
||||
if (field.disabled) return false;
|
||||
if (field.disabled || field.readOnly) return false;
|
||||
const lastSaved = field.getAttribute('data-last-saved') || '';
|
||||
if (value === lastSaved) return false;
|
||||
const parsed = parseFieldName(field.name || '');
|
||||
@@ -434,8 +440,9 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
form.addEventListener('submit', function(event) {
|
||||
syncCsrfToken();
|
||||
const errors = [];
|
||||
form.querySelectorAll('textarea[data-first-name]').forEach(field => {
|
||||
const value = field.value.trim();
|
||||
form.querySelectorAll('textarea[data-first-name]').forEach(field => {
|
||||
if (field.disabled || field.readOnly) return;
|
||||
const value = field.value.trim();
|
||||
if (value === '') return;
|
||||
|
||||
const min = 100;
|
||||
@@ -472,9 +479,10 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
const wireCopyButtons = (selector) => {
|
||||
document.querySelectorAll(selector).forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
const source = document.querySelector(this.dataset.copySource || '');
|
||||
const target = document.querySelector(this.dataset.copyTarget || '');
|
||||
if (!source || !target) return;
|
||||
const source = document.querySelector(this.dataset.copySource || '');
|
||||
const target = document.querySelector(this.dataset.copyTarget || '');
|
||||
if (!source || !target) return;
|
||||
if (target.disabled || target.readOnly) return;
|
||||
target.value = source.value;
|
||||
target.style.height = 'auto';
|
||||
target.style.height = (target.scrollHeight) + 'px';
|
||||
|
||||
@@ -88,15 +88,20 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($students as $index => $student): ?>
|
||||
<tr>
|
||||
<tbody>
|
||||
<?php foreach ($students as $index => $student): ?>
|
||||
<?php
|
||||
$rowLocked = student_is_non_active_for_editing($student, $schoolYear ?? null);
|
||||
$rowLockAttr = $scoresLocked ? $lockAttr : ($rowLocked ? 'readonly aria-disabled="true"' : '');
|
||||
?>
|
||||
<tr class="<?= $rowLocked ? 'table-secondary text-muted' : '' ?>">
|
||||
<td><?= $index + 1 ?></td>
|
||||
<td><?= esc($student['school_id']) ?></td>
|
||||
<td>
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)($student['student_id'] ?? 0) ?>">
|
||||
<?= esc($student['firstname']) ?>
|
||||
</a>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td>
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)($student['student_id'] ?? 0) ?>">
|
||||
@@ -106,7 +111,7 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
<td>
|
||||
<input type="number" name="final_score[<?= esc($student['student_id']) ?>][score]"
|
||||
value="<?= esc($student['score'] ?? '') ?>" class="form-control text-center" min="0" max="100" step="0.01"
|
||||
placeholder="Enter score (optional)" <?= $lockAttr ?>>
|
||||
placeholder="Enter score (optional)" <?= $rowLockAttr ?>>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
|
||||
@@ -357,9 +357,10 @@
|
||||
<th>Semester Score</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($students as $student): ?>
|
||||
<tr>
|
||||
<tbody>
|
||||
<?php foreach ($students as $student): ?>
|
||||
<?php $rowLocked = student_is_non_active_for_editing($student, $schoolYear ?? null); ?>
|
||||
<tr class="<?= $rowLocked ? 'table-secondary text-muted' : '' ?>">
|
||||
<td><?= esc($student['school_id'] ?? 'N/A') ?></td>
|
||||
<td>
|
||||
<?php $sid = (int)($student['id'] ?? 0); ?>
|
||||
@@ -367,8 +368,10 @@
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= $sid ?>">
|
||||
<?= esc($student['firstname'] ?? 'N/A') ?>
|
||||
</a>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
<?php else: ?>
|
||||
<?= esc($student['firstname'] ?? 'N/A') ?>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -55,14 +55,17 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
<?php
|
||||
$studentId = $student['id'];
|
||||
$scores = $homeworkScores[$studentId]['scores'] ?? [];
|
||||
$rowLocked = student_is_non_active_for_editing($student, $schoolYear ?? null);
|
||||
$rowLockAttr = $scoresLocked ? $lockAttr : ($rowLocked ? 'readonly aria-disabled="true"' : '');
|
||||
?>
|
||||
<tr>
|
||||
<tr class="<?= $rowLocked ? 'table-secondary text-muted' : '' ?>">
|
||||
<td><?= $row++ ?></td>
|
||||
<td><?= esc($student['school_id']) ?></td>
|
||||
<td>
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)$studentId ?>">
|
||||
<?= esc($student['firstname']) ?>
|
||||
</a>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td>
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)$studentId ?>">
|
||||
@@ -78,7 +81,7 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
name="scores[<?= $studentId ?>][<?= $index ?>]"
|
||||
value="<?= esc(is_array($scoreValue) ? '' : $scoreValue) ?>"
|
||||
class="form-control text-center"
|
||||
min="0" max="100" step="0.01" <?= $lockAttr ?>>
|
||||
min="0" max="100" step="0.01" <?= $rowLockAttr ?>>
|
||||
</td>
|
||||
<?php endforeach; ?>
|
||||
</tr>
|
||||
|
||||
@@ -45,15 +45,20 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($students as $index => $student): ?>
|
||||
<tr>
|
||||
<tbody>
|
||||
<?php foreach ($students as $index => $student): ?>
|
||||
<?php
|
||||
$rowLocked = student_is_non_active_for_editing($student, $schoolYear ?? null);
|
||||
$rowLockAttr = $scoresLocked ? $lockAttr : ($rowLocked ? 'readonly aria-disabled="true"' : '');
|
||||
?>
|
||||
<tr class="<?= $rowLocked ? 'table-secondary text-muted' : '' ?>">
|
||||
<td><?= $index + 1 ?></td>
|
||||
<td><?= esc($student['school_id']) ?></td>
|
||||
<td>
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)($student['student_id'] ?? 0) ?>">
|
||||
<?= esc($student['firstname']) ?>
|
||||
</a>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td>
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)($student['student_id'] ?? 0) ?>">
|
||||
@@ -63,7 +68,7 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
<td>
|
||||
<input type="number" name="final_score[<?= esc($student['student_id']) ?>][score]"
|
||||
value="<?= esc($student['score'] ?? '') ?>" class="form-control text-center" min="0" max="100" step="0.01"
|
||||
placeholder="Enter score (optional)" <?= $lockAttr ?>>
|
||||
placeholder="Enter score (optional)" <?= $rowLockAttr ?>>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
|
||||
@@ -45,15 +45,20 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($students as $index => $student): ?>
|
||||
<tr>
|
||||
<tbody>
|
||||
<?php foreach ($students as $index => $student): ?>
|
||||
<?php
|
||||
$rowLocked = student_is_non_active_for_editing($student, $schoolYear ?? null);
|
||||
$rowLockAttr = $scoresLocked ? $lockAttr : ($rowLocked ? 'readonly aria-disabled="true"' : '');
|
||||
?>
|
||||
<tr class="<?= $rowLocked ? 'table-secondary text-muted' : '' ?>">
|
||||
<td><?= $index + 1 ?></td>
|
||||
<td><?= esc($student['school_id']) ?></td>
|
||||
<td>
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)($student['student_id'] ?? 0) ?>">
|
||||
<?= esc($student['firstname']) ?>
|
||||
</a>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td>
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)($student['student_id'] ?? 0) ?>">
|
||||
@@ -63,7 +68,7 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
<td>
|
||||
<input type="number" name="final_score[<?= esc($student['student_id']) ?>][score]"
|
||||
value="<?= esc($student['score'] ?? '') ?>" class="form-control text-center" min="0" max="100" step="0.01"
|
||||
placeholder="Enter score (optional)" <?= $lockAttr ?>>
|
||||
placeholder="Enter score (optional)" <?= $rowLockAttr ?>>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
|
||||
@@ -53,13 +53,17 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($students as $student): ?>
|
||||
<?php
|
||||
$sid = (int) ($student['student_id'] ?? 0);
|
||||
$current = (string) ($levels[$sid] ?? '');
|
||||
?>
|
||||
<tr>
|
||||
<?php
|
||||
$sid = (int) ($student['student_id'] ?? 0);
|
||||
$current = (string) ($levels[$sid] ?? '');
|
||||
$rowLocked = student_is_non_active_for_editing($student, $schoolYear ?? null);
|
||||
?>
|
||||
<tr class="<?= $rowLocked ? 'table-secondary text-muted' : '' ?>">
|
||||
<td><?= esc($student['school_id'] ?? '') ?></td>
|
||||
<td><?= esc($student['firstname'] ?? '') ?></td>
|
||||
<td>
|
||||
<?= esc($student['firstname'] ?? '') ?>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($student['lastname'] ?? '') ?></td>
|
||||
<td>
|
||||
<input type="number"
|
||||
@@ -67,9 +71,10 @@
|
||||
class="form-control form-control-sm"
|
||||
min="0"
|
||||
max="100"
|
||||
step="1"
|
||||
value="<?= esc($current) ?>"
|
||||
placeholder="0-100">
|
||||
step="1"
|
||||
value="<?= esc($current) ?>"
|
||||
<?= $rowLocked ? 'readonly aria-disabled="true"' : '' ?>
|
||||
placeholder="0-100">
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
|
||||
@@ -53,14 +53,18 @@
|
||||
<?php
|
||||
$sid = (int) ($student['student_id'] ?? 0);
|
||||
$scoreRow = $scores[$sid] ?? null;
|
||||
$current = $scoreRow ? (string) ($scoreRow['score'] ?? '') : '';
|
||||
$sectionName = (string) ($student['class_section_name'] ?? '');
|
||||
$className = (string) ($student['class_name'] ?? '');
|
||||
$sectionLabel = $className !== '' ? ($className . ' — ' . $sectionName) : $sectionName;
|
||||
?>
|
||||
<tr>
|
||||
$current = $scoreRow ? (string) ($scoreRow['score'] ?? '') : '';
|
||||
$sectionName = (string) ($student['class_section_name'] ?? '');
|
||||
$className = (string) ($student['class_name'] ?? '');
|
||||
$sectionLabel = $className !== '' ? ($className . ' — ' . $sectionName) : $sectionName;
|
||||
$rowLocked = student_is_non_active_for_editing($student, $schoolYear ?? null);
|
||||
?>
|
||||
<tr class="<?= $rowLocked ? 'table-secondary text-muted' : '' ?>">
|
||||
<td><?= esc($student['school_id'] ?? '') ?></td>
|
||||
<td><?= esc($student['firstname'] ?? '') ?></td>
|
||||
<td>
|
||||
<?= esc($student['firstname'] ?? '') ?>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($student['lastname'] ?? '') ?></td>
|
||||
<td><?= esc($sectionLabel ?: '—') ?></td>
|
||||
<td>
|
||||
@@ -69,9 +73,10 @@
|
||||
class="form-control form-control-sm"
|
||||
min="0"
|
||||
max="100"
|
||||
step="1"
|
||||
value="<?= esc($current) ?>"
|
||||
placeholder="0-100">
|
||||
step="1"
|
||||
value="<?= esc($current) ?>"
|
||||
<?= $rowLocked ? 'readonly aria-disabled="true"' : '' ?>
|
||||
placeholder="0-100">
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
|
||||
@@ -61,13 +61,17 @@
|
||||
<?php foreach ($students as $student): ?>
|
||||
<?php
|
||||
$sid = (int) ($student['student_id'] ?? 0);
|
||||
$sectionName = (string) ($student['class_section_name'] ?? '');
|
||||
$className = (string) ($student['class_name'] ?? '');
|
||||
$sectionLabel = $className !== '' ? ($className . ' — ' . $sectionName) : $sectionName;
|
||||
?>
|
||||
<tr>
|
||||
$sectionName = (string) ($student['class_section_name'] ?? '');
|
||||
$className = (string) ($student['class_name'] ?? '');
|
||||
$sectionLabel = $className !== '' ? ($className . ' — ' . $sectionName) : $sectionName;
|
||||
$rowLocked = student_is_non_active_for_editing($student, $schoolYear ?? null);
|
||||
?>
|
||||
<tr class="<?= $rowLocked ? 'table-secondary text-muted' : '' ?>">
|
||||
<td><?= esc($student['school_id'] ?? '') ?></td>
|
||||
<td><?= esc($student['firstname'] ?? '') ?></td>
|
||||
<td>
|
||||
<?= esc($student['firstname'] ?? '') ?>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($student['lastname'] ?? '') ?></td>
|
||||
<td><?= esc($sectionLabel ?: '—') ?></td>
|
||||
<td>
|
||||
@@ -76,9 +80,10 @@
|
||||
class="form-control form-control-sm"
|
||||
min="0"
|
||||
max="100"
|
||||
step="1"
|
||||
value=""
|
||||
placeholder="0-100">
|
||||
step="1"
|
||||
value=""
|
||||
<?= $rowLocked ? 'readonly aria-disabled="true"' : '' ?>
|
||||
placeholder="0-100">
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
@@ -154,13 +159,17 @@
|
||||
<tbody>
|
||||
<?php foreach ($detailRows as $row): ?>
|
||||
<?php
|
||||
$sectionName = (string) ($row['class_section_name'] ?? '');
|
||||
$className = (string) ($row['class_name'] ?? '');
|
||||
$sectionLabel = $className !== '' ? ($className . ' — ' . $sectionName) : $sectionName;
|
||||
?>
|
||||
<tr>
|
||||
$sectionName = (string) ($row['class_section_name'] ?? '');
|
||||
$className = (string) ($row['class_name'] ?? '');
|
||||
$sectionLabel = $className !== '' ? ($className . ' — ' . $sectionName) : $sectionName;
|
||||
$rowLocked = student_is_non_active_for_editing($row, $schoolYear ?? null);
|
||||
?>
|
||||
<tr class="<?= $rowLocked ? 'table-secondary text-muted' : '' ?>">
|
||||
<td><?= esc($row['school_id'] ?? '') ?></td>
|
||||
<td><?= esc($row['firstname'] ?? '') ?></td>
|
||||
<td>
|
||||
<?= esc($row['firstname'] ?? '') ?>
|
||||
<?= student_enrollment_status_button($row, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td><?= esc($row['lastname'] ?? '') ?></td>
|
||||
<td><?= esc($sectionLabel ?: '—') ?></td>
|
||||
<td><?= esc($row['score'] ?? '') ?></td>
|
||||
|
||||
@@ -56,14 +56,17 @@
|
||||
<?php
|
||||
$studentId = $student['id'];
|
||||
$scores = $projectScores[$studentId]['scores'] ?? [];
|
||||
$rowLocked = student_is_non_active_for_editing($student, $schoolYear ?? null);
|
||||
$rowLockAttr = $scoresLocked ? $lockAttr : ($rowLocked ? 'readonly aria-disabled="true"' : '');
|
||||
?>
|
||||
<tr>
|
||||
<tr class="<?= $rowLocked ? 'table-secondary text-muted' : '' ?>">
|
||||
<td><?= $row++ ?></td>
|
||||
<td><?= esc($student['school_id']) ?></td>
|
||||
<td>
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)$studentId ?>">
|
||||
<?= esc($student['firstname']) ?>
|
||||
</a>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td>
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)$studentId ?>">
|
||||
@@ -79,7 +82,7 @@
|
||||
name="scores[<?= $studentId ?>][<?= $index ?>]"
|
||||
value="<?= esc(is_array($scoreValue) ? '' : $scoreValue) ?>"
|
||||
class="form-control text-center"
|
||||
min="0" max="100" step="0.01" <?= $lockAttr ?>>
|
||||
min="0" max="100" step="0.01" <?= $rowLockAttr ?>>
|
||||
</td>
|
||||
<?php endforeach; ?>
|
||||
</tr>
|
||||
|
||||
@@ -56,14 +56,17 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
<?php
|
||||
$studentId = $student['id'];
|
||||
$scores = $quizScores[$studentId]['scores'] ?? [];
|
||||
$rowLocked = student_is_non_active_for_editing($student, $schoolYear ?? null);
|
||||
$rowLockAttr = $scoresLocked ? $lockAttr : ($rowLocked ? 'readonly aria-disabled="true"' : '');
|
||||
?>
|
||||
<tr>
|
||||
<tr class="<?= $rowLocked ? 'table-secondary text-muted' : '' ?>">
|
||||
<td><?= $row++ ?></td>
|
||||
<td><?= esc($student['school_id']) ?></td>
|
||||
<td>
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)$studentId ?>">
|
||||
<?= esc($student['firstname']) ?>
|
||||
</a>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</td>
|
||||
<td>
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)$studentId ?>">
|
||||
@@ -79,7 +82,7 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
name="scores[<?= $studentId ?>][<?= $index ?>]"
|
||||
value="<?= esc(is_array($scoreValue) ? '' : $scoreValue) ?>"
|
||||
class="form-control text-center"
|
||||
min="0" max="100" step="0.01" <?= $lockAttr ?>>
|
||||
min="0" max="100" step="0.01" <?= $rowLockAttr ?>>
|
||||
</td>
|
||||
<?php endforeach; ?>
|
||||
</tr>
|
||||
|
||||
@@ -41,6 +41,9 @@ switch ($viewFile) {
|
||||
|
||||
$scoresLocked = !empty($scoresLocked);
|
||||
$lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
$rowLocked = student_is_non_active_for_editing($student, $schoolYear ?? null);
|
||||
$rowLockAttr = $scoresLocked ? $lockAttr : ($rowLocked ? 'readonly aria-disabled="true"' : '');
|
||||
$rowButtonLockAttr = ($scoresLocked || $rowLocked) ? 'disabled' : '';
|
||||
?>
|
||||
|
||||
<?= $this->extend('layout/management_layout') ?>
|
||||
@@ -51,6 +54,7 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
<a href="#" class="text-decoration-none" data-family-student-id="<?= (int)($student['id'] ?? 0) ?>">
|
||||
<?= esc($student['firstname'] . ' ' . $student['lastname']) ?>
|
||||
</a>
|
||||
<?= student_enrollment_status_button($student, $schoolYear ?? null) ?>
|
||||
</h2>
|
||||
<?php if ($scoresLocked): ?>
|
||||
<div class="alert alert-warning text-center">
|
||||
@@ -79,10 +83,10 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
<td><?= $index + 1 ?></td>
|
||||
<td>
|
||||
<input type="hidden" name="score_ids[]" value="<?= $row['id'] ?>">
|
||||
<input type="number" class="form-control" name="scores[]" value="<?= $row['score'] ?>" <?= $lockAttr ?>>
|
||||
<input type="number" class="form-control" name="scores[]" value="<?= $row['score'] ?>" <?= $rowLockAttr ?>>
|
||||
</td>
|
||||
<td>
|
||||
<textarea class="form-control" name="comments[]" <?= $lockAttr ?>><?= esc($row['comment'] ?? '') ?></textarea>
|
||||
<textarea class="form-control" name="comments[]" <?= $rowLockAttr ?>><?= esc($row['comment'] ?? '') ?></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
@@ -91,17 +95,17 @@ $lockAttr = $scoresLocked ? 'disabled' : '';
|
||||
<?php elseif (in_array($type, ['midterm', 'final', 'test'])): ?>
|
||||
<div class="form-group">
|
||||
<label>Score</label>
|
||||
<input type="number" class="form-control" name="score" value="<?= $scores[0]['score'] ?? '' ?>" <?= $lockAttr ?>>
|
||||
<input type="number" class="form-control" name="score" value="<?= $scores[0]['score'] ?? '' ?>" <?= $rowLockAttr ?>>
|
||||
</div>
|
||||
<?php elseif ($type === 'comments'): ?>
|
||||
<div class="form-group">
|
||||
<label>General Comment</label>
|
||||
<textarea class="form-control" name="comment" rows="5" <?= $lockAttr ?>><?= $scores[0]['comment'] ?? '' ?></textarea>
|
||||
<textarea class="form-control" name="comment" rows="5" <?= $rowLockAttr ?>><?= $scores[0]['comment'] ?? '' ?></textarea>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="form-group text-center mt-3">
|
||||
<button type="submit" class="btn btn-primary" <?= $lockAttr ?>>Save Changes</button>
|
||||
<button type="submit" class="btn btn-primary" <?= $rowButtonLockAttr ?>>Save Changes</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="text-center mt-4">
|
||||
|
||||
@@ -81,7 +81,9 @@
|
||||
btn.type = 'button';
|
||||
btn.className = 'btn btn-link btn-sm ps-0';
|
||||
btn.textContent = 'Apply';
|
||||
btn.disabled = !!(textarea.disabled || textarea.readOnly);
|
||||
btn.addEventListener('click', () => {
|
||||
if (textarea.disabled || textarea.readOnly) return;
|
||||
textarea.value = applyMatches(textarea.value, [match]);
|
||||
resize(textarea);
|
||||
textarea.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
@@ -97,6 +99,7 @@
|
||||
|
||||
const proofreadField = async (textarea) => {
|
||||
if (!textarea) return { ok: false };
|
||||
if (textarea.disabled || textarea.readOnly) return { ok: true, skipped: true };
|
||||
const targetId = textarea.id || textarea.name || '';
|
||||
|
||||
const text = textarea.value || '';
|
||||
@@ -159,7 +162,8 @@
|
||||
const proofreadAll = async () => {
|
||||
const btn = document.getElementById('proofreadAllBtn');
|
||||
const summary = document.getElementById('proofreadAllStatus');
|
||||
const fields = Array.from(document.querySelectorAll('textarea.review-field'));
|
||||
const fields = Array.from(document.querySelectorAll('textarea.review-field:not(:disabled)'))
|
||||
.filter((field) => !field.readOnly);
|
||||
if (!fields.length) return;
|
||||
|
||||
if (btn) btn.disabled = true;
|
||||
|
||||
Reference in New Issue
Block a user