feat: Permettre à l'enseignant de créer et gérer ses évaluations
Les enseignants avaient besoin de définir les critères de notation (barème, coefficient) avant de pouvoir saisir des notes. Sans cette brique, le module Notes & Évaluations (Epic 6) ne pouvait pas démarrer. L'évaluation est un agrégat du bounded context Scolarité avec deux Value Objects (GradeScale 1-100, Coefficient 0.1-10). Le barème est verrouillé dès qu'une note existe pour éviter les incohérences. Un port EvaluationGradesChecker (stub pour l'instant) sera branché sur le repository de notes dans la story 6.2.
This commit is contained in:
168
backend/src/Scolarite/Domain/Model/Evaluation/Evaluation.php
Normal file
168
backend/src/Scolarite/Domain/Model/Evaluation/Evaluation.php
Normal file
@@ -0,0 +1,168 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Scolarite\Domain\Model\Evaluation;
|
||||
|
||||
use App\Administration\Domain\Model\SchoolClass\ClassId;
|
||||
use App\Administration\Domain\Model\Subject\SubjectId;
|
||||
use App\Administration\Domain\Model\User\UserId;
|
||||
use App\Scolarite\Domain\Event\EvaluationCreee;
|
||||
use App\Scolarite\Domain\Event\EvaluationModifiee;
|
||||
use App\Scolarite\Domain\Event\EvaluationSupprimee;
|
||||
use App\Scolarite\Domain\Exception\BaremeNonModifiableException;
|
||||
use App\Scolarite\Domain\Exception\EvaluationDejaSupprimeeException;
|
||||
use App\Shared\Domain\AggregateRoot;
|
||||
use App\Shared\Domain\Tenant\TenantId;
|
||||
use DateTimeImmutable;
|
||||
|
||||
final class Evaluation extends AggregateRoot
|
||||
{
|
||||
public private(set) DateTimeImmutable $updatedAt;
|
||||
|
||||
private function __construct(
|
||||
public private(set) EvaluationId $id,
|
||||
public private(set) TenantId $tenantId,
|
||||
public private(set) ClassId $classId,
|
||||
public private(set) SubjectId $subjectId,
|
||||
public private(set) UserId $teacherId,
|
||||
public private(set) string $title,
|
||||
public private(set) ?string $description,
|
||||
public private(set) DateTimeImmutable $evaluationDate,
|
||||
public private(set) GradeScale $gradeScale,
|
||||
public private(set) Coefficient $coefficient,
|
||||
public private(set) EvaluationStatus $status,
|
||||
public private(set) DateTimeImmutable $createdAt,
|
||||
) {
|
||||
$this->updatedAt = $createdAt;
|
||||
}
|
||||
|
||||
public static function creer(
|
||||
TenantId $tenantId,
|
||||
ClassId $classId,
|
||||
SubjectId $subjectId,
|
||||
UserId $teacherId,
|
||||
string $title,
|
||||
?string $description,
|
||||
DateTimeImmutable $evaluationDate,
|
||||
GradeScale $gradeScale,
|
||||
Coefficient $coefficient,
|
||||
DateTimeImmutable $now,
|
||||
): self {
|
||||
$evaluation = new self(
|
||||
id: EvaluationId::generate(),
|
||||
tenantId: $tenantId,
|
||||
classId: $classId,
|
||||
subjectId: $subjectId,
|
||||
teacherId: $teacherId,
|
||||
title: $title,
|
||||
description: $description,
|
||||
evaluationDate: $evaluationDate,
|
||||
gradeScale: $gradeScale,
|
||||
coefficient: $coefficient,
|
||||
status: EvaluationStatus::PUBLISHED,
|
||||
createdAt: $now,
|
||||
);
|
||||
|
||||
$evaluation->recordEvent(new EvaluationCreee(
|
||||
evaluationId: $evaluation->id,
|
||||
classId: (string) $classId,
|
||||
subjectId: (string) $subjectId,
|
||||
teacherId: (string) $teacherId,
|
||||
title: $title,
|
||||
evaluationDate: $evaluationDate,
|
||||
occurredOn: $now,
|
||||
));
|
||||
|
||||
return $evaluation;
|
||||
}
|
||||
|
||||
public function modifier(
|
||||
string $title,
|
||||
?string $description,
|
||||
Coefficient $coefficient,
|
||||
DateTimeImmutable $evaluationDate,
|
||||
?GradeScale $gradeScale,
|
||||
bool $hasGrades,
|
||||
DateTimeImmutable $now,
|
||||
): void {
|
||||
if ($this->status === EvaluationStatus::DELETED) {
|
||||
throw EvaluationDejaSupprimeeException::withId($this->id);
|
||||
}
|
||||
|
||||
if ($gradeScale !== null && !$this->gradeScale->equals($gradeScale) && $hasGrades) {
|
||||
throw BaremeNonModifiableException::carNotesExistantes($this->id);
|
||||
}
|
||||
|
||||
$this->title = $title;
|
||||
$this->description = $description;
|
||||
$this->coefficient = $coefficient;
|
||||
$this->evaluationDate = $evaluationDate;
|
||||
|
||||
if ($gradeScale !== null && !$hasGrades) {
|
||||
$this->gradeScale = $gradeScale;
|
||||
}
|
||||
|
||||
$this->updatedAt = $now;
|
||||
|
||||
$this->recordEvent(new EvaluationModifiee(
|
||||
evaluationId: $this->id,
|
||||
title: $title,
|
||||
evaluationDate: $evaluationDate,
|
||||
occurredOn: $now,
|
||||
));
|
||||
}
|
||||
|
||||
public function supprimer(DateTimeImmutable $now): void
|
||||
{
|
||||
if ($this->status === EvaluationStatus::DELETED) {
|
||||
throw EvaluationDejaSupprimeeException::withId($this->id);
|
||||
}
|
||||
|
||||
$this->status = EvaluationStatus::DELETED;
|
||||
$this->updatedAt = $now;
|
||||
|
||||
$this->recordEvent(new EvaluationSupprimee(
|
||||
evaluationId: $this->id,
|
||||
occurredOn: $now,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Pour usage Infrastructure uniquement
|
||||
*/
|
||||
public static function reconstitute(
|
||||
EvaluationId $id,
|
||||
TenantId $tenantId,
|
||||
ClassId $classId,
|
||||
SubjectId $subjectId,
|
||||
UserId $teacherId,
|
||||
string $title,
|
||||
?string $description,
|
||||
DateTimeImmutable $evaluationDate,
|
||||
GradeScale $gradeScale,
|
||||
Coefficient $coefficient,
|
||||
EvaluationStatus $status,
|
||||
DateTimeImmutable $createdAt,
|
||||
DateTimeImmutable $updatedAt,
|
||||
): self {
|
||||
$evaluation = new self(
|
||||
id: $id,
|
||||
tenantId: $tenantId,
|
||||
classId: $classId,
|
||||
subjectId: $subjectId,
|
||||
teacherId: $teacherId,
|
||||
title: $title,
|
||||
description: $description,
|
||||
evaluationDate: $evaluationDate,
|
||||
gradeScale: $gradeScale,
|
||||
coefficient: $coefficient,
|
||||
status: $status,
|
||||
createdAt: $createdAt,
|
||||
);
|
||||
|
||||
$evaluation->updatedAt = $updatedAt;
|
||||
|
||||
return $evaluation;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user