From 56f713379909ae2c62725e326007dd830d46ade6 Mon Sep 17 00:00:00 2001 From: Martin Date: Tue, 14 Jun 2022 07:46:12 +0200 Subject: [PATCH] fix(procedure_presentation): can not present a 'virtual field' like depose_since fix(data): add migration to remove fields depose_since from existing procedure presentation --- .../instructeurs/procedures_controller.rb | 4 +- app/models/procedure_presentation.rb | 18 ++-- .../procedures/_dossiers_filter.html.haml | 2 +- .../instructeurs/procedures/show.html.haml | 6 +- ...cedure_presentation_with_depose_since.rake | 30 +++++++ spec/models/procedure_presentation_spec.rb | 83 ++++++++++--------- 6 files changed, 94 insertions(+), 49 deletions(-) create mode 100644 lib/tasks/deployment/20220614053743_fix_procedure_presentation_with_depose_since.rake diff --git a/app/controllers/instructeurs/procedures_controller.rb b/app/controllers/instructeurs/procedures_controller.rb index 379119141..185bde472 100644 --- a/app/controllers/instructeurs/procedures_controller.rb +++ b/app/controllers/instructeurs/procedures_controller.rb @@ -55,8 +55,8 @@ module Instructeurs @procedure_presentation = procedure_presentation @current_filters = current_filters - @displayed_fields_options, @displayed_fields_selected = procedure_presentation.displayed_fields_for_select - + @displayable_fields_for_select, @displayable_fields_selected = procedure_presentation.displayable_fields_for_select + @filterable_fields_for_select = procedure_presentation.filterable_fields_options @counts = current_instructeur .dossiers_count_summary(groupe_instructeur_ids) .symbolize_keys diff --git a/app/models/procedure_presentation.rb b/app/models/procedure_presentation.rb index 1685bf800..20d0428c1 100644 --- a/app/models/procedure_presentation.rb +++ b/app/models/procedure_presentation.rb @@ -41,8 +41,8 @@ class ProcedurePresentation < ApplicationRecord field_hash('self', 'en_construction_at'), field_hash('self', 'depose_at'), field_hash('self', 'updated_at'), - field_hash('self', 'depose_since'), - field_hash('self', 'updated_since'), + field_hash('self', 'depose_since', virtual: true), + field_hash('self', 'updated_since', virtual: true), field_hash('user', 'email'), field_hash('followers_instructeurs', 'email'), field_hash('groupe_instructeur', 'label') @@ -80,13 +80,18 @@ class ProcedurePresentation < ApplicationRecord fields end - def displayed_fields_for_select + def displayable_fields_for_select [ - fields.map { |field| [field['label'], field_id(field)] }, + fields.reject { |field| field['virtual'] } + .map { |field| [field['label'], field_id(field)] }, displayed_fields.map { |field| field_id(field) } ] end + def filterable_fields_options + fields.map { |field| [field['label'], field_id(field)] } + end + def displayed_fields_for_headers [ field_hash('self', 'id', classname: 'number-col'), @@ -333,12 +338,13 @@ class ProcedurePresentation < ApplicationRecord end end - def field_hash(table, column, label: nil, classname: '') + def field_hash(table, column, label: nil, classname: '', virtual: false) { 'label' => label || I18n.t(column, scope: [:activerecord, :attributes, :procedure_presentation, :fields, table]), TABLE => table, COLUMN => column, - 'classname' => classname + 'classname' => classname, + 'virtual' => virtual } end diff --git a/app/views/instructeurs/procedures/_dossiers_filter.html.haml b/app/views/instructeurs/procedures/_dossiers_filter.html.haml index 675bb17c5..74bf6dcea 100644 --- a/app/views/instructeurs/procedures/_dossiers_filter.html.haml +++ b/app/views/instructeurs/procedures/_dossiers_filter.html.haml @@ -4,7 +4,7 @@ #filter-menu.dropdown-content.left-aligned.fade-in-down{ data: { menu_button_target: 'menu' } } = form_tag add_filter_instructeur_procedure_path(procedure), method: :post, class: 'dropdown-form large' do = label_tag :field, t('views.instructeurs.dossiers.filters.column') - = select_tag :field, options_for_select(displayed_fields_options) + = select_tag :field, options_for_select(filterable_fields_for_select) %br = label_tag :value, t('views.instructeurs.dossiers.filters.value') = text_field_tag :value, nil, maxlength: ProcedurePresentation::FILTERS_VALUE_MAX_LENGTH diff --git a/app/views/instructeurs/procedures/show.html.haml b/app/views/instructeurs/procedures/show.html.haml index ce0205fb0..2f66a72ef 100644 --- a/app/views/instructeurs/procedures/show.html.haml +++ b/app/views/instructeurs/procedures/show.html.haml @@ -62,7 +62,7 @@ = pagination .flex .flex-grow - = render partial: "dossiers_filter", locals: { procedure: @procedure, procedure_presentation: @procedure_presentation, current_filters: @current_filters, statut: @statut, displayed_fields_options: @displayed_fields_options } + = render partial: "dossiers_filter", locals: { procedure: @procedure, procedure_presentation: @procedure_presentation, current_filters: @current_filters, statut: @statut, filterable_fields_for_select: @filterable_fields_for_select } - if @dossiers_count > 0 .dossiers-export = render Dossiers::ExportComponent.new(procedure: @procedure, exports: @exports, statut: @statut, count: @dossiers_count) @@ -86,8 +86,8 @@ = form_tag update_displayed_fields_instructeur_procedure_path(@procedure), method: :patch, class: 'dropdown-form large columns-form' do = hidden_field_tag :values, nil = react_component("ComboMultiple", - options: @displayed_fields_options, - selected: @displayed_fields_selected, + options: @displayable_fields_for_select, + selected: @displayable_fields_selected, disabled: [], label: 'Colonne à afficher', group: '.columns-form', diff --git a/lib/tasks/deployment/20220614053743_fix_procedure_presentation_with_depose_since.rake b/lib/tasks/deployment/20220614053743_fix_procedure_presentation_with_depose_since.rake new file mode 100644 index 000000000..c647a2062 --- /dev/null +++ b/lib/tasks/deployment/20220614053743_fix_procedure_presentation_with_depose_since.rake @@ -0,0 +1,30 @@ +namespace :after_party do + desc 'Deployment task: fix_procedure_presentation_with_depose_since' + task fix_procedure_presentation_with_depose_since: :environment do + puts "Running deploy task 'fix_procedure_presentation_with_depose_since'" + + # Put your task implementation HERE. + errored_presentation = { + 'label' => "Déposé depuis", + 'table' => "self", + 'column' => "depose_since", + 'classname' => "" + } + procedures_presentations = ProcedurePresentation.where("displayed_fields @> ?", [errored_presentation].to_json) + progress = ProgressReport.new(procedures_presentations.size) + + procedures_presentations.find_each do |procedure_presentation| + procedure_presentation.displayed_fields.delete_if do |field| + ['updated_since', 'depose_since'].include?(field['column']) + end + procedure_presentation.save + progress.inc + end + + progress.finish + # Update task as completed. If you remove the line below, the task will + # run with every deploy (or every time you call after_party:run). + AfterParty::TaskRecord + .create version: AfterParty::TaskRecorder.new(__FILE__).timestamp + end +end diff --git a/spec/models/procedure_presentation_spec.rb b/spec/models/procedure_presentation_spec.rb index b92c3a773..e59176696 100644 --- a/spec/models/procedure_presentation_spec.rb +++ b/spec/models/procedure_presentation_spec.rb @@ -58,28 +58,28 @@ describe ProcedurePresentation do let(:tdc_private_2) { procedure.types_de_champ_private[1] } let(:expected) { [ - { "label" => 'Créé le', "table" => 'self', "column" => 'created_at', 'classname' => '' }, - { "label" => 'En construction le', "table" => 'self', "column" => 'en_construction_at', 'classname' => '' }, - { "label" => 'Déposé le', "table" => 'self', "column" => 'depose_at', 'classname' => '' }, - { "label" => 'Mis à jour le', "table" => 'self', "column" => 'updated_at', 'classname' => '' }, - { "label" => "Déposé depuis", "table" => "self", "column" => "depose_since", "classname" => "" }, - { "label" => "Mis à jour depuis", "table" => "self", "column" => "updated_since", "classname" => "" }, - { "label" => 'Demandeur', "table" => 'user', "column" => 'email', 'classname' => '' }, - { "label" => 'Email instructeur', "table" => 'followers_instructeurs', "column" => 'email', 'classname' => '' }, - { "label" => 'Groupe instructeur', "table" => 'groupe_instructeur', "column" => 'label', 'classname' => '' }, - { "label" => 'SIREN', "table" => 'etablissement', "column" => 'entreprise_siren', 'classname' => '' }, - { "label" => 'Forme juridique', "table" => 'etablissement', "column" => 'entreprise_forme_juridique', 'classname' => '' }, - { "label" => 'Nom commercial', "table" => 'etablissement', "column" => 'entreprise_nom_commercial', 'classname' => '' }, - { "label" => 'Raison sociale', "table" => 'etablissement', "column" => 'entreprise_raison_sociale', 'classname' => '' }, - { "label" => 'SIRET siège social', "table" => 'etablissement', "column" => 'entreprise_siret_siege_social', 'classname' => '' }, - { "label" => 'Date de création', "table" => 'etablissement', "column" => 'entreprise_date_creation', 'classname' => '' }, - { "label" => 'SIRET', "table" => 'etablissement', "column" => 'siret', 'classname' => '' }, - { "label" => 'Libellé NAF', "table" => 'etablissement', "column" => 'libelle_naf', 'classname' => '' }, - { "label" => 'Code postal', "table" => 'etablissement', "column" => 'code_postal', 'classname' => '' }, - { "label" => tdc_1.libelle, "table" => 'type_de_champ', "column" => tdc_1.stable_id.to_s, 'classname' => '' }, - { "label" => tdc_2.libelle, "table" => 'type_de_champ', "column" => tdc_2.stable_id.to_s, 'classname' => '' }, - { "label" => tdc_private_1.libelle, "table" => 'type_de_champ_private', "column" => tdc_private_1.stable_id.to_s, 'classname' => '' }, - { "label" => tdc_private_2.libelle, "table" => 'type_de_champ_private', "column" => tdc_private_2.stable_id.to_s, 'classname' => '' } + { "label" => 'Créé le', "table" => 'self', "column" => 'created_at', 'classname' => '', 'virtual' => false }, + { "label" => 'En construction le', "table" => 'self', "column" => 'en_construction_at', 'classname' => '', 'virtual' => false }, + { "label" => 'Déposé le', "table" => 'self', "column" => 'depose_at', 'classname' => '', 'virtual' => false }, + { "label" => 'Mis à jour le', "table" => 'self', "column" => 'updated_at', 'classname' => '', 'virtual' => false }, + { "label" => "Déposé depuis", "table" => "self", "column" => "depose_since", "classname" => "", 'virtual' => true }, + { "label" => "Mis à jour depuis", "table" => "self", "column" => "updated_since", "classname" => "", 'virtual' => true }, + { "label" => 'Demandeur', "table" => 'user', "column" => 'email', 'classname' => '', 'virtual' => false }, + { "label" => 'Email instructeur', "table" => 'followers_instructeurs', "column" => 'email', 'classname' => '', 'virtual' => false }, + { "label" => 'Groupe instructeur', "table" => 'groupe_instructeur', "column" => 'label', 'classname' => '', 'virtual' => false }, + { "label" => 'SIREN', "table" => 'etablissement', "column" => 'entreprise_siren', 'classname' => '', 'virtual' => false }, + { "label" => 'Forme juridique', "table" => 'etablissement', "column" => 'entreprise_forme_juridique', 'classname' => '', 'virtual' => false }, + { "label" => 'Nom commercial', "table" => 'etablissement', "column" => 'entreprise_nom_commercial', 'classname' => '', 'virtual' => false }, + { "label" => 'Raison sociale', "table" => 'etablissement', "column" => 'entreprise_raison_sociale', 'classname' => '', 'virtual' => false }, + { "label" => 'SIRET siège social', "table" => 'etablissement', "column" => 'entreprise_siret_siege_social', 'classname' => '', 'virtual' => false }, + { "label" => 'Date de création', "table" => 'etablissement', "column" => 'entreprise_date_creation', 'classname' => '', 'virtual' => false }, + { "label" => 'SIRET', "table" => 'etablissement', "column" => 'siret', 'classname' => '', 'virtual' => false }, + { "label" => 'Libellé NAF', "table" => 'etablissement', "column" => 'libelle_naf', 'classname' => '', 'virtual' => false }, + { "label" => 'Code postal', "table" => 'etablissement', "column" => 'code_postal', 'classname' => '', 'virtual' => false }, + { "label" => tdc_1.libelle, "table" => 'type_de_champ', "column" => tdc_1.stable_id.to_s, 'classname' => '', 'virtual' => false }, + { "label" => tdc_2.libelle, "table" => 'type_de_champ', "column" => tdc_2.stable_id.to_s, 'classname' => '', 'virtual' => false }, + { "label" => tdc_private_1.libelle, "table" => 'type_de_champ_private', "column" => tdc_private_1.stable_id.to_s, 'classname' => '', 'virtual' => false }, + { "label" => tdc_private_2.libelle, "table" => 'type_de_champ_private', "column" => tdc_private_2.stable_id.to_s, 'classname' => '', 'virtual' => false } ] } @@ -96,9 +96,9 @@ describe ProcedurePresentation do end context 'when the procedure is for individuals' do - let(:name_field) { { "label" => "Prénom", "table" => "individual", "column" => "prenom", 'classname' => '' } } - let(:surname_field) { { "label" => "Nom", "table" => "individual", "column" => "nom", 'classname' => '' } } - let(:gender_field) { { "label" => "Civilité", "table" => "individual", "column" => "gender", 'classname' => '' } } + let(:name_field) { { "label" => "Prénom", "table" => "individual", "column" => "prenom", 'classname' => '', 'virtual' => false } } + let(:surname_field) { { "label" => "Nom", "table" => "individual", "column" => "nom", 'classname' => '', 'virtual' => false } } + let(:gender_field) { { "label" => "Civilité", "table" => "individual", "column" => "gender", 'classname' => '', 'virtual' => false } } let(:procedure) { create(:procedure, :for_individual) } let(:procedure_presentation) { create(:procedure_presentation, assign_to: assign_to) } @@ -108,25 +108,34 @@ describe ProcedurePresentation do end end - describe "#displayed_fields_for_select" do + describe "#displayable_fields_for_select" do subject { create(:procedure_presentation, assign_to: assign_to) } + let(:excluded_displayable_field) { { "label" => "depose_since", "table" => "self", "column" => "depose_since", 'virtual' => true } } + let(:included_displayable_field) { { "label" => "label1", "table" => "table1", "column" => "column1", 'virtual' => false } } before do allow(subject).to receive(:fields).and_return([ - { - "label" => "label1", - "table" => "table1", - "column" => "column1" - }, - { - "label" => "label2", - "table" => "table2", - "column" => "column2" - } + excluded_displayable_field, + included_displayable_field ]) end - it { expect(subject.displayed_fields_for_select).to eq([[["label1", "table1/column1"], ["label2", "table2/column2"]], ["user/email"]]) } + it { expect(subject.displayable_fields_for_select).to eq([[["label1", "table1/column1"]], ["user/email"]]) } + end + describe "#filterable_fields_options" do + subject { create(:procedure_presentation, assign_to: assign_to) } + let(:included_displayable_field) do + [ + { "label" => "label1", "table" => "table1", "column" => "column1", 'virtual' => false }, + { "label" => "depose_since", "table" => "self", "column" => "depose_since", 'virtual' => true } + ] + end + + before do + allow(subject).to receive(:fields).and_return(included_displayable_field) + end + + it { expect(subject.filterable_fields_options).to eq([["label1", "table1/column1"], ["depose_since", "self/depose_since"]]) } end describe '#sorted_ids' do