Admin: manual scoring for open-ended questions

This commit is contained in:
jeremy bayse
2026-03-22 22:06:12 +01:00
parent 732d9416f4
commit 2df0d6def0
5 changed files with 105 additions and 20 deletions

View File

@@ -110,26 +110,9 @@ class AttemptController extends Controller
return redirect()->route('dashboard');
}
$attempt->load(['quiz.questions.options', 'answers']);
$score = 0;
$maxScore = $attempt->quiz->questions->sum('points');
foreach ($attempt->quiz->questions as $question) {
if ($question->type === 'qcm') {
$userAnswer = $attempt->answers->where('question_id', $question->id)->first();
if ($userAnswer && $userAnswer->option_id) {
$option = $question->options->where('id', $userAnswer->option_id)->first();
if ($option && $option->is_correct) {
$score += $question->points;
}
}
}
}
$this->recalculateScore($attempt);
$attempt->update([
'score' => $score,
'max_score' => $maxScore,
'finished_at' => now(),
]);
@@ -137,4 +120,47 @@ class AttemptController extends Controller
return redirect()->route('dashboard');
}
public function updateAnswerScore(Request $request, Answer $answer)
{
$this->authorizeAdmin();
$request->validate([
'score' => 'required|numeric|min:0'
]);
$answer->update(['score' => $request->score]);
$this->recalculateScore($answer->attempt);
return back()->with('success', 'Note mise à jour et score total recalculé.');
}
private function recalculateScore(Attempt $attempt)
{
$attempt->load(['quiz.questions.options', 'answers.option']);
$score = 0;
$maxScore = 0;
foreach ($attempt->quiz->questions as $question) {
$maxScore += $question->points;
$userAnswer = $attempt->answers->where('question_id', $question->id)->first();
if ($userAnswer) {
if ($question->type === 'qcm') {
if ($userAnswer->option && $userAnswer->option->is_correct) {
$score += $question->points;
}
} else if ($question->type === 'open') {
$score += (float) $userAnswer->score;
}
}
}
$attempt->update([
'score' => $score,
'max_score' => $maxScore,
]);
}
}

View File

@@ -8,11 +8,15 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
#[Fillable(['attempt_id', 'question_id', 'option_id', 'text_content'])]
#[Fillable(['attempt_id', 'question_id', 'option_id', 'text_content', 'score'])]
class Answer extends Model
{
use HasFactory;
protected $casts = [
'score' => 'float',
];
public function attempt(): BelongsTo
{
return $this->belongsTo(Attempt::class);