From 68cca713185e3b32487db2bc3bfd4359cbf61cbf Mon Sep 17 00:00:00 2001 From: Colin Darie Date: Mon, 14 Oct 2024 22:25:08 +0200 Subject: [PATCH] feat(service): prefill contact information UI interactions --- .../administrateurs/services_controller.rb | 24 ++++++++- .../controllers/autosave_controller.ts | 5 +- .../administrateurs/services/_form.html.haml | 29 +++++++---- .../administrateurs/services/edit.html.haml | 2 +- .../administrateurs/services/new.html.haml | 2 +- config/locales/models/service/en.yml | 7 +-- config/locales/models/service/fr.yml | 7 +-- .../services_controller_spec.rb | 52 +++++++++++++++++-- 8 files changed, 104 insertions(+), 24 deletions(-) diff --git a/app/controllers/administrateurs/services_controller.rb b/app/controllers/administrateurs/services_controller.rb index 6ca2af356..ba87ccdef 100644 --- a/app/controllers/administrateurs/services_controller.rb +++ b/app/controllers/administrateurs/services_controller.rb @@ -18,7 +18,9 @@ module Administrateurs @service = Service.new(service_params) @service.administrateur = current_administrateur - if @service.save + if request.xhr? && params[:service][:siret].present? + handle_siret_update + elsif @service.save @service.enqueue_api_entreprise redirect_to admin_services_path(procedure_id: params[:procedure_id]), @@ -108,5 +110,25 @@ module Administrateurs def procedure current_administrateur.procedures.find(params[:procedure_id]) end + + def handle_siret_update + @service.assign_attributes(siret: params[:service][:siret]) + @service.validate + + if !@service.errors.include?(:siret) + result = @service.prefill_from_siret + prefilled = result.success? ? :success : :failure + end + + siret_errors = @service.errors.where(:siret) + @service.errors.clear + siret_errors.each { @service.errors.import(_1) } + + render turbo_stream: turbo_stream.replace( + "service_form", + partial: "administrateurs/services/form", + locals: { service: @service, prefilled:, procedure: @procedure } + ) + end end end diff --git a/app/javascript/controllers/autosave_controller.ts b/app/javascript/controllers/autosave_controller.ts index 0a3cc0570..96aca094d 100644 --- a/app/javascript/controllers/autosave_controller.ts +++ b/app/javascript/controllers/autosave_controller.ts @@ -252,7 +252,10 @@ export class AutosaveController extends ApplicationController { return httpRequest(form.action, { method: 'post', body: formData, - headers: { 'x-http-method-override': 'PATCH' }, + headers: { + 'x-http-method-override': + form.dataset.turboMethod?.toUpperCase() || 'PATCH' + }, signal: this.#abortController.signal, timeout: AUTOSAVE_TIMEOUT_DELAY }).turbo(); diff --git a/app/views/administrateurs/services/_form.html.haml b/app/views/administrateurs/services/_form.html.haml index 2ac6fb5ff..6386655b2 100644 --- a/app/views/administrateurs/services/_form.html.haml +++ b/app/views/administrateurs/services/_form.html.haml @@ -1,11 +1,21 @@ -= form_with model: [ :admin, service], local: true do |f| += form_with model: [:admin, service], id: "service_form", data: { turbo: token_list('true' => service.new_record?), controller: token_list('autosave' => service.new_record?), turbo_method: 'post' } do |f| = render Dsfr::InputComponent.new(form: f, attribute: :siret, input_type: :text_field, opts: { placeholder: "14 chiffres, sans espace" }) do |c| - - c.with_hint do - = "Indiquez le numéro de SIRET de l’organisme dont ce service dépend. Rechercher le SIRET sur " - = link_to("annuaire-entreprises.data.gouv.fr", annuaire_link, **external_link_attributes) - %br - = "Nous préremplirons les informations de contact à partir de l’Annuaire Service Public correspondant." + - if service.etablissement_infos.blank? && local_assigns[:prefilled].nil? + - c.with_hint do + = "Indiquez le numéro de SIRET de l’organisme dont ce service dépend. Rechercher le SIRET sur " + = link_to("annuaire-entreprises.data.gouv.fr", annuaire_link, **external_link_attributes) + - if service.new_record? + %br + = "Nous préremplirons les informations de contact à partir de l’Annuaire Service Public correspondant." + + .fr-mb-2w + - if local_assigns[:prefilled] == :success + %p.fr-info-text Génial ! Les informations du service ont été préremplies ci-dessous. Vérifiez-les et complétez-les le cas échéant. + - elsif local_assigns[:prefilled] == :failure + %p.fr-error-text + Une erreur a empêché le préremplissage des informations. + Vérifiez que le numéro de SIRET est correct et complétez les informations manuellement le cas échéant. = render Dsfr::InputComponent.new(form: f, attribute: :nom, input_type: :text_field) @@ -33,7 +43,6 @@ = render Dsfr::InputComponent.new(form: f, attribute: :horaires, input_type: :text_area) = render Dsfr::InputComponent.new(form: f, attribute: :adresse, input_type: :text_area) - - if procedure_id.present? - = hidden_field_tag :procedure_id, procedure_id - - = render Procedure::FixedFooterComponent.new(procedure: @procedure, form: f) + - if local_assigns[:procedure].present? + = hidden_field_tag :procedure_id, procedure.id + = render Procedure::FixedFooterComponent.new(procedure: procedure, form: f) diff --git a/app/views/administrateurs/services/edit.html.haml b/app/views/administrateurs/services/edit.html.haml index 0b056372c..3cd11f6fc 100644 --- a/app/views/administrateurs/services/edit.html.haml +++ b/app/views/administrateurs/services/edit.html.haml @@ -23,4 +23,4 @@ %p.mt-3 Si vous souhaitez modifier uniquement les informations pour ce service, créez un nouveau service puis associez-le à la démarche = render partial: 'form', - locals: { service: @service, procedure_id: @procedure.id } + locals: { service: @service, procedure: @procedure } diff --git a/app/views/administrateurs/services/new.html.haml b/app/views/administrateurs/services/new.html.haml index 691b864e7..27a39f2b5 100644 --- a/app/views/administrateurs/services/new.html.haml +++ b/app/views/administrateurs/services/new.html.haml @@ -8,4 +8,4 @@ %h1 Nouveau Service = render partial: 'form', - locals: { service: @service, procedure_id: @procedure.id } + locals: { service: @service, procedure: @procedure } diff --git a/config/locales/models/service/en.yml b/config/locales/models/service/en.yml index a28cd43a5..e9da428d0 100644 --- a/config/locales/models/service/en.yml +++ b/config/locales/models/service/en.yml @@ -14,6 +14,7 @@ en: service: attributes: siret: - format: "SIRET number %{message}" - length: "must contain exactly 14 digits" - checksum: "is invalid" + format: 'SIRET number %{message}' + length: 'must contain exactly 14 digits' + checksum: 'is invalid' + not_prefillable: 'Unable to pre-fill information for this SIRET, please fill it manually' diff --git a/config/locales/models/service/fr.yml b/config/locales/models/service/fr.yml index 1abe6afdb..40c35197c 100644 --- a/config/locales/models/service/fr.yml +++ b/config/locales/models/service/fr.yml @@ -34,9 +34,10 @@ fr: service: attributes: siret: - format: "Le numéro SIRET %{message}" - length: "doit comporter exactement 14 chiffres" - checksum: "est invalide" + format: 'Le numéro SIRET %{message}' + length: 'doit comporter exactement 14 chiffres' + checksum: 'est invalide' + not_prefillable: 'Impossible de préremplir les informations pour ce SIRET, veuillez les saisir manuellement' type_organisme: administration_centrale: 'Administration centrale' association: 'Association' diff --git a/spec/controllers/administrateurs/services_controller_spec.rb b/spec/controllers/administrateurs/services_controller_spec.rb index 380d23787..fbfb334f4 100644 --- a/spec/controllers/administrateurs/services_controller_spec.rb +++ b/spec/controllers/administrateurs/services_controller_spec.rb @@ -7,7 +7,47 @@ describe Administrateurs::ServicesController, type: :controller do describe '#create' do before do sign_in(admin.user) - post :create, params: params + end + + let(:xhr) { false } + subject { post :create, params:, xhr: } + + context 'when prefilling from a SIRET' do + let(:xhr) { true } + let(:params) do + { + procedure_id: procedure.id, + service: { siret: "20004021000060" } + } + end + + it "prefill from annuaire public" do + VCR.use_cassette('annuaire_service_public_success_20004021000060') do + subject + expect(response.body).to include('turbo-stream') + expect(assigns[:service].nom).to eq("Communauté de communes - Lacs et Gorges du Verdon") + expect(assigns[:service].adresse).to eq("242 avenue Albert-1er 83630 Aups") + end + end + end + + context 'when attempting to prefilling from unknown SIRET' do + let(:xhr) { true } + let(:params) do + { + procedure_id: procedure.id, + service: { siret: "20004021000000" } + } + end + + it "render an error" do + VCR.use_cassette('annuaire_service_public_failure_20004021000000') do + subject + expect(response.body).to include('turbo-stream') + expect(assigns[:service].nom).to be_nil + expect(assigns[:service].errors.key?(:siret)).to be_present + end + end end context 'when submitting a new service' do @@ -28,6 +68,7 @@ describe Administrateurs::ServicesController, type: :controller do end it do + subject expect(flash.alert).to be_nil expect(flash.notice).to eq('super service créé') expect(Service.last.nom).to eq('super service') @@ -47,9 +88,12 @@ describe Administrateurs::ServicesController, type: :controller do context 'when submitting an invalid service' do let(:params) { { service: { nom: 'super service' }, procedure_id: procedure.id } } - it { expect(flash.alert).not_to be_nil } - it { expect(response).to render_template(:new) } - it { expect(assigns(:service).nom).to eq('super service') } + it do + subject + expect(flash.alert).not_to be_nil + expect(response).to render_template(:new) + expect(assigns(:service).nom).to eq('super service') + end end end