diff --git a/CHANGELOG.md b/CHANGELOG.md index 62513250d748d50e2a2c493a166997a73149ff82..2a36e831a7f9aa3672ee1202126b81914e6fd8fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ Journal des modifications ========================= +5.3.2 +----- +- Module Soutenance : 2 nouvelles qualités possibles : 'Autre membre de rang B' et Associate Professor - Équivalent HDR' +- [FIX] Erreur dans le test de pertinence des étapes de dépôt d'une version corrigée (SQL). +- [FIX] Remise de la fonction getNbInscription effacée car sans d'usage (explicite) +- [FIX] Remise du controle de sursis pour les validations acteurs +- [FIX] Inversion de l'ordre de génération des avis de souteances et procés verbaux + 5.3.1 ----- - [FIX] Donnée : ajout de garde lorsque le mail fourni par les données sources est " " diff --git a/doc/release-notes/v5.3.2.md b/doc/release-notes/v5.3.2.md new file mode 100644 index 0000000000000000000000000000000000000000..59a65ca6356246fe73602e49c59797bdb503f8b7 --- /dev/null +++ b/doc/release-notes/v5.3.2.md @@ -0,0 +1,251 @@ +# Version 5.3.2 + +## 1. Sur le serveur d'application + +- Placez-vous dans le répertoire de l'application puis lancez la commande suivante + pour installer la nouvelle version : + +```bash +git fetch --tags && git checkout --force 5.3.2 && bash ./install.sh +``` + +- Selon le moteur PHP que vous avez installé, rechargez le service, exemple : + - php7.4-fpm : `service php7.4-fpm reload` + - apache2-mod-php7.4 : `service apache2 reload` + +## 2. Dans la base de données + +```sql +-- Module Soutenance : 2 nouvelles qualités possibles. +insert into soutenance_qualite (id, libelle, rang, hdr, emeritat, histo_creation, histo_createur_id, histo_modification, histo_modificateur_id) +select nextval('soutenance_qualite_id_seq'), 'Autre membre de rang B', 'B', 'N', 'N', current_timestamp, 1, current_timestamp, 1; +insert into soutenance_qualite (id, libelle, rang, hdr, emeritat, histo_creation, histo_createur_id, histo_modification, histo_modificateur_id) +select nextval('soutenance_qualite_id_seq'), 'Associate Professor - Équivalent HDR', 'B', 'O', 'N', current_timestamp, 1, current_timestamp, 1; + +-- +-- [FIX] Erreur dans le test de pertinence des étapes de dépôt d'une version corrigée. +-- +create or replace view v_wf_etape_pertin(these_id, etape_id, code, ordre, id) as +SELECT alias38.these_id::numeric AS these_id, + alias38.etape_id::numeric AS etape_id, + alias38.code, + alias38.ordre, + row_number() OVER (ORDER BY 1::integer, 2::integer, 3::integer, 4::integer) AS id +FROM (SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'VALIDATION_PAGE_DE_COUVERTURE'::text + WHERE t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text]) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'DEPOT_VERSION_ORIGINALE'::text + WHERE t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text]) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'AUTORISATION_DIFFUSION_THESE'::text + WHERE t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text]) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'ATTESTATIONS'::text + WHERE t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text]) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'SIGNALEMENT_THESE'::text + WHERE t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text]) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'ARCHIVABILITE_VERSION_ORIGINALE'::text + WHERE t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text]) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'DEPOT_VERSION_ARCHIVAGE'::text + JOIN v_situ_archivab_vo situ ON situ.these_id = t.id AND situ.est_valide = false + WHERE t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text]) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'ARCHIVABILITE_VERSION_ARCHIVAGE'::text + JOIN v_situ_archivab_vo situ ON situ.these_id = t.id AND situ.est_valide = false + WHERE t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text]) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'VERIFICATION_VERSION_ARCHIVAGE'::text + JOIN v_situ_archivab_va situ ON situ.these_id = t.id AND situ.est_valide = true + WHERE t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text]) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'RDV_BU_SAISIE_DOCTORANT'::text + WHERE t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text]) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'RDV_BU_SAISIE_BU'::text + WHERE t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text]) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'RDV_BU_VALIDATION_BU'::text + WHERE t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text]) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'DEPOT_VERSION_ORIGINALE_CORRIGEE'::text + WHERE (t.correc_autorisee IS NOT NULL OR + t.correc_autorisee_forcee IS NOT NULL AND t.correc_autorisee_forcee::text <> 'aucune'::text OR + t.correc_effectuee::text = 'O'::text) + AND (t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text])) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'AUTORISATION_DIFFUSION_THESE_VERSION_CORRIGEE'::text + WHERE (t.correc_autorisee IS NOT NULL OR + t.correc_autorisee_forcee IS NOT NULL AND t.correc_autorisee_forcee::text <> 'aucune'::text OR + t.correc_effectuee::text = 'O'::text) + AND (t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text])) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'ATTESTATIONS_VERSION_CORRIGEE'::text + WHERE (t.correc_autorisee IS NOT NULL OR + t.correc_autorisee_forcee IS NOT NULL AND t.correc_autorisee_forcee::text <> 'aucune'::text OR + t.correc_effectuee::text = 'O'::text) + AND (t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text])) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'ARCHIVABILITE_VERSION_ORIGINALE_CORRIGEE'::text + WHERE (t.correc_autorisee IS NOT NULL OR + t.correc_autorisee_forcee IS NOT NULL AND t.correc_autorisee_forcee::text <> 'aucune'::text OR + t.correc_effectuee::text = 'O'::text) + AND (t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text])) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'DEPOT_VERSION_ARCHIVAGE_CORRIGEE'::text + JOIN v_situ_archivab_voc situ ON situ.these_id = t.id AND situ.est_valide = false + WHERE (t.correc_autorisee IS NOT NULL OR + t.correc_autorisee_forcee IS NOT NULL AND t.correc_autorisee_forcee::text <> 'aucune'::text OR + t.correc_effectuee::text = 'O'::text) + AND (t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text])) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'ARCHIVABILITE_VERSION_ARCHIVAGE_CORRIGEE'::text + JOIN v_situ_archivab_voc situ ON situ.these_id = t.id AND situ.est_valide = false + WHERE (t.correc_autorisee IS NOT NULL OR + t.correc_autorisee_forcee IS NOT NULL AND t.correc_autorisee_forcee::text <> 'aucune'::text OR + t.correc_effectuee::text = 'O'::text) + AND (t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text])) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'VERIFICATION_VERSION_ARCHIVAGE_CORRIGEE'::text + JOIN v_situ_archivab_vac situ ON situ.these_id = t.id AND situ.est_valide = true + WHERE (t.correc_autorisee IS NOT NULL OR + t.correc_autorisee_forcee IS NOT NULL AND t.correc_autorisee_forcee::text <> 'aucune'::text OR + t.correc_effectuee::text = 'O'::text) + AND (t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text])) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'DEPOT_VERSION_CORRIGEE_VALIDATION_DOCTORANT'::text + WHERE (t.correc_autorisee IS NOT NULL OR + t.correc_autorisee_forcee IS NOT NULL AND t.correc_autorisee_forcee::text <> 'aucune'::text OR + t.correc_effectuee::text = 'O'::text) + AND (t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text])) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'DEPOT_VERSION_CORRIGEE_VALIDATION_DIRECTEUR'::text + WHERE (t.correc_autorisee IS NOT NULL OR + t.correc_autorisee_forcee IS NOT NULL AND t.correc_autorisee_forcee::text <> 'aucune'::text OR + t.correc_effectuee::text = 'O'::text) + AND (t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text])) + UNION ALL + SELECT t.id AS these_id, + e.id AS etape_id, + e.code, + e.ordre + FROM these t + JOIN wf_etape e ON e.code::text = 'REMISE_EXEMPLAIRE_PAPIER_THESE_CORRIGEE'::text + WHERE (t.correc_autorisee IS NOT NULL OR + t.correc_autorisee_forcee IS NOT NULL AND t.correc_autorisee_forcee::text <> 'aucune'::text OR + t.correc_effectuee::text = 'O'::text) + AND (t.etat_these::text = ANY (ARRAY ['E'::character varying::text, 'S'::character varying::text])) + AND (EXISTS(SELECT d.id + FROM diffusion d + WHERE d.these_id = t.id + AND d.version_corrigee = true + AND (d.autoris_mel = ANY (ARRAY [0, 1]))))) alias38; + +``` \ No newline at end of file diff --git a/module/Application/src/Application/Command/ShellCommandRunnerTrait.php b/module/Application/src/Application/Command/ShellCommandRunnerTrait.php index 9bbb0baa3c1c0eb8ea7429320b9e0fbea335a153..bd4105c36baa1648348f20434e8c8016d7de0193 100644 --- a/module/Application/src/Application/Command/ShellCommandRunnerTrait.php +++ b/module/Application/src/Application/Command/ShellCommandRunnerTrait.php @@ -21,9 +21,10 @@ trait ShellCommandRunnerTrait } if (!$result->isSuccessfull()) { - $message = sprintf("La commande '%s' a échoué (code retour = %s). ", + $message = sprintf("La commande '%s' a échoué (code retour = %s) : %s", $command->getName(), - $result->getReturnCode() + $result->getReturnCode(), + $command->getCommandLine() ); if ($output = $result->getOutput()) { $message .= "Voici le log d'exécution : " . implode(PHP_EOL, $output); diff --git a/module/Fichier/src/Fichier/Command/Pdf/PdfMergeShellCommandQpdf.php b/module/Fichier/src/Fichier/Command/Pdf/PdfMergeShellCommandQpdf.php index 640d1d79a45bc1bd079c5960313d37f106188dcc..7b298d65e603a7baa7a8b4fa4e2fcc17760cfb29 100644 --- a/module/Fichier/src/Fichier/Command/Pdf/PdfMergeShellCommandQpdf.php +++ b/module/Fichier/src/Fichier/Command/Pdf/PdfMergeShellCommandQpdf.php @@ -11,7 +11,7 @@ use Fichier\Command\MergeShellCommand; */ class PdfMergeShellCommandQpdf extends MergeShellCommand { - protected $executable = '/usr/local/bin/qpdf'; + protected $executable = 'qpdf'; /** * @return string diff --git a/module/Formation/src/Formation/Controller/SessionController.php b/module/Formation/src/Formation/Controller/SessionController.php index a2e23582fe864be3c0f33938772853717dc81d61..a57e1479e063478c9f5eeddbdc37a3bf6979f970 100644 --- a/module/Formation/src/Formation/Controller/SessionController.php +++ b/module/Formation/src/Formation/Controller/SessionController.php @@ -436,10 +436,12 @@ class SessionController extends AbstractController foreach ($inscriptions as $inscription) { $doctorant = $inscription->getDoctorant(); $theses = array_filter($doctorant->getTheses(), function (These $t) { return ($t->getEtatThese() === These::ETAT_EN_COURS AND $t->estNonHistorise());}); + /** @var These $these */ + $these = (!empty($theses))?current($theses):null; $etablissements = array_map(function (These $t) { return ($t->getEtablissement())?$t->getEtablissement()->getStructure()->getLibelle():"Établissement non renseigné";}, $theses); $ecoles = array_map(function (These $t) { return ($t->getEcoleDoctorale())?$t->getEcoleDoctorale()->getStructure()->getLibelle():"École doctorale non renseignée";}, $theses); $unites = array_map(function (These $t) { return ($t->getUniteRecherche())?$t->getUniteRecherche()->getStructure()->getLibelle():"Unité de recherche non renseignée";}, $theses); - $nbInscription = (!empty($theses))?current($theses)->getNbInscription($annee):"---"; + $nbInscription = ($these)?$these->getNbInscription():"---"; $entry = [ 'Liste' => $inscription->getListe(), 'Dénomination étudiant' => $doctorant->getIndividu()->getNomComplet(), diff --git a/module/Soutenance/view/soutenance/presoutenance/partial/documents.phtml b/module/Soutenance/view/soutenance/presoutenance/partial/documents.phtml index cb262b4d4f46d7957ec58019c0262ee1db127b5a..803daeda32af0e21a70d9ddd242dfc877d835b00 100644 --- a/module/Soutenance/view/soutenance/presoutenance/partial/documents.phtml +++ b/module/Soutenance/view/soutenance/presoutenance/partial/documents.phtml @@ -42,7 +42,7 @@ $canAjouterRapport = $this->isAllowed($these, PropositionPrivileges <?php if ($autorisation === null) : ?> <div class="card-header bg-warning"> <span class="icon icon-attention"></span> - Aucune autorisation de soutenance de déposée. + Aucune autorisation de soutenance déposée. </div> <?php else : ?> <ul> @@ -85,7 +85,7 @@ $canAjouterRapport = $this->isAllowed($these, PropositionPrivileges <?php if ($rapport === null or empty($rapport)) : ?> <div class="card-header bg-warning"> <span class="icon icon-attention"></span> - Aucune rapport de soutenance de déposé. + Aucune rapport de soutenance déposé. </div> <?php else: ?> <ul> diff --git a/module/Soutenance/view/soutenance/presoutenance/presoutenance.phtml b/module/Soutenance/view/soutenance/presoutenance/presoutenance.phtml index a648d5c539033830d3fa2cff640cb334f3c82ab8..f594213a96f524543e658e20ae4c35bfa453e9c9 100644 --- a/module/Soutenance/view/soutenance/presoutenance/presoutenance.phtml +++ b/module/Soutenance/view/soutenance/presoutenance/presoutenance.phtml @@ -293,18 +293,17 @@ $canSimulerRemonter = $this->isAllowed(PresoutenancePrivileges::getResourceId(Pr <div class="row"> <div class="col-md-3"> <?php if ($canGenererDocument) : ?> - <a <?php /** @see \Soutenance\Controller\PresoutenanceController::procesVerbalSoutenanceAction() */ ?> - href="<?php echo $this->url('soutenance/presoutenance/proces-verbal-soutenance', ['these' => $these->getId()], [], true); ?>" + <a <?php /** @see \Soutenance\Controller\PresoutenanceController::avisSoutenanceAction() */ ?> + href="<?php echo $this->url('soutenance/presoutenance/avis-soutenance', ['these' => $these->getId()], [], true); ?>" class="btn btn-primary action" target="_blank" > - <span class="fas fa-list-alt"></span> - Générer le procès verbal + <span class="fas fa-list-alt"></span>Générer l'avis de soutenance </a> <?php endif; ?> </div> <div class="col-md-9"> - <?php echo $this->dernierHorodatage($proposition, HorodatageService::TYPE_EDITION, "Procès verbal"); ?> + <?php echo $this->dernierHorodatage($proposition, HorodatageService::TYPE_EDITION, "Avis de soutenance"); ?> </div> </div> @@ -388,12 +387,13 @@ $canSimulerRemonter = $this->isAllowed(PresoutenancePrivileges::getResourceId(Pr <div class="row"> <div class="col-md-12"> <?php if ($canGenererDocument) : ?> - <a <?php /** @see \Soutenance\Controller\PresoutenanceController::avisSoutenanceAction() */ ?> - href="<?php echo $this->url('soutenance/presoutenance/avis-soutenance', ['these' => $these->getId()], [], true); ?>" - class="btn btn-primary action" - target="_blank" + <a <?php /** @see \Soutenance\Controller\PresoutenanceController::procesVerbalSoutenanceAction() */ ?> + href="<?php echo $this->url('soutenance/presoutenance/proces-verbal-soutenance', ['these' => $these->getId()], [], true); ?>" + class="btn btn-primary action" + target="_blank" > - <span class="fas fa-list-alt"></span>Générer l'avis de soutenance + <span class="fas fa-list-alt"></span> + Générer le procès verbal </a> <?php endif; ?> @@ -429,7 +429,7 @@ $canSimulerRemonter = $this->isAllowed(PresoutenancePrivileges::getResourceId(Pr </div> <?php echo $this->derniersHorodatages($proposition, [ - [HorodatageService::TYPE_EDITION, "Avis de soutenance"], + [HorodatageService::TYPE_EDITION, "Procès verbal"], [HorodatageService::TYPE_EDITION, "Rapport de soutenance"], [HorodatageService::TYPE_EDITION, "Rapport technique"], [HorodatageService::TYPE_EDITION, "Convocations"], diff --git a/module/Soutenance/view/soutenance/proposition/partial/pre-rapports.phtml b/module/Soutenance/view/soutenance/proposition/partial/pre-rapports.phtml index fb5edbaad60c34b8af5ff3c6be079646b5f64a2d..e18ea3c98fad274ce12e05fb3c3a16fbd76f5c41 100644 --- a/module/Soutenance/view/soutenance/proposition/partial/pre-rapports.phtml +++ b/module/Soutenance/view/soutenance/proposition/partial/pre-rapports.phtml @@ -18,7 +18,7 @@ use These\Entity\Db\These; <div> <?php if (empty($avis)) : ?> <div class="alert alert-info"> - Aucun pré-rapport de déposer pour le moment. + Aucun pré-rapport déposé pour le moment. </div> <?php else : ?> <table class="table table-condensed"> diff --git a/module/Soutenance/view/soutenance/proposition/partial/validations-acteurs.phtml b/module/Soutenance/view/soutenance/proposition/partial/validations-acteurs.phtml index 5b90cb1d78154d37ec88ed85ae316b788f1d187a..4e1e51508a9df91d1a8b22969251a50b7e617910 100644 --- a/module/Soutenance/view/soutenance/proposition/partial/validations-acteurs.phtml +++ b/module/Soutenance/view/soutenance/proposition/partial/validations-acteurs.phtml @@ -32,8 +32,9 @@ $these = $proposition->getThese(); $hasDeclaration= !empty($validations[TypeValidation::CODE_VALIDATION_DECLARATION_HONNEUR]); $hasAttestation = !empty($attestationsIntegriteScientifique); +$hasSursis = $proposition->hasSursis(); -$isDateOk = ((new DateTime())->add(new DateInterval('P2M')) < $proposition->getDate()); +$isDateOk = ((new DateTime())->add(new DateInterval('P2M')) < $proposition->getDate() OR $hasSursis); $isAllOk = ($hasDeclaration AND $hasAttestation AND $isDateOk AND $isInformationsOk) ?> diff --git a/module/These/src/These/Entity/Db/These.php b/module/These/src/These/Entity/Db/These.php index 6514fe3209b965236bf90c8c523618a6d459abb9..bab0d98407ff77ccb726d15b439fb12965b50c37 100644 --- a/module/These/src/These/Entity/Db/These.php +++ b/module/These/src/These/Entity/Db/These.php @@ -1543,4 +1543,11 @@ class These implements HistoriqueAwareInterface, ResourceInterface } return null; } + + public function getNbInscription() : int + { + $inscriptions = $this->getAnneesUnivInscription()->toArray(); + $inscriptions = array_filter($inscriptions, function (TheseAnneeUniv $a) { return $a->estNonHistorise();}); + return count($inscriptions); + } }