Merge pull request #9648 from demarches-simplifiees/add-rnf-service
Ajout d'un nouveau référentiel : le Répertoire National des Fondations (RNF)
This commit is contained in:
commit
0968f02a26
31 changed files with 378 additions and 14 deletions
|
@ -48,6 +48,8 @@
|
||||||
= render partial: "shared/champs/regions/show", locals: { champ: champ }
|
= render partial: "shared/champs/regions/show", locals: { champ: champ }
|
||||||
- when TypeDeChamp.type_champs.fetch(:rna)
|
- when TypeDeChamp.type_champs.fetch(:rna)
|
||||||
= render partial: "shared/champs/rna/show", locals: { champ: champ, profile: @profile }
|
= render partial: "shared/champs/rna/show", locals: { champ: champ, profile: @profile }
|
||||||
|
- when TypeDeChamp.type_champs.fetch(:rnf)
|
||||||
|
= render partial: "shared/champs/rnf/show", locals: { champ: champ, profile: @profile }
|
||||||
- when TypeDeChamp.type_champs.fetch(:epci)
|
- when TypeDeChamp.type_champs.fetch(:epci)
|
||||||
= render partial: "shared/champs/epci/show", locals: { champ: champ }
|
= render partial: "shared/champs/epci/show", locals: { champ: champ }
|
||||||
- when TypeDeChamp.type_champs.fetch(:cojo)
|
- when TypeDeChamp.type_champs.fetch(:cojo)
|
||||||
|
@ -60,4 +62,3 @@
|
||||||
%p= helpers.number_with_html_delimiter(champ.to_s)
|
%p= helpers.number_with_html_delimiter(champ.to_s)
|
||||||
- else
|
- else
|
||||||
= helpers.format_text_value(champ.to_s.strip) # format already wrap in p
|
= helpers.format_text_value(champ.to_s.strip) # format already wrap in p
|
||||||
|
|
||||||
|
|
2
app/components/editable_champ/rnf_component.rb
Normal file
2
app/components/editable_champ/rnf_component.rb
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
class EditableChamp::RNFComponent < EditableChamp::EditableChampBaseComponent
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
en:
|
||||||
|
rnf_info_error: No foundation found
|
||||||
|
rnf_info_pending: RNF verification pending
|
||||||
|
rnf_info_success: "This RNF matches %{title}"
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
fr:
|
||||||
|
rnf_info_error: Aucune fondation trouvée
|
||||||
|
rnf_info_pending: Vérification du RNF en cours
|
||||||
|
rnf_info_success: "Ce RNF correspond à %{title}"
|
|
@ -0,0 +1,9 @@
|
||||||
|
= @form.text_field :external_id, required: @champ.required?, class: "width-33-desktop fr-input small-margin", id: @champ.input_id
|
||||||
|
|
||||||
|
.rnf-info{ id: dom_id(@champ, :rnf_info) }
|
||||||
|
- if @champ.fetch_external_data_error?
|
||||||
|
%p.fr-error-text= t('.rnf_info_error')
|
||||||
|
- elsif @champ.fetch_external_data_pending?
|
||||||
|
%p.fr-info-text= t('.rnf_info_pending')
|
||||||
|
- elsif @champ.data?
|
||||||
|
%p.fr-info-text= t('.rnf_info_success', title: @champ.title)
|
|
@ -110,6 +110,7 @@ class API::V2::Schema < GraphQL::Schema
|
||||||
Types::Champs::Descriptor::RegionChampDescriptorType,
|
Types::Champs::Descriptor::RegionChampDescriptorType,
|
||||||
Types::Champs::Descriptor::RepetitionChampDescriptorType,
|
Types::Champs::Descriptor::RepetitionChampDescriptorType,
|
||||||
Types::Champs::Descriptor::RNAChampDescriptorType,
|
Types::Champs::Descriptor::RNAChampDescriptorType,
|
||||||
|
Types::Champs::Descriptor::RNFChampDescriptorType,
|
||||||
Types::Champs::Descriptor::SiretChampDescriptorType,
|
Types::Champs::Descriptor::SiretChampDescriptorType,
|
||||||
Types::Champs::Descriptor::TextareaChampDescriptorType,
|
Types::Champs::Descriptor::TextareaChampDescriptorType,
|
||||||
Types::Champs::Descriptor::TextChampDescriptorType,
|
Types::Champs::Descriptor::TextChampDescriptorType,
|
||||||
|
|
|
@ -3553,6 +3553,34 @@ type RNAChampDescriptor implements ChampDescriptor {
|
||||||
type: TypeDeChamp! @deprecated(reason: "Utilisez le champ `__typename` à la place.")
|
type: TypeDeChamp! @deprecated(reason: "Utilisez le champ `__typename` à la place.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RNFChampDescriptor implements ChampDescriptor {
|
||||||
|
"""
|
||||||
|
Description des champs d’un bloc répétable.
|
||||||
|
"""
|
||||||
|
champDescriptors: [ChampDescriptor!] @deprecated(reason: "Utilisez le champ `RepetitionChampDescriptor.champ_descriptors` à la place.")
|
||||||
|
|
||||||
|
"""
|
||||||
|
Description du champ.
|
||||||
|
"""
|
||||||
|
description: String
|
||||||
|
id: ID!
|
||||||
|
|
||||||
|
"""
|
||||||
|
Libellé du champ.
|
||||||
|
"""
|
||||||
|
label: String!
|
||||||
|
|
||||||
|
"""
|
||||||
|
Est-ce que le champ est obligatoire ?
|
||||||
|
"""
|
||||||
|
required: Boolean!
|
||||||
|
|
||||||
|
"""
|
||||||
|
Type de la valeur du champ.
|
||||||
|
"""
|
||||||
|
type: TypeDeChamp! @deprecated(reason: "Utilisez le champ `__typename` à la place.")
|
||||||
|
}
|
||||||
|
|
||||||
type Region {
|
type Region {
|
||||||
code: String!
|
code: String!
|
||||||
name: String!
|
name: String!
|
||||||
|
@ -4072,10 +4100,15 @@ enum TypeDeChamp {
|
||||||
repetition
|
repetition
|
||||||
|
|
||||||
"""
|
"""
|
||||||
RNA
|
RNA (Répertoire national des associations)
|
||||||
"""
|
"""
|
||||||
rna
|
rna
|
||||||
|
|
||||||
|
"""
|
||||||
|
RNF (Répertoire national des fondations)
|
||||||
|
"""
|
||||||
|
rnf
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Numéro Siret
|
Numéro Siret
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -72,6 +72,8 @@ module Types
|
||||||
Types::Champs::Descriptor::PieceJustificativeChampDescriptorType
|
Types::Champs::Descriptor::PieceJustificativeChampDescriptorType
|
||||||
when TypeDeChamp.type_champs.fetch(:rna)
|
when TypeDeChamp.type_champs.fetch(:rna)
|
||||||
Types::Champs::Descriptor::RNAChampDescriptorType
|
Types::Champs::Descriptor::RNAChampDescriptorType
|
||||||
|
when TypeDeChamp.type_champs.fetch(:rnf)
|
||||||
|
Types::Champs::Descriptor::RNFChampDescriptorType
|
||||||
when TypeDeChamp.type_champs.fetch(:carte)
|
when TypeDeChamp.type_champs.fetch(:carte)
|
||||||
Types::Champs::Descriptor::CarteChampDescriptorType
|
Types::Champs::Descriptor::CarteChampDescriptorType
|
||||||
when TypeDeChamp.type_champs.fetch(:repetition)
|
when TypeDeChamp.type_champs.fetch(:repetition)
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
module Types::Champs::Descriptor
|
||||||
|
class RNFChampDescriptorType < Types::BaseObject
|
||||||
|
implements Types::ChampDescriptorType
|
||||||
|
end
|
||||||
|
end
|
|
@ -205,9 +205,7 @@ class Champ < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def log_fetch_external_data_exception(exception)
|
def log_fetch_external_data_exception(exception)
|
||||||
exceptions = self.fetch_external_data_exceptions ||= []
|
update_column(:fetch_external_data_exceptions, [exception.inspect])
|
||||||
exceptions << exception.inspect
|
|
||||||
update_column(:fetch_external_data_exceptions, exceptions)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_external_data?
|
def fetch_external_data?
|
||||||
|
@ -218,10 +216,12 @@ class Champ < ApplicationRecord
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fetch_external_data_error?
|
||||||
|
fetch_external_data_exceptions.present? && self.external_id.present?
|
||||||
|
end
|
||||||
|
|
||||||
def fetch_external_data_pending?
|
def fetch_external_data_pending?
|
||||||
# We don't have a good mechanism right now to know if the last fetch has errored. So, in order
|
fetch_external_data? && poll_external_data? && external_id.present? && data.nil? && !fetch_external_data_error?
|
||||||
# to ensure we don't poll to infinity, we stop after 5 minutes no matter what.
|
|
||||||
fetch_external_data? && poll_external_data? && external_id.present? && data.nil? && updated_at > 5.minutes.ago
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_external_data
|
def fetch_external_data
|
||||||
|
@ -289,6 +289,7 @@ class Champ < ApplicationRecord
|
||||||
|
|
||||||
def fetch_external_data_later
|
def fetch_external_data_later
|
||||||
if fetch_external_data? && external_id.present? && data.nil?
|
if fetch_external_data? && external_id.present? && data.nil?
|
||||||
|
update_column(:fetch_external_data_exceptions, [])
|
||||||
ChampFetchExternalDataJob.perform_later(self, external_id)
|
ChampFetchExternalDataJob.perform_later(self, external_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
23
app/models/champs/rnf_champ.rb
Normal file
23
app/models/champs/rnf_champ.rb
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
class Champs::RNFChamp < Champ
|
||||||
|
store_accessor :data, :title, :email, :phone, :createdAt, :updatedAt, :dissolvedAt, :address, :status
|
||||||
|
|
||||||
|
def rnf_id
|
||||||
|
external_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_external_data
|
||||||
|
RNFService.new.(rnf_id:)
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_external_data?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def poll_external_data?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def blank?
|
||||||
|
rnf_id.blank?
|
||||||
|
end
|
||||||
|
end
|
|
@ -51,6 +51,7 @@ class TypeDeChamp < ApplicationRecord
|
||||||
yes_no: CHOICE,
|
yes_no: CHOICE,
|
||||||
annuaire_education: REFERENTIEL_EXTERNE,
|
annuaire_education: REFERENTIEL_EXTERNE,
|
||||||
rna: REFERENTIEL_EXTERNE,
|
rna: REFERENTIEL_EXTERNE,
|
||||||
|
rnf: REFERENTIEL_EXTERNE,
|
||||||
carte: REFERENTIEL_EXTERNE,
|
carte: REFERENTIEL_EXTERNE,
|
||||||
cnaf: REFERENTIEL_EXTERNE,
|
cnaf: REFERENTIEL_EXTERNE,
|
||||||
dgfip: REFERENTIEL_EXTERNE,
|
dgfip: REFERENTIEL_EXTERNE,
|
||||||
|
@ -91,6 +92,7 @@ class TypeDeChamp < ApplicationRecord
|
||||||
yes_no: 'yes_no',
|
yes_no: 'yes_no',
|
||||||
annuaire_education: 'annuaire_education',
|
annuaire_education: 'annuaire_education',
|
||||||
rna: 'rna',
|
rna: 'rna',
|
||||||
|
rnf: 'rnf',
|
||||||
carte: 'carte',
|
carte: 'carte',
|
||||||
cnaf: 'cnaf',
|
cnaf: 'cnaf',
|
||||||
dgfip: 'dgfip',
|
dgfip: 'dgfip',
|
||||||
|
|
2
app/models/types_de_champ/rnf_type_de_champ.rb
Normal file
2
app/models/types_de_champ/rnf_type_de_champ.rb
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
class TypesDeChamp::RNFTypeDeChamp < TypesDeChamp::TextTypeDeChamp
|
||||||
|
end
|
36
app/schemas/rnf.json
Normal file
36
app/schemas/rnf.json
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
{
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
|
"$id": "http://demarches-simplifiees.fr/rnf.schema.json",
|
||||||
|
"title": "RNF",
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": { "type": "integer" },
|
||||||
|
"rnfId": { "type": "string" },
|
||||||
|
"type": { "type": "string" },
|
||||||
|
"department": { "type": "string" },
|
||||||
|
"title": { "type": "string" },
|
||||||
|
"dissolvedAt": { "type": ["string", "null"] },
|
||||||
|
"phone": { "type": "string" },
|
||||||
|
"email": { "type": "string" },
|
||||||
|
"addressId": { "type": "integer" },
|
||||||
|
"address": {
|
||||||
|
"id": { "type": "integer" },
|
||||||
|
"createdAt":{ "type": "string" },
|
||||||
|
"updatedAt":{ "type": "string" },
|
||||||
|
"label":{ "type": "string" },
|
||||||
|
"type":{ "type": "string" },
|
||||||
|
"streetAddress":{ "type": "string" },
|
||||||
|
"streetNumber":{ "type": "string" },
|
||||||
|
"streetName":{ "type": "string" },
|
||||||
|
"postalCode":{ "type": "string" },
|
||||||
|
"cityName":{ "type": "string" },
|
||||||
|
"cityCode":{ "type": "string" },
|
||||||
|
"departmentName":{ "type": "string" },
|
||||||
|
"departmentCode":{ "type": "string" },
|
||||||
|
"regionName":{ "type": "string" },
|
||||||
|
"regionCode":{ "type": "string" }
|
||||||
|
},
|
||||||
|
"status": { "type": ["string", "null"] },
|
||||||
|
"persons": { "type": "array" }
|
||||||
|
}
|
||||||
|
}
|
25
app/services/rnf_service.rb
Normal file
25
app/services/rnf_service.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
class RNFService
|
||||||
|
include Dry::Monads[:result]
|
||||||
|
|
||||||
|
def call(rnf_id:)
|
||||||
|
result = API::Client.new.(url: "#{url}/#{rnf_id}", schema:)
|
||||||
|
case result
|
||||||
|
in Success(body:)
|
||||||
|
Success(body)
|
||||||
|
in Failure(code:, reason:) if code.in?(401..403)
|
||||||
|
Failure(API::Client::Error[:unauthorized, code, false, reason])
|
||||||
|
else
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def schema
|
||||||
|
JSONSchemer.schema(Rails.root.join('app/schemas/rnf.json'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def url
|
||||||
|
"#{API_RNF_URL}/api/foundations"
|
||||||
|
end
|
||||||
|
end
|
30
app/views/shared/champs/rnf/_show.html.haml
Normal file
30
app/views/shared/champs/rnf/_show.html.haml
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
- if champ.data.blank?
|
||||||
|
%p= t('.not_found', rnf: champ.rnf_id)
|
||||||
|
- else
|
||||||
|
.fr-background-alt--grey.fr-p-3v
|
||||||
|
= render Dossiers::RowShowComponent.new(label: t("activemodel.attributes.rnf_champ.rnf_id")) do |c|
|
||||||
|
- c.with_value do
|
||||||
|
%p
|
||||||
|
= champ.rnf_id
|
||||||
|
= render Dsfr::CopyButtonComponent.new(text: champ.rnf_id, title: t("activemodel.attributes.rnf_champ.paste"), success: t("activemodel.attributes.rnf_champ.paste_success"))
|
||||||
|
|
||||||
|
- ['title', 'email', 'phone','status'].each do |scope|
|
||||||
|
- if champ.data[scope].present?
|
||||||
|
= render Dossiers::RowShowComponent.new(label: t("activemodel.attributes.rnf_champ.data.#{scope}")) do |c|
|
||||||
|
- c.with_value do
|
||||||
|
%p= champ.data[scope]
|
||||||
|
|
||||||
|
- ['createdAt', 'updatedAt', 'dissolvedAt'].each do |scope|
|
||||||
|
- if champ.data[scope].present?
|
||||||
|
= render Dossiers::RowShowComponent.new(label: t("activemodel.attributes.rnf_champ.data.#{scope}")) do |c|
|
||||||
|
- c.with_value do
|
||||||
|
%p= l(champ.data[scope].to_date)
|
||||||
|
|
||||||
|
- if champ.data['address'].present?
|
||||||
|
- ['label', 'cityCode', 'postalCode'].each do |scope|
|
||||||
|
= render Dossiers::RowShowComponent.new(label: t("activemodel.attributes.rnf_champ.data.#{scope}")) do |c|
|
||||||
|
- c.with_value do
|
||||||
|
%p= champ.data['address'][scope]
|
||||||
|
= render Dossiers::RowShowComponent.new(label: t("activemodel.attributes.rnf_champ.data.department")) do |c|
|
||||||
|
- c.with_value do
|
||||||
|
%p= "#{champ.data['address']['departmentCode']} – #{champ.data['address']['departmentName']}"
|
|
@ -7,6 +7,7 @@ API_GEO_URL = ENV.fetch("API_GEO_URL", "https://geo.api.gouv.fr")
|
||||||
API_PARTICULIER_URL = ENV.fetch("API_PARTICULIER_URL", "https://particulier.api.gouv.fr/api")
|
API_PARTICULIER_URL = ENV.fetch("API_PARTICULIER_URL", "https://particulier.api.gouv.fr/api")
|
||||||
API_TCHAP_URL = ENV.fetch("API_TCHAP_URL", "https://matrix.agent.tchap.gouv.fr/_matrix/identity/api/v1")
|
API_TCHAP_URL = ENV.fetch("API_TCHAP_URL", "https://matrix.agent.tchap.gouv.fr/_matrix/identity/api/v1")
|
||||||
API_COJO_URL = ENV.fetch("API_COJO_URL", nil)
|
API_COJO_URL = ENV.fetch("API_COJO_URL", nil)
|
||||||
|
API_RNF_URL = ENV.fetch("API_RNF_URL", "https://rnf.dso.numerique-interieur.com")
|
||||||
HELPSCOUT_API_URL = ENV.fetch("HELPSCOUT_API_URL", "https://api.helpscout.net/v2")
|
HELPSCOUT_API_URL = ENV.fetch("HELPSCOUT_API_URL", "https://api.helpscout.net/v2")
|
||||||
SENDINBLUE_API_URL = ENV.fetch("SENDINBLUE_API_URL", "https://in-automate.sendinblue.com/api/v2")
|
SENDINBLUE_API_URL = ENV.fetch("SENDINBLUE_API_URL", "https://in-automate.sendinblue.com/api/v2")
|
||||||
SENDINBLUE_API_V3_URL = ENV.fetch("SENDINBLUE_API_V3_URL", "https://api.sendinblue.com/v3")
|
SENDINBLUE_API_V3_URL = ENV.fetch("SENDINBLUE_API_V3_URL", "https://api.sendinblue.com/v3")
|
||||||
|
|
|
@ -14,6 +14,7 @@ ActiveSupport::Inflector.inflections(:en) do |inflect|
|
||||||
inflect.acronym 'IP'
|
inflect.acronym 'IP'
|
||||||
inflect.acronym 'JSON'
|
inflect.acronym 'JSON'
|
||||||
inflect.acronym 'RNA'
|
inflect.acronym 'RNA'
|
||||||
|
inflect.acronym 'RNF'
|
||||||
inflect.acronym 'URL'
|
inflect.acronym 'URL'
|
||||||
inflect.acronym 'SVA'
|
inflect.acronym 'SVA'
|
||||||
inflect.acronym 'SVR'
|
inflect.acronym 'SVR'
|
||||||
|
|
24
config/locales/models/champs/rnf_champ/en.yml
Normal file
24
config/locales/models/champs/rnf_champ/en.yml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
en:
|
||||||
|
activemodel:
|
||||||
|
attributes:
|
||||||
|
rnf_champ:
|
||||||
|
rnf_id: RNF id
|
||||||
|
data:
|
||||||
|
title: Foundation name
|
||||||
|
email: Email
|
||||||
|
phone: Phone
|
||||||
|
createdAt: Created at
|
||||||
|
updatedAt: Updated at
|
||||||
|
dissolvedAt: Dissolved at
|
||||||
|
address: Address
|
||||||
|
status: Status
|
||||||
|
cityCode: City code
|
||||||
|
postalCode: Postal code
|
||||||
|
department: Department
|
||||||
|
paste: Copy the RNF to the clipboard
|
||||||
|
paste_success: The RNF has been copied to the clipboard
|
||||||
|
activerecord:
|
||||||
|
attributes:
|
||||||
|
champs/rnf_champ:
|
||||||
|
hints:
|
||||||
|
value: "Expected format : 075-FDD-00003-01"
|
24
config/locales/models/champs/rnf_champ/fr.yml
Normal file
24
config/locales/models/champs/rnf_champ/fr.yml
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
fr:
|
||||||
|
activemodel:
|
||||||
|
attributes:
|
||||||
|
rnf_champ:
|
||||||
|
rnf_id: Numéro RNF
|
||||||
|
data:
|
||||||
|
title: Nom de la fondation
|
||||||
|
email: Email
|
||||||
|
phone: Téléphone
|
||||||
|
createdAt: Créée le
|
||||||
|
updatedAt: Mise à jour le
|
||||||
|
dissolvedAt: Dissoute le
|
||||||
|
address: Adresse
|
||||||
|
status: Statut
|
||||||
|
cityCode: Code INSEE
|
||||||
|
postalCode: Code postal
|
||||||
|
department: Département
|
||||||
|
paste: Copier le RNF dans le presse-papier
|
||||||
|
paste_success: Le RNF a été copié dans le presse-papier
|
||||||
|
activerecord:
|
||||||
|
attributes:
|
||||||
|
champs/rnf_champ:
|
||||||
|
hints:
|
||||||
|
value: "Format attendu : 075-FDD-00003-01"
|
|
@ -48,6 +48,7 @@ en:
|
||||||
yes_no_false: 'no'
|
yes_no_false: 'no'
|
||||||
annuaire_education: 'Schooling directory'
|
annuaire_education: 'Schooling directory'
|
||||||
rna: 'RNA'
|
rna: 'RNA'
|
||||||
|
rnf: 'RNF'
|
||||||
carte: 'Card'
|
carte: 'Card'
|
||||||
cnaf: 'Data from Caisse nationale des allocations familiales'
|
cnaf: 'Data from Caisse nationale des allocations familiales'
|
||||||
dgfip: 'Data from Direction générale des Finances publiques'
|
dgfip: 'Data from Direction générale des Finances publiques'
|
||||||
|
|
|
@ -47,7 +47,8 @@ fr:
|
||||||
yes_no_true: 'oui'
|
yes_no_true: 'oui'
|
||||||
yes_no_false: 'non'
|
yes_no_false: 'non'
|
||||||
annuaire_education: 'Annuaire de l’éducation'
|
annuaire_education: 'Annuaire de l’éducation'
|
||||||
rna: 'RNA'
|
rna: 'RNA (Répertoire national des associations)'
|
||||||
|
rnf: 'RNF (Répertoire national des fondations)'
|
||||||
carte: 'Carte'
|
carte: 'Carte'
|
||||||
cnaf: 'Données de la Caisse nationale des allocations familiales'
|
cnaf: 'Données de la Caisse nationale des allocations familiales'
|
||||||
dgfip: 'Données de la Direction générale des Finances publiques'
|
dgfip: 'Données de la Direction générale des Finances publiques'
|
||||||
|
|
|
@ -30,6 +30,9 @@ en:
|
||||||
data_fetched: "This RNA number is linked to %{title}"
|
data_fetched: "This RNA number is linked to %{title}"
|
||||||
not_found: "No association found"
|
not_found: "No association found"
|
||||||
network_error: "A network error has prevented the association associated with this RNA to be fetched"
|
network_error: "A network error has prevented the association associated with this RNA to be fetched"
|
||||||
|
rnf:
|
||||||
|
show:
|
||||||
|
not_found: "RNF %{rnf} (no foundation found)"
|
||||||
dgfip:
|
dgfip:
|
||||||
show:
|
show:
|
||||||
not_filled: not filled
|
not_filled: not filled
|
||||||
|
|
|
@ -32,6 +32,9 @@ fr:
|
||||||
data_fetched: "Ce RNA correspond à %{title}"
|
data_fetched: "Ce RNA correspond à %{title}"
|
||||||
not_found: "Aucun établissement trouvé"
|
not_found: "Aucun établissement trouvé"
|
||||||
network_error: "Une erreur réseau a empêché l’association liée à ce RNA d’être trouvée"
|
network_error: "Une erreur réseau a empêché l’association liée à ce RNA d’être trouvée"
|
||||||
|
rnf:
|
||||||
|
show:
|
||||||
|
not_found: "RNF %{rnf} (aucune fondation trouvée)"
|
||||||
dgfip:
|
dgfip:
|
||||||
show:
|
show:
|
||||||
not_filled: non renseigné
|
not_filled: non renseigné
|
||||||
|
|
|
@ -242,6 +242,10 @@ FactoryBot.define do
|
||||||
type_de_champ { association :type_de_champ_cojo, procedure: dossier.procedure }
|
type_de_champ { association :type_de_champ_cojo, procedure: dossier.procedure }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
factory :champ_rnf, class: 'Champs::RNFChamp' do
|
||||||
|
type_de_champ { association :type_de_champ_rnf, procedure: dossier.procedure }
|
||||||
|
end
|
||||||
|
|
||||||
factory :champ_expression_reguliere, class: 'Champs::ExpressionReguliereChamp' do
|
factory :champ_expression_reguliere, class: 'Champs::ExpressionReguliereChamp' do
|
||||||
type_de_champ { association :type_de_champ_expression_reguliere, procedure: dossier.procedure }
|
type_de_champ { association :type_de_champ_expression_reguliere, procedure: dossier.procedure }
|
||||||
end
|
end
|
||||||
|
|
|
@ -187,6 +187,9 @@ FactoryBot.define do
|
||||||
factory :type_de_champ_cojo do
|
factory :type_de_champ_cojo do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:cojo) }
|
type_champ { TypeDeChamp.type_champs.fetch(:cojo) }
|
||||||
end
|
end
|
||||||
|
factory :type_de_champ_rnf do
|
||||||
|
type_champ { TypeDeChamp.type_champs.fetch(:rnf) }
|
||||||
|
end
|
||||||
factory :type_de_champ_repetition do
|
factory :type_de_champ_repetition do
|
||||||
type_champ { TypeDeChamp.type_champs.fetch(:repetition) }
|
type_champ { TypeDeChamp.type_champs.fetch(:repetition) }
|
||||||
|
|
||||||
|
|
6
spec/fixtures/files/api_rnf/invalid.json
vendored
Normal file
6
spec/fixtures/files/api_rnf/invalid.json
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"id":3,
|
||||||
|
"createdAt":"2023-09-07T13:26:10.358Z",
|
||||||
|
"updatedAt":"2023-09-07T13:26:10.358Z",
|
||||||
|
"rnfId": 750000301
|
||||||
|
}
|
32
spec/fixtures/files/api_rnf/valid.json
vendored
Normal file
32
spec/fixtures/files/api_rnf/valid.json
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"id":3,
|
||||||
|
"createdAt":"2023-09-07T13:26:10.358Z",
|
||||||
|
"updatedAt":"2023-09-07T13:26:10.358Z",
|
||||||
|
"rnfId":"075-FDD-00003-01",
|
||||||
|
"type":"FDD",
|
||||||
|
"department":"75",
|
||||||
|
"title":"Fondation SFR",
|
||||||
|
"dissolvedAt":null,
|
||||||
|
"phone":"+33185060000",
|
||||||
|
"email":"fondation@sfr.fr",
|
||||||
|
"addressId":3,
|
||||||
|
"address": {
|
||||||
|
"id":3,
|
||||||
|
"createdAt":"2023-09-07T13:26:10.358Z",
|
||||||
|
"updatedAt":"2023-09-07T13:26:10.358Z",
|
||||||
|
"label":"16 Rue du Général de Boissieu 75015 Paris",
|
||||||
|
"type":"housenumber",
|
||||||
|
"streetAddress":"16 Rue du Général de Boissieu",
|
||||||
|
"streetNumber":"16",
|
||||||
|
"streetName":"Rue du Général de Boissieu",
|
||||||
|
"postalCode":"75015",
|
||||||
|
"cityName":"Paris",
|
||||||
|
"cityCode":"75115",
|
||||||
|
"departmentName":"Paris",
|
||||||
|
"departmentCode":"75",
|
||||||
|
"regionName":"Île-de-France",
|
||||||
|
"regionCode":"11"
|
||||||
|
},
|
||||||
|
"status":null,
|
||||||
|
"persons":[]
|
||||||
|
}
|
|
@ -14,9 +14,9 @@ describe '20220705164551_remove_unused_champs' do
|
||||||
|
|
||||||
describe 'remove_unused_champs' do
|
describe 'remove_unused_champs' do
|
||||||
it "with bad champs" do
|
it "with bad champs" do
|
||||||
expect(Champ.where(dossier: dossier).count).to eq(42)
|
expect(Champ.where(dossier: dossier).count).to eq(43)
|
||||||
run_task
|
run_task
|
||||||
expect(Champ.where(dossier: dossier).count).to eq(41)
|
expect(Champ.where(dossier: dossier).count).to eq(42)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
76
spec/models/champs/rnf_champ_spec.rb
Normal file
76
spec/models/champs/rnf_champ_spec.rb
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
describe Champs::RNFChamp, type: :model do
|
||||||
|
let(:champ) { build(:champ_rnf, external_id:) }
|
||||||
|
let(:stub) { stub_request(:get, "#{url}/#{external_id}").to_return(body:, status:) }
|
||||||
|
let(:url) { RNFService.new.send(:url) }
|
||||||
|
let(:body) { Rails.root.join('spec', 'fixtures', 'files', 'api_rnf', "#{response_type}.json").read }
|
||||||
|
let(:external_id) { '075-FDD-00003-01' }
|
||||||
|
let(:status) { 200 }
|
||||||
|
let(:response_type) { 'valid' }
|
||||||
|
|
||||||
|
describe 'fetch_external_data' do
|
||||||
|
subject { stub; champ.fetch_external_data }
|
||||||
|
|
||||||
|
context 'success' do
|
||||||
|
it do
|
||||||
|
expect(subject.value!).to eq({
|
||||||
|
id: 3,
|
||||||
|
rnfId: '075-FDD-00003-01',
|
||||||
|
type: 'FDD',
|
||||||
|
department: '75',
|
||||||
|
title: 'Fondation SFR',
|
||||||
|
dissolvedAt: nil,
|
||||||
|
phone: '+33185060000',
|
||||||
|
email: 'fondation@sfr.fr',
|
||||||
|
addressId: 3,
|
||||||
|
createdAt: "2023-09-07T13:26:10.358Z",
|
||||||
|
updatedAt: "2023-09-07T13:26:10.358Z",
|
||||||
|
address: {
|
||||||
|
id: 3,
|
||||||
|
createdAt: "2023-09-07T13:26:10.358Z",
|
||||||
|
updatedAt: "2023-09-07T13:26:10.358Z",
|
||||||
|
label: "16 Rue du Général de Boissieu 75015 Paris",
|
||||||
|
type: "housenumber",
|
||||||
|
streetAddress: "16 Rue du Général de Boissieu",
|
||||||
|
streetNumber: "16",
|
||||||
|
streetName: "Rue du Général de Boissieu",
|
||||||
|
postalCode: "75015",
|
||||||
|
cityName: "Paris",
|
||||||
|
cityCode: "75115",
|
||||||
|
departmentName: "Paris",
|
||||||
|
departmentCode: "75",
|
||||||
|
regionName: "Île-de-France",
|
||||||
|
regionCode: "11"
|
||||||
|
},
|
||||||
|
status: nil,
|
||||||
|
persons: []
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'failure (schema)' do
|
||||||
|
let(:response_type) { 'invalid' }
|
||||||
|
it {
|
||||||
|
expect(subject.failure.retryable).to be_falsey
|
||||||
|
expect(subject.failure.reason).to be_a(API::Client::SchemaError)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'failure (http 500)' do
|
||||||
|
let(:status) { 500 }
|
||||||
|
let(:response_type) { 'invalid' }
|
||||||
|
it {
|
||||||
|
expect(subject.failure.retryable).to be_truthy
|
||||||
|
expect(subject.failure.reason).to be_a(API::Client::HTTPError)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'failure (http 401)' do
|
||||||
|
let(:status) { 401 }
|
||||||
|
let(:response_type) { 'invalid' }
|
||||||
|
it {
|
||||||
|
expect(subject.failure.retryable).to be_falsey
|
||||||
|
expect(subject.failure.reason).to be_a(API::Client::HTTPError)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -90,7 +90,8 @@ describe ProcedureExportService do
|
||||||
"epci (Code)",
|
"epci (Code)",
|
||||||
"epci (Département)",
|
"epci (Département)",
|
||||||
"cojo",
|
"cojo",
|
||||||
"expression_reguliere"
|
"expression_reguliere",
|
||||||
|
"rnf"
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -202,7 +203,8 @@ describe ProcedureExportService do
|
||||||
"epci (Code)",
|
"epci (Code)",
|
||||||
"epci (Département)",
|
"epci (Département)",
|
||||||
"cojo",
|
"cojo",
|
||||||
"expression_reguliere"
|
"expression_reguliere",
|
||||||
|
"rnf"
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -297,7 +299,8 @@ describe ProcedureExportService do
|
||||||
"epci (Code)",
|
"epci (Code)",
|
||||||
"epci (Département)",
|
"epci (Département)",
|
||||||
"cojo",
|
"cojo",
|
||||||
"expression_reguliere"
|
"expression_reguliere",
|
||||||
|
"rnf"
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue