fix parent, teacher and admin pages

This commit is contained in:
root
2026-04-25 00:00:23 -04:00
parent 4cd98f1d30
commit eafe4eb134
30 changed files with 1566 additions and 105 deletions
@@ -2,11 +2,143 @@
namespace App\Services\Students;
use App\Models\Configuration;
use App\Models\Student;
use App\Models\StudentClass;
use App\Models\TeacherClass;
use App\Models\User;
use Illuminate\Support\Facades\DB;
class StudentScoreCardService
{
/**
* Students shown on the score-card picker (CI `StudentController::scoreCardList` parity).
* Teachers: only students in `class_section_id` for `school_year` after `teacher_class` check.
* Parents: their children only. Other roles: active students (optional search/limit).
*
* @return list<array{id: int, student_id: int, school_id: string, firstname: string, lastname: string, name: string, is_active: int}>
*/
public function scoreCardSelectableStudents(
User $user,
string $searchQuery,
int $limit,
?int $classSectionId,
?string $schoolYear,
): array {
$rolesLower = array_map('strtolower', $user->roleNamesLikeCodeIgniter());
$isTeacher = in_array('teacher', $rolesLower, true) || in_array('teacher_assistant', $rolesLower, true);
$isParent = in_array('parent', $rolesLower, true);
$cid = (int) ($classSectionId ?? 0);
$year = $schoolYear !== null && trim($schoolYear) !== '' ? trim($schoolYear) : (string) (Configuration::getConfig('school_year') ?? '');
if ($isTeacher && $cid > 0) {
$assigned = TeacherClass::query()
->where('teacher_id', $user->id)
->where('class_section_id', $cid)
->when($year !== '', fn ($q) => $q->where('school_year', $year))
->exists();
if (! $assigned) {
return [];
}
$students = $year !== ''
? Student::getByClassAndYear($cid, $year)
: Student::query()
->whereIn('id', StudentClass::query()->select('student_id')->where('class_section_id', $cid))
->where('is_active', 1)
->orderBy('lastname')
->orderBy('firstname')
->get()
->all();
$rows = array_map(fn (Student $s) => $this->selectableStudentPayload($s), $students);
return $this->applySearchAndLimit($rows, $searchQuery, $limit);
}
if ($isTeacher && ! $isParent) {
return [];
}
if ($isParent) {
$q = Student::query()
->select('id', 'school_id', 'firstname', 'lastname', 'is_active')
->where('parent_id', $user->id)
->where('is_active', 1);
if ($searchQuery !== '') {
$sq = $searchQuery;
$q->where(function ($b) use ($sq) {
$b->where('firstname', 'like', '%'.$sq.'%')
->orWhere('lastname', 'like', '%'.$sq.'%')
->orWhere('school_id', 'like', '%'.$sq.'%');
});
}
$students = $q->orderBy('lastname')->orderBy('firstname')->limit($limit)->get();
return $students->map(fn (Student $s) => $this->selectableStudentPayload($s))->values()->all();
}
$studentsQuery = Student::query()
->select('id', 'school_id', 'firstname', 'lastname', 'is_active')
->where('is_active', 1);
if ($searchQuery !== '') {
$studentsQuery->where(function ($builder) use ($searchQuery) {
$builder->where('firstname', 'like', '%'.$searchQuery.'%')
->orWhere('lastname', 'like', '%'.$searchQuery.'%')
->orWhere('school_id', 'like', '%'.$searchQuery.'%');
});
}
return $studentsQuery
->orderBy('lastname')
->orderBy('firstname')
->limit($limit)
->get()
->map(fn (Student $student) => $this->selectableStudentPayload($student))
->values()
->all();
}
/**
* @param list<array{id: int, student_id: int, school_id: string, firstname: string, lastname: string, name: string, is_active: int}> $rows
* @return list<array{id: int, student_id: int, school_id: string, firstname: string, lastname: string, name: string, is_active: int}>
*/
private function applySearchAndLimit(array $rows, string $searchQuery, int $limit): array
{
if ($searchQuery === '') {
return array_slice($rows, 0, $limit);
}
$needle = strtolower($searchQuery);
$filtered = array_values(array_filter($rows, static function (array $r) use ($needle): bool {
$hay = strtolower(
($r['firstname'] ?? '').' '.($r['lastname'] ?? '').' '.($r['school_id'] ?? '')
);
return str_contains($hay, $needle);
}));
return array_slice($filtered, 0, $limit);
}
private function selectableStudentPayload(Student $student): array
{
return [
'id' => (int) $student->id,
'student_id' => (int) $student->id,
'school_id' => (string) ($student->school_id ?? ''),
'firstname' => (string) ($student->firstname ?? ''),
'lastname' => (string) ($student->lastname ?? ''),
'name' => trim(((string) ($student->firstname ?? '')).' '.((string) ($student->lastname ?? ''))),
'is_active' => (int) ($student->is_active ?? 0),
];
}
public function scoreCard(int $studentId): array
{
$student = Student::query()