diff --git a/app/assets/stylesheets/dossier_views.scss b/app/assets/stylesheets/dossier_views.scss index 65ab61c73..95190b43c 100644 --- a/app/assets/stylesheets/dossier_views.scss +++ b/app/assets/stylesheets/dossier_views.scss @@ -32,7 +32,20 @@ .header-actions { margin-bottom: $default-spacer; - text-align: right; + display: flex; + justify-content: flex-end; + column-gap: $default-spacer * 2; + } + } + + .edit-identity-action { + .dropdown-content { + padding: $default-padding; + min-width: 250px; + } + + .table { + margin-bottom: $default-padding * 2; } } diff --git a/app/controllers/champs/siret_controller.rb b/app/controllers/champs/siret_controller.rb index 1b1b33edd..fbf8d2495 100644 --- a/app/controllers/champs/siret_controller.rb +++ b/app/controllers/champs/siret_controller.rb @@ -17,7 +17,7 @@ class Champs::SiretController < ApplicationController begin etablissement = find_etablissement_with_siret - rescue APIEntreprise::API::Error::RequestFailed, APIEntreprise::API::Error::BadGateway, APIEntreprise::API::Error::TimedOut, APIEntreprise::API::Error::ServiceUnavailable + rescue APIEntreprise::API::Error::RequestFailed, APIEntreprise::API::Error::BadGateway, APIEntreprise::API::Error::TimedOut, APIEntreprise::API::Error::ServiceUnavailable, APIEntrepriseToken::TokenError # i18n-tasks-use t('errors.messages.siret_network_error') return siret_error(:network_error) end diff --git a/app/controllers/users/dossiers_controller.rb b/app/controllers/users/dossiers_controller.rb index 170ebac13..a0e7b8f13 100644 --- a/app/controllers/users/dossiers_controller.rb +++ b/app/controllers/users/dossiers_controller.rb @@ -114,7 +114,7 @@ module Users sanitized_siret = siret_model.siret begin etablissement = APIEntrepriseService.create_etablissement(@dossier, sanitized_siret, current_user.id) - rescue APIEntreprise::API::Error::RequestFailed, APIEntreprise::API::Error::BadGateway, APIEntreprise::API::Error::TimedOut, APIEntreprise::API::Error::ServiceUnavailable + rescue APIEntreprise::API::Error::RequestFailed, APIEntreprise::API::Error::BadGateway, APIEntreprise::API::Error::TimedOut, APIEntreprise::API::Error::ServiceUnavailable, APIEntrepriseToken::TokenError return render_siret_error(t('errors.messages.siret_network_error')) end if etablissement.nil? diff --git a/app/lib/api_entreprise/api.rb b/app/lib/api_entreprise/api.rb index 297ad0669..9f92f5cad 100644 --- a/app/lib/api_entreprise/api.rb +++ b/app/lib/api_entreprise/api.rb @@ -82,7 +82,10 @@ class APIEntreprise::API end def self.call_with_siret(resource_name, siret_or_siren, procedure_id, user_id = nil) - return if APIEntrepriseToken.new(token_for_procedure(procedure_id)).expired? + if APIEntrepriseToken.new(token_for_procedure(procedure_id)).expired? + raise APIEntrepriseToken::TokenError, I18n.t("api_entreprise.errors.token_expired") + end + url = url(resource_name, siret_or_siren) params = params(siret_or_siren, procedure_id, user_id) diff --git a/app/views/shared/dossiers/_header.html.haml b/app/views/shared/dossiers/_header.html.haml index b235930e3..bf3fa62e8 100644 --- a/app/views/shared/dossiers/_header.html.haml +++ b/app/views/shared/dossiers/_header.html.haml @@ -13,3 +13,6 @@ - elsif current_user.owns?(dossier) .header-actions = render partial: 'invites/dropdown', locals: { dossier: dossier } + + - unless dossier.read_only? + = render partial: 'users/dossiers/identity_dropdown', locals: { dossier: dossier } diff --git a/app/views/shared/dossiers/_identite_entreprise.html.haml b/app/views/shared/dossiers/_identite_entreprise.html.haml index 1b0156c41..f8859f6b2 100644 --- a/app/views/shared/dossiers/_identite_entreprise.html.haml +++ b/app/views/shared/dossiers/_identite_entreprise.html.haml @@ -11,140 +11,142 @@ %td.libelle SIRET : %td= etablissement.siret - - if etablissement.siret != etablissement.entreprise.siret_siege_social - %tr - %td.libelle SIRET du siège social: - %td= etablissement.entreprise.siret_siege_social - %tr - %td.libelle Forme juridique : - %td= sanitize(etablissement.entreprise.forme_juridique) - %tr - %td.libelle Libellé NAF : - %td= etablissement.libelle_naf - %tr - %td.libelle Code NAF : - %td= etablissement.naf - %tr - %td.libelle Date de création : - %td= try_format_date(etablissement.entreprise.date_creation) - - if profile == 'instructeur' - %tr - %td.libelle - Effectif mensuel - = try_format_mois_effectif(etablissement) - (URSSAF) : - %td= etablissement.entreprise_effectif_mensuel - %tr - %td.libelle - Effectif moyen annuel - = etablissement.entreprise_effectif_annuel_annee - (URSSAF) : - %td= etablissement.entreprise_effectif_annuel - %tr - %td.libelle Effectif de l'organisation (INSEE) : - %td - = effectif(etablissement) - %tr - %td.libelle Numéro de TVA intracommunautaire : - %td= etablissement.entreprise.numero_tva_intracommunautaire - %tr - %td.libelle Adresse : - %td - - etablissement.adresse.split("\n").each do |line| - = line - %br - %tr - %td.libelle Capital social : - %td= pretty_currency(etablissement.entreprise.capital_social) - %tr - %td.libelle Chiffre d’affaires : - %td - - if profile == 'instructeur' - %details - - etablissement.exercices.each_with_index do |exercice, index| - = "#{exercice.date_fin_exercice.year} : " - = pretty_currency(exercice.ca) - %br - - elsif etablissement.exercices.present? - = t('activemodel.models.exercices_summary', count: etablissement.exercices.count) - - - - if etablissement.entreprise_bilans_bdf.present? - - if profile == 'instructeur' - = render partial: 'shared/dossiers/identite_entreprise_bilan_detail', - locals: { libelle: 'Résultat exercice', key: 'resultat_exercice', etablissement: etablissement } - - = render partial: 'shared/dossiers/identite_entreprise_bilan_detail', - locals: { libelle: "Excédent brut d’exploitation", key: 'excedent_brut_exploitation', etablissement: etablissement } - - = render partial: 'shared/dossiers/identite_entreprise_bilan_detail', - locals: { libelle: 'Fonds de roulement net global', key: 'fonds_roulement_net_global', etablissement: etablissement } - - = render partial: 'shared/dossiers/identite_entreprise_bilan_detail', - locals: { libelle: 'Besoin en fonds de roulement', key: 'besoin_en_fonds_de_roulement', etablissement: etablissement } + - unless local_assigns[:short_identity] + - if etablissement.siret != etablissement.entreprise.siret_siege_social %tr - %td.libelle - Chiffres financiers clés (Banque de France) - = "en #{pretty_currency_unit(etablissement.entreprise_bilans_bdf_monnaie)} :" - - - if controller.is_a?(Instructeurs::AvisController) - %td - Les consulter - = link_to "au format csv", bilans_bdf_instructeur_avis_path(@avis, format: 'csv') - , - = link_to "au format xlsx", bilans_bdf_instructeur_avis_path(@avis, format: 'xlsx') - ou - = link_to "au format ods", bilans_bdf_instructeur_avis_path(@avis, format: 'ods') - - else - %td - Les consulter - = link_to "au format csv", bilans_bdf_instructeur_dossier_path(procedure_id: @dossier.procedure.id, dossier_id: @dossier.id, format: 'csv') - , - = link_to "au format xlsx", bilans_bdf_instructeur_dossier_path(procedure_id: @dossier.procedure.id, dossier_id: @dossier.id, format: 'xlsx') - ou - = link_to "au format ods", bilans_bdf_instructeur_dossier_path(procedure_id: @dossier.procedure.id, dossier_id: @dossier.id, format: 'ods') - - else - %tr - %td.libelle - Bilans Banque de France : - %td Les 3 derniers bilans connus de votre entreprise par la Banque de France ont été joints à votre dossier. - - if etablissement.entreprise_attestation_sociale.attached? + %td.libelle SIRET du siège social: + %td= etablissement.entreprise.siret_siege_social %tr - %td.libelle Attestation sociale : - - if profile == 'instructeur' - %td= link_to "Consulter l'attestation", url_for(etablissement.entreprise_attestation_sociale) - - else - %td Une attestation de vigilance délivrée par l'ACOSS a été jointe à votre dossier. - - - if etablissement.entreprise_attestation_fiscale.attached? + %td.libelle Forme juridique : + %td= sanitize(etablissement.entreprise.forme_juridique) %tr - %td.libelle Attestation fiscale : - - if profile == 'instructeur' - %td= link_to "Consulter l'attestation", url_for(etablissement.entreprise_attestation_fiscale) - - else - %td Une attestation fiscale délivrée par l'URSSAF a été jointe à votre dossier. - - - if etablissement.association? + %td.libelle Libellé NAF : + %td= etablissement.libelle_naf %tr - %td.libelle Numéro RNA : - %td= etablissement.association_rna - %tr - %td.libelle Titre : - %td= etablissement.association_titre - %tr - %td.libelle Objet : - %td= etablissement.association_objet + %td.libelle Code NAF : + %td= etablissement.naf %tr %td.libelle Date de création : - %td= try_format_date(etablissement.association_date_creation) + %td= try_format_date(etablissement.entreprise.date_creation) + - if profile == 'instructeur' + %tr + %td.libelle + Effectif mensuel + = try_format_mois_effectif(etablissement) + (URSSAF) : + %td= etablissement.entreprise_effectif_mensuel + %tr + %td.libelle + Effectif moyen annuel + = etablissement.entreprise_effectif_annuel_annee + (URSSAF) : + %td= etablissement.entreprise_effectif_annuel %tr - %td.libelle Date de publication : - %td= try_format_date(etablissement.association_date_publication) + %td.libelle Effectif de l'organisation (INSEE) : + %td + = effectif(etablissement) %tr - %td.libelle Date de déclaration : - %td= try_format_date(etablissement.association_date_declaration) + %td.libelle Numéro de TVA intracommunautaire : + %td= etablissement.entreprise.numero_tva_intracommunautaire + %tr + %td.libelle Adresse : + %td + - etablissement.adresse.split("\n").each do |line| + = line + %br + %tr + %td.libelle Capital social : + %td= pretty_currency(etablissement.entreprise.capital_social) + %tr + %td.libelle Chiffre d’affaires : + %td + - if profile == 'instructeur' + %details + - etablissement.exercices.each_with_index do |exercice, index| + = "#{exercice.date_fin_exercice.year} : " + = pretty_currency(exercice.ca) + %br + - elsif etablissement.exercices.present? + = t('activemodel.models.exercices_summary', count: etablissement.exercices.count) -%p - = link_to "➡ Autres informations sur l’organisme sur « annuaire-entreprises.data.gouv.fr » (ex: fiche d’immatriculation RNCS)", - annuaire_link(etablissement.siren), - target: "_blank" + + - if etablissement.entreprise_bilans_bdf.present? + - if profile == 'instructeur' + = render partial: 'shared/dossiers/identite_entreprise_bilan_detail', + locals: { libelle: 'Résultat exercice', key: 'resultat_exercice', etablissement: etablissement } + + = render partial: 'shared/dossiers/identite_entreprise_bilan_detail', + locals: { libelle: "Excédent brut d’exploitation", key: 'excedent_brut_exploitation', etablissement: etablissement } + + = render partial: 'shared/dossiers/identite_entreprise_bilan_detail', + locals: { libelle: 'Fonds de roulement net global', key: 'fonds_roulement_net_global', etablissement: etablissement } + + = render partial: 'shared/dossiers/identite_entreprise_bilan_detail', + locals: { libelle: 'Besoin en fonds de roulement', key: 'besoin_en_fonds_de_roulement', etablissement: etablissement } + %tr + %td.libelle + Chiffres financiers clés (Banque de France) + = "en #{pretty_currency_unit(etablissement.entreprise_bilans_bdf_monnaie)} :" + + - if controller.is_a?(Instructeurs::AvisController) + %td + Les consulter + = link_to "au format csv", bilans_bdf_instructeur_avis_path(@avis, format: 'csv') + , + = link_to "au format xlsx", bilans_bdf_instructeur_avis_path(@avis, format: 'xlsx') + ou + = link_to "au format ods", bilans_bdf_instructeur_avis_path(@avis, format: 'ods') + - else + %td + Les consulter + = link_to "au format csv", bilans_bdf_instructeur_dossier_path(procedure_id: @dossier.procedure.id, dossier_id: @dossier.id, format: 'csv') + , + = link_to "au format xlsx", bilans_bdf_instructeur_dossier_path(procedure_id: @dossier.procedure.id, dossier_id: @dossier.id, format: 'xlsx') + ou + = link_to "au format ods", bilans_bdf_instructeur_dossier_path(procedure_id: @dossier.procedure.id, dossier_id: @dossier.id, format: 'ods') + - else + %tr + %td.libelle + Bilans Banque de France : + %td Les 3 derniers bilans connus de votre entreprise par la Banque de France ont été joints à votre dossier. + - if etablissement.entreprise_attestation_sociale.attached? + %tr + %td.libelle Attestation sociale : + - if profile == 'instructeur' + %td= link_to "Consulter l'attestation", url_for(etablissement.entreprise_attestation_sociale) + - else + %td Une attestation de vigilance délivrée par l'ACOSS a été jointe à votre dossier. + + - if etablissement.entreprise_attestation_fiscale.attached? + %tr + %td.libelle Attestation fiscale : + - if profile == 'instructeur' + %td= link_to "Consulter l'attestation", url_for(etablissement.entreprise_attestation_fiscale) + - else + %td Une attestation fiscale délivrée par l'URSSAF a été jointe à votre dossier. + + - if etablissement.association? + %tr + %td.libelle Numéro RNA : + %td= etablissement.association_rna + %tr + %td.libelle Titre : + %td= etablissement.association_titre + %tr + %td.libelle Objet : + %td= etablissement.association_objet + %tr + %td.libelle Date de création : + %td= try_format_date(etablissement.association_date_creation) + %tr + %td.libelle Date de publication : + %td= try_format_date(etablissement.association_date_publication) + %tr + %td.libelle Date de déclaration : + %td= try_format_date(etablissement.association_date_declaration) + +- unless local_assigns[:short_identity] + %p + = link_to "➡ Autres informations sur l’organisme sur « annuaire-entreprises.data.gouv.fr » (ex: fiche d’immatriculation RNCS)", + annuaire_link(etablissement.siren), + target: "_blank" diff --git a/app/views/users/dossiers/_identity_dropdown.html.haml b/app/views/users/dossiers/_identity_dropdown.html.haml new file mode 100644 index 000000000..d814fd0e4 --- /dev/null +++ b/app/views/users/dossiers/_identity_dropdown.html.haml @@ -0,0 +1,17 @@ +.dropdown.edit-identity-action{ data: { controller: 'menu-button', popover: 'true' } } + %button.button.dropdown-button{ data: { menu_button_target: 'button' } } + = t("views.shared.dossiers.demande.my_identity") + + #edit-identity-content.dropdown-content.fade-in-down{ data: { menu_button_target: 'menu' } } + - if dossier.procedure.for_individual + = render partial: "shared/dossiers/identite_individual", locals: { individual: dossier.individual } + + .center + = link_to t('views.shared.dossiers.demande.edit_identity'), identite_dossier_path(dossier), class: 'button' + + - elsif dossier.etablissement + = render partial: "shared/dossiers/identite_entreprise", locals: { etablissement: dossier.etablissement, short_identity: true, profile: "usager" } + + .center + = link_to t('views.shared.dossiers.demande.edit_siret'), siret_dossier_path(dossier), class: 'button' + diff --git a/config/locales/api_entreprise.en.yml b/config/locales/api_entreprise.en.yml index ee815c16e..e6c2fe6fa 100644 --- a/config/locales/api_entreprise.en.yml +++ b/config/locales/api_entreprise.en.yml @@ -2,3 +2,4 @@ en: api_entreprise: errors: missing_token: "the API Entreprise token cannot be blank" + token_expired: "API Entreprise token has expired." diff --git a/config/locales/api_entreprise.fr.yml b/config/locales/api_entreprise.fr.yml index f8d81a523..8c997879d 100644 --- a/config/locales/api_entreprise.fr.yml +++ b/config/locales/api_entreprise.fr.yml @@ -2,3 +2,4 @@ fr: api_entreprise: errors: missing_token: "le jeton API Entreprise ne peut être vide" + token_expired: "Le jeton API Entreprise a expiré." diff --git a/config/locales/en.yml b/config/locales/en.yml index 486a73e97..ec24bf4d1 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -133,6 +133,7 @@ en: write_message_to_administration_placeholder: "Write your message to the administration here" demande: requester_identity: "Identity of the requester" + my_identity: "My identity" form: "Form" edit_siret: "Edit SIRET" edit_identity: "Edit identity data" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index b83bf48fd..c7a2a2a1c 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -128,6 +128,7 @@ fr: write_message_to_administration_placeholder: "Écrivez votre message à l’administration ici" demande: requester_identity: "Identité du demandeur" + my_identity: "Mon identité" form: "Formulaire" edit_siret: "Modifier le SIRET" edit_identity: "Modifier l’identité" diff --git a/spec/controllers/users/dossiers_controller_spec.rb b/spec/controllers/users/dossiers_controller_spec.rb index 4fb36ec88..958fc04f4 100644 --- a/spec/controllers/users/dossiers_controller_spec.rb +++ b/spec/controllers/users/dossiers_controller_spec.rb @@ -271,7 +271,7 @@ describe Users::DossiersController, type: :controller do let(:api_etablissement_status) { 200 } let(:token_expired) { true } - it_behaves_like 'the request fails with an error', I18n.t('errors.messages.siret_unknown') + it_behaves_like 'the request fails with an error', I18n.t('errors.messages.siret_network_error') end context 'when all API informations available' do diff --git a/spec/lib/api_entreprise/api_spec.rb b/spec/lib/api_entreprise/api_spec.rb index bb6d6aff1..03021f6f0 100644 --- a/spec/lib/api_entreprise/api_spec.rb +++ b/spec/lib/api_entreprise/api_spec.rb @@ -267,7 +267,7 @@ describe APIEntreprise::API do end it 'makes no call to api-entreprise' do - subject + expect { subject }.to raise_error(APIEntrepriseToken::TokenError) expect(WebMock).not_to have_requested(:get, /https:\/\/entreprise.api.gouv.fr\/v2\/entreprises\/#{siren}/) end end diff --git a/spec/views/shared/dossiers/_header.html.haml.spec.rb b/spec/views/shared/dossiers/_header.html.haml.spec.rb index 402b4edb1..1350509ed 100644 --- a/spec/views/shared/dossiers/_header.html.haml.spec.rb +++ b/spec/views/shared/dossiers/_header.html.haml.spec.rb @@ -52,4 +52,27 @@ describe 'dossiers/show/header.html.haml', type: :view do end end end + + describe "identity edit" do + context "when the identity is individual" do + let(:procedure) { create(:procedure, for_individual: true) } + let(:dossier) { create(:dossier, :with_individual, state: "brouillon", procedure: procedure) } + + it "display identity with an edit link" do + expect(rendered).to have_text(/Nom\s+#{dossier.individual.nom}/) + expect(rendered).to have_link("Modifier l’identité") + end + end + + context "when the identity is an enterprise" do + let(:procedure) { create(:procedure, for_individual: false) } + let(:dossier) { create(:dossier, :with_entreprise, state: "brouillon", procedure: procedure) } + + it "display short identity with an edit siret link" do + expect(rendered).to have_text(/Dénomination :\s+#{dossier.etablissement.entreprise_raison_sociale}/) + expect(rendered).not_to have_text("Numéro de TVA") + expect(rendered).to have_link("Modifier le SIRET") + end + end + end end