Akeneo permet de configurer des règles de devoirs en mode Hard qui bloquent totalement la création. Or certains cas légitimes (sorties scolaires, événements exceptionnels) nécessitent de passer outre ces règles. Sans mécanisme d'exception, l'enseignant est bloqué et doit contacter manuellement la direction. Cette implémentation ajoute un flux complet d'exception : l'enseignant justifie sa demande (min 20 caractères), le devoir est créé immédiatement, et la direction est notifiée par email. Le handler vérifie côté serveur que les règles sont réellement bloquantes avant d'accepter l'exception, empêchant toute fabrication de fausses exceptions via l'API. La direction dispose d'un rapport filtrable par période, enseignant et type de règle.
102 lines
3.7 KiB
PHP
102 lines
3.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Scolarite\Application\Command\CreateHomeworkWithException;
|
|
|
|
use App\Administration\Domain\Model\SchoolClass\ClassId;
|
|
use App\Administration\Domain\Model\Subject\SubjectId;
|
|
use App\Administration\Domain\Model\User\UserId;
|
|
use App\Scolarite\Application\Port\CurrentCalendarProvider;
|
|
use App\Scolarite\Application\Port\EnseignantAffectationChecker;
|
|
use App\Scolarite\Application\Port\HomeworkRulesChecker;
|
|
use App\Scolarite\Domain\Exception\EnseignantNonAffecteException;
|
|
use App\Scolarite\Domain\Exception\ExceptionNonNecessaireException;
|
|
use App\Scolarite\Domain\Model\Homework\Homework;
|
|
use App\Scolarite\Domain\Model\Homework\HomeworkRuleException;
|
|
use App\Scolarite\Domain\Repository\HomeworkRepository;
|
|
use App\Scolarite\Domain\Repository\HomeworkRuleExceptionRepository;
|
|
use App\Scolarite\Domain\Service\DueDateValidator;
|
|
use App\Shared\Domain\Clock;
|
|
use App\Shared\Domain\Tenant\TenantId;
|
|
use DateTimeImmutable;
|
|
use Doctrine\DBAL\Connection;
|
|
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
|
|
use Throwable;
|
|
|
|
#[AsMessageHandler(bus: 'command.bus')]
|
|
final readonly class CreateHomeworkWithExceptionHandler
|
|
{
|
|
public function __construct(
|
|
private HomeworkRepository $homeworkRepository,
|
|
private HomeworkRuleExceptionRepository $exceptionRepository,
|
|
private EnseignantAffectationChecker $affectationChecker,
|
|
private CurrentCalendarProvider $calendarProvider,
|
|
private DueDateValidator $dueDateValidator,
|
|
private HomeworkRulesChecker $rulesChecker,
|
|
private Clock $clock,
|
|
private Connection $connection,
|
|
) {
|
|
}
|
|
|
|
/**
|
|
* @return array{homework: Homework, exception: HomeworkRuleException}
|
|
*/
|
|
public function __invoke(CreateHomeworkWithExceptionCommand $command): array
|
|
{
|
|
$tenantId = TenantId::fromString($command->tenantId);
|
|
$classId = ClassId::fromString($command->classId);
|
|
$subjectId = SubjectId::fromString($command->subjectId);
|
|
$teacherId = UserId::fromString($command->teacherId);
|
|
$now = $this->clock->now();
|
|
|
|
if (!$this->affectationChecker->estAffecte($teacherId, $classId, $subjectId, $tenantId)) {
|
|
throw EnseignantNonAffecteException::pourClasseEtMatiere($teacherId, $classId, $subjectId);
|
|
}
|
|
|
|
$calendar = $this->calendarProvider->forCurrentYear($tenantId);
|
|
$dueDate = new DateTimeImmutable($command->dueDate);
|
|
$this->dueDateValidator->valider($dueDate, $now, $calendar);
|
|
|
|
$rulesResult = $this->rulesChecker->verifier($tenantId, $dueDate, $now);
|
|
|
|
if (!$rulesResult->estBloquant()) {
|
|
throw ExceptionNonNecessaireException::carReglesNonBloquantes();
|
|
}
|
|
|
|
$homework = Homework::creer(
|
|
tenantId: $tenantId,
|
|
classId: $classId,
|
|
subjectId: $subjectId,
|
|
teacherId: $teacherId,
|
|
title: $command->title,
|
|
description: $command->description,
|
|
dueDate: $dueDate,
|
|
now: $now,
|
|
);
|
|
|
|
$exception = HomeworkRuleException::demander(
|
|
tenantId: $tenantId,
|
|
homeworkId: $homework->id,
|
|
ruleTypes: $rulesResult->ruleTypes(),
|
|
justification: $command->justification,
|
|
createdBy: $teacherId,
|
|
now: $now,
|
|
);
|
|
|
|
$this->connection->beginTransaction();
|
|
|
|
try {
|
|
$this->homeworkRepository->save($homework);
|
|
$this->exceptionRepository->save($exception);
|
|
$this->connection->commit();
|
|
} catch (Throwable $e) {
|
|
$this->connection->rollBack();
|
|
|
|
throw $e;
|
|
}
|
|
|
|
return ['homework' => $homework, 'exception' => $exception];
|
|
}
|
|
}
|