Skip to content

Commit 8bdcab5

Browse files
authored
Merge pull request #12932 from demarche-numerique/link_dossier_with_different_state
ETQ Usager, je peux renseigner le numéro d'un dossier supprimé dans les champs dossier-lié
2 parents b8dcf62 + 8878e42 commit 8bdcab5

9 files changed

Lines changed: 137 additions & 20 deletions

File tree

app/components/dsfr/input_status_message_component.rb

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,33 @@ def statut_message
6363
when TypeDeChamp.type_champs[:rna]
6464
{ state: :info, text: t(".rna.data_fetched", title: @champ.title, address: @champ.full_address) }
6565
when TypeDeChamp.type_champs[:dossier_link]
66-
dossier = Dossier.visible_by_administration.find_by(id: @champ.value)
67-
if dossier.present?
68-
{ state: :info, text: dossier.text_summary }
66+
dossier = Dossier.find_by(id: @champ.value)
67+
deleted_dossier = DeletedDossier.find_by(dossier_id: @champ.value) if dossier.nil?
68+
if deleted_dossier.present?
69+
{
70+
state: :info, text: I18n.t('shared.champs.dossier_link.hidden',
71+
depose_at: l(deleted_dossier.depose_at),
72+
procedure_libelle: deleted_dossier.procedure.libelle,
73+
hidden_at: l(deleted_dossier.deleted_at.to_date)),
74+
}
75+
elsif dossier.present?
76+
if dossier.hidden_by_expired_at.present?
77+
{
78+
state: :info, text: I18n.t('shared.champs.dossier_link.expired',
79+
depose_at: l(dossier.depose_at.to_date),
80+
procedure_libelle: dossier.procedure.libelle,
81+
expired_at: l(dossier.hidden_by_expired_at.to_date)),
82+
}
83+
elsif dossier.hidden_by_user_at.present?
84+
{
85+
state: :info, text: I18n.t('shared.champs.dossier_link.hidden',
86+
depose_at: l(dossier.depose_at.to_date),
87+
procedure_libelle: dossier.procedure.libelle,
88+
hidden_at: l(dossier.hidden_by_user_at.to_date)),
89+
}
90+
else
91+
{ state: :info, text: dossier.text_summary }
92+
end
6993
end
7094
when TypeDeChamp.type_champs[:referentiel]
7195
if type_de_champ.referentiel.blank?

app/models/champs/dossier_link_champ.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ class Champs::DossierLinkChamp < Champ
88
private
99

1010
def dossier_exists
11-
if !Dossier.exists?(value)
11+
linked_dossier = Dossier.find_by(id: value)
12+
if linked_dossier.nil? && !DeletedDossier.exists?(dossier_id: value)
1213
errors.add(:value, :not_found)
14+
elsif linked_dossier&.brouillon?
15+
errors.add(:value, :brouillon_not_allowed)
1316
end
1417
end
1518

@@ -20,7 +23,10 @@ def dossier_in_allowed_procedures
2023
allowed_ids = type_de_champ.dossier_link_procedure_ids
2124
return if allowed_ids.empty?
2225

23-
if !Dossier.joins(:revision).exists?(id: value, user: dossier.user, procedure_revisions: { procedure_id: allowed_ids })
26+
dossier_matches = Dossier.joins(:revision).exists?(id: value, user: dossier.user, procedure_revisions: { procedure_id: allowed_ids })
27+
deleted_dossier_matches = DeletedDossier.exists?(dossier_id: value, user_id: dossier.user_id, procedure_id: allowed_ids)
28+
29+
if !dossier_matches && !deleted_dossier_matches
2430
errors.add(:value, :not_in_allowed_procedures)
2531
end
2632
end
Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,31 @@
11
- dossier = Dossier.includes(:procedure).find_by(id: champ.to_s)
2-
- if dossier
3-
- path = dossier_linked_path(current_instructeur || current_user, dossier)
4-
- if path.present?
5-
%p= link_to("Dossier n° #{dossier.id}", path, target: '_blank', rel: 'noopener')
6-
- else
7-
%p Dossier n° #{dossier.id}
2+
- deleted_dossier = dossier.nil? ? DeletedDossier.includes(:procedure).find_by(dossier_id: champ.to_s) : nil
3+
- profile = controller.try(:nav_bar_profile)
4+
- hidden_at = dossier && ((profile == :user && dossier.hidden_by_user_at) || (profile == :instructeur && dossier.hidden_by_administration_at))
5+
- if deleted_dossier
6+
%p Dossier n° #{champ}
87
%br
98
.copy-zone
10-
%p= sanitize(dossier.text_summary)
9+
%p= t('shared.champs.dossier_link.deleted', procedure_libelle: deleted_dossier.procedure&.libelle)
10+
- elsif dossier
11+
- if dossier.hidden_by_expired_at.present?
12+
%p Dossier n° #{dossier.id}
13+
%br
14+
.copy-zone
15+
%p= t('shared.champs.dossier_link.expired', depose_at: l(dossier.depose_at.to_date), procedure_libelle: dossier.procedure.libelle, expired_at: l(dossier.hidden_by_expired_at.to_date))
16+
- elsif hidden_at.present?
17+
%p Dossier n° #{dossier.id}
18+
%br
19+
.copy-zone
20+
%p= t('shared.champs.dossier_link.hidden', depose_at: l(dossier.depose_at.to_date), procedure_libelle: dossier.procedure.libelle, hidden_at: l(hidden_at.to_date))
21+
- else
22+
- path = dossier_linked_path(current_instructeur || current_user, dossier)
23+
- if path.present?
24+
%p= link_to("Dossier n° #{dossier.id}", path, target: '_blank', rel: 'noopener')
25+
- else
26+
%p Dossier n° #{dossier.id}
27+
%br
28+
.copy-zone
29+
%p= sanitize(dossier.text_summary)
1130
- else
1231
%p Pas de dossier associé

config/locales/models/champs/dossier_link_champ/en.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ en:
1111
attributes:
1212
value:
1313
not_found: "File not found"
14+
brouillon_not_allowed: "This file has not been submitted yet"
1415
not_in_allowed_procedures: "This file is not in an allowed procedure"

config/locales/models/champs/dossier_link_champ/fr.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ fr:
1111
attributes:
1212
value:
1313
not_found: "Le dossier n’existe pas"
14+
brouillon_not_allowed: "Le dossier n’a pas encore été déposé"
1415
not_in_allowed_procedures: "Ce dossier n’est pas dans une démarche autorisée"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
en:
3+
shared:
4+
champs:
5+
dossier_link:
6+
hidden: "File submitted on %{depose_at} for the procedure “%{procedure_libelle}” but deleted on %{hidden_at}"
7+
expired: "File submitted on %{depose_at} for the procedure “%{procedure_libelle}” but expired on %{expired_at}"
8+
deleted: "The file referenced at submission for the procedure “%{procedure_libelle}” no longer exists"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
fr:
3+
shared:
4+
champs:
5+
dossier_link:
6+
hidden: "Dossier déposé le %{depose_at} sur la démarche « %{procedure_libelle} » mais supprimé le %{hidden_at}"
7+
expired: "Dossier déposé le %{depose_at} sur la démarche « %{procedure_libelle} » mais expiré le %{expired_at}"
8+
deleted: "Le dossier renseigné lors du dépôt sur la démarche « %{procedure_libelle} » n’existe plus"

spec/components/input_status_message_component_spec.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@
5555
expect(subject).to have_css(".fr-message--info", text: /Dossier/)
5656
end
5757
end
58+
59+
context "when the linked dossier has been hidden by the user" do
60+
let(:linked_dossier) do
61+
create(:dossier, :en_instruction, hidden_by_user_at: Time.zone.local(2026, 3, 15))
62+
end
63+
64+
it "renders the hidden_by_user message" do
65+
expect(subject).to have_css(
66+
".fr-message--info",
67+
text: /Dossier déposé le .* sur la démarche .* mais supprimé le 15 mars 2026/
68+
)
69+
end
70+
end
5871
end
5972

6073
context 'with referentiel champs' do

spec/models/champs/dossier_link_champ_spec.rb

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@
33
describe Champs::DossierLinkChamp, type: :model do
44
let(:types_de_champ_public) { [{ type: :dossier_link, mandatory: }] }
55
let(:procedure) { create(:procedure, types_de_champ_public:) }
6-
let(:dossier) { create(:dossier, procedure:) }
6+
let(:dossier) { create(:dossier, :en_construction, procedure:) }
77
let(:champ) { dossier.champs.first.tap { _1.update(value:) } }
88
let(:value) { nil }
99
let(:mandatory) { false }
1010

1111
describe 'prefilling validations' do
12-
let(:linked_dossier) { create(:dossier) }
12+
let(:linked_dossier) { create(:dossier, :en_construction) }
1313
describe 'value' do
1414
subject { champ.valid?(:prefill) }
1515

@@ -57,14 +57,29 @@
5757
context 'when mandatory' do
5858
let(:mandatory) { true }
5959
context 'when valid id' do
60-
let(:value) { create(:dossier).id }
60+
let(:value) { create(:dossier, :en_construction).id }
6161
it { is_expected.to be_truthy }
6262
end
6363

6464
context 'when invalid id' do
6565
let(:value) { 'kthxbye' }
6666
it { is_expected.to be_falsey }
6767
end
68+
69+
context 'when id of a deleted dossier' do
70+
let(:value) { create(:deleted_dossier).dossier_id }
71+
72+
it { is_expected.to be_truthy }
73+
end
74+
75+
context 'when id of a brouillon dossier' do
76+
let(:value) { create(:dossier).id }
77+
78+
it 'is invalid with brouillon_not_allowed error' do
79+
is_expected.to be_falsey
80+
expect(champ.errors.added?(:value, :brouillon_not_allowed)).to be(true)
81+
end
82+
end
6883
end
6984
end
7085

@@ -85,12 +100,12 @@
85100
end
86101

87102
context 'when dossier belongs to an allowed procedure and to the current user' do
88-
let(:value) { create(:dossier, procedure: allowed_procedure, user:).id }
103+
let(:value) { create(:dossier, :en_construction, procedure: allowed_procedure, user:).id }
89104
it { is_expected.to be_truthy }
90105
end
91106

92107
context 'when dossier does not belong to an allowed procedure' do
93-
let(:value) { create(:dossier, procedure: other_procedure, user:).id }
108+
let(:value) { create(:dossier, :en_construction, procedure: other_procedure, user:).id }
94109

95110
it 'is invalid with correct error message' do
96111
is_expected.to be_falsey
@@ -99,7 +114,29 @@
99114
end
100115

101116
context 'when dossier belongs to another user' do
102-
let(:value) { create(:dossier, procedure: allowed_procedure).id }
117+
let(:value) { create(:dossier, :en_construction, procedure: allowed_procedure).id }
118+
119+
it 'is invalid' do
120+
is_expected.to be_falsey
121+
end
122+
end
123+
124+
context 'when deleted dossier belongs to an allowed procedure and to the current user' do
125+
let(:value) { create(:deleted_dossier, procedure: allowed_procedure, user_id: user.id).dossier_id }
126+
it { is_expected.to be_truthy }
127+
end
128+
129+
context 'when deleted dossier does not belong to an allowed procedure' do
130+
let(:value) { create(:deleted_dossier, procedure: other_procedure, user_id: user.id).dossier_id }
131+
132+
it 'is invalid with correct error message' do
133+
is_expected.to be_falsey
134+
expect(champ.errors.full_messages).to include("Ce dossier n’est pas dans une démarche autorisée")
135+
end
136+
end
137+
138+
context 'when deleted dossier belongs to another user' do
139+
let(:value) { create(:deleted_dossier, procedure: allowed_procedure).dossier_id }
103140

104141
it 'is invalid' do
105142
is_expected.to be_falsey
@@ -111,7 +148,7 @@
111148
type_de_champ.update!(options: type_de_champ.options.merge('procedures_limit' => nil))
112149
end
113150

114-
let(:value) { create(:dossier, procedure: other_procedure, user:).id }
151+
let(:value) { create(:dossier, :en_construction, procedure: other_procedure, user:).id }
115152
it { is_expected.to be_truthy }
116153
end
117154

@@ -120,7 +157,7 @@
120157
type_de_champ.update!(options: type_de_champ.options.merge('dossier_link_procedure_ids' => []))
121158
end
122159

123-
let(:value) { create(:dossier, procedure: other_procedure, user:).id }
160+
let(:value) { create(:dossier, :en_construction, procedure: other_procedure, user:).id }
124161
it { is_expected.to be_truthy }
125162
end
126163
end

0 commit comments

Comments
 (0)