From f69ed0bc151a10971e3ea48df2be75eac8062822 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Thu, 3 Sep 2026 11:35:27 +0700 Subject: [PATCH] refactor: reorganize StudentService methods and enhance query efficiency with enums --- app/Services/Admin/Users/StudentService.php | 117 ++++++++++---------- 1 file changed, 58 insertions(+), 59 deletions(-) diff --git a/app/Services/Admin/Users/StudentService.php b/app/Services/Admin/Users/StudentService.php index ec35cfc..4f0acff 100644 --- a/app/Services/Admin/Users/StudentService.php +++ b/app/Services/Admin/Users/StudentService.php @@ -2,6 +2,8 @@ namespace App\Services\Admin\Users; +use App\Enums\StudentStatus; +use App\Enums\UserRole; use App\Models\Student; use App\Models\User; use Illuminate\Contracts\Pagination\LengthAwarePaginator; @@ -12,67 +14,11 @@ class StudentService { - public function getAllForSelect(?string $status = null): Collection - { - return Student::select(['students.id', 'students.user_id', 'students.student_number', 'students.department_id', 'students.current_semester']) - ->join('departments', 'departments.id', '=', 'students.department_id') - ->join('users', 'users.id', '=', 'students.user_id') - ->join('user_profiles', 'user_profiles.user_id', '=', 'users.id') - ->with([ - 'user:id,username', - 'user.profile:id,user_id,full_name', - 'department:id,name', - ]) - ->when($status, fn ($q) => $q->where('students.status', $status)) - ->orderBy('departments.name') - ->orderBy('students.current_semester') - ->orderBy('user_profiles.full_name') - ->get(); - } - - public function getEnrollmentYears(): array - { - return Student::query() - ->select('enrollment_year') - ->distinct() - ->orderByDesc('enrollment_year') - ->pluck('enrollment_year') - ->all(); - } - public function paginated(int $perPage = 25, string $search = '', ?string $gender = null, ?int $departmentId = null, ?string $status = null, ?int $enrollmentYear = null): LengthAwarePaginator { return $this->filteredQuery($search, $gender, $departmentId, $status, $enrollmentYear) ->latest() - ->paginate($perPage); - } - - public function forExport(string $search = '', ?string $gender = null, ?int $departmentId = null, ?string $status = null, ?int $enrollmentYear = null): Collection - { - return $this->filteredQuery($search, $gender, $departmentId, $status, $enrollmentYear) - ->orderBy('created_at', 'desc') - ->get(); - } - - private function filteredQuery(string $search, ?string $gender, ?int $departmentId, ?string $status, ?int $enrollmentYear = null): Builder - { - return User::select(['id', 'username', 'email', 'is_active']) - ->with([ - 'profile:id,user_id,full_name,phone_number,gender,birth_place,birth_date,address', - 'student:id,user_id,student_number,department_id,enrollment_year,current_semester,status', - 'student.department:id,name', - ]) - ->whereHas('roles', fn ($q) => $q->where('name', 'mahasiswa')) - ->when($search, fn ($q) => $q->where(function ($query) use ($search) { - $query->where('username', 'like', "%{$search}%") - ->orWhere('email', 'like', "%{$search}%") - ->orWhereHas('profile', fn ($q) => $q->where('full_name', 'like', "%{$search}%")) - ->orWhereHas('student', fn ($q) => $q->where('student_number', 'like', "%{$search}%")); - })) - ->when($gender, fn ($q) => $q->whereHas('profile', fn ($q) => $q->where('gender', $gender))) - ->when($departmentId, fn ($q) => $q->whereHas('student', fn ($q) => $q->where('department_id', $departmentId))) - ->when($status, fn ($q) => $q->whereHas('student', fn ($q) => $q->where('status', $status))) - ->when($enrollmentYear, fn ($q) => $q->whereHas('student', fn ($q) => $q->where('enrollment_year', $enrollmentYear))); + ->paginate($perPage, ['id', 'username', 'email', 'is_active']); } public function create(array $data): User @@ -84,7 +30,7 @@ public function create(array $data): User 'password' => Hash::make(config('app.default_password')), ]); - $user->assignRole('mahasiswa'); + $user->assignRole(UserRole::Mahasiswa->value); $user->profile()->create([ 'full_name' => $data['full_name'], @@ -101,7 +47,7 @@ public function create(array $data): User 'enrollment_year' => $data['enrollment_year'], 'current_semester' => $data['current_semester'], 'academic_advisor_id' => $data['academic_advisor_id'], - 'status' => 'active', + 'status' => StudentStatus::Active, ]); return $user; @@ -162,4 +108,57 @@ public function updateUserStatus(User $user, bool $isActive): void { $user->update(['is_active' => $isActive]); } + + public function forExport(string $search = '', ?string $gender = null, ?int $departmentId = null, ?string $status = null, ?int $enrollmentYear = null): Collection + { + return $this->filteredQuery($search, $gender, $departmentId, $status, $enrollmentYear) + ->orderBy('created_at', 'desc') + ->get(['id', 'username', 'email', 'is_active']); + } + + public function getAllForSelect(?string $status = null): Collection + { + return Student::join('departments', 'departments.id', '=', 'students.department_id') + ->join('users', 'users.id', '=', 'students.user_id') + ->join('user_profiles', 'user_profiles.user_id', '=', 'users.id') + ->with([ + 'user:id,username', + 'user.profile:id,user_id,full_name', + 'department:id,name', + ]) + ->when($status, fn ($q) => $q->where('students.status', $status)) + ->orderBy('departments.name') + ->orderBy('students.current_semester') + ->orderBy('user_profiles.full_name') + ->get(['students.id', 'students.user_id', 'students.student_number', 'students.department_id', 'students.current_semester']); + } + + public function getEnrollmentYears(): array + { + return Student::query() + ->distinct() + ->orderByDesc('enrollment_year') + ->pluck('enrollment_year') + ->all(); + } + + private function filteredQuery(string $search, ?string $gender, ?int $departmentId, ?string $status, ?int $enrollmentYear = null): Builder + { + return User::with([ + 'profile:id,user_id,full_name,phone_number,gender,birth_place,birth_date,address', + 'student:id,user_id,student_number,department_id,enrollment_year,current_semester,status', + 'student.department:id,name', + ]) + ->whereHas('roles', fn ($q) => $q->where('name', UserRole::Mahasiswa->value)) + ->when($search, fn ($q) => $q->where(function ($query) use ($search) { + $query->where('username', 'like', "%{$search}%") + ->orWhere('email', 'like', "%{$search}%") + ->orWhereHas('profile', fn ($q) => $q->where('full_name', 'like', "%{$search}%")) + ->orWhereHas('student', fn ($q) => $q->where('student_number', 'like', "%{$search}%")); + })) + ->when($gender, fn ($q) => $q->whereHas('profile', fn ($q) => $q->where('gender', $gender))) + ->when($departmentId, fn ($q) => $q->whereHas('student', fn ($q) => $q->where('department_id', $departmentId))) + ->when($status, fn ($q) => $q->whereHas('student', fn ($q) => $q->where('status', $status))) + ->when($enrollmentYear, fn ($q) => $q->whereHas('student', fn ($q) => $q->where('enrollment_year', $enrollmentYear))); + } }