feat(rnf/rna/siret): normalize address in champs.value_json

This commit is contained in:
mfo 2024-07-24 10:23:00 +02:00
parent 385277d5a0
commit d866309d45
No known key found for this signature in database
GPG key ID: 7CE3E1F5B794A8EC
7 changed files with 123 additions and 4 deletions

View file

@ -13,6 +13,10 @@ class Champs::RNFChamp < Champ
RNFService.new.(rnf_id:) RNFService.new.(rnf_id:)
end end
def update_with_external_data!(data:)
update!(data:, value_json: APIGeoService.parse_rnf_address(data[:address]))
end
def fetch_external_data? def fetch_external_data?
true true
end end

View file

@ -10,7 +10,7 @@ module RNAChampAssociationFetchableConcern
return clear_association!(:invalid) unless valid_champ_value? return clear_association!(:invalid) unless valid_champ_value?
return clear_association!(:not_found) if (data = APIEntreprise::RNAAdapter.new(rna, procedure_id).to_params).blank? 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 rescue APIEntreprise::API::Error => error
error_key = :network_error if error.try(:network_error?) && !APIEntrepriseService.api_djepva_up? error_key = :network_error if error.try(:network_error?) && !APIEntrepriseService.api_djepva_up?
clear_association!(error_key) clear_association!(error_key)

View file

@ -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!(: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') 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 rescue => error
if error.try(:network_error?) && !APIEntrepriseService.api_insee_up? if error.try(:network_error?) && !APIEntrepriseService.api_insee_up?
# TODO: notify ops
update!( update!(
etablissement: APIEntrepriseService.create_etablissement_as_degraded_mode(self, siret, user.id) etablissement: APIEntrepriseService.create_etablissement_as_degraded_mode(self, siret, user.id)
) )

View file

@ -122,6 +122,87 @@ class APIGeoService
}.merge(territory) }.merge(territory)
end 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) def safely_normalize_city_name(department_code, city_code, fallback)
return fallback if department_code.blank? || city_code.blank? return fallback if department_code.blank? || city_code.blank?

View file

@ -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_date_publication"]).to eq("2018-01-01")
expect(champ.data["association_rna"]).to eq("W751080001") expect(champ.data["association_rna"]).to eq("W751080001")
end 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
end end

View file

@ -576,7 +576,7 @@ describe Champ do
end end
context "fetch_external_data_later" do 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 it "fill data from external source" do
expect_any_instance_of(Champs::RNFChamp).to receive(:fetch_external_data) { data } expect_any_instance_of(Champs::RNFChamp).to receive(:fetch_external_data) { data }

View file

@ -96,6 +96,25 @@ describe Champs::RNFChamp, type: :model do
expect(subject.failure.reason).to be_a(API::Client::HTTPError) expect(subject.failure.reason).to be_a(API::Client::HTTPError)
} }
end 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 end
describe 'for_export' do describe 'for_export' do