fix enrollment, invoice, payment and financila aid
Deploy to Shared Hosting / Shared hosting deploy (push) Failing after 47s
Tests / PHPUnit (push) Failing after 1m19s

This commit is contained in:
root
2026-08-24 21:20:58 -04:00
parent 576da3bd78
commit 608aca79b8
30 changed files with 3327 additions and 774 deletions
@@ -233,7 +233,6 @@ class EnrollmentAdminController extends BaseController
$ruleCodes = $this->ruleCodesForFlag((string) $flag['flag_type']);
$now = date('Y-m-d H:i:s');
$expiresAt = date('Y-m-d H:i:s', strtotime('+30 days'));
$this->db->transStart();
@@ -260,7 +259,7 @@ class EnrollmentAdminController extends BaseController
'created_by' => $this->userId(),
'approved_by' => $this->userId(),
'starts_at' => $now,
'expires_at' => $expiresAt,
'expires_at' => null,
'updated_at' => $now,
];
@@ -314,7 +313,6 @@ class EnrollmentAdminController extends BaseController
$schoolYear = trim((string) ($this->request->getPost('school_year') ?? ''));
$reasonCode = trim((string) ($this->request->getPost('reason_code') ?? ''));
$reasonNote = trim((string) ($this->request->getPost('reason_note') ?? ''));
$expiresAt = trim((string) ($this->request->getPost('expires_at') ?? ''));
$postedCodesByStudent = $this->request->getPost('bypassed_rule_codes_by_student') ?? [];
$postedCodesByStudent = is_array($postedCodesByStudent) ? $postedCodesByStudent : [];
@@ -327,16 +325,6 @@ class EnrollmentAdminController extends BaseController
return redirect()->back()->withInput()->with('error', 'Unable to determine the source school year.');
}
if ($expiresAt === '') {
$expiresAt = date('Y-m-d H:i:s', strtotime('+30 days'));
} else {
try {
$expiresAt = (new \DateTimeImmutable($expiresAt))->format('Y-m-d H:i:s');
} catch (\Throwable) {
return redirect()->back()->withInput()->with('error', 'Expiration date is invalid.');
}
}
$now = date('Y-m-d H:i:s');
$transitionService = service('enrollmentTransition');
$saved = 0;
@@ -360,7 +348,7 @@ class EnrollmentAdminController extends BaseController
$failedCodes = array_values(array_unique(array_map(static fn (string $code): string => strtoupper(trim($code)), $failedCodes)));
$ruleCodes = $postedCodes !== [] ? array_values(array_intersect($postedCodes, $failedCodes)) : $failedCodes;
$ruleCodes = array_values(array_filter($ruleCodes, static fn (string $code): bool => $code !== ''));
$nonOverridable = array_values(array_intersect($ruleCodes, ['STUDENT_NOT_LINKED', 'SOURCE_YEAR_NOT_FOUND', 'TARGET_YEAR_NOT_FOUND', 'ALREADY_ENROLLED']));
$nonOverridable = array_values(array_intersect($ruleCodes, ['ADULT_STUDENT_PARENT_BLOCKED']));
if ($nonOverridable !== []) {
$this->db->transRollback();
return redirect()->back()->withInput()->with('error', 'These rule(s) cannot be bypassed: ' . implode(', ', $nonOverridable));
@@ -393,7 +381,7 @@ class EnrollmentAdminController extends BaseController
'created_by' => $this->userId(),
'approved_by' => $this->userId(),
'starts_at' => $now,
'expires_at' => $expiresAt,
'expires_at' => null,
'updated_at' => $now,
];
@@ -496,8 +484,13 @@ class EnrollmentAdminController extends BaseController
if (is_numeric($assignedTo) && (int) $assignedTo > 0) {
$builder->where('ef.assigned_to', (int) $assignedTo);
}
$builder->where('ef.flag_type !=', 'CLASS_CAPACITY_EXCEPTION_REQUIRED');
$rows = $builder->get()->getResultArray();
$rows = array_values(array_filter(
$rows,
static fn (array $row): bool => (string) ($row['flag_type'] ?? '') !== 'CLASS_CAPACITY_EXCEPTION_REQUIRED'
));
foreach ($rows as &$row) {
$row['student_name'] = trim((string) ($row['firstname'] ?? '') . ' ' . (string) ($row['lastname'] ?? '')) ?: 'Student #' . (int) ($row['student_id'] ?? 0);
$row['assignee_name'] = trim((string) ($row['assignee_firstname'] ?? '') . ' ' . (string) ($row['assignee_lastname'] ?? ''));
@@ -671,7 +664,6 @@ class EnrollmentAdminController extends BaseController
$followupTypes = [
'PENDING_MAKE_UP_EXAM_PROMOTION' => 'temporary_same_grade',
'CLASS_REASSIGNMENT_REQUIRED' => 'manual_class_required',
'CLASS_CAPACITY_EXCEPTION_REQUIRED' => 'manual_class_required',
'COMPLETION_OR_EXIT_PROCESS_REQUIRED' => 'exit_required',
];
@@ -707,7 +699,6 @@ class EnrollmentAdminController extends BaseController
'AGE_EXCEPTION_REQUIRED',
'LATE_REGISTRATION_EXCEPTION',
'FINANCIAL_REVIEW_REQUIRED',
'CLASS_CAPACITY_EXCEPTION_REQUIRED',
'SIBLING_LAST_NAME_MISMATCH',
'DEFERRED_DELIBERATION',
'WITHDRAWAL_REVIEW_REQUIRED',
@@ -802,7 +793,7 @@ class EnrollmentAdminController extends BaseController
throw new \RuntimeException('Selected class section was not found.');
}
$originalEnrollment = $this->latestEnrollment($studentId, $schoolYear);
$originalEnrollment = service('enrollmentStatus')->controllingEnrollment($studentId, $schoolYear);
$payload = [
'class_section_id' => $sectionId,
'assigned_class_section_id' => $sectionId,
@@ -838,6 +829,26 @@ class EnrollmentAdminController extends BaseController
}
$this->audit($studentId, $schoolYear, (string) ($originalEnrollment['source_school_year'] ?? ''), $auditAction, $originalEnrollment, $payload, 'Class section assigned by administrator.');
$parentId = (int) ($originalEnrollment['parent_id'] ?? 0);
if ($parentId <= 0) {
$student = $this->db->table('students')->select('parent_id')->where('id', $studentId)->limit(1)->get()->getRowArray();
$parentId = (int) ($student['parent_id'] ?? 0);
}
if ($parentId > 0) {
try {
(new InvoiceController())->generateInvoice(
(string) $parentId,
$schoolYear,
(string) ($originalEnrollment['semester'] ?? getSemester())
);
} catch (\Throwable $e) {
log_message('error', 'Invoice refresh after enrollment admin class assignment failed for parent {parent_id}: {error}', [
'parent_id' => $parentId,
'error' => $e->getMessage(),
]);
}
}
}
private function updateEnrollmentPlacementStatus(int $studentId, string $schoolYear, string $placementStatus): void
@@ -853,14 +864,7 @@ class EnrollmentAdminController extends BaseController
private function latestEnrollment(int $studentId, string $schoolYear): ?array
{
return $this->db->table('enrollments')
->where('student_id', $studentId)
->where('school_year', $schoolYear)
->orderBy('updated_at', 'DESC')
->orderBy('id', 'DESC')
->limit(1)
->get()
->getRowArray() ?: null;
return service('enrollmentStatus')->controllingEnrollment($studentId, $schoolYear);
}
private function audit(int $studentId, string $schoolYear, string $sourceSchoolYear, string $action, ?array $original, array $new, string $reason): void
@@ -1126,7 +1130,6 @@ class EnrollmentAdminController extends BaseController
'AGE_EXCEPTION_REQUIRED' => ['AGE_RULE_BLOCKED'],
'LATE_REGISTRATION_EXCEPTION' => ['REGISTRATION_CLOSED'],
'FINANCIAL_REVIEW_REQUIRED' => ['OUTSTANDING_BALANCE_BLOCKED', 'FINANCE_APPROVAL_REQUIRED'],
'CLASS_CAPACITY_EXCEPTION_REQUIRED' => ['CLASS_CAPACITY_EXCEPTION_REQUIRED'],
'RESTRICTED_ADMINISTRATIVE_REVIEW' => ['EXPELLED'],
'WITHDRAWAL_REVIEW_REQUIRED' => ['WITHDRAWN'],
'DEFERRED_DELIBERATION' => ['NO_FINAL_DECISION', 'UNRECOGNIZED_DECISION', 'DEFERRED_DECISION'],
@@ -1246,7 +1249,9 @@ class EnrollmentAdminController extends BaseController
return 0;
}
$builder = $this->db->table('enrollment_flags')->where('status', 'open');
$builder = $this->db->table('enrollment_flags')
->where('status', 'open')
->where('flag_type !=', 'CLASS_CAPACITY_EXCEPTION_REQUIRED');
if ($schoolYear !== '') {
$builder->where('school_year', $schoolYear);
}
@@ -1260,7 +1265,18 @@ class EnrollmentAdminController extends BaseController
return [];
}
return array_column($this->db->table('enrollment_flags')->select('flag_type')->distinct()->orderBy('flag_type')->get()->getResultArray(), 'flag_type');
$types = array_column(
$this->db->table('enrollment_flags')
->select('flag_type')
->where('flag_type !=', 'CLASS_CAPACITY_EXCEPTION_REQUIRED')
->distinct()
->orderBy('flag_type')
->get()
->getResultArray(),
'flag_type'
);
return array_values(array_filter($types, static fn ($type): bool => (string) $type !== 'CLASS_CAPACITY_EXCEPTION_REQUIRED'));
}
private function schoolYears(): array