diff --git a/app/controllers/instructeurs/procedures_controller.rb b/app/controllers/instructeurs/procedures_controller.rb index 6332107b5..96824488d 100644 --- a/app/controllers/instructeurs/procedures_controller.rb +++ b/app/controllers/instructeurs/procedures_controller.rb @@ -159,7 +159,7 @@ module Instructeurs @statut = statut @procedure = procedure @procedure_presentation = procedure_presentation - @facet = Facet.find(procedure:, id: params[:field]) + @facet = procedure.find_facet(id: params[:field]) end def remove_filter diff --git a/app/models/concerns/facets_concern.rb b/app/models/concerns/facets_concern.rb new file mode 100644 index 000000000..1ac45dbb8 --- /dev/null +++ b/app/models/concerns/facets_concern.rb @@ -0,0 +1,107 @@ +module FacetsConcern + extend ActiveSupport::Concern + + included do + TYPE_DE_CHAMP = 'type_de_champ' + + def find_facet(id:) + facets.find { |f| f.id == id } + end + + def facets + facets = dossier_facets + + facets.push( + Facet.new(table: 'user', column: 'email', type: :text), + Facet.new(table: 'followers_instructeurs', column: 'email', type: :text), + Facet.new(table: 'groupe_instructeur', column: 'id', type: :enum), + Facet.new(table: 'avis', column: 'question_answer', filterable: false) + ) + + if for_individual + facets.push( + Facet.new(table: "individual", column: "prenom", type: :text), + Facet.new(table: "individual", column: "nom", type: :text), + Facet.new(table: "individual", column: "gender", type: :text) + ) + end + + if !for_individual + facets.push( + Facet.new(table: 'etablissement', column: 'entreprise_siren', type: :text), + Facet.new(table: 'etablissement', column: 'entreprise_forme_juridique', type: :text), + Facet.new(table: 'etablissement', column: 'entreprise_nom_commercial', type: :text), + Facet.new(table: 'etablissement', column: 'entreprise_raison_sociale', type: :text), + Facet.new(table: 'etablissement', column: 'entreprise_siret_siege_social', type: :text), + Facet.new(table: 'etablissement', column: 'entreprise_date_creation', type: :date), + Facet.new(table: 'etablissement', column: 'siret', type: :text), + Facet.new(table: 'etablissement', column: 'libelle_naf', type: :text), + Facet.new(table: 'etablissement', column: 'code_postal', type: :text) + ) + end + + facets.concat(types_de_champ_facets) + + facets + end + + def dossier_facets + [ + Facet.new(table: 'self', column: 'created_at', type: :date), + Facet.new(table: 'self', column: 'updated_at', type: :date), + Facet.new(table: 'self', column: 'depose_at', type: :date), + Facet.new(table: 'self', column: 'en_construction_at', type: :date), + Facet.new(table: 'self', column: 'en_instruction_at', type: :date), + Facet.new(table: 'self', column: 'processed_at', type: :date), + *sva_svr_facets(for_filters: true), + Facet.new(table: 'self', column: 'updated_since', type: :date, virtual: true), + Facet.new(table: 'self', column: 'depose_since', type: :date, virtual: true), + Facet.new(table: 'self', column: 'en_construction_since', type: :date, virtual: true), + Facet.new(table: 'self', column: 'en_instruction_since', type: :date, virtual: true), + Facet.new(table: 'self', column: 'processed_since', type: :date, virtual: true), + Facet.new(table: 'self', column: 'state', type: :enum, scope: 'instructeurs.dossiers.filterable_state', virtual: true) + ].compact_blank + end + + def sva_svr_facets(for_filters: false) + return if !sva_svr_enabled? + + i18n_scope = [:activerecord, :attributes, :procedure_presentation, :fields, :self] + + facets = [] + facets << Facet.new(table: 'self', column: 'sva_svr_decision_on', + type: :date, + label: I18n.t("#{sva_svr_decision}_decision_on", scope: i18n_scope), + classname: for_filters ? '' : 'sva-col') + + if for_filters + facets << Facet.new(table: 'self', column: 'sva_svr_decision_before', + label: I18n.t("#{sva_svr_decision}_decision_before", scope: i18n_scope), + type: :date, virtual: true) + end + + facets + end + + private + + def types_de_champ_facets + types_de_champ_for_procedure_presentation + .pluck(:type_champ, :libelle, :stable_id) + .reject { |(type_champ)| type_champ == TypeDeChamp.type_champs.fetch(:repetition) } + .flat_map do |(type_champ, libelle, stable_id)| + tdc = TypeDeChamp.new(type_champ:, libelle:, stable_id:) + + tdc.dynamic_type.search_paths.map do |path_struct| + Facet.new( + table: TYPE_DE_CHAMP, + column: tdc.stable_id.to_s, + label: path_struct[:libelle], + type: TypeDeChamp.filter_hash_type(tdc.type_champ), + value_column: path_struct[:path] + ) + end + end + end + end +end diff --git a/app/models/facet.rb b/app/models/facet.rb index d068d831e..910106f7f 100644 --- a/app/models/facet.rb +++ b/app/models/facet.rb @@ -1,8 +1,6 @@ class Facet attr_reader :table, :column, :label, :classname, :virtual, :type, :scope, :value_column, :filterable - TYPE_DE_CHAMP = 'type_de_champ' - def initialize(table:, column:, label: nil, virtual: false, type: :text, value_column: :value, filterable: true, classname: '', scope: '') @table = table @column = column @@ -28,103 +26,4 @@ class Facet table:, column:, label:, classname:, virtual:, type:, scope:, value_column:, filterable: } end - - def self.find(procedure:, id:) - facets(procedure:).find { _1.id == id } - end - - def self.dossier_facets(procedure:) - [ - new(table: 'self', column: 'created_at', type: :date), - new(table: 'self', column: 'updated_at', type: :date), - new(table: 'self', column: 'depose_at', type: :date), - new(table: 'self', column: 'en_construction_at', type: :date), - new(table: 'self', column: 'en_instruction_at', type: :date), - new(table: 'self', column: 'processed_at', type: :date), - *sva_svr_facets(procedure:, for_filters: true), - new(table: 'self', column: 'updated_since', type: :date, virtual: true), - new(table: 'self', column: 'depose_since', type: :date, virtual: true), - new(table: 'self', column: 'en_construction_since', type: :date, virtual: true), - new(table: 'self', column: 'en_instruction_since', type: :date, virtual: true), - new(table: 'self', column: 'processed_since', type: :date, virtual: true), - new(table: 'self', column: 'state', type: :enum, scope: 'instructeurs.dossiers.filterable_state', virtual: true) - ].compact_blank - end - - def self.facets(procedure:) - facets = Facet.dossier_facets(procedure:) - - facets.push( - new(table: 'user', column: 'email', type: :text), - new(table: 'followers_instructeurs', column: 'email', type: :text), - new(table: 'groupe_instructeur', column: 'id', type: :enum), - new(table: 'avis', column: 'question_answer', filterable: false) - ) - - if procedure.for_individual - facets.push( - new(table: "individual", column: "prenom", type: :text), - new(table: "individual", column: "nom", type: :text), - new(table: "individual", column: "gender", type: :text) - ) - end - - if !procedure.for_individual - facets.push( - new(table: 'etablissement', column: 'entreprise_siren', type: :text), - new(table: 'etablissement', column: 'entreprise_forme_juridique', type: :text), - new(table: 'etablissement', column: 'entreprise_nom_commercial', type: :text), - new(table: 'etablissement', column: 'entreprise_raison_sociale', type: :text), - new(table: 'etablissement', column: 'entreprise_siret_siege_social', type: :text), - new(table: 'etablissement', column: 'entreprise_date_creation', type: :date), - new(table: 'etablissement', column: 'siret', type: :text), - new(table: 'etablissement', column: 'libelle_naf', type: :text), - new(table: 'etablissement', column: 'code_postal', type: :text) - ) - end - - facets.concat(types_de_champ_facets(procedure)) - - facets - end - - def self.types_de_champ_facets(procedure) - procedure - .types_de_champ_for_procedure_presentation - .pluck(:type_champ, :libelle, :stable_id) - .reject { |(type_champ)| type_champ == TypeDeChamp.type_champs.fetch(:repetition) } - .flat_map do |(type_champ, libelle, stable_id)| - tdc = TypeDeChamp.new(type_champ:, libelle:, stable_id:) - - tdc.dynamic_type.search_paths.map do |path_struct| - new( - table: TYPE_DE_CHAMP, - column: tdc.stable_id.to_s, - label: path_struct[:libelle], - type: TypeDeChamp.filter_hash_type(tdc.type_champ), - value_column: path_struct[:path] - ) - end - end - end - - def self.sva_svr_facets(procedure:, for_filters: false) - return if !procedure.sva_svr_enabled? - - i18n_scope = [:activerecord, :attributes, :procedure_presentation, :fields, :self] - - facets = [] - facets << new(table: 'self', column: 'sva_svr_decision_on', - type: :date, - label: I18n.t("#{procedure.sva_svr_decision}_decision_on", scope: i18n_scope), - classname: for_filters ? '' : 'sva-col') - - if for_filters - facets << new(table: 'self', column: 'sva_svr_decision_before', - label: I18n.t("#{procedure.sva_svr_decision}_decision_before", scope: i18n_scope), - type: :date, virtual: true) - end - - facets - end end diff --git a/app/models/procedure.rb b/app/models/procedure.rb index c336dcce5..d86f30b6d 100644 --- a/app/models/procedure.rb +++ b/app/models/procedure.rb @@ -6,6 +6,7 @@ class Procedure < ApplicationRecord include ProcedureSVASVRConcern include ProcedureChorusConcern include PiecesJointesListConcern + include FacetsConcern include Discard::Model self.discard_column = :hidden_at diff --git a/app/models/procedure_presentation.rb b/app/models/procedure_presentation.rb index fb1c1d87c..5fc4095b0 100644 --- a/app/models/procedure_presentation.rb +++ b/app/models/procedure_presentation.rb @@ -26,13 +26,13 @@ class ProcedurePresentation < ApplicationRecord def displayable_fields_for_select [ - Facet.facets(procedure:).reject(&:virtual).map { |facet| [facet.label, facet.id] }, + procedure.facets.reject(&:virtual).map { |facet| [facet.label, facet.id] }, displayed_fields.map { Facet.new(**_1.deep_symbolize_keys).id } ] end def filterable_fields_options - Facet.facets(procedure:).filter_map do |facet| + procedure.facets.filter_map do |facet| next if facet.filterable == false [facet.label, facet.id] @@ -44,7 +44,7 @@ class ProcedurePresentation < ApplicationRecord Facet.new(table: 'self', column: 'id', classname: 'number-col'), *displayed_fields.map { Facet.new(**_1.deep_symbolize_keys) }, Facet.new(table: 'self', column: 'state', classname: 'state-col'), - *Facet.sva_svr_facets(procedure:) + *procedure.sva_svr_facets ] end @@ -72,7 +72,7 @@ class ProcedurePresentation < ApplicationRecord instructeur.groupe_instructeurs .find { _1.id == filter['value'].to_i }&.label || filter['value'] else - facet = Facet.facets(procedure:).find { _1.table == filter[TABLE] && _1.column == filter[COLUMN] } + facet = procedure.facets.find { _1.table == filter[TABLE] && _1.column == filter[COLUMN] } if facet.type == :date parsed_date = safe_parse_date(filter['value']) @@ -92,7 +92,7 @@ class ProcedurePresentation < ApplicationRecord def add_filter(statut, facet_id, value) if value.present? - facet = Facet.find(procedure:, id: facet_id) + facet = procedure.find_facet(id: facet_id) label = facet.label column = facet.column table = facet.table @@ -117,7 +117,7 @@ class ProcedurePresentation < ApplicationRecord end def remove_filter(statut, facet_id, value) - facet = Facet.find(procedure:, id: facet_id) + facet = procedure.find_facet(id: facet_id) table, column = facet.table, facet.column updated_filters = filters.dup @@ -130,7 +130,7 @@ class ProcedurePresentation < ApplicationRecord def update_displayed_fields(facet_ids) facet_ids = Array.wrap(facet_ids) - facets = facet_ids.map { |id| Facet.find(procedure:, id:) } + facets = facet_ids.map { |id| procedure.find_facet(id:) } update!(displayed_fields: facets) @@ -233,7 +233,7 @@ class ProcedurePresentation < ApplicationRecord value_column = filters.pluck('value_column').compact.first || :value case table when 'self' - field = Facet.dossier_facets(procedure:).find { |h| h.column == column } + field = procedure.dossier_facets.find { |h| h.column == column } if field.type == :date dates = values .filter_map { |v| Time.zone.parse(v).beginning_of_day rescue nil } @@ -348,7 +348,7 @@ class ProcedurePresentation < ApplicationRecord end def valid_columns_for_table(table) - @column_whitelist ||= Facet.facets(procedure:) + @column_whitelist ||= procedure.facets .group_by(&:table) .transform_values { |facets| Set.new(facets.map(&:column)) } diff --git a/spec/models/facet_spec.rb b/spec/models/concerns/facets_concern_spec.rb similarity index 97% rename from spec/models/facet_spec.rb rename to spec/models/concerns/facets_concern_spec.rb index 77b951062..5ba738441 100644 --- a/spec/models/facet_spec.rb +++ b/spec/models/concerns/facets_concern_spec.rb @@ -1,5 +1,7 @@ -describe Facet do +describe FacetsConcern do describe "#facets" do + subject { procedure.facets } + context 'when the procedure can have a SIRET number' do let(:procedure) do create(:procedure, @@ -44,8 +46,6 @@ describe Facet do ].map { Facet.new(**_1) } } - subject { Facet.facets(procedure:) } - context 'with explication/header_sections' do let(:types_de_champ_public) { Array.new(4) { { type: :text } } } let(:types_de_champ_private) { Array.new(4) { { type: :text } } } @@ -73,8 +73,6 @@ describe Facet do let(:procedure) { create(:procedure, :for_individual) } let(:procedure_presentation) { create(:procedure_presentation, assign_to: assign_to) } - subject { Facet.facets(procedure:) } - it { is_expected.to include(name_field, surname_field, gender_field) } end @@ -85,8 +83,6 @@ describe Facet do let(:decision_on) { Facet.new(label: "Date décision SVA", table: "self", column: "sva_svr_decision_on", classname: '', virtual: false, type: :date, scope: '', value_column: :value, filterable: true) } let(:decision_before_field) { Facet.new(label: "Date décision SVA avant", table: "self", column: "sva_svr_decision_before", classname: '', virtual: true, type: :date, scope: '', value_column: :value, filterable: true) } - subject { Facet.facets(procedure:) } - it { is_expected.to include(decision_on, decision_before_field) } end @@ -97,8 +93,6 @@ describe Facet do let(:decision_on) { Facet.new(label: "Date décision SVR", table: "self", column: "sva_svr_decision_on", classname: '', virtual: false, type: :date, scope: '', value_column: :value, filterable: true) } let(:decision_before_field) { Facet.new(label: "Date décision SVR avant", table: "self", column: "sva_svr_decision_before", classname: '', virtual: true, type: :date, scope: '', value_column: :value, filterable: true) } - subject { Facet.facets(procedure:) } - it { is_expected.to include(decision_on, decision_before_field) } end end diff --git a/spec/models/procedure_presentation_spec.rb b/spec/models/procedure_presentation_spec.rb index 546721eb8..926d476f9 100644 --- a/spec/models/procedure_presentation_spec.rb +++ b/spec/models/procedure_presentation_spec.rb @@ -58,7 +58,7 @@ describe ProcedurePresentation do let(:excluded_displayable_field) { Facet.new(label: "label1", table: "table1", column: "column1", virtual: true) } before do - allow(Facet).to receive(:facets).and_return([ + allow(procedure).to receive(:facets).and_return([ default_user_email, excluded_displayable_field ]) @@ -78,7 +78,7 @@ describe ProcedurePresentation do end before do - allow(Facet).to receive(:facets).and_return(included_displayable_field) + allow(procedure).to receive(:facets).and_return(included_displayable_field) end it { expect(subject.filterable_fields_options).to eq([["label1", "table1/column1"], ["depose_since", "self/depose_since"]]) }