fix close year and ignore not active students
This commit is contained in:
@@ -540,7 +540,7 @@ class AdministratorController extends BaseController
|
||||
|
||||
public function teacherSubmissionsReport()
|
||||
{
|
||||
$semester = (string) (getSemester() ?? $this->semester ?? '');
|
||||
$semester = (string) ($this->semester !== '' ? $this->semester : (getSemester() ?? $this->semester ?? ''));
|
||||
$schoolYear = trim((string) ($this->request->getGet('school_year') ?? ''));
|
||||
if ($schoolYear === '') {
|
||||
$schoolYear = $this->currentSchoolYearName((string) ($this->schoolYear ?? ''));
|
||||
@@ -561,7 +561,7 @@ class AdministratorController extends BaseController
|
||||
{
|
||||
$result = service('teacherSubmissionReport')->sendNotifications(
|
||||
(array) $this->request->getPost(),
|
||||
(string) (getSemester() ?? $this->semester ?? ''),
|
||||
(string) ($this->semester !== '' ? $this->semester : (getSemester() ?? '')),
|
||||
(int) (session()->get('user_id') ?? 0)
|
||||
);
|
||||
|
||||
|
||||
@@ -304,6 +304,12 @@ class ParentController extends BaseController
|
||||
foreach ($students as &$student) {
|
||||
$studentId = $student['id'];
|
||||
$student['age'] = $this->calculateAgeAsOfSchoolYearStartYear($student['dob'] ?? null, $selectedYear);
|
||||
$student['allergies'] = $this->allergyModel
|
||||
->where('student_id', (int) $studentId)
|
||||
->findColumn('allergy') ?? [];
|
||||
$student['medical_conditions'] = $this->medicalConditionModel
|
||||
->where('student_id', (int) $studentId)
|
||||
->findColumn('condition_name') ?? [];
|
||||
|
||||
// Get class section info (can be multiple sections like Grade + Arabic)
|
||||
$classSections = $this->studentClassModel->getClassSectionsByStudentId($studentId, $selectedYear, true);
|
||||
@@ -816,66 +822,38 @@ class ParentController extends BaseController
|
||||
continue;
|
||||
}
|
||||
|
||||
$firstName = $this->normalizeEnrollmentStudentName((string) ($fields['firstname'] ?? ''));
|
||||
$lastName = $this->normalizeEnrollmentStudentName((string) ($fields['lastname'] ?? ''));
|
||||
$dob = trim((string) ($fields['dob'] ?? ''));
|
||||
$gender = trim((string) ($fields['gender'] ?? ''));
|
||||
$registrationGrade = trim((string) ($fields['registration_grade'] ?? ''));
|
||||
$studentLabel = trim((string) ($existing['firstname'] ?? '') . ' ' . (string) ($existing['lastname'] ?? ''))
|
||||
?: 'Student ID ' . $studentId;
|
||||
$photoConsent = (string) ($fields['photo_consent'] ?? '');
|
||||
$studentLabel = trim($firstName . ' ' . $lastName) ?: 'Student ID ' . $studentId;
|
||||
|
||||
try {
|
||||
$this->validateNames($firstName);
|
||||
$this->validateNames($lastName);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
$errors[] = $studentLabel . ': ' . $e->getMessage();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! in_array($gender, ['Male', 'Female'], true)) {
|
||||
$errors[] = $studentLabel . ': gender is required.';
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($photoConsent !== '0' && $photoConsent !== '1') {
|
||||
$errors[] = $studentLabel . ': photo consent is required.';
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($registrationGrade === '' || mb_strlen($registrationGrade) > 50) {
|
||||
$errors[] = $studentLabel . ': registration grade is required.';
|
||||
continue;
|
||||
}
|
||||
|
||||
$dobObj = \DateTimeImmutable::createFromFormat('!Y-m-d', $dob, new \DateTimeZone('UTC'));
|
||||
$dobErrors = \DateTimeImmutable::getLastErrors();
|
||||
$dobWarningCount = is_array($dobErrors) ? (int) ($dobErrors['warning_count'] ?? 0) : 0;
|
||||
$dobErrorCount = is_array($dobErrors) ? (int) ($dobErrors['error_count'] ?? 0) : 0;
|
||||
if ($dobObj === false || $dobWarningCount > 0 || $dobErrorCount > 0) {
|
||||
$errors[] = $studentLabel . ': date of birth must use YYYY-MM-DD format.';
|
||||
continue;
|
||||
}
|
||||
|
||||
$validation = $this->validateDobAge(
|
||||
$dob,
|
||||
$this->registrationMinimumAgeDeadline($schoolYear),
|
||||
5,
|
||||
18,
|
||||
$this->schoolYearAgeDeadline($schoolYear)
|
||||
$medicalConditions = $this->normalizeEnrollmentHealthSelections(
|
||||
$fields['medical_conditions'] ?? [],
|
||||
(string) ($fields['medical_condition_other'] ?? '')
|
||||
);
|
||||
if (! $validation['isValid']) {
|
||||
$errors[] = $studentLabel . ': ' . $validation['message'] . '.';
|
||||
$allergies = $this->normalizeEnrollmentHealthSelections(
|
||||
$fields['allergies'] ?? [],
|
||||
(string) ($fields['allergy_other'] ?? '')
|
||||
);
|
||||
|
||||
if ($medicalConditions === []) {
|
||||
$errors[] = $studentLabel . ': medical conditions are required.';
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($allergies === []) {
|
||||
$errors[] = $studentLabel . ': allergies are required.';
|
||||
continue;
|
||||
}
|
||||
|
||||
$updates[$studentId] = [
|
||||
'firstname' => $firstName,
|
||||
'lastname' => $lastName,
|
||||
'dob' => $dobObj->format('Y-m-d'),
|
||||
'age' => $this->calculateAgeAsOfSchoolYearStartYear($dobObj->format('Y-m-d'), $schoolYear),
|
||||
'gender' => $gender,
|
||||
'registration_grade' => $registrationGrade,
|
||||
'photo_consent' => (int) $photoConsent,
|
||||
'medical_conditions' => $medicalConditions,
|
||||
'allergies' => $allergies,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -884,14 +862,62 @@ class ParentController extends BaseController
|
||||
}
|
||||
|
||||
foreach ($updates as $studentId => $payload) {
|
||||
if (! $this->studentModel->update($studentId, $payload)) {
|
||||
if (! $this->studentModel->update($studentId, ['photo_consent' => $payload['photo_consent']])) {
|
||||
$errors[] = 'Student ID ' . $studentId . ': student information could not be updated.';
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->medicalConditionModel->where('student_id', $studentId)->delete();
|
||||
foreach ($payload['medical_conditions'] as $condition) {
|
||||
$this->medicalConditionModel->insert([
|
||||
'student_id' => $studentId,
|
||||
'condition_name' => $condition,
|
||||
]);
|
||||
}
|
||||
|
||||
$this->allergyModel->where('student_id', $studentId)->delete();
|
||||
foreach ($payload['allergies'] as $allergy) {
|
||||
$this->allergyModel->insert([
|
||||
'student_id' => $studentId,
|
||||
'allergy' => $allergy,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $selected
|
||||
* @return list<string>
|
||||
*/
|
||||
private function normalizeEnrollmentHealthSelections($selected, string $otherText): array
|
||||
{
|
||||
$values = [];
|
||||
foreach ((array) $selected as $value) {
|
||||
$value = trim((string) $value);
|
||||
if ($value === '') {
|
||||
continue;
|
||||
}
|
||||
$values[] = $value;
|
||||
}
|
||||
|
||||
$otherText = trim($otherText);
|
||||
if (in_array('Other', $values, true)) {
|
||||
$values = array_values(array_filter($values, static fn(string $value): bool => $value !== 'Other'));
|
||||
if ($otherText !== '') {
|
||||
$values[] = mb_substr($otherText, 0, 100);
|
||||
}
|
||||
}
|
||||
|
||||
$unique = [];
|
||||
foreach ($values as $value) {
|
||||
$unique[$value] = $value;
|
||||
}
|
||||
|
||||
return array_values($unique);
|
||||
}
|
||||
|
||||
private function normalizeEnrollmentStudentName(string $name): string
|
||||
{
|
||||
$name = trim(preg_replace('/\s+/', ' ', $name) ?? '');
|
||||
|
||||
@@ -587,6 +587,9 @@ final class SchoolYearClosingService
|
||||
|
||||
$hasEventOnly = $this->db->fieldExists('is_event_only', 'student_class');
|
||||
$hasActive = $this->db->fieldExists('is_active', 'students');
|
||||
$hasEnrollments = $this->db->tableExists('enrollments');
|
||||
$hasEnrollmentStatus = $hasEnrollments && $this->db->fieldExists('enrollment_status', 'enrollments');
|
||||
$hasEnrollmentWithdrawn = $hasEnrollments && $this->db->fieldExists('is_withdrawn', 'enrollments');
|
||||
$hasDob = $this->db->fieldExists('dob', 'students');
|
||||
$hasRegistrationGrade = $this->db->fieldExists('registration_grade', 'students');
|
||||
|
||||
@@ -600,6 +603,14 @@ final class SchoolYearClosingService
|
||||
->where('sc.school_year', $schoolYear)
|
||||
->where('sc.class_section_id IS NOT NULL', null, false);
|
||||
|
||||
if ($hasEnrollments && ($hasEnrollmentStatus || $hasEnrollmentWithdrawn)) {
|
||||
$builder->join(
|
||||
'enrollments e',
|
||||
'e.student_id = sc.student_id AND e.school_year = ' . $this->db->escape($schoolYear),
|
||||
'left'
|
||||
);
|
||||
}
|
||||
|
||||
if ($hasDob) {
|
||||
$builder->select('s.dob');
|
||||
}
|
||||
@@ -619,6 +630,19 @@ final class SchoolYearClosingService
|
||||
$builder->where('s.is_active', 1);
|
||||
}
|
||||
|
||||
if ($hasEnrollmentStatus) {
|
||||
$inactiveStatuses = implode(',', array_map([$this->db, 'escape'], EnrollmentStatusService::INACTIVE_STATUSES));
|
||||
$builder->where(
|
||||
'(e.enrollment_status IS NULL OR LOWER(TRIM(e.enrollment_status)) NOT IN (' . $inactiveStatuses . '))',
|
||||
null,
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
if ($hasEnrollmentWithdrawn) {
|
||||
$builder->where('(e.is_withdrawn IS NULL OR e.is_withdrawn != 1)', null, false);
|
||||
}
|
||||
|
||||
$assignmentRows = $builder
|
||||
->orderBy('sc.student_id', 'ASC')
|
||||
->orderBy('sc.updated_at', 'DESC')
|
||||
|
||||
@@ -345,7 +345,70 @@ foreach (($students ?? []) as $student) {
|
||||
|
||||
<div data-step-panel="0">
|
||||
<h6 class="fw-semibold">Review student information</h6>
|
||||
<div class="text-muted small mb-3">Select each student you want to enroll for <?= esc($selectedYear ?? 'the selected school year') ?> and update their information if needed.</div>
|
||||
<div class="text-muted small mb-3">Select each student you want to enroll for <?= esc($selectedYear ?? 'the selected school year') ?>. Photo consent, medical conditions, and allergies can be updated below.</div>
|
||||
<?php
|
||||
$enrollmentMedicalOptions = [
|
||||
'None',
|
||||
'ADHD (Attention-Deficit/Hyperactivity Disorder)',
|
||||
'Anxiety or Emotional Disorders',
|
||||
'Asthma',
|
||||
'Autism Spectrum Disorder (ASD)',
|
||||
'Behavioral or Conduct Disorders',
|
||||
'Blindness / Vision Impairment',
|
||||
'Celiac Disease (Gluten Intolerance)',
|
||||
'Cerebral Palsy',
|
||||
'Cystic Fibrosis',
|
||||
'Depression',
|
||||
'Diabetes (Type 1 or Type 2)',
|
||||
'Down Syndrome',
|
||||
'Dyslexia or Learning Disabilities',
|
||||
'Eating Disorders',
|
||||
'Eczema / Severe Skin Conditions',
|
||||
'Epilepsy / Seizure Disorders',
|
||||
'Hearing Impairments / Deafness',
|
||||
'Heart Conditions (congenital or acquired)',
|
||||
'Hemophilia / Bleeding Disorders',
|
||||
'Kidney Disease',
|
||||
'Migraines / Chronic Headaches',
|
||||
'Obsessive-Compulsive Disorder (OCD)',
|
||||
'Physical Disabilities / Mobility Impairments',
|
||||
'PTSD (Post-Traumatic Stress Disorder)',
|
||||
'Sickle Cell Anemia',
|
||||
'Speech and Language Disorders',
|
||||
'Thyroid Disorders',
|
||||
'Tourette Syndrome',
|
||||
'Traumatic Brain Injury (TBI)',
|
||||
'Rheumatic diseases',
|
||||
'Ulcerative Colitis / Crohn’s Disease',
|
||||
'Other',
|
||||
];
|
||||
$enrollmentAllergyOptions = [
|
||||
'None',
|
||||
'Animal Dander (cats, dogs, etc.)',
|
||||
'Antibiotics',
|
||||
'Bee stings',
|
||||
'Cockroach',
|
||||
'Corn',
|
||||
'Dust Mites',
|
||||
'Egg',
|
||||
'Fire ant stings',
|
||||
'Fish',
|
||||
'Fragrances / Perfumes',
|
||||
'Latex',
|
||||
'Milk / Dairy',
|
||||
'Mold',
|
||||
'Mosquito bites',
|
||||
'Peanut',
|
||||
'Pollen (grass, tree, weed)',
|
||||
'Sesame',
|
||||
'Shellfish (shrimp, crab, lobster, etc.)',
|
||||
'Soy',
|
||||
'Tree Nuts (almond, cashew, walnut, etc.)',
|
||||
'Wasp stings',
|
||||
'Wheat / Gluten',
|
||||
'Other',
|
||||
];
|
||||
?>
|
||||
<div class="d-grid gap-2">
|
||||
<?php foreach ($students as $student): ?>
|
||||
<?php
|
||||
@@ -360,6 +423,25 @@ foreach (($students ?? []) as $student) {
|
||||
$gradeLabel = $section
|
||||
? preg_replace_callback('/\byouth\b/i', fn($m) => ucfirst(strtolower($m[0])), (string) $section)
|
||||
: 'Not Assigned';
|
||||
$medicalSelected = is_array($student['medical_conditions'] ?? null)
|
||||
? array_values(array_filter(array_map('trim', $student['medical_conditions'])))
|
||||
: array_values(array_filter(array_map('trim', preg_split('/[,\n;]+/', (string) ($student['medical_conditions'] ?? ''), -1, PREG_SPLIT_NO_EMPTY) ?: [])));
|
||||
$allergySelected = is_array($student['allergies'] ?? null)
|
||||
? array_values(array_filter(array_map('trim', $student['allergies'])))
|
||||
: array_values(array_filter(array_map('trim', preg_split('/[,\n;]+/', (string) ($student['allergies'] ?? ''), -1, PREG_SPLIT_NO_EMPTY) ?: [])));
|
||||
$medicalOther = implode(', ', array_diff($medicalSelected, $enrollmentMedicalOptions));
|
||||
$allergyOther = implode(', ', array_diff($allergySelected, $enrollmentAllergyOptions));
|
||||
if ($medicalOther !== '') {
|
||||
$medicalSelected[] = 'Other';
|
||||
}
|
||||
if ($allergyOther !== '') {
|
||||
$allergySelected[] = 'Other';
|
||||
}
|
||||
$dobDisplay = !empty($student['dob']) ? local_date($student['dob'], 'm-d-Y') : 'N/A';
|
||||
$photoConsentValue = (string) ($student['photo_consent'] ?? '');
|
||||
if ($photoConsentValue !== '0' && $photoConsentValue !== '1') {
|
||||
$photoConsentValue = !empty($student['photo_consent']) ? '1' : '';
|
||||
}
|
||||
?>
|
||||
<div class="student-select-card <?= $canEnroll ? '' : 'is-disabled' ?>"
|
||||
data-student-card
|
||||
@@ -376,56 +458,65 @@ foreach (($students ?? []) as $student) {
|
||||
<div class="fw-semibold"><?= esc($studentName) ?></div>
|
||||
<?= $statusBadge($student['enrollment_status'] ?? '') ?>
|
||||
</div>
|
||||
<div class="small text-muted">Current grade: <?= esc($gradeLabel) ?> · School ID: <?= esc($student['school_id'] ?? 'N/A') ?></div>
|
||||
|
||||
<div class="small text-muted mt-1">
|
||||
<div>School ID: <?= esc($student['school_id'] ?? 'N/A') ?></div>
|
||||
<div>Date of birth: <?= esc($dobDisplay) ?><?php if (isset($student['age'])): ?> · Age: <?= esc($student['age']) ?><?php endif; ?></div>
|
||||
<div>Gender: <?= esc($student['gender'] ?? 'N/A') ?></div>
|
||||
<div>Registration grade: <?= esc($student['registration_grade'] ?? 'N/A') ?></div>
|
||||
<div>Current grade: <?= esc($gradeLabel) ?></div>
|
||||
<div>Expected placement: <?= esc($student['expected_placement_label'] ?? $gradeLabel) ?></div>
|
||||
<div>Required action: <?= esc($student['required_action_label'] ?? 'Contact administration') ?></div>
|
||||
</div>
|
||||
|
||||
<?php if ($canEnroll): ?>
|
||||
<div class="row g-2 mt-2" data-student-edit-fields>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small fw-semibold" for="student-firstname-<?= esc($student['id']) ?>">First name</label>
|
||||
<input class="form-control form-control-sm" type="text" id="student-firstname-<?= esc($student['id']) ?>" name="student_info[<?= esc($student['id']) ?>][firstname]" value="<?= esc($student['firstname'] ?? '') ?>" required maxlength="30" disabled data-student-edit-input>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small fw-semibold" for="student-lastname-<?= esc($student['id']) ?>">Last name</label>
|
||||
<input class="form-control form-control-sm" type="text" id="student-lastname-<?= esc($student['id']) ?>" name="student_info[<?= esc($student['id']) ?>][lastname]" value="<?= esc($student['lastname'] ?? '') ?>" required maxlength="30" disabled data-student-edit-input>
|
||||
<input type="hidden" name="student_info[<?= esc($student['id']) ?>][firstname]" value="<?= esc($student['firstname'] ?? '') ?>">
|
||||
<input type="hidden" name="student_info[<?= esc($student['id']) ?>][lastname]" value="<?= esc($student['lastname'] ?? '') ?>">
|
||||
<input type="hidden" name="student_info[<?= esc($student['id']) ?>][dob]" value="<?= esc($student['dob'] ?? '') ?>">
|
||||
<input type="hidden" name="student_info[<?= esc($student['id']) ?>][gender]" value="<?= esc($student['gender'] ?? '') ?>">
|
||||
<input type="hidden" name="student_info[<?= esc($student['id']) ?>][registration_grade]" value="<?= esc($student['registration_grade'] ?? '') ?>">
|
||||
|
||||
<div class="row g-2 mt-3" data-student-edit-fields>
|
||||
<div class="col-12">
|
||||
<div class="fw-semibold small mb-1">Editable health information</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small fw-semibold" for="student-dob-<?= esc($student['id']) ?>">Date of birth</label>
|
||||
<input class="form-control form-control-sm" type="date" id="student-dob-<?= esc($student['id']) ?>" name="student_info[<?= esc($student['id']) ?>][dob]" value="<?= esc($student['dob'] ?? '') ?>" required disabled data-student-edit-input>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small fw-semibold" for="student-gender-<?= esc($student['id']) ?>">Gender</label>
|
||||
<select class="form-select form-select-sm" id="student-gender-<?= esc($student['id']) ?>" name="student_info[<?= esc($student['id']) ?>][gender]" required disabled data-student-edit-input>
|
||||
<option value="">Select</option>
|
||||
<option value="Male" <?= ($student['gender'] ?? '') === 'Male' ? 'selected' : '' ?>>Male</option>
|
||||
<option value="Female" <?= ($student['gender'] ?? '') === 'Female' ? 'selected' : '' ?>>Female</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small fw-semibold" for="student-grade-<?= esc($student['id']) ?>">Registration grade</label>
|
||||
<input class="form-control form-control-sm" type="text" id="student-grade-<?= esc($student['id']) ?>" name="student_info[<?= esc($student['id']) ?>][registration_grade]" value="<?= esc($student['registration_grade'] ?? '') ?>" required maxlength="50" disabled data-student-edit-input>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small fw-semibold" for="student-photo-consent-<?= esc($student['id']) ?>">Photo consent</label>
|
||||
<select class="form-select form-select-sm" id="student-photo-consent-<?= esc($student['id']) ?>" name="student_info[<?= esc($student['id']) ?>][photo_consent]" required disabled data-student-edit-input>
|
||||
<option value="">Select</option>
|
||||
<option value="1" <?= (string) ($student['photo_consent'] ?? '') === '1' ? 'selected' : '' ?>>Yes</option>
|
||||
<option value="0" <?= (string) ($student['photo_consent'] ?? '') === '0' ? 'selected' : '' ?>>No</option>
|
||||
<option value="1" <?= $photoConsentValue === '1' ? 'selected' : '' ?>>Yes</option>
|
||||
<option value="0" <?= $photoConsentValue === '0' ? 'selected' : '' ?>>No</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label small fw-semibold">Expected placement</label>
|
||||
<div class="form-control form-control-sm bg-light"><?= esc($student['expected_placement_label'] ?? $gradeLabel) ?></div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small fw-semibold">Medical conditions</label>
|
||||
<div class="border rounded p-2 bg-white small" style="max-height: 180px; overflow-y: auto;" data-health-group="medical_conditions">
|
||||
<?php foreach ($enrollmentMedicalOptions as $opt): ?>
|
||||
<?php $optId = 'student-medical-' . $student['id'] . '-' . md5($opt); ?>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="<?= esc($optId) ?>" name="student_info[<?= esc($student['id']) ?>][medical_conditions][]" value="<?= esc($opt) ?>" <?= in_array($opt, $medicalSelected, true) ? 'checked' : '' ?> disabled data-student-edit-input data-health-option="<?= $opt === 'Other' ? 'other' : ($opt === 'None' ? 'none' : 'item') ?>">
|
||||
<label class="form-check-label" for="<?= esc($optId) ?>"><?= esc($opt) ?></label>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<input type="text" class="form-control form-control-sm mt-2 <?= $medicalOther === '' ? 'd-none' : '' ?>" name="student_info[<?= esc($student['id']) ?>][medical_condition_other]" value="<?= esc($medicalOther) ?>" placeholder="Please specify if Other is selected" disabled data-student-edit-input data-other-input="medical_conditions" maxlength="100">
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label small fw-semibold">Allergies</label>
|
||||
<div class="border rounded p-2 bg-white small" style="max-height: 180px; overflow-y: auto;" data-health-group="allergies">
|
||||
<?php foreach ($enrollmentAllergyOptions as $opt): ?>
|
||||
<?php $optId = 'student-allergy-' . $student['id'] . '-' . md5($opt); ?>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="<?= esc($optId) ?>" name="student_info[<?= esc($student['id']) ?>][allergies][]" value="<?= esc($opt) ?>" <?= in_array($opt, $allergySelected, true) ? 'checked' : '' ?> disabled data-student-edit-input data-health-option="<?= $opt === 'Other' ? 'other' : ($opt === 'None' ? 'none' : 'item') ?>">
|
||||
<label class="form-check-label" for="<?= esc($optId) ?>"><?= esc($opt) ?></label>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<input type="text" class="form-control form-control-sm mt-2 <?= $allergyOther === '' ? 'd-none' : '' ?>" name="student_info[<?= esc($student['id']) ?>][allergy_other]" value="<?= esc($allergyOther) ?>" placeholder="Please specify if Other is selected" disabled data-student-edit-input data-other-input="allergies" maxlength="100">
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="small text-muted">
|
||||
Date of birth: <?= esc(!empty($student['dob']) ? local_date($student['dob'], 'm-d-Y') : 'N/A') ?>
|
||||
<?php if (isset($student['age'])): ?>
|
||||
· Age: <?= esc($student['age']) ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="small text-muted">Expected placement: <?= esc($student['expected_placement_label'] ?? $gradeLabel) ?></div>
|
||||
<?php endif; ?>
|
||||
<div class="small">Required action: <?= esc($student['required_action_label'] ?? 'Contact administration') ?></div>
|
||||
|
||||
<?php if (($eligibilityMessage['message'] ?? '') !== ''): ?>
|
||||
<div class="alert alert-<?= esc($eligibilityMessage['level'] ?? 'info') ?> py-2 px-3 mt-2 mb-0 small">
|
||||
<?= esc($eligibilityMessage['message']) ?>
|
||||
@@ -462,9 +553,6 @@ foreach (($students ?? []) as $student) {
|
||||
<div class="col-md-4"><span class="text-muted">Previous-year carry-over balance:</span> <strong data-financial-value="carry_over_balance"><?= esc($money($familyFinancialSummary['carry_over_balance'] ?? 0)) ?></strong></div>
|
||||
<div class="col-md-4"><span class="text-muted">Total currently due:</span> <strong data-financial-value="amount_due"><?= esc($money($familyFinancialSummary['amount_due'] ?? 0)) ?></strong></div>
|
||||
</div>
|
||||
<?php if (!empty($familyFinancialSummary['policy_message'])): ?>
|
||||
<div class="small text-muted mt-2"><?= esc($familyFinancialSummary['policy_message']) ?></div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="alert alert-warning mb-0">Family account information is not available. Please contact the administration if you have questions about tuition or balance.</div>
|
||||
@@ -476,7 +564,7 @@ foreach (($students ?? []) as $student) {
|
||||
<div class="text-muted small mb-3">Review the enrollment summary before submitting.</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="fw-semibold mb-2">Fees by student</div>
|
||||
<div class="fw-semibold mb-2">Summary</div>
|
||||
<div id="enrollmentFeeReviewList" class="d-grid gap-2"></div>
|
||||
</div>
|
||||
|
||||
@@ -509,11 +597,8 @@ foreach (($students ?? []) as $student) {
|
||||
<div class="alert alert-warning mb-0 small">
|
||||
<div class="fw-semibold mb-1">Important information</div>
|
||||
<ul class="mb-0 ps-3">
|
||||
<li>Submitting sends the selected enrollment(s) to admission review.</li>
|
||||
<li>For newly registered students, enrollment status changes to admission under review after submitting the request.</li>
|
||||
<li>Payments are processed on the first day of school.</li>
|
||||
<?php if (!empty($familyFinancialSummary['policy_message'])): ?>
|
||||
<li><?= esc($familyFinancialSummary['policy_message']) ?></li>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($fallMakeupExamOn)): ?>
|
||||
<li>Students with a make-up exam decision may initially remain in the same grade until the make-up exam result is confirmed.</li>
|
||||
<?php endif; ?>
|
||||
@@ -721,8 +806,118 @@ foreach (($students ?? []) as $student) {
|
||||
card.querySelectorAll('[data-student-edit-input]').forEach(field => {
|
||||
field.disabled = !enabled;
|
||||
});
|
||||
syncHealthGroup(card, 'medical_conditions');
|
||||
syncHealthGroup(card, 'allergies');
|
||||
}
|
||||
|
||||
function syncHealthGroup(card, groupName) {
|
||||
const selected = !!card.querySelector('[data-enroll-input]')?.checked;
|
||||
const group = card.querySelector('[data-health-group="' + groupName + '"]');
|
||||
const otherInput = card.querySelector('[data-other-input="' + groupName + '"]');
|
||||
if (!group) {
|
||||
return;
|
||||
}
|
||||
|
||||
const noneChecked = !!group.querySelector('[data-health-option="none"]:checked');
|
||||
const otherChecked = !!group.querySelector('[data-health-option="other"]:checked');
|
||||
|
||||
group.querySelectorAll('input[type="checkbox"]').forEach(input => {
|
||||
if (!selected) {
|
||||
input.disabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (input.dataset.healthOption === 'none') {
|
||||
input.disabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (noneChecked) {
|
||||
input.checked = false;
|
||||
input.disabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
input.disabled = false;
|
||||
});
|
||||
|
||||
if (otherInput) {
|
||||
otherInput.classList.toggle('d-none', !otherChecked);
|
||||
otherInput.disabled = !selected || !otherChecked;
|
||||
if (!otherChecked) {
|
||||
otherInput.value = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function validateSelectedStudentHealth() {
|
||||
for (const input of selectedEnrollInputs()) {
|
||||
const card = input.closest('[data-student-card]');
|
||||
if (!card) {
|
||||
continue;
|
||||
}
|
||||
const name = card.querySelector('.fw-semibold')?.textContent?.trim() || 'Student';
|
||||
const photo = card.querySelector("select[name$='[photo_consent]']");
|
||||
if (!photo || photo.value === '') {
|
||||
alert('Please select photo consent for ' + name + '.');
|
||||
return false;
|
||||
}
|
||||
|
||||
const medicalChecked = card.querySelectorAll('[data-health-group="medical_conditions"] input[type="checkbox"]:checked');
|
||||
if (!medicalChecked.length) {
|
||||
alert('Please select medical conditions for ' + name + '.');
|
||||
return false;
|
||||
}
|
||||
const medicalOther = card.querySelector('[data-other-input="medical_conditions"]');
|
||||
if (card.querySelector('[data-health-group="medical_conditions"] [data-health-option="other"]:checked') && (!medicalOther || !medicalOther.value.trim())) {
|
||||
alert('Please specify the other medical condition for ' + name + '.');
|
||||
return false;
|
||||
}
|
||||
|
||||
const allergyChecked = card.querySelectorAll('[data-health-group="allergies"] input[type="checkbox"]:checked');
|
||||
if (!allergyChecked.length) {
|
||||
alert('Please select allergies for ' + name + '.');
|
||||
return false;
|
||||
}
|
||||
const allergyOther = card.querySelector('[data-other-input="allergies"]');
|
||||
if (card.querySelector('[data-health-group="allergies"] [data-health-option="other"]:checked') && (!allergyOther || !allergyOther.value.trim())) {
|
||||
alert('Please specify the other allergy for ' + name + '.');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
document.querySelectorAll('[data-student-card]').forEach(card => {
|
||||
card.querySelectorAll('[data-health-group]').forEach(group => {
|
||||
group.addEventListener('change', function(event) {
|
||||
const target = event.target;
|
||||
if (!(target instanceof HTMLInputElement) || target.type !== 'checkbox') {
|
||||
return;
|
||||
}
|
||||
const groupName = group.getAttribute('data-health-group');
|
||||
if (!groupName) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (target.dataset.healthOption === 'none' && target.checked) {
|
||||
group.querySelectorAll('[data-health-option="item"], [data-health-option="other"]').forEach(input => {
|
||||
input.checked = false;
|
||||
});
|
||||
}
|
||||
|
||||
if ((target.dataset.healthOption === 'item' || target.dataset.healthOption === 'other') && target.checked) {
|
||||
const noneInput = group.querySelector('[data-health-option="none"]');
|
||||
if (noneInput) {
|
||||
noneInput.checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
syncHealthGroup(card, groupName);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
if (startButton && flowModal) {
|
||||
startButton.addEventListener('click', function() {
|
||||
if (deadlinePassed) {
|
||||
@@ -768,6 +963,9 @@ foreach (($students ?? []) as $student) {
|
||||
alert('Please select at least one student to enroll.');
|
||||
return;
|
||||
}
|
||||
if (currentStep === 0 && !validateSelectedStudentHealth()) {
|
||||
return;
|
||||
}
|
||||
if (currentStep === 1) {
|
||||
syncPolicyAccepted();
|
||||
if (!hasAcceptedSchoolPolicy) {
|
||||
|
||||
Reference in New Issue
Block a user