Commit b605c9a5 authored by Bertrand Gauthier's avatar Bertrand Gauthier
Browse files

Soutenance Thèse : ajout d'une alerte quand une association membre=>acteur est...

Soutenance Thèse : ajout d'une alerte quand une association membre=>acteur est incorrecte en raison du rôle inadéquat de l'acteur.
parent 719f3080
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ Journal des modifications
- [FIX] Formation : plantage lors de l'ouverture de la page de modification d'une Formation.
- [FIX] Script de purge des fichiers temporaires : correction pour ce qui concerne la génération XML/TEF (envoi vers step-star). 
- Indicateur au format Thèse : inclusion de la colonne 'etat_these' et d'une colonne facultative 'extra'.
- Soutenance Thèse : ajout d'une alerte quand une association membre=>acteur est incorrecte en raison du rôle inadéquat de l'acteur.

10.4.0
------
+2 −1
Original line number Diff line number Diff line
@@ -44,7 +44,8 @@ abstract class AbstractActeurRepository extends DefaultEntityRepository
    public function findActeurByEntity(These|HDR $entity): array
    {
        $qb = $this->createQueryBuilder('a')
            ->addSelect('role')->join('a.role', 'role');
            ->addSelect('role')->join('a.role', 'role')
            ->andWhereNotHistorise('a');

        if ($entity instanceof These) {
            $qb->andWhere('a.these = :entity');
+6 −7
Original line number Diff line number Diff line
@@ -77,8 +77,7 @@ class PresoutenanceAssertion extends AbstractAssertion
                case PresoutenancePrivileges::PRESOUTENANCE_DATE_RETOUR_MODIFICATION:
                    $etatObject = $this->entity instanceof These ? $this->entity->getEtatThese() : $this->entity->getEtatHDR();
                    if ($etatObject === These::ETAT_SOUTENUE || $etatObject === HDR::ETAT_SOUTENUE) return false;
                    $role = $this->userContextService->getSelectedIdentityRole();
                    return (($role->getCode() === Role::CODE_BDD || Role::CODE_GEST_HDR) && $role->getStructure() === $this->entity->getEtablissement()->getStructure());
                    return true;
                case HDRPrivileges::HDR_DONNER_RESULTAT:
                case ThesePrivileges::THESE_DONNER_RESULTAT:
                    /** @var Proposition $p */
+15 −58
Original line number Diff line number Diff line
@@ -94,73 +94,32 @@ abstract class PresoutenanceController extends AbstractSoutenanceController
    }

    /**
     * Ici on affecte au membre des acteurs qui remonte des SIs des établissements
     * Puis on affecte les rôles rapporteurs et membres
     * QUID :: Président ...
     * Création du lien entre la saisie libre d'un membre du jury et un acteur de thèse importé du SI de l'établissement.
     */
    public function associerJuryAction() : ViewModel
    {
        $this->initializeFromType(false, false);

        /** @var Membre[] $membres */
//        $membres = $this->proposition->getMembres();
        $membre = $this->getMembreService()->getRequestedMembre($this);
        $membre = $this->membreService->getRequestedMembre($this);

        /** Ici, on prépare la liste des acteurs correspondant aux différents rôles pour le Select du formulaire
         *  d'association. On part du principe :
         *  - qu'un Rapporteur du jury est Rapporteur et Membre du jury,
         *  - qu'un Rapporteur absent est Rapporteur,
         *  - qu'un Membre du jury est Membre du jury.
         */
        // Préparation de la liste des acteurs sélectionnables en fonction du rôle du membre
        $acteurs = $this->type === Proposition::ROUTE_PARAM_PROPOSITION_THESE ?
            $this->acteurService->getRepository()->findActeurByThese($this->entity) :
            $this->acteurService->getRepository()->findActeurByHDR($this->entity);
        $acteurs = array_filter($acteurs, function (ActeurThese|ActeurHDR $a) { return $a->estNonHistorise();});
        switch ($membre->getRole()) {
            case Membre::RAPPORTEUR_JURY :
            case Membre::RAPPORTEUR_VISIO :
                $acteurs = array_filter($acteurs, function (ActeurThese|ActeurHDR $a) {
                    /** @var Profil $profil */
                    $profil = $a->getRole()->getProfil();
                    return $profil?->getRoleCode() === 'R';
                });
                break;
            case Membre::RAPPORTEUR_ABSENT :
                $acteurs = array_filter($acteurs, function (ActeurThese|ActeurHDR $a) {
                    /** @var Profil $profil */
                    $profil = $a->getRole()->getProfil();
                    return $profil?->getRoleCode() === 'R';
                });
                break;
            case Membre::MEMBRE_JURY :
                $acteurs = array_filter($acteurs, function (ActeurThese|ActeurHDR $a) {
                    /** @var Profil $profil */
                    $profil = $a->getRole()->getProfil();
                    return $profil?->getRoleCode() === 'M';
                });
                break;
        }

        $acteurs_libres = [];
        /** @var ActeurThese|ActeurHDR $acteur */
        $roleActeur = Membre::ROLE_MEMBRE_TO_ROLE_ACTEUR[$membre->getRole()] ?? null;
        if ($roleActeur) {
            $acteurs = array_filter($acteurs,
                fn(ActeurThese|ActeurHDR $a) => $a->getRole()->getCode() === $roleActeur
            );
        }
        $acteursDisponibles = [];
        foreach ($acteurs as $acteur) {
            // à avoir si ça pose des problèmes
            // si l'acteur n'est pas encore associé à un membre,
            // ou que la proposition associée au membre n'est pas la même que celle actuelle
            // Un acteur est sélectionnable/disponible s'il n'est pas encore associé à un membre,
            // ou si la proposition associée au membre n'est pas la même que celle actuelle
            // (dans le cas d'une première prop. rejetée)
            if (!$acteur->getMembre() || $acteur->getMembre()->getProposition()->getId() !== $this->proposition->getId()) {
                $acteurs_libres[] = $acteur;
            }
//            $libre = true;
//            foreach ($membres as $membre_) {
//                $acteur_ = $this->acteurService->getRepository()->findActeurForSoutenanceMembre($membre_);
////                if ($membre_->getActeur() && $membre_->getActeur()->getId() === $acteur->getId()) {
//                if ($acteur_ && $acteur_->getId() === $acteur->getId()) {
//                    $libre = false;
//                    break;
//                }
//            }
//            if ($libre) $acteurs_libres[] = $acteur;
                $acteursDisponibles[] = $acteur;
            }
        }

        $request = $this->getRequest();
@@ -172,9 +131,6 @@ abstract class PresoutenanceController extends AbstractSoutenanceController

            if (! isset($acteur)) throw new RuntimeException("Aucun acteur à associer !");

//            //mise à jour du membre de soutenance
//            $membre->setActeur($acteur);
//            $this->getMembreService()->update($membre);
            $acteur->setMembre($membre);
            $this->acteurService->save($acteur);
            $this->flashMessenger()->addSuccessMessage($membre->getDenomination()." a bien été associé à un acteur.");
@@ -190,11 +146,12 @@ abstract class PresoutenanceController extends AbstractSoutenanceController
        $vm->setTemplate('soutenance/presoutenance/associer-jury');
        $vm->setVariables([
            'title' => "Association de " . $membre->getDenomination() . " à un acteur " . $this->appInfos()->getNom(),
            'acteurs' => $acteurs_libres,
            'acteurs' => $acteursDisponibles,
            'membre' => $membre,
            'entity' => $this->entity,
            'typeProposition' => $this->type
        ]);

        return $vm;
    }

+26 −1
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ class PresoutenanceTheseController extends PresoutenanceController
        $this->initializeFromType();

        /** @var Membre[] $membres */
        $membres = $this->proposition->getMembres()->toArray();
        $membres = $this->membreService->findMembresForProposition($this->proposition);
        $acteursMembres = $this->acteurService->getRepository()->findActeursForSoutenanceMembres($membres);

        $rapporteurs = $this->propositionService->getRapporteurs($this->proposition);
@@ -88,6 +88,30 @@ class PresoutenanceTheseController extends PresoutenanceController
        $validationBDD = $this->validationService->getRepository()->findValidationByCodeAndThese(TypeValidation::CODE_VALIDATION_PROPOSITION_BDD, $this->entity);
        $validationPDC = $this->validationService->getRepository()->findValidationByCodeAndThese(TypeValidation::CODE_PAGE_DE_COUVERTURE, $this->entity);

        // alerte en cas de membre associé à un acteur dont le rôle ne colle plus
        /** @var ActeurThese $acteur */
        $alertesAssociation = [];
        foreach (array_filter($acteursMembres) as $membreId => $acteur) {
            $membre = $membres[$membreId];
            $codeRoleAttendu = Membre::ROLE_MEMBRE_TO_ROLE_ACTEUR[$membre->getRole()] ?? null;
            if ($codeRoleAttendu === null) {
                continue;
            }
            if ($acteur->getRole()->getCode() !== $codeRoleAttendu) {
                $roleAttendu = $this->applicationRoleService->getRepo()->findOneByCodeAndStructureConcrete($codeRoleAttendu, $this->entity->getEtablissement());
                $alertesAssociation[$membreId] = sprintf(
                    "L'association du membre « %s / %s » à l'acteur « %s / %s » (id %d) est incorrecte, " .
                    "elle devrait être faite avec un acteur ayant le rôle « %s ».",
                    $membre->getDenomination(),
                    $membre->getRole(),
                    $acteur->getIndividu(),
                    $acteur->getRole(),
                    $acteur->getId(),
                    $roleAttendu,
                );
            }
        }

        /** Parametres ---------------------------------------------------------------------------------------------- */
        try {
            $deadline = $this->parametreService->getValeurForParametre(SoutenanceParametres::CATEGORIE, SoutenanceParametres::DELAI_RETOUR);
@@ -116,6 +140,7 @@ class PresoutenanceTheseController extends PresoutenanceController
            'validationPDC' => $validationPDC,
            'justificatifsOk' => $justificatifsOk,
            'justificatifs' => $justificatifs,
            'alertesAssociation' => $alertesAssociation,

            'deadline' => $deadline,

Loading