mirror of
https://github.com/MarijnDoeve/TijdVoorDeTest.git
synced 2026-07-05 15:10:16 +02:00
Answer on candidate (#72)
* Add Penalty Seconds on tests * Refactors and start of candidate answer relation * Add breadcrumbs and UI consistency updates across backoffice templates * Add breadcrumbs and UI consistency updates across backoffice templates * Add Dutch translations for email verification and security messages * Rector * Refactor for code consistency and type safety assertions across repositories and entities * Refactor candidate-related logic to optimize queries, improve template separation, and add "Answer Mapping" functionality. * Cleanup * Update Symfony * Add coderabbit config * Fixes from coderabbit
This commit is contained in:
@@ -9,6 +9,7 @@ use Doctrine\Persistence\ManagerRegistry;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Safe\DateTimeImmutable;
|
||||
use Safe\Exceptions\DatetimeException;
|
||||
use Symfony\Component\Uid\Uuid;
|
||||
use Tvdt\Dto\Result;
|
||||
use Tvdt\Entity\Quiz;
|
||||
use Tvdt\Exception\ErrorClearingQuizException;
|
||||
@@ -81,26 +82,86 @@ class QuizRepository extends ServiceEntityRepository
|
||||
c.name,
|
||||
sum(case when a.isRightAnswer = true then 1 else 0 end) as correct,
|
||||
qd.corrections,
|
||||
qd.penaltySeconds,
|
||||
max(ga.created) as end_time,
|
||||
qd.created as start_time,
|
||||
qd.started as start_time,
|
||||
(sum(case when a.isRightAnswer = true then 1 else 0 end) + qd.corrections) as score
|
||||
from Tvdt\Entity\Candidate c
|
||||
join c.givenAnswers ga
|
||||
join ga.answer a
|
||||
join c.quizData qd
|
||||
where qd.quiz = :quiz and ga.quiz = :quiz
|
||||
where qd.quiz = :quiz and ga.quiz = :quiz and qd.started is not null
|
||||
group by ga.quiz, c.id, qd.id
|
||||
order by score desc, max(ga.created) - qd.created asc
|
||||
order by score desc, max(ga.created) - qd.started asc
|
||||
DQL
|
||||
)->setParameter('quiz', $quiz)->getResult();
|
||||
|
||||
return array_map(static fn (array $row): Result => new Result(
|
||||
id: $row['id'],
|
||||
name: $row['name'],
|
||||
correct: (int) $row['correct'],
|
||||
corrections: $row['corrections'],
|
||||
time: $row['start_time']->diff(new DateTimeImmutable($row['end_time'])),
|
||||
score: $row['score'],
|
||||
), $result);
|
||||
return array_map(static function (array $row): Result {
|
||||
\assert($row['start_time'] instanceof \DateTimeImmutable);
|
||||
|
||||
return new Result(
|
||||
id: $row['id'],
|
||||
name: $row['name'],
|
||||
correct: (int) $row['correct'],
|
||||
corrections: $row['corrections'],
|
||||
penaltySeconds: $row['penaltySeconds'],
|
||||
time: $row['start_time']->diff(new DateTimeImmutable($row['end_time'])),
|
||||
score: $row['score'],
|
||||
);
|
||||
}, $result);
|
||||
}
|
||||
|
||||
public function fetchWithQuestions(Uuid $id): Quiz
|
||||
{
|
||||
return $this->getEntityManager()->createQuery(<<<dql
|
||||
select q, qz, a from Tvdt\Entity\Quiz q
|
||||
join q.questions qz
|
||||
join qz.answers a
|
||||
where q.id = :id
|
||||
dql)->setParameter('id', $id)->getSingleResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch quiz with all relations needed for error checking.
|
||||
* This includes: questions, answers, answer candidates, and season candidates.
|
||||
*/
|
||||
public function fetchWithQuestionsAndCandidates(Uuid $id): Quiz
|
||||
{
|
||||
return $this->getEntityManager()->createQuery(<<<dql
|
||||
select q, qz, a, ac, s, sc, qc from Tvdt\Entity\Quiz q
|
||||
join q.questions qz
|
||||
join qz.answers a
|
||||
left join a.candidates ac
|
||||
join q.season s
|
||||
left join s.candidates sc
|
||||
left join q.candidateData qc
|
||||
where q.id = :id
|
||||
dql)->setParameter('id', $id)->getSingleResult();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get given answers count per candidate for a quiz.
|
||||
*
|
||||
* @return array<string, int> Array with candidate ID as key and count as value
|
||||
*/
|
||||
public function getGivenAnswersCountPerCandidate(Quiz $quiz): array
|
||||
{
|
||||
$results = $this->getEntityManager()->createQuery(<<<DQL
|
||||
select c.id as candidateId, count(ga.id) as answerCount
|
||||
from Tvdt\Entity\Candidate c
|
||||
left join c.givenAnswers ga with ga.quiz = :quiz
|
||||
where c.season = :season
|
||||
group by c.id
|
||||
DQL
|
||||
)->setParameter('quiz', $quiz)
|
||||
->setParameter('season', $quiz->season)
|
||||
->getResult();
|
||||
|
||||
$counts = [];
|
||||
foreach ($results as $row) {
|
||||
$counts[$row['candidateId']->toString()] = (int) $row['answerCount'];
|
||||
}
|
||||
|
||||
return $counts;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user