fix closing year
Tests / PHPUnit (push) Successful in 1m20s

This commit is contained in:
root
2026-08-10 01:11:16 -04:00
parent 1ef2800f12
commit c12bb59372
5 changed files with 416 additions and 126 deletions
+89 -1
View File
@@ -31,6 +31,7 @@ use App\Models\GradingLockModel;
use App\Models\BelowSixtyDecisionModel;
use App\Models\StudentDecisionModel;
use App\Services\NavbarService;
use App\Support\Enrollment\DeliberationDecision;
//use App\Models\ScoreModel;
@@ -3399,13 +3400,16 @@ public function allDecisions()
's.firstname',
's.lastname',
's.gender',
's.dob',
'ss.class_section_id',
'cs.class_section_name',
'c.class_name',
'LOWER(TRIM(ss.semester)) AS sem_key',
'ss.semester_score',
])
->join('students s', 's.id = ss.student_id', 'inner')
->join('classSection cs', 'cs.class_section_id = ss.class_section_id', 'left')
->join('classes c', 'c.id = cs.class_id', 'left')
->where('s.is_active', 1)
->where('ss.school_year', $schoolYear)
->whereIn('LOWER(TRIM(ss.semester))', ['fall', 'spring'])
@@ -3432,7 +3436,9 @@ public function allDecisions()
'firstname' => $sr['firstname'] ?? '',
'lastname' => $sr['lastname'] ?? '',
'gender' => $sr['gender'] ?? '',
'dob' => $sr['dob'] ?? '',
'class_section_id' => (int)($sr['class_section_id'] ?? 0),
'class_name' => $sr['class_name'] ?? '',
'class_section_name' => $sr['class_section_name'] ?? '',
'fall_score' => null,
'spring_score' => null,
@@ -3513,18 +3519,30 @@ public function allDecisions()
$notes = '';
}
$currentClassSectionName = trim((string)($info['class_section_name'] ?? ''));
if ($currentClassSectionName === '' && isset($savedMap[$sid])) {
$currentClassSectionName = trim((string)($savedMap[$sid]['class_section_name'] ?? ''));
}
$currentClassName = trim((string)($info['class_name'] ?? ''));
if ($currentClassName === '') {
$currentClassName = $this->classOnlyLabel($currentClassSectionName);
}
$rows[] = [
'student_id' => $sid,
'school_id' => $info['school_id'],
'firstname' => $info['firstname'],
'lastname' => $info['lastname'],
'gender' => $info['gender'] ?? '',
'dob' => $info['dob'] ?? '',
'class_section_id' => (int)($info['class_section_id'] ?? 0),
'class_section_name' => $info['class_section_name'],
'class_name' => $currentClassName,
'class_section_name' => $currentClassSectionName,
'fall_score' => $fall,
'spring_score' => $spring,
'year_score' => $yearScore,
'decision' => $decision,
'next_year_placement' => $this->nextYearPlacementLabel($decision, $currentClassName, $currentClassSectionName, (string)($info['dob'] ?? ''), $schoolYear),
'source' => $source,
'notes' => $notes,
'saved' => isset($savedMap[$sid]),
@@ -3741,6 +3759,76 @@ public function generateAllDecisions()
->with('status', "Decisions generated for {$savedCount} students.");
}
private function nextYearPlacementLabel(
?string $decision,
string $currentClassName,
string $currentClassSectionName,
string $dob,
string $schoolYear
): string
{
$normalizedDecision = DeliberationDecision::normalize($decision);
$classLabel = $this->classOnlyLabel($currentClassName !== '' ? $currentClassName : $currentClassSectionName);
if ($this->isKgClass($classLabel)) {
$kgPlacement = $this->kgPlacementByComingSeptember($dob, $schoolYear);
if ($kgPlacement !== '') {
return $kgPlacement;
}
}
if ($normalizedDecision === DeliberationDecision::REPEAT_CLASS) {
return $classLabel;
}
return '';
}
private function classOnlyLabel(string $className): string
{
return trim((string) preg_replace('/-.+$/', '', $className));
}
private function isKgClass(string $className): bool
{
$value = strtoupper(trim($className));
return preg_match('/(^|[^A-Z0-9])KG([^A-Z0-9]|$)/', $value) === 1 || str_contains($value, 'KINDERGARTEN');
}
private function kgPlacementByComingSeptember(string $dob, string $schoolYear): string
{
$dob = trim($dob);
if ($dob === '') {
return '';
}
try {
$birthDate = new \DateTimeImmutable($dob);
$cutoff = $this->comingSeptemberFirstCutoff($schoolYear);
} catch (\Throwable) {
return '';
}
if ($birthDate > $cutoff) {
return '';
}
return $birthDate->diff($cutoff)->y >= 6 ? '1' : 'KG';
}
private function comingSeptemberFirstCutoff(string $schoolYear): \DateTimeImmutable
{
if (preg_match('/^(\d{4})-\d{4}$/', $schoolYear, $matches) === 1) {
return new \DateTimeImmutable(((int) $matches[1] + 1) . '-09-01');
}
$today = new \DateTimeImmutable('today');
$cutoff = new \DateTimeImmutable($today->format('Y') . '-09-01');
return $today <= $cutoff ? $cutoff : $cutoff->modify('+1 year');
}
private function calculateTrophyThreshold(array $scores, float $percentile = 75.0): array
{
$scores = array_values(array_filter(