fix is_new issue with enrollment fixes
This commit is contained in:
@@ -83,7 +83,8 @@ class ParentController extends BaseController
|
||||
|
||||
$this->ageDateRefernce = $this->configModel->getConfig('date_age_reference');
|
||||
$this->lastDayOfRegistration = $this->configModel->getConfig('enrollment_deadline');
|
||||
$this->schoolStartDate = $this->configModel->getConfig('fall_semester_start');
|
||||
$this->schoolStartDate = $this->configModel->getConfig('first_day_of_school')
|
||||
?: $this->configModel->getConfig('fall_semester_start');
|
||||
$this->withdrawalDeadline = $this->configModel->getConfig('refund_deadline');
|
||||
$this->schoolYear = $this->configModel->getConfig('school_year');
|
||||
$this->semester = getSemester();
|
||||
@@ -263,7 +264,7 @@ class ParentController extends BaseController
|
||||
|
||||
// Verify user type is "parent" from the `users` table
|
||||
$userData = $this->db->table('users')
|
||||
->select('user_type, accept_school_policy')
|
||||
->select('user_type, accept_school_policy, firstname, lastname, cellphone, address_street, apt, city, state, zip')
|
||||
->where('id', $parentId)
|
||||
->get()
|
||||
->getRowArray();
|
||||
@@ -385,6 +386,30 @@ class ParentController extends BaseController
|
||||
$student['parent_enrollment_state'] = $this->parentEnrollmentState($student);
|
||||
}
|
||||
}
|
||||
unset($student);
|
||||
|
||||
service('studentYearStatus')->attachToStudents($students, $selectedYear);
|
||||
foreach ($students as &$student) {
|
||||
$studentId = (int) ($student['id'] ?? 0);
|
||||
if ($studentId > 0 && $this->isReturningReEnrollmentStudent($studentId, $selectedYear)) {
|
||||
$student['is_new'] = 0;
|
||||
}
|
||||
}
|
||||
unset($student);
|
||||
|
||||
$enrollmentStartStep = (int) $this->request->getGet('start');
|
||||
if ($enrollmentStartStep < 1 || $enrollmentStartStep > 5) {
|
||||
$enrollmentStartStep = 0;
|
||||
}
|
||||
|
||||
$preselectedStudentIds = [];
|
||||
$studentsParam = trim((string) $this->request->getGet('students'));
|
||||
if ($studentsParam !== '') {
|
||||
$preselectedStudentIds = array_values(array_unique(array_filter(
|
||||
array_map('intval', explode(',', $studentsParam)),
|
||||
static fn (int $id): bool => $id > 0
|
||||
)));
|
||||
}
|
||||
|
||||
// Render view
|
||||
return view('/parent/enroll_classes', [
|
||||
@@ -399,6 +424,9 @@ class ParentController extends BaseController
|
||||
'hasAcceptedSchoolPolicy' => $this->hasAcceptedPolicyForYear((int) $parentId, $selectedYear),
|
||||
'familyFinancialSummary' => $this->familyFinancialSummary((int) $parentId, $previousSchoolYear, $selectedYear, $students),
|
||||
'enrollmentFeeSchedule' => $this->enrollmentFeeSchedule($selectedYear),
|
||||
'parentContact' => $this->parentContactForEnrollment($userData),
|
||||
'enrollmentStartStep' => $enrollmentStartStep,
|
||||
'preselectedStudentIds' => $preselectedStudentIds,
|
||||
]);
|
||||
} catch (Exception $e) {
|
||||
log_message('error', 'An error occurred in enrollClasses: ' . $e->getMessage());
|
||||
@@ -452,6 +480,7 @@ class ParentController extends BaseController
|
||||
|
||||
// Handle enrollments
|
||||
$studentData = [];
|
||||
$enrollmentResultMessages = [];
|
||||
|
||||
if (!empty($enroll)) {
|
||||
$selectedYear = $this->currentSchoolYearName((string) ($this->schoolYear ?? ''));
|
||||
@@ -476,6 +505,11 @@ class ParentController extends BaseController
|
||||
return redirect()->back()->withInput()->with('error', implode(' ', $studentInfoErrors));
|
||||
}
|
||||
|
||||
$parentContactErrors = $this->updateEnrollmentParentContact((int) $parentId);
|
||||
if ($parentContactErrors !== []) {
|
||||
return redirect()->back()->withInput()->with('error', implode(' ', $parentContactErrors));
|
||||
}
|
||||
|
||||
foreach ($submittedStudentIds as $studentId) {
|
||||
try {
|
||||
$evaluation = $transitionService->evaluateForParent((int) $parentId, $studentId, $previousSchoolYear, $selectedYear, 'parent');
|
||||
@@ -539,12 +573,13 @@ class ParentController extends BaseController
|
||||
|
||||
$studentName = trim((string) ($studentData[$studentId]['firstname'] ?? '') . ' ' . (string) ($studentData[$studentId]['lastname'] ?? '')) ?: 'Student ID ' . $studentId;
|
||||
$isReturningReEnrollment = $this->isReturningReEnrollmentStudent((int)$studentId, $selectedYear);
|
||||
$submittedEnrollmentContexts[$studentId] = $isReturningReEnrollment ? 're_enrollment' : 'first_enrollment';
|
||||
$isNewForSelectedYear = ! $isReturningReEnrollment
|
||||
&& service('studentYearStatus')->isNew($studentId, $selectedYear);
|
||||
$submittedEnrollmentContexts[$studentId] = $isNewForSelectedYear ? 'first_enrollment' : 're_enrollment';
|
||||
$targetEnrollmentStatus = $isNewForSelectedYear ? 'admission under review' : 'payment pending';
|
||||
$targetAdmissionStatus = $isNewForSelectedYear ? 'pending' : 'accepted';
|
||||
|
||||
if ($existingEnrollment) {
|
||||
$targetEnrollmentStatus = $isReturningReEnrollment ? 'payment pending' : 'admission under review';
|
||||
$targetAdmissionStatus = $isReturningReEnrollment ? 'accepted' : 'pending';
|
||||
|
||||
$update = $this->enrollmentPayloadFromEvaluation($evaluation, [
|
||||
'is_withdrawn' => 0,
|
||||
'withdrawal_date' => null,
|
||||
@@ -595,10 +630,8 @@ class ParentController extends BaseController
|
||||
$this->enrollmentAuditPayload($update, $evaluation),
|
||||
implode(' ', array_map('strval', $evaluation['rule_codes'] ?? []))
|
||||
);
|
||||
$enrollmentResultMessages[] = $studentName . ': ' . $targetEnrollmentStatus;
|
||||
} else {
|
||||
$targetEnrollmentStatus = $isReturningReEnrollment ? 'payment pending' : 'admission under review';
|
||||
$targetAdmissionStatus = $isReturningReEnrollment ? 'accepted' : 'pending';
|
||||
|
||||
// If no enrollment record exists, insert a new enrollment record
|
||||
$payload = $this->enrollmentPayloadFromEvaluation($evaluation, [
|
||||
'student_id' => $studentId,
|
||||
@@ -636,6 +669,7 @@ class ParentController extends BaseController
|
||||
$this->enrollmentAuditPayload($payload, $evaluation),
|
||||
implode(' ', array_map('strval', $evaluation['rule_codes'] ?? []))
|
||||
);
|
||||
$enrollmentResultMessages[] = $studentName . ': ' . $targetEnrollmentStatus;
|
||||
}
|
||||
}
|
||||
$this->db->transComplete();
|
||||
@@ -649,8 +683,11 @@ class ParentController extends BaseController
|
||||
// $studentData now holds info for all students processed
|
||||
|
||||
// Handle withdrawals
|
||||
$withdrawalResultMessages = [];
|
||||
$withdrawalErrors = [];
|
||||
if (!empty($withdraw)) {
|
||||
foreach ($withdraw as $studentId) {
|
||||
$studentId = (int) $studentId;
|
||||
$enrollment = $this->enrollmentModel
|
||||
->where('student_id', $studentId)
|
||||
->where('school_year', $this->schoolYear)
|
||||
@@ -673,6 +710,7 @@ class ParentController extends BaseController
|
||||
'updated_at' => utc_now()
|
||||
], (int) $parentId, 'parent_withdrawal_requested');
|
||||
log_message('info', "Student ID $studentId has been withdrawn from enrollment ID {$enrollment['id']}.");
|
||||
$withdrawalResultMessages[] = 'Student ID ' . $studentId . ': withdraw under review';
|
||||
|
||||
// === Trigger refund process ===
|
||||
// Find the related invoice (you may need to adjust this based on your DB structure)
|
||||
@@ -752,6 +790,7 @@ class ParentController extends BaseController
|
||||
}
|
||||
} else {
|
||||
log_message('error', "No active enrollment found for student ID $studentId.");
|
||||
$withdrawalErrors[] = 'Student ID ' . $studentId . ': no active enrollment was found.';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -761,13 +800,32 @@ class ParentController extends BaseController
|
||||
// Redirect to the success page after processing enrollment and withdrawal
|
||||
if (!empty($withdraw)) {
|
||||
// Redirect to withdrawal success page if there are withdrawals //parent/enroll_classes
|
||||
return redirect()->to('/parent/enroll_classes');
|
||||
$redirect = redirect()->to('/parent/enroll_classes');
|
||||
if ($withdrawalResultMessages !== []) {
|
||||
$redirect = $redirect->with('success', 'Withdrawal request submitted. ' . implode(' ', $withdrawalResultMessages));
|
||||
}
|
||||
if ($withdrawalErrors !== []) {
|
||||
$redirect = $redirect->with('error', 'Some withdrawal requests failed. ' . implode(' ', $withdrawalErrors));
|
||||
}
|
||||
|
||||
return $redirect;
|
||||
} else {
|
||||
// Redirect to enrollment success page if there are enrollments
|
||||
$contextValues = array_values(array_unique($submittedEnrollmentContexts ?? []));
|
||||
$parentData['enrollment_context'] = count($contextValues) === 1 ? $contextValues[0] : 'mixed';
|
||||
Events::trigger('admissionUnderReview', $parentData, $studentData); //send notification for enrolled student
|
||||
return redirect()->to('/parent/enroll_classes');
|
||||
try {
|
||||
Events::trigger('admissionUnderReview', $parentData, $studentData);
|
||||
} catch (Throwable $e) {
|
||||
log_message('error', 'Enrollment notification failed after successful submission: {message}', [
|
||||
'message' => $e->getMessage(),
|
||||
]);
|
||||
}
|
||||
$successMessage = 'Enrollment submitted successfully.';
|
||||
if ($enrollmentResultMessages !== []) {
|
||||
$successMessage .= ' ' . implode(' ', $enrollmentResultMessages);
|
||||
}
|
||||
|
||||
return redirect()->to('/parent/enroll_success')->with('success', $successMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -887,6 +945,107 @@ class ParentController extends BaseController
|
||||
return $errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $user
|
||||
* @return array<string, string>
|
||||
*/
|
||||
private function parentContactForEnrollment(array $user): array
|
||||
{
|
||||
$posted = old('parent_contact');
|
||||
$posted = is_array($posted) ? $posted : [];
|
||||
$phoneDigits = preg_replace('/\D/', '', (string) ($posted['cellphone'] ?? $user['cellphone'] ?? '')) ?? '';
|
||||
$phoneDisplay = strlen($phoneDigits) === 10
|
||||
? substr($phoneDigits, 0, 3) . '-' . substr($phoneDigits, 3, 3) . '-' . substr($phoneDigits, 6)
|
||||
: trim((string) ($posted['cellphone'] ?? $user['cellphone'] ?? ''));
|
||||
|
||||
return [
|
||||
'firstname' => trim((string) ($user['firstname'] ?? '')),
|
||||
'lastname' => trim((string) ($user['lastname'] ?? '')),
|
||||
'cellphone' => $phoneDisplay,
|
||||
'address_street' => trim((string) ($posted['address_street'] ?? $user['address_street'] ?? '')),
|
||||
'apt' => trim((string) ($posted['apt'] ?? $user['apt'] ?? '')),
|
||||
'city' => trim((string) ($posted['city'] ?? $user['city'] ?? '')),
|
||||
'state' => strtoupper(trim((string) ($posted['state'] ?? $user['state'] ?? ''))),
|
||||
'zip' => trim((string) ($posted['zip'] ?? $user['zip'] ?? '')),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<string>
|
||||
*/
|
||||
private function updateEnrollmentParentContact(int $parentId): array
|
||||
{
|
||||
$fields = $this->request->getPost('parent_contact');
|
||||
$normalized = $this->normalizeEnrollmentParentContact(is_array($fields) ? $fields : []);
|
||||
if ($normalized['errors'] !== []) {
|
||||
return $normalized['errors'];
|
||||
}
|
||||
|
||||
if (! $this->userModel->update($parentId, $normalized['data'])) {
|
||||
return ['Parent contact information could not be updated.'];
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $fields
|
||||
* @return array{errors: list<string>, data: array<string, string>}
|
||||
*/
|
||||
private function normalizeEnrollmentParentContact(array $fields): array
|
||||
{
|
||||
$phoneDigits = preg_replace('/\D/', '', (string) ($fields['cellphone'] ?? '')) ?? '';
|
||||
$street = trim((string) ($fields['address_street'] ?? ''));
|
||||
$apt = trim((string) ($fields['apt'] ?? ''));
|
||||
$city = trim((string) ($fields['city'] ?? ''));
|
||||
$state = strtoupper(trim((string) ($fields['state'] ?? '')));
|
||||
$zip = trim((string) ($fields['zip'] ?? ''));
|
||||
$errors = [];
|
||||
|
||||
if (strlen($phoneDigits) !== 10) {
|
||||
$errors[] = 'A valid 10-digit home/cell phone number is required.';
|
||||
}
|
||||
|
||||
if (strlen($street) < 5 || strlen($street) > 255) {
|
||||
$errors[] = 'Home street address is required.';
|
||||
}
|
||||
|
||||
if ($apt !== '' && strlen($apt) > 15) {
|
||||
$errors[] = 'Apartment or unit must be 15 characters or fewer.';
|
||||
}
|
||||
|
||||
if (strlen($city) < 2 || strlen($city) > 100) {
|
||||
$errors[] = 'City is required.';
|
||||
}
|
||||
|
||||
if (! preg_match('/^[A-Z]{2}$/', $state)) {
|
||||
$errors[] = 'State is required.';
|
||||
}
|
||||
|
||||
if (! preg_match('/^\d{5}$/', $zip)) {
|
||||
$errors[] = 'A valid 5-digit ZIP code is required.';
|
||||
}
|
||||
|
||||
if ($errors !== []) {
|
||||
return ['errors' => $errors, 'data' => []];
|
||||
}
|
||||
|
||||
$formattedPhone = (new PhoneFormatterService())->formatPhoneNumber($phoneDigits);
|
||||
|
||||
return [
|
||||
'errors' => [],
|
||||
'data' => [
|
||||
'cellphone' => $formattedPhone ?: $phoneDigits,
|
||||
'address_street' => $street,
|
||||
'apt' => $apt,
|
||||
'city' => ucfirst(strtolower($city)),
|
||||
'state' => $state,
|
||||
'zip' => $zip,
|
||||
'updated_at' => utc_now(),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $selected
|
||||
* @return list<string>
|
||||
@@ -1968,6 +2127,11 @@ class ParentController extends BaseController
|
||||
return ((int) $matches[1] - 1) . '-' . ((int) $matches[2] - 1);
|
||||
}
|
||||
|
||||
public function enrollSuccess()
|
||||
{
|
||||
return view('/parent/enroll_success');
|
||||
}
|
||||
|
||||
public function enrollFailure()
|
||||
{
|
||||
echo view('/parent/enroll_failure');
|
||||
@@ -2446,6 +2610,7 @@ class ParentController extends BaseController
|
||||
$this->db->transStart();
|
||||
|
||||
$studentAdded = false;
|
||||
$registeredStudentIds = [];
|
||||
|
||||
// Gather all POST data for last year flags
|
||||
$rawPost = $this->request->getPost();
|
||||
@@ -2472,6 +2637,9 @@ class ParentController extends BaseController
|
||||
|
||||
if ($result) {
|
||||
$studentAdded = true;
|
||||
if (is_numeric($result) && (int) $result > 0) {
|
||||
$registeredStudentIds[] = (int) $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2492,6 +2660,16 @@ class ParentController extends BaseController
|
||||
throw new \Exception('DB transaction failed.');
|
||||
}
|
||||
|
||||
if ($studentAdded) {
|
||||
$enrollmentQuery = ['start' => 2];
|
||||
if ($registeredStudentIds !== []) {
|
||||
$enrollmentQuery['students'] = implode(',', array_values(array_unique($registeredStudentIds)));
|
||||
}
|
||||
|
||||
return redirect()->to(base_url('/parent/enroll_classes?' . http_build_query($enrollmentQuery)))
|
||||
->with('success', 'Registration successful! Continue enrollment by confirming your home address and phone number.');
|
||||
}
|
||||
|
||||
return redirect()->to(base_url('/parent/child_register'))->with('success', 'Registration successful!');
|
||||
} catch (\Throwable $e) {
|
||||
log_message('error', $e->getMessage());
|
||||
@@ -2564,8 +2742,15 @@ class ParentController extends BaseController
|
||||
->findColumn('condition_name') ?? [];
|
||||
|
||||
$kid['enrollment'] = isset($enrollmentMap[$studentId]['id']) && !empty($enrollmentMap[$studentId]['id']) ? 1 : 0;
|
||||
}
|
||||
unset($kid);
|
||||
|
||||
service('studentYearStatus')->attachToStudents($kids, $selectedSchoolYear);
|
||||
|
||||
foreach ($kids as &$kid) {
|
||||
$kid['can_delete'] = $this->canParentDeleteStudent($kid, $parentId);
|
||||
}
|
||||
unset($kid);
|
||||
|
||||
$emergencies = $this->emergencyContactModel->where('parent_id', $parentId)->findAll();
|
||||
|
||||
@@ -2693,6 +2878,10 @@ $existing = $this->studentModel
|
||||
}
|
||||
}
|
||||
|
||||
if (! is_null($isNew) && (int) $studentId > 0) {
|
||||
service('studentYearStatus')->upsert((int) $studentId, (string) $schoolYear, (bool) $isNew);
|
||||
}
|
||||
|
||||
// ---------- SAVE MEDICAL CONDITIONS ----------
|
||||
$this->medicalConditionModel->where('student_id', $studentId)->delete();
|
||||
foreach ((array) $conditions as $c) {
|
||||
@@ -2710,14 +2899,14 @@ $existing = $this->studentModel
|
||||
foreach ((array) $allergies as $a) {
|
||||
$a = trim($a);
|
||||
if ($a !== '') {
|
||||
$this->allergyModel->insert([
|
||||
$this->allergyModel->insert([
|
||||
'student_id' => $studentId,
|
||||
'allergy' => $a,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return (int) $studentId > 0 ? (int) $studentId : true;
|
||||
}
|
||||
|
||||
|
||||
@@ -3099,7 +3288,15 @@ $existing = $this->studentModel
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((string) ($student['is_new'] ?? '1') === '0') {
|
||||
$statusYear = trim((string) ($student['school_year'] ?? ''));
|
||||
if ($statusYear === '') {
|
||||
$statusYear = (string) (service('studentYearStatus')->activeSchoolYear() ?? '');
|
||||
}
|
||||
$isNew = $statusYear !== ''
|
||||
? service('studentYearStatus')->isNew($studentId, $statusYear)
|
||||
: ((string) ($student['is_new'] ?? '1') === '1');
|
||||
|
||||
if (! $isNew) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user