Loading CHANGELOG.md +1 −0 Changes for CHANGELOG.md: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ Journal des modifications - Rapports d'activité : initialisation du formulaire de création d'un nouveau rapport avec les formations suivies (module Formation). - Stockage de fichier S3/Filesystem : plus de copie sur disque dans le cas d'une demande d'un fichier issu du Filesystem. - Inclusion au script de purge des fichiers temporaires ceux générés par le FichierStorageService. - Module Substitutions : amélioration de fonctions pgsql du moteur de substitutions. - [FIX] Module Substitutions : plantage de la page consacrée aux doublons (substitutions possibles). - [FIX] Page Assistance : plantage de la page lorsque le rôle de l'utilisateur est structure-dépendant. Loading data/SQL/substitutions.sql 0 → 100644 +112 −0 Changes for data/SQL/substitutions.sql: 112 added lines, 0 removed lines. Original line number Diff line number Diff line --====================================================================================================================== -- MODIFICATION DU FONCTIONNEMENT DE LA SUBSTITUTION D'INDIVIDU ET DE DOCTORANT ------------------------------------------------------------------------------------------------------------------------ -- On ne veut plus que soit possible la substitution de 2 individus dont les doctorants liés -- ne sont pas eux-mêmes substitués. --====================================================================================================================== -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -- ! Idée abandonnée ! -- -- Ça a quand même du sens que les individus soient substitués indépendemment du fait qu'ils -- soient des individus "purs" (acteur) ou des doctorants ou les 2. On peut même imaginer que -- ça soit utile utile de savoir qu'un acteur donné a été doctorant. -- Pour régler le "pb" des 2 doctorants non substitués (car INE différents) alors que leurs -- individus respectifs le sont (car même nom,prénom,ddn) qui faisait couiner la recherche de -- doctorant par individu_id (car 2 doctorants liés au même individu substituant), on ne lève -- plus d'exception et on prend le doctorant le plus "récent". Sachant que : -- - 1/ ce cas de doctroants non substitués alors que leurs individus respectifs le sont, est -- aberrant donc improbable (et pour s'en sortir, on a forcé ne NPD d'un des doctorants). -- - 2/ il faudrait s'arranger pour ne plus avoir à faire de recherche de doctorant par individu_id, -- en s'assurant que l'on référence là où il faut un doctorant et pas un individu. -- -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -- -- Suppression de toutes les substitutions de doctorants, en forçant le NPD. -- update doctorant d set npd_force = substit_npd_doctorant(d)||'-zzz-'||d.id from substit_doctorant sub where d.id = sub.from_id and npd_force is null ; ---------------> 12min -- -- Verif absence de substitutions de doctorants. -- select * from substit_doctorant order by npd ; -- -- Modif manuelle du "NPD forcé" *s'il est null* pour retirer des substitutions d'individus les individus étant -- des doctorants. -- update individu i set npd_force = substit_npd_individu(i)||'-zzz-'||i.id where npd_force IS NULL and id in ( select i.id from individu i join substit_individu sub on i.id = sub.from_id where type = 'doctorant' ); ---------------> 24min (sur bdd locale) -- -- Verif absence de substitutions d'individus étant aussi des doctorants. -- select * from substit_individu sub join individu i on sub.from_id = i.id and i.type = 'doctorant'; -- -- Impossibilités de supprimer des substituants car ils sont référencés dans d'autres tables (ex: validation, acteur) ? -- select * from substit_log where type = 'doctorant' and operation = 'SUBSTITUANT_SUPPR_PROBLEM'; select * from substit_log where type = 'individu' and operation = 'SUBSTITUANT_SUPPR_PROBLEM'; -- -- recherche de cobayes : individus à la fois acteur et doctorant -- select nom_patronymique, prenom1, sum(count_doctorant) as count_doctorant, sum(count_acteur) as count_acteur from ( select nom_patronymique, prenom1, type, 0 as count_doctorant, count(*) count_acteur from individu where type = 'acteur' and source_id <> 1 group by nom_patronymique, prenom1, type union select nom_patronymique, prenom1, type, count(*) count_doctorant, 0 as count_acteur from individu where type = 'doctorant' and source_id <> 1 group by nom_patronymique, prenom1, type ) tmp group by nom_patronymique, prenom1 having sum(count_doctorant) > 0 and sum(count_acteur) > 0 and sum(count_doctorant) + sum(count_acteur) > 2; -- -- cobaye 1 -- select substit_npd_individu(i)npd,id,type,nom_patronymique,prenom1,date_naissance,source_code,email,npd_force from individu i where nom_patronymique = 'XXXXX' and prenom1 ilike '%Yyyyy%' order by type; alter table individu disable trigger substit_trigger_individu; alter table substit_individu disable trigger substit_trigger_on_substit_individu; update individu set npd_force = null where id = 1122; update individu set npd_force = null where id = 1011; -------------------------------> ça fonctionne : les individu-doctrants 1122 et 1011 ne sont pas substitués select * from v_individu_doublon where npd = 'bentahar_omar_19831007'; -- 37995 update individu set npd_force = 'lsdfjlmsdqjfmlqsdjfqsldkfj' where id in (1198707); select * from v_individu_doublon where nom_patronymique = 'XXXXX'; alter table individu enable trigger substit_trigger_individu; alter table substit_individu enable trigger substit_trigger_on_substit_individu; -- -- cobaye 2 -- select substit_npd_individu(i)npd,id,type,nom_patronymique,prenom1,date_naissance,source_code,email,npd_force from individu i where nom_patronymique = 'XXXXX' and prenom1 ilike '%Yyyyyy%' order by type; select * from individu where id = 1200286; -- substituait les individus 37995,18879 select * from acteur where individu_id = 1200286; select * from acteur where individu_id in (37995,18879); -- substituait les individus 37995,18879 select i.* from individu i join substit_individu sub on i.id = sub.from_id where to_id = 1199128; alter table individu disable trigger substit_trigger_individu; alter table substit_individu disable trigger substit_trigger_on_substit_individu; update individu set date_naissance = '1975-11-19 00:00:00.000000' where id = 1187822; update individu set npd_force = null where id = 18879; select * from v_individu_doublon where nom_patronymique = 'XXXXX'; -- 37995 update individu set npd_force = 'lsdfjlmsdqjfmlqsdjfqsldkfj' where id in (18879); select * from v_individu_doublon where nom_patronymique = 'XXXXX'; alter table individu enable trigger substit_trigger_individu; alter table substit_individu enable trigger substit_trigger_on_substit_individu; select * from substit_individu sub join individu i on sub.from_id = i.id and i.type = 'doctorant'; doc/release-notes/v7.1.0.md +68 −0 Changes for doc/release-notes/v7.1.0.md: 68 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -18,6 +18,10 @@ ## 2. Dans la base de données ```postgresql -- -- Restauration des valeurs originales de clés étrangères : -- modif pour n'afficher une notice qu'en cas de remplacements faits (et pas systématiquement). -- create or replace function substit_restore_foreign_key_value(p_type varchar, p_tab_name varchar, p_col_name varchar, p_from_id bigint, p_to_id bigint) returns int language plpgsql as Loading Loading @@ -54,4 +58,68 @@ begin return v_count; end $$; -- -- Modification de la fonction de suppression d'une substitution 'individu' : -- en cas d'échec de la suppression du substituant à cause d'une contrainte d'intégrité (i.e. il est référencé -- dans d'autres tables) : -- - dans le cas où il ne reste qu'1 substitué dans la substitution on remplace partout l'id du substituant -- par celui du dernier substitué, ce qui nous permettra ensuite de procéder à la suppression prévue. -- - sinon, on logue simplement le problème. -- create or replace function substit_delete_substitution(type character varying, p_substituant_id bigint) returns void language plpgsql as $$declare v_count int; v_message text; v_stack text; v_substit record; begin -- -- Supprime une substitution, spécifiée par l'enregistrement substituant. -- raise notice 'Suppression du substituant % et de la substitution associée...', p_substituant_id; execute format('select count(*) from substit_%s where to_id = %s', type, p_substituant_id) into v_count; begin -- NB : la suppression déclenche le trigger de la table 'substit_%s' execute format('delete from substit_%s where to_id = %s', type, p_substituant_id); perform substit_insert_log(type, 'SUBSTITUTION_SUPPR', null, p_substituant_id, null, format('Suppression des %s substitutions par %s', v_count, p_substituant_id)); execute format('delete from %I where id = %s', type, p_substituant_id); perform substit_insert_log(type, 'SUBSTITUANT_SUPPR', null, p_substituant_id, null, format('Suppression du substituant %s', p_substituant_id)); exception WHEN integrity_constraint_violation THEN -- échec de la suppression du substituant à cause d'une contrainte d'intégrité (i.e. il est référencé -- dans d'autres tables) : cela annule tout ce qui est entre `begin` et `exception`. v_message = format('Suppression du substituant %s impossible car il est utilisé dans au moins une table ' || '(contrainte d''intégrité) : %L', p_substituant_id, v_stack); raise notice '%', v_message; if v_count = 1 then -- dans le cas où il ne reste qu'1 substitué dans la substitution on remplace partout l'id du substituant -- par celui du dernier substitué, ce qui nous permettra ensuite de procéder à la suppression prévue. raise notice 'Un seul substitué restant donc remplacement de l''id du substituant par l''id du substitué...'; -- remplacement de l'id du substituant par l'id du dernier substitué restant execute format('select * from substit_%s where to_id = %s limit 1', type, p_substituant_id) into v_substit; select substit_replace_foreign_keys_values(type, p_substituant_id, v_substit.from_id) into v_count; -- ensuite on peut supprimer le substituant perform substit_delete_substitution(type, p_substituant_id); else -- sinon, on logue simplement le problème. GET STACKED DIAGNOSTICS v_stack = MESSAGE_TEXT; perform substit_insert_log(type, 'SUBSTITUANT_SUPPR_PROBLEM', null, p_substituant_id, null, v_message); end if; end; raise notice '=> Terminé.'; end $$; ``` Loading
CHANGELOG.md +1 −0 Changes for CHANGELOG.md: 1 added line, 0 removed lines. Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ Journal des modifications - Rapports d'activité : initialisation du formulaire de création d'un nouveau rapport avec les formations suivies (module Formation). - Stockage de fichier S3/Filesystem : plus de copie sur disque dans le cas d'une demande d'un fichier issu du Filesystem. - Inclusion au script de purge des fichiers temporaires ceux générés par le FichierStorageService. - Module Substitutions : amélioration de fonctions pgsql du moteur de substitutions. - [FIX] Module Substitutions : plantage de la page consacrée aux doublons (substitutions possibles). - [FIX] Page Assistance : plantage de la page lorsque le rôle de l'utilisateur est structure-dépendant. Loading
data/SQL/substitutions.sql 0 → 100644 +112 −0 Changes for data/SQL/substitutions.sql: 112 added lines, 0 removed lines. Original line number Diff line number Diff line --====================================================================================================================== -- MODIFICATION DU FONCTIONNEMENT DE LA SUBSTITUTION D'INDIVIDU ET DE DOCTORANT ------------------------------------------------------------------------------------------------------------------------ -- On ne veut plus que soit possible la substitution de 2 individus dont les doctorants liés -- ne sont pas eux-mêmes substitués. --====================================================================================================================== -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -- ! Idée abandonnée ! -- -- Ça a quand même du sens que les individus soient substitués indépendemment du fait qu'ils -- soient des individus "purs" (acteur) ou des doctorants ou les 2. On peut même imaginer que -- ça soit utile utile de savoir qu'un acteur donné a été doctorant. -- Pour régler le "pb" des 2 doctorants non substitués (car INE différents) alors que leurs -- individus respectifs le sont (car même nom,prénom,ddn) qui faisait couiner la recherche de -- doctorant par individu_id (car 2 doctorants liés au même individu substituant), on ne lève -- plus d'exception et on prend le doctorant le plus "récent". Sachant que : -- - 1/ ce cas de doctroants non substitués alors que leurs individus respectifs le sont, est -- aberrant donc improbable (et pour s'en sortir, on a forcé ne NPD d'un des doctorants). -- - 2/ il faudrait s'arranger pour ne plus avoir à faire de recherche de doctorant par individu_id, -- en s'assurant que l'on référence là où il faut un doctorant et pas un individu. -- -- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -- -- Suppression de toutes les substitutions de doctorants, en forçant le NPD. -- update doctorant d set npd_force = substit_npd_doctorant(d)||'-zzz-'||d.id from substit_doctorant sub where d.id = sub.from_id and npd_force is null ; ---------------> 12min -- -- Verif absence de substitutions de doctorants. -- select * from substit_doctorant order by npd ; -- -- Modif manuelle du "NPD forcé" *s'il est null* pour retirer des substitutions d'individus les individus étant -- des doctorants. -- update individu i set npd_force = substit_npd_individu(i)||'-zzz-'||i.id where npd_force IS NULL and id in ( select i.id from individu i join substit_individu sub on i.id = sub.from_id where type = 'doctorant' ); ---------------> 24min (sur bdd locale) -- -- Verif absence de substitutions d'individus étant aussi des doctorants. -- select * from substit_individu sub join individu i on sub.from_id = i.id and i.type = 'doctorant'; -- -- Impossibilités de supprimer des substituants car ils sont référencés dans d'autres tables (ex: validation, acteur) ? -- select * from substit_log where type = 'doctorant' and operation = 'SUBSTITUANT_SUPPR_PROBLEM'; select * from substit_log where type = 'individu' and operation = 'SUBSTITUANT_SUPPR_PROBLEM'; -- -- recherche de cobayes : individus à la fois acteur et doctorant -- select nom_patronymique, prenom1, sum(count_doctorant) as count_doctorant, sum(count_acteur) as count_acteur from ( select nom_patronymique, prenom1, type, 0 as count_doctorant, count(*) count_acteur from individu where type = 'acteur' and source_id <> 1 group by nom_patronymique, prenom1, type union select nom_patronymique, prenom1, type, count(*) count_doctorant, 0 as count_acteur from individu where type = 'doctorant' and source_id <> 1 group by nom_patronymique, prenom1, type ) tmp group by nom_patronymique, prenom1 having sum(count_doctorant) > 0 and sum(count_acteur) > 0 and sum(count_doctorant) + sum(count_acteur) > 2; -- -- cobaye 1 -- select substit_npd_individu(i)npd,id,type,nom_patronymique,prenom1,date_naissance,source_code,email,npd_force from individu i where nom_patronymique = 'XXXXX' and prenom1 ilike '%Yyyyy%' order by type; alter table individu disable trigger substit_trigger_individu; alter table substit_individu disable trigger substit_trigger_on_substit_individu; update individu set npd_force = null where id = 1122; update individu set npd_force = null where id = 1011; -------------------------------> ça fonctionne : les individu-doctrants 1122 et 1011 ne sont pas substitués select * from v_individu_doublon where npd = 'bentahar_omar_19831007'; -- 37995 update individu set npd_force = 'lsdfjlmsdqjfmlqsdjfqsldkfj' where id in (1198707); select * from v_individu_doublon where nom_patronymique = 'XXXXX'; alter table individu enable trigger substit_trigger_individu; alter table substit_individu enable trigger substit_trigger_on_substit_individu; -- -- cobaye 2 -- select substit_npd_individu(i)npd,id,type,nom_patronymique,prenom1,date_naissance,source_code,email,npd_force from individu i where nom_patronymique = 'XXXXX' and prenom1 ilike '%Yyyyyy%' order by type; select * from individu where id = 1200286; -- substituait les individus 37995,18879 select * from acteur where individu_id = 1200286; select * from acteur where individu_id in (37995,18879); -- substituait les individus 37995,18879 select i.* from individu i join substit_individu sub on i.id = sub.from_id where to_id = 1199128; alter table individu disable trigger substit_trigger_individu; alter table substit_individu disable trigger substit_trigger_on_substit_individu; update individu set date_naissance = '1975-11-19 00:00:00.000000' where id = 1187822; update individu set npd_force = null where id = 18879; select * from v_individu_doublon where nom_patronymique = 'XXXXX'; -- 37995 update individu set npd_force = 'lsdfjlmsdqjfmlqsdjfqsldkfj' where id in (18879); select * from v_individu_doublon where nom_patronymique = 'XXXXX'; alter table individu enable trigger substit_trigger_individu; alter table substit_individu enable trigger substit_trigger_on_substit_individu; select * from substit_individu sub join individu i on sub.from_id = i.id and i.type = 'doctorant';
doc/release-notes/v7.1.0.md +68 −0 Changes for doc/release-notes/v7.1.0.md: 68 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -18,6 +18,10 @@ ## 2. Dans la base de données ```postgresql -- -- Restauration des valeurs originales de clés étrangères : -- modif pour n'afficher une notice qu'en cas de remplacements faits (et pas systématiquement). -- create or replace function substit_restore_foreign_key_value(p_type varchar, p_tab_name varchar, p_col_name varchar, p_from_id bigint, p_to_id bigint) returns int language plpgsql as Loading Loading @@ -54,4 +58,68 @@ begin return v_count; end $$; -- -- Modification de la fonction de suppression d'une substitution 'individu' : -- en cas d'échec de la suppression du substituant à cause d'une contrainte d'intégrité (i.e. il est référencé -- dans d'autres tables) : -- - dans le cas où il ne reste qu'1 substitué dans la substitution on remplace partout l'id du substituant -- par celui du dernier substitué, ce qui nous permettra ensuite de procéder à la suppression prévue. -- - sinon, on logue simplement le problème. -- create or replace function substit_delete_substitution(type character varying, p_substituant_id bigint) returns void language plpgsql as $$declare v_count int; v_message text; v_stack text; v_substit record; begin -- -- Supprime une substitution, spécifiée par l'enregistrement substituant. -- raise notice 'Suppression du substituant % et de la substitution associée...', p_substituant_id; execute format('select count(*) from substit_%s where to_id = %s', type, p_substituant_id) into v_count; begin -- NB : la suppression déclenche le trigger de la table 'substit_%s' execute format('delete from substit_%s where to_id = %s', type, p_substituant_id); perform substit_insert_log(type, 'SUBSTITUTION_SUPPR', null, p_substituant_id, null, format('Suppression des %s substitutions par %s', v_count, p_substituant_id)); execute format('delete from %I where id = %s', type, p_substituant_id); perform substit_insert_log(type, 'SUBSTITUANT_SUPPR', null, p_substituant_id, null, format('Suppression du substituant %s', p_substituant_id)); exception WHEN integrity_constraint_violation THEN -- échec de la suppression du substituant à cause d'une contrainte d'intégrité (i.e. il est référencé -- dans d'autres tables) : cela annule tout ce qui est entre `begin` et `exception`. v_message = format('Suppression du substituant %s impossible car il est utilisé dans au moins une table ' || '(contrainte d''intégrité) : %L', p_substituant_id, v_stack); raise notice '%', v_message; if v_count = 1 then -- dans le cas où il ne reste qu'1 substitué dans la substitution on remplace partout l'id du substituant -- par celui du dernier substitué, ce qui nous permettra ensuite de procéder à la suppression prévue. raise notice 'Un seul substitué restant donc remplacement de l''id du substituant par l''id du substitué...'; -- remplacement de l'id du substituant par l'id du dernier substitué restant execute format('select * from substit_%s where to_id = %s limit 1', type, p_substituant_id) into v_substit; select substit_replace_foreign_keys_values(type, p_substituant_id, v_substit.from_id) into v_count; -- ensuite on peut supprimer le substituant perform substit_delete_substitution(type, p_substituant_id); else -- sinon, on logue simplement le problème. GET STACKED DIAGNOSTICS v_stack = MESSAGE_TEXT; perform substit_insert_log(type, 'SUBSTITUANT_SUPPR_PROBLEM', null, p_substituant_id, null, v_message); end if; end; raise notice '=> Terminé.'; end $$; ```