diff --git a/app/models/champs/rnf_champ.rb b/app/models/champs/rnf_champ.rb index 05e7dede7..e4ac7ff2a 100644 --- a/app/models/champs/rnf_champ.rb +++ b/app/models/champs/rnf_champ.rb @@ -13,6 +13,10 @@ class Champs::RNFChamp < Champ RNFService.new.(rnf_id:) end + def update_with_external_data!(data:) + update!(data:, value_json: APIGeoService.parse_rnf_address(data[:address])) + end + def fetch_external_data? true end diff --git a/app/models/concerns/rna_champ_association_fetchable_concern.rb b/app/models/concerns/rna_champ_association_fetchable_concern.rb index 1a17691dc..0788d428d 100644 --- a/app/models/concerns/rna_champ_association_fetchable_concern.rb +++ b/app/models/concerns/rna_champ_association_fetchable_concern.rb @@ -10,7 +10,7 @@ module RNAChampAssociationFetchableConcern return clear_association!(:invalid) unless valid_champ_value? return clear_association!(:not_found) if (data = APIEntreprise::RNAAdapter.new(rna, procedure_id).to_params).blank? - update!(data: data) + update!(data: data, value_json: APIGeoService.parse_rna_address(data['adresse'])) rescue APIEntreprise::API::Error => error error_key = :network_error if error.try(:network_error?) && !APIEntrepriseService.api_djepva_up? clear_association!(error_key) diff --git a/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb b/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb index 333d58ad8..bfff40977 100644 --- a/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb +++ b/app/models/concerns/siret_champ_etablissement_fetchable_concern.rb @@ -9,10 +9,9 @@ module SiretChampEtablissementFetchableConcern return clear_etablissement!(:invalid_checksum) if invalid_because?(siret, :checksum) # i18n-tasks-use t('errors.messages.invalid_siret_checksum') return clear_etablissement!(:not_found) unless (etablissement = APIEntrepriseService.create_etablissement(self, siret, user&.id)) # i18n-tasks-use t('errors.messages.siret_not_found') - update!(etablissement: etablissement) + update!(etablissement: etablissement, value_json: APIGeoService.parse_etablissement_address(etablissement)) rescue => error if error.try(:network_error?) && !APIEntrepriseService.api_insee_up? - # TODO: notify ops update!( etablissement: APIEntrepriseService.create_etablissement_as_degraded_mode(self, siret, user.id) ) diff --git a/app/services/api_geo_service.rb b/app/services/api_geo_service.rb index f1ed8c228..167bae36b 100644 --- a/app/services/api_geo_service.rb +++ b/app/services/api_geo_service.rb @@ -122,6 +122,87 @@ class APIGeoService }.merge(territory) end + def parse_rna_address(address) + postal_code = address[:code_postal] + city_name_fallback = address[:commune] + city_code = address[:code_insee] + departement_code, region_code = if postal_code.present? && city_code.present? + commune = communes_by_postal_code(postal_code).find { _1[:code] == city_code } + if commune.present? + [commune[:departement_code], commune[:region_code]] + else + [] + end + end + + { + street_number: address[:numero_voie], + street_name: address[:libelle_voie], + street_address: address[:libelle_voie].present? ? [address[:numero_voie], address[:type_voie], address[:libelle_voie]].compact.join(' ') : nil, + postal_code: postal_code.presence || '', + city_name: safely_normalize_city_name(departement_code, city_code, city_name_fallback), + city_code: city_code.presence || '', + departement_code:, + departement_name: departement_name(departement_code), + region_code:, + region_name: region_name(region_code) + } + end + + def parse_rnf_address(address) + postal_code = address[:postalCode] + city_name_fallback = address[:cityName] + city_code = address[:cityCode] + departement_code, region_code = if postal_code.present? && city_code.present? + commune = communes_by_postal_code(postal_code).find { _1[:code] == city_code } + if commune.present? + [commune[:departement_code], commune[:region_code]] + else + [] + end + end + + { + street_number: address[:streetNumber], + street_name: address[:streetName], + street_address: address[:streetAddress], + postal_code: postal_code.presence || '', + city_name: safely_normalize_city_name(departement_code, city_code, city_name_fallback), + city_code: city_code.presence || '', + departement_code:, + departement_name: departement_name(departement_code), + region_code:, + region_name: region_name(region_code) + } + end + + def parse_etablissement_address(etablissement) + postal_code = etablissement.code_postal + city_name_fallback = etablissement.localite.presence || '' + city_code = etablissement.code_insee_localite + departement_code, region_code = if postal_code.present? && city_code.present? + commune = communes_by_postal_code(postal_code).find { _1[:code] == city_code } + if commune.present? + [commune[:departement_code], commune[:region_code]] + else + [] + end + end + + { + street_number: etablissement.numero_voie, + street_name: etablissement.nom_voie, + street_address: etablissement.nom_voie.present? ? [etablissement.numero_voie, etablissement.type_voie, etablissement.nom_voie].compact.join(' ') : nil, + postal_code: postal_code.presence || '', + city_name: safely_normalize_city_name(departement_code, city_code, city_name_fallback), + city_code: city_code.presence || '', + departement_code:, + departement_name: departement_name(departement_code), + region_code:, + region_name: region_name(region_code) + } + end + def safely_normalize_city_name(department_code, city_code, fallback) return fallback if department_code.blank? || city_code.blank? diff --git a/spec/controllers/champs/rna_controller_spec.rb b/spec/controllers/champs/rna_controller_spec.rb index 449c34c68..288ba48df 100644 --- a/spec/controllers/champs/rna_controller_spec.rb +++ b/spec/controllers/champs/rna_controller_spec.rb @@ -117,6 +117,22 @@ describe Champs::RNAController, type: :controller do expect(champ.data["association_date_publication"]).to eq("2018-01-01") expect(champ.data["association_rna"]).to eq("W751080001") end + it 'populates the value_json and RNA on the model' do + champ.reload + expect(champ.value).to eq(rna) + expect(champ.value_json).to eq({ + "city_code" => "75108", + "city_name" => "Paris", + "departement_code" => nil, # might seem broken lookup, but no, it's anonymized + "departement_name" => nil, + "postal_code" => "75009", + "region_code" => nil, + "region_name" => nil, + "street_address" => "33 rue de Modagor", + "street_name" => "de Modagor", + "street_number" => "33" + }) + end end end diff --git a/spec/models/champ_spec.rb b/spec/models/champ_spec.rb index fe457faff..22f64c5e7 100644 --- a/spec/models/champ_spec.rb +++ b/spec/models/champ_spec.rb @@ -576,7 +576,7 @@ describe Champ do end context "fetch_external_data_later" do - let(:data) { 'some other data' } + let(:data) { { data: { address: { city: "some external data" } } }.with_indifferent_access } it "fill data from external source" do expect_any_instance_of(Champs::RNFChamp).to receive(:fetch_external_data) { data } diff --git a/spec/models/champs/rnf_champ_spec.rb b/spec/models/champs/rnf_champ_spec.rb index bd22eff4d..aa15b20e1 100644 --- a/spec/models/champs/rnf_champ_spec.rb +++ b/spec/models/champs/rnf_champ_spec.rb @@ -96,6 +96,25 @@ describe Champs::RNFChamp, type: :model do expect(subject.failure.reason).to be_a(API::Client::HTTPError) } end + + describe 'update_with_external_data!' do + it 'works' do + value_json = { + :street_number => "16", + :street_name => "Rue du Général de Boissieu", + :street_address => "16 Rue du Général de Boissieu", + :postal_code => "75015", + :city_name => "Paris 15e Arrondissement", + :city_code => "75115", + :departement_code => "75", + :departement_name => "Paris", + :region_code => "11", + :region_name => "Île-de-France" + } + expect(champ).to receive(:update!).with(data: anything, value_json:) + champ.update_with_external_data!(data: subject.value!) + end + end end describe 'for_export' do