Merge pull request #7789 from betagouv/fix-instructeurs-dossier-termine-incomplet

Fix(dossier): don't accept/reject  ith an incomplete etablissement (degraded mode)
This commit is contained in:
Colin Darie 2022-09-21 16:07:29 +02:00 committed by GitHub
commit a90c5f1d74
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 110 additions and 8 deletions

View file

@ -308,6 +308,8 @@ module Instructeurs
def aasm_error_message(exception, target_state:)
if exception.originating_state == target_state
"Le dossier est déjà #{dossier_display_state(target_state, lower: true)}."
elsif exception.failures.include?(:can_terminer?)
"Les données relatives au SIRET de ce dossier nont pas pu encore être vérifiées : il nest pas possible de le passer #{dossier_display_state(target_state, lower: true)}."
else
"Le dossier est en ce moment #{dossier_display_state(exception.originating_state, lower: true)} : il nest pas possible de le passer #{dossier_display_state(target_state, lower: true)}."
end

View file

@ -170,19 +170,19 @@ class Dossier < ApplicationRecord
end
event :accepter, after: :after_accepter do
transitions from: :en_instruction, to: :accepte
transitions from: :en_instruction, to: :accepte, guard: :can_terminer?
end
event :accepter_automatiquement, after: :after_accepter_automatiquement do
transitions from: :en_construction, to: :accepte
transitions from: :en_construction, to: :accepte, guard: :can_terminer?
end
event :refuser, after: :after_refuser do
transitions from: :en_instruction, to: :refuse
transitions from: :en_instruction, to: :refuse, guard: :can_terminer?
end
event :classer_sans_suite, after: :after_classer_sans_suite do
transitions from: :en_instruction, to: :sans_suite
transitions from: :en_instruction, to: :sans_suite, guard: :can_terminer?
end
event :repasser_en_instruction, after: :after_repasser_en_instruction do
@ -515,6 +515,12 @@ class Dossier < ApplicationRecord
brouillon? && procedure.dossier_can_transition_to_en_construction? && !for_procedure_preview?
end
def can_terminer?
return false if etablissement&.as_degraded_mode?
true
end
def can_repasser_en_instruction?
termine? && !user_deleted?
end

View file

@ -2,4 +2,17 @@
= render partial: "header", locals: { dossier: @dossier }
- if @dossier.etablissement&.as_degraded_mode?
.container
= render Dsfr::CalloutComponent.new(title: "Données de lentreprise non vérifiées", theme: :warning, icon: "fr-icon-feedback-fill") do |c|
- c.with_body do
%p
Les services de lINSEE sont indisponibles, nous ne pouvons pas
vérifier les informations liées à létablissement de ce dossier.
%strong Il nest pas possible daccepter ou de refuser un dossier sans cette étape.
%br
%br
Les informations sur l'entreprise arriveront dici quelques heures.
= render partial: "shared/dossiers/demande", locals: { dossier: @dossier, demande_seen_at: @demande_seen_at, profile: 'instructeur' }

View file

@ -2,7 +2,7 @@
%table.table.vertical.dossier-champs
%tbody
%tr
%td.libelle{ colspan: 2 } ⚠ LʼINSEE est indisponible, les informations sur lʼentreprise arriveront dʼici quelques jours.
%td.libelle{ colspan: 2 } ⚠ LʼINSEE est indisponible, les informations sur lʼentreprise arriveront dʼici quelques heures.
%tr
%td.libelle SIRET :
%td= etablissement.siret

View file

@ -388,6 +388,24 @@ describe Instructeurs::DossiersController, type: :controller do
end
end
context 'when related etablissement is still in degraded_mode' do
let(:procedure) { create(:procedure, :published, for_individual: false, instructeurs: instructeurs) }
let(:dossier) { create(:dossier, :en_instruction, :with_entreprise, procedure: procedure, as_degraded_mode: true) }
subject { post :terminer, params: { process_action: "accepter", procedure_id: procedure.id, dossier_id: dossier.id }, format: :turbo_stream }
context "with accepter" do
it 'warns about the error' do
subject
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:en_instruction))
expect(response).to have_http_status(:ok)
expect(response.body).to match(/Les données relatives au SIRET .+ de le passer accepté/)
end
end
end
context 'when a dossier is already closed' do
let(:dossier) { create(:dossier, :accepte, procedure: procedure) }

View file

@ -18,12 +18,22 @@ FactoryBot.define do
end
trait :with_entreprise do
after(:build) do |dossier, _evaluator|
transient do
as_degraded_mode { false }
end
after(:build) do |dossier, evaluator|
if dossier.procedure.for_individual?
raise 'Inconsistent factory: attempting to create a dossier :with_entreprise on a procedure that is `for_individual?`'
end
etablissement = create(:etablissement, :with_exercices, :with_effectif_mensuel)
dossier.etablissement = etablissement
etablissement = if evaluator.as_degraded_mode
Etablissement.new(siret: build(:etablissement).siret)
else
create(:etablissement, :with_exercices, :with_effectif_mensuel)
end
dossier.update(etablissement:)
end
end

View file

@ -1138,6 +1138,41 @@ describe Dossier do
it { expect(operation_serialized['executed_at']).to eq(last_operation.executed_at.iso8601) }
end
describe "can't transition to terminer when etablissement is in degraded mode" do
let(:instructeur) { create(:instructeur) }
let(:motivation) { 'motivation' }
context "when dossier is en_instruction" do
let(:dossier_incomplete) { create(:dossier, :en_instruction, :with_entreprise, as_degraded_mode: true) }
let(:dossier_ok) { create(:dossier, :en_instruction, :with_entreprise, as_degraded_mode: false) }
it "can't accepter" do
expect(dossier_incomplete.may_accepter?(instructeur:, motivation:)).to be_falsey
expect(dossier_ok.accepter(instructeur:, motivation:)).to be_truthy
end
it "can't refuser" do
expect(dossier_incomplete.may_refuser?(instructeur:, motivation:)).to be_falsey
expect(dossier_ok.may_refuser?(instructeur:, motivation:)).to be_truthy
end
it "can't classer_sans_suite" do
expect(dossier_incomplete.may_classer_sans_suite?(instructeur:, motivation:)).to be_falsey
expect(dossier_ok.may_classer_sans_suite?(instructeur:, motivation:)).to be_truthy
end
end
context "when dossier is en_construction" do
let(:dossier_incomplete) { create(:dossier, :en_construction, :with_entreprise, as_degraded_mode: true) }
let(:dossier_ok) { create(:dossier, :en_construction, :with_entreprise, as_degraded_mode: false) }
it "can't accepter_automatiquement" do
expect(dossier_incomplete.may_accepter_automatiquement?(instructeur:, motivation:)).to be_falsey
expect(dossier_ok.accepter_automatiquement(instructeur:, motivation:)).to be_truthy
end
end
end
describe "#check_mandatory_champs" do
include Logic

View file

@ -33,4 +33,22 @@ describe 'instructeurs/dossiers/show.html.haml', type: :view do
expect(rendered).to have_text("Le dossier a été déposé par le compte de #{france_connect_information.given_name} #{france_connect_information.family_name}, authentifié par France Connect le #{france_connect_information.updated_at.strftime('%d/%m/%Y')}")
end
end
describe 'entreprise degraded mode' do
context 'etablissement complete' do
let(:dossier) { create(:dossier, :en_construction, :with_entreprise, as_degraded_mode: false) }
it 'contains no warning' do
expect(rendered).not_to have_text("Les services de lINSEE sont indisponibles")
end
end
context 'etablissement in degraded mode' do
let(:dossier) { create(:dossier, :en_construction, :with_entreprise, as_degraded_mode: true) }
it 'warns the instructeur' do
expect(rendered).to have_text("Les services de lINSEE sont indisponibles")
end
end
end
end