with([ 'courseClass.course:id,code,name', 'courseClass.lecturer.user.profile', ]) ->when($search, fn ($q) => $q->where('title', 'like', "%{$search}%")) ->when($courseClassId, fn ($q) => $q->where('course_class_id', $courseClassId)) ->when($academicTermId, fn ($q) => $q->whereHas('courseClass', fn ($q) => $q->where('academic_term_id', $academicTermId))) ->when($user->hasRole(UserRole::Dosen->value), fn ($q) => $q->whereHas('courseClass', fn ($q) => $q->where('lecturer_id', $user->lecturer?->id))) ->when($user->hasRole(UserRole::Mahasiswa->value), fn ($q) => $q->whereHas('courseClass', function ($q) use ($user) { $q->whereHas('registrations', function ($q) use ($user) { $q->where('student_id', $user->student?->id) ->whereHas('submission', fn ($q) => $q->where('status', RegistrationStatus::Approved)); }); })) ->latest() ->paginate($perPage, ['id', 'course_class_id', 'title', 'description', 'meeting_number', 'created_at']); } public function create(array $data, ?UploadedFile $file): Material { $material = Material::create([ 'course_class_id' => $data['course_class_id'], 'title' => $data['title'], 'description' => $data['description'] ?? null, 'meeting_number' => $data['meeting_number'] ?? null, ]); if ($file) { $material->addMedia($file)->toMediaCollection('materials'); } $material->load('courseClass.course'); $recipientUserIds = CourseRegistration::query() ->where('course_class_id', $material->course_class_id) ->whereHas('submission', fn ($q) => $q->where('status', RegistrationStatus::Approved)) ->with('student:id,user_id') ->get() ->pluck('student.user_id'); $this->notificationService->sendToUsers( $recipientUserIds, 'Materi Baru', "Materi baru \"{$material->title}\" telah ditambahkan pada kelas {$material->courseClass->course->name}.", ); return $material; } public function update(Material $material, array $data, ?UploadedFile $file): Material { $material->update([ 'course_class_id' => $data['course_class_id'], 'title' => $data['title'], 'description' => $data['description'] ?? null, 'meeting_number' => $data['meeting_number'] ?? null, ]); if ($file) { $material->addMedia($file)->toMediaCollection('materials'); } return $material; } public function delete(Material $material): bool { return $material->delete(); } }