This commit is contained in:
@@ -33,6 +33,7 @@ use App\Models\TeacherSubmissionNotificationHistoryModel;
|
||||
use App\Models\ExamDraftModel;
|
||||
use App\Models\HomeworkModel;
|
||||
use App\Services\SemesterRangeService;
|
||||
use App\Support\Enrollment\DeliberationDecision;
|
||||
|
||||
use CodeIgniter\Events\Events;
|
||||
|
||||
@@ -572,14 +573,14 @@ class AdministratorController extends BaseController
|
||||
// USERS (phone col: cellphone)
|
||||
$uCols = ['firstname', 'lastname', 'email', 'cellphone', 'school_id', 'city', 'state'];
|
||||
$uQB = $db->table('users')
|
||||
->select('id, firstname, lastname, email, cellphone, school_id, city, state, semester');
|
||||
->select('id, firstname, lastname, email, cellphone, school_id, city, state');
|
||||
$applyMultiTokenLike($uQB, $uCols, $tokens, ['cellphone']);
|
||||
$users = $uQB->limit(150)->get()->getResultArray();
|
||||
|
||||
// STUDENTS (no phone column to search)
|
||||
$sCols = ['firstname', 'lastname', 'school_id', 'rfid_tag', 'dob', 'gender'];
|
||||
$sQB = $db->table('students')
|
||||
->select('id, parent_id, school_id, firstname, lastname, dob, gender, semester, rfid_tag');
|
||||
->select('id, parent_id, school_id, firstname, lastname, dob, gender, rfid_tag');
|
||||
$applyMultiTokenLike($sQB, $sCols, $tokens, []);
|
||||
$students = $sQB->limit(150)->get()->getResultArray();
|
||||
|
||||
@@ -2061,6 +2062,7 @@ class AdministratorController extends BaseController
|
||||
{
|
||||
$db = db_connect();
|
||||
$isPg = ($db->getPlatform() === 'Postgre'); // 'MySQLi', 'Postgre', 'SQLSRV', ...
|
||||
$selectedYear = $this->currentSchoolYearName((string) ($this->schoolYear ?? ''));
|
||||
|
||||
// In MySQL, avoid truncation of long lists
|
||||
if (!$isPg) {
|
||||
@@ -2133,20 +2135,23 @@ class AdministratorController extends BaseController
|
||||
->getResultArray();
|
||||
}
|
||||
|
||||
// === Inject class_section_name from student_class via your method and replace grade ===
|
||||
// === Inject current-year class_section_name from student_class and replace grade ===
|
||||
foreach ($students as $i => $row) {
|
||||
$sid = (int) ($row['id'] ?? 0);
|
||||
if ($sid > 0) {
|
||||
// Fetch class_section_name for this student
|
||||
// Assumes your method signature: getClassSectionNameByStudentId(int $studentId): ?string
|
||||
$classSectionName = (string) ($this->studentClassModel->getClassSectionNameByStudentId($sid) ?? '');
|
||||
$classSectionName = (string) ($this->studentClassModel->getClassSectionNameByStudentId($sid, $selectedYear) ?? '');
|
||||
|
||||
// Expose it explicitly and replace original grade if present
|
||||
$students[$i]['class_section_name'] = $classSectionName;
|
||||
} else {
|
||||
// Keep keys consistent even if id missing
|
||||
$students[$i]['class_section_name'] = '';
|
||||
}
|
||||
|
||||
$studentYear = trim((string) ($row['school_year'] ?? ''));
|
||||
$students[$i]['age'] = $this->calculateAgeAsOfSchoolYearStartYear(
|
||||
$row['dob'] ?? null,
|
||||
$studentYear !== '' ? $studentYear : $selectedYear
|
||||
);
|
||||
}
|
||||
// === end injection ===
|
||||
|
||||
@@ -2154,9 +2159,45 @@ class AdministratorController extends BaseController
|
||||
'students' => $students,
|
||||
'gradeOptions' => ['K', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'Youth'],
|
||||
'genderOptions' => ['Male', 'Female', 'Other'],
|
||||
'selectedYear' => $selectedYear,
|
||||
]);
|
||||
}
|
||||
|
||||
private function calculateAgeAsOfSchoolYearStartYear(?string $dob, string $schoolYear): ?int
|
||||
{
|
||||
$dob = trim((string) $dob);
|
||||
$schoolYear = trim($schoolYear);
|
||||
|
||||
if ($dob === '' || ! preg_match('/^(\d{4})/', $schoolYear, $matches)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
$timezone = new \DateTimeZone((string) (config('School')->attendance['timezone'] ?? user_timezone()));
|
||||
$birthDate = \DateTimeImmutable::createFromFormat('!Y-m-d', $dob, $timezone);
|
||||
$errors = \DateTimeImmutable::getLastErrors();
|
||||
$hasParseErrors = is_array($errors)
|
||||
&& (($errors['warning_count'] ?? 0) > 0 || ($errors['error_count'] ?? 0) > 0);
|
||||
|
||||
if ($birthDate === false || $hasParseErrors) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$schoolYearStartYearCutoff = new \DateTimeImmutable($matches[1] . '-09-01', $timezone);
|
||||
if ($birthDate > $schoolYearStartYearCutoff) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $birthDate->diff($schoolYearStartYearCutoff)->y;
|
||||
} catch (\Throwable $e) {
|
||||
log_message('warning', 'Unable to calculate school-year age from DOB: {message}', [
|
||||
'message' => $e->getMessage(),
|
||||
]);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function parentProfiles()
|
||||
@@ -2330,28 +2371,19 @@ class AdministratorController extends BaseController
|
||||
$schoolYearContext = $this->resolveSchoolYearContext();
|
||||
$selectedYear = $schoolYearContext->yearName();
|
||||
|
||||
$this->syncReviewDecisionEnrollments($selectedYear);
|
||||
|
||||
$students = $this->studentModel->getStudentsWithClassAndEnrollment($selectedYear);
|
||||
|
||||
$selectedStartYear = $this->getSchoolYearStartYear((string)$selectedYear);
|
||||
$removedPriorIds = [];
|
||||
if ($selectedStartYear !== null) {
|
||||
$removedRows = $this->db->table('enrollments')
|
||||
->select('student_id, school_year')
|
||||
->where('is_withdrawn', 1)
|
||||
->get()->getResultArray();
|
||||
foreach ($removedRows as $row) {
|
||||
$rowYear = $this->getSchoolYearStartYear((string)($row['school_year'] ?? ''));
|
||||
if ($rowYear !== null && $rowYear < $selectedStartYear) {
|
||||
$removedPriorIds[(int)($row['student_id'] ?? 0)] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$removedPriorStatuses = $this->removedPriorYearStudentStatuses($selectedYear);
|
||||
$returningStudentIds = $this->priorYearStudentIds($selectedYear);
|
||||
|
||||
foreach ($students as &$s) {
|
||||
// ===== Ensure IDs needed by the modal =====
|
||||
$s['student_id'] = (int)($s['id'] ?? 0);
|
||||
$s['removed_previous_year'] = isset($removedPriorIds[$s['student_id']]) ? 'Yes' : 'No';
|
||||
$priorRemovedStatus = $removedPriorStatuses[$s['student_id']] ?? null;
|
||||
$s['removed_previous_year'] = $priorRemovedStatus !== null ? 'Yes' : 'No';
|
||||
$s['prior_removed_status'] = $priorRemovedStatus;
|
||||
|
||||
// Prefer parent_id; fallback to secondparent_user_id if present
|
||||
if (empty($s['parent_id']) && !empty($s['secondparent_user_id'])) {
|
||||
@@ -2389,7 +2421,9 @@ class AdministratorController extends BaseController
|
||||
// ===== Admission override =====
|
||||
// Enrollment status for selected year
|
||||
$statusForYear = $this->enrollmentModel->getEnrollmentStatus((int)$s['student_id'], $selectedYear);
|
||||
if (!empty($statusForYear)) {
|
||||
if (!empty($priorRemovedStatus)) {
|
||||
$s['enrollment_status'] = $priorRemovedStatus;
|
||||
} elseif (!empty($statusForYear)) {
|
||||
$s['enrollment_status'] = $statusForYear;
|
||||
} elseif (($s['admission_status'] ?? null) === 'denied') {
|
||||
$s['enrollment_status'] = 'denied';
|
||||
@@ -2401,6 +2435,8 @@ class AdministratorController extends BaseController
|
||||
// ===== Class section name for the selected year =====
|
||||
$name = $this->studentClassModel->getClassSectionsByStudentId((int)$s['student_id'], $selectedYear);
|
||||
$s['class_section'] = $name ?: 'Class not Assigned';
|
||||
$calculatedAge = $this->calculateAgeAsOfSchoolYearStartYear($s['dob'] ?? null, $selectedYear);
|
||||
$s['age'] = $calculatedAge ?? ($s['age'] ?? null);
|
||||
|
||||
// ===== Sortable registration date (for data-order in view) =====
|
||||
$s['registration_date_order'] = !empty($s['registration_date'])
|
||||
@@ -2445,27 +2481,18 @@ class AdministratorController extends BaseController
|
||||
try {
|
||||
$selectedYear = $this->currentSchoolYearName((string)($this->schoolYear ?? ''));
|
||||
|
||||
$this->syncReviewDecisionEnrollments($selectedYear);
|
||||
|
||||
$students = $this->studentModel->getStudentsWithClassAndEnrollment($selectedYear);
|
||||
|
||||
$selectedStartYear = $this->getSchoolYearStartYear((string)$selectedYear);
|
||||
$removedPriorIds = [];
|
||||
if ($selectedStartYear !== null) {
|
||||
$removedRows = $this->db->table('enrollments')
|
||||
->select('student_id, school_year')
|
||||
->where('is_withdrawn', 1)
|
||||
->get()->getResultArray();
|
||||
foreach ($removedRows as $row) {
|
||||
$rowYear = $this->getSchoolYearStartYear((string)($row['school_year'] ?? ''));
|
||||
if ($rowYear !== null && $rowYear < $selectedStartYear) {
|
||||
$removedPriorIds[(int)($row['student_id'] ?? 0)] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$removedPriorStatuses = $this->removedPriorYearStudentStatuses($selectedYear);
|
||||
$returningStudentIds = $this->priorYearStudentIds($selectedYear);
|
||||
|
||||
foreach ($students as &$s) {
|
||||
$s['student_id'] = (int)($s['id'] ?? 0);
|
||||
$s['removed_previous_year'] = isset($removedPriorIds[$s['student_id']]) ? 'Yes' : 'No';
|
||||
$priorRemovedStatus = $removedPriorStatuses[$s['student_id']] ?? null;
|
||||
$s['removed_previous_year'] = $priorRemovedStatus !== null ? 'Yes' : 'No';
|
||||
$s['prior_removed_status'] = $priorRemovedStatus;
|
||||
|
||||
if (empty($s['parent_id']) && !empty($s['secondparent_user_id'])) {
|
||||
$s['parent_id'] = (int)$s['secondparent_user_id'];
|
||||
@@ -2490,7 +2517,9 @@ class AdministratorController extends BaseController
|
||||
$s['new_student'] = $s['is_new'] === 1 ? 'Yes' : 'No';
|
||||
|
||||
$statusForYear = $this->enrollmentModel->getEnrollmentStatus((int)$s['student_id'], $selectedYear);
|
||||
if (!empty($statusForYear)) {
|
||||
if (!empty($priorRemovedStatus)) {
|
||||
$s['enrollment_status'] = $priorRemovedStatus;
|
||||
} elseif (!empty($statusForYear)) {
|
||||
$s['enrollment_status'] = $statusForYear;
|
||||
} elseif (($s['admission_status'] ?? null) === 'denied') {
|
||||
$s['enrollment_status'] = 'denied';
|
||||
@@ -2501,6 +2530,8 @@ class AdministratorController extends BaseController
|
||||
|
||||
$className = $this->studentClassModel->getClassSectionsByStudentId((int)$s['student_id'], $selectedYear);
|
||||
$s['class_section'] = $className ?: 'Class not Assigned';
|
||||
$calculatedAge = $this->calculateAgeAsOfSchoolYearStartYear($s['dob'] ?? null, $selectedYear);
|
||||
$s['age'] = $calculatedAge ?? ($s['age'] ?? null);
|
||||
|
||||
$s['registration_date_order'] = !empty($s['registration_date'])
|
||||
? date('Y-m-d', strtotime($s['registration_date']))
|
||||
@@ -2536,6 +2567,172 @@ class AdministratorController extends BaseController
|
||||
}
|
||||
}
|
||||
|
||||
private function syncReviewDecisionEnrollments(string $selectedYear): void
|
||||
{
|
||||
$selectedYear = trim($selectedYear);
|
||||
$sourceYear = $this->getPreviousSchoolYear($selectedYear);
|
||||
if ($selectedYear === '' || $sourceYear === '' || ! $this->db->tableExists('enrollments')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$studentIds = $this->sourceYearStudentIds($sourceYear);
|
||||
if ($studentIds === []) {
|
||||
return;
|
||||
}
|
||||
|
||||
$transitionService = service('enrollmentTransition');
|
||||
$now = utc_now();
|
||||
|
||||
foreach ($studentIds as $studentId) {
|
||||
try {
|
||||
$evaluation = $transitionService->evaluate((int) $studentId, $sourceYear, $selectedYear, 'parent');
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Review & Decision enrollment sync evaluation failed for student {studentId}: {message}', [
|
||||
'studentId' => $studentId,
|
||||
'message' => $e->getMessage(),
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $this->needsReviewDecisionEnrollment($evaluation)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$student = $this->studentModel->find((int) $studentId);
|
||||
if (! is_array($student)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$parentId = (int) ($student['parent_id'] ?? ($student['secondparent_user_id'] ?? 0));
|
||||
if ($parentId <= 0) {
|
||||
log_message('warning', 'Review & Decision enrollment sync skipped student {studentId}: no parent ID.', [
|
||||
'studentId' => $studentId,
|
||||
]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$existing = $this->db->table('enrollments')
|
||||
->select('id, enrollment_status')
|
||||
->where('student_id', (int) $studentId)
|
||||
->where('school_year', $selectedYear)
|
||||
->orderBy('updated_at', 'DESC')
|
||||
->orderBy('id', 'DESC')
|
||||
->limit(1)
|
||||
->get()
|
||||
->getRowArray();
|
||||
|
||||
if ($existing !== null) {
|
||||
$existingStatus = (string) ($existing['enrollment_status'] ?? '');
|
||||
if ($existingStatus === 'review & decision' || ! in_array($existingStatus, ['', 'admission under review'], true)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$payload = [
|
||||
'student_id' => (int) $studentId,
|
||||
'parent_id' => $parentId,
|
||||
'school_year' => $selectedYear,
|
||||
'semester' => (string) $this->semester,
|
||||
'source_school_year' => $sourceYear,
|
||||
'deliberation_decision' => $evaluation['deliberation_decision'] ?? null,
|
||||
'source_grade_id' => $evaluation['source_grade_id'] ?? null,
|
||||
'assigned_grade_id' => $evaluation['assigned_grade_id'] ?? null,
|
||||
'source_class_section_id' => $evaluation['source_class_section_id'] ?? null,
|
||||
'assigned_class_section_id' => $evaluation['assigned_class_section_id'] ?? null,
|
||||
'placement_status' => $evaluation['placement_status'] ?? 'not_created',
|
||||
'age_reference_date' => $evaluation['age_reference_date'] ?? null,
|
||||
'age_on_reference_date' => $evaluation['age_on_reference_date'] ?? null,
|
||||
'adult_student' => ! empty($evaluation['adult_student']) ? 1 : 0,
|
||||
'parent_enrollment_allowed' => ! empty($evaluation['parent_enrollment_allowed']) ? 1 : 0,
|
||||
'student_self_enrollment_allowed' => ! empty($evaluation['student_self_enrollment_allowed']) ? 1 : 0,
|
||||
'exception_required' => 1,
|
||||
'exception_reason' => implode(', ', array_filter(array_column($evaluation['flags'] ?? [], 'flag_type'))) ?: implode(' ', array_map('strval', $evaluation['blockers'] ?? [])),
|
||||
'enrollment_date' => local_date(utc_now(), 'Y-m-d'),
|
||||
'enrollment_status' => 'review & decision',
|
||||
'admission_status' => 'pending',
|
||||
'is_withdrawn' => 0,
|
||||
'updated_at' => $now,
|
||||
];
|
||||
$payload = $this->filterEnrollmentPayloadByColumns($payload);
|
||||
|
||||
if ($existing !== null) {
|
||||
$this->db->table('enrollments')
|
||||
->where('id', (int) $existing['id'])
|
||||
->update($payload);
|
||||
} else {
|
||||
$payload['created_at'] = $now;
|
||||
$this->db->table('enrollments')->insert($this->filterEnrollmentPayloadByColumns($payload));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function needsReviewDecisionEnrollment(array $evaluation): bool
|
||||
{
|
||||
$decision = (string) ($evaluation['deliberation_decision'] ?? '');
|
||||
|
||||
if (in_array($decision, [
|
||||
DeliberationDecision::EXPELLED,
|
||||
DeliberationDecision::WITHDRAWN,
|
||||
DeliberationDecision::DEFERRED_DECISION,
|
||||
], true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$hasSourceAssignment = (int) ($evaluation['source_class_section_id'] ?? 0) > 0
|
||||
|| (int) ($evaluation['source_grade_id'] ?? 0) > 0;
|
||||
|
||||
return $decision === ''
|
||||
&& $hasSourceAssignment
|
||||
&& array_filter($evaluation['blockers'] ?? []) !== [];
|
||||
}
|
||||
|
||||
private function sourceYearStudentIds(string $sourceYear): array
|
||||
{
|
||||
$studentIds = [];
|
||||
|
||||
foreach (['student_class', 'enrollments', 'student_decisions'] as $table) {
|
||||
if (! $this->db->tableExists($table) || ! $this->db->fieldExists('student_id', $table)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$yearColumn = match ($table) {
|
||||
'student_class', 'student_decisions' => 'school_year',
|
||||
default => 'school_year',
|
||||
};
|
||||
|
||||
if (! $this->db->fieldExists($yearColumn, $table)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$rows = $this->db->table($table)
|
||||
->select('student_id')
|
||||
->where($yearColumn, $sourceYear)
|
||||
->where('student_id IS NOT NULL', null, false)
|
||||
->get()
|
||||
->getResultArray();
|
||||
|
||||
foreach ($rows as $row) {
|
||||
$studentId = (int) ($row['student_id'] ?? 0);
|
||||
if ($studentId > 0) {
|
||||
$studentIds[$studentId] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_keys($studentIds);
|
||||
}
|
||||
|
||||
private function filterEnrollmentPayloadByColumns(array $payload): array
|
||||
{
|
||||
foreach (array_keys($payload) as $column) {
|
||||
if (! $this->db->fieldExists($column, 'enrollments')) {
|
||||
unset($payload[$column]);
|
||||
}
|
||||
}
|
||||
|
||||
return $payload;
|
||||
}
|
||||
|
||||
private function enrollmentClassOptions(string $selectedYear): array
|
||||
{
|
||||
$select = ['id', 'class_section_id', 'class_section_name'];
|
||||
@@ -2572,6 +2769,115 @@ class AdministratorController extends BaseController
|
||||
->findAll();
|
||||
}
|
||||
|
||||
private function removedPriorYearStudentStatuses(string $selectedYear): array
|
||||
{
|
||||
$selectedStartYear = $this->getSchoolYearStartYear($selectedYear);
|
||||
if ($selectedStartYear === null || ! $this->db->tableExists('enrollments')) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$select = ['student_id', 'school_year'];
|
||||
$hasIsWithdrawn = $this->db->fieldExists('is_withdrawn', 'enrollments');
|
||||
$hasEnrollmentStatus = $this->db->fieldExists('enrollment_status', 'enrollments');
|
||||
$hasAdmissionStatus = $this->db->fieldExists('admission_status', 'enrollments');
|
||||
|
||||
if ($hasIsWithdrawn) {
|
||||
$select[] = 'is_withdrawn';
|
||||
}
|
||||
if ($hasEnrollmentStatus) {
|
||||
$select[] = 'enrollment_status';
|
||||
}
|
||||
if ($hasAdmissionStatus) {
|
||||
$select[] = 'admission_status';
|
||||
}
|
||||
|
||||
if (! $hasIsWithdrawn && ! $hasEnrollmentStatus && ! $hasAdmissionStatus) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$builder = $this->db->table('enrollments')
|
||||
->select(implode(', ', $select))
|
||||
->where('student_id IS NOT NULL', null, false)
|
||||
->where('school_year IS NOT NULL', null, false)
|
||||
->groupStart();
|
||||
|
||||
$hasRemovalCondition = false;
|
||||
if ($hasIsWithdrawn) {
|
||||
$builder->where('is_withdrawn', 1);
|
||||
$hasRemovalCondition = true;
|
||||
}
|
||||
|
||||
if ($hasEnrollmentStatus) {
|
||||
if ($hasRemovalCondition) {
|
||||
$builder->orWhereIn('enrollment_status', ['withdrawn', 'widthran', 'denied']);
|
||||
} else {
|
||||
$builder->whereIn('enrollment_status', ['withdrawn', 'widthran', 'denied']);
|
||||
}
|
||||
$hasRemovalCondition = true;
|
||||
}
|
||||
|
||||
if ($hasAdmissionStatus) {
|
||||
if ($hasRemovalCondition) {
|
||||
$builder->orWhere('admission_status', 'denied');
|
||||
} else {
|
||||
$builder->where('admission_status', 'denied');
|
||||
}
|
||||
$hasRemovalCondition = true;
|
||||
}
|
||||
|
||||
$builder->groupEnd();
|
||||
if (! $hasRemovalCondition) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$removedPriorStatuses = [];
|
||||
foreach ($builder->get()->getResultArray() as $row) {
|
||||
$rowYear = $this->getSchoolYearStartYear((string)($row['school_year'] ?? ''));
|
||||
$studentId = (int)($row['student_id'] ?? 0);
|
||||
if ($studentId <= 0 || $rowYear === null || $rowYear >= $selectedStartYear) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$status = $this->priorRemovedEnrollmentStatus($row);
|
||||
if ($status === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
!isset($removedPriorStatuses[$studentId])
|
||||
|| $rowYear > (int)$removedPriorStatuses[$studentId]['year']
|
||||
) {
|
||||
$removedPriorStatuses[$studentId] = [
|
||||
'year' => $rowYear,
|
||||
'status' => $status,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$statusByStudentId = [];
|
||||
foreach ($removedPriorStatuses as $studentId => $row) {
|
||||
$statusByStudentId[(int)$studentId] = (string)$row['status'];
|
||||
}
|
||||
|
||||
return $statusByStudentId;
|
||||
}
|
||||
|
||||
private function priorRemovedEnrollmentStatus(array $row): ?string
|
||||
{
|
||||
$enrollmentStatus = strtolower(trim((string)($row['enrollment_status'] ?? '')));
|
||||
$admissionStatus = strtolower(trim((string)($row['admission_status'] ?? '')));
|
||||
|
||||
if ($enrollmentStatus === 'denied' || $admissionStatus === 'denied') {
|
||||
return 'denied';
|
||||
}
|
||||
|
||||
if (in_array($enrollmentStatus, ['withdrawn', 'widthran'], true) || (int)($row['is_withdrawn'] ?? 0) === 1) {
|
||||
return 'withdrawn';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function priorYearStudentIds(string $selectedYear): array
|
||||
{
|
||||
$selectedStartYear = $this->getSchoolYearStartYear($selectedYear);
|
||||
@@ -2674,6 +2980,7 @@ class AdministratorController extends BaseController
|
||||
|
||||
$validStatuses = [
|
||||
'admission under review',
|
||||
'review & decision',
|
||||
'payment pending',
|
||||
'enrolled',
|
||||
'withdraw under review',
|
||||
@@ -2921,6 +3228,7 @@ class AdministratorController extends BaseController
|
||||
// === AFTER COMMIT: fire specific events, batched per parent/status ===
|
||||
$eventMap = [
|
||||
'admission under review' => 'admissionUnderReview',
|
||||
'review & decision' => 'admissionUnderReview',
|
||||
'payment pending' => 'paymentPending',
|
||||
'enrolled' => 'studentEnrolled',
|
||||
'withdraw under review' => 'withdrawUnderReview',
|
||||
|
||||
Reference in New Issue
Block a user