# frozen_string_literal: true module PrefillableFromServicePublicConcern extend ActiveSupport::Concern included do def prefill_from_siret future_sp = Concurrent::Future.execute { AnnuaireServicePublicService.new.call(siret:) } future_api_ent = Concurrent::Future.execute { APIRechercheEntreprisesService.new.call(siret:) } result_sp = future_sp.value! result_api_ent = future_api_ent.value! prefill_from_service_public(result_sp) prefill_from_api_entreprise(result_api_ent) [result_sp, result_api_ent] end private def prefill_from_service_public(result) case result in Dry::Monads::Success(data) self.nom = data[:nom] if nom.blank? self.email = data[:adresse_courriel] if email.blank? self.telephone = data[:telephone]&.first&.dig("valeur") if telephone.blank? self.horaires = denormalize_plage_ouverture(data[:plage_ouverture]) if horaires.blank? self.adresse = APIGeoService.inline_service_public_address(data[:adresse]&.first) if adresse.blank? else # NOOP end end def prefill_from_api_entreprise(result) case result in Dry::Monads::Success(data) self.type_organisme = detect_type_organisme(data) if type_organisme.blank? self.nom = data[:nom_complet] if nom.blank? self.adresse = data.dig(:siege, :geo_adresse) if adresse.blank? else # NOOP end end def denormalize_plage_ouverture(data) return if data.blank? data.map do |range| day_range = range.values_at('nom_jour_debut', 'nom_jour_fin').uniq.join(' au ') hours_range = (1..2).each_with_object([]) do |i, hours| start_hour = range["valeur_heure_debut_#{i}"] end_hour = range["valeur_heure_fin_#{i}"] if start_hour.present? && end_hour.present? hours << "de #{format_time(start_hour)} à #{format_time(end_hour)}" end end result = day_range result += " : #{hours_range.join(' et ')}" if hours_range.present? result += " (#{range['commentaire']})" if range['commentaire'].present? result end.join("\n") end def detect_type_organisme(data) # Cf https://recherche-entreprises.api.gouv.fr/docs/#tag/Recherche-textuelle/paths/~1search/get type = if data.dig(:complements, :collectivite_territoriale).present? :collectivite_territoriale elsif data.dig(:complements, :est_association) :association elsif data[:section_activite_principale] == "P" :etablissement_enseignement elsif data[:nom_complet].match?(/MINISTERE|MINISTERIEL/) :administration_centrale else # we can't differentiate between operateur d'état, administration centrale and service déconcentré de l'état, set the most frequent :service_deconcentre_de_l_etat end Service.type_organismes[type] end def format_time(str_time) Time.zone .parse(str_time) .strftime("%-H:%M") end end end