110 lines
3.6 KiB
PHP
110 lines
3.6 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Grading;
|
|
|
|
use App\Models\ScoreComment;
|
|
use App\Models\SemesterScore;
|
|
use App\Models\Student;
|
|
use App\Services\Scores\SemesterScoreService;
|
|
use RuntimeException;
|
|
|
|
class GradingRefreshService
|
|
{
|
|
public function __construct(private SemesterScoreService $semesterScoreService) {}
|
|
|
|
public function refreshSemesterScores(int $classSectionId, string $semester, string $schoolYear): void
|
|
{
|
|
if ($classSectionId <= 0) {
|
|
throw new RuntimeException('Missing class section.');
|
|
}
|
|
|
|
$studentTeacherInfo = Student::getStudentInfoByClassSectionId(
|
|
$classSectionId,
|
|
$semester,
|
|
$schoolYear
|
|
);
|
|
if (empty($studentTeacherInfo)) {
|
|
throw new RuntimeException('No students found for this class/term.');
|
|
}
|
|
|
|
$this->semesterScoreService->updateScoresForStudents($studentTeacherInfo, $semester, $schoolYear);
|
|
$this->refreshAttendanceComments($classSectionId, $semester, $schoolYear);
|
|
}
|
|
|
|
private function refreshAttendanceComments(int $classSectionId, string $semester, string $schoolYear): void
|
|
{
|
|
if (! function_exists('attendance_comment_from_score')) {
|
|
return;
|
|
}
|
|
|
|
$scoreRows = SemesterScore::query()
|
|
->select(['student_id', 'attendance_score'])
|
|
->where('class_section_id', $classSectionId)
|
|
->where('semester', $semester)
|
|
->where('school_year', $schoolYear)
|
|
->get();
|
|
|
|
if ($scoreRows->isEmpty()) {
|
|
return;
|
|
}
|
|
|
|
$studentIds = $scoreRows->pluck('student_id')->map(fn ($v) => (int) $v)->unique()->values()->all();
|
|
if (empty($studentIds)) {
|
|
return;
|
|
}
|
|
|
|
$students = Student::query()
|
|
->select(['id', 'firstname'])
|
|
->whereIn('id', $studentIds)
|
|
->get();
|
|
$nameMap = [];
|
|
foreach ($students as $student) {
|
|
$nameMap[(int) $student->id] = (string) ($student->firstname ?? '');
|
|
}
|
|
|
|
$existing = ScoreComment::query()
|
|
->where('score_type', 'attendance')
|
|
->where('class_section_id', $classSectionId)
|
|
->where('semester', $semester)
|
|
->where('school_year', $schoolYear)
|
|
->whereIn('student_id', $studentIds)
|
|
->get();
|
|
$existingByStudent = [];
|
|
foreach ($existing as $row) {
|
|
$existingByStudent[(int) $row->student_id] = $row;
|
|
}
|
|
|
|
foreach ($scoreRows as $row) {
|
|
$studentId = (int) $row->student_id;
|
|
if ($studentId <= 0) {
|
|
continue;
|
|
}
|
|
$score = $row->attendance_score !== null ? (float) $row->attendance_score : null;
|
|
if ($score === null) {
|
|
continue;
|
|
}
|
|
$auto = attendance_comment_from_score($score, $nameMap[$studentId] ?? '');
|
|
if ($auto === null) {
|
|
continue;
|
|
}
|
|
|
|
if (isset($existingByStudent[$studentId])) {
|
|
$existingByStudent[$studentId]->update([
|
|
'comment' => $auto,
|
|
]);
|
|
} else {
|
|
ScoreComment::query()->create([
|
|
'student_id' => $studentId,
|
|
'class_section_id' => $classSectionId,
|
|
'score_type' => 'attendance',
|
|
'semester' => $semester,
|
|
'school_year' => $schoolYear,
|
|
'comment' => $auto,
|
|
'commented_by' => null,
|
|
'created_at' => now(),
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
}
|