feat: Gestion des classes scolaires
Permet aux administrateurs de créer, modifier et supprimer des classes pour organiser les élèves par niveau. L'archivage soft-delete préserve l'historique tout en masquant les classes obsolètes. Inclut la validation des noms (2-50 caractères), les niveaux scolaires du CP à la Terminale, et les contrôles d'accès par rôle.
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Application\Command\CreateClass;
|
||||
|
||||
/**
|
||||
* Command pour créer une nouvelle classe scolaire.
|
||||
*/
|
||||
final readonly class CreateClassCommand
|
||||
{
|
||||
public function __construct(
|
||||
public string $tenantId,
|
||||
public string $schoolId,
|
||||
public string $academicYearId,
|
||||
public string $name,
|
||||
public ?string $level,
|
||||
public ?int $capacity,
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Application\Command\CreateClass;
|
||||
|
||||
use App\Administration\Domain\Exception\ClasseDejaExistanteException;
|
||||
use App\Administration\Domain\Model\SchoolClass\AcademicYearId;
|
||||
use App\Administration\Domain\Model\SchoolClass\ClassName;
|
||||
use App\Administration\Domain\Model\SchoolClass\SchoolClass;
|
||||
use App\Administration\Domain\Model\SchoolClass\SchoolId;
|
||||
use App\Administration\Domain\Model\SchoolClass\SchoolLevel;
|
||||
use App\Administration\Domain\Repository\ClassRepository;
|
||||
use App\Shared\Domain\Clock;
|
||||
use App\Shared\Domain\Tenant\TenantId;
|
||||
use Symfony\Component\Messenger\Attribute\AsMessageHandler;
|
||||
|
||||
/**
|
||||
* Handler pour créer une nouvelle classe scolaire.
|
||||
*/
|
||||
#[AsMessageHandler(bus: 'command.bus')]
|
||||
final readonly class CreateClassHandler
|
||||
{
|
||||
public function __construct(
|
||||
private ClassRepository $classRepository,
|
||||
private Clock $clock,
|
||||
) {
|
||||
}
|
||||
|
||||
public function __invoke(CreateClassCommand $command): SchoolClass
|
||||
{
|
||||
$tenantId = TenantId::fromString($command->tenantId);
|
||||
$academicYearId = AcademicYearId::fromString($command->academicYearId);
|
||||
$name = new ClassName($command->name);
|
||||
|
||||
// Vérifier l'unicité du nom dans le tenant et l'année scolaire
|
||||
$existingClass = $this->classRepository->findByName($name, $tenantId, $academicYearId);
|
||||
if ($existingClass !== null) {
|
||||
throw ClasseDejaExistanteException::avecNom($name);
|
||||
}
|
||||
|
||||
$class = SchoolClass::creer(
|
||||
tenantId: $tenantId,
|
||||
schoolId: SchoolId::fromString($command->schoolId),
|
||||
academicYearId: $academicYearId,
|
||||
name: $name,
|
||||
level: $command->level !== null ? SchoolLevel::from($command->level) : null,
|
||||
capacity: $command->capacity,
|
||||
createdAt: $this->clock->now(),
|
||||
);
|
||||
|
||||
$this->classRepository->save($class);
|
||||
|
||||
return $class;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Application\Command\CreateClass;
|
||||
|
||||
/**
|
||||
* Résultat de la création d'une classe.
|
||||
*/
|
||||
final readonly class CreateClassResult
|
||||
{
|
||||
public function __construct(
|
||||
public string $classId,
|
||||
public string $name,
|
||||
public ?string $level,
|
||||
public ?int $capacity,
|
||||
) {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user