get(); } public function paginated(int $perPage = 25, string $search = ''): LengthAwarePaginator { return Department::query() ->select(['id', 'code', 'name', 'degree_level']) ->with(['currentLeader.lecturer.user.profile']) ->when($search, fn ($q) => $q->where('name', 'like', "%{$search}%")->orWhere('code', 'like', "%{$search}%")) ->latest() ->paginate($perPage); } public function create(array $data): Department { $department = Department::create([ 'code' => $data['code'], 'name' => $data['name'], 'degree_level' => $data['degree_level'] ?? null, ]); $this->syncLeadership($department, $data['lecturer_id'] ?? null, $data['leadership_started_at'] ?? null); return $department; } public function update(Department $department, array $data): Department { $department->code = $data['code']; $department->name = $data['name']; $department->degree_level = $data['degree_level'] ?? null; $department->update(); $this->syncLeadership($department, $data['lecturer_id'] ?? null, $data['leadership_started_at'] ?? null); return $department; } private function syncLeadership(Department $department, ?int $lecturerId, ?string $startedAt): void { $currentLeader = DepartmentLeadership::query() ->where('department_id', $department->id) ->whereNull('ended_at') ->first(); if (! $lecturerId) { if ($currentLeader) { $currentLeader->update(['ended_at' => now()]); $this->revokeKaprodiRoleIfNoLongerLeading($currentLeader->lecturer_id); } return; } if ($currentLeader && $currentLeader->lecturer_id === $lecturerId) { $currentLeader->update(['started_at' => $startedAt ?? $currentLeader->started_at]); $this->grantKaprodiRole($lecturerId); return; } if ($currentLeader) { $currentLeader->update(['ended_at' => now()]); $this->revokeKaprodiRoleIfNoLongerLeading($currentLeader->lecturer_id); } $department->leaderships()->create([ 'lecturer_id' => $lecturerId, 'started_at' => $startedAt ?? now(), ]); $this->grantKaprodiRole($lecturerId); } private function grantKaprodiRole(int $lecturerId): void { $user = Lecturer::find($lecturerId)?->user; if ($user && ! $user->hasRole('kaprodi')) { $user->assignRole('kaprodi'); } } private function revokeKaprodiRoleIfNoLongerLeading(int $lecturerId): void { $stillLeadsAnyDepartment = DepartmentLeadership::query() ->where('lecturer_id', $lecturerId) ->whereNull('ended_at') ->exists(); if (! $stillLeadsAnyDepartment) { Lecturer::find($lecturerId)?->user?->removeRole('kaprodi'); } } public function delete(Department $department): bool { return $department->delete(); } }