Fix Laravel Pint formatting

This commit is contained in:
root
2026-06-09 00:03:03 -04:00
parent 8d4d610b82
commit b5fd4a4ca1
1414 changed files with 11317 additions and 10201 deletions
+16 -8
View File
@@ -14,8 +14,7 @@ class AttendanceCalculator implements ScoreCalculatorInterface
private AttendanceRecord $attendanceModel,
private Configuration $configModel,
private CalendarEvent $calendarModel
) {
}
) {}
public function calculate(int $studentId, string $semester, string $schoolYear, ?int $classSectionId = null): array
{
@@ -30,7 +29,7 @@ class AttendanceCalculator implements ScoreCalculatorInterface
$events = CalendarEvent::getEventsBySchoolYearAndSemester($schoolYear, $normSemester);
$noSchoolSundays = 0;
foreach ($events as $event) {
if (!empty($event['no_school'])) {
if (! empty($event['no_school'])) {
$date = new \DateTime($event['date']);
if ($date->format('N') == 7) {
if ($date->format('Y-m-d') >= $semRange[0] && $date->format('Y-m-d') <= $semRange[1]) {
@@ -75,16 +74,21 @@ class AttendanceCalculator implements ScoreCalculatorInterface
protected function normalizeSemester(?string $input): string
{
$s = strtolower(trim((string) $input));
if ($s === 'fall' || str_contains($s, '1')) return 'fall';
if ($s === 'spring' || str_contains($s, '2')) return 'spring';
if ($s === 'fall' || str_contains($s, '1')) {
return 'fall';
}
if ($s === 'spring' || str_contains($s, '2')) {
return 'spring';
}
return '';
}
protected function getSemesterRange(string $schoolYear, string $semester): ?array
{
$norm = $this->normalizeSemester($semester);
if ($norm === '' || !preg_match('/^(\d{4})-(\d{4})$/', trim($schoolYear), $m)) {
if ($norm === '' || !preg_match('/^(\d{4})/', trim($schoolYear), $m)) {
if ($norm === '' || ! preg_match('/^(\d{4})-(\d{4})$/', trim($schoolYear), $m)) {
if ($norm === '' || ! preg_match('/^(\d{4})/', trim($schoolYear), $m)) {
return null;
}
$y1 = (int) $m[1];
@@ -102,12 +106,14 @@ class AttendanceCalculator implements ScoreCalculatorInterface
if ($norm === 'fall') {
$start = ($fallStartCfg !== '') ? sprintf('%04d-%s', $y1, date('m-d', strtotime($fallStartCfg))) : "{$y1}-09-01";
$end = ($fallEndCfg !== '') ? sprintf('%04d-%s', $y2, date('m-d', strtotime($fallEndCfg))) : "{$y2}-01-15";
return [$start, $end];
}
if ($norm === 'spring') {
$start = ($springStartCfg !== '') ? sprintf('%04d-%s', $y2, date('m-d', strtotime($springStartCfg))) : "{$y2}-01-16";
$end = ($springEndCfg !== '') ? sprintf('%04d-%s', $y2, date('m-d', strtotime($springEndCfg))) : "{$y2}-06-30";
return [$start, $end];
}
@@ -127,6 +133,7 @@ class AttendanceCalculator implements ScoreCalculatorInterface
$sundays++;
}
}
return $sundays;
}
@@ -139,11 +146,12 @@ class AttendanceCalculator implements ScoreCalculatorInterface
$configKey = $norm === 'fall' ? 'total_semester1_days' : 'total_semester2_days';
$value = Configuration::getConfig($configKey);
if (!is_numeric($value)) {
if (! is_numeric($value)) {
return null;
}
$length = (int) $value;
return $length > 0 ? $length : null;
}
}
+8 -10
View File
@@ -2,19 +2,17 @@
namespace App\Services\Scores;
use App\Models\ClassSection;
use App\Models\GradingLock;
use App\Models\MissingScoreOverride;
use App\Models\Student;
use App\Models\TeacherClass;
use App\Models\ClassSection;
use App\Services\Grading\Validation\ScoreValueValidator;
use Illuminate\Support\Facades\DB;
class ExamScoreService
{
public function __construct(private ScoreTermService $term)
{
}
public function __construct(private ScoreTermService $term) {}
public function resolveClassSectionIdForTeacher(int $teacherId, ?int $requestedClassSectionId, ?string $schoolYearInput): ?int
{
@@ -72,7 +70,7 @@ class ExamScoreService
->where('sc.school_year', '=', $schoolYear);
})
->leftJoinSub($latestSub, 'latest', 'latest.student_id', '=', 's.id')
->leftJoin($table . ' as ex', 'ex.id', '=', 'latest.max_id')
->leftJoin($table.' as ex', 'ex.id', '=', 'latest.max_id')
->orderBy('s.lastname')
->orderBy('s.firstname')
->get()
@@ -125,17 +123,17 @@ class ExamScoreService
$count = 0;
foreach ($scores as $studentId => $data) {
if (!is_numeric($studentId)) {
if (! is_numeric($studentId)) {
continue;
}
$student = Student::query()->find((int) $studentId);
if (!$student) {
if (! $student) {
continue;
}
$rawScore = is_array($data) ? ($data['score'] ?? null) : $data;
$validator = new ScoreValueValidator();
$validator = new ScoreValueValidator;
$normalizedScore = $validator->normalizeNullable($rawScore, ScoreValueValidator::DEFAULT_MAX_POINTS, 'Exam score');
$missingAllowed = !empty($missingOk[$studentId]);
$missingAllowed = ! empty($missingOk[$studentId]);
$existing = $builder
->where('student_id', $studentId)
@@ -178,7 +176,7 @@ class ExamScoreService
$schoolYearVariants = [$schoolYear];
}
$rows = DB::table($table . ' as ex')
$rows = DB::table($table.' as ex')
->select([
'ex.*',
's.firstname as student_firstname',
+2 -3
View File
@@ -7,13 +7,12 @@ use App\Models\Homework;
class HomeworkCalculator implements ScoreCalculatorInterface
{
public function __construct(private Homework $homeworkModel)
{
}
public function __construct(private Homework $homeworkModel) {}
public function calculate(int $studentId, string $semester, string $schoolYear, ?int $classSectionId = null): array
{
$average = Homework::getAverageHomeworkScore($studentId, $semester, $schoolYear, $classSectionId);
return ['homework_avg' => $average !== null ? (float) $average : null];
}
}
+14 -14
View File
@@ -2,20 +2,18 @@
namespace App\Services\Scores;
use App\Models\ClassSection;
use App\Models\GradingLock;
use App\Models\Homework;
use App\Models\MissingScoreOverride;
use App\Models\Student;
use App\Models\StudentClass;
use App\Models\TeacherClass;
use App\Models\ClassSection;
use App\Services\Grading\Validation\ScoreValueValidator;
class HomeworkScoreService
{
public function __construct(private ScoreTermService $term)
{
}
public function __construct(private ScoreTermService $term) {}
/**
* When the client omits class_section_id (legacy teacher portal), use the teacher's assignment
@@ -174,6 +172,7 @@ class HomeworkScoreService
return true;
}
}
return false;
}
@@ -181,10 +180,11 @@ class HomeworkScoreService
{
foreach ($schoolYearVariants as $year) {
$map = MissingScoreOverride::getOverridesMap($classSectionId, $semester, $year, 'homework');
if (!empty($map)) {
if (! empty($map)) {
return $map;
}
}
return [];
}
@@ -197,7 +197,7 @@ class HomeworkScoreService
$studentIds = array_keys($scores);
$indexSet = [];
foreach ($scores as $hwData) {
if (!is_array($hwData)) {
if (! is_array($hwData)) {
continue;
}
foreach ($hwData as $index => $_) {
@@ -209,11 +209,11 @@ class HomeworkScoreService
$checkedItems = [];
foreach ($missingOk as $studentId => $indexes) {
if (!is_array($indexes)) {
if (! is_array($indexes)) {
continue;
}
foreach ($indexes as $index => $flag) {
if (!is_numeric($index)) {
if (! is_numeric($index)) {
continue;
}
$checkedItems[] = [
@@ -236,22 +236,22 @@ class HomeworkScoreService
$count = 0;
foreach ($scores as $studentId => $hwData) {
if (!is_numeric($studentId) || !is_array($hwData)) {
if (! is_numeric($studentId) || ! is_array($hwData)) {
continue;
}
$student = Student::query()->find((int) $studentId);
if (!$student) {
if (! $student) {
continue;
}
foreach ($hwData as $index => $score) {
if (!is_numeric($index)) {
if (! is_numeric($index)) {
continue;
}
$rawScore = $score ?? null;
$validator = new ScoreValueValidator();
$validator = new ScoreValueValidator;
$normalizedScore = $validator->normalizeNullable($rawScore, ScoreValueValidator::DEFAULT_MAX_POINTS, 'Homework score');
$missingAllowed = !empty($missingOk[$studentId][$index]);
$missingAllowed = ! empty($missingOk[$studentId][$index]);
$existing = Homework::query()
->where('student_id', $studentId)
@@ -306,7 +306,7 @@ class HomeworkScoreService
foreach ($students as $student) {
$studentRow = Student::query()->find((int) $student->student_id);
if (!$studentRow) {
if (! $studentRow) {
continue;
}
$exists = Homework::query()
@@ -2,20 +2,18 @@
namespace App\Services\Scores;
use App\Models\GradingLock;
use App\Models\ClassSection;
use App\Services\Grading\Validation\ScoreValueValidator;
use App\Models\GradingLock;
use App\Models\MissingScoreOverride;
use App\Models\Participation;
use App\Models\Student;
use App\Models\StudentClass;
use App\Models\TeacherClass;
use App\Services\Grading\Validation\ScoreValueValidator;
class ParticipationScoreService
{
public function __construct(private ScoreTermService $term)
{
}
public function __construct(private ScoreTermService $term) {}
public function resolveClassSectionIdForTeacher(int $teacherId, ?int $requestedClassSectionId, ?string $schoolYearInput): ?int
{
@@ -173,22 +171,22 @@ class ParticipationScoreService
$count = 0;
foreach ($scores as $studentId => $data) {
if (!is_numeric($studentId)) {
if (! is_numeric($studentId)) {
continue;
}
if (!is_array($data)) {
if (! is_array($data)) {
$data = ['score' => $data];
}
$student = Student::query()->find((int) $studentId);
if (!$student) {
if (! $student) {
continue;
}
$rawScore = $data['score'] ?? null;
$validator = new ScoreValueValidator();
$validator = new ScoreValueValidator;
$normalizedScore = $validator->normalizeNullable($rawScore, ScoreValueValidator::DEFAULT_MAX_POINTS, 'Participation score');
$missingAllowed = !empty($missingOk[$studentId]);
$missingAllowed = ! empty($missingOk[$studentId]);
$existing = Participation::query()
->where('student_id', $studentId)
+2 -3
View File
@@ -7,13 +7,12 @@ use App\Models\Project;
class ProjectCalculator implements ScoreCalculatorInterface
{
public function __construct(private Project $projectModel)
{
}
public function __construct(private Project $projectModel) {}
public function calculate(int $studentId, string $semester, string $schoolYear, ?int $classSectionId = null): array
{
$average = Project::averageScore($studentId, $semester, $schoolYear, $classSectionId);
return ['project_avg' => $average !== null ? (float) $average : null];
}
}
+11 -14
View File
@@ -2,21 +2,18 @@
namespace App\Services\Scores;
use App\Models\ClassSection;
use App\Models\GradingLock;
use App\Models\MissingScoreOverride;
use App\Models\Project;
use App\Models\Student;
use App\Models\StudentClass;
use App\Models\TeacherClass;
use App\Models\ClassSection;
use App\Services\Grading\Validation\ScoreValueValidator;
use Illuminate\Support\Facades\DB;
class ProjectScoreService
{
public function __construct(private ScoreTermService $term)
{
}
public function __construct(private ScoreTermService $term) {}
public function resolveClassSectionIdForTeacher(int $teacherId, ?int $requestedClassSectionId, ?string $schoolYearInput): ?int
{
@@ -168,7 +165,7 @@ class ProjectScoreService
$studentIds = array_keys($scores);
$indexSet = [];
foreach ($scores as $projects) {
if (!is_array($projects)) {
if (! is_array($projects)) {
continue;
}
foreach ($projects as $index => $_) {
@@ -180,11 +177,11 @@ class ProjectScoreService
$checkedItems = [];
foreach ($missingOk as $studentId => $indexes) {
if (!is_array($indexes)) {
if (! is_array($indexes)) {
continue;
}
foreach ($indexes as $index => $flag) {
if (!is_numeric($index)) {
if (! is_numeric($index)) {
continue;
}
$checkedItems[] = [
@@ -207,21 +204,21 @@ class ProjectScoreService
$count = 0;
foreach ($scores as $studentId => $projects) {
if (!is_numeric($studentId) || !is_array($projects)) {
if (! is_numeric($studentId) || ! is_array($projects)) {
continue;
}
$student = Student::query()->find((int) $studentId);
if (!$student) {
if (! $student) {
continue;
}
foreach ($projects as $index => $score) {
if (!is_numeric($index)) {
if (! is_numeric($index)) {
continue;
}
$validator = new ScoreValueValidator();
$validator = new ScoreValueValidator;
$normalizedScore = $validator->normalizeNullable($score, ScoreValueValidator::DEFAULT_MAX_POINTS, 'Project score');
$missingAllowed = !empty($missingOk[$studentId][$index]);
$missingAllowed = ! empty($missingOk[$studentId][$index]);
$existing = Project::query()
->where('student_id', $studentId)
@@ -275,7 +272,7 @@ class ProjectScoreService
foreach ($students as $student) {
$studentRow = Student::query()->find((int) $student->student_id);
if (!$studentRow) {
if (! $studentRow) {
continue;
}
$exists = Project::query()
+1 -1
View File
@@ -24,7 +24,7 @@ class QuizCalculator implements ScoreCalculatorInterface
$count = 0;
foreach ($rows as $row) {
$score = $row->score ?? null;
if ($score === null || $score === '' || !is_numeric($score)) {
if ($score === null || $score === '' || ! is_numeric($score)) {
continue;
}
$total += (float) $score;
+12 -14
View File
@@ -2,20 +2,18 @@
namespace App\Services\Scores;
use App\Models\ClassSection;
use App\Models\GradingLock;
use App\Models\MissingScoreOverride;
use App\Models\Quiz;
use App\Models\Student;
use App\Models\StudentClass;
use App\Models\TeacherClass;
use App\Models\ClassSection;
use App\Services\Grading\Validation\ScoreValueValidator;
class QuizScoreService
{
public function __construct(private ScoreTermService $term)
{
}
public function __construct(private ScoreTermService $term) {}
public function resolveClassSectionIdForTeacher(int $teacherId, ?int $requestedClassSectionId, ?string $schoolYearInput): ?int
{
@@ -167,7 +165,7 @@ class QuizScoreService
$studentIds = array_keys($scores);
$indexSet = [];
foreach ($scores as $quizData) {
if (!is_array($quizData)) {
if (! is_array($quizData)) {
continue;
}
foreach ($quizData as $index => $_) {
@@ -179,11 +177,11 @@ class QuizScoreService
$checkedItems = [];
foreach ($missingOk as $studentId => $indexes) {
if (!is_array($indexes)) {
if (! is_array($indexes)) {
continue;
}
foreach ($indexes as $index => $flag) {
if (!is_numeric($index)) {
if (! is_numeric($index)) {
continue;
}
$checkedItems[] = [
@@ -206,23 +204,23 @@ class QuizScoreService
$count = 0;
foreach ($scores as $studentId => $quizData) {
if (!is_numeric($studentId)) {
if (! is_numeric($studentId)) {
continue;
}
if (!is_array($quizData)) {
if (! is_array($quizData)) {
$quizData = [1 => $quizData];
}
$student = Student::query()->find((int) $studentId);
if (!$student) {
if (! $student) {
continue;
}
foreach ($quizData as $quizNumber => $score) {
if (!is_numeric($quizNumber)) {
if (! is_numeric($quizNumber)) {
continue;
}
$validator = new ScoreValueValidator();
$validator = new ScoreValueValidator;
$normalizedScore = $validator->normalizeNullable($score, ScoreValueValidator::DEFAULT_MAX_POINTS, 'Quiz score');
$missingAllowed = !empty($missingOk[$studentId][$quizNumber]);
$missingAllowed = ! empty($missingOk[$studentId][$quizNumber]);
$existing = Quiz::query()
->where('student_id', $studentId)
@@ -276,7 +274,7 @@ class QuizScoreService
foreach ($students as $student) {
$studentRow = Student::query()->find((int) $student->student_id);
if (!$studentRow) {
if (! $studentRow) {
continue;
}
$exists = Quiz::query()
+18 -19
View File
@@ -2,21 +2,18 @@
namespace App\Services\Scores;
use App\Models\Configuration;
use App\Models\ClassSection;
use App\Models\Configuration;
use App\Models\GradingLock;
use App\Models\MissingScoreOverride;
use App\Models\ScoreComment;
use App\Models\SemesterScore;
use App\Models\Student;
use App\Models\StudentClass;
use Illuminate\Support\Facades\DB;
class ScoreCommentService
{
public function __construct(private ScoreTermService $term)
{
}
public function __construct(private ScoreTermService $term) {}
public function list(?string $classSectionId, ?string $semester, ?string $schoolYear): array
{
@@ -33,24 +30,24 @@ class ScoreCommentService
->orderBy('s.firstname')
->distinct();
if (!$isAllSections && $classSectionInt) {
if (! $isAllSections && $classSectionInt) {
$builder->where('sc.class_section_id', $classSectionInt);
}
$students = $builder->get()->map(fn ($row) => (array) $row)->all();
$comments = [];
if (!empty($students)) {
if (! empty($students)) {
$studentIds = array_map(static fn ($r) => (int) $r['student_id'], $students);
$rawComments = ScoreComment::query()
->whereIn('student_id', $studentIds)
->whereIn('score_type', ['midterm', 'final', 'ptap', 'attendance'])
->where('semester', $activeSemester)
->where('school_year', $schoolYear)
->when(!$isAllSections && $classSectionInt, function ($q) use ($classSectionInt) {
->when(! $isAllSections && $classSectionInt, function ($q) use ($classSectionInt) {
$q->where(function ($w) use ($classSectionInt) {
$w->where('class_section_id', $classSectionInt)
->orWhereNull('class_section_id');
->orWhereNull('class_section_id');
});
})
->get();
@@ -87,7 +84,7 @@ class ScoreCommentService
if ($hasComment) {
continue;
}
if (!function_exists('attendance_comment_from_score')) {
if (! function_exists('attendance_comment_from_score')) {
continue;
}
$score = $attendanceScores[$sid] ?? null;
@@ -112,10 +109,10 @@ class ScoreCommentService
'semester' => $activeSemester,
'schoolYear' => $schoolYear,
'classSectionId' => $isAllSections ? 'allsections' : $classSectionInt,
'classSectionName' => (!$isAllSections && $classSectionInt)
'classSectionName' => (! $isAllSections && $classSectionInt)
? (string) (ClassSection::query()->where('class_section_id', $classSectionInt)->value('class_section_name') ?? '')
: '',
'scoresLocked' => (!$isAllSections && $classSectionInt)
'scoresLocked' => (! $isAllSections && $classSectionInt)
? GradingLock::isLocked($classSectionInt, $activeSemester, $schoolYear)
: false,
];
@@ -143,7 +140,7 @@ class ScoreCommentService
foreach ($commentTypes as $type) {
$checkedItems = [];
foreach ($missingOk as $studentId => $types) {
if (!is_array($types) || empty($types[$type])) {
if (! is_array($types) || empty($types[$type])) {
continue;
}
$checkedItems[] = [
@@ -175,6 +172,7 @@ class ScoreCommentService
$validationError = $this->validateComment($trimmedComment, (int) $studentId, $normalizedScoreType, $studentNames);
if ($validationError !== null) {
$errors[] = $validationError;
continue;
}
@@ -185,7 +183,7 @@ class ScoreCommentService
->where('school_year', $schoolYear)
->where(function ($q) use ($classSectionId) {
$q->where('class_section_id', $classSectionId)
->orWhereNull('class_section_id');
->orWhereNull('class_section_id');
})
->first();
@@ -239,6 +237,7 @@ class ScoreCommentService
$validationError = $this->validateComment($commentText, (int) $studentId, $normalizedScoreType, $studentNames);
if ($validationError !== null) {
$errors[] = $validationError;
continue;
}
}
@@ -250,7 +249,7 @@ class ScoreCommentService
->where('school_year', $schoolYear)
->where(function ($q) use ($classSectionId) {
$q->where('class_section_id', $classSectionId)
->orWhereNull('class_section_id');
->orWhereNull('class_section_id');
})
->first();
@@ -322,8 +321,8 @@ class ScoreCommentService
return "{$firstName}'s {$scoreType} comment must be at most 400 characters.";
}
$pattern = '/^' . preg_quote($firstName, '/') . '\\b/i';
if (!preg_match($pattern, $trimmed)) {
$pattern = '/^'.preg_quote($firstName, '/').'\\b/i';
if (! preg_match($pattern, $trimmed)) {
return "{$firstName}'s {$scoreType} comment must start with the student's first name.";
}
@@ -333,7 +332,7 @@ class ScoreCommentService
private function isReviewer(): bool
{
$user = auth()->user();
if (!$user) {
if (! $user) {
return false;
}
@@ -354,6 +353,6 @@ class ScoreCommentService
explode(',', $reviewerRoles)
);
return !empty(array_intersect($currentUserRoles, $allowedRoles));
return ! empty(array_intersect($currentUserRoles, $allowedRoles));
}
}
+7 -10
View File
@@ -3,7 +3,6 @@
namespace App\Services\Scores;
use App\Models\ClassSection;
use App\Models\Configuration;
use App\Models\GradingLock;
use App\Models\MissingScoreOverride;
use App\Models\ScoreComment;
@@ -15,16 +14,14 @@ use Illuminate\Support\Facades\DB;
class ScoreDashboardService
{
public function __construct(private ScoreTermService $term)
{
}
public function __construct(private ScoreTermService $term) {}
public function overview(int $teacherId, ?int $classSectionId, ?string $semester, ?string $schoolYear): array
{
$schoolYear = $this->term->schoolYear($schoolYear);
$semesterLabel = $this->term->semesterLabel($semester, $semester);
if ($teacherId <= 0 && !empty($classSectionId)) {
if ($teacherId <= 0 && ! empty($classSectionId)) {
$allowedIds = [(int) $classSectionId];
} else {
$allowedIds = TeacherClass::query()
@@ -45,7 +42,7 @@ class ScoreDashboardService
$studentQuery = StudentClass::query();
if (DB::connection()->getDriverName() === 'sqlite') {
$studentQuery->whereRaw('class_section_id = ' . (int) $classSectionId);
$studentQuery->whereRaw('class_section_id = '.(int) $classSectionId);
if ($schoolYear !== '') {
$quoted = DB::connection()->getPdo()->quote($schoolYear);
$studentQuery->whereRaw("school_year = {$quoted}");
@@ -62,9 +59,9 @@ class ScoreDashboardService
->map(fn ($v) => (int) $v)
->all();
if (empty($studentIds) && DB::connection()->getDriverName() === 'sqlite') {
$schoolYearClause = $schoolYear !== '' ? " and school_year = " . DB::connection()->getPdo()->quote($schoolYear) : '';
$schoolYearClause = $schoolYear !== '' ? ' and school_year = '.DB::connection()->getPdo()->quote($schoolYear) : '';
$rows = DB::select(
"select student_id from student_class where class_section_id = " . (int) $classSectionId . $schoolYearClause
'select student_id from student_class where class_section_id = '.(int) $classSectionId.$schoolYearClause
);
$studentIds = array_values(array_filter(array_map(
static fn ($row) => isset($row->student_id) ? (int) $row->student_id : 0,
@@ -173,7 +170,7 @@ class ScoreDashboardService
foreach ($commentTypes as $type) {
$checkedItems = [];
foreach ($missingOk as $studentId => $types) {
if (!is_array($types) || empty($types[$type])) {
if (! is_array($types) || empty($types[$type])) {
continue;
}
$checkedItems[] = [
@@ -229,7 +226,7 @@ class ScoreDashboardService
->all();
$scores = [];
if (!empty($students)) {
if (! empty($students)) {
$studentIdList = array_column($students, 'id');
$semesterScores = DB::table('semester_scores')
->whereIn('student_id', $studentIdList)
@@ -56,7 +56,7 @@ class ScorePredictorDataService
->orWhere('cs.class_section_name', 'not like', 'KG%');
});
if (!empty($classSectionId)) {
if (! empty($classSectionId)) {
$builder->where('sc.class_section_id', $classSectionId);
}
@@ -81,7 +81,7 @@ class ScorePredictorDataService
->orWhere('cs.class_section_name', 'not like', 'KG%');
});
if (!empty($classSectionId)) {
if (! empty($classSectionId)) {
$builder->where('student_class.class_section_id', $classSectionId);
}
@@ -14,6 +14,7 @@ class ScorePredictorRiskService
$a5 = 1.061405429;
$erf = 1 - ((((($a5 * $t + $a4) * $t + $a3) * $t + $a2) * $t + $a1) * $t) * exp(-$z * $z);
$sign = $z < 0 ? -1 : 1;
return 0.5 * (1 + $sign * $erf);
}
@@ -26,7 +27,7 @@ class ScorePredictorRiskService
$springScore = is_numeric($student['spring_score'] ?? null) ? (float) $student['spring_score'] : null;
$scoreParts = array_values(array_filter([$fallScore, $springScore], static fn ($v) => $v !== null));
$finalAvg = !empty($scoreParts) ? round(array_sum($scoreParts) / count($scoreParts), 1) : null;
$finalAvg = ! empty($scoreParts) ? round(array_sum($scoreParts) / count($scoreParts), 1) : null;
$waitingForSpring = ($fallScore !== null && $springScore === null);
@@ -40,8 +41,8 @@ class ScorePredictorRiskService
$probLow = $zLow !== null ? $this->normalCdf($zLow) : null;
$riskHigh = match (true) {
$finalAvg !== null && !$waitingForSpring && $finalAvg >= $trophyThreshold => 'Achieved Trophy',
$finalAvg !== null && !$waitingForSpring => 'Unreachable',
$finalAvg !== null && ! $waitingForSpring && $finalAvg >= $trophyThreshold => 'Achieved Trophy',
$finalAvg !== null && ! $waitingForSpring => 'Unreachable',
$requiredHigh !== null && $requiredHigh > 100 => 'Unreachable',
is_null($probHigh) => 'New student',
$probHigh >= 0.66 => 'Low',
@@ -50,8 +51,8 @@ class ScorePredictorRiskService
};
$riskLow = match (true) {
$finalAvg !== null && !$waitingForSpring && $finalAvg < $targetLow => 'High',
$finalAvg !== null && !$waitingForSpring => 'Low',
$finalAvg !== null && ! $waitingForSpring && $finalAvg < $targetLow => 'High',
$finalAvg !== null && ! $waitingForSpring => 'Low',
$requiredLow !== null && $requiredLow > 100 => 'Unlikely to pass',
is_null($probLow) => 'New student',
$probLow >= 0.66 => 'High',
@@ -103,19 +104,23 @@ class ScorePredictorRiskService
}
foreach ($bySection as $cid => $indices) {
if (!empty($hasThresholdTrophy[$cid])) {
if (! empty($hasThresholdTrophy[$cid])) {
continue;
}
$candidates = [];
foreach ($indices as $idx) {
$val = $results[$idx]['final_average'] ?? null;
if (!is_numeric($val)) {
if (! is_numeric($val)) {
$fall = $results[$idx]['fall_score'] ?? null;
$spring = $results[$idx]['spring_score'] ?? null;
$parts = [];
if (is_numeric($fall)) $parts[] = (float) $fall;
if (is_numeric($spring)) $parts[] = (float) $spring;
if (!empty($parts)) {
if (is_numeric($fall)) {
$parts[] = (float) $fall;
}
if (is_numeric($spring)) {
$parts[] = (float) $spring;
}
if (! empty($parts)) {
$val = array_sum($parts) / count($parts);
}
}
@@ -9,8 +9,7 @@ class ScorePredictorService
public function __construct(
private ScorePredictorDataService $dataService,
private ScorePredictorRiskService $riskService
) {
}
) {}
public function report(?string $schoolYear, ?int $classSectionId = null): array
{
+1
View File
@@ -15,6 +15,7 @@ class ScoreTermService
if ($value === 'spring' || str_contains($value, '2')) {
return 'spring';
}
return '';
}
+26 -22
View File
@@ -3,21 +3,17 @@
namespace App\Services\Scores;
use App\Interfaces\ScoreCalculatorInterface;
use App\Models\Configuration;
use App\Models\FinalExam;
use App\Models\MidtermExam;
use App\Models\Participation;
use App\Models\SemesterScore;
use App\Services\Scores\AttendanceCalculator;
use App\Services\Scores\HomeworkCalculator;
use App\Services\Scores\ProjectCalculator;
use App\Services\Scores\QuizCalculator;
use App\Models\AttendanceRecord;
use App\Models\CalendarEvent;
use App\Models\Configuration;
use App\Models\FinalExam;
use App\Models\Homework;
use App\Models\MidtermExam;
use App\Models\Participation;
use App\Models\Project;
use RuntimeException;
use App\Models\SemesterScore;
use App\Services\Grading\Policy\GradingPolicyResolver;
use RuntimeException;
class SemesterScoreService
{
@@ -25,8 +21,11 @@ class SemesterScoreService
private array $scoreCalculators = [];
private string $semester;
private string $schoolYear;
private ?int $actorId;
private GradingPolicyResolver $policyResolver;
public function __construct(
@@ -38,16 +37,16 @@ class SemesterScoreService
$this->semester = (string) (Configuration::getConfig('semester') ?? '');
$this->schoolYear = (string) (Configuration::getConfig('school_year') ?? '');
$this->actorId = (int) (auth()->id() ?? 0) ?: null;
$this->policyResolver = new GradingPolicyResolver();
$this->policyResolver = new GradingPolicyResolver;
$attendanceCalculator = $attendanceCalculator ?? new AttendanceCalculator(
new AttendanceRecord(),
new Configuration(),
new CalendarEvent()
new AttendanceRecord,
new Configuration,
new CalendarEvent
);
$homeworkCalculator = $homeworkCalculator ?? new HomeworkCalculator(new Homework());
$quizCalculator = $quizCalculator ?? new QuizCalculator();
$projectCalculator = $projectCalculator ?? new ProjectCalculator(new Project());
$homeworkCalculator = $homeworkCalculator ?? new HomeworkCalculator(new Homework);
$quizCalculator = $quizCalculator ?? new QuizCalculator;
$projectCalculator = $projectCalculator ?? new ProjectCalculator(new Project);
$this->scoreCalculators = [
AttendanceCalculator::class => $attendanceCalculator,
@@ -70,7 +69,7 @@ class SemesterScoreService
public function updateStudentScores(array $student, string $semester, string $schoolYear): void
{
foreach (['student_id', 'school_id', 'class_section_id'] as $field) {
if (!isset($student[$field])) {
if (! isset($student[$field])) {
throw new RuntimeException("Missing required student field: {$field}");
}
}
@@ -114,7 +113,7 @@ class SemesterScoreService
}
}
if (!isset($scoreData['participation_score'])) {
if (! isset($scoreData['participation_score'])) {
$participationScore = Participation::getParticipationScore($studentId, $semester, $schoolYear, $classSectionId);
$scoreData['participation_score'] = $participationScore !== null ? (float) $participationScore : null;
}
@@ -140,24 +139,27 @@ class SemesterScoreService
$hasTests = $avgQuiz !== null;
$hasProjects = $avgProject !== null;
if (!$hasTests && !$hasProjects) {
if (! $hasTests && ! $hasProjects) {
if ($avgHomework === null || $avgParticipation === null) {
return null;
}
return round(($avgHomework * 0.5) + ($avgParticipation * 0.5), 1);
}
if (!$hasProjects) {
if (! $hasProjects) {
if ($avgHomework === null || $avgParticipation === null || $avgQuiz === null) {
return null;
}
return round(($avgHomework * 0.4) + ($avgParticipation * 0.4) + ($avgQuiz * 0.2), 1);
}
if (!$hasTests) {
if (! $hasTests) {
if ($avgHomework === null || $avgParticipation === null || $avgProject === null) {
return null;
}
return round(($avgHomework * 0.34) + ($avgParticipation * 0.33) + ($avgProject * 0.33), 1);
}
@@ -188,6 +190,7 @@ class SemesterScoreService
if ($ptap !== null && $attendance !== null && $out['midterm_score'] !== null) {
$out['semester_score'] = round(($attendance * 0.2) + ($ptap * 0.2) + ($out['midterm_score'] * 0.6), 1);
}
return $out;
}
@@ -197,6 +200,7 @@ class SemesterScoreService
if ($ptap !== null && $attendance !== null && $out['final_score'] !== null) {
$out['semester_score'] = round(($attendance * 0.2) + ($ptap * 0.2) + ($out['final_score'] * 0.6), 1);
}
return $out;
}