is_locked) { $existing->update([ 'is_locked' => 0, 'locked_by' => null, 'locked_at' => null, ]); return false; } if ($existing) { $existing->update([ 'is_locked' => 1, 'locked_by' => $userId ?: null, 'locked_at' => now(), ]); } else { GradingLock::query()->create([ 'class_section_id' => $classSectionId, 'semester' => $semester, 'school_year' => $schoolYear, 'is_locked' => 1, 'locked_by' => $userId ?: null, 'locked_at' => now(), ]); } return true; } public function lockAll(string $semester, string $schoolYear, ?int $userId): int { if ($semester === '' || $schoolYear === '') { throw new RuntimeException('Missing semester or school year.'); } $sectionIds = ClassSection::query() ->select('class_section_id') ->groupBy('class_section_id') ->pluck('class_section_id') ->map(fn ($v) => (int) $v) ->filter(fn ($v) => $v > 0) ->values() ->all(); if (empty($sectionIds)) { return 0; } $existingLocks = GradingLock::query() ->whereIn('class_section_id', $sectionIds) ->where('semester', $semester) ->where('school_year', $schoolYear) ->get(); $existingBySection = []; foreach ($existingLocks as $row) { $sid = (int) $row->class_section_id; if ($sid > 0) { $existingBySection[$sid] = $row; } } $now = now(); $insertRows = []; $count = 0; foreach ($sectionIds as $sid) { if (!empty($existingBySection[$sid])) { if ($existingBySection[$sid]->is_locked) { continue; } $existingBySection[$sid]->update([ 'is_locked' => 1, 'locked_by' => $userId ?: null, 'locked_at' => $now, ]); $count++; continue; } $insertRows[] = [ 'class_section_id' => $sid, 'semester' => $semester, 'school_year' => $schoolYear, 'is_locked' => 1, 'locked_by' => $userId ?: null, 'locked_at' => $now, 'created_at' => $now, 'updated_at' => $now, ]; $count++; } if (!empty($insertRows)) { GradingLock::query()->insert($insertRows); } return $count; } }