Merge pull request #10346 from mfo/US/permit-to-disable-tiers-bloc
ETQ administrateur, je souhaite pouvoir conditionner l'affichage du bloc " Pour un bénéficiaire : membre de la famille, proche, mandant, professionnel en charge du suivi du dossier…"
This commit is contained in:
commit
9518982166
26 changed files with 242 additions and 200 deletions
11
app/components/dossiers/individual_form_component.rb
Normal file
11
app/components/dossiers/individual_form_component.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
class Dossiers::IndividualFormComponent < ApplicationComponent
|
||||||
|
delegate :for_tiers?, to: :@dossier
|
||||||
|
|
||||||
|
def initialize(dossier:)
|
||||||
|
@dossier = dossier
|
||||||
|
end
|
||||||
|
|
||||||
|
def email_notifications?(individual)
|
||||||
|
individual.object.notification_method == Individual.notification_methods[:email]
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
en:
|
||||||
|
self_title: Your identity
|
||||||
|
callout_text: "You are acting as a proxy for a principal, either professionally (such as accountant, lawyer, civil servant…) or personally (family). Make sure to respect the conditions of"
|
||||||
|
callout_link: Articles 1984 and following of the Civil Code.
|
||||||
|
callout_link_title: Articles 1984 and following of the Civil Code
|
||||||
|
beneficiaire_title: "Identity of the beneficiary"
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
fr:
|
||||||
|
self_title: Votre identité
|
||||||
|
callout_text: Vous agissez en tant que mandataire, soit professionnellement (comme expert-comptable, avocat, agent public…) soit personnellement (famille). Assurez-vous de respecter les conditions
|
||||||
|
callout_link: des Articles 1984 et suivants du Code civil.
|
||||||
|
callout_link_title: Articles 1984 et suivants du Code civil
|
||||||
|
beneficiaire_title: Identité du bénéficiaire
|
|
@ -0,0 +1,76 @@
|
||||||
|
= form_for @dossier, url: update_identite_dossier_path(@dossier), html: { id: 'identite-form', class: "form", "data-controller" => "for-tiers" } do |f|
|
||||||
|
- if for_tiers?
|
||||||
|
.fr-alert.fr-alert--info.fr-mb-2w
|
||||||
|
%p.fr-notice__text
|
||||||
|
= t('.callout_text')
|
||||||
|
= link_to(t('.callout_link'),
|
||||||
|
'https://www.legifrance.gouv.fr/codes/section_lc/LEGITEXT000006070721/LEGISCTA000006136404/#LEGISCTA000006136404',
|
||||||
|
title: helpers.new_tab_suffix(t('.callout_link_title')),
|
||||||
|
**helpers.external_link_attributes)
|
||||||
|
|
||||||
|
%fieldset.fr-fieldset.mandataire-infos
|
||||||
|
%legend.fr-fieldset__legend--regular.fr-fieldset__legend
|
||||||
|
%h2.fr-h4
|
||||||
|
= t('.self_title')
|
||||||
|
|
||||||
|
.fr-fieldset__element.fr-fieldset__element--short-text
|
||||||
|
= render Dsfr::InputComponent.new(form: f, attribute: :mandataire_first_name, opts: { autocomplete: 'given-name' })
|
||||||
|
|
||||||
|
.fr-fieldset__element.fr-fieldset__element--short-text
|
||||||
|
= render Dsfr::InputComponent.new(form: f, attribute: :mandataire_last_name, opts: { autocomplete: 'family-name' })
|
||||||
|
|
||||||
|
= f.fields_for :individual, include_id: false do |individual|
|
||||||
|
%fieldset.fr-fieldset.fr-mb-0.individual-infos
|
||||||
|
%legend.fr-fieldset__legend--regular.fr-fieldset__legend
|
||||||
|
%h2.fr-h4
|
||||||
|
- if for_tiers?
|
||||||
|
= t('.beneficiaire_title')
|
||||||
|
- else
|
||||||
|
= t('.self_title')
|
||||||
|
|
||||||
|
.fr-fieldset__element.fr-mb-0
|
||||||
|
%fieldset.fr-fieldset
|
||||||
|
%legend.fr-fieldset__legend--regular.fr-fieldset__legend
|
||||||
|
= t('activerecord.attributes.individual.gender')
|
||||||
|
= render EditableChamp::AsteriskMandatoryComponent.new
|
||||||
|
|
||||||
|
.fr-fieldset__element
|
||||||
|
.fr-radio-group
|
||||||
|
= individual.radio_button :gender, Individual::GENDER_FEMALE, required: true, id: "identite_champ_radio_#{Individual::GENDER_FEMALE}"
|
||||||
|
%label.fr-label{ for: "identite_champ_radio_#{Individual::GENDER_FEMALE}" }
|
||||||
|
= Individual.human_attribute_name('gender.female')
|
||||||
|
.fr-fieldset__element
|
||||||
|
.fr-radio-group
|
||||||
|
= individual.radio_button :gender, Individual::GENDER_MALE, required: true, id: "identite_champ_radio_#{Individual::GENDER_MALE}"
|
||||||
|
%label.fr-label{ for: "identite_champ_radio_#{Individual::GENDER_MALE}" }
|
||||||
|
= Individual.human_attribute_name('gender.male')
|
||||||
|
.fr-fieldset__element.fr-mb-0
|
||||||
|
%fieldset.fr-fieldset.width-100
|
||||||
|
.fr-fieldset__element.fr-fieldset__element--short-text
|
||||||
|
= render Dsfr::InputComponent.new(form: individual, attribute: :prenom, opts: { autocomplete: (for_tiers? ? false : 'given-name') })
|
||||||
|
.fr-fieldset__element.fr-fieldset__element--short-text
|
||||||
|
= render Dsfr::InputComponent.new(form: individual, attribute: :nom, opts: { autocomplete: (for_tiers? ? false : 'family-name') })
|
||||||
|
|
||||||
|
- if @dossier.procedure.ask_birthday?
|
||||||
|
.fr-fieldset__element
|
||||||
|
= render Dsfr::InputComponent.new(form: individual, attribute: :birthdate, input_type: :date_field,
|
||||||
|
opts: { placeholder: 'Format : AAAA-MM-JJ', max: Date.today.iso8601, min: "1900-01-01", autocomplete: 'bday' })
|
||||||
|
|
||||||
|
- if for_tiers?
|
||||||
|
%fieldset.fr-fieldset
|
||||||
|
%legend.fr-fieldset__legend--regular.fr-fieldset__legend
|
||||||
|
= t('activerecord.attributes.individual.notification_method')
|
||||||
|
= render EditableChamp::AsteriskMandatoryComponent.new
|
||||||
|
|
||||||
|
- Individual.notification_methods.each do |method, _|
|
||||||
|
.fr-fieldset__element
|
||||||
|
.fr-radio-group
|
||||||
|
= individual.radio_button :notification_method, method, required: true, id: "notification_method_#{method}", "data-action" => "for-tiers#toggleEmailInput", "data-for-tiers-target" => "notificationMethod"
|
||||||
|
%label.fr-label{ for: "notification_method_#{method}" }
|
||||||
|
= t("activerecord.attributes.individual.notification_methods.#{method}")
|
||||||
|
|
||||||
|
|
||||||
|
.fr-fieldset__element.fr-fieldset__element--short-text{ "data-for-tiers-target" => "emailContainer", class: class_names(hidden: !email_notifications?(individual)) }
|
||||||
|
= render Dsfr::InputComponent.new(form: individual, attribute: :email, input_type: :email_field, opts: { "data-for-tiers-target" => "emailInput" })
|
||||||
|
|
||||||
|
= f.submit t('views.users.dossiers.identite.continue'), class: "fr-btn"
|
|
@ -135,6 +135,13 @@ module Users
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
@user = current_user
|
@user = current_user
|
||||||
@no_description = true
|
@no_description = true
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.html
|
||||||
|
format.turbo_stream do
|
||||||
|
@dossier.update_columns(params.require(:dossier).permit(:for_tiers).to_h)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_identite
|
def update_identite
|
||||||
|
|
|
@ -46,6 +46,7 @@ class ProcedureDashboard < Administrate::BaseDashboard
|
||||||
max_duree_conservation_dossiers_dans_ds: Field::Number,
|
max_duree_conservation_dossiers_dans_ds: Field::Number,
|
||||||
estimated_duration_visible: Field::Boolean,
|
estimated_duration_visible: Field::Boolean,
|
||||||
piece_justificative_multiple: Field::Boolean,
|
piece_justificative_multiple: Field::Boolean,
|
||||||
|
for_tiers_enabled: Field::Boolean,
|
||||||
replaced_by_procedure_id: Field::String,
|
replaced_by_procedure_id: Field::String,
|
||||||
tags: Field::Text,
|
tags: Field::Text,
|
||||||
template: Field::Boolean
|
template: Field::Boolean
|
||||||
|
@ -109,6 +110,7 @@ class ProcedureDashboard < Administrate::BaseDashboard
|
||||||
:max_duree_conservation_dossiers_dans_ds,
|
:max_duree_conservation_dossiers_dans_ds,
|
||||||
:estimated_duration_visible,
|
:estimated_duration_visible,
|
||||||
:piece_justificative_multiple,
|
:piece_justificative_multiple,
|
||||||
|
:for_tiers_enabled,
|
||||||
:replaced_by_procedure_id
|
:replaced_by_procedure_id
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
|
@ -121,6 +123,7 @@ class ProcedureDashboard < Administrate::BaseDashboard
|
||||||
:max_duree_conservation_dossiers_dans_ds,
|
:max_duree_conservation_dossiers_dans_ds,
|
||||||
:estimated_duration_visible,
|
:estimated_duration_visible,
|
||||||
:piece_justificative_multiple,
|
:piece_justificative_multiple,
|
||||||
|
:for_tiers_enabled,
|
||||||
:replaced_by_procedure_id
|
:replaced_by_procedure_id
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
|
|
|
@ -1,87 +1,32 @@
|
||||||
|
import { toggle } from '@utils';
|
||||||
import { ApplicationController } from './application_controller';
|
import { ApplicationController } from './application_controller';
|
||||||
|
|
||||||
|
function onVisibleEnableInputs(element: HTMLInputElement) {
|
||||||
|
element.disabled = false;
|
||||||
|
element.required = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onHiddenDisableInputs(element: HTMLInputElement) {
|
||||||
|
element.disabled = true;
|
||||||
|
element.required = false;
|
||||||
|
}
|
||||||
|
|
||||||
export class ForTiersController extends ApplicationController {
|
export class ForTiersController extends ApplicationController {
|
||||||
static targets = [
|
static targets = ['emailContainer', 'emailInput', 'notificationMethod'];
|
||||||
'mandataireFirstName',
|
|
||||||
'mandataireLastName',
|
|
||||||
'forTiers',
|
|
||||||
'mandataireBlock',
|
|
||||||
'beneficiaireNotificationBlock',
|
|
||||||
'email',
|
|
||||||
'notificationMethod',
|
|
||||||
'mandataireTitle',
|
|
||||||
'beneficiaireTitle',
|
|
||||||
'emailInput'
|
|
||||||
];
|
|
||||||
|
|
||||||
declare mandataireFirstNameTarget: HTMLInputElement;
|
|
||||||
declare mandataireLastNameTarget: HTMLInputElement;
|
|
||||||
declare forTiersTargets: NodeListOf<HTMLInputElement>;
|
|
||||||
declare mandataireBlockTarget: HTMLElement;
|
|
||||||
declare beneficiaireNotificationBlockTarget: HTMLElement;
|
|
||||||
declare notificationMethodTargets: NodeListOf<HTMLInputElement>;
|
declare notificationMethodTargets: NodeListOf<HTMLInputElement>;
|
||||||
declare emailTarget: HTMLInputElement;
|
declare emailContainerTarget: HTMLElement;
|
||||||
declare mandataireTitleTarget: HTMLElement;
|
declare emailInputTarget: HTMLInputElement;
|
||||||
declare beneficiaireTitleTarget: HTMLElement;
|
|
||||||
declare emailInput: HTMLInputElement;
|
|
||||||
|
|
||||||
connect() {
|
|
||||||
const emailInputElement = this.emailTarget.querySelector('input');
|
|
||||||
if (emailInputElement) {
|
|
||||||
this.emailInput = emailInputElement;
|
|
||||||
}
|
|
||||||
this.toggleFieldRequirements();
|
|
||||||
this.addAllEventListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
addAllEventListeners() {
|
|
||||||
this.forTiersTargets.forEach((radio) => {
|
|
||||||
radio.addEventListener('change', () => this.toggleFieldRequirements());
|
|
||||||
});
|
|
||||||
this.notificationMethodTargets.forEach((radio) => {
|
|
||||||
radio.addEventListener('change', () => this.toggleEmailInput());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleFieldRequirements() {
|
|
||||||
const forTiersSelected = this.isForTiersSelected();
|
|
||||||
this.toggleDisplay(this.mandataireBlockTarget, forTiersSelected);
|
|
||||||
this.toggleDisplay(
|
|
||||||
this.beneficiaireNotificationBlockTarget,
|
|
||||||
forTiersSelected
|
|
||||||
);
|
|
||||||
this.mandataireFirstNameTarget.required = forTiersSelected;
|
|
||||||
this.mandataireLastNameTarget.required = forTiersSelected;
|
|
||||||
this.mandataireTitleTarget.classList.toggle('hidden', forTiersSelected);
|
|
||||||
this.beneficiaireTitleTarget.classList.toggle('hidden', !forTiersSelected);
|
|
||||||
this.notificationMethodTargets.forEach((radio) => {
|
|
||||||
radio.required = forTiersSelected;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.toggleEmailInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
isForTiersSelected() {
|
|
||||||
return Array.from(this.forTiersTargets).some(
|
|
||||||
(radio) => radio.checked && radio.value === 'true'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
toggleDisplay(element: HTMLElement, shouldDisplay: boolean) {
|
|
||||||
element.classList.toggle('hidden', !shouldDisplay);
|
|
||||||
}
|
|
||||||
toggleEmailInput() {
|
toggleEmailInput() {
|
||||||
const isEmailSelected = this.isEmailSelected();
|
const isEmailSelected = this.isEmailSelected();
|
||||||
const forTiersSelected = this.isForTiersSelected();
|
|
||||||
|
|
||||||
if (this.emailInput) {
|
toggle(this.emailContainerTarget, isEmailSelected);
|
||||||
this.emailInput.required = forTiersSelected && isEmailSelected;
|
|
||||||
|
|
||||||
if (!isEmailSelected) {
|
if (isEmailSelected) {
|
||||||
this.emailInput.value = '';
|
onVisibleEnableInputs(this.emailInputTarget);
|
||||||
}
|
} else {
|
||||||
|
onHiddenDisableInputs(this.emailInputTarget);
|
||||||
this.toggleDisplay(this.emailTarget, forTiersSelected && isEmailSelected);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ class Individual < ApplicationRecord
|
||||||
if: -> { dossier.for_tiers? },
|
if: -> { dossier.for_tiers? },
|
||||||
on: :update
|
on: :update
|
||||||
|
|
||||||
validates :email, presence: true, if: -> { dossier.for_tiers? && self.email? }, on: :update
|
validates :email, strict_email: true, presence: true, if: -> { dossier.for_tiers? && self.email? }, on: :update
|
||||||
|
|
||||||
GENDER_MALE = "M."
|
GENDER_MALE = "M."
|
||||||
GENDER_FEMALE = 'Mme'
|
GENDER_FEMALE = 'Mme'
|
||||||
|
|
|
@ -3,98 +3,28 @@
|
||||||
= render partial: "shared/dossiers/submit_is_over", locals: { dossier: @dossier }
|
= render partial: "shared/dossiers/submit_is_over", locals: { dossier: @dossier }
|
||||||
|
|
||||||
- if !dossier_submission_is_closed?(@dossier)
|
- if !dossier_submission_is_closed?(@dossier)
|
||||||
= form_for @dossier, url: update_identite_dossier_path(@dossier), html: { class: "form", "data-controller" => "for-tiers" } do |f|
|
- if @dossier.procedure.for_tiers_enabled?
|
||||||
|
= form_for @dossier, url: identite_dossier_path(@dossier), method: :patch, html: { class: "form" }, data: {turbo: true, controller: :autosubmit} do |f|
|
||||||
|
|
||||||
%fieldset#radio-rich-hint.fr-fieldset{ "aria-labelledby" => "radio-rich-hint-legend radio-rich-hint-messages" }
|
%fieldset#radio-rich-hint.fr-fieldset{ "aria-labelledby" => "radio-rich-hint-legend radio-rich-hint-messages" }
|
||||||
%legend#radio-rich-hint-legend.fr-fieldset__legend--regular.fr-fieldset__legend
|
%legend#radio-rich-hint-legend.fr-fieldset__legend--regular.fr-fieldset__legend
|
||||||
= t('views.users.dossiers.identite.legend')
|
= t('views.users.dossiers.identite.legend')
|
||||||
|
|
||||||
.fr-fieldset__element
|
.fr-fieldset__element
|
||||||
.fr-radio-group.fr-radio-rich
|
.fr-radio-group.fr-radio-rich
|
||||||
= f.radio_button :for_tiers, false, required: true, id: "radio-self-manage", "data-action" => "click->for-tiers#toggleFieldRequirements", "data-for-tiers-target" => "forTiers"
|
= f.radio_button :for_tiers, false, required: true, id: "radio-self-manage"
|
||||||
%label.fr-label{ for: "radio-self-manage" }
|
%label.fr-label{ for: "radio-self-manage" }
|
||||||
= t('activerecord.attributes.dossier.for_tiers.false')
|
= t('activerecord.attributes.dossier.for_tiers.false')
|
||||||
.fr-radio-rich__img
|
.fr-radio-rich__img
|
||||||
%span.fr-icon-user-fill
|
%span.fr-icon-user-fill
|
||||||
.fr-fieldset__element
|
.fr-fieldset__element
|
||||||
.fr-radio-group.fr-radio-rich
|
.fr-radio-group.fr-radio-rich
|
||||||
= f.radio_button :for_tiers, true, required: true, id: "radio-tiers-manage", "data-action" => "click->for-tiers#toggleFieldRequirements", "data-for-tiers-target" => "forTiers"
|
= f.radio_button :for_tiers, true, required: true, id: "radio-tiers-manage"
|
||||||
%label.fr-label{ for: "radio-tiers-manage" }
|
%label.fr-label{ for: "radio-tiers-manage" }
|
||||||
= t('activerecord.attributes.dossier.for_tiers.true')
|
= t('activerecord.attributes.dossier.for_tiers.true')
|
||||||
.fr-radio-rich__img
|
.fr-radio-rich__img
|
||||||
%span.fr-icon-parent-fill
|
%span.fr-icon-parent-fill
|
||||||
|
|
||||||
.mandataire-infos{ "data-for-tiers-target" => "mandataireBlock" }
|
= f.submit t('views.users.dossiers.identite.continue'), class: 'visually-hidden'
|
||||||
.fr-alert.fr-alert--info.fr-mb-2w
|
|
||||||
%p.fr-notice__text
|
|
||||||
= t('views.users.dossiers.identite.callout_text')
|
|
||||||
= link_to(t('views.users.dossiers.identite.callout_link'),
|
|
||||||
'https://www.legifrance.gouv.fr/codes/section_lc/LEGITEXT000006070721/LEGISCTA000006136404/#LEGISCTA000006136404',
|
|
||||||
title: new_tab_suffix(t('views.users.dossiers.identite.callout_link_title')),
|
|
||||||
**external_link_attributes)
|
|
||||||
|
|
||||||
|
= render Dossiers::IndividualFormComponent.new(dossier: @dossier)
|
||||||
%fieldset.fr-fieldset
|
|
||||||
%legend.fr-fieldset__legend--regular.fr-fieldset__legend
|
|
||||||
%h2.fr-h4= t('views.users.dossiers.identite.self_title')
|
|
||||||
|
|
||||||
.fr-fieldset__element.fr-fieldset__element--short-text
|
|
||||||
= render Dsfr::InputComponent.new(form: f, attribute: :mandataire_first_name, opts: { "data-for-tiers-target" => "mandataireFirstName" })
|
|
||||||
|
|
||||||
.fr-fieldset__element.fr-fieldset__element--short-text
|
|
||||||
= render Dsfr::InputComponent.new(form: f, attribute: :mandataire_last_name, opts: { "data-for-tiers-target" => "mandataireLastName" })
|
|
||||||
|
|
||||||
= f.fields_for :individual, include_id: false do |individual|
|
|
||||||
.individual-infos
|
|
||||||
%fieldset.fr-fieldset
|
|
||||||
%legend.fr-fieldset__legend--regular.fr-fieldset__legend{ "data-for-tiers-target" => "mandataireTitle" }
|
|
||||||
%h2.fr-h4= t('views.users.dossiers.identite.self_title')
|
|
||||||
|
|
||||||
%legend.fr-fieldset__legend--regular.fr-fieldset__legend.hidden{ "data-for-tiers-target" => "beneficiaireTitle" }
|
|
||||||
%h2.fr-h4= t('views.users.dossiers.identite.beneficiaire_title')
|
|
||||||
|
|
||||||
|
|
||||||
%legend.fr-fieldset__legend--regular.fr-fieldset__legend
|
|
||||||
= t('activerecord.attributes.individual.gender')
|
|
||||||
= render EditableChamp::AsteriskMandatoryComponent.new
|
|
||||||
.fr-fieldset__element
|
|
||||||
.fr-radio-group
|
|
||||||
= individual.radio_button :gender, Individual::GENDER_FEMALE, required: true, id: "identite_champ_radio_#{Individual::GENDER_FEMALE}"
|
|
||||||
%label.fr-label{ for: "identite_champ_radio_#{Individual::GENDER_FEMALE}" }
|
|
||||||
= Individual.human_attribute_name('gender.female')
|
|
||||||
.fr-fieldset__element
|
|
||||||
.fr-radio-group
|
|
||||||
= individual.radio_button :gender, Individual::GENDER_MALE, required: true, id: "identite_champ_radio_#{Individual::GENDER_MALE}"
|
|
||||||
%label.fr-label{ for: "identite_champ_radio_#{Individual::GENDER_MALE}" }
|
|
||||||
= Individual.human_attribute_name('gender.male')
|
|
||||||
|
|
||||||
.fr-fieldset__element.fr-fieldset__element--short-text
|
|
||||||
= render Dsfr::InputComponent.new(form: individual, attribute: :prenom, opts: { autocomplete: 'given-name' })
|
|
||||||
|
|
||||||
.fr-fieldset__element.fr-fieldset__element--short-text
|
|
||||||
= render Dsfr::InputComponent.new(form: individual, attribute: :nom, opts: { autocomplete: 'family-name' })
|
|
||||||
|
|
||||||
%fieldset.fr-fieldset{ "data-for-tiers-target" => "beneficiaireNotificationBlock" }
|
|
||||||
%legend.fr-fieldset__legend--regular.fr-fieldset__legend
|
|
||||||
= t('activerecord.attributes.individual.notification_method')
|
|
||||||
= render EditableChamp::AsteriskMandatoryComponent.new
|
|
||||||
|
|
||||||
- Individual.notification_methods.each do |method, _|
|
|
||||||
.fr-fieldset__element
|
|
||||||
.fr-radio-group
|
|
||||||
= individual.radio_button :notification_method, method, id: "notification_method_#{method}", "data-action" => "for-tiers#toggleFieldRequirements", "data-for-tiers-target" => "notificationMethod"
|
|
||||||
%label.fr-label{ for: "notification_method_#{method}" }
|
|
||||||
= t("activerecord.attributes.individual.notification_methods.#{method}")
|
|
||||||
|
|
||||||
|
|
||||||
.fr-fieldset__element.fr-fieldset__element--short-text.hidden{ "data-for-tiers-target" => "email" }
|
|
||||||
= render Dsfr::InputComponent.new(form: individual, attribute: :email)
|
|
||||||
|
|
||||||
|
|
||||||
- if @dossier.procedure.ask_birthday?
|
|
||||||
.fr-fieldset__element
|
|
||||||
= render Dsfr::InputComponent.new(form: individual, attribute: :birthdate, input_type: :date_field,
|
|
||||||
opts: { placeholder: 'Format : AAAA-MM-JJ', max: Date.today.iso8601, min: "1900-01-01", autocomplete: 'bday' })
|
|
||||||
|
|
||||||
|
|
||||||
= f.submit t('views.users.dossiers.identite.continue'), class: "fr-btn"
|
|
||||||
|
|
1
app/views/users/dossiers/identite.turbo_stream.haml
Normal file
1
app/views/users/dossiers/identite.turbo_stream.haml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
= turbo_stream.replace 'identite-form', render(Dossiers::IndividualFormComponent.new(dossier: @dossier))
|
|
@ -423,11 +423,6 @@ en:
|
||||||
archived_dossier: "Your file will be kept %{duree_conservation_dossiers_dans_ds} more months"
|
archived_dossier: "Your file will be kept %{duree_conservation_dossiers_dans_ds} more months"
|
||||||
identite:
|
identite:
|
||||||
legend: 'This file is:'
|
legend: 'This file is:'
|
||||||
self_title: Your identity
|
|
||||||
callout_text: "You are acting as a proxy for a principal, either professionally (such as accountant, lawyer, civil servant…) or personally (family). Make sure to respect the conditions of"
|
|
||||||
callout_link: Articles 1984 and following of the Civil Code.
|
|
||||||
callout_link_title: Articles 1984 and following of the Civil Code
|
|
||||||
beneficiaire_title: "Identity of the beneficiary"
|
|
||||||
identity_siret: Identify your establishment
|
identity_siret: Identify your establishment
|
||||||
civility: Civility
|
civility: Civility
|
||||||
first_name: First Name
|
first_name: First Name
|
||||||
|
|
|
@ -426,11 +426,6 @@ fr:
|
||||||
archived_dossier: "Votre dossier sera conservé %{duree_conservation_dossiers_dans_ds} mois supplémentaire"
|
archived_dossier: "Votre dossier sera conservé %{duree_conservation_dossiers_dans_ds} mois supplémentaire"
|
||||||
identite:
|
identite:
|
||||||
legend: 'Ce dossier est : '
|
legend: 'Ce dossier est : '
|
||||||
self_title: Votre identité
|
|
||||||
callout_text: Vous agissez en tant que mandataire, soit professionnellement (comme expert-comptable, avocat, agent public…) soit personnellement (famille). Assurez-vous de respecter les conditions
|
|
||||||
callout_link: des Articles 1984 et suivants du Code civil.
|
|
||||||
callout_link_title: Articles 1984 et suivants du Code civil
|
|
||||||
beneficiaire_title: Identité du bénéficiaire
|
|
||||||
identity_siret: Identifier votre établissement
|
identity_siret: Identifier votre établissement
|
||||||
civility: Civilité
|
civility: Civilité
|
||||||
first_name: Prénom
|
first_name: Prénom
|
||||||
|
|
|
@ -37,6 +37,7 @@ en:
|
||||||
lien_dpo: Link or email to contact the data protection officer (DPO)
|
lien_dpo: Link or email to contact the data protection officer (DPO)
|
||||||
duree_conservation_dossiers_dans_ds: Duration files will be kept
|
duree_conservation_dossiers_dans_ds: Duration files will be kept
|
||||||
max_duree_conservation_dossiers_dans_ds: Max duration allowed to keep files
|
max_duree_conservation_dossiers_dans_ds: Max duration allowed to keep files
|
||||||
|
for_tiers_enabled: Enable a third party to submit a file
|
||||||
aasm_state:
|
aasm_state:
|
||||||
brouillon: Draft
|
brouillon: Draft
|
||||||
publiee: Published
|
publiee: Published
|
||||||
|
|
|
@ -20,6 +20,7 @@ fr:
|
||||||
organisation: Organisme
|
organisation: Organisme
|
||||||
duree_conservation_dossiers_dans_ds: Durée de conservation des dossiers
|
duree_conservation_dossiers_dans_ds: Durée de conservation des dossiers
|
||||||
max_duree_conservation_dossiers_dans_ds: Durée maximale de conservation des dossiers (autorisée par un super admin)
|
max_duree_conservation_dossiers_dans_ds: Durée maximale de conservation des dossiers (autorisée par un super admin)
|
||||||
|
for_tiers_enabled: Activer le dépot par un tiers
|
||||||
id: Id
|
id: Id
|
||||||
libelle: Titre de la démarche
|
libelle: Titre de la démarche
|
||||||
description: Quel est l’objet de la démarche ?
|
description: Quel est l’objet de la démarche ?
|
||||||
|
|
|
@ -361,6 +361,7 @@ Rails.application.routes.draw do
|
||||||
resources :dossiers, only: [:index, :show, :destroy, :new] do
|
resources :dossiers, only: [:index, :show, :destroy, :new] do
|
||||||
member do
|
member do
|
||||||
get 'identite'
|
get 'identite'
|
||||||
|
patch 'identite'
|
||||||
patch 'update_identite'
|
patch 'update_identite'
|
||||||
post 'clone'
|
post 'clone'
|
||||||
get 'siret'
|
get 'siret'
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddColumnForTiersEnabledToProcedure < ActiveRecord::Migration[7.0]
|
||||||
|
def change
|
||||||
|
add_column :procedures, :for_tiers_enabled, :boolean, default: true, null: false
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[7.0].define(version: 2024_04_16_062900) do
|
ActiveRecord::Schema[7.0].define(version: 2024_04_17_053843) do
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "pg_buffercache"
|
enable_extension "pg_buffercache"
|
||||||
enable_extension "pg_stat_statements"
|
enable_extension "pg_stat_statements"
|
||||||
|
@ -894,6 +894,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_04_16_062900) do
|
||||||
t.boolean "euro_flag", default: false
|
t.boolean "euro_flag", default: false
|
||||||
t.boolean "experts_require_administrateur_invitation", default: false
|
t.boolean "experts_require_administrateur_invitation", default: false
|
||||||
t.boolean "for_individual", default: false
|
t.boolean "for_individual", default: false
|
||||||
|
t.boolean "for_tiers_enabled", default: true, null: false
|
||||||
t.datetime "hidden_at", precision: nil
|
t.datetime "hidden_at", precision: nil
|
||||||
t.datetime "hidden_at_as_template", precision: nil
|
t.datetime "hidden_at_as_template", precision: nil
|
||||||
t.boolean "instructeurs_self_management_enabled", default: false
|
t.boolean "instructeurs_self_management_enabled", default: false
|
||||||
|
|
|
@ -8,7 +8,9 @@ shared_examples "the user has got a prefilled dossier, owned by themselves" do
|
||||||
expect(page).to have_field('Prénom', with: prenom_value)
|
expect(page).to have_field('Prénom', with: prenom_value)
|
||||||
expect(page).to have_field('Nom', with: nom_value)
|
expect(page).to have_field('Nom', with: nom_value)
|
||||||
end
|
end
|
||||||
click_on 'Continuer'
|
within "#identite-form" do
|
||||||
|
click_on 'Continuer'
|
||||||
|
end
|
||||||
|
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
expect(page).to have_current_path(brouillon_dossier_path(dossier))
|
||||||
expect(page).to have_field(type_de_champ_text.libelle, with: text_value)
|
expect(page).to have_field(type_de_champ_text.libelle, with: text_value)
|
||||||
|
|
|
@ -126,7 +126,9 @@ describe 'wcag rules for usager', js: true do
|
||||||
fill_in('Prénom', with: 'prenom')
|
fill_in('Prénom', with: 'prenom')
|
||||||
fill_in('Nom', with: 'nom')
|
fill_in('Nom', with: 'nom')
|
||||||
end
|
end
|
||||||
click_on 'Continuer'
|
within "#identite-form" do
|
||||||
|
click_on 'Continuer'
|
||||||
|
end
|
||||||
|
|
||||||
expect(page).to be_axe_clean
|
expect(page).to be_axe_clean
|
||||||
end
|
end
|
||||||
|
|
|
@ -272,7 +272,9 @@ describe 'fetch API Particulier Data', js: true do
|
||||||
fill_in('Nom', with: 'nom')
|
fill_in('Nom', with: 'nom')
|
||||||
end
|
end
|
||||||
|
|
||||||
click_button('Continuer')
|
within "#identite-form" do
|
||||||
|
click_on 'Continuer'
|
||||||
|
end
|
||||||
|
|
||||||
fill_in 'Le numéro d’allocataire CAF', with: numero_allocataire
|
fill_in 'Le numéro d’allocataire CAF', with: numero_allocataire
|
||||||
fill_in 'Le code postal', with: 'wrong_code'
|
fill_in 'Le code postal', with: 'wrong_code'
|
||||||
|
@ -331,7 +333,9 @@ describe 'fetch API Particulier Data', js: true do
|
||||||
fill_in('Prénom', with: 'Georges')
|
fill_in('Prénom', with: 'Georges')
|
||||||
fill_in('Nom', with: 'Moustaki')
|
fill_in('Nom', with: 'Moustaki')
|
||||||
end
|
end
|
||||||
click_button('Continuer')
|
within "#identite-form" do
|
||||||
|
click_on 'Continuer'
|
||||||
|
end
|
||||||
|
|
||||||
fill_in "Identifiant", with: 'wrong code'
|
fill_in "Identifiant", with: 'wrong code'
|
||||||
|
|
||||||
|
@ -405,7 +409,9 @@ describe 'fetch API Particulier Data', js: true do
|
||||||
fill_in('Prénom', with: 'Angela Claire Louise')
|
fill_in('Prénom', with: 'Angela Claire Louise')
|
||||||
fill_in('Nom', with: 'Dubois')
|
fill_in('Nom', with: 'Dubois')
|
||||||
end
|
end
|
||||||
click_button('Continuer')
|
within "#identite-form" do
|
||||||
|
click_on 'Continuer'
|
||||||
|
end
|
||||||
|
|
||||||
fill_in "INE", with: 'wrong code'
|
fill_in "INE", with: 'wrong code'
|
||||||
|
|
||||||
|
@ -469,7 +475,9 @@ describe 'fetch API Particulier Data', js: true do
|
||||||
fill_in('Prénom', with: 'Karine')
|
fill_in('Prénom', with: 'Karine')
|
||||||
fill_in('Nom', with: 'FERRI')
|
fill_in('Nom', with: 'FERRI')
|
||||||
end
|
end
|
||||||
click_button('Continuer')
|
within "#identite-form" do
|
||||||
|
click_on 'Continuer'
|
||||||
|
end
|
||||||
|
|
||||||
fill_in 'Le numéro fiscal', with: numero_fiscal
|
fill_in 'Le numéro fiscal', with: numero_fiscal
|
||||||
fill_in "La référence d’avis d’imposition", with: 'wrong_code'
|
fill_in "La référence d’avis d’imposition", with: 'wrong_code'
|
||||||
|
|
|
@ -258,7 +258,9 @@ describe 'The routing with rules', js: true do
|
||||||
find('label', text: 'Monsieur').click
|
find('label', text: 'Monsieur').click
|
||||||
fill_in('Prénom', with: 'prenom', visible: true)
|
fill_in('Prénom', with: 'prenom', visible: true)
|
||||||
fill_in('Nom', with: 'Nom', visible: true)
|
fill_in('Nom', with: 'Nom', visible: true)
|
||||||
click_button('Continuer')
|
within "#identite-form" do
|
||||||
|
click_button('Continuer')
|
||||||
|
end
|
||||||
|
|
||||||
# the old system should not be present
|
# the old system should not be present
|
||||||
expect(page).not_to have_selector("#dossier_groupe_instructeur_id")
|
expect(page).not_to have_selector("#dossier_groupe_instructeur_id")
|
||||||
|
|
|
@ -665,7 +665,9 @@ describe 'The user' do
|
||||||
find('label', text: 'Monsieur').click
|
find('label', text: 'Monsieur').click
|
||||||
fill_in('Prénom', with: 'prenom', visible: true)
|
fill_in('Prénom', with: 'prenom', visible: true)
|
||||||
fill_in('Nom', with: 'Nom', visible: true)
|
fill_in('Nom', with: 'Nom', visible: true)
|
||||||
click_on 'Continuer'
|
within "#identite-form" do
|
||||||
|
click_on 'Continuer'
|
||||||
|
end
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
|
expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,7 +28,9 @@ describe 'Creating a new dossier:', js: true do
|
||||||
|
|
||||||
shared_examples 'the user can create a new draft' do
|
shared_examples 'the user can create a new draft' do
|
||||||
it do
|
it do
|
||||||
click_button('Continuer')
|
within "#identite-form" do
|
||||||
|
click_button('Continuer')
|
||||||
|
end
|
||||||
|
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(procedure.dossiers.last))
|
expect(page).to have_current_path(brouillon_dossier_path(procedure.dossiers.last))
|
||||||
expect(user.dossiers.first.individual.birthdate).to eq(expected_birthday)
|
expect(user.dossiers.first.individual.birthdate).to eq(expected_birthday)
|
||||||
|
@ -58,7 +60,6 @@ describe 'Creating a new dossier:', js: true do
|
||||||
context 'when individual fill dossier for a tiers' do
|
context 'when individual fill dossier for a tiers' do
|
||||||
it 'completes the form with email notification method selected' do
|
it 'completes the form with email notification method selected' do
|
||||||
find('label', text: 'Pour un bénéficiaire : membre de la famille, proche, mandant, professionnel en charge du suivi du dossier…').click
|
find('label', text: 'Pour un bénéficiaire : membre de la famille, proche, mandant, professionnel en charge du suivi du dossier…').click
|
||||||
|
|
||||||
within('.mandataire-infos') do
|
within('.mandataire-infos') do
|
||||||
fill_in('Prénom', with: 'John')
|
fill_in('Prénom', with: 'John')
|
||||||
fill_in('Nom', with: 'Doe')
|
fill_in('Nom', with: 'Doe')
|
||||||
|
@ -73,7 +74,15 @@ describe 'Creating a new dossier:', js: true do
|
||||||
|
|
||||||
find('label', text: 'Par e-mail').click
|
find('label', text: 'Par e-mail').click
|
||||||
fill_in('dossier_individual_attributes_email', with: 'prenom.nom@mail.com')
|
fill_in('dossier_individual_attributes_email', with: 'prenom.nom@mail.com')
|
||||||
click_button('Continuer')
|
find('label', text: 'Monsieur').click # force focus out
|
||||||
|
within "#identite-form" do
|
||||||
|
within '.suspect-email' do
|
||||||
|
expect(page).to have_content("Information : Voulez-vous dire ?")
|
||||||
|
click_button("Oui")
|
||||||
|
end
|
||||||
|
click_button("Continuer")
|
||||||
|
end
|
||||||
|
|
||||||
expect(procedure.dossiers.last.individual.notification_method == 'email')
|
expect(procedure.dossiers.last.individual.notification_method == 'email')
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(procedure.dossiers.last))
|
expect(page).to have_current_path(brouillon_dossier_path(procedure.dossiers.last))
|
||||||
end
|
end
|
||||||
|
@ -93,7 +102,10 @@ describe 'Creating a new dossier:', js: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
find('label', text: 'Pas de notification').click
|
find('label', text: 'Pas de notification').click
|
||||||
click_button('Continuer')
|
within "#identite-form" do
|
||||||
|
click_button('Continuer')
|
||||||
|
end
|
||||||
|
|
||||||
expect(procedure.dossiers.last.individual.notification_method.empty?)
|
expect(procedure.dossiers.last.individual.notification_method.empty?)
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(procedure.dossiers.last))
|
expect(page).to have_current_path(brouillon_dossier_path(procedure.dossiers.last))
|
||||||
end
|
end
|
||||||
|
|
|
@ -79,7 +79,9 @@ describe 'dropdown list with other option activated', js: true do
|
||||||
fill_in('Prénom', with: 'prenom')
|
fill_in('Prénom', with: 'prenom')
|
||||||
fill_in('Nom', with: 'nom')
|
fill_in('Nom', with: 'nom')
|
||||||
end
|
end
|
||||||
click_on 'Continuer'
|
within "#identite-form" do
|
||||||
|
click_on 'Continuer'
|
||||||
|
end
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
|
expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -85,7 +85,9 @@ describe 'linked dropdown lists' do
|
||||||
fill_in('Prénom', with: 'prenom')
|
fill_in('Prénom', with: 'prenom')
|
||||||
fill_in('Nom', with: 'nom')
|
fill_in('Nom', with: 'nom')
|
||||||
end
|
end
|
||||||
click_on 'Continuer'
|
within "#identite-form" do
|
||||||
|
click_on 'Continuer'
|
||||||
|
end
|
||||||
expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
|
expect(page).to have_current_path(brouillon_dossier_path(user_dossier))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
describe 'users/dossiers/identite', type: :view do
|
describe 'users/dossiers/identite', type: :view do
|
||||||
let(:procedure) { create(:simple_procedure, :for_individual) }
|
|
||||||
let(:dossier) { create(:dossier, :with_service, state: Dossier.states.fetch(:brouillon), procedure: procedure) }
|
let(:dossier) { create(:dossier, :with_service, state: Dossier.states.fetch(:brouillon), procedure: procedure) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
@ -9,18 +8,43 @@ describe 'users/dossiers/identite', type: :view do
|
||||||
|
|
||||||
subject! { render }
|
subject! { render }
|
||||||
|
|
||||||
it 'has identity fields' do
|
context 'when procedure has for_tiers_enabled' do
|
||||||
within('.individual-infos') do
|
let(:procedure) { create(:simple_procedure, :for_individual) }
|
||||||
expect(rendered).to have_field(id: 'Prenom')
|
|
||||||
expect(rendered).to have_field(id: 'Nom')
|
it 'has choice for you or a tiers' do
|
||||||
|
expect(rendered).to have_content "Pour vous"
|
||||||
|
expect(rendered).to have_content "Pour un bénéficiaire : membre de la famille, proche, mandant, professionnel en charge du suivi du dossier…"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has identity fields' do
|
||||||
|
within('.individual-infos') do
|
||||||
|
expect(rendered).to have_field(id: 'Prenom')
|
||||||
|
expect(rendered).to have_field(id: 'Nom')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the demarche asks for the birthdate' do
|
||||||
|
let(:procedure) { create(:simple_procedure, for_individual: true, ask_birthday: true) }
|
||||||
|
|
||||||
|
it 'has a birthday field' do
|
||||||
|
expect(rendered).to have_field('Date de naissance')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the demarche asks for the birthdate' do
|
context 'when procedure has for_tiers_enabled' do
|
||||||
let(:procedure) { create(:simple_procedure, for_individual: true, ask_birthday: true) }
|
let(:procedure) { create(:simple_procedure, :for_individual, for_tiers_enabled: false) }
|
||||||
|
|
||||||
it 'has a birthday field' do
|
it 'has choice for you or a tiers' do
|
||||||
expect(rendered).to have_field('Date de naissance')
|
expect(rendered).not_to have_content "Pour vous"
|
||||||
|
expect(rendered).not_to have_content "Pour un bénéficiaire : membre de la famille, proche, mandant, professionnel en charge du suivi du dossier…"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'has identity fields' do
|
||||||
|
within('.individual-infos') do
|
||||||
|
expect(rendered).to have_field(id: 'Prenom')
|
||||||
|
expect(rendered).to have_field(id: 'Nom')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue