mirror of
https://github.com/MarijnDoeve/TijdVoorDeTest.git
synced 2026-03-05 20:44:19 +01:00
Add correction management to backoffice, refactor security voter logic, and enhance candidate scoring
This commit introduces functionality to manage candidate corrections in the backoffice, with updated templates and a new route handler. The SeasonVoter is refactored to support additional entities, and scoring logic is updated to incorporate corrections consistently. Includes test coverage for voter logic and UI improvements for score tables.
This commit is contained in:
@@ -16,7 +16,7 @@ use Symfony\Component\Uid\Uuid;
|
||||
/**
|
||||
* @extends ServiceEntityRepository<Candidate>
|
||||
*
|
||||
* @phpstan-type Result array{id: Uuid, name: string, correct: int, time: \DateInterval, corrections?: float, score: float}
|
||||
* @phpstan-type Result array{id: Uuid, name: string, correct: int, time: \DateInterval, corrections: float, score: float}
|
||||
* @phpstan-type ResultList list<Result>
|
||||
*/
|
||||
class CandidateRepository extends ServiceEntityRepository
|
||||
@@ -54,40 +54,32 @@ class CandidateRepository extends ServiceEntityRepository
|
||||
/** @return ResultList */
|
||||
public function getScores(Quiz $quiz): array
|
||||
{
|
||||
$scoreQb = $this->createQueryBuilder('c', 'c.id')
|
||||
->select('c.id', 'c.name', 'sum(case when a.isRightAnswer = true then 1 else 0 end) as correct')
|
||||
$qb = $this->createQueryBuilder('c', 'c.id')
|
||||
->select('c.id', 'c.name', 'sum(case when a.isRightAnswer = true then 1 else 0 end) as correct', 'qc.corrections', 'max(ga.created) - qc.created as time')
|
||||
->join('c.givenAnswers', 'ga')
|
||||
->join('ga.answer', 'a')
|
||||
->where('ga.quiz = :quiz')
|
||||
->groupBy('c.id')
|
||||
->setParameter('quiz', $quiz);
|
||||
|
||||
$startTimeCorrectionQb = $this->createQueryBuilder('c', 'c.id')
|
||||
->select('c.id', 'qc.corrections', 'max(ga.created) - qc.created as time')
|
||||
->join('c.quizData', 'qc')
|
||||
->join('c.givenAnswers', 'ga')
|
||||
->where('qc.quiz = :quiz')
|
||||
->groupBy('ga.quiz', 'c.id', 'qc.id')
|
||||
->setParameter('quiz', $quiz);
|
||||
|
||||
$merged = array_merge_recursive(
|
||||
$scoreQb->getQuery()->getArrayResult(),
|
||||
$startTimeCorrectionQb->getQuery()->getArrayResult(),
|
||||
return $this->sortResults(
|
||||
$this->calculateScore(
|
||||
$qb->getQuery()->getResult(),
|
||||
),
|
||||
);
|
||||
|
||||
return $this->sortResults($this->calculateScore($merged));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, array{id: Uuid, name: string, correct: int, time: \DateInterval, corrections?: float}> $in
|
||||
* @param array<string, array{id: Uuid, name: string, correct: int, time: \DateInterval, corrections: float}> $in
|
||||
*
|
||||
* @return array<string, Result>
|
||||
* */
|
||||
*/
|
||||
private function calculateScore(array $in): array
|
||||
{
|
||||
return array_map(static fn ($candidate): array => [
|
||||
...$candidate,
|
||||
'score' => $candidate['correct'] + ($candidate['corrections'] ?? 0.0),
|
||||
'score' => $candidate['correct'] + $candidate['corrections'],
|
||||
], $in);
|
||||
}
|
||||
|
||||
|
||||
@@ -33,4 +33,15 @@ class QuizCandidateRepository extends ServiceEntityRepository
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function setCorrectionsForCandidate(Quiz $quiz, Candidate $candidate, float $corrections): void
|
||||
{
|
||||
$quizCandidate = $this->findOneBy(['candidate' => $candidate, 'quiz' => $quiz]);
|
||||
if (!$quizCandidate instanceof QuizCandidate) {
|
||||
throw new \InvalidArgumentException('Quiz candidate not found');
|
||||
}
|
||||
|
||||
$quizCandidate->setCorrections($corrections);
|
||||
$this->getEntityManager()->flush();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user