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:
Colin Darie 2023-11-27 13:52:06 +00:00 committed by GitHub
commit 15ff65429b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 175 additions and 53 deletions

View file

@ -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?

View file

@ -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

View file

@ -0,0 +1,3 @@
---
en:
confirm_label: I certify that I have made all corrections requested by the administration.

View file

@ -0,0 +1,3 @@
---
fr:
confirm_label: Je certifie avoir effectué toutes les corrections demandées par ladministration.

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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)

View file

@ -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"

View file

@ -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 ladministration.
messages:
form:
send_message: "Envoyer le message"

View file

@ -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.

View file

@ -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."

View file

@ -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

View file

@ -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