fix parent, teacher and admin pages
This commit is contained in:
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user