Loading CHANGELOG.md +1 −0 Changes for CHANGELOG.md: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ Journal des modifications ----- - [FIX] Recherche de rapports d'Activité/CSI/Mi-parcours : les filtres Établissement/ED/UR géraient mal la subsitution de structures. - Changement de la page de couverture pour tenir compte de la co-accréditation - Module Soutenance : Possibilité pour les structures de révoquer leur validation (avec modal de confirmation) 6.0.3 ----- Loading doc/release-notes/v6.0.4.md +48 −1 Changes for doc/release-notes/v6.0.4.md: 48 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -19,4 +19,51 @@ systemctl reload php8.0-fpm ## 2. Dans la base de données Néant. No newline at end of file ```postgresql -- Ajout du privilège pour revoquer INSERT INTO privilege (categorie_id, code, libelle, ordre) WITH d(code, lib, ordre) AS ( SELECT 'proposition-revoquer-structure', 'Révoquer la validation (structure) de la proposition', 34 ) SELECT cp.id, d.code, d.lib, d.ordre FROM d JOIN categorie_privilege cp ON cp.CODE = 'soutenance'; --Ajout au profil INSERT INTO PROFIL_PRIVILEGE (PRIVILEGE_ID, PROFIL_ID) with data(categ, priv) as ( select 'soutenance'::text, 'proposition-revoquer-structure'::text ) select p.id as PRIVILEGE_ID, profil.id as PROFIL_ID from data join PROFIL on profil.ROLE_ID in ('RESP_ED', 'RESP_UR', 'BDD') join CATEGORIE_PRIVILEGE cp on cp.CODE = data.categ join PRIVILEGE p on p.CATEGORIE_ID = cp.id and p.code = data.priv where not exists ( select * from PROFIL_PRIVILEGE where PRIVILEGE_ID = p.id and PROFIL_ID = profil.id ); INSERT INTO PROFIL_PRIVILEGE (PRIVILEGE_ID, PROFIL_ID) with data(categ, priv) as ( select 'missionenseignement'::text, 'missionenseignement_modifier'::text ) select p.id as PRIVILEGE_ID, profil.id as PROFIL_ID from data join PROFIL on profil.ROLE_ID in ('ADMIN_TECH', 'GEST_FORMATION', 'BDD', 'ADMIN') join CATEGORIE_PRIVILEGE cp on cp.CODE = data.categ join PRIVILEGE p on p.CATEGORIE_ID = cp.id and p.code = data.priv where not exists ( select * from PROFIL_PRIVILEGE where PRIVILEGE_ID = p.id and PROFIL_ID = profil.id ); insert into ROLE_PRIVILEGE (ROLE_ID, PRIVILEGE_ID) select p2r.ROLE_ID, pp.PRIVILEGE_ID from PROFIL_TO_ROLE p2r join profil pr on pr.id = p2r.PROFIL_ID join PROFIL_PRIVILEGE pp on pp.PROFIL_ID = pr.id where not exists ( select * from role_privilege where role_id = p2r.role_id and privilege_id = pp.privilege_id ); ``` No newline at end of file module/Soutenance/config/others/proposition.config.php +24 −0 Changes for module/Soutenance/config/others/proposition.config.php: 24 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ return [ PropositionPrivileges::PROPOSITION_VALIDER_ED, PropositionPrivileges::PROPOSITION_VALIDER_UR, PropositionPrivileges::PROPOSITION_VALIDER_BDD, PropositionPrivileges::PROPOSITION_REVOQUER_STRUCTURE, PropositionPrivileges::PROPOSITION_PRESIDENCE, PropositionPrivileges::PROPOSITION_DECLARATION_HONNEUR_VALIDER, Loading Loading @@ -137,6 +138,15 @@ return [ PropositionPrivileges::PROPOSITION_VALIDER_BDD, ], ], [ 'controller' => PropositionController::class, 'action' => [ 'revoquer-structure', ], 'privileges' => [ PropositionPrivileges::PROPOSITION_REVOQUER_STRUCTURE, ], ], [ 'controller' => PropositionController::class, 'action' => [ Loading Loading @@ -378,17 +388,31 @@ return [ 'options' => [ 'route' => '/valider-structure', 'defaults' => [ /** @see PropositionController::validerStructureAction() */ 'controller' => PropositionController::class, 'action' => 'valider-structure', ], ], ], 'revoquer-structure' => [ 'type' => Segment::class, 'may_terminate' => true, 'options' => [ 'route' => '/revoquer-structure', 'defaults' => [ /** @see PropositionController::revoquerStructureAction() */ 'controller' => PropositionController::class, 'action' => 'revoquer-structure', ], ], ], 'refuser-structure' => [ 'type' => Segment::class, 'may_terminate' => true, 'options' => [ 'route' => '/refuser-PropositionController', 'defaults' => [ /** @see PropositionController::refuserStructureAction() */ 'controller' => PropositionController::class, 'action' => 'refuser-structure', ], Loading module/Soutenance/src/Soutenance/Assertion/PropositionAssertion.php +16 −0 Changes for module/Soutenance/src/Soutenance/Assertion/PropositionAssertion.php: 16 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ namespace Soutenance\Assertion; use Soutenance\Entity\Etat; use These\Entity\Db\Acteur; use Application\Entity\Db\Role; use These\Entity\Db\These; Loading Loading @@ -211,6 +212,21 @@ class PropositionAssertion implements AssertionInterface { default: return false; } case PropositionPrivileges::PROPOSITION_REVOQUER_STRUCTURE: if ($proposition->getEtat()->getCode() !== Etat::EN_COURS && $proposition->getEtat()->getCode() !== Etat::ETABLISSEMENT) return false; switch ($role) { case Role::CODE_BDD : $validations_BDD = $this->getValidationService()->getRepository()->findValidationByCodeAndThese(TypeValidation::CODE_VALIDATION_PROPOSITION_BDD, $these); return (!empty($validations_BDD) && $structure === $theseEtablissementStructure); case Role::CODE_RESP_UR : $validations_UNITE = $this->getValidationService()->getRepository()->findValidationByCodeAndThese(TypeValidation::CODE_VALIDATION_PROPOSITION_UR, $these); return (!empty($validations_UNITE) && $structure === $these->getUniteRecherche()->getStructure()); case Role::CODE_RESP_ED : $validations_ED = $this->getValidationService()->getRepository()->findValidationByCodeAndThese(TypeValidation::CODE_VALIDATION_PROPOSITION_ED, $these); return (!empty($validations_ED) && $structure === $these->getEcoleDoctorale()->getStructure()); default: return false; } case PropositionPrivileges::PROPOSITION_PRESIDENCE: switch($role) { case Role::CODE_BDD : Loading module/Soutenance/src/Soutenance/Controller/PropositionController.php +63 −1 Changes for module/Soutenance/src/Soutenance/Controller/PropositionController.php: 63 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ namespace Soutenance\Controller; use Application\Controller\AbstractController; use Application\Entity\Db\Role; use Application\Entity\Db\Utilisateur; use Application\Entity\Db\Validation; use Application\Service\Role\RoleServiceAwareTrait; use Application\Service\UserContextServiceAwareTrait; use Exception; Loading Loading @@ -486,7 +487,7 @@ class PropositionController extends AbstractController } public function validerStructureAction() public function validerStructureAction(): Response|ViewModel { $these = $this->requestedThese(); $proposition = $this->getPropositionService()->findOneForThese($these); Loading Loading @@ -549,6 +550,67 @@ class PropositionController extends AbstractController } public function revoquerStructureAction(): ViewModel { $these = $this->requestedThese(); $proposition = $this->getPropositionService()->findOneForThese($these); /** * @var Role $role * @var Individu $individu */ $role = $this->userContextService->getSelectedIdentityRole(); /** NOTE: pas de break ici pour dévalider en cascade */ $validations = []; switch ($role->getCode()) { case Role::CODE_RESP_UR : $validations = array_merge($validations, $this->getValidationService()->getRepository()->findValidationByCodeAndThese(\Application\Entity\Db\TypeValidation::CODE_VALIDATION_PROPOSITION_UR,$these)); case Role::CODE_RESP_ED : $validations = array_merge($validations, $this->getValidationService()->getRepository()->findValidationByCodeAndThese(\Application\Entity\Db\TypeValidation::CODE_VALIDATION_PROPOSITION_ED,$these)); case Role::CODE_BDD : $validations = array_merge($validations, $this->getValidationService()->getRepository()->findValidationByCodeAndThese(\Application\Entity\Db\TypeValidation::CODE_VALIDATION_PROPOSITION_BDD,$these)); } $validationsListing = "<ul>"; if (!empty($validations)) { /** @var Validation $v */ foreach ($validations as $v) { $validationsListing .= "<li>" . $v->getTypeValidation()->getLibelle() . " faite par" . $v->getHistoCreateur()->getDisplayName(). " le". $v->getHistoCreation()->format('d/m/y à H:i')."</li>"; } } $validationsListing .= "</ul>"; $request = $this->getRequest(); if ($request->isPost()) { $data = $request->getPost(); if ($data["reponse"] === "oui") { if (!empty($validations)) { foreach ($validations as $v) { $this->getValidationService()->historise($v); } } $etat = $this->getPropositionService()->findPropositionEtatByCode(Etat::EN_COURS); $proposition->setEtat($etat); $this->getPropositionService()->update($proposition); } } $this->getHorodatageService()->addHorodatage($proposition, HorodatageService::TYPE_VALIDATION, "Révocation " . $role->getCode()); $vm = new ViewModel(); if (!empty($validations)) { $vm->setTemplate('default/confirmation'); $vm->setVariables([ 'title' => "Révocation de votre validation", 'text' => "Cette révocation annulera les validations suivantes : " . $validationsListing . "Êtes-vous sûr·e de vouloir continuer ?", 'action' => $this->url()->fromRoute('soutenance/proposition/revoquer-structure', ["these" => $these->getId()], [], true), ]); } return $vm; } public function refuserStructureAction(): ViewModel { $these = $this->requestedThese(); Loading Loading
CHANGELOG.md +1 −0 Changes for CHANGELOG.md: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ Journal des modifications ----- - [FIX] Recherche de rapports d'Activité/CSI/Mi-parcours : les filtres Établissement/ED/UR géraient mal la subsitution de structures. - Changement de la page de couverture pour tenir compte de la co-accréditation - Module Soutenance : Possibilité pour les structures de révoquer leur validation (avec modal de confirmation) 6.0.3 ----- Loading
doc/release-notes/v6.0.4.md +48 −1 Changes for doc/release-notes/v6.0.4.md: 48 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -19,4 +19,51 @@ systemctl reload php8.0-fpm ## 2. Dans la base de données Néant. No newline at end of file ```postgresql -- Ajout du privilège pour revoquer INSERT INTO privilege (categorie_id, code, libelle, ordre) WITH d(code, lib, ordre) AS ( SELECT 'proposition-revoquer-structure', 'Révoquer la validation (structure) de la proposition', 34 ) SELECT cp.id, d.code, d.lib, d.ordre FROM d JOIN categorie_privilege cp ON cp.CODE = 'soutenance'; --Ajout au profil INSERT INTO PROFIL_PRIVILEGE (PRIVILEGE_ID, PROFIL_ID) with data(categ, priv) as ( select 'soutenance'::text, 'proposition-revoquer-structure'::text ) select p.id as PRIVILEGE_ID, profil.id as PROFIL_ID from data join PROFIL on profil.ROLE_ID in ('RESP_ED', 'RESP_UR', 'BDD') join CATEGORIE_PRIVILEGE cp on cp.CODE = data.categ join PRIVILEGE p on p.CATEGORIE_ID = cp.id and p.code = data.priv where not exists ( select * from PROFIL_PRIVILEGE where PRIVILEGE_ID = p.id and PROFIL_ID = profil.id ); INSERT INTO PROFIL_PRIVILEGE (PRIVILEGE_ID, PROFIL_ID) with data(categ, priv) as ( select 'missionenseignement'::text, 'missionenseignement_modifier'::text ) select p.id as PRIVILEGE_ID, profil.id as PROFIL_ID from data join PROFIL on profil.ROLE_ID in ('ADMIN_TECH', 'GEST_FORMATION', 'BDD', 'ADMIN') join CATEGORIE_PRIVILEGE cp on cp.CODE = data.categ join PRIVILEGE p on p.CATEGORIE_ID = cp.id and p.code = data.priv where not exists ( select * from PROFIL_PRIVILEGE where PRIVILEGE_ID = p.id and PROFIL_ID = profil.id ); insert into ROLE_PRIVILEGE (ROLE_ID, PRIVILEGE_ID) select p2r.ROLE_ID, pp.PRIVILEGE_ID from PROFIL_TO_ROLE p2r join profil pr on pr.id = p2r.PROFIL_ID join PROFIL_PRIVILEGE pp on pp.PROFIL_ID = pr.id where not exists ( select * from role_privilege where role_id = p2r.role_id and privilege_id = pp.privilege_id ); ``` No newline at end of file
module/Soutenance/config/others/proposition.config.php +24 −0 Changes for module/Soutenance/config/others/proposition.config.php: 24 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ return [ PropositionPrivileges::PROPOSITION_VALIDER_ED, PropositionPrivileges::PROPOSITION_VALIDER_UR, PropositionPrivileges::PROPOSITION_VALIDER_BDD, PropositionPrivileges::PROPOSITION_REVOQUER_STRUCTURE, PropositionPrivileges::PROPOSITION_PRESIDENCE, PropositionPrivileges::PROPOSITION_DECLARATION_HONNEUR_VALIDER, Loading Loading @@ -137,6 +138,15 @@ return [ PropositionPrivileges::PROPOSITION_VALIDER_BDD, ], ], [ 'controller' => PropositionController::class, 'action' => [ 'revoquer-structure', ], 'privileges' => [ PropositionPrivileges::PROPOSITION_REVOQUER_STRUCTURE, ], ], [ 'controller' => PropositionController::class, 'action' => [ Loading Loading @@ -378,17 +388,31 @@ return [ 'options' => [ 'route' => '/valider-structure', 'defaults' => [ /** @see PropositionController::validerStructureAction() */ 'controller' => PropositionController::class, 'action' => 'valider-structure', ], ], ], 'revoquer-structure' => [ 'type' => Segment::class, 'may_terminate' => true, 'options' => [ 'route' => '/revoquer-structure', 'defaults' => [ /** @see PropositionController::revoquerStructureAction() */ 'controller' => PropositionController::class, 'action' => 'revoquer-structure', ], ], ], 'refuser-structure' => [ 'type' => Segment::class, 'may_terminate' => true, 'options' => [ 'route' => '/refuser-PropositionController', 'defaults' => [ /** @see PropositionController::refuserStructureAction() */ 'controller' => PropositionController::class, 'action' => 'refuser-structure', ], Loading
module/Soutenance/src/Soutenance/Assertion/PropositionAssertion.php +16 −0 Changes for module/Soutenance/src/Soutenance/Assertion/PropositionAssertion.php: 16 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ namespace Soutenance\Assertion; use Soutenance\Entity\Etat; use These\Entity\Db\Acteur; use Application\Entity\Db\Role; use These\Entity\Db\These; Loading Loading @@ -211,6 +212,21 @@ class PropositionAssertion implements AssertionInterface { default: return false; } case PropositionPrivileges::PROPOSITION_REVOQUER_STRUCTURE: if ($proposition->getEtat()->getCode() !== Etat::EN_COURS && $proposition->getEtat()->getCode() !== Etat::ETABLISSEMENT) return false; switch ($role) { case Role::CODE_BDD : $validations_BDD = $this->getValidationService()->getRepository()->findValidationByCodeAndThese(TypeValidation::CODE_VALIDATION_PROPOSITION_BDD, $these); return (!empty($validations_BDD) && $structure === $theseEtablissementStructure); case Role::CODE_RESP_UR : $validations_UNITE = $this->getValidationService()->getRepository()->findValidationByCodeAndThese(TypeValidation::CODE_VALIDATION_PROPOSITION_UR, $these); return (!empty($validations_UNITE) && $structure === $these->getUniteRecherche()->getStructure()); case Role::CODE_RESP_ED : $validations_ED = $this->getValidationService()->getRepository()->findValidationByCodeAndThese(TypeValidation::CODE_VALIDATION_PROPOSITION_ED, $these); return (!empty($validations_ED) && $structure === $these->getEcoleDoctorale()->getStructure()); default: return false; } case PropositionPrivileges::PROPOSITION_PRESIDENCE: switch($role) { case Role::CODE_BDD : Loading
module/Soutenance/src/Soutenance/Controller/PropositionController.php +63 −1 Changes for module/Soutenance/src/Soutenance/Controller/PropositionController.php: 63 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ namespace Soutenance\Controller; use Application\Controller\AbstractController; use Application\Entity\Db\Role; use Application\Entity\Db\Utilisateur; use Application\Entity\Db\Validation; use Application\Service\Role\RoleServiceAwareTrait; use Application\Service\UserContextServiceAwareTrait; use Exception; Loading Loading @@ -486,7 +487,7 @@ class PropositionController extends AbstractController } public function validerStructureAction() public function validerStructureAction(): Response|ViewModel { $these = $this->requestedThese(); $proposition = $this->getPropositionService()->findOneForThese($these); Loading Loading @@ -549,6 +550,67 @@ class PropositionController extends AbstractController } public function revoquerStructureAction(): ViewModel { $these = $this->requestedThese(); $proposition = $this->getPropositionService()->findOneForThese($these); /** * @var Role $role * @var Individu $individu */ $role = $this->userContextService->getSelectedIdentityRole(); /** NOTE: pas de break ici pour dévalider en cascade */ $validations = []; switch ($role->getCode()) { case Role::CODE_RESP_UR : $validations = array_merge($validations, $this->getValidationService()->getRepository()->findValidationByCodeAndThese(\Application\Entity\Db\TypeValidation::CODE_VALIDATION_PROPOSITION_UR,$these)); case Role::CODE_RESP_ED : $validations = array_merge($validations, $this->getValidationService()->getRepository()->findValidationByCodeAndThese(\Application\Entity\Db\TypeValidation::CODE_VALIDATION_PROPOSITION_ED,$these)); case Role::CODE_BDD : $validations = array_merge($validations, $this->getValidationService()->getRepository()->findValidationByCodeAndThese(\Application\Entity\Db\TypeValidation::CODE_VALIDATION_PROPOSITION_BDD,$these)); } $validationsListing = "<ul>"; if (!empty($validations)) { /** @var Validation $v */ foreach ($validations as $v) { $validationsListing .= "<li>" . $v->getTypeValidation()->getLibelle() . " faite par" . $v->getHistoCreateur()->getDisplayName(). " le". $v->getHistoCreation()->format('d/m/y à H:i')."</li>"; } } $validationsListing .= "</ul>"; $request = $this->getRequest(); if ($request->isPost()) { $data = $request->getPost(); if ($data["reponse"] === "oui") { if (!empty($validations)) { foreach ($validations as $v) { $this->getValidationService()->historise($v); } } $etat = $this->getPropositionService()->findPropositionEtatByCode(Etat::EN_COURS); $proposition->setEtat($etat); $this->getPropositionService()->update($proposition); } } $this->getHorodatageService()->addHorodatage($proposition, HorodatageService::TYPE_VALIDATION, "Révocation " . $role->getCode()); $vm = new ViewModel(); if (!empty($validations)) { $vm->setTemplate('default/confirmation'); $vm->setVariables([ 'title' => "Révocation de votre validation", 'text' => "Cette révocation annulera les validations suivantes : " . $validationsListing . "Êtes-vous sûr·e de vouloir continuer ?", 'action' => $this->url()->fromRoute('soutenance/proposition/revoquer-structure', ["these" => $these->getId()], [], true), ]); } return $vm; } public function refuserStructureAction(): ViewModel { $these = $this->requestedThese(); Loading