leftJoin('user_roles', 'user_roles.user_id', '=', 'users.id') ->leftJoin('roles', 'roles.id', '=', 'user_roles.role_id') ->select([ 'users.id', 'users.firstname', 'users.lastname', DB::raw("GROUP_CONCAT(DISTINCT CASE WHEN LOWER(roles.name) != 'parent' THEN roles.name END ORDER BY roles.name SEPARATOR ', ') as roles"), ]) ->groupBy('users.id', 'users.firstname', 'users.lastname'); if (!empty($selectedUserIds)) { $query->whereIn('users.id', $selectedUserIds); } if (Schema::hasColumn('user_roles', 'deleted_at')) { $query->whereNull('user_roles.deleted_at'); } $rows = array_map(static fn ($row) => (array) $row, $query->get()->all()); return array_values(array_filter($rows, static function (array $row): bool { $roles = strtolower(trim((string) ($row['roles'] ?? ''))); if ($roles === '') { return false; } $parts = array_values(array_filter(array_map('trim', explode(',', $roles)))); foreach ($parts as $part) { if (in_array($part, ['parent', 'student'], true)) { continue; } return true; } return false; })); } public function getLatestClassForUser(int $userId, ?string $schoolYear = null): ?array { $query = DB::table('teacher_class as tc') ->leftJoin('classSection as cs', 'cs.class_section_id', '=', 'tc.class_section_id') ->select([ 'tc.class_section_id', 'cs.class_section_name', ]) ->where('tc.teacher_id', $userId); if (!empty($schoolYear)) { $query->where('tc.school_year', $schoolYear); } $row = $query ->orderByRaw("FIELD(tc.position, 'main', 'ta')") ->orderByRaw('IFNULL(tc.updated_at,"0000-00-00 00:00:00") DESC') ->orderByDesc('tc.id') ->first(); if (!$row || empty($row->class_section_id)) { return null; } return [ 'class_section_id' => (int) $row->class_section_id, 'class_section_name' => $row->class_section_name ?? null, ]; } public function getUserInfoById(int $id, ?string $schoolYear = null): ?array { $u = DB::table('users') ->select(['id as user_id', 'firstname', 'lastname', 'school_id', 'account_id']) ->where('id', $id) ->first(); if (!$u) { return null; } $userId = (int) $u->user_id; $fullname = trim(($u->firstname ?? '') . ' ' . ($u->lastname ?? '')); $schoolId = trim((string) ($u->school_id ?? '')); if ($schoolId === '') { $schoolId = trim((string) ($u->account_id ?? '')); } $rolesRows = DB::table('user_roles as ur') ->join('roles as r', 'r.id', '=', 'ur.role_id') ->select(['r.id as role_id', 'r.name as role_name']) ->where('ur.user_id', $userId) ->get(); $allRoles = []; foreach ($rolesRows as $rr) { $name = trim((string) ($rr->role_name ?? '')); if ($name !== '' && strtolower($name) !== 'parent') { $allRoles[] = ucwords(strtolower($name)); } } $allRoles = array_values(array_unique($allRoles)); $rolesCsv = $allRoles ? implode(', ', $allRoles) : ''; $tcQuery = DB::table('teacher_class') ->select(['class_section_id', 'updated_at', 'id', 'position', 'school_year']) ->where('teacher_id', $userId); if (!empty($schoolYear)) { $tcQuery->where('school_year', $schoolYear); } $assignment = $tcQuery ->orderByRaw('IFNULL(updated_at, "1970-01-01 00:00:00") DESC, id DESC') ->first(); $classId = $assignment->class_section_id ?? null; $position = strtolower(trim((string) ($assignment->position ?? ''))); $className = null; if (!empty($classId)) { $className = $this->resolveClassName((int) $classId); } if (in_array($position, ['ta', 'teacher_assistant', 'assistant'], true)) { $roleLabel = 'Teacher Assistant'; } elseif ($position === 'teacher' || $position === 'main') { $roleLabel = 'Teacher'; } elseif (!empty($allRoles)) { $roleLabel = $allRoles[0]; } else { $roleLabel = 'Staff'; } $schoolLogo = $this->formatter->firstExisting([ public_path('assets/images/school_logo.png'), public_path('assets/images/logo.png'), ]); $isglLogo = $this->formatter->firstExisting([ public_path('assets/images/isgl_logo.png'), public_path('assets/images/isgl.png'), ]); $jobTitle = ''; if (!empty($roleLabel) && !empty($className)) { $jobTitle = "{$roleLabel} - {$className}"; } elseif (!empty($roleLabel)) { $jobTitle = $roleLabel; } elseif (!empty($className)) { $jobTitle = $className; } return [ 'user_id' => $userId, 'name' => $fullname !== '' ? $fullname : 'STAFF', 'role' => $roleLabel, 'roles' => $rolesCsv, 'class_section_id' => $classId ? (int) $classId : null, 'class_section_name' => $className, 'job_title' => $jobTitle, 'school_name' => 'Al Rahma Sunday School', 'school_id' => $schoolId, 'school_logo' => $schoolLogo, 'isgl_logo' => $isglLogo, 'school_year' => $assignment->school_year ?? $schoolYear, ]; } public function getAvailableSchoolYears(): array { $schoolYears = []; try { if (Schema::hasTable('teacher_class')) { $schoolYears = DB::table('teacher_class') ->selectRaw('DISTINCT school_year') ->whereNotNull('school_year') ->orderByDesc('school_year') ->pluck('school_year') ->filter() ->values() ->all(); } } catch (\Throwable) { } if (empty($schoolYears)) { try { if (Schema::hasTable('user_roles') && Schema::hasColumn('user_roles', 'school_year')) { $schoolYears = DB::table('user_roles') ->selectRaw('DISTINCT school_year') ->whereNotNull('school_year') ->orderByDesc('school_year') ->pluck('school_year') ->filter() ->values() ->all(); } } catch (\Throwable) { } } return $schoolYears; } protected function resolveClassName(int $classSectionId): ?string { $row = DB::table('classSection') ->select('class_section_name') ->where('class_section_id', $classSectionId) ->first(); return $row->class_section_name ?? null; } }