fix is_new issue with enrollment fixes
Deploy to Shared Hosting / Shared hosting deploy (push) Failing after 48s
Tests / PHPUnit (push) Failing after 1m22s

This commit is contained in:
root
2026-08-20 19:57:25 -04:00
parent 127098b87c
commit 889c037660
29 changed files with 77306 additions and 293 deletions
+139 -39
View File
@@ -17,7 +17,6 @@ class StudentModel extends Model
'gender',
'registration_grade',
'photo_consent',
'is_new',
'parent_id',
'registration_date',
'tuition_paid',
@@ -27,24 +26,38 @@ class StudentModel extends Model
];
protected $useTimestamps = false;
// File: app/Models/StudentModel.php
/**
* Get all students marked as new (is_new = 1).
*
* @return array
* Get students marked as new for a school year.
*/
public function getNewStudents(): array
public function getNewStudents(string $schoolYear): array
{
return $this->where('is_new', 1)
->orderBy('lastname', 'ASC')
->orderBy('firstname', 'ASC')
$schoolYear = trim($schoolYear);
if (! preg_match('/^\d{4}-\d{4}$/', $schoolYear) || ! $this->db->tableExists('student_year_status')) {
return [];
}
return $this->select('students.*, COALESCE(sys.is_new, 1) AS is_new')
->join(
'student_year_status sys',
'sys.student_id = students.id AND sys.school_year = ' . $this->db->escape($schoolYear),
'inner'
)
->where('COALESCE(sys.is_new, 1)', 1, false)
->orderBy('students.lastname', 'ASC')
->orderBy('students.firstname', 'ASC')
->findAll();
}
public function getNewStudentsWithParents(): array
public function getNewStudentsWithParents(string $schoolYear): array
{
$schoolYear = trim($schoolYear);
if (! preg_match('/^\d{4}-\d{4}$/', $schoolYear) || ! $this->db->tableExists('student_year_status')) {
return [];
}
return $this->select([
'students.*',
'COALESCE(sys.is_new, 1) AS is_new',
'u.id AS parent_id',
'u.firstname AS parent_firstname',
'u.lastname AS parent_lastname',
@@ -52,55 +65,91 @@ class StudentModel extends Model
'u.cellphone AS parent_phone',
])
->join('users u', 'u.id = students.parent_id', 'left')
->where('students.is_new', 1)
->join(
'student_year_status sys',
'sys.student_id = students.id AND sys.school_year = ' . $this->db->escape($schoolYear),
'inner'
)
->where('COALESCE(sys.is_new, 1)', 1, false)
->orderBy('students.lastname', 'ASC')
->orderBy('students.firstname', 'ASC')
->findAll();
}
/**
* Fetch only new students (is_new=1) with parent info and a single emergency contact.
* - Parent fields: parent_firstname, parent_lastname, parent_email, parent_phone
* - Emergency fields: emergency_name, emergency_relationship, emergency_phone
* Fetch only new students for a school year with parent info and a single emergency contact.
*/
public function getNewStudentsWithParentsAndEmergency(): array
public function getNewStudentsWithParentsAndEmergency(string $schoolYear): array
{
$schoolYear = trim($schoolYear);
if (! preg_match('/^\d{4}-\d{4}$/', $schoolYear) || ! $this->db->tableExists('student_year_status')) {
return [];
}
return $this->select([
'students.*',
'COALESCE(sys.is_new, 1) AS is_new',
'u.firstname AS parent_firstname',
'u.lastname AS parent_lastname',
'u.email AS parent_email',
'u.cellphone AS parent_phone',
// Pick one emergency contact (MIN() works fine if you group by student)
'MIN(ec.emergency_contact_name) AS emergency_name',
'MIN(ec.relation) AS emergency_relationship',
'MIN(ec.cellphone) AS emergency_phone',
])
->join('users u', 'u.id = students.parent_id', 'left')
->join('emergency_contacts ec', 'ec.parent_id = students.parent_id', 'left')
->where('students.is_new', 1) // strictly 1; change to 'Yes' if your data uses Yes/No
->join(
'student_year_status sys',
'sys.student_id = students.id AND sys.school_year = ' . $this->db->escape($schoolYear),
'inner'
)
->where('COALESCE(sys.is_new, 1)', 1, false)
->groupBy('students.id')
->orderBy('students.lastname', 'ASC')
->orderBy('students.firstname', 'ASC')
->findAll();
}
/**
* Fetch students with parent + one emergency contact.
* @param null|int $isNew Pass 1 for only new, 0 for only not-new, null for both.
*/
/**
* Fetch students with parent + one emergency contact.
*
* @param null|int $isNew 1 = only new, 0 = only not-new, null = both
* @param null|string $schoolYear e.g. "2025-2026"; pass null or "all" for no filter
* @param null|int $isNew 1 = only new, 0 = only not-new, null for both
* @param null|string $schoolYear e.g. "2025-2026"; pass null or "all" for no year filter
* @return array
*/
public function getStudentsWithParentsAndEmergency(?string $schoolYear = null, ?int $isNew = null): array
{
$builder = $this->select([
'students.*',
$filterByYear = $schoolYear !== null && strtolower((string) $schoolYear) !== 'all';
$statusYear = $filterByYear ? trim((string) $schoolYear) : '';
if ($statusYear === '' && ($isNew === 0 || $isNew === 1)) {
$statusYear = (string) (service('studentYearStatus')->activeSchoolYear() ?? '');
}
$useYearScopedIsNew = $statusYear !== ''
&& preg_match('/^\d{4}-\d{4}$/', $statusYear)
&& $this->db->tableExists('student_year_status');
$schoolYearSelect = $statusYear !== ''
? $this->db->escape($statusYear) . ' AS school_year'
: 'NULL AS school_year';
$select = [
'students.id',
'students.school_id',
'students.firstname',
'students.lastname',
'students.dob',
'students.age',
'students.gender',
'students.registration_grade',
'students.photo_consent',
'students.parent_id',
'students.registration_date',
'students.tuition_paid',
'students.year_of_registration',
$schoolYearSelect,
'students.rfid_tag',
'NULL AS semester',
'students.is_active',
'u.firstname AS parent_firstname',
'u.lastname AS parent_lastname',
'u.email AS parent_email',
@@ -108,30 +157,47 @@ class StudentModel extends Model
'MIN(ec.emergency_contact_name) AS emergency_name',
'MIN(ec.relation) AS emergency_relationship',
'MIN(ec.cellphone) AS emergency_phone',
])
];
if ($useYearScopedIsNew) {
$select[] = 'COALESCE(sys.is_new, 1) AS is_new';
}
$builder = $this->select($select)
->join('users u', 'u.id = students.parent_id', 'left')
->join('emergency_contacts ec', 'ec.parent_id = students.parent_id', 'left');
// is_new filter
if ($isNew === 0 || $isNew === 1) {
$builder->where('students.is_new', $isNew);
} else {
$builder->whereIn('students.is_new', [0, 1]); // both
if ($useYearScopedIsNew) {
$builder->join(
'student_year_status sys',
'sys.student_id = students.id AND sys.school_year = ' . $this->db->escape($statusYear),
'left'
);
}
// school_year filter (skip if null or "all")
if ($schoolYear !== null && strtolower($schoolYear) !== 'all') {
if ($isNew === 0 || $isNew === 1) {
if (! $useYearScopedIsNew) {
return [];
}
$builder->where('COALESCE(sys.is_new, 1)', $isNew, false);
}
if ($filterByYear) {
$builder
->join('student_class sc_filter', 'sc_filter.student_id = students.id', 'inner')
->where('sc_filter.school_year', $schoolYear);
}
return $builder
$builder = $builder
->groupBy('students.id')
->orderBy('students.is_new', 'DESC') // new first
->orderBy('students.lastname', 'ASC')
->orderBy('students.firstname', 'ASC')
->findAll();
->orderBy('students.firstname', 'ASC');
if ($useYearScopedIsNew) {
$builder->orderBy('COALESCE(sys.is_new, 1)', 'DESC', false);
}
return $builder->findAll();
}
@@ -407,6 +473,15 @@ class StudentModel extends Model
$studentClassJoin = 'student_class.student_id = students.id';
$enrollmentJoin = 'enrollments.student_id = students.id';
$selectedYearFilter = '';
$useYearScopedIsNew = $schoolYear !== ''
&& preg_match('/^\d{4}-\d{4}$/', $schoolYear)
&& $this->db->tableExists('student_year_status');
$schoolYearSelect = $schoolYear !== ''
? $this->db->escape($schoolYear) . ' AS school_year'
: 'NULL AS school_year';
$isNewSelect = $useYearScopedIsNew
? 'COALESCE(sys.is_new, 1) AS is_new'
: '1 AS is_new';
if ($schoolYear !== '') {
$escapedSchoolYear = $this->db->escape($schoolYear);
@@ -433,7 +508,24 @@ class StudentModel extends Model
}
$builder = $this->select('
students.*,
students.id,
students.school_id,
students.firstname,
students.lastname,
students.dob,
students.age,
students.gender,
students.registration_grade,
students.photo_consent,
students.parent_id,
students.registration_date,
students.tuition_paid,
students.year_of_registration,
' . $schoolYearSelect . ',
students.rfid_tag,
NULL AS semester,
students.is_active,
' . $isNewSelect . ',
student_class.class_section_id,
enrollments.enrollment_status,
enrollments.admission_status,
@@ -444,6 +536,14 @@ class StudentModel extends Model
->join('enrollments', $enrollmentJoin, 'left')
->join('users u', 'u.id = students.parent_id', 'left');
if ($useYearScopedIsNew) {
$builder->join(
'student_year_status sys',
'sys.student_id = students.id AND sys.school_year = ' . $this->db->escape($schoolYear),
'left'
);
}
if ($selectedYearFilter !== '') {
$builder->where($selectedYearFilter, null, false);
}