This commit is contained in:
@@ -19,6 +19,7 @@ use App\Models\AdminNotificationSubjectModel;
|
||||
use Doctrine\DBAL\Configuration;
|
||||
use App\Services\FeeCalculationService;
|
||||
use App\Models\StudentClassModel;
|
||||
use App\Models\StudentSectionDistributionDraftModel;
|
||||
use App\Controllers\View\EmailController;
|
||||
use App\Controllers\View\InvoiceController;
|
||||
use App\Models\StaffAttendanceModel;
|
||||
@@ -2159,6 +2160,10 @@ class AdministratorController extends BaseController
|
||||
|
||||
public function parentProfiles()
|
||||
{
|
||||
if ($redirect = $this->redirectWithoutLegacyTermFilters('administrator/parent_profiles')) {
|
||||
return $redirect;
|
||||
}
|
||||
|
||||
// Fetch all users with their roles in one go
|
||||
$allUsers = $this->userModel->findAll();
|
||||
$parents = [];
|
||||
@@ -2215,6 +2220,27 @@ class AdministratorController extends BaseController
|
||||
return view('administrator/parent_profile', ['parents' => $parents]);
|
||||
}
|
||||
|
||||
private function redirectWithoutLegacyTermFilters(string $route): ?\CodeIgniter\HTTP\RedirectResponse
|
||||
{
|
||||
$legacyTermKeys = ['school_year', 'schoolYear', 'year', 'semester'];
|
||||
$query = $this->request->getGet();
|
||||
$hasLegacyTermFilter = false;
|
||||
|
||||
foreach ($legacyTermKeys as $key) {
|
||||
if (array_key_exists($key, $query)) {
|
||||
unset($query[$key]);
|
||||
$hasLegacyTermFilter = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$hasLegacyTermFilter) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$target = site_url($route) . (!empty($query) ? '?' . http_build_query($query) : '');
|
||||
return redirect()->to($target);
|
||||
}
|
||||
|
||||
public function manageUsers()
|
||||
{// Fetch all users
|
||||
$users = $this->userModel->findAll();
|
||||
@@ -2298,8 +2324,8 @@ class AdministratorController extends BaseController
|
||||
public function showEnrollmentWithdrawalPage()
|
||||
{
|
||||
try {
|
||||
$schoolYears = $this->availableSchoolYears();
|
||||
$selectedYear = $this->selectedEnrollmentSchoolYear($schoolYears);
|
||||
$schoolYearContext = $this->resolveSchoolYearContext();
|
||||
$selectedYear = $schoolYearContext->yearName();
|
||||
|
||||
$students = $this->studentModel->getStudentsWithClassAndEnrollment($selectedYear);
|
||||
|
||||
@@ -2399,11 +2425,10 @@ class AdministratorController extends BaseController
|
||||
return view('enroll_withdraw/enrollment_withdrawal', [
|
||||
'students' => $students,
|
||||
'classes' => $classes, // <-- used by the modal <select>
|
||||
'schoolYears' => $schoolYears,
|
||||
'selectedYear' => $selectedYear,
|
||||
'currentYear' => (string)$this->schoolYear,
|
||||
'isCurrentYear' => ((string)$selectedYear === (string)$this->schoolYear),
|
||||
'missingYear' => empty($this->schoolYear),
|
||||
'currentYear' => $selectedYear,
|
||||
'isCurrentYear' => ! $schoolYearContext->isReadonly(),
|
||||
'missingYear' => $selectedYear === '',
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'Enrollment/Withdrawal page error: {msg}', ['msg' => $e->getMessage()]);
|
||||
@@ -2415,8 +2440,7 @@ class AdministratorController extends BaseController
|
||||
public function enrollmentWithdrawalData()
|
||||
{
|
||||
try {
|
||||
$schoolYears = $this->availableSchoolYears();
|
||||
$selectedYear = $this->selectedEnrollmentSchoolYear($schoolYears);
|
||||
$selectedYear = $this->currentSchoolYearName((string)($this->schoolYear ?? ''));
|
||||
|
||||
$students = $this->studentModel->getStudentsWithClassAndEnrollment($selectedYear);
|
||||
|
||||
@@ -2502,7 +2526,6 @@ class AdministratorController extends BaseController
|
||||
'csrfHash' => csrf_hash(),
|
||||
'semester' => (string)$this->semester,
|
||||
'school_year' => (string)$selectedYear,
|
||||
'schoolYears' => $schoolYears,
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'enrollmentWithdrawalData error: {msg}', ['msg' => $e->getMessage()]);
|
||||
@@ -2510,70 +2533,6 @@ 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'];
|
||||
@@ -2795,6 +2754,9 @@ class AdministratorController extends BaseController
|
||||
}
|
||||
|
||||
log_message('info', "Created enrollment for student ID {$studentId} with status {$newEnrollmentStatus} and admission {$admissionStatus}.");
|
||||
if (in_array($newEnrollmentStatus, ['payment pending', 'enrolled'], true)) {
|
||||
$this->applyDistributionDraftToStudentClass((int)$studentId, (string)$this->schoolYear);
|
||||
}
|
||||
continue; // go to next student
|
||||
}
|
||||
|
||||
@@ -2811,6 +2773,9 @@ class AdministratorController extends BaseController
|
||||
// Skip if no actual change
|
||||
if ($oldStatus === $newEnrollmentStatus) {
|
||||
log_message('debug', "No status change for student {$studentId} ({$oldStatus}) — skipping.");
|
||||
if (in_array($newEnrollmentStatus, ['payment pending', 'enrolled'], true)) {
|
||||
$this->applyDistributionDraftToStudentClass((int)$studentId, (string)$this->schoolYear);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2830,6 +2795,9 @@ class AdministratorController extends BaseController
|
||||
}
|
||||
|
||||
log_message('info', "Updated enrollment for student ID $studentId: {$oldStatus} → {$newEnrollmentStatus} (admission: {$admissionStatus})");
|
||||
if (in_array($newEnrollmentStatus, ['payment pending', 'enrolled'], true)) {
|
||||
$this->applyDistributionDraftToStudentClass((int)$studentId, (string)$this->schoolYear);
|
||||
}
|
||||
|
||||
// Student name
|
||||
$studentRow = $this->studentModel->find($studentId);
|
||||
@@ -3009,4 +2977,71 @@ class AdministratorController extends BaseController
|
||||
->with('error', 'An unexpected error occurred while processing enrollments.');
|
||||
}
|
||||
}
|
||||
|
||||
private function applyDistributionDraftToStudentClass(int $studentId, string $year): void
|
||||
{
|
||||
try {
|
||||
$draftModel = new StudentSectionDistributionDraftModel();
|
||||
$draft = $draftModel->where('student_id', $studentId)
|
||||
->where('school_year', $year)
|
||||
->where('status', 'pending')
|
||||
->first();
|
||||
|
||||
if (!$draft) {
|
||||
return;
|
||||
}
|
||||
|
||||
$targetSectionId = (int)($draft['class_section_id'] ?? 0);
|
||||
if ($targetSectionId <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$studentClass = new StudentClassModel();
|
||||
$exists = $studentClass->where('student_id', $studentId)
|
||||
->where('school_year', $year)
|
||||
->first();
|
||||
|
||||
$payload = [
|
||||
'student_id' => $studentId,
|
||||
'class_section_id' => $targetSectionId,
|
||||
'school_year' => $year,
|
||||
'updated_by' => (int)(session()->get('user_id') ?? 0) ?: null,
|
||||
'updated_at' => utc_now(),
|
||||
];
|
||||
|
||||
if ($exists) {
|
||||
$studentClass->update((int)$exists['id'], $payload);
|
||||
} else {
|
||||
$payload['created_at'] = utc_now();
|
||||
$studentClass->insert($payload);
|
||||
}
|
||||
|
||||
$this->db->table('enrollments')
|
||||
->where('student_id', $studentId)
|
||||
->where('school_year', $year)
|
||||
->whereIn('enrollment_status', ['payment pending', 'enrolled'])
|
||||
->update([
|
||||
'class_section_id' => $targetSectionId,
|
||||
'updated_at' => utc_now(),
|
||||
]);
|
||||
|
||||
$this->db->table('promotion_queue')
|
||||
->where('student_id', $studentId)
|
||||
->where('school_year_to', $year)
|
||||
->update([
|
||||
'to_class_section_id' => $targetSectionId,
|
||||
'status' => 'applied',
|
||||
'updated_by' => (int)(session()->get('user_id') ?? 0) ?: null,
|
||||
'updated_at' => utc_now(),
|
||||
]);
|
||||
|
||||
$draftModel->update((int)$draft['id'], [
|
||||
'status' => 'applied',
|
||||
'applied_at' => utc_now(),
|
||||
'updated_at' => utc_now(),
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', 'applyDistributionDraftToStudentClass failed: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user