apply the school year concept
Tests / PHPUnit (push) Failing after 1m19s

This commit is contained in:
root
2026-07-14 00:59:00 -04:00
parent 504c3bc9f9
commit feb1b29a32
73 changed files with 4288 additions and 620 deletions
+160 -61
View File
@@ -699,7 +699,10 @@ class AdministratorController extends BaseController
public function teacherSubmissionsReport()
{
$semester = (string)($this->configModel->getConfig('semester') ?? $this->semester ?? '');
$schoolYear = (string)($this->configModel->getConfig('school_year') ?? $this->schoolYear ?? '');
$schoolYear = trim((string) ($this->request->getGet('school_year') ?? ''));
if ($schoolYear === '') {
$schoolYear = $this->currentSchoolYearName((string) ($this->schoolYear ?? ''));
}
$semesterResolver = new SemesterRangeService($this->configModel);
$semesterNorm = $semesterResolver->normalizeSemester($semester);
$semesterFilter = $semesterNorm !== '' ? $semesterNorm : $semester;
@@ -1099,9 +1102,9 @@ class AdministratorController extends BaseController
}
$semesterResolver = new SemesterRangeService($this->configModel);
$schoolYear = (string)($this->configModel->getConfig('school_year') ?? '');
$schoolYear = $this->currentSchoolYearName((string) ($this->schoolYear ?? ''));
$semester = (string)($this->configModel->getConfig('semester') ?? '');
$schoolYearForRange = $schoolYear !== '' ? $schoolYear : (string)($this->configModel->getConfig('school_year') ?? '');
$schoolYearForRange = $schoolYear !== '' ? $schoolYear : $this->currentSchoolYearName((string) ($this->schoolYear ?? ''));
[$rangeStart, $rangeEnd] = $semesterResolver->getSchoolYearRange($schoolYearForRange);
$semesterNorm = $semesterResolver->normalizeSemester($semester);
if ($semesterNorm !== '' && $schoolYearForRange !== '') {
@@ -2295,22 +2298,10 @@ class AdministratorController extends BaseController
public function showEnrollmentWithdrawalPage()
{
try {
$selectedYear = trim((string)($this->request->getGet('schoolYear') ?? ''));
if ($selectedYear === '') {
$selectedYear = (string)$this->schoolYear;
}
$schoolYears = $this->availableSchoolYears();
$selectedYear = $this->selectedEnrollmentSchoolYear($schoolYears);
// Distinct school years from enrollments (for selector)
$yearsRows = $this->db->table('enrollments')
->distinct()
->select('school_year')
->orderBy('school_year', 'DESC')
->get()->getResultArray();
$schoolYears = array_values(array_filter(array_map(static function ($r) {
return isset($r['school_year']) ? (string)$r['school_year'] : null;
}, $yearsRows)));
$students = $this->studentModel->getStudentsWithClassAndEnrollment();
$students = $this->studentModel->getStudentsWithClassAndEnrollment($selectedYear);
$selectedStartYear = $this->getSchoolYearStartYear((string)$selectedYear);
$removedPriorIds = [];
@@ -2326,6 +2317,7 @@ class AdministratorController extends BaseController
}
}
}
$returningStudentIds = $this->priorYearStudentIds($selectedYear);
foreach ($students as &$s) {
// ===== Ensure IDs needed by the modal =====
@@ -2360,6 +2352,9 @@ class AdministratorController extends BaseController
// ===== New-student flags =====
$s['is_new'] = (int) ($s['is_new'] ?? 0);
if (isset($returningStudentIds[$s['student_id']])) {
$s['is_new'] = 0;
}
$s['new_student'] = $s['is_new'] === 1 ? 'Yes' : 'No';
// ===== Admission override =====
@@ -2369,6 +2364,9 @@ class AdministratorController extends BaseController
$s['enrollment_status'] = $statusForYear;
} elseif (($s['admission_status'] ?? null) === 'denied') {
$s['enrollment_status'] = 'denied';
} else {
$s['enrollment_status'] = 'admission under review';
$s['admission_status'] = 'pending';
}
// ===== Class section name for the selected year =====
@@ -2396,22 +2394,7 @@ class AdministratorController extends BaseController
return strcasecmp($pa, $pb);
});
// ===== Provide classes for the modal select (like studentClassAssignment) =====
// Filter to current term; loosen if your table doesnt store these fields.
$classes = $this->classSectionModel
->select('id, class_section_id, class_section_name, school_year, semester')
->where('school_year', (string)$selectedYear)
->where('semester', (string)$this->semester)
->orderBy('class_section_name', 'ASC')
->findAll();
// Fallback so the dropdown never shows empty if filters are too strict
if (empty($classes)) {
$classes = $this->classSectionModel
->select('id, class_section_id, class_section_name')
->orderBy('class_section_name', 'ASC')
->findAll();
}
$classes = $this->enrollmentClassOptions((string)$selectedYear);
return view('enroll_withdraw/enrollment_withdrawal', [
'students' => $students,
@@ -2432,22 +2415,10 @@ class AdministratorController extends BaseController
public function enrollmentWithdrawalData()
{
try {
$selectedYear = trim((string)($this->request->getGet('schoolYear') ?? ''));
if ($selectedYear === '') {
$selectedYear = (string)$this->schoolYear;
}
$schoolYears = $this->availableSchoolYears();
$selectedYear = $this->selectedEnrollmentSchoolYear($schoolYears);
// Distinct school years
$yearsRows = $this->db->table('enrollments')
->distinct()
->select('school_year')
->orderBy('school_year', 'DESC')
->get()->getResultArray();
$schoolYears = array_values(array_filter(array_map(static function ($r) {
return isset($r['school_year']) ? (string)$r['school_year'] : null;
}, $yearsRows)));
$students = $this->studentModel->getStudentsWithClassAndEnrollment();
$students = $this->studentModel->getStudentsWithClassAndEnrollment($selectedYear);
$selectedStartYear = $this->getSchoolYearStartYear((string)$selectedYear);
$removedPriorIds = [];
@@ -2463,6 +2434,7 @@ class AdministratorController extends BaseController
}
}
}
$returningStudentIds = $this->priorYearStudentIds($selectedYear);
foreach ($students as &$s) {
$s['student_id'] = (int)($s['id'] ?? 0);
@@ -2485,6 +2457,9 @@ class AdministratorController extends BaseController
$s['parent_sort'] = trim(($pl !== '' ? $pl : $pf) . ' ' . $pf) ?: 'ZZZ Unknown Parent';
$s['is_new'] = (int) ($s['is_new'] ?? 0);
if (isset($returningStudentIds[$s['student_id']])) {
$s['is_new'] = 0;
}
$s['new_student'] = $s['is_new'] === 1 ? 'Yes' : 'No';
$statusForYear = $this->enrollmentModel->getEnrollmentStatus((int)$s['student_id'], $selectedYear);
@@ -2492,6 +2467,9 @@ class AdministratorController extends BaseController
$s['enrollment_status'] = $statusForYear;
} elseif (($s['admission_status'] ?? null) === 'denied') {
$s['enrollment_status'] = 'denied';
} else {
$s['enrollment_status'] = 'admission under review';
$s['admission_status'] = 'pending';
}
$className = $this->studentClassModel->getClassSectionsByStudentId((int)$s['student_id'], $selectedYear);
@@ -2516,18 +2494,7 @@ class AdministratorController extends BaseController
return strcasecmp($pa, $pb);
});
$classes = $this->classSectionModel
->select('id, class_section_id, class_section_name, school_year, semester')
->where('school_year', (string)$selectedYear)
->where('semester', (string)$this->semester)
->orderBy('class_section_name', 'ASC')
->findAll();
if (empty($classes)) {
$classes = $this->classSectionModel
->select('id, class_section_id, class_section_name')
->orderBy('class_section_name', 'ASC')
->findAll();
}
$classes = $this->enrollmentClassOptions((string)$selectedYear);
return $this->response->setJSON([
'students' => $students,
@@ -2543,6 +2510,138 @@ class AdministratorController extends BaseController
}
}
private function availableSchoolYears(): array
{
$years = [];
$addYear = static function (mixed $value) use (&$years): void {
$year = trim((string) $value);
if ($year !== '' && !in_array($year, $years, true)) {
$years[] = $year;
}
};
$addYear($this->schoolYear ?? null);
if ($this->db->tableExists('school_years')) {
$rows = $this->db->table('school_years')
->select('name')
->orderBy('name', 'DESC')
->get()
->getResultArray();
foreach ($rows as $row) {
$addYear($row['name'] ?? null);
}
}
if ($this->db->tableExists('enrollments')) {
$rows = $this->db->table('enrollments')
->distinct()
->select('school_year')
->where('school_year IS NOT NULL', null, false)
->orderBy('school_year', 'DESC')
->get()
->getResultArray();
foreach ($rows as $row) {
$addYear($row['school_year'] ?? null);
}
}
usort($years, static fn(string $a, string $b): int => strnatcasecmp($b, $a));
$activeYear = trim((string) ($this->schoolYear ?? ''));
if ($activeYear !== '') {
$years = array_values(array_filter($years, static fn(string $year): bool => $year !== $activeYear));
array_unshift($years, $activeYear);
}
return $years;
}
private function selectedEnrollmentSchoolYear(array $schoolYears): string
{
$requestedYear = trim((string) ($this->request->getGet('schoolYear') ?? ''));
if ($requestedYear !== '' && in_array($requestedYear, $schoolYears, true)) {
return $requestedYear;
}
$activeYear = trim((string) ($this->schoolYear ?? ''));
if ($activeYear !== '') {
return $activeYear;
}
return (string) ($schoolYears[0] ?? '');
}
private function enrollmentClassOptions(string $selectedYear): array
{
$select = ['id', 'class_section_id', 'class_section_name'];
$hasSchoolYear = $this->db->fieldExists('school_year', 'classSection');
$hasSemester = $this->db->fieldExists('semester', 'classSection');
if ($hasSchoolYear) {
$select[] = 'school_year';
}
if ($hasSemester) {
$select[] = 'semester';
}
$query = $this->classSectionModel
->select(implode(', ', $select))
->orderBy('class_section_name', 'ASC');
if ($hasSchoolYear && $selectedYear !== '') {
$query->where('school_year', $selectedYear);
}
if ($hasSemester) {
$query->where('semester', (string)$this->semester);
}
$classes = $query->findAll();
if (! empty($classes) || (! $hasSchoolYear && ! $hasSemester)) {
return $classes;
}
return $this->classSectionModel
->select('id, class_section_id, class_section_name')
->orderBy('class_section_name', 'ASC')
->findAll();
}
private function priorYearStudentIds(string $selectedYear): array
{
$selectedStartYear = $this->getSchoolYearStartYear($selectedYear);
if ($selectedStartYear === null) {
return [];
}
$studentIds = [];
foreach (['enrollments', 'student_class'] as $table) {
if (! $this->db->tableExists($table) || ! $this->db->fieldExists('school_year', $table)) {
continue;
}
$rows = $this->db->table($table)
->select('student_id, school_year')
->where('student_id IS NOT NULL', null, false)
->where('school_year IS NOT NULL', null, false)
->get()
->getResultArray();
foreach ($rows as $row) {
$rowStartYear = $this->getSchoolYearStartYear((string) ($row['school_year'] ?? ''));
$studentId = (int) ($row['student_id'] ?? 0);
if ($studentId > 0 && $rowStartYear !== null && $rowStartYear < $selectedStartYear) {
$studentIds[$studentId] = true;
}
}
}
return $studentIds;
}
/**
* Show only newly registered students, with contact modal support.
*