extend('layout/management_layout') ?> section('content') ?> [], 'rows' => []]; $promotionSummary = $promotion['summary'] ?? []; $promotionRows = $promotion['rows'] ?? []; $promotionTotal = count($promotionRows); $blockers = $preview['blockers'] ?? []; $warnings = $preview['warnings'] ?? []; $carryForward = $preview['carry_forward'] ?? []; $status = (string) ($source['status'] ?? ''); $batchStatus = (string) ($latestBatch['status'] ?? ''); $missingCarryForwardInvoices = (int) ($missingCarryForwardInvoices ?? 0); $money = static fn ($value): string => '$' . number_format((float) $value, 2); $score = static fn ($value): string => is_numeric($value) ? number_format((float) $value, 2) : '-'; $ageBySchoolYearSecondSeptember = static function (array $row) use ($source): string { $dob = trim((string) ($row['dob'] ?? '')); $schoolYear = (string) ($source['name'] ?? ''); if ($dob === '' || preg_match('/^\d{4}-(\d{4})$/', $schoolYear, $matches) !== 1) { return ''; } try { $birthDate = new DateTimeImmutable($dob); $cutoff = new DateTimeImmutable($matches[1] . '-09-01'); } catch (Throwable) { return ''; } if ($birthDate > $cutoff) { return ''; } return (string) $birthDate->diff($cutoff)->y; }; $kgPlacementFallback = static function (array $row) use ($target): string { $classText = strtoupper(trim( (string) ($row['class_name'] ?? '') . ' ' . (string) ($row['class_section_name'] ?? '') )); if (preg_match('/(^|[^A-Z0-9])KG([^A-Z0-9]|$)/', $classText) !== 1 && ! str_contains($classText, 'KINDERGARTEN')) { return ''; } $dob = trim((string) ($row['dob'] ?? '')); if ($dob === '') { return ''; } try { $targetName = (string) ($target['name'] ?? ''); if (preg_match('/^(\d{4})-\d{4}$/', $targetName, $matches) === 1) { $cutoff = new DateTimeImmutable($matches[1] . '-09-01'); } else { $today = new DateTimeImmutable('today'); $cutoff = new DateTimeImmutable($today->format('Y') . '-09-01'); if ($today > $cutoff) { $cutoff = $cutoff->modify('+1 year'); } } $birthDate = new DateTimeImmutable($dob); } catch (Throwable) { return ''; } if ($birthDate > $cutoff) { return ''; } return $birthDate->diff($cutoff)->y >= 6 ? '1' : 'KG'; }; ?> getFlashdata('success')): ?>
getFlashdata('success')) ?>
getFlashdata('error')): ?>
getFlashdata('error')) ?>

End-Year Checklist:

Status: Next year: Generated:
Back to School Years
How to End This Year
  1. Clear all blocking issues below.
  2. Start the end-year process to lock the checklist.
  3. Confirm carry-forward balances, then mark this school year closed.
Students
Families
Invoices
Outstanding
Blocking Issues

No blocking issues found.

  • :
Warnings

No warnings found.

  • :
Finance Summary
Total invoiced
Total paid
Positive balances
Credits
End-Year Progress
  1. Checklist generated
  2. Validation
  3. End-year process
  4. Carry-forward completed
  5. Year closed
Student Promotion Preview
Promotion decisions must be generated and resolved before this school year can end.
Manage Promotion Decisions
Students
Decided
Pass
Pending
Other
Student School ID Class Age Sep 1 Year Score Decision Source Next Year Placement Status
Carry-Forward Families
Family Parent Source Balance Credits Adjustments Net Carry-Forward
Create or select the next school year first. Resolve the blocking issues above first.
endSection() ?> section('scripts') ?> endSection() ?>