db = $db; $this->studentClassModel = $studentClassModel; $this->userModel = $userModel; $this->userRoleModel = $userRoleModel; $this->invoiceModel = $invoiceModel; $this->studentModel = $studentModel; } public function studentProfiles(string $selectedYear): array { $db = db_connect(); $isPg = ($db->getPlatform() === 'Postgre'); // 'MySQLi', 'Postgre', 'SQLSRV', ... // In MySQL, avoid truncation of long lists if (!$isPg) { $db->query('SET SESSION group_concat_max_len = 8192'); } $b = $db->table('students'); if ($isPg) { // Postgres: use subqueries for aggregates to avoid GROUP BY on students.* $students = $b->select([ 'students.*', 'users.firstname AS parent_firstname', 'users.lastname AS parent_lastname', 'users.email AS parent_email', 'users.cellphone AS parent_phone', // Pick one emergency contact (first by id) "(SELECT ec.emergency_contact_name FROM emergency_contacts ec WHERE ec.parent_id = students.parent_id ORDER BY ec.id ASC LIMIT 1) AS emergency_name", "(SELECT ec.relation FROM emergency_contacts ec WHERE ec.parent_id = students.parent_id ORDER BY ec.id ASC LIMIT 1) AS emergency_relationship", "(SELECT ec.cellphone FROM emergency_contacts ec WHERE ec.parent_id = students.parent_id ORDER BY ec.id ASC LIMIT 1) AS emergency_phone", "(SELECT ec.email FROM emergency_contacts ec WHERE ec.parent_id = students.parent_id ORDER BY ec.id ASC LIMIT 1) AS emergency_email", // Aggregated lists "(SELECT STRING_AGG(DISTINCT sa.allergy, ', ' ORDER BY sa.allergy) FROM student_allergies sa WHERE sa.student_id = students.id) AS allergies", "(SELECT STRING_AGG(DISTINCT smc.condition_name, ', ' ORDER BY smc.condition_name) FROM student_medical_conditions smc WHERE smc.student_id = students.id) AS medical_conditions", ]) ->join('users', 'users.id = students.parent_id', 'left') ->orderBy('students.lastname', 'ASC') ->orderBy('students.firstname', 'ASC') ->get() ->getResultArray(); } else { // MySQL: GROUP_CONCAT + MIN() for emergency_* to satisfy ONLY_FULL_GROUP_BY $students = $b->select([ 'students.*', 'users.firstname AS parent_firstname', 'users.lastname AS parent_lastname', 'users.email AS parent_email', 'users.cellphone AS parent_phone', 'MIN(emergency_contacts.emergency_contact_name) AS emergency_name', 'MIN(emergency_contacts.relation) AS emergency_relationship', 'MIN(emergency_contacts.cellphone) AS emergency_phone', 'MIN(emergency_contacts.email) AS emergency_email', "GROUP_CONCAT(DISTINCT student_allergies.allergy ORDER BY student_allergies.allergy SEPARATOR ', ') AS allergies", "GROUP_CONCAT(DISTINCT student_medical_conditions.condition_name ORDER BY student_medical_conditions.condition_name SEPARATOR ', ') AS medical_conditions", ]) ->join('users', 'users.id = students.parent_id', 'left') ->join('emergency_contacts', 'emergency_contacts.parent_id = students.parent_id', 'left') ->join('student_allergies', 'student_allergies.student_id = students.id', 'left') ->join('student_medical_conditions', 'student_medical_conditions.student_id = students.id', 'left') ->groupBy('students.id') ->orderBy('students.lastname', 'ASC') ->orderBy('students.firstname', 'ASC') ->get() ->getResultArray(); } if ($selectedYear !== '') { service('studentYearStatus')->attachToStudents($students, $selectedYear); } $enrollmentStatusByStudentId = []; $studentIds = array_values(array_unique(array_filter(array_map( static fn (array $row): int => (int) ($row['id'] ?? 0), $students )))); if ($selectedYear !== '' && !empty($studentIds)) { $enrollmentRows = $db->table('enrollments') ->select('student_id, enrollment_status') ->whereIn('student_id', $studentIds) ->where('school_year', $selectedYear) ->orderBy('student_id', 'ASC') ->orderBy('updated_at', 'DESC') ->orderBy('enrollment_date', 'DESC') ->orderBy('id', 'DESC') ->get() ->getResultArray(); foreach ($enrollmentRows as $enrollmentRow) { $studentId = (int) ($enrollmentRow['student_id'] ?? 0); if ($studentId > 0 && !isset($enrollmentStatusByStudentId[$studentId])) { $enrollmentStatusByStudentId[$studentId] = (string) ($enrollmentRow['enrollment_status'] ?? ''); } } } // === Inject current-year class_section_name from student_class and replace grade === foreach ($students as $i => $row) { $sid = (int) ($row['id'] ?? 0); if ($sid > 0) { $classSectionName = (string) ($this->studentClassModel->getClassSectionNameByStudentId($sid, $selectedYear) ?? ''); $students[$i]['class_section_name'] = $classSectionName; $students[$i]['enrollment_status'] = $enrollmentStatusByStudentId[$sid] ?? ''; } else { // Keep keys consistent even if id missing $students[$i]['class_section_name'] = ''; $students[$i]['enrollment_status'] = ''; } $studentYear = trim((string) ($row['school_year'] ?? '')); $students[$i]['age'] = EnrollmentEligibility::ageOnSeptemberFirst( $row['dob'] ?? null, $studentYear !== '' ? $studentYear : $selectedYear ); } // === end injection === return [ 'students' => $students, 'gradeOptions' => ['K', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'Youth'], 'genderOptions' => ['Male', 'Female', 'Other'], 'selectedYear' => $selectedYear, ]; } public function parentProfiles(): array { $allUsers = $this->userModel->findAll(); $parents = []; // Fetch roles for users in one query to avoid looping over all users foreach ($allUsers as $user) { // Get the roles of the user directly $roles = $this->userRoleModel->getRolesByUserId($user['id']); $isParent = false; // Check if $roles is iterable and contains the 'parent' role if (is_array($roles)) { foreach ($roles as $role) { if (isset($role['role_name']) && $role['role_name'] === 'parent') { $isParent = true; break; } } } if ($isParent) { // Retrieve the latest paid amount and balance for this parent $paidAmount = $this->invoiceModel->getLatestInvoicePaidAmount($user['id']) ?? 0; $balance = $this->invoiceModel->getLatestInvoiceBalance($user['id']) ?? 0; // Get students for this parent $studentsData = $this->studentModel->where('parent_id', $user['id'])->findAll(); $students = []; foreach ($studentsData as $student) { $classSectionName = $this->studentClassModel->getClassSectionNameByStudentId($student['id']) ?? 'N/A'; $students[] = [ 'name' => $student['firstname'] . ' ' . $student['lastname'], 'class_section' => $classSectionName ]; } // Add parent data to the array $parents[] = [ 'id' => $user['id'], 'school_id' => $user['school_id'], 'firstname' => $user['firstname'], 'lastname' => $user['lastname'], 'email' => $user['email'], 'cellphone' => $user['cellphone'], 'gender' => $user['gender'], 'created_at' => $user['created_at'], 'paid_amount' => $paidAmount, 'balance' => $balance, 'students' => $students, ]; } } return ['parents' => $parents]; } }