Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ajout d'un nouveau référentiel : le Répertoire National des Fondations (RNF) #9648

Merged
merged 6 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
= render partial: "shared/champs/regions/show", locals: { champ: champ }
- when TypeDeChamp.type_champs.fetch(:rna)
= 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)
= render partial: "shared/champs/epci/show", locals: { champ: champ }
- when TypeDeChamp.type_champs.fetch(:cojo)
Expand All @@ -60,4 +62,3 @@
%p= helpers.number_with_html_delimiter(champ.to_s)
- else
= helpers.format_text_value(champ.to_s.strip) # format already wrap in p

2 changes: 2 additions & 0 deletions app/components/editable_champ/rnf_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class EditableChamp::RNFComponent < EditableChamp::EditableChampBaseComponent
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
en:
rnf_info_error: No foundation found
rnf_info_pending: RNF verification pending
rnf_info_success: "This RNF matches %{title}"
Original file line number Diff line number Diff line change
@@ -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}"
Original file line number Diff line number Diff line change
@@ -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)
1 change: 1 addition & 0 deletions app/graphql/api/v2/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def self.resolve_type(type_definition, object, ctx)
Types::Champs::Descriptor::RegionChampDescriptorType,
Types::Champs::Descriptor::RepetitionChampDescriptorType,
Types::Champs::Descriptor::RNAChampDescriptorType,
Types::Champs::Descriptor::RNFChampDescriptorType,
Types::Champs::Descriptor::SiretChampDescriptorType,
Types::Champs::Descriptor::TextareaChampDescriptorType,
Types::Champs::Descriptor::TextChampDescriptorType,
Expand Down
35 changes: 34 additions & 1 deletion app/graphql/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -3535,6 +3535,34 @@ type RNAChampDescriptor implements ChampDescriptor {
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 {
code: String!
name: String!
Expand Down Expand Up @@ -4049,10 +4077,15 @@ enum TypeDeChamp {
repetition

"""
RNA
RNA (Répertoire national des associations)
"""
rna

"""
RNF (Répertoire national des fondations)
"""
rnf

"""
Numéro Siret
"""
Expand Down
2 changes: 2 additions & 0 deletions app/graphql/types/champ_descriptor_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ def resolve_type(object, context)
Types::Champs::Descriptor::PieceJustificativeChampDescriptorType
when TypeDeChamp.type_champs.fetch(:rna)
Types::Champs::Descriptor::RNAChampDescriptorType
when TypeDeChamp.type_champs.fetch(:rnf)
Types::Champs::Descriptor::RNFChampDescriptorType
when TypeDeChamp.type_champs.fetch(:carte)
Types::Champs::Descriptor::CarteChampDescriptorType
when TypeDeChamp.type_champs.fetch(:repetition)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module Types::Champs::Descriptor
class RNFChampDescriptorType < Types::BaseObject
implements Types::ChampDescriptorType
end
end
13 changes: 7 additions & 6 deletions app/models/champ.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,7 @@ def describedby_id
end

def log_fetch_external_data_exception(exception)
exceptions = self.fetch_external_data_exceptions ||= []
exceptions << exception.inspect
update_column(:fetch_external_data_exceptions, exceptions)
update_column(:fetch_external_data_exceptions, [exception.inspect])
end

def fetch_external_data?
Expand All @@ -218,10 +216,12 @@ def poll_external_data?
false
end

def fetch_external_data_error?
fetch_external_data_exceptions.present? && self.external_id.present?
end

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
# 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
fetch_external_data? && poll_external_data? && external_id.present? && data.nil? && !fetch_external_data_error?
end

def fetch_external_data
Expand Down Expand Up @@ -289,6 +289,7 @@ def cleanup_if_empty

def fetch_external_data_later
if fetch_external_data? && external_id.present? && data.nil?
update_column(:fetch_external_data_exceptions, [])
ChampFetchExternalDataJob.perform_later(self, external_id)
end
end
Expand Down
23 changes: 23 additions & 0 deletions app/models/champs/rnf_champ.rb
Original file line number Diff line number Diff line change
@@ -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
2 changes: 2 additions & 0 deletions app/models/type_de_champ.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class TypeDeChamp < ApplicationRecord
yes_no: CHOICE,
annuaire_education: REFERENTIEL_EXTERNE,
rna: REFERENTIEL_EXTERNE,
rnf: REFERENTIEL_EXTERNE,
carte: REFERENTIEL_EXTERNE,
cnaf: REFERENTIEL_EXTERNE,
dgfip: REFERENTIEL_EXTERNE,
Expand Down Expand Up @@ -91,6 +92,7 @@ class TypeDeChamp < ApplicationRecord
yes_no: 'yes_no',
annuaire_education: 'annuaire_education',
rna: 'rna',
rnf: 'rnf',
carte: 'carte',
cnaf: 'cnaf',
dgfip: 'dgfip',
Expand Down
2 changes: 2 additions & 0 deletions app/models/types_de_champ/rnf_type_de_champ.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class TypesDeChamp::RNFTypeDeChamp < TypesDeChamp::TextTypeDeChamp
end
36 changes: 36 additions & 0 deletions app/schemas/rnf.json
Original file line number Diff line number Diff line change
@@ -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 changes: 25 additions & 0 deletions app/services/rnf_service.rb
Original file line number Diff line number Diff line change
@@ -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 changes: 30 additions & 0 deletions app/views/shared/champs/rnf/_show.html.haml
Original file line number Diff line number Diff line change
@@ -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']}"
1 change: 1 addition & 0 deletions config/initializers/02_urls.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
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_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")
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")
Expand Down
1 change: 1 addition & 0 deletions config/initializers/inflections.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
inflect.acronym 'IP'
inflect.acronym 'JSON'
inflect.acronym 'RNA'
inflect.acronym 'RNF'
inflect.acronym 'URL'
inflect.acronym 'SVA'
inflect.acronym 'SVR'
Expand Down
24 changes: 24 additions & 0 deletions config/locales/models/champs/rnf_champ/en.yml
Original file line number Diff line number Diff line change
@@ -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 changes: 24 additions & 0 deletions config/locales/models/champs/rnf_champ/fr.yml
Original file line number Diff line number Diff line change
@@ -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"
1 change: 1 addition & 0 deletions config/locales/models/type_de_champ/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ en:
yes_no_false: 'no'
annuaire_education: 'Schooling directory'
rna: 'RNA'
rnf: 'RNF'
carte: 'Card'
cnaf: 'Data from Caisse nationale des allocations familiales'
dgfip: 'Data from Direction générale des Finances publiques'
Expand Down
3 changes: 2 additions & 1 deletion config/locales/models/type_de_champ/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ fr:
yes_no_true: 'oui'
yes_no_false: 'non'
annuaire_education: 'Annuaire de l’éducation'
rna: 'RNA'
rna: 'RNA (Répertoire national des associations)'
rnf: 'RNF (Répertoire national des fondations)'
carte: 'Carte'
cnaf: 'Données de la Caisse nationale des allocations familiales'
dgfip: 'Données de la Direction générale des Finances publiques'
Expand Down
3 changes: 3 additions & 0 deletions config/locales/shared.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ en:
data_fetched: "This RNA number is linked to %{title}"
not_found: "No association found"
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:
show:
not_filled: not filled
Expand Down
3 changes: 3 additions & 0 deletions config/locales/shared.fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ fr:
data_fetched: "Ce RNA correspond à %{title}"
not_found: "Aucun établissement trouvé"
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:
show:
not_filled: non renseigné
Expand Down
Loading