Skip to content

Commit

Permalink
Merge pull request #11099 from colinux/many-siret-champ-columns
Browse files Browse the repository at this point in the history
ETQ instructeur je peux ajouter une colonne ou filtrer par des sous-valeurs d'un champ SIRET
  • Loading branch information
colinux authored Dec 6, 2024
2 parents 9fabef0 + bab474d commit 6ed6d1e
Show file tree
Hide file tree
Showing 29 changed files with 248 additions and 56 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ storage/
yarn-debug.log*
.yarn-integrity
/.vscode
/.zed
/.idea
/public/assets
/spec/support/spec_config.local.rb
Expand Down
3 changes: 1 addition & 2 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1497,8 +1497,7 @@ Style/WhileUntilModifier:
Enabled: false

Style/WordArray:
Enabled: true
EnforcedStyle: brackets
Enabled: false

Style/YodaCondition:
Enabled: true
Expand Down
6 changes: 5 additions & 1 deletion app/assets/stylesheets/buttons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,11 @@ ul.dropdown-items {
padding: 2 * $default-spacer;

&.large {
width: 340px;
width: 90vw;

@media (min-width: 62em) {
width: 40vw;
}
}

ul {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
= current_filter_tags

.fr-select-group
= label_tag :column, t('.column'), class: 'fr-label fr-m-0', id: 'instructeur-filter-combo-label', for: 'search-filter'
= label_tag :column, t('.column'), class: 'fr-label fr-mb-1w', id: 'instructeur-filter-combo-label', for: 'search-filter'
%react-fragment
= render ReactComponent.new "ComboBox/SingleComboBox", **filter_react_props

Expand Down
1 change: 1 addition & 0 deletions app/jobs/api_entreprise/entreprise_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ def perform(etablissement_id, procedure_id)
find_etablissement(etablissement_id)
etablissement_params = APIEntreprise::EntrepriseAdapter.new(etablissement.siret, procedure_id).to_params
etablissement.update!(etablissement_params)
etablissement.update_champ_value_json!
end
end
1 change: 1 addition & 0 deletions app/models/column.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def self.find(h_id)

def dossier_column? = false
def champ_column? = false
def filterable? = filterable

def label_for_value(value)
if options_for_select.present?
Expand Down
3 changes: 2 additions & 1 deletion app/models/columns/json_path_column.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
class Columns::JSONPathColumn < Columns::ChampColumn
attr_reader :jsonpath

def initialize(procedure_id:, label:, stable_id:, tdc_type:, jsonpath:, options_for_select: [], displayable:, type: :text)
def initialize(procedure_id:, label:, stable_id:, tdc_type:, jsonpath:, options_for_select: [], displayable:, filterable: true, type: :text)
@jsonpath = quote_string(jsonpath)

super(
Expand All @@ -12,6 +12,7 @@ def initialize(procedure_id:, label:, stable_id:, tdc_type:, jsonpath:, options_
stable_id:,
tdc_type:,
displayable:,
filterable:,
type:,
options_for_select:
)
Expand Down
8 changes: 4 additions & 4 deletions app/models/concerns/addressable_column_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ module AddressableColumnConcern
included do
def addressable_columns(procedure:, displayable: true, prefix: nil)
[
["code postal (5 chiffres)", '$.postal_code', :text, []],
["commune", '$.city_name', :text, []],
["département", '$.departement_code', :enum, APIGeoService.departement_options],
["region", '$.region_name', :enum, APIGeoService.region_options]
["Code postal (5 chiffres)", '$.postal_code', :text, []],
["Commune", '$.city_name', :text, []],
["Département", '$.departement_code', :enum, APIGeoService.departement_options],
["Région", '$.region_name', :enum, APIGeoService.region_options]
].map do |(label, jsonpath, type, options_for_select)|
Columns::JSONPathColumn.new(
procedure_id: procedure.id,
Expand Down
42 changes: 33 additions & 9 deletions app/models/concerns/columns_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,17 +154,41 @@ def individual_columns
end

def moral_columns
etablissements = ['entreprise_forme_juridique', 'entreprise_siren', 'entreprise_nom_commercial', 'entreprise_raison_sociale', 'entreprise_siret_siege_social']
.map { |column| dossier_col(table: 'etablissement', column:) }
siret_column = dossier_col(table: 'etablissement', column: :siret)

etablissement_dates = ['entreprise_date_creation'].map { |column| dossier_col(table: 'etablissement', column:, type: :date) }

for_export = ["siege_social", "naf", "adresse", "numero_voie", "type_voie", "nom_voie", "complement_adresse", "localite", "code_insee_localite", "entreprise_siren", "entreprise_capital_social", "entreprise_numero_tva_intracommunautaire", "entreprise_forme_juridique_code", "entreprise_code_effectif_entreprise", "entreprise_etat_administratif", "entreprise_nom", "entreprise_prenom", "association_rna", "association_titre", "association_objet", "association_date_creation", "association_date_declaration", "association_date_publication"]
.map { |column| dossier_col(table: 'etablissement', column:, displayable: false, filterable: false) }

other = ['siret', 'libelle_naf', 'code_postal'].map { |column| dossier_col(table: 'etablissement', column:) }
etablissements = Etablissement::DISPLAYABLE_COLUMNS.map do |(column, attributes)|
dossier_col(table: 'etablissement', column:, type: attributes[:type], filterable: attributes.fetch(:filterable, true))
end

[etablissements, etablissement_dates, other, for_export].flatten
others = %w[code_postal].map { |column| dossier_col(table: 'etablissement', column:) }

for_export = %w[
siege_social
code_naf
adresse
numero_voie
type_voie
nom_voie
complement_adresse
localite
code_insee_localite
entreprise_capital_social
entreprise_numero_tva_intracommunautaire
entreprise_forme_juridique_code
entreprise_code_effectif_entreprise
entreprise_etat_administratif
entreprise_siret_siege_social
entreprise_nom
entreprise_prenom
association_rna
association_titre
association_objet
association_date_creation
association_date_declaration
association_date_publication
].map { |column| dossier_col(table: 'etablissement', column:, displayable: false, filterable: false) }

[siret_column, etablissements, others, for_export].flatten
end

def types_de_champ_columns
Expand Down
28 changes: 28 additions & 0 deletions app/models/etablissement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ class Etablissement < ApplicationRecord

after_commit -> { dossier&.index_search_terms_later }

alias_attribute :code_naf, :naf

# See https://github.com/demarches-simplifiees/demarches-simplifiees.fr/pull/10591#discussion_r1819399688
# SIRET is already exposed as base column.
DISPLAYABLE_COLUMNS = {
"entreprise_raison_sociale" => { type: :text },
"entreprise_siren" => { type: :text },
"entreprise_nom_commercial" => { type: :text },
"entreprise_forme_juridique" => { type: :text },
"entreprise_date_creation" => { type: :date, filterable: false },
"libelle_naf" => { type: :text }
}.freeze

def entreprise_raison_sociale
read_attribute(:entreprise_raison_sociale).presence || raison_sociale_for_ei
end
Expand Down Expand Up @@ -193,6 +206,21 @@ def as_degraded_mode?
adresse.nil? # TOOD: maybe dedicated column or more robust way
end

def update_champ_value_json!
return if champ.nil?

champ.update!(value_json: champ_value_json)
end

def champ_value_json
address_data = APIGeoService.parse_etablissement_address(self)

DISPLAYABLE_COLUMNS.keys.each_with_object(address_data) do |attr, hash|
value = public_send(attr)
hash[attr.to_sym] = value if value.present?
end
end

private

def bilans_new_keys
Expand Down
23 changes: 22 additions & 1 deletion app/models/types_de_champ/siret_type_de_champ.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,27 @@ def estimated_fill_duration(revision)
def champ_blank_or_invalid?(champ) = Siret.new(siret: champ.value).invalid?

def columns(procedure:, displayable: true, prefix: nil)
super.concat(addressable_columns(procedure:, displayable:, prefix:))
super
.concat(etablissement_columns(procedure:, displayable:, prefix:))
.concat(addressable_columns(procedure:, displayable:, prefix:))
end

private

def etablissement_columns(procedure:, displayable:, prefix:)
i18n_scope = [:activerecord, :attributes, :procedure_presentation, :fields, :etablissement]

Etablissement::DISPLAYABLE_COLUMNS.map do |(column, attributes)|
Columns::JSONPathColumn.new(
procedure_id: procedure.id,
stable_id:,
tdc_type: type_champ,
label: [prefix, libelle, I18n.t(column, scope: i18n_scope)].compact.join(' – '),
type: attributes[:type],
jsonpath: "$.#{column}",
displayable: true,
filterable: attributes.fetch(:filterable, true)
)
end
end
end
7 changes: 6 additions & 1 deletion app/models/types_de_champ/type_de_champ_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,12 @@ def columns(procedure:, displayable: true, prefix: nil)
private

def libelle_with_prefix(prefix)
[prefix, libelle].compact.join(' – ')
# SIRET needs to be explicit in listings for better UI readability
if type_champ == "siret" && !libelle.upcase.include?("SIRET")
[prefix, libelle, "SIRET"].compact.join(' – ')
else
[prefix, libelle].compact.join(' – ')
end
end

def paths
Expand Down
10 changes: 2 additions & 8 deletions app/services/api_entreprise_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@ def create_etablissement(dossier_or_champ, siret, user_id = nil)

etablissement = dossier_or_champ.build_etablissement(etablissement_params)
etablissement.save!

if dossier_or_champ.is_a?(Champ)
dossier_or_champ.update!(value_json: APIGeoService.parse_etablissement_address(etablissement))
end
etablissement.update_champ_value_json!

perform_later_fetch_jobs(etablissement, procedure_id, user_id)

Expand All @@ -49,10 +46,7 @@ def update_etablissement_from_degraded_mode(etablissement, procedure_id)
return nil if etablissement_params.empty?

etablissement.update!(etablissement_params)

if etablissement.champ.present?
etablissement.champ.update!(value_json: APIGeoService.parse_etablissement_address(etablissement))
end
etablissement.update_champ_value_json!

etablissement
end
Expand Down
7 changes: 6 additions & 1 deletion app/tasks/maintenance/populate_siret_value_json_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@
# la normalisation des adresses des champs RNA/RNF/SIRET
# le fait de stocker ces données normalisées dans le champs.value_json (un jsonb)
# le backfill les anciens champs RNA/RNF/SIRET
# A (re)jouer après déploiement de PR #11013 https://github.com/demarches-simplifiees/demarches-simplifiees.fr/pull/11013
module Maintenance
class PopulateSiretValueJSONTask < MaintenanceTasks::Task
include RunnableOnDeployConcern

run_on_first_deploy

def collection
Champs::SiretChamp.where.not(value: nil)
end

def process(champ)
return if champ.etablissement.blank?
champ.update!(value_json: APIGeoService.parse_etablissement_address(champ.etablissement))
champ.update!(value_json: champ.etablissement.champ_value_json)
rescue ActiveRecord::RecordInvalid
# noop, just a champ without dossier
end
Expand Down
2 changes: 1 addition & 1 deletion app/views/shared/dossiers/_identite_entreprise.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
- c.with_value do
%p= etablissement.libelle_naf
= render Dossiers::RowShowComponent.new(label: "Libellé NAF") do |c|
= render Dossiers::RowShowComponent.new(label: "Code NAF") do |c|
- c.with_value do
%p= etablissement.naf
Expand Down
5 changes: 1 addition & 4 deletions config/locales/models/procedure_presentation/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,10 @@ en:
question_answer: Opinion yes/no
etablissement:
entreprise_etat_administratif: 'Entreprise état administratif'
entreprise_forme_juridique: Forme juridique
entreprise_nom_commercial: Commercial name
entreprise_raison_sociale: Raison sociale
entreprise_siret_siege_social: SIRET siège social
entreprise_date_creation: Entreprise date de création
siret: Établissement SIRET
libelle_naf: Libellé NAF
code_naf: Code NAF
siege_social: "Établissement siège social"
naf: "Établissement NAF"
adresse: "Établissement Adresse"
Expand Down
5 changes: 1 addition & 4 deletions config/locales/models/procedure_presentation/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,10 @@ fr:
question_answer: Avis oui/non
etablissement:
entreprise_etat_administratif: 'Entreprise état administratif'
entreprise_forme_juridique: Forme juridique
entreprise_nom_commercial: Nom commercial
entreprise_raison_sociale: Raison sociale
entreprise_siret_siege_social: SIRET siège social
entreprise_date_creation: Entreprise date de création
siret: Établissement SIRET
libelle_naf: Libellé NAF
code_naf: Code NAF
siege_social: "Établissement siège social"
naf: "Établissement NAF"
adresse: "Établissement Adresse"
Expand Down
2 changes: 1 addition & 1 deletion spec/factories/champ.rb
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@
factory :champ_do_not_use_siret, class: 'Champs::SiretChamp' do
association :etablissement, factory: [:etablissement]
value { '44011762001530' }
value_json { AddressProxy::ADDRESS_PARTS.index_by(&:itself) }
value_json { etablissement.champ_value_json }
end

factory :champ_do_not_use_rna, class: 'Champs::RNAChamp' do
Expand Down
16 changes: 15 additions & 1 deletion spec/models/columns/champ_column_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,21 @@
expect_type_de_champ_values('pays', eq(['France']))
expect_type_de_champ_values('epci', eq([nil]))
expect_type_de_champ_values('iban', eq([nil]))
expect_type_de_champ_values('siret', eq(["44011762001530", "postal_code", "city_name", "departement_code", "region_name"]))
expect_type_de_champ_values('siret', match_array(
[
"44011762001530",
"SA à conseil d'administration (s.a.i.)",
"440117620",
"GRTGAZ",
"GRTGAZ",
"1990-04-24",
"Transports par conduites",
"92270",
"Bois-Colombes",
"92",
"Île-de-France"
]
))
expect_type_de_champ_values('text', eq(['text']))
expect_type_de_champ_values('textarea', eq(['textarea']))
expect_type_de_champ_values('number', eq(['42']))
Expand Down
2 changes: 1 addition & 1 deletion spec/models/columns/dossier_column_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@
expect(procedure.find_column(label: "Date de création").value(dossier)).to be_an_instance_of(ActiveSupport::TimeWithZone)
expect(procedure.find_column(label: "Établissement SIRET").value(dossier)).to eq('44011762001530')
expect(procedure.find_column(label: "Libellé NAF").value(dossier)).to eq('Transports par conduites')
expect(procedure.find_column(label: "Code NAF").value(dossier)).to eq('4950Z')
expect(procedure.find_column(label: "Établissement code postal").value(dossier)).to eq('92270')
expect(procedure.find_column(label: "Établissement siège social").value(dossier)).to eq(true)
expect(procedure.find_column(label: "Établissement NAF").value(dossier)).to eq('4950Z')
expect(procedure.find_column(label: "Établissement Adresse").value(dossier)).to eq("GRTGAZ\r IMMEUBLE BORA\r 6 RUE RAOUL NORDLING\r 92270 BOIS COLOMBES\r")
expect(procedure.find_column(label: "Établissement numero voie").value(dossier)).to eq('6')
expect(procedure.find_column(label: "Établissement type voie").value(dossier)).to eq('RUE')
Expand Down
6 changes: 3 additions & 3 deletions spec/models/concerns/columns_concern_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@
end

context 'with rna' do
let(:types_de_champ_public) { [{ type: :rna, libelle: 'rna' }] }
let(:types_de_champ_public) { [{ type: :rna, libelle: 'RNA' }] }
let(:types_de_champ_private) { [] }
it { expect(subject.map(&:label)).to include('rnacommune') }
it { expect(subject.map(&:label)).to include('RNACommune') }
end

context 'with linked drop down list' do
Expand Down Expand Up @@ -187,8 +187,8 @@
procedure.find_column(label: "France connecté ?"),
procedure.find_column(label: "Établissement SIRET"),
procedure.find_column(label: "Établissement siège social"),
procedure.find_column(label: "Établissement NAF"),
procedure.find_column(label: "Libellé NAF"),
procedure.find_column(label: "Code NAF"),
procedure.find_column(label: "Établissement Adresse"),
procedure.find_column(label: "Établissement numero voie"),
procedure.find_column(label: "Établissement type voie"),
Expand Down
Loading

0 comments on commit 6ed6d1e

Please sign in to comment.