fix enrollment for the new school-year
Tests / PHPUnit (push) Successful in 1m26s

This commit is contained in:
root
2026-08-07 23:43:31 -04:00
parent b6f3b14e7b
commit 1ef2800f12
66 changed files with 8997 additions and 498 deletions
+13 -6
View File
@@ -7,6 +7,7 @@ use App\Models\SchoolYearClosingItemModel;
use App\Models\SchoolYearModel;
use App\Models\ConfigurationModel;
use App\Models\InvoiceModel;
use App\Support\Enrollment\DeliberationDecision;
use App\Support\SchoolYear\SchoolYearStatus;
use CodeIgniter\Database\BaseConnection;
use InvalidArgumentException;
@@ -644,6 +645,7 @@ final class SchoolYearClosingService
'auto_kg_pass' => false,
'year_score' => null,
'decision' => '',
'normalized_decision' => null,
'source' => 'missing',
'notes' => '',
'status' => 'missing',
@@ -667,6 +669,7 @@ final class SchoolYearClosingService
if ($decision !== null) {
$student['year_score'] = $decision['year_score'];
$student['decision'] = $decision['decision'];
$student['normalized_decision'] = $decision['normalized_decision'];
$student['source'] = $decision['source'];
$student['notes'] = $decision['notes'];
$student['status'] = $decision['status'];
@@ -676,17 +679,19 @@ final class SchoolYearClosingService
}
if ($decision === null && $this->isKgStudent($student)) {
$kgAgeStatus = $this->kgAgeStatusByTargetYearCutoff((string) $student['dob'], $targetSchoolYear);
$kgAgeStatus = $this->kgAgeStatusByTargetYearStartCutoff((string) $student['dob'], $targetSchoolYear);
if ($kgAgeStatus === 'pass') {
$student['decision'] = 'Pass';
$student['normalized_decision'] = DeliberationDecision::PASSED;
$student['source'] = 'automatic_kg_age';
$student['notes'] = 'Auto-pass KG student: age 6 or older by Dec 31 of the next school year start year.';
$student['notes'] = 'Auto-pass KG student: age 6 or older by Sep 1 of the next school year.';
$student['status'] = 'decided';
$student['auto_kg_pass'] = true;
} elseif ($kgAgeStatus === 'keep_kg') {
$student['decision'] = 'Keep KG';
$student['normalized_decision'] = DeliberationDecision::REPEAT_CLASS;
$student['source'] = 'automatic_kg_age';
$student['notes'] = 'Auto-keep KG student: younger than 6 by Dec 31 of the next school year start year.';
$student['notes'] = 'Auto-keep KG student: younger than 6 by Sep 1 of the next school year.';
$student['status'] = 'decided';
}
}
@@ -705,7 +710,7 @@ final class SchoolYearClosingService
$summary['pending_decision']++;
} else {
$summary['with_decision']++;
if (strcasecmp((string) $student['decision'], 'Pass') === 0) {
if (($student['normalized_decision'] ?? null) === DeliberationDecision::PASSED) {
$summary['pass']++;
if ($queue === null && $student['auto_kg_pass'] !== true) {
$summary['missing_queue']++;
@@ -745,7 +750,7 @@ final class SchoolYearClosingService
return false;
}
private function kgAgeStatusByTargetYearCutoff(string $dob, ?string $targetSchoolYear): string
private function kgAgeStatusByTargetYearStartCutoff(string $dob, ?string $targetSchoolYear): string
{
$dob = trim($dob);
if ($dob === '' || $targetSchoolYear === null || ! preg_match('/^(\d{4})-\d{4}$/', $targetSchoolYear, $matches)) {
@@ -754,7 +759,7 @@ final class SchoolYearClosingService
try {
$birthDate = new \DateTimeImmutable($dob);
$cutoff = new \DateTimeImmutable($matches[1] . '-12-31');
$cutoff = new \DateTimeImmutable($matches[1] . '-09-01');
} catch (\Throwable) {
return '';
}
@@ -808,11 +813,13 @@ final class SchoolYearClosingService
$decision = trim((string) ($row['decision'] ?? ''));
$source = trim((string) ($row['source'] ?? ''));
$status = $decision === '' || $source === 'pending' ? 'pending' : 'decided';
$normalizedDecision = DeliberationDecision::normalize($decision);
$decisions[$studentId] = [
'class_section_name' => (string) ($row['class_section_name'] ?? ''),
'year_score' => is_numeric($row['year_score'] ?? null) ? round((float) $row['year_score'], 2) : null,
'decision' => $decision,
'normalized_decision' => $normalizedDecision,
'source' => $source !== '' ? $source : ($status === 'pending' ? 'pending' : 'manual'),
'notes' => (string) ($row['notes'] ?? ''),
'status' => $status,