Add Penalty Seconds on tests

This commit is contained in:
2026-03-07 21:56:19 +01:00
parent ac46f380cb
commit 6d3402b8e3
7 changed files with 83 additions and 0 deletions
+31
View File
@@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20260125191247 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}
public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE quiz_candidate ADD penalty_seconds SMALLINT DEFAULT 0 NOT NULL');
}
public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE quiz_candidate DROP penalty_seconds');
}
}
@@ -117,4 +117,23 @@ class QuizController extends AbstractController
return $this->redirectToRoute('tvdt_backoffice_quiz', ['seasonCode' => $quiz->season->seasonCode, 'quiz' => $quiz->id]);
}
#[IsGranted(SeasonVoter::EDIT, subject: 'quiz')]
#[Route(
'/backoffice/quiz/{quiz}/candidate/{candidate}/modify_penalty',
name: 'tvdt_backoffice_modify_penalty',
requirements: ['quiz' => Requirement::UUID, 'candidate' => Requirement::UUID],
)]
public function modifyPenalty(Quiz $quiz, Candidate $candidate, Request $request): RedirectResponse
{
if (!$request->isMethod('POST')) {
throw new MethodNotAllowedHttpException(['POST']);
}
$penalty = (int) $request->request->get('penalty');
$this->quizCandidateRepository->setPenaltyForCandidate($quiz, $candidate, $penalty);
return $this->redirectToRoute('tvdt_backoffice_quiz', ['seasonCode' => $quiz->season->seasonCode, 'quiz' => $quiz->id]);
}
}
+1
View File
@@ -13,6 +13,7 @@ final readonly class Result
public string $name,
public int $correct,
public float $corrections,
public int $penaltySeconds,
public \DateInterval $time,
public float $score,
) {}
+3
View File
@@ -24,6 +24,9 @@ class QuizCandidate
#[ORM\Column]
public float $corrections = 0;
#[ORM\Column(type: Types::SMALLINT, options: ['default' => 0])]
public int $penaltySeconds = 0;
#[Gedmo\Timestampable(on: 'create')]
#[ORM\Column(type: Types::DATETIMETZ_IMMUTABLE)]
public private(set) \DateTimeImmutable $created;
@@ -44,4 +44,15 @@ class QuizCandidateRepository extends ServiceEntityRepository
$quizCandidate->corrections = $corrections;
$this->getEntityManager()->flush();
}
public function setPenaltyForCandidate(Quiz $quiz, Candidate $candidate, int $penalty): void
{
$quizCandidate = $this->findOneBy(['candidate' => $candidate, 'quiz' => $quiz]);
if (!$quizCandidate instanceof QuizCandidate) {
throw new \InvalidArgumentException('Quiz candidate not found');
}
$quizCandidate->penaltySeconds = $penalty;
$this->getEntityManager()->flush();
}
}
+2
View File
@@ -81,6 +81,7 @@ 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,
(sum(case when a.isRightAnswer = true then 1 else 0 end) + qd.corrections) as score
@@ -99,6 +100,7 @@ class QuizRepository extends ServiceEntityRepository
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);
+16
View File
@@ -84,6 +84,7 @@
<th scope="col">{{ 'Candidate'|trans }}</th>
<th style="width: 15%" scope="col">{{ 'Correct Answers'|trans }}</th>
<th style="width: 20%" scope="col">{{ 'Corrections'|trans }}</th>
<th style="width: 20%" scope="col">{{ 'Penalty'|trans }}</th>
<th style="width: 10%" scope="col">{{ 'Score'|trans }}</th>
<th style="width: 20%" scope="col">{{ 'Time'|trans }}</th>
</tr>
@@ -108,6 +109,21 @@
</div>
</form>
</td>
<td>
<form method="post"
action="{{ path('tvdt_backoffice_modify_penalty', {quiz: quiz.id, candidate: candidate.id}) }}">
<div class="row">
<div class="col-8">
<input class="form-control form-control-sm" type="number"
value="{{ candidate.penaltySeconds }}" step="1"
name="penalty">
</div>
<div class="col-2">
<button class="btn btn-sm btn-primary" type="submit">{{ 'Save'|trans }}</button>
</div>
</div>
</form>
</td>
<td>{{ candidate.score|default('x') }}</td>
<td>{{ candidate.time.format('%i:%S') }}</td>
</tr>