isAdmin($user)) { return true; } return $this->isAuthor($user, $report) || $this->teachesSection($user, $report) || $this->parentHasEnrolledSection($user, $report); } public function create(User $user): bool { return $user !== null; } public function update(User $user, ClassProgressReport $report): bool { return $this->isAdmin($user) || $this->isAuthor($user, $report); } public function delete(User $user, ClassProgressReport $report): bool { return $this->isAdmin($user) || $this->isAuthor($user, $report); } private function isAuthor(User $user, ClassProgressReport $report): bool { return (int) $report->teacher_id === (int) $user->id; } /** Same relaxed section membership used by `ClassProgressQueryService::listReports`. */ private function teachesSection(User $user, ClassProgressReport $report): bool { return in_array( (int) $report->class_section_id, TeacherClass::distinctAccessibleSectionIdsForTeacher((int) $user->id), true ); } private function isAdmin(User $user): bool { $roles = $user->roles() ->pluck('roles.name') ->map(fn ($name) => strtolower((string) $name)) ->toArray(); foreach (['administrator', 'admin', 'principal', 'vice_principal', 'vice-principal'] as $role) { if (in_array($role, $roles, true)) { return true; } } return false; } private function parentHasEnrolledSection(User $user, ClassProgressReport $report): bool { if (! Schema::hasTable('enrollments')) { return false; } $parentId = (int) (request()?->attributes?->get('primary_parent_id') ?? 0); if ($parentId <= 0) { if (! $this->isParent($user)) { return false; } $parentId = (int) $user->id; } return DB::table('enrollments') ->where('parent_id', $parentId) ->where('class_section_id', (int) $report->class_section_id) ->where('is_withdrawn', 0) ->exists(); } private function isParent(User $user): bool { return $user->roles() ->pluck('roles.name') ->map(fn ($name) => strtolower((string) $name)) ->contains('parent'); } }