fix financial and certificates
This commit is contained in:
@@ -63,7 +63,10 @@ class AttendanceCalculator implements ScoreCalculatorInterface
|
||||
return ['attendance_score' => 100.0];
|
||||
}
|
||||
|
||||
$attendanceRatio = ($totalDays + 1 - $absences) / $totalDays;
|
||||
// School policy: one absence is excused by grace before attendance is reduced.
|
||||
$graceAbsences = 1;
|
||||
$effectiveAbsences = max(0, (int) $absences - $graceAbsences);
|
||||
$attendanceRatio = ($totalDays - $effectiveAbsences) / $totalDays;
|
||||
$score = min(100, max(0, $attendanceRatio * 100));
|
||||
|
||||
return ['attendance_score' => round($score, 2)];
|
||||
|
||||
@@ -7,6 +7,7 @@ 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
|
||||
@@ -131,8 +132,10 @@ class ExamScoreService
|
||||
if (!$student) {
|
||||
continue;
|
||||
}
|
||||
$rawScore = $data['score'] ?? null;
|
||||
$normalizedScore = is_numeric($rawScore) ? (float) $rawScore : null;
|
||||
$rawScore = is_array($data) ? ($data['score'] ?? null) : $data;
|
||||
$validator = new ScoreValueValidator();
|
||||
$normalizedScore = $validator->normalizeNullable($rawScore, ScoreValueValidator::DEFAULT_MAX_POINTS, 'Exam score');
|
||||
$missingAllowed = !empty($missingOk[$studentId]);
|
||||
|
||||
$existing = $builder
|
||||
->where('student_id', $studentId)
|
||||
@@ -147,6 +150,8 @@ class ExamScoreService
|
||||
'class_section_id' => $classSectionId,
|
||||
'updated_by' => $updatedBy,
|
||||
'score' => $normalizedScore,
|
||||
'max_points' => ScoreValueValidator::DEFAULT_MAX_POINTS,
|
||||
'status' => $validator->inferStatus($normalizedScore, $missingAllowed),
|
||||
'semester' => $semester,
|
||||
'school_year' => $schoolYear,
|
||||
'updated_at' => now(),
|
||||
|
||||
@@ -9,6 +9,7 @@ use App\Models\Student;
|
||||
use App\Models\StudentClass;
|
||||
use App\Models\TeacherClass;
|
||||
use App\Models\ClassSection;
|
||||
use App\Services\Grading\Validation\ScoreValueValidator;
|
||||
|
||||
class HomeworkScoreService
|
||||
{
|
||||
@@ -248,8 +249,9 @@ class HomeworkScoreService
|
||||
continue;
|
||||
}
|
||||
$rawScore = $score ?? null;
|
||||
$isBlank = $rawScore === null || (is_string($rawScore) && trim($rawScore) === '');
|
||||
$normalizedScore = (!$isBlank && is_numeric($rawScore)) ? (float) $rawScore : null;
|
||||
$validator = new ScoreValueValidator();
|
||||
$normalizedScore = $validator->normalizeNullable($rawScore, ScoreValueValidator::DEFAULT_MAX_POINTS, 'Homework score');
|
||||
$missingAllowed = !empty($missingOk[$studentId][$index]);
|
||||
|
||||
$existing = Homework::query()
|
||||
->where('student_id', $studentId)
|
||||
@@ -266,6 +268,8 @@ class HomeworkScoreService
|
||||
'updated_by' => $updatedBy,
|
||||
'homework_index' => (int) $index,
|
||||
'score' => $normalizedScore,
|
||||
'max_points' => ScoreValueValidator::DEFAULT_MAX_POINTS,
|
||||
'status' => $validator->inferStatus($normalizedScore, $missingAllowed),
|
||||
'semester' => $semester,
|
||||
'school_year' => $schoolYear,
|
||||
'updated_at' => now(),
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Services\Scores;
|
||||
|
||||
use App\Models\GradingLock;
|
||||
use App\Models\ClassSection;
|
||||
use App\Services\Grading\Validation\ScoreValueValidator;
|
||||
use App\Models\MissingScoreOverride;
|
||||
use App\Models\Participation;
|
||||
use App\Models\Student;
|
||||
@@ -185,8 +186,9 @@ class ParticipationScoreService
|
||||
}
|
||||
|
||||
$rawScore = $data['score'] ?? null;
|
||||
$isBlank = $rawScore === null || (is_string($rawScore) && trim($rawScore) === '');
|
||||
$normalizedScore = (!$isBlank && is_numeric($rawScore)) ? (float) $rawScore : null;
|
||||
$validator = new ScoreValueValidator();
|
||||
$normalizedScore = $validator->normalizeNullable($rawScore, ScoreValueValidator::DEFAULT_MAX_POINTS, 'Participation score');
|
||||
$missingAllowed = !empty($missingOk[$studentId]);
|
||||
|
||||
$existing = Participation::query()
|
||||
->where('student_id', $studentId)
|
||||
@@ -201,6 +203,8 @@ class ParticipationScoreService
|
||||
'class_section_id' => $classSectionId,
|
||||
'updated_by' => $updatedBy,
|
||||
'score' => $normalizedScore,
|
||||
'max_points' => ScoreValueValidator::DEFAULT_MAX_POINTS,
|
||||
'status' => $validator->inferStatus($normalizedScore, $missingAllowed),
|
||||
'semester' => $semester,
|
||||
'school_year' => $schoolYear,
|
||||
'updated_at' => now(),
|
||||
|
||||
@@ -9,6 +9,7 @@ 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
|
||||
@@ -218,7 +219,9 @@ class ProjectScoreService
|
||||
if (!is_numeric($index)) {
|
||||
continue;
|
||||
}
|
||||
$normalizedScore = is_numeric($score) ? (float) $score : null;
|
||||
$validator = new ScoreValueValidator();
|
||||
$normalizedScore = $validator->normalizeNullable($score, ScoreValueValidator::DEFAULT_MAX_POINTS, 'Project score');
|
||||
$missingAllowed = !empty($missingOk[$studentId][$index]);
|
||||
|
||||
$existing = Project::query()
|
||||
->where('student_id', $studentId)
|
||||
@@ -235,6 +238,8 @@ class ProjectScoreService
|
||||
'updated_by' => $updatedBy,
|
||||
'project_index' => (int) $index,
|
||||
'score' => $normalizedScore,
|
||||
'max_points' => ScoreValueValidator::DEFAULT_MAX_POINTS,
|
||||
'status' => $validator->inferStatus($normalizedScore, $missingAllowed),
|
||||
'semester' => $semester,
|
||||
'school_year' => $schoolYear,
|
||||
'updated_at' => now(),
|
||||
|
||||
@@ -9,6 +9,7 @@ use App\Models\Student;
|
||||
use App\Models\StudentClass;
|
||||
use App\Models\TeacherClass;
|
||||
use App\Models\ClassSection;
|
||||
use App\Services\Grading\Validation\ScoreValueValidator;
|
||||
|
||||
class QuizScoreService
|
||||
{
|
||||
@@ -219,8 +220,9 @@ class QuizScoreService
|
||||
if (!is_numeric($quizNumber)) {
|
||||
continue;
|
||||
}
|
||||
$isBlank = $score === null || (is_string($score) && trim($score) === '');
|
||||
$normalizedScore = (!$isBlank && is_numeric($score)) ? (float) $score : null;
|
||||
$validator = new ScoreValueValidator();
|
||||
$normalizedScore = $validator->normalizeNullable($score, ScoreValueValidator::DEFAULT_MAX_POINTS, 'Quiz score');
|
||||
$missingAllowed = !empty($missingOk[$studentId][$quizNumber]);
|
||||
|
||||
$existing = Quiz::query()
|
||||
->where('student_id', $studentId)
|
||||
@@ -237,6 +239,8 @@ class QuizScoreService
|
||||
'updated_by' => $updatedBy,
|
||||
'quiz_index' => (int) $quizNumber,
|
||||
'score' => $normalizedScore,
|
||||
'max_points' => ScoreValueValidator::DEFAULT_MAX_POINTS,
|
||||
'status' => $validator->inferStatus($normalizedScore, $missingAllowed),
|
||||
'semester' => $semester,
|
||||
'school_year' => $schoolYear,
|
||||
'updated_at' => now(),
|
||||
|
||||
@@ -17,6 +17,7 @@ use App\Models\CalendarEvent;
|
||||
use App\Models\Homework;
|
||||
use App\Models\Project;
|
||||
use RuntimeException;
|
||||
use App\Services\Grading\Policy\GradingPolicyResolver;
|
||||
|
||||
class SemesterScoreService
|
||||
{
|
||||
@@ -26,6 +27,7 @@ class SemesterScoreService
|
||||
private string $semester;
|
||||
private string $schoolYear;
|
||||
private ?int $actorId;
|
||||
private GradingPolicyResolver $policyResolver;
|
||||
|
||||
public function __construct(
|
||||
?AttendanceCalculator $attendanceCalculator = null,
|
||||
@@ -36,6 +38,7 @@ 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();
|
||||
|
||||
$attendanceCalculator = $attendanceCalculator ?? new AttendanceCalculator(
|
||||
new AttendanceRecord(),
|
||||
@@ -209,12 +212,16 @@ class SemesterScoreService
|
||||
string $schoolYear,
|
||||
array $scoreData
|
||||
): void {
|
||||
$calculationMode = $this->policyResolver->calculationMode($classSectionId, $semester, $schoolYear);
|
||||
|
||||
$payload = array_merge([
|
||||
'student_id' => $studentId,
|
||||
'school_id' => $schoolId,
|
||||
'class_section_id' => $classSectionId,
|
||||
'semester' => $semester,
|
||||
'school_year' => $schoolYear,
|
||||
'calculation_mode' => $calculationMode,
|
||||
'calculation_policy_version' => $this->policyResolver->policyVersion($calculationMode),
|
||||
'updated_at' => now(),
|
||||
], $scoreData);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user