diff --git a/CHANGELOG.md b/CHANGELOG.md index d461c17d73105482fb5f4599af31ef7b832a7187..97a438a54da8b854f84f704f991685cb4a999149 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,18 @@ Journal des modifications 6.0.6 ----- - Passage dans UnicaenRenderer du template des historiques de co-encadrements -- [FORMATION] Ajout d'un filtre sur l'année sur l'écran des formations pour masquer/afficher les sessions +- Ajout d'un filtre sur l'année sur l'écran des formations pour masquer/afficher les sessions +- Extraction CSV des thèses : amélioration du temps de génération (création d'une vue en bdd) ; ajout des colonnes +'Dernier rapport d'activité', 'Dernier rapport CSI', 'Date d'extraction', 'Discipline Code SISE', 'Autorisation de MEL', +'Années financées' ; modification du séparateur de valeurs multiples ',' en ' ; ' ; correction de la colonne +'Date de dépôt version corrigée' toujours vide. +- [FIX] Création d'un compte utilisateur local : vérif de l'email déjà utilisé remplacée par vérif de l'email déjà utilisé comme username. +- [FIX] Création d'un compte utilisateur local : redirection vers la fiche du nouveau compte après création. +- [FIX] Soutenance : message d'alerte affiché à tort systématiquement à propos de l'adresse Doctorat manquante. +- [FIX] Chargement de la navigation : plantage d'une assertion à cause d'une variable null (role). +- [FIX] Accès aux fiches individus. +- [FIX] Pages de couverture : réduction de la marge en haut de page. +- [FORMATION] Filtre selon les année pour les sessions - [SOUTENANCE] Récupération de la date de fin de confidentialité depuis la thèse puis du dossier de soutenance pour le docuement de la présidence 6.0.5 @@ -12,7 +23,7 @@ Journal des modifications - [FIX] Correction d'un bug empêchant la création d'établissement ; améliorations des validateurs des formulaires de structures. - [FIX] Correction de bugs en cas d'utilisateur ayant à la fois le rôle Doctorant et un autre rôle. - [FIX] Correction du plantage survenant dans RapportActiviteAssertion (interrogée par la navigation) lorsque l'utilisateur n'est pas authentifié. -- [FIX] Destinataires de la notification de demande de validation d'une proposition de soutenance : adresse mail "aspects doctorat" +- [FIX] Destinataires de la notification de demande de validation d'une proposition de soutenance : adresse mail 'aspects doctorat' de l'établissement d'inscription, plutôt que la liste des individus ayant le rôle BDD obsolète. - Onglet 'Rôles et membres' d'une ED/UR : renommage de 'Site' en 'Établissement d'inscription' (clarification). - Complétion des qualités du jury sur la page de couverture avec le dossier de soutenance si manquante dans la donnée source @@ -72,7 +83,7 @@ Journal des modifications 5.3.1 ----- -- [FIX] Donnée : ajout de garde lorsque le mail fourni par les données sources est " " +- [FIX] Donnée : ajout de garde lorsque le mail fourni par les données sources est ' ' - [FIX] hydration des justificatifs 5.3.0 @@ -85,10 +96,10 @@ Journal des modifications - Soutenance : Renommange de Parité en Équilibre (et ajustement des couleurs des barres de l'indicateur) - Soutenance : Retravail du rapport de soutenance (Ajout d'une page blacnhe et d'une troisième page pour les signatures) - Soutenance : Ajout du dépôt de l'autorisation de soutenance et du rapport de soutenance -- Soutenance : Dépôt de l'attestation de la formation "Intégrité scientifique" +- Soutenance : Dépôt de l'attestation de la formation 'Intégrité scientifique' - Soutenance : Mise en place de l'horodatage - Soutenance : Ajout d'une étape intermédiaire avant feu vert pour soutenance -- Soutenance : [Fix] Echappement des caractères " et encapsulation des réponses +- Soutenance : [Fix] Echappement des caractères ' et encapsulation des réponses - Dépôt de thèse : un dépôt existant de la version corrigée reste visible même si l'avis de reproduction Apogée revient à Non. - Menu Dépôt fichiers divers : remonté et affiché sans condition - Page Dépôt fichiers divers : téléversement bloqué pour PV soutenance, Pré-rapport soutenance, Rapport soutenance @@ -133,7 +144,7 @@ Journal des modifications - Suppression du menu 'Mes données' : la modif de l'adresse de contact et du consentement associé est désormais sur la fiche Thèse - Abandon (avant suppression) de la table obsolète doctorant_compl. - Ajout d'un bloc dans l'écran de proposition de soutenance pour le téléchargement des pré-rapports et du serment -- Nouveau document "Serment du docteur" +- Nouveau document 'Serment du docteur' - Modification du pv de soutenance - Ajout d'un nouvel mail intermediare à la clôture des inscriptions + deplacement du mail d'echec d'inscription - [FIX] Module Formation : Ordonnancement des séances sur les index des formations et des sessions @@ -198,7 +209,7 @@ Journal des modifications - Changement de l'assertion pour l'accès des rapporteurs à la proposition de soutenance - [FIX] Remise en place du menu de dépôt de rapport de pré-soutenance - Changement du libellé 'Aucun Site' => 'Multi-site' (module de formation) -- Extension du mail "échec d'inscription" aux personnes non classées (module de formation) +- Extension du mail 'échec d'inscription' aux personnes non classées (module de formation) - Changements de libellés. 5.2.1 @@ -225,7 +236,7 @@ Journal des modifications 5.1.1 ----- - [FIX] Corrections suite à l'intégration du nouveau module Fichier. -- [FIX] Suppression à tort des "attestations" du 1er dépôt à la place de celles du 2nd dépôt. +- [FIX] Suppression à tort des 'attestations' du 1er dépôt à la place de celles du 2nd dépôt. - [FIX] Suppression physique de l'ancien fichier lors du changement de logo d'une structure. - [FIX] Correction et amélioration du calcul du nom de fichier du logo (existant ou nouveau) d'une structure. - Template de pagination : abandon du module/Application/view/paginator.phtml et généralisation du module/Application/view/application/paginator.phtml @@ -233,7 +244,7 @@ Journal des modifications 5.1.0 ----- -- Nouveau module "technique" Fichier proposant 2 modes de stockage des fichiers téléversés : Filesystem ou S3 +- Nouveau module 'technique' Fichier proposant 2 modes de stockage des fichiers téléversés : Filesystem ou S3 (cf. [releases notes](./doc/release-notes/v5.1.0.md)). - [FIX] Correction du chemin de stockage des rapports CSI et de mi-parcours @@ -311,7 +322,7 @@ Journal des modifications 4.0.4 ----- - Correction de typos dans mail de feu vert de la soutenance -- Ajout de redirection de mail lorsque certains mails n'ont pas de destinataire "ATTENTION MAIL NON DÉLIVRÉ". +- Ajout de redirection de mail lorsque certains mails n'ont pas de destinataire 'ATTENTION MAIL NON DÉLIVRÉ'. - Compléments d'individu : mise en place des éléments de base - Modification du texte de mail de réussite au doctorat - [FIX] verification des assertions au niveau des actions de PropositionController @@ -340,14 +351,14 @@ Journal des modifications - Migration vers Bootstrap 5 (front-end JS & CSS). - Réorganisation des infos affichées à propos de la connexion dans le menu principal. - Cas de la connexion d'un utilisateur sans possibilité de trouver d'individu associé : plus de création automatique d'individu car peut bloquer un import ultétieur. -- Amélioration de la page "Contact Assistance" en cas d'établissement indéterminé et/ou d'adresse d'assistance indéterminé ou invalide. -- [FIX] Plantage de la page "Contact Assistance" en cas de connexion avec un compte local. +- Amélioration de la page 'Contact Assistance' en cas d'établissement indéterminé et/ou d'adresse d'assistance indéterminé ou invalide. +- [FIX] Plantage de la page 'Contact Assistance' en cas de connexion avec un compte local. - [FIX] Activation de la mise en cache de la config lorsque le mode development est désactivé. - [FIX] Lancement de la synchro des thèses pour prendre en compte la création/modification/suppression de substitution de structures. - Ajout des unités de recherche fermées dans le filtre des thèses - [FIX] correction du bug lié au typage de retour trop strict de l'entité Structure - Mise en place de la déclaration de non plagiat dans la proposition de soutenance -- [FIX] Plantage lors de la création/modification/suppression d'une substitution de structure ("Synchro introuvable avec ce nom : these") +- [FIX] Plantage lors de la création/modification/suppression d'une substitution de structure ('Synchro introuvable avec ce nom : these') 3.0.12 ------ @@ -374,7 +385,7 @@ Journal des modifications 3.0.10 ----- -- Ajout de la mention "La réservation du lieu de soutenance n'est pas faite automatiquement et reste à votre charge" +- Ajout de la mention 'La réservation du lieu de soutenance n'est pas faite automatiquement et reste à votre charge' - Meilleure gestion des tokens des membres d'une soutenance - Déclaration tardive de visoconférence ajouté aux interventions de soutenance - Avis sur rapport d'activité de fin de thèse @@ -434,7 +445,7 @@ Journal des modifications 3.0.3 ----- -- Ajout d'une valeur d'état aux soutenances "Validée par l'établissement" post validation d'une soutenance par la présidence de l'établissement +- Ajout d'une valeur d'état aux soutenances 'Validée par l'établissement' post validation d'une soutenance par la présidence de l'établissement - [FIX] Plus de demande de justificatif pour la confidentialité si la demande est faite en amont de la soutenance - [FIX] La notif de validation de la version corrigée par le Président du jury faisait mention à tort du Directeur de thèse. - [FIX] Plantage de l'export CSV des thèses à cause d'un appel de méthode erroné (getMailContact). @@ -472,12 +483,12 @@ Journal des modifications 2.2.3 ----- -- Scission du rôle "École doctorale" en 2 : "Responsable École doctorale" et "Gestionnaire École doctorale". -- Scission du rôle "Unité de recherche" en 2 : "Responsable Unité de recherche" et "Gestionnaire Unité de recherche". +- Scission du rôle 'École doctorale' en 2 : 'Responsable École doctorale' et 'Gestionnaire École doctorale'. +- Scission du rôle 'Unité de recherche' en 2 : 'Responsable Unité de recherche' et 'Gestionnaire Unité de recherche'. - Envoi automatique par mail des jetons d'authentification créés + possibilité de les renvoyer. - Utilisation des dates et lieux des dossiers de soutenances plutôt que celles saisies dans les SIs pour la génération des documents du module soutenance. - Précision de la date de rendu des rapports dès le premier mail des rapporteurs -- Recherche de rapports d'activité : nouveau filtre "Annuel ou fin de thèse". +- Recherche de rapports d'activité : nouveau filtre 'Annuel ou fin de thèse'. - Fiche d'identité de la thèse : la date prévisionnelle de soutenance n'est plus affichée car elle peut être erronée. - Rapports d'activité, CSI, de fin de thèse : la date de bascule pour déterminer l'année universitaire est le 01/11. - [FIX] Dédoublonnage des origines de financement dans le filtres de la page des rapports. @@ -495,7 +506,7 @@ Journal des modifications - [FIX] Ligne de commande de lancement de toutes les synchros. - [FIX] Correction du texte de la convocation s'attendant à avoir un individu (pas toujours le cas car le lien n'est pas fait systèmatiquement). - [FIX] La recherche du doctorant lié à un individu doit écarter les individus historisés. -- [FIX] Warning lors de la génération de la PDC à cause d'un tableau non initialisé" +- [FIX] Warning lors de la génération de la PDC à cause d'un tableau non initialisé' 2.2.0 ----- @@ -575,8 +586,8 @@ Journal des modifications - Ajout à l'export de l'annuaire des co-encadrants - Onglets dans les pages d'information des structures - Page de connexion scindée par type d'authentification activée. -- Import du témoin "corrections effectuées" de chaque thèse. -- Pages de dépôt de la version corrigée : visibles dès lors que le témoin "corrections effectuées" est à Oui. +- Import du témoin 'corrections effectuées' de chaque thèse. +- Pages de dépôt de la version corrigée : visibles dès lors que le témoin 'corrections effectuées' est à Oui. - Amélioration du temps de réponse de la recherche textuelle de thèses. - Retour du bouton d'import forcé de thèse qui avait disparu à cause d'une erreur de config. - Mise en retrait des items de menus concernant le dépôt de la version initiale en cas de corrections attendues ou effectuées. @@ -625,7 +636,7 @@ Journal des modifications - Ajout d'une configuration pour le fil d'actualité. - Ajout du champ IdREF pour toutes les structures et modification de l'affichage/saisie des informations. - Changement de l'affichage des structures fermées dans le filtre des thèses. -- Nouveau message "Dépôt terminé" au doctorant sur la page Rendez-vous BU. +- Nouveau message 'Dépôt terminé' au doctorant sur la page Rendez-vous BU. 1.4.8 (01/09/2020) ------------------ @@ -637,15 +648,15 @@ Journal des modifications ------------------ - Lors du dépôt d'une version corrigée, l'autorisation de mise en ligne est reprise texto (dupliquée) du 1er dépôt, -sauf si l'utilisateur possède le privilège "Saisie du formulaire d'autorisation de diffusion de la version corrigée", +sauf si l'utilisateur possède le privilège 'Saisie du formulaire d'autorisation de diffusion de la version corrigée', auquel cas elle est redemandée à l'utilisateur. -Idem pour les attestations et le privilège "Modification des attestations concernant la version corrigée". +Idem pour les attestations et le privilège 'Modification des attestations concernant la version corrigée'. - Masquage du complément de financement dans la fiche d'identité de la thèse - Optimisation de l'export CSV des thèses - Pages de téléversement et de recherche des rapports annuels. - Correction d'un bug dans la recherche de thèses par nom du doctorant. - Correction d'un bug dans le package Oracle APP_IMPORT qui ne filtrait pas les thèses selon l'établissement spécifié. -- Possibilité d'attribuer un "identifiant permanent" à un fichier (ex: 'RAPPORT_ANNUEL_MODELE') facilitant l'intégration +- Possibilité d'attribuer un 'identifiant permanent' à un fichier (ex: 'RAPPORT_ANNUEL_MODELE') facilitant l'intégration de lien de téléchargement de ce fichier dans une page. - Listes de diffusion dynamique Sympa alimentées par SyGAL : pages de consultation des listes de diffusion déclarées dans la config ; une URL pour fournir les abonnés, une autre pour fournir les propriétaires. @@ -653,16 +664,16 @@ Idem pour les attestations et le privilège "Modification des attestations conce 1.4.6 (29/05/2020) ------------------ -- Ajout du drapeau "établissement d'inscription" et ajout des visualisations et interfaces pour gérer ce nouveau drapeau. +- Ajout du drapeau 'établissement d'inscription' et ajout des visualisations et interfaces pour gérer ce nouveau drapeau. - Restriction du filtre des établissements sur la partie annuaire aux établissements d'inscription. - Ajout dans structures des champs adresse, tel, fax, site web, email qui sont utilisables pour l'édition de document. - Utilisation des nouveaux champs dans la génération de la convention de MEL (requiert unicaen/app v1.3.19). - Amélioration de la recherche textuelle de thèses : ajout d'une liste déroulante permettant de sélectionner - précisément sur quels critères porte la recherche : "Titre de la thèse", "Numéro étudiant de l'auteur", - "Nom de l'auteur", "Prénom de l'auteur", "Nom du directeur ou co-directeur de thèse", - "Code national de l'école doctorale concernée (ex: 181)", "Unité de recherche concernée (ex: umr6211)". -- Correction d'un dysfonctionnement de la recherche textuelle sur les critères "numéro étudiant", "unité de recherche" - et "école doctorale". + précisément sur quels critères porte la recherche : 'Titre de la thèse', 'Numéro étudiant de l'auteur', + 'Nom de l'auteur', 'Prénom de l'auteur', 'Nom du directeur ou co-directeur de thèse', + 'Code national de l'école doctorale concernée (ex: 181)', 'Unité de recherche concernée (ex: umr6211)'. +- Correction d'un dysfonctionnement de la recherche textuelle sur les critères 'numéro étudiant', 'unité de recherche' + et 'école doctorale'. 1.4.5 (08/04/2020) @@ -691,7 +702,7 @@ Idem pour les attestations et le privilège "Modification des attestations conce - Extraction CSV des thèses : nouvelles colonnes concernant l'embargo et refus de diffusion ; virgule plutôt que point dans la durée de la thèse. - Page d'accueil : affichage des actualités issues du flux RSS fourni par la COMUE. -- Filtrage de la liste des thèses : correction de l'affichage du filtre "Unité de recherche". +- Filtrage de la liste des thèses : correction de l'affichage du filtre 'Unité de recherche'. - Corrections de textes sur la page RDV BU. @@ -711,8 +722,8 @@ Idem pour les attestations et le privilège "Modification des attestations conce - Modification des textes liés à l'autorisation de diffusion dans le formulaire et dans la convention PDF générée. - Convention de MEL : suppression du petit logo dans l'entête puisqu'il y en a déjà un sous le titre - Nouvelle charte de diffusion téléchargeable. -- Ajout du flag "fermé" pour les structures et utilisations dans la recherche de thèses. -- Ajout d'un champ "Id HAL" dans le formulaire d'autorisation de diffusion. +- Ajout du flag 'fermé' pour les structures et utilisations dans la recherche de thèses. +- Ajout d'un champ 'Id HAL' dans le formulaire d'autorisation de diffusion. - Ajout d'un menu dépôt pour séparer les action liés au dépôt de la partie annuaire - La couverture est maintenant recto/verso lorsque la premiere page n'est pas retirée - Ajout de la colonne durée des thèses dans l'export @@ -752,7 +763,7 @@ Idem pour les attestations et le privilège "Modification des attestations conce - Convention de mise en ligne : - Le libellé du tribunal compétent mentionné est importé de chaque établissement. - - Utilisation de la mention générique "Le chef d'établissement" plutôt que d'exploiter les libellés + - Utilisation de la mention générique 'Le chef d'établissement' plutôt que d'exploiter les libellés importés des établissements. - Nouvelle ligne de commande pour importer une thèse à la demande. @@ -763,7 +774,7 @@ Idem pour les attestations et le privilège "Modification des attestations conce - Améliorations pour utiliser moins de mémoire ; meilleurs logs. - Correction des exceptions de type `ORA-00001: unique constraint (SYGAL.TMP_ACTEUR_UNIQ) violated` par un changement de stratégie côté web service (interrogation de tables plutôt que des vues). -- Le bouton d'import d'une thèse à la demande avait disparu (menu "Page de couverture") à cause d'une config erronée. +- Le bouton d'import d'une thèse à la demande avait disparu (menu 'Page de couverture') à cause d'une config erronée. 1.2.11 (13/11/2019) ------------------ @@ -782,7 +793,7 @@ Idem pour les attestations et le privilège "Modification des attestations conce ### Ajout - Un message avertissant des formats d'image valide est maintenant ajouté dans les pages de modification des structures concertes -- Utilisation de convert (imagemagick) pour convertir les logos "automatiquement" au format png +- Utilisation de convert (imagemagick) pour convertir les logos 'automatiquement' au format png 1.2.9 (24/10/2019) ------------------ @@ -852,19 +863,19 @@ Idem pour les attestations et le privilège "Modification des attestations conce ### Ajout -- Nouvelle page consacrée au dépôt de fichiers divers liés à une thèse (précédemment dans la page "Thèse"). -- Possibilité de déposer des fichiers dits "communs" utiles aux gestionnaires, ex: modèle d'avenant à la convention +- Nouvelle page consacrée au dépôt de fichiers divers liés à une thèse (précédemment dans la page 'Thèse'). +- Possibilité de déposer des fichiers dits 'communs' utiles aux gestionnaires, ex: modèle d'avenant à la convention de mise en ligne. ### Améliorations -- Améliorations de la page "Privilèges", notamment le filtrage par rôle. +- Améliorations de la page 'Privilèges', notamment le filtrage par rôle. - Déplacement des privilèges de la catégorie `fichier-divers` vers la catégorie `these` car ils concernent des fichiers liés à une thèse (ex: PV de soutenance). La catégorie `fichier-divers` désigne désormais les privilèges concernant des fichiers sans lien aux thèses (ex: fichiers déposés pour les pages d'informations). - Refonte technique de la gestion des fichiers liés aux pages d'informations, prélable au travail sur les droits de - dépôt de fichiers "divers" et "communs". + dépôt de fichiers 'divers' et 'communs'. 1.2.0 (10/07/2019) diff --git a/doc/release-notes/v6.0.6.md b/doc/release-notes/v6.0.6.md index 54a7f04a8f547f196f56d3703a3a908540bdec43..ba1620098ea9504dc6fdf138beeb498081b5da37 100644 --- a/doc/release-notes/v6.0.6.md +++ b/doc/release-notes/v6.0.6.md @@ -1,4 +1,4 @@ -# Version 6.0.5 +# Version 6.0.6 ## 1. Sur le serveur d'application @@ -8,7 +8,7 @@ pour installer la nouvelle version : ```bash -git fetch --tags && git checkout --force 6.0.5 && bash ./install.sh +git fetch --tags && git checkout --force 6.0.6 && bash ./install.sh ``` - Rechargez le moteur PHP, exemple : @@ -20,6 +20,9 @@ systemctl reload php8.0-fpm ## 2. Dans la base de données ```postgresql +alter table structure + alter column type_structure_id set not null; + -- INSERTION DE NOUVELLES MACROS -- INSERT INTO unicaen_renderer_macro (code, description, variable_name, methode_name) VALUES ('Acteur#Denomination', '<p>Retourne la dénomination de l''acteur sous la forme - Prénom Nom -</p>', 'acteur', 'getDenomination'); INSERT INTO unicaen_renderer_macro (code, description, variable_name, methode_name) VALUES ('Acteur#Etablissement', '<p>Retourne le libellé de l''établissement du co-encadrant</p>', 'acteur', 'getEtablissementAsLibelle'); @@ -28,5 +31,213 @@ INSERT INTO unicaen_renderer_macro (code, description, variable_name, methode_na INSERT INTO unicaen_renderer_template (code, description, document_type, document_sujet, document_corps, document_css, namespace) VALUES ('COENCADREMENTS_JUSTIFICATIF', null, 'pdf', 'Justificatif de co-encadrements de VAR[Acteur#Denomination]', e'<h1>Justificatif de co-encadrements</h1> <p>Ce document certifie que VAR[Acteur#Denomination], actuellement VAR[Acteur#Qualite] à VAR[Acteur#Etablissement], a assuré la fonction de co-encadrant sur pour les thèses suivantes :<br />###LISTING_THESE###</p>', null, 'These\Provider\Template'); +-- +-- Nouvelle vue pour l'extraction CSV des thèses. +-- +drop view if exists v_extract_theses; +create or replace view v_extract_theses as + with mails_contacts as ( + select distinct individu_id, + first_value(email) over (partition by individu_id order by id desc) email + from mail_confirmation + where etat = 'C'/*confirmé*/ + ), directeurs as ( + select these_id, + string_agg(concat(i.nom_usuel, ' ', i.prenom1), ' ; ') identites + from acteur a + join role r on a.role_id = r.id and r.code = 'D' + join individu i on a.individu_id = i.id + where a.histo_destruction is null + group by these_id + ), codirecteurs as ( + select these_id, + string_agg(concat(i.nom_usuel, ' ', i.prenom1), ' ; ') identites + from acteur a + join role r on a.role_id = r.id and r.code in ('C','K') + join individu i on a.individu_id = i.id + where a.histo_destruction is null + group by these_id + ), coencadrants as ( + select these_id, + string_agg(concat(i.nom_usuel, ' ', i.prenom1), ' ; ') identites + from acteur a + join role r on a.role_id = r.id and r.code in ('B','N') + join individu i on a.individu_id = i.id + where a.histo_destruction is null + group by these_id + ), financements as ( + select these_id, + string_agg(case o.visible when true then 'O' else 'N' end, ' ; ') financ_origs_visibles, + string_agg(f.annee::varchar, ' ; ') financ_annees, + string_agg(o.libelle_long, ' ; ') financ_origs, + string_agg(f.complement_financement, ' ; ') financ_compls, + string_agg(f.libelle_type_financement, ' ; ') financ_types + from financement f + join origine_financement o on f.origine_financement_id = o.id + where f.histo_destruction is null + group by these_id + ), domaines as ( + select unite_id, + string_agg(d.libelle, ' ; ') libelles + from unite_domaine_linker udl + join domaine_scientifique d on d.id = udl.domaine_id + group by unite_id + ), depots_vo_pdf as ( + select distinct these_id, + first_value(vf.code) over (partition by these_id order by ft.id desc) version_code, + first_value(f.histo_creation) over (partition by these_id order by ft.id desc) histo_creation + from fichier_these ft + join fichier f on ft.fichier_id = f.id and f.histo_destruction is null + join nature_fichier nf on f.nature_id = nf.id and nf.code = 'THESE_PDF' + join version_fichier vf on f.version_fichier_id = vf.id and vf.code = 'VO' + ), depots_voc_pdf as ( + select distinct these_id, + first_value(vf.code) over (partition by these_id order by ft.id desc) version_code, + first_value(f.histo_creation) over (partition by these_id order by ft.id desc) histo_creation + from fichier_these ft + join fichier f on ft.fichier_id = f.id and f.histo_destruction is null + join nature_fichier nf on f.nature_id = nf.id and nf.code = 'THESE_PDF' + join version_fichier vf on f.version_fichier_id = vf.id and vf.code = 'VOC' + ), depots_non_pdf as ( + select distinct these_id, + first_value(vf.code) over (partition by these_id order by ft.id desc) version_code, + first_value(f.histo_creation) over (partition by these_id order by ft.id desc) histo_creation + from fichier_these ft + join fichier f on ft.fichier_id = f.id and f.histo_destruction is null + join nature_fichier nf on f.nature_id = nf.id and nf.code = 'FICHIER_NON_PDF' + join version_fichier vf on f.version_fichier_id = vf.id and vf.code in ('VO', 'VOC') + ), diffusion as ( + select distinct these_id, + first_value(autoris_mel) over (partition by these_id order by version_corrigee desc, id desc) autoris_mel, + first_value(autoris_embargo_duree) over (partition by these_id order by version_corrigee desc, id desc) autoris_embargo_duree, + first_value(autoris_motif) over (partition by these_id order by version_corrigee desc, id desc) autoris_motif + from diffusion d + where histo_destruction is null + ), dernier_rapport_activite as ( + select distinct these_id, + first_value(annee_univ) over (partition by these_id order by annee_univ desc) annee + from rapport_activite ra + where ra.histo_destruction is null + ), dernier_rapport_csi as ( + select distinct these_id, + first_value(annee_univ) over (partition by these_id order by annee_univ desc) annee + from rapport r + join type_rapport tr on r.type_rapport_id = tr.id and tr.code = 'RAPPORT_CSI' + where r.histo_destruction is null + ) + select to_char(current_timestamp,'DD/MM/YYYY HH24:MI:SS') date_extraction, + th.id, + di.civilite, + di.nom_usuel, + di.nom_patronymique, + di.prenom1, + to_char(di.date_naissance,'DD/MM/YYYY') date_naissance, + di.nationalite, + coalesce(dic.email, di.email) email_pro, + mc.email email_contact, + d.ine, + substr(d.source_code, strpos(d.source_code, '::') + 2) num_etudiant, + th.source_code num_these, + th.titre, + th.code_sise_disc, + th.lib_disc, + dirs.identites dirs, + codirs.identites codirs, + coencs.identites coencs, + coalesce(se2.libelle, se.libelle) etab_lib, + coalesce(sed2.code, sed.code) ed_code, + coalesce(sed2.libelle, sed.libelle) ed_lib, + coalesce(sur2.code, sur.code) ur_code, + coalesce(sur2.libelle, sur.libelle) ur_lib, + th.lib_etab_cotut, + th.lib_pays_cotut, + ta.libelle_titre_acces, + ta.libelle_etb_titre_acces, + f.financ_origs_visibles, + f.financ_annees, + f.financ_origs, + f.financ_compls, + f.financ_types, + dom.libelles domaines, + to_char(th.date_prem_insc,'DD/MM/YYYY') date_prem_insc, to_char(th.date_abandon,'DD/MM/YYYY') date_abandon, + to_char(th.date_transfert,'DD/MM/YYYY') date_transfert, to_char(th.date_prev_soutenance,'DD/MM/YYYY') date_prev_soutenance, + to_char(th.date_soutenance,'DD/MM/YYYY') date_soutenance, to_char(th.date_fin_confid,'DD/MM/YYYY') date_fin_confid, + round((th.date_soutenance::date - th.date_prem_insc::date) / 30.5, 2) duree_these_mois, + to_char(depots_vo_pdf.histo_creation,'DD/MM/YYYY') date_depot_vo, + to_char(depots_voc_pdf.histo_creation,'DD/MM/YYYY') date_depot_voc, + case th.etat_these when 'E' then 'En cours' when 'A' then 'Abandonnée' when 'S' then 'Soutenue' when 'U' then 'Transférée' end etat_these, + th.soutenance_autoris, + case when th.date_fin_confid is null or th.date_fin_confid < current_timestamp then 'N' else 'O' end confidentielle, + th.resultat, + case when th.correc_autorisee_forcee = 'aucune' then 'N' else coalesce(th.correc_autorisee_forcee, th.correc_autorisee) end correc_autorisee, + case when depots_vo_pdf.these_id is null and depots_voc_pdf.these_id is null then 'N' else 'O' end depot_pdf, + case when depots_non_pdf.these_id is null then 'N' else 'O' end depot_annexe, + case diff.autoris_mel when 0 then 'Non' when 1 then 'Oui, avec embargo' when 2 then 'Oui, immédiatement' end autoris_mel, + diff.autoris_embargo_duree, + diff.autoris_motif, + case when ract.annee is not null then concat(ract.annee,'/',ract.annee+1) else null end dernier_rapport_activite, + case when rcsi.annee is not null then concat(rcsi.annee,'/',rcsi.annee+1) else null end dernier_rapport_csi + from these th + join doctorant d on th.doctorant_id = d.id + join individu di on d.individu_id = di.id + left join individu_compl dic on di.id = dic.individu_id and dic.histo_destruction is null + left join mails_contacts mc on mc.individu_id = di.id + join etablissement e on d.etablissement_id = e.id + join structure se on e.structure_id = se.id + left join structure_substit ses on se.id = ses.from_structure_id and ses.histo_destruction is null + left join structure se2 on se2.id = ses.to_structure_id + left join ecole_doct ed on th.ecole_doct_id = ed.id + left join structure sed on ed.structure_id = sed.id + left join structure_substit seds on sed.id = seds.from_structure_id and seds.histo_destruction is null + left join structure sed2 on sed2.id = seds.to_structure_id + left join unite_rech ur on th.unite_rech_id = ur.id + left join structure sur on ur.structure_id = sur.id + left join structure_substit surs on sur.id = surs.from_structure_id and surs.histo_destruction is null + left join structure sur2 on sur2.id = surs.to_structure_id + left join domaines dom on dom.unite_id = ur.id + left join titre_acces ta on th.id = ta.these_id and ta.histo_destruction is null + left join financements f on th.id = f.these_id + left join directeurs dirs on dirs.these_id = th.id + left join codirecteurs codirs on codirs.these_id = th.id + left join coencadrants coencs on coencs.these_id = th.id + left join depots_vo_pdf on depots_vo_pdf.these_id = th.id + left join depots_voc_pdf on depots_voc_pdf.these_id = th.id + left join depots_non_pdf on depots_non_pdf.these_id = th.id + left join diffusion diff on diff.these_id = th.id + left join dernier_rapport_activite ract on ract.these_id = th.id + left join dernier_rapport_csi rcsi on rcsi.these_id = th.id + where th.histo_destruction is null +; + + +create or replace function transfert_these(fromtheseid bigint, totheseid bigint) returns void + language plpgsql +as +$$ +BEGIN + -- select 'update '||rpad(table_name, 35)||' set '||column_name||' = totheseid where '||column_name||' = fromtheseid ;' from information_schema.columns +-- where column_name ilike 'these_id' and +-- table_name not ilike 'v\_%' and +-- table_name not ilike 'src_%' and +-- table_name not ilike 'tmp_%' and +-- lower(table_name) not in ('acteur', 'financement', 'these_annee_univ', 'titre_acces', 'step_star_log'); + + --update soutenance_proposition set histo_destruction = now(), histo_destructeur_id = 1 where these_id = totheseid ; + + update attestation set these_id = totheseid where these_id = fromtheseid ; + update diffusion set these_id = totheseid where these_id = fromtheseid ; + update fichier_these set these_id = totheseid where these_id = fromtheseid ; + update metadonnee_these set these_id = totheseid where these_id = fromtheseid ; + update rapport set these_id = totheseid where these_id = fromtheseid ; + update rdv_bu set these_id = totheseid where these_id = fromtheseid ; + update soutenance_intervention set these_id = totheseid where these_id = fromtheseid ; + update soutenance_proposition set these_id = totheseid where these_id = fromtheseid ; + update validation set these_id = totheseid where these_id = fromtheseid ; + update csi_membre set these_id = totheseid where these_id = fromtheseid ; + update rapport_activite set these_id = totheseid where these_id = fromtheseid ; + + refresh materialized view mv_recherche_these; +END; +$$; ``` \ No newline at end of file diff --git a/module/Application/config/others/export.config.php b/module/Application/config/others/export.config.php index c06e427a15cac3fbe2e60520667f3d4304669dde..f73e85dac79e9812ffa6f7a5421e6eba93a2bb63 100755 --- a/module/Application/config/others/export.config.php +++ b/module/Application/config/others/export.config.php @@ -1,5 +1,6 @@ <?php +use Application\Controller\ExportController; use Application\Controller\Factory\ExportControllerFactory; use These\Provider\Privilege\ThesePrivileges; use UnicaenAuth\Guard\PrivilegeController; @@ -9,7 +10,7 @@ return [ 'guards' => [ PrivilegeController::class => [ [ - 'controller' => 'Application\Controller\Export', + 'controller' => ExportController::class, 'action' => [ 'csv', ], @@ -25,8 +26,7 @@ return [ 'options' => [ 'route' => '/export', 'defaults' => [ - '__NAMESPACE__' => 'Application\Controller', - 'controller' => 'Export', + 'controller' => ExportController::class, ], ], 'may_terminate' => false, @@ -36,6 +36,7 @@ return [ 'options' => [ 'route' => '/csv', 'defaults' => [ + /** @see ExportController::csvAction() */ 'action' => 'csv', ], ], @@ -51,7 +52,7 @@ return [ ], 'controllers' => [ 'factories' => [ - 'Application\Controller\Export' => ExportControllerFactory::class, + ExportController::class => ExportControllerFactory::class, ], ], ]; \ No newline at end of file diff --git a/module/Application/src/Application/Assertion/Rapport/RapportPageAssertion.php b/module/Application/src/Application/Assertion/Rapport/RapportPageAssertion.php index 9aa0b7aeb383bd8065eb6ceb2c67ae9fff4748cc..04d73f230617cee8407d65130838149e33a149dc 100644 --- a/module/Application/src/Application/Assertion/Rapport/RapportPageAssertion.php +++ b/module/Application/src/Application/Assertion/Rapport/RapportPageAssertion.php @@ -57,7 +57,7 @@ class RapportPageAssertion implements PageAssertionInterface, UserContextService $role = $this->userContextService->getSelectedIdentityRole(); // rôle doctorant - if ($role->isDoctorant()) { + if ($role && $role->isDoctorant()) { $doctorant = $this->userContextService->getIdentityDoctorant(); $this->assertTrue( $this->these->getDoctorant()->getId() === $doctorant->getId(), diff --git a/module/Application/src/Application/Controller/ExportController.php b/module/Application/src/Application/Controller/ExportController.php index c64e7510f9dad9e0c73668afbfdad356ebe31375..da03865ef8a952d3f3e596505742aa87fb6f2639 100644 --- a/module/Application/src/Application/Controller/ExportController.php +++ b/module/Application/src/Application/Controller/ExportController.php @@ -2,16 +2,14 @@ namespace Application\Controller; -use These\Entity\Db\Acteur; -use Application\Entity\Db\Financement; -use Application\Entity\Db\Role; -use These\Entity\Db\These; +use Application\Entity\Db\OrigineFinancement; use Application\Provider\Privilege\FinancementPrivileges; +use Application\SourceCodeStringHelperAwareTrait; use Depot\Service\FichierThese\FichierTheseServiceAwareTrait; +use Doctrine\DBAL\Exception; +use RuntimeException; use These\Service\These\TheseSearchServiceAwareTrait; use These\Service\These\TheseServiceAwareTrait; -use Application\SourceCodeStringHelperAwareTrait; -use UnicaenApp\Exception\LogicException; use UnicaenApp\View\Model\CsvModel; class ExportController extends AbstractController @@ -21,144 +19,90 @@ class ExportController extends AbstractController use FichierTheseServiceAwareTrait; use SourceCodeStringHelperAwareTrait; - public function csvAction() + public function csvAction(): CsvModel { + $originesFinancementsFilter = function ($r) { + if (empty($r['financ_origs'])) { + return null; + } + // certaines origines ne sont pas visibles par tout le monde (ex : handicap) + $origines = array_map('trim', explode(';', $r['financ_origs'])); + $visibles = array_map('trim', explode(';', $r['financ_origs_visibles'])); + $filteredOrigines = []; + foreach ($origines as $i => $orig) { + $isVisible = ['O'=>true,'N'=>false][$visibles[$i]]; + if ($isVisible || $this->isAllowed(new OrigineFinancement(), FinancementPrivileges::FINANCEMENT_VOIR_ORIGINE_NON_VISIBLE)) { + $filteredOrigines[] = $orig; + } + } + return implode(" ; ", $filteredOrigines); + }; + $headers = [ + 'id' => fn($r) => $r['id'], // Doctorant - 'Civilité' => function ($variables) { return $variables['doctorant']->getIndividu()->getCivilite(); }, - 'Nom usuel' => function ($variables) { return $variables['doctorant']->getIndividu()->getNomUsuel(); }, - 'Prenom' => function ($variables) { return $variables['doctorant']->getIndividu()->getPrenom(); }, - 'Nom patronymique' => function ($variables) { return $variables['doctorant']->getIndividu()->getNomPatronymique(); }, - 'Date de naissance' => function ($variables) { return $variables['doctorant']->getIndividu()->getDateNaissance(); }, - 'Nationalité' => function ($variables) { return $variables['doctorant']->getIndividu()->getNationalite(); }, - 'Adresse électronique' => function ($variables) { return $variables['doctorant']->getIndividu()->getEmailPro(); }, - 'Adresse électronique personnelle' => function ($variables) { return $variables['doctorant']->getIndividu()->getEmailContact(); }, - 'Numéro étudiant' => function ($variables) { return $this->sourceCodeStringHelper->removePrefixFrom($variables['doctorant']->getSourceCode()); }, - 'I.N.E.' => function ($variables) { return $variables['doctorant']->getIne(); }, + 'Civilité' => fn($r) => $r['civilite'], + 'Nom usuel' => fn($r) => $r['nom_usuel'], + 'Prenom' => fn($r) => $r['prenom1'], + 'Nom patronymique' => fn($r) => $r['nom_patronymique'], + 'Date de naissance' => fn($r) => $r['date_naissance'], + 'Nationalité' => fn($r) => $r['nationalite'], + 'Adresse électronique' => fn($r) => $r['email_pro'], + 'Adresse électronique personnelle' => fn($r) => $r['email_contact'], + 'Numéro étudiant' => fn($r) => $r['num_etudiant'], + 'I.N.E.' => fn($r) => $r['ine'], //These - 'Identifiant de la thèse' => function ($variables) { return $variables['these']->getSourceCode(); }, - 'Titre' => function ($variables) { return $variables['these']->getTitre(); }, - 'Discipline' => function ($variables) { return $variables['these']->getLibelleDiscipline(); }, + 'Identifiant de la thèse' => fn($r) => $r['num_these'], + 'Titre' => fn($r) => $r['titre'], + 'Discipline Code SISE' => fn($r) => $r['code_sise_disc'], + 'Discipline' => fn($r) => $r['lib_disc'], //Encadrements - 'Directeurs' => function ($variables) { - $directeurs = $variables['directeurs']; - $noms = []; - /** @var Acteur $directeur */ - foreach ($directeurs as $directeur) $noms[] = $directeur->getIndividu()->getNomComplet(); - return implode(",", $noms); - }, - 'Co-directeurs' => function ($variables) { - $directeurs = $variables['co-directeurs']; - $noms = []; - /** @var Acteur $directeur */ - foreach ($directeurs as $directeur) $noms[] = $directeur->getIndividu()->getNomComplet(); - return implode(",", $noms); - }, - 'Co-encadrants' => function ($variables) { - $acteurs = $variables['co-encadrants']; - $noms = []; - /** @var Acteur $acteurs */ - foreach ($acteurs as $directeur) $noms[] = $directeur->getIndividu()->getNomComplet(); - return implode(",", $noms); - }, + 'Directeurs' => fn($r) => $r['dirs'], + 'Co-directeurs' => fn($r) => $r['codirs'], + 'Co-encadrants' => fn($r) => $r['coencs'], //Structures - 'Etablissement' => function ($variables) { return $variables['etablissement']->getStructure()->getLibelle(); }, - 'Ecole Doctorale Code' => function ($variables) { return ($variables['ecole doctorale'])?$variables['ecole doctorale']->getStructure()->getCode():null; }, - 'Ecole Doctorale' => function ($variables) { return ($variables['ecole doctorale'])?$variables['ecole doctorale']->getStructure()->getLibelle():null; }, - 'Unité de Recherche Code' => function ($variables) { return ($variables['unite de recherche'])?$variables['unite de recherche']->getStructure()->getCode():null; }, - 'Unité de Recherche' => function ($variables) { return ($variables['unite de recherche'])?$variables['unite de recherche']->getStructure()->getLibelle():null; }, - 'Etablissement Co-Tutelle' => function ($variables) { return $variables['these']->getLibelleEtabCotutelle(); }, - 'Pays Co-Tutelle' => function ($variables) { return $variables['these']->getLibellePaysCotutelle(); }, + 'Etablissement' => fn($r) => $r['etab_lib'], + 'Ecole Doctorale Code' => fn($r) => $r['ed_code'], + 'Ecole Doctorale' => fn($r) => $r['ed_lib'], + 'Unité de Recherche Code' => fn($r) => $r['ur_code'], + 'Unité de Recherche' => fn($r) => $r['ur_lib'], + 'Etablissement Co-Tutelle' => fn($r) => $r['lib_etab_cotut'], + 'Pays Co-Tutelle' => fn($r) => $r['lib_pays_cotut'], //accession - 'Diplôme d\'accession à la thèse' => function ($variables) { return ($variables['these']->getTitreAcces())?$variables['these']->getTitreAcces()->getLibelleTitreAcces():null; }, - 'Établissement d\'accession à la thèse' => function ($variables) { return ($variables['these']->getTitreAcces())?$variables['these']->getTitreAcces()->getLibelleEtabTitreAcces():null; }, + "Diplôme d'accession à la thèse" => fn($r) => $r['libelle_titre_acces'], + "Établissement d'accession à la thèse" => fn($r) => $r['libelle_etb_titre_acces'], //Financements - 'Origines du financement' => function ($variables) { - $these = $variables['these']; - $financements = $these->getFinancements(); - $origines = []; - /** @var Financement $financement */ - foreach ($financements as $financement) { - $origine = $financement->getOrigineFinancement(); - if ($origine->isVisible() || $this->isAllowed($origine, FinancementPrivileges::FINANCEMENT_VOIR_ORIGINE_NON_VISIBLE)) { - $origines[] = $origine->getLibelleLong(); - } - } - return implode(",", $origines); - }, - 'Complément sur les financements' => function ($variables) { - $these = $variables['these']; - $financements = $these->getFinancements(); - $origines = []; - /** @var Financement $financement */ - foreach ($financements as $financement) $origines[] = ($financement->getComplementFinancement())?:" - "; - return implode(",", $origines); - }, - 'Type du financement' => function ($variables) { - $these = $variables['these']; - $financements = $these->getFinancements(); - $types = []; - /** @var Financement $financement */ - foreach ($financements as $financement) $types[] = $financement->getLibelleTypeFinancement(); - return implode(",", array_filter($types)); - }, + 'Années financées' => fn($r) => $r['financ_annees'], + 'Origines du financement' => $originesFinancementsFilter, + 'Complément sur les financements' => fn($r) => $r['financ_compls'], + 'Type du financement' => fn($r) => $r['financ_types'], //Domaine - 'Domaines scientifiques' => function ($variables) { - $unite = $variables['unite de recherche']; - $domaines = ($unite)?$unite->getDomaines():[]; - $liste = []; - /** @var Financement $financement */ - foreach ($domaines as $domaine) $liste[] = $domaine->getLibelle(); - return implode(",", $liste); - }, + 'Domaines scientifiques' => fn($r) => $r['domaines'], //Dates - 'Date de première inscription' => function ($variables) { return $variables['these']->getDatePremiereInscription(); }, - "Date d'abandon" => function ($variables) { return $variables['these']->getDateAbandon(); }, - 'Date de transfert' => function ($variables) { return $variables['these']->getDateTransfert(); }, - 'Date de prévisionnel de soutenance' => function ($variables) { return $variables['these']->getDatePrevisionSoutenance(); }, - 'Date de soutenance' => function ($variables) { return $variables['these']->getDateSoutenance(); }, - 'Date de fin de confientialité' => function ($variables) { return $variables['these']->getDateFinConfidentialite(); }, - 'Date de dépôt version initiale' => function ($variables) { return ($variables['version_initiale'])?$variables['version_initiale']->getFichier()->getHistoCreation()->format('d/m/Y'):"";}, - 'Date de dépôt version corigée' => function ($variables) { return ($variables['version_corrigee'])?$variables['version_corrigee']->getFichier()->getHistoCreation()->format('d/m/Y'):"";}, - 'Durée en mois de la thèse' => function ($variables) { try { return number_format($variables['these']->getDureeThese(), 2, ',', ''); } catch (LogicException $e) { return ""; } }, + 'Date de première inscription' => fn($r) => $r['date_prem_insc'], + "Date d'abandon" => fn($r) => $r['date_abandon'], + 'Date de transfert' => fn($r) => $r['date_transfert'], + 'Date de prévisionnel de soutenance' => fn($r) => $r['date_prev_soutenance'], + 'Date de soutenance' => fn($r) => $r['date_soutenance'], + 'Date de fin de confientialité' => fn($r) => $r['date_fin_confid'], + 'Date de dépôt version initiale' => fn($r) => $r['date_depot_vo'], + 'Date de dépôt version corrigée' => fn($r) => $r['date_depot_voc'], + 'Durée en mois de la thèse' => fn($r) => $r['duree_these_mois'], //Flags - 'Etat de la thèse' => function ($variables) { return $variables['these']->getEtatTheseToString();}, - 'Autorisation à soutenir' => function ($variables) { return $variables['these']->getSoutenanceAutorisee();}, - 'Est confidentielle' => function ($variables) { $now = new \DateTime(); $end= $variables['these']->getDateFinConfidentialite(); if ($now > $end) return "N"; else return "O"; }, - 'Résultat' => function ($variables) { return $variables['these']->getResultat();}, - 'Corrections' => function ($variables) { return $variables['these']->getCorrectionAutorisee();}, - 'Thèse format PDF' => function ($variables) { return $variables['version_initiale']?'O':'N'; }, - 'Annexe non PDF' => function ($variables) { return $variables['annexe']?'O':'N'; }, -// - //Embargo et refus de diffusion - 'Embargo' => function ($variables) { - $these = $variables['these']; - $versionInitiale = $variables['version_initiale']; - $versionCorrigee = $variables['version_corrigee']; - if ($versionCorrigee !== null) { - $diffusionCorrigee = $these->getDiffusionForVersion($versionCorrigee->getFichier()->getVersion()); - if ($diffusionCorrigee !== null) return $diffusionCorrigee->getAutorisEmbargoDuree(); - } - if ($versionInitiale !== null) { - $diffusionInitiale = $these->getDiffusionForVersion($versionInitiale->getFichier()->getVersion()); - if ($diffusionInitiale !== null) return $diffusionInitiale->getAutorisEmbargoDuree(); - } - return null; - }, - 'Refus de diffusion' => function ($variables) { - $these = $variables['these']; - $versionInitiale = $variables['version_initiale']; - $versionCorrigee = $variables['version_corrigee']->getVersion; - if ($versionCorrigee !== null) { - $diffusionCorrigee = $these->getDiffusionForVersion($versionCorrigee->getFichier()->getVersion()); - if ($diffusionCorrigee !== null) return $diffusionCorrigee->getAutorisMotif(); - } - if ($versionInitiale !== null) { - $diffusionInitiale = $these->getDiffusionForVersion($versionInitiale->getFichier()->getVersion()); - if ($diffusionInitiale !== null) return $diffusionInitiale->getAutorisMotif(); - } - return null; - }, + 'Etat de la thèse' => fn($r) => $r['etat_these'], + 'Autorisation à soutenir' => fn($r) => $r['soutenance_autoris'], + 'Est confidentielle' => fn($r) => $r['confidentielle'], + 'Résultat' => fn($r) => $r['resultat'], + 'Corrections' => fn($r) => $r['correc_autorisee'], + 'Thèse format PDF' => fn($r) => $r['depot_pdf'], + 'Annexe non PDF' => fn($r) => $r['depot_annexe'], + //Diffusion + 'Autorisation de MEL' => fn($r) => $r['autoris_mel'], + 'Embargo' => fn($r) => $r['autoris_embargo_duree'], + 'Refus de diffusion' => fn($r) => $r['autoris_motif'], + //Rapports + "Dernier rapport d'activité" => fn($r) => $r['dernier_rapport_activite'], + "Dernier rapport CSI" => fn($r) => $r['dernier_rapport_csi'], ]; $queryParams = $this->params()->fromQuery(); @@ -166,37 +110,40 @@ class ExportController extends AbstractController $this->theseSearchService->init(); $this->theseSearchService->processQueryParams($queryParams); $qb = $this->theseSearchService->getQueryBuilder(); - $theses = $qb->getQuery()->getResult(); + $qb->select('these'); // pas besoin de tout sélectionner, seuls les ids nous intéressent + $theses = $qb->getQuery()->getArrayResult(); + $thesesIds = array_map(fn(array $t) => $t['id'], $theses); // extraction des 'id' + + // on fragmente la liste des id pour éviter de dépasser le nombre maxi de termes autorisés dans un IN() + $wheres = array_map( + fn(string $ids) => "id in ($ids)", + array_map( + fn(array $ids) => implode(',', $ids), + array_chunk($thesesIds, 3000) + ) + ); + $sql = sprintf('select * from v_extract_theses where %s', implode(' or ', $wheres)); + try { + $records = $qb->getEntityManager()->getConnection()->executeQuery($sql)->fetchAllAssociative(); + } catch (Exception $e) { + throw new RuntimeException("Erreur rencontrée lors de l'exécution de la requête SQL", null, $e); + } - $records = []; - for ($i = 0 ; $i < count($theses) ; $i++) { - /** @var These $these */ - $these = $theses[$i]; - $record = []; - foreach($headers as $key => $fct) { - $variables = [ - 'these' => $these, - 'doctorant' => $these->getDoctorant(), - 'directeurs' => $these->getActeursByRoleCode(Role::CODE_DIRECTEUR_THESE), - 'co-directeurs' => $these->getActeursByRoleCode(Role::CODE_CODIRECTEUR_THESE), - 'co-encadrants' => $these->getActeursByRoleCode(Role::CODE_CO_ENCADRANT), - 'etablissement' => $these->getEtablissement(), - 'ecole doctorale' => $these->getEcoleDoctorale(), - 'unite de recherche' => $these->getUniteRecherche(), - 'version_initiale' => $these->hasVersionInitiale(), - 'version_corrigée' => $these->hasVersionCorrigee(), - 'annexe' => $these->hasAnnexe(), - ]; - $record[] = $fct($variables); + $data = []; + foreach ($records as $r) { + $row = []; + /** @var callable $fct */ + foreach ($headers as $fct) { + $row[] = $fct($r); } - $records[] = $record; + $data[] = $row; } $result = new CsvModel(); $result->setDelimiter(';'); - $result->setEnclosure('"'); + $result->setEnclosure('"'); // indispensable car il peut y avoir des ; dans les données $result->setHeader(array_keys($headers)); - $result->setData($records); + $result->setData($data); $result->setFilename('export_theses.csv'); return $result; diff --git a/module/Application/src/Application/Controller/UtilisateurController.php b/module/Application/src/Application/Controller/UtilisateurController.php index 7e5ea56fbb615894275a143652c9e1b6f636ef26..76de3e40a11974d36e5577b9f7a9fe5ecd923716 100644 --- a/module/Application/src/Application/Controller/UtilisateurController.php +++ b/module/Application/src/Application/Controller/UtilisateurController.php @@ -275,7 +275,7 @@ class UtilisateurController extends \UnicaenAuth\Controller\UtilisateurControlle $this->flashMessenger()->addSuccessMessage("Utilisateur <strong>{$utilisateur->getUsername()}</strong> créé avec succès."); - return $this->redirect()->toRoute('utilisateur'); + return $this->redirect()->toRoute('utilisateur/voir', ['utilisateur' => $utilisateur->getId()], [], true); } } diff --git a/module/Application/src/Application/Form/Validator/NewEmailValidator.php b/module/Application/src/Application/Form/Validator/NewEmailValidator.php index e584e31b4b98b88f86f648f739b8052effedc865..358d27f2df93e562d5b1d51072a5b2b46acc92e3 100644 --- a/module/Application/src/Application/Form/Validator/NewEmailValidator.php +++ b/module/Application/src/Application/Form/Validator/NewEmailValidator.php @@ -34,7 +34,7 @@ class NewEmailValidator extends AbstractValidator $perimetre = $this->getPerimetre(); if (in_array('utilisateur', $perimetre)) { - if ($this->entityManager->getRepository(Utilisateur::class)->findOneBy(['email' => $value]) !== null) { + if ($this->entityManager->getRepository(Utilisateur::class)->findOneBy(['username' => $value]) !== null) { $this->error(self::UTILISATEUR); $nb_pb++; } diff --git a/module/Depot/src/Depot/Service/FichierThese/FichierTheseServiceFactory.php b/module/Depot/src/Depot/Service/FichierThese/FichierTheseServiceFactory.php index 268145630d6b71c206269634345219a3421f320e..94888984678ecdf60033d6126554c9a463626145 100644 --- a/module/Depot/src/Depot/Service/FichierThese/FichierTheseServiceFactory.php +++ b/module/Depot/src/Depot/Service/FichierThese/FichierTheseServiceFactory.php @@ -65,6 +65,8 @@ class FichierTheseServiceFactory /** @var PageDeCouverturePdfExporter $pdcPdfExporter */ $pdcPdfExporter = $container->get(PageDeCouverturePdfExporter::class); $pdcPdfExporter + ->setMarginTop(5) + ->setMarginBottom(5) ->setTemplateFilePath($templateFilePath) ->setCssFilePath($cssFilePath); diff --git a/module/Individu/config/individu.config.php b/module/Individu/config/individu.config.php index e721e1c10519f4fe4c1d6959d6a8afdef7b57ca6..e1bcbe5b8e60db38ad5aef49a4747aa046f27a53 100644 --- a/module/Individu/config/individu.config.php +++ b/module/Individu/config/individu.config.php @@ -3,6 +3,8 @@ namespace Individu; use BjyAuthorize\Provider\Resource\Config; +use Individu\Assertion\IndividuAssertion; +use Individu\Assertion\IndividuAssertionFactory; use Individu\Controller\IndividuController; use Individu\Controller\IndividuControllerFactory; use Individu\Form\IndividuForm; @@ -46,27 +48,27 @@ return [ [ 'controller' => IndividuController::class, 'action' => ['index', 'rechercher'], - 'privilege' => IndividuPrivileges::INDIVIDU_LISTER, + 'privileges' => IndividuPrivileges::INDIVIDU_LISTER, ], [ 'controller' => IndividuController::class, 'action' => ['voir'], - 'privilege' => IndividuPrivileges::INDIVIDU_CONSULTER, + 'privileges' => IndividuPrivileges::INDIVIDU_CONSULTER, ], [ 'controller' => IndividuController::class, 'action' => ['ajouter'], - 'privilege' => IndividuPrivileges::INDIVIDU_AJOUTER, + 'privileges' => IndividuPrivileges::INDIVIDU_AJOUTER, ], [ 'controller' => IndividuController::class, 'action' => ['modifier'], - 'privilege' => IndividuPrivileges::INDIVIDU_MODIFIER, + 'privileges' => IndividuPrivileges::INDIVIDU_MODIFIER, ], [ 'controller' => IndividuController::class, 'action' => ['supprimer', 'restaurer'], - 'privilege' => IndividuPrivileges::INDIVIDU_SUPPRIMER, + 'privileges' => IndividuPrivileges::INDIVIDU_SUPPRIMER, ], ], ], @@ -173,6 +175,7 @@ return [ 'factories' => [ IndividuService::class => IndividuServiceFactory::class, IndividuSearchService::class => IndividuSearchServiceFactory::class, + IndividuAssertion::class => IndividuAssertionFactory::class, ], 'aliases' => [ 'IndividuService' => IndividuService::class, diff --git a/module/Soutenance/view/soutenance/proposition/proposition.phtml b/module/Soutenance/view/soutenance/proposition/proposition.phtml index 7e1d1fd09af6c54c3857af482526b45e92399a88..7e923341dc26d2de91e9dc7e3d24988b20e83179 100644 --- a/module/Soutenance/view/soutenance/proposition/proposition.phtml +++ b/module/Soutenance/view/soutenance/proposition/proposition.phtml @@ -39,7 +39,7 @@ use These\Entity\Db\These; * * @var IndividuRole[] $ecoleResponsables * @var IndividuRole[] $uniteResponsables - * @var IndividuRole[] $etablissementResponsables + * @var string[] $emailsAspectDoctorats * @var bool $informationsOk * * @var $FORMULAIRE_DELOCALISATION @@ -87,7 +87,7 @@ echo $this->partial('partial/informations', [ 'directeurs' => $directeurs, 'uniteResponsables' => $uniteResponsables, 'ecoleResponsables' => $ecoleResponsables, - 'etablissementResponsables' => $etablissementResponsables, + 'emailsAspectDoctorats' => $emailsAspectDoctorats, 'canModifier' => $canModifier]); ?>