Merge pull request #9738 from colinux/validate-pending-correction
ETQ usager modifiant un dossier en construction je n'ai plus besoin de cocher la case de correction effectuée
This commit is contained in:
commit
15ff65429b
15 changed files with 175 additions and 53 deletions
|
@ -12,12 +12,18 @@ class Dossiers::ErrorsFullMessagesComponent < ApplicationComponent
|
|||
formated_errors = @errors.to_enum # ActiveModel::Errors.to_a is an alias to full_messages, we don't want that
|
||||
.to_a # but enum.to_a gives back an array
|
||||
.uniq { |error| [error.inner_error.base] } # dedup cumulated errors from dossier.champs, dossier.champs_public, dossier.champs_private which run the validator one time per association
|
||||
.map { |error| to_error_descriptor(error.message, error.inner_error.base) }
|
||||
.map { |error| to_error_descriptor(error) }
|
||||
yield(Array(formated_errors[0..2]), Array(formated_errors[3..]))
|
||||
end
|
||||
|
||||
def to_error_descriptor(str_error, model)
|
||||
ErrorDescriptor.new("##{model.labelledby_id}", model.libelle.truncate(200), str_error)
|
||||
def to_error_descriptor(error)
|
||||
model = error.inner_error.base
|
||||
|
||||
if model.respond_to?(:libelle) # a Champ or something acting as a Champ
|
||||
ErrorDescriptor.new("##{model.labelledby_id}", model.libelle.truncate(200), error.message)
|
||||
else
|
||||
ErrorDescriptor.new("##{model.model_name.singular}_#{error.attribute}", model.class.human_attribute_name(error.attribute), error.message)
|
||||
end
|
||||
end
|
||||
|
||||
def render?
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Dossiers::PendingCorrectionCheckboxComponent < ApplicationComponent
|
||||
attr_reader :dossier
|
||||
|
||||
# Pass the editing fork origin, ie. dossier en construction holding the correction
|
||||
def initialize(dossier:)
|
||||
@dossier = dossier
|
||||
end
|
||||
|
||||
def render?
|
||||
return false unless dossier.procedure.sva_svr_enabled?
|
||||
|
||||
dossier.pending_correction?
|
||||
end
|
||||
|
||||
def error? = dossier.errors.include?(:pending_correction)
|
||||
|
||||
def error_message
|
||||
dossier.errors.generate_message(:pending_correction, :blank)
|
||||
end
|
||||
|
||||
def check_box_aria_attributes
|
||||
return unless error?
|
||||
|
||||
{ describedby: :dossier_pending_correction_error_messages }
|
||||
end
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
en:
|
||||
confirm_label: I certify that I have made all corrections requested by the administration.
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
fr:
|
||||
confirm_label: Je certifie avoir effectué toutes les corrections demandées par l’administration.
|
|
@ -0,0 +1,10 @@
|
|||
.fr-checkbox-group.fr-my-3w{ class: class_names("fr-checkbox-group--error" => error?) }
|
||||
= check_box_tag field_name(:dossier, :pending_correction), "1", false, form: "form-submit-en-construction", required: true, aria: check_box_aria_attributes
|
||||
%label.fr-label{ for: :dossier_pending_correction }
|
||||
= t('.confirm_label')
|
||||
= render EditableChamp::AsteriskMandatoryComponent.new
|
||||
|
||||
- if error?
|
||||
#dossier_pending_correction_error_messages.fr-messages-group{ aria: { live: "assertlive" } }
|
||||
%p.fr-message.fr-message--error= error_message
|
||||
|
|
@ -250,19 +250,23 @@ module Users
|
|||
|
||||
def submit_en_construction
|
||||
@dossier = dossier_with_champs(pj_template: false)
|
||||
editing_fork_origin = @dossier.editing_fork_origin
|
||||
|
||||
if cast_bool(params.dig(:dossier, :pending_correction))
|
||||
editing_fork_origin.resolve_pending_correction
|
||||
end
|
||||
|
||||
@errors = submit_dossier_and_compute_errors
|
||||
|
||||
if @errors.blank?
|
||||
pending_correction_confirm = cast_bool(params.dig(:dossier, :pending_correction_confirm))
|
||||
editing_fork_origin = @dossier.editing_fork_origin
|
||||
editing_fork_origin.merge_fork(@dossier)
|
||||
editing_fork_origin.submit_en_construction!(pending_correction_confirm:)
|
||||
editing_fork_origin.submit_en_construction!
|
||||
|
||||
redirect_to dossier_path(editing_fork_origin)
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html do
|
||||
@dossier = @dossier.editing_fork_origin
|
||||
@dossier = editing_fork_origin
|
||||
render :modifier
|
||||
end
|
||||
|
||||
|
@ -537,10 +541,18 @@ module Users
|
|||
@dossier.validate(:champs_public_value)
|
||||
|
||||
errors = @dossier.errors
|
||||
@dossier.check_mandatory_and_visible_champs.map do |error_on_champ|
|
||||
@dossier.check_mandatory_and_visible_champs.each do |error_on_champ|
|
||||
errors.import(error_on_champ)
|
||||
end
|
||||
|
||||
if @dossier.editing_fork_origin&.pending_correction?
|
||||
@dossier.editing_fork_origin.validate(:champs_public_value)
|
||||
@dossier.editing_fork_origin.errors.where(:pending_correction).each do |error|
|
||||
errors.import(error)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
errors
|
||||
end
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ module DossierCorrectableConcern
|
|||
|
||||
scope :with_pending_corrections, -> { joins(:corrections).where(corrections: { resolved_at: nil }) }
|
||||
|
||||
validate :validate_pending_correction, on: :champs_public_value
|
||||
|
||||
def flag_as_pending_correction!(commentaire, reason = nil)
|
||||
return unless may_flag_as_pending_correction?
|
||||
|
||||
|
@ -38,11 +40,26 @@ module DossierCorrectableConcern
|
|||
pending_corrections.exists?
|
||||
end
|
||||
|
||||
def resolve_pending_correction
|
||||
return if pending_correction.nil?
|
||||
|
||||
pending_correction.resolved_at = Time.current
|
||||
end
|
||||
|
||||
def resolve_pending_correction!
|
||||
pending_corrections.update!(resolved_at: Time.current)
|
||||
resolve_pending_correction
|
||||
pending_correction&.save!
|
||||
|
||||
pending_corrections.reset
|
||||
end
|
||||
|
||||
def validate_pending_correction
|
||||
return unless procedure.sva_svr_enabled?
|
||||
return if pending_correction.nil? || pending_correction.resolved?
|
||||
|
||||
errors.add(:pending_correction, :blank)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def log_pending_correction_operation(commentaire, reason)
|
||||
|
|
|
@ -888,16 +888,14 @@ class Dossier < ApplicationRecord
|
|||
RoutingEngine.compute(self)
|
||||
end
|
||||
|
||||
def submit_en_construction!(pending_correction_confirm: false)
|
||||
def submit_en_construction!
|
||||
self.traitements.submit_en_construction
|
||||
save!
|
||||
|
||||
RoutingEngine.compute(self)
|
||||
|
||||
if pending_correction_confirm
|
||||
resolve_pending_correction!
|
||||
process_sva_svr!
|
||||
end
|
||||
resolve_pending_correction!
|
||||
process_sva_svr!
|
||||
end
|
||||
|
||||
def after_passer_en_instruction(h)
|
||||
|
|
|
@ -24,10 +24,6 @@
|
|||
|
||||
= render EditableChamp::SectionComponent.new(champs: dossier_for_editing.champs_public)
|
||||
|
||||
- if dossier.pending_correction?
|
||||
.fr-checkbox-group.fr-my-3w
|
||||
= check_box_tag field_name(:dossier, :pending_correction_confirm), "1", false, form: "form-submit-en-construction"
|
||||
%label.fr-label{ for: :dossier_pending_correction_confirm }= t('views.shared.dossiers.edit.pending_correction.confirm_label')
|
||||
|
||||
= render Dossiers::PendingCorrectionCheckboxComponent.new(dossier: dossier)
|
||||
|
||||
= render Dossiers::EditFooterComponent.new(dossier: dossier_for_editing, annotation: false)
|
||||
|
|
|
@ -333,8 +333,6 @@ en:
|
|||
updated_at: "Updated on %{datetime}"
|
||||
edit:
|
||||
autosave: Your file is automatically saved after each modification. You can close the window at any time and pick up where you left off later.
|
||||
pending_correction:
|
||||
confirm_label: I certify that I have made all corrections requested by the administration.
|
||||
messages:
|
||||
form:
|
||||
send_message: "Send message"
|
||||
|
|
|
@ -333,8 +333,6 @@ fr:
|
|||
updated_at: "Modifié le %{datetime}"
|
||||
edit:
|
||||
autosave: Votre dossier est enregistré automatiquement après chaque modification. Vous pouvez à tout moment fermer la fenêtre et reprendre plus tard là où vous en étiez.
|
||||
pending_correction:
|
||||
confirm_label: Je certifie avoir effectué toutes les corrections demandées par l’administration.
|
||||
messages:
|
||||
form:
|
||||
send_message: "Envoyer le message"
|
||||
|
|
|
@ -8,6 +8,7 @@ en:
|
|||
dossier:
|
||||
id: "File number"
|
||||
state: "State"
|
||||
pending_correction: Requested correction
|
||||
dossier/state: &state
|
||||
brouillon: "Draft"
|
||||
en_construction: "In progress"
|
||||
|
@ -24,3 +25,9 @@ en:
|
|||
state: "State"
|
||||
traitement/state:
|
||||
<<: *state
|
||||
errors:
|
||||
models:
|
||||
dossier:
|
||||
attributes:
|
||||
pending_correction:
|
||||
blank: Check to confirm that you have made the requested corrections.
|
||||
|
|
|
@ -12,6 +12,7 @@ fr:
|
|||
date_previsionnelle: "La date de début prévisionnelle"
|
||||
state: "État"
|
||||
autorisation_donnees: Acceptation des CGU
|
||||
pending_correction: Demande de correction
|
||||
dossier/state: &state
|
||||
brouillon: "Brouillon"
|
||||
en_construction: "En construction"
|
||||
|
@ -28,3 +29,9 @@ fr:
|
|||
state: "État"
|
||||
traitement/state:
|
||||
<<: *state
|
||||
errors:
|
||||
models:
|
||||
dossier:
|
||||
attributes:
|
||||
pending_correction:
|
||||
blank: "Cochez la case indiquant avoir effectué les corrections demandées."
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
RSpec.describe Dossiers::PendingCorrectionCheckboxComponent, type: :component do
|
||||
subject { render_inline(described_class.new(dossier:)) }
|
||||
|
||||
let(:procedure) { create(:procedure) }
|
||||
let(:dossier) { create(:dossier, :en_construction, procedure:) }
|
||||
|
||||
context 'when dossier has no pending correction' do
|
||||
it 'renders nothing' do
|
||||
expect(subject.to_html).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'when dossier has pending correction' do
|
||||
before do
|
||||
create(:dossier_correction, dossier:)
|
||||
end
|
||||
|
||||
it 'renders nothing' do
|
||||
expect(subject.to_html).to be_empty
|
||||
end
|
||||
|
||||
context 'when procedure is sva' do
|
||||
let(:procedure) { create(:procedure, :sva) }
|
||||
|
||||
it 'renders a checkbox' do
|
||||
expect(subject).to have_selector('input[type="checkbox"][name="dossier[pending_correction]"]')
|
||||
end
|
||||
|
||||
context 'when there are error on checkbox' do
|
||||
before do
|
||||
dossier.errors.add(:pending_correction, :blank)
|
||||
end
|
||||
|
||||
it 'renders the error' do
|
||||
expect(subject).to have_content("Cochez la case")
|
||||
expect(subject).to have_selector('.fr-checkbox-group--error')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -567,50 +567,46 @@ describe Users::DossiersController, type: :controller do
|
|||
context "when there are pending correction" do
|
||||
let!(:correction) { create(:dossier_correction, dossier: dossier) }
|
||||
|
||||
subject { post :submit_en_construction, params: { id: dossier.id, dossier: { pending_correction_confirm: "1" } } }
|
||||
subject { post :submit_en_construction, params: { id: dossier.id } }
|
||||
|
||||
it "resolve correction" do
|
||||
it "resolves correction automatically" do
|
||||
expect { subject }.to change { correction.reload.resolved_at }.to be_truthy
|
||||
end
|
||||
|
||||
context 'when procedure has sva enabled' do
|
||||
let(:procedure) { create(:procedure, :sva) }
|
||||
let!(:dossier) { create(:dossier, :en_construction, procedure:, user:) }
|
||||
let(:dossier) { create(:dossier, :en_construction, procedure:, user:) }
|
||||
let!(:correction) { create(:dossier_correction, dossier: dossier) }
|
||||
|
||||
it 'passe automatiquement en instruction' do
|
||||
expect(dossier.pending_correction?).to be_truthy
|
||||
subject { post :submit_en_construction, params: { id: dossier.id, dossier: { pending_correction: pending_correction_value } } }
|
||||
|
||||
subject
|
||||
dossier.reload
|
||||
context 'when resolving correction' do
|
||||
let(:pending_correction_value) { "1" }
|
||||
it 'passe automatiquement en instruction' do
|
||||
expect(dossier.pending_correction?).to be_truthy
|
||||
|
||||
expect(dossier).to be_en_instruction
|
||||
expect(dossier.pending_correction?).to be_falsey
|
||||
expect(dossier.en_instruction_at).to within(5.seconds).of(Time.current)
|
||||
subject
|
||||
dossier.reload
|
||||
|
||||
expect(dossier).to be_en_instruction
|
||||
expect(dossier.pending_correction?).to be_falsey
|
||||
expect(dossier.en_instruction_at).to within(5.seconds).of(Time.current)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is sva without confirming correction' do
|
||||
let!(:correction) { create(:dossier_correction, dossier: dossier) }
|
||||
context 'when not resolving correction' do
|
||||
render_views
|
||||
|
||||
subject { post :submit_en_construction, params: { id: dossier.id } }
|
||||
let(:pending_correction_value) { "" }
|
||||
it 'does not passe automatiquement en instruction' do
|
||||
subject
|
||||
dossier.reload
|
||||
|
||||
it "does not resolve correction" do
|
||||
expect { subject }.not_to change { correction.reload.resolved_at }
|
||||
end
|
||||
expect(dossier).to be_en_construction
|
||||
expect(dossier.pending_correction?).to be_truthy
|
||||
|
||||
context 'when procedure has sva enabled' do
|
||||
let(:procedure) { create(:procedure, :sva) }
|
||||
let!(:dossier) { create(:dossier, :en_construction, procedure:, user:) }
|
||||
|
||||
it 'does not passe automatiquement en instruction' do
|
||||
expect(dossier.pending_correction?).to be_truthy
|
||||
|
||||
subject
|
||||
dossier.reload
|
||||
|
||||
expect(dossier).to be_en_construction
|
||||
expect(dossier.pending_correction?).to be_truthy
|
||||
expect(response.body).to include("Cochez la case")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue