refactor(dossier): cleanup user controller
This commit is contained in:
parent
671d121480
commit
1f5dd3bd02
5 changed files with 92 additions and 92 deletions
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class Dossiers::EditFooterComponent < ApplicationComponent
|
class Dossiers::EditFooterComponent < ApplicationComponent
|
||||||
delegate :can_passer_en_construction?, to: :@dossier
|
delegate :can_passer_en_construction?, :can_transition_to_en_construction?, :forked_with_changes?, to: :@dossier
|
||||||
|
|
||||||
def initialize(dossier:, annotation:)
|
def initialize(dossier:, annotation:)
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
|
@ -18,7 +18,43 @@ class Dossiers::EditFooterComponent < ApplicationComponent
|
||||||
@annotation.present?
|
@annotation.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
def disabled_submit_buttons_options
|
def can_submit?
|
||||||
|
can_submit_draft? || can_submit_en_construction?
|
||||||
|
end
|
||||||
|
|
||||||
|
def can_submit_draft?
|
||||||
|
!annotation? && can_transition_to_en_construction?
|
||||||
|
end
|
||||||
|
|
||||||
|
def can_submit_en_construction?
|
||||||
|
forked_with_changes?
|
||||||
|
end
|
||||||
|
|
||||||
|
def submit_button_label
|
||||||
|
if can_submit_draft?
|
||||||
|
t('.submit')
|
||||||
|
else
|
||||||
|
t('.submit_changes')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def submit_button_path
|
||||||
|
if can_submit_draft?
|
||||||
|
brouillon_dossier_path(@dossier)
|
||||||
|
else
|
||||||
|
modifier_dossier_path(@dossier.editing_fork_origin)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def submit_button_options
|
||||||
|
if can_submit_draft?
|
||||||
|
submit_draft_button_options
|
||||||
|
else
|
||||||
|
submit_en_construction_button_options
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def disabled_submit_button_options
|
||||||
{
|
{
|
||||||
class: 'fr-text--sm fr-mb-0 fr-mr-2w',
|
class: 'fr-text--sm fr-mb-0 fr-mr-2w',
|
||||||
data: { 'fr-opened': "true" },
|
data: { 'fr-opened': "true" },
|
||||||
|
|
|
@ -2,16 +2,10 @@
|
||||||
.send-dossier-actions-bar
|
.send-dossier-actions-bar
|
||||||
= render Dossiers::AutosaveFooterComponent.new(dossier: @dossier, annotation: annotation?)
|
= render Dossiers::AutosaveFooterComponent.new(dossier: @dossier, annotation: annotation?)
|
||||||
|
|
||||||
- if !annotation? && @dossier.can_transition_to_en_construction?
|
- if can_submit?
|
||||||
- if !can_passer_en_construction?
|
- if !can_passer_en_construction?
|
||||||
= link_to t('.submit_disabled'), "#", disabled_submit_buttons_options
|
= link_to t('.submit_disabled'), "#", disabled_submit_button_options
|
||||||
= button_to t('.submit'), brouillon_dossier_url(@dossier), submit_draft_button_options
|
= button_to submit_button_label, submit_button_path, submit_button_options
|
||||||
|
|
||||||
- if @dossier.forked_with_changes?
|
|
||||||
- if !can_passer_en_construction?
|
|
||||||
= link_to t('.submit_disabled'), "#", disabled_submit_buttons_options
|
|
||||||
= button_to t('.submit_changes'), modifier_dossier_url(@dossier.editing_fork_origin), submit_en_construction_button_options
|
|
||||||
|
|
||||||
|
|
||||||
- if @dossier.brouillon? && !owner?
|
- if @dossier.brouillon? && !owner?
|
||||||
.fr-pb-2w.invite-cannot-submit
|
.fr-pb-2w.invite-cannot-submit
|
||||||
|
@ -19,7 +13,5 @@
|
||||||
- c.with_body do
|
- c.with_body do
|
||||||
%p.fr-pb-0= t('.invite_notice').html_safe
|
%p.fr-pb-0= t('.invite_notice').html_safe
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- if !annotation?
|
- if !annotation?
|
||||||
= render partial: "shared/dossiers/submit_is_over", locals: { dossier: @dossier }
|
= render partial: "shared/dossiers/submit_is_over", locals: { dossier: @dossier }
|
||||||
|
|
|
@ -235,10 +235,7 @@ module Users
|
||||||
@dossier.passer_en_construction!
|
@dossier.passer_en_construction!
|
||||||
redirect_to merci_dossier_path(@dossier)
|
redirect_to merci_dossier_path(@dossier)
|
||||||
else
|
else
|
||||||
respond_to do |format|
|
render :brouillon
|
||||||
format.html { render :brouillon }
|
|
||||||
format.turbo_stream
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -256,6 +253,7 @@ module Users
|
||||||
|
|
||||||
def modifier
|
def modifier
|
||||||
@dossier = dossier_with_champs
|
@dossier = dossier_with_champs
|
||||||
|
@dossier_for_editing = dossier.owner_editing_fork
|
||||||
end
|
end
|
||||||
|
|
||||||
def submit_en_construction
|
def submit_en_construction
|
||||||
|
@ -268,29 +266,21 @@ module Users
|
||||||
|
|
||||||
submit_dossier_and_compute_errors
|
submit_dossier_and_compute_errors
|
||||||
|
|
||||||
if @dossier.errors.blank? && @dossier.can_passer_en_construction?
|
if dossier.errors.blank? && dossier.can_passer_en_construction?
|
||||||
editing_fork_origin.merge_fork(@dossier)
|
editing_fork_origin.merge_fork(dossier)
|
||||||
editing_fork_origin.submit_en_construction!
|
editing_fork_origin.submit_en_construction!
|
||||||
|
|
||||||
redirect_to dossier_path(editing_fork_origin)
|
redirect_to dossier_path(editing_fork_origin)
|
||||||
else
|
else
|
||||||
respond_to do |format|
|
@dossier_for_editing = dossier
|
||||||
format.html do
|
@dossier = editing_fork_origin
|
||||||
render :modifier
|
render :modifier
|
||||||
end
|
|
||||||
|
|
||||||
format.turbo_stream do
|
|
||||||
@to_show, @to_hide, @to_update = champs_to_turbo_update(champs_public_attributes_params, dossier.champs.filter(&:public?))
|
|
||||||
render :update, layout: false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
@dossier = dossier.en_construction? ? dossier.find_editing_fork(dossier.user) : dossier
|
@dossier = dossier.en_construction? ? dossier.find_editing_fork(dossier.user) : dossier
|
||||||
@dossier = dossier_with_champs(pj_template: false)
|
@dossier = dossier_with_champs(pj_template: false)
|
||||||
@can_passer_en_construction_was, @can_passer_en_construction_is = @dossier.track_can_passer_en_construction do
|
@can_passer_en_construction_was, @can_passer_en_construction_is = dossier.track_can_passer_en_construction do
|
||||||
update_dossier_and_compute_errors
|
update_dossier_and_compute_errors
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -308,8 +298,8 @@ module Users
|
||||||
|
|
||||||
def champ
|
def champ
|
||||||
@dossier = dossier_with_champs(pj_template: false)
|
@dossier = dossier_with_champs(pj_template: false)
|
||||||
type_de_champ = @dossier.find_type_de_champ_by_stable_id(params[:stable_id], :public)
|
type_de_champ = dossier.find_type_de_champ_by_stable_id(params[:stable_id], :public)
|
||||||
champ = @dossier.project_champ(type_de_champ, params[:row_id])
|
champ = dossier.project_champ(type_de_champ, params[:row_id])
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.turbo_stream do
|
format.turbo_stream do
|
||||||
|
@ -543,36 +533,34 @@ module Users
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_dossier_and_compute_errors
|
def update_dossier_and_compute_errors
|
||||||
@dossier.update_champs_attributes(champs_public_attributes_params, :public, updated_by: current_user.email)
|
dossier.update_champs_attributes(champs_public_attributes_params, :public, updated_by: current_user.email)
|
||||||
updated_champs = @dossier.champs.filter(&:changed_for_autosave?)
|
updated_champs = dossier.champs.filter(&:changed_for_autosave?)
|
||||||
if updated_champs.present?
|
|
||||||
@dossier.last_champ_updated_at = Time.zone.now
|
|
||||||
end
|
|
||||||
|
|
||||||
# We save the dossier without validating fields, and if it is successful and the client
|
# We save the dossier without validating fields, and if it is successful and the client
|
||||||
# requests it, we ask for field validation errors.
|
# requests it, we ask for field validation errors.
|
||||||
if @dossier.save
|
if dossier.save
|
||||||
if updated_champs.any?(&:used_by_routing_rules?)
|
if dossier.brouillon? && updated_champs.present?
|
||||||
@update_contact_information = true
|
dossier.touch(:last_champ_updated_at)
|
||||||
RoutingEngine.compute(@dossier)
|
if updated_champs.any?(&:used_by_routing_rules?)
|
||||||
|
@update_contact_information = true
|
||||||
|
RoutingEngine.compute(dossier)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if params[:validate].present?
|
if params[:validate].present?
|
||||||
@dossier.valid?(:champs_public_value)
|
dossier.valid?(:champs_public_value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@dossier.errors
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def submit_dossier_and_compute_errors
|
def submit_dossier_and_compute_errors
|
||||||
@dossier.validate(:champs_public_value)
|
dossier.validate(:champs_public_value)
|
||||||
@dossier.check_mandatory_and_visible_champs
|
dossier.check_mandatory_and_visible_champs
|
||||||
|
|
||||||
if @dossier.editing_fork_origin&.pending_correction?
|
if dossier.editing_fork_origin&.pending_correction?
|
||||||
@dossier.editing_fork_origin.validate(:champs_public_value)
|
dossier.editing_fork_origin.validate(:champs_public_value)
|
||||||
@dossier.editing_fork_origin.errors.where(:pending_correction).each do |error|
|
dossier.editing_fork_origin.errors.where(:pending_correction).each do |error|
|
||||||
@dossier.errors.import(error)
|
dossier.errors.import(error)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,12 +26,6 @@ module DossierCloneConcern
|
||||||
find_or_create_editing_fork(user).tap { DossierPreloader.load_one(_1) }
|
find_or_create_editing_fork(user).tap { DossierPreloader.load_one(_1) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def reset_editing_fork!
|
|
||||||
if editing_fork? && forked_with_changes?
|
|
||||||
destroy_editing_fork!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy_editing_fork!
|
def destroy_editing_fork!
|
||||||
if editing_fork?
|
if editing_fork?
|
||||||
update!(hidden_by_administration_at: Time.current, hidden_by_reason: :stale_fork)
|
update!(hidden_by_administration_at: Time.current, hidden_by_reason: :stale_fork)
|
||||||
|
@ -43,6 +37,18 @@ module DossierCloneConcern
|
||||||
editing_fork_origin_id.present?
|
editing_fork_origin_id.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def forked_with_changes?
|
||||||
|
if forked_diff.present?
|
||||||
|
forked_diff.values.any?(&:present?) || forked_groupe_instructeur_changed?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def champ_forked_with_changes?(champ)
|
||||||
|
if forked_diff.present?
|
||||||
|
forked_diff.values.any? { |champs| champs.any? { _1.public_id == champ.public_id } }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def make_diff(editing_fork)
|
def make_diff(editing_fork)
|
||||||
origin_champs_index = project_champs_public_all.index_by(&:public_id)
|
origin_champs_index = project_champs_public_all.index_by(&:public_id)
|
||||||
forked_champs_index = editing_fork.project_champs_public_all.index_by(&:public_id)
|
forked_champs_index = editing_fork.project_champs_public_all.index_by(&:public_id)
|
||||||
|
@ -126,18 +132,6 @@ module DossierCloneConcern
|
||||||
cloned_dossier.reload
|
cloned_dossier.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
def forked_with_changes?
|
|
||||||
if forked_diff.present?
|
|
||||||
forked_diff.values.any?(&:present?) || forked_groupe_instructeur_changed?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def champ_forked_with_changes?(champ)
|
|
||||||
if forked_diff.present?
|
|
||||||
forked_diff.values.any? { _1.include?(champ) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def forked_diff
|
def forked_diff
|
||||||
|
|
|
@ -836,10 +836,11 @@ describe Users::DossiersController, type: :controller do
|
||||||
before { sign_in(user) }
|
before { sign_in(user) }
|
||||||
|
|
||||||
let(:procedure) { create(:procedure, :published, types_de_champ_public: [{}, { type: :piece_justificative }]) }
|
let(:procedure) { create(:procedure, :published, types_de_champ_public: [{}, { type: :piece_justificative }]) }
|
||||||
let!(:dossier) { create(:dossier, :en_construction, user:, procedure:) }
|
let(:dossier) { create(:dossier, :en_construction, user:, procedure:) }
|
||||||
let(:first_champ) { dossier.project_champs_public.first }
|
let!(:editing_fork) { dossier.owner_editing_fork }
|
||||||
|
let(:first_champ) { editing_fork.project_champs_public.first }
|
||||||
|
let(:piece_justificative_champ) { editing_fork.project_champs_public.last }
|
||||||
let(:anchor_to_first_champ) { controller.helpers.link_to I18n.t('views.users.dossiers.fix_champ'), brouillon_dossier_path(anchor: first_champ.labelledby_id), class: 'error-anchor' }
|
let(:anchor_to_first_champ) { controller.helpers.link_to I18n.t('views.users.dossiers.fix_champ'), brouillon_dossier_path(anchor: first_champ.labelledby_id), class: 'error-anchor' }
|
||||||
let(:piece_justificative_champ) { dossier.project_champs_public.last }
|
|
||||||
let(:value) { 'beautiful value' }
|
let(:value) { 'beautiful value' }
|
||||||
let(:file) { fixture_file_upload('spec/fixtures/files/piece_justificative_0.pdf', 'application/pdf') }
|
let(:file) { fixture_file_upload('spec/fixtures/files/piece_justificative_0.pdf', 'application/pdf') }
|
||||||
let(:now) { Time.zone.parse('01/01/2100') }
|
let(:now) { Time.zone.parse('01/01/2100') }
|
||||||
|
@ -887,14 +888,9 @@ describe Users::DossiersController, type: :controller do
|
||||||
|
|
||||||
it 'updates the dossier timestamps' do
|
it 'updates the dossier timestamps' do
|
||||||
subject
|
subject
|
||||||
dossier.reload
|
editing_fork.reload
|
||||||
expect(dossier.updated_at).to eq(now)
|
expect(editing_fork.updated_at).to eq(now)
|
||||||
expect(dossier.last_champ_updated_at).to eq(now)
|
expect(editing_fork.last_champ_updated_at).to eq(now)
|
||||||
end
|
|
||||||
|
|
||||||
it 'updates the dossier state' do
|
|
||||||
subject
|
|
||||||
expect(dossier.reload.state).to eq(Dossier.states.fetch(:en_construction))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it { is_expected.to have_http_status(:ok) }
|
it { is_expected.to have_http_status(:ok) }
|
||||||
|
@ -923,9 +919,9 @@ describe Users::DossiersController, type: :controller do
|
||||||
|
|
||||||
it 'updates the dossier timestamps' do
|
it 'updates the dossier timestamps' do
|
||||||
subject
|
subject
|
||||||
dossier.reload
|
editing_fork.reload
|
||||||
expect(dossier.updated_at).to eq(now)
|
expect(editing_fork.updated_at).to eq(now)
|
||||||
expect(dossier.last_champ_updated_at).to eq(now)
|
expect(editing_fork.last_champ_updated_at).to eq(now)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -958,14 +954,10 @@ describe Users::DossiersController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'iban error' do
|
context 'iban error' do
|
||||||
|
let(:types_de_champ_public) { [{ type: :iban }] }
|
||||||
let(:value) { 'abc' }
|
let(:value) { 'abc' }
|
||||||
|
|
||||||
before do
|
before { subject }
|
||||||
first_champ.type_de_champ.update!(type_champ: :iban, mandatory: true, libelle: 'l')
|
|
||||||
dossier.project_champs_public.first.becomes!(Champs::IbanChamp).save!
|
|
||||||
|
|
||||||
subject
|
|
||||||
end
|
|
||||||
|
|
||||||
it { expect(response).to have_http_status(:success) }
|
it { expect(response).to have_http_status(:success) }
|
||||||
end
|
end
|
||||||
|
@ -998,9 +990,7 @@ describe Users::DossiersController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the champ is a phone number' do
|
context 'when the champ is a phone number' do
|
||||||
let(:procedure) { create(:procedure, :published, types_de_champ_public: [{ type: :phone }]) }
|
let(:types_de_champ_public) { [{ type: :phone }] }
|
||||||
let!(:dossier) { create(:dossier, :en_construction, user:, procedure:) }
|
|
||||||
let(:first_champ) { dossier.project_champs_public.first }
|
|
||||||
let(:now) { Time.zone.parse('01/01/2100') }
|
let(:now) { Time.zone.parse('01/01/2100') }
|
||||||
|
|
||||||
let(:submit_payload) do
|
let(:submit_payload) do
|
||||||
|
|
Loading…
Reference in a new issue