Commit 30b2512e authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Admission : utilisation d'une transaction globale pour la suppression d'un dossier d'admission.

parent 72d53746
Loading
Loading
Loading
Loading
+1 −0
Changes for CHANGELOG.md: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ Journal des modifications
- Inscriptions administratives importées : pas de création du doctorant si la création de la thèse est impossible.
- Saise d'une thèse : recherche/utilisation d'un éventuel doctorant existant en cas de création ; impossible de changer le doctorant d'une thèse existante ; meilleure remontée/affichage d'erreur.
- Admission : ajout du bouton de suppression d'un dossier d'admission dans le formulaire de modification.
- Admission : utilisation d'une transaction globale pour la suppression d'un dossier d'admission.
- [FIX] Formations suivies : les inscriptions sans réponse à l'enquête étaient écartées à tort.
- [FIX] Formations suivies : rétablissement de l'accès au dépôt de justificatif d'absence.
- [FIX] Inscriptions administratives importées : les liens historisés avec un doctorant n'étaient pas écartés.
+16 −17
Changes for module/Admission/src/Admission/Controller/AdmissionController.php: 16 added lines, 17 removed lines.
Original line number Diff line number Diff line
@@ -504,27 +504,26 @@ class AdmissionController extends AdmissionAbstractController
    public function supprimerAction(): HttpResponse
    {
        $admission = $this->getAdmission();
        /** @var Inscription $inscription */
        $inscription = $admission->getInscription()->first() ? $admission->getInscription()->first() : null;
        $admissionId = $admission->getId();
        $individu = $admission->getIndividu();
        try {
            $directeur = $inscription?->getDirecteur();
            $coDirecteur = $inscription?->getCoDirecteur();

            $this->admissionService->delete($admission);
            $this->admissionProcess->deleteAdmission($admission);

            //Suppression des rôles pour les directeurs/co-directeurs/candidat de thèse de ce dossier d'admission
            $this->gererRoleIndividu($individu, Role::ROLE_ID_ADMISSION_CANDIDAT);
            $this->gererRoleIndividu($directeur, Role::ROLE_ID_ADMISSION_DIRECTEUR_THESE);
            $this->gererRoleIndividu($coDirecteur, Role::ROLE_ID_ADMISSION_CODIRECTEUR_THESE);
        } catch (Exception $e) {
            $message = "Un problème est survenu lors de la suppression du dossier d'admission : " . $e->getMessage();
            error_log($message . PHP_EOL . $e->getTraceAsString());
            throw new RuntimeException($message, previous: $e);
            $this->multipageForm($this->admissionForm)->clear();
            $this->flashMessenger()->addSuccessMessage(sprintf(
                "Le dossier d'admission %d de %s a été supprimé avec succès",
                $admissionId,
                $individu
            ));
        }
        catch (Exception $e) {
            $this->flashMessenger()->addErrorMessage(sprintf(
                "La suppression du dossier d'admission %d de %s a échoué ! " . $e->getMessage(),
                $admission->getId(),
                $individu
            ));
        }

        $this->multipageForm($this->admissionForm)->clear();
        $this->flashMessenger()->addSuccessMessage("Le dossier d'admission de $individu a bien été supprimé");
        return $this->redirect()->toRoute('admission');
    }

@@ -629,7 +628,7 @@ class AdmissionController extends AdmissionAbstractController
                $this->documentService->createDocumentWithoutFichier($admission);

                //Ajout du rôle Candidat à la personne reliée au dossier d'admission
//                $this->gererRoleIndividu($individu, Role::ROLE_ID_ADMISSION_CANDIDAT);
                $this->gererRoleIndividu($individu, Role::ROLE_ID_ADMISSION_CANDIDAT);

                $this->flashMessenger()->addSuccessMessage("Les informations concernant l'étape précédente ont été ajoutées avec succès.");
            } catch (Exception $e) {
+87 −0
Changes for module/Admission/src/Admission/Service/Process/AdmissionProcess.php: 87 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -3,10 +3,21 @@
namespace Admission\Service\Process;

use Admission\Entity\Db\Admission;
use Admission\Entity\Db\Inscription;
use Admission\Service\Admission\AdmissionServiceAwareTrait;
use Admission\Service\Inscription\InscriptionServiceAwareTrait;
use Application\Entity\Db\Role;
use Application\Process\AbstractProcess;
use Application\Service\Role\ApplicationRoleServiceAwareTrait;
use Application\Service\Utilisateur\UtilisateurServiceAwareTrait;
use Doctorant\Service\DoctorantServiceAwareTrait;
use Exception;
use Individu\Entity\Db\Individu;
use Individu\Service\IndividuServiceAwareTrait;
use Structure\Entity\Db\EcoleDoctorale;
use Structure\Entity\Db\Etablissement;
use Structure\Entity\Db\Structure;
use Structure\Entity\Db\UniteRecherche;
use These\Entity\Db\These;
use These\Process\TheseProcessAwareTrait;
use Webmozart\Assert\Assert;
@@ -15,8 +26,84 @@ class AdmissionProcess extends AbstractProcess
{
    use AdmissionServiceAwareTrait;
    use DoctorantServiceAwareTrait;
    use InscriptionServiceAwareTrait;
    use IndividuServiceAwareTrait;
    use UtilisateurServiceAwareTrait;
    use ApplicationRoleServiceAwareTrait;
    use TheseProcessAwareTrait;

    /**
     * @throws \Admission\Service\Process\AdmissionProcessException
     */
    public function deleteAdmission(Admission $admission): void
    {
        /** @var Inscription $inscription */
        $inscription = $admission->getInscription()->first() ?: null;
        $individu = $admission->getIndividu();

        array_map(fn($o) => $this->entityManager->getUnitOfWork()->removeFromIdentityMap($o), $this->entityManager->getUnitOfWork()->getIdentityMap()[Role::class] ?? []);
        array_map(fn($o) => $this->entityManager->getUnitOfWork()->removeFromIdentityMap($o), $this->entityManager->getUnitOfWork()->getIdentityMap()[Structure::class] ?? []);
        array_map(fn($o) => $this->entityManager->getUnitOfWork()->removeFromIdentityMap($o), $this->entityManager->getUnitOfWork()->getIdentityMap()[Etablissement::class] ?? []);
        array_map(fn($o) => $this->entityManager->getUnitOfWork()->removeFromIdentityMap($o), $this->entityManager->getUnitOfWork()->getIdentityMap()[EcoleDoctorale::class] ?? []);
        array_map(fn($o) => $this->entityManager->getUnitOfWork()->removeFromIdentityMap($o), $this->entityManager->getUnitOfWork()->getIdentityMap()[UniteRecherche::class] ?? []);

        $this->entityManager->beginTransaction();
        try {
            $this->admissionService->delete($admission);

            // Suppression des rôles pour les directeurs/co-directeurs/candidat de thèse de ce dossier d'admission
            $this->deleteRoleIndividu($individu, Role::ROLE_ID_ADMISSION_CANDIDAT);
            if ($directeur = $inscription?->getDirecteur()) {
                $this->deleteRoleIndividu($directeur, Role::ROLE_ID_ADMISSION_DIRECTEUR_THESE);
            }
            if ($coDirecteur = $inscription?->getCoDirecteur()) {
                $this->deleteRoleIndividu($coDirecteur, Role::ROLE_ID_ADMISSION_CODIRECTEUR_THESE);
            }

            if ($comptesUtilisateurs = $individu->getUtilisateurs()) {
                $this->utilisateurService->supprimerUtilisateurs($comptesUtilisateurs);
            }
            $this->individuService->delete($individu);

            $this->entityManager->flush();
            $this->entityManager->commit();

        } catch (Exception $e) {
            $this->entityManager->rollback();

            $message = sprintf(
                "Un problème est survenu lors de la suppression du dossier d'admission %d : %s",
                $admission->getId(),
                $e->getMessage()
            );
            error_log($message . PHP_EOL . $e->getTraceAsString());
            throw new AdmissionProcessException($message, previous: $e);
        }


    }

    private function deleteRoleIndividu(Individu $individu, string $roleId): void
    {
        $role = $this->applicationRoleService->getRepository()->findOneBy(["roleId" => $roleId]);
        $hasRole = $this->applicationRoleService->findOneIndividuRole($individu, $role);
        if (!$hasRole) {
            return;
        }

        // Si l'individu possède ce rôle, on regarde s'il possède encore des dossiers d'admissions
        // si c'est non, on lui enlève le rôle
        $admissionsIndividu = null;
        if ($roleId === Role::ROLE_ID_ADMISSION_DIRECTEUR_THESE) {
            $admissionsIndividu = $this->inscriptionService->getRepository()->findBy(["directeur" => $individu]);
        } elseif ($roleId === Role::ROLE_ID_ADMISSION_CODIRECTEUR_THESE) {
            $admissionsIndividu = $this->inscriptionService->getRepository()->findBy(["coDirecteur" => $individu]);
        }
        if ($admissionsIndividu === null) {
            $this->applicationRoleService->removeRole($individu, $role);
        }
    }

    /**
     * @throws \Admission\Service\Process\AdmissionProcessException
     */
+23 −0
Changes for module/Admission/src/Admission/Service/Process/AdmissionProcessFactory.php: 23 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -3,7 +3,12 @@
namespace Admission\Service\Process;


use Admission\Service\Admission\AdmissionService;
use Admission\Service\Inscription\InscriptionService;
use Application\Service\Role\RoleService;
use Application\Service\Utilisateur\UtilisateurService;
use Doctorant\Service\DoctorantService;
use Individu\Service\IndividuService;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Psr\Container\ContainerInterface;
use These\Process\TheseProcess;
@@ -18,6 +23,9 @@ class AdmissionProcessFactory implements FactoryInterface
        $em = $container->get('doctrine.entitymanager.orm_default');
        $process->setEntityManager($em);

        $admissionService = $container->get(AdmissionService::class);
        $process->setAdmissionService($admissionService);

        /** @var DoctorantService $doctorantService */
        $doctorantService = $container->get(DoctorantService::class);
        $process->setDoctorantService($doctorantService);
@@ -26,6 +34,21 @@ class AdmissionProcessFactory implements FactoryInterface
        $theseProcess = $container->get(TheseProcess::class);
        $process->setTheseProcess($theseProcess);

        /** @var IndividuService $individuService */
        $individuService = $container->get(IndividuService::class);
        $process->setIndividuService($individuService);

        $utilisateurService = $container->get(UtilisateurService::class);
        $process->setUtilisateurService($utilisateurService);

        /** @var InscriptionService $inscriptionService */
        $inscriptionService = $container->get(InscriptionService::class);
        $process->setInscriptionService($inscriptionService);

        /** @var RoleService $roleService */
        $roleService = $container->get(RoleService::class);
        $process->setApplicationRoleService($roleService);

        return $process;
    }
}
 No newline at end of file
+3 −0
Changes for module/Application/src/Application/Entity/Db/Repository/RoleRepository.php: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -8,6 +8,9 @@ use Structure\Entity\Db\StructureConcreteInterface;
use Structure\Entity\Db\StructureInterface;
use UnicaenApp\Exception\RuntimeException;

/**
 * @method Role|null findOneBy(array $criteria, ?array $orderBy = null)
 */
class RoleRepository extends DefaultEntityRepository
{
    /**
Loading