demarches-normaliennes/app/services/api_geo_service.rb
2023-03-28 16:34:19 +02:00

131 lines
3.9 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

class APIGeoService
class << self
def countries(locale: I18n.locale)
I18nData.countries(locale)
.merge(get_localized_additional_countries(locale))
.map { |(code, name)| { name:, code: } }
.sort_by { I18n.transliterate(_1[:name].tr('î', 'Î')) }
end
def country_name(code, locale: I18n.locale)
countries(locale:).find { _1[:code] == code }&.dig(:name)
end
def country_code(name)
return if name.nil?
code = I18nData.country_code(name) || I18nData.country_code(name.humanize) || I18nData.country_code(name.titleize)
if code.nil?
countries_index_fr[I18n.transliterate(name).upcase]&.dig(:code)
else
code
end
end
def regions
get_from_api_geo(:regions).sort_by { I18n.transliterate(_1[:name]) }
end
def region_name(code)
regions.find { _1[:code] == code }&.dig(:name)
end
def region_code(name)
return if name.nil?
regions.find { _1[:name] == name }&.dig(:code)
end
def departements
[{ code: '99', name: 'Etranger' }] + get_from_api_geo('departements?zone=metro,drom,com').sort_by { _1[:code] }
end
def departement_name(code)
departements.find { _1[:code] == code }&.dig(:name)
end
def departement_code(name)
return if name.nil?
departements.find { _1[:name] == name }&.dig(:code)
end
def epcis(departement_code)
get_from_api_geo("epcis?codeDepartement=#{departement_code}").sort_by { I18n.transliterate(_1[:name]) }
end
def epci_name(departement_code, code)
epcis(departement_code).find { _1[:code] == code }&.dig(:name)
end
def epci_code(departement_code, name)
epcis(departement_code).find { _1[:name] == name }&.dig(:code)
end
def communes(departement_code)
get_from_api_geo("communes?codeDepartement=#{departement_code}&type=commune-actuelle,arrondissement-municipal").sort_by { I18n.transliterate([_1[:name], _1[:postal_code]].join(' ')) }
end
def communes_by_postal_code(postal_code)
if postal_code.size > 3
metro_code = postal_code[0..1]
drom_com_code = postal_code[0..2]
if metro_code == '20'
communes('2A') + communes('2B')
elsif metro_code == '97' || metro_code == '98'
departement_name(drom_com_code) ? communes(drom_com_code) : []
else
departement_name(metro_code) ? communes(metro_code) : []
end
.filter { _1[:postal_code] == postal_code }
.sort_by { I18n.transliterate([_1[:name], _1[:postal_code]].join(' ')) }
else
[]
end
end
def commune_name(departement_code, code)
communes(departement_code).find { _1[:code] == code }&.dig(:name)
end
def commune_code(departement_code, name)
communes(departement_code).find { _1[:name] == name }&.dig(:code)
end
private
def get_from_api_geo(scope)
Rails.cache.fetch("api_geo_#{scope}", expires_in: 1.year) do
response = Typhoeus.get("#{API_GEO_URL}/#{scope}")
JSON.parse(response.body).map(&:symbolize_keys).flat_map do |result|
item = {
name: result[:nom].tr("'", ''),
code: result[:code],
epci_code: result[:codeEpci],
departement_code: result[:codeDepartement]
}.compact
if result[:codesPostaux].present?
result[:codesPostaux].map { item.merge(postal_code: _1) }
else
[item]
end
end
end
end
def countries_index_fr
Rails.cache.fetch('countries_index_fr', expires_in: 1.year) do
countries(locale: 'FR').index_by { I18n.transliterate(_1[:name]).upcase }
end
end
def get_localized_additional_countries(locale)
additional_countries[locale.to_s.upcase] || {}
end
def additional_countries
{
'FR' => { 'XK' => 'Kosovo' },
'EN' => { 'XK' => 'Kosovo' }
}
end
end
end