updatedAt = $createdAt; } /** * Crée une nouvelle classe scolaire. */ public static function creer( TenantId $tenantId, SchoolId $schoolId, AcademicYearId $academicYearId, ClassName $name, ?SchoolLevel $level, ?int $capacity, DateTimeImmutable $createdAt, ): self { $class = new self( id: ClassId::generate(), tenantId: $tenantId, schoolId: $schoolId, academicYearId: $academicYearId, name: $name, level: $level, capacity: $capacity, status: ClassStatus::ACTIVE, createdAt: $createdAt, ); $class->recordEvent(new ClasseCreee( classId: $class->id, tenantId: $class->tenantId, name: $class->name, level: $class->level, occurredOn: $createdAt, )); return $class; } /** * Renomme la classe. */ public function renommer(ClassName $nouveauNom, DateTimeImmutable $at): void { if ($this->name->equals($nouveauNom)) { return; } $ancienNom = $this->name; $this->name = $nouveauNom; $this->updatedAt = $at; $this->recordEvent(new ClasseModifiee( classId: $this->id, tenantId: $this->tenantId, ancienNom: $ancienNom, nouveauNom: $nouveauNom, occurredOn: $at, )); } /** * Modifie le niveau scolaire de la classe. */ public function changerNiveau(?SchoolLevel $niveau, DateTimeImmutable $at): void { if ($this->level === $niveau) { return; } $this->level = $niveau; $this->updatedAt = $at; $this->recordEvent(new ClasseModifiee( classId: $this->id, tenantId: $this->tenantId, ancienNom: $this->name, nouveauNom: $this->name, occurredOn: $at, )); } /** * Modifie la capacité maximale de la classe. */ public function changerCapacite(?int $capacity, DateTimeImmutable $at): void { if ($this->capacity === $capacity) { return; } $this->capacity = $capacity; $this->updatedAt = $at; } /** * Ajoute ou modifie la description de la classe. */ public function decrire(?string $description, DateTimeImmutable $at): void { $this->description = $description; $this->updatedAt = $at; } /** * Archive la classe (soft delete). * * Note: La vérification des élèves affectés doit être faite par l'Application Layer * via une Query avant d'appeler cette méthode. */ public function archiver(DateTimeImmutable $at): void { if ($this->status === ClassStatus::ARCHIVED) { return; } $this->status = ClassStatus::ARCHIVED; $this->deletedAt = $at; $this->updatedAt = $at; $this->recordEvent(new ClasseArchivee( classId: $this->id, tenantId: $this->tenantId, occurredOn: $at, )); } /** * Vérifie si la classe est active. */ public function estActive(): bool { return $this->status === ClassStatus::ACTIVE; } /** * Vérifie si la classe peut recevoir des élèves. */ public function peutRecevoirEleves(): bool { return $this->status->peutRecevoirEleves(); } /** * Reconstitue une SchoolClass depuis le stockage. * * @internal Pour usage Infrastructure uniquement */ public static function reconstitute( ClassId $id, TenantId $tenantId, SchoolId $schoolId, AcademicYearId $academicYearId, ClassName $name, ?SchoolLevel $level, ?int $capacity, ClassStatus $status, ?string $description, DateTimeImmutable $createdAt, DateTimeImmutable $updatedAt, ?DateTimeImmutable $deletedAt, ): self { $class = new self( id: $id, tenantId: $tenantId, schoolId: $schoolId, academicYearId: $academicYearId, name: $name, level: $level, capacity: $capacity, status: $status, createdAt: $createdAt, ); $class->description = $description; $class->updatedAt = $updatedAt; $class->deletedAt = $deletedAt; return $class; } }