feat(dossiers/show): enhance header with expirations message/banner. also ensure consistent design between dossier states

fix(spec): broken due to last refactoring

spec(dossier.extend_conservation): add system spec

lint(ruby): still not yet ready for auto lint in IDE...
This commit is contained in:
Martin 2021-11-22 14:51:52 +01:00
parent 2a87b9bf89
commit b6adf5fc72
13 changed files with 164 additions and 38 deletions

View file

@ -98,6 +98,11 @@ module DossierHelper
end end
end end
def safe_expiration_date(dossier)
date = dossier.expiration_date.presence || dossier.approximative_expiration_date
l(date, format: '%d/%m/%Y')
end
def annuaire_link(siren) def annuaire_link(siren)
base_url = "https://annuaire-entreprises.data.gouv.fr" base_url = "https://annuaire-entreprises.data.gouv.fr"
return base_url if siren.blank? return base_url if siren.blank?

View file

@ -539,20 +539,32 @@ class Dossier < ApplicationRecord
!brouillon? && !user_deleted? && !archived !brouillon? && !user_deleted? && !archived
end end
def close_to_expiration_at def expirable?
[brouillon?, en_construction?, termine?].any?
end
def approximative_expiration_date_reference
if brouillon? if brouillon?
created_at created_at
elsif en_construction? elsif en_construction?
en_construction_at en_construction_at
elsif en_instruction? elsif termine?
en_instruction_at
else
processed_at processed_at
end + conservation_extension + procedure.duree_conservation_dossiers_dans_ds.months - REMAINING_WEEKS_BEFORE_EXPIRATION.weeks else
fail "approximative_expiration_date_reference should not be called in state #{self.state}"
end
end end
def duration_after_notice def approximative_expiration_date
MONTHS_AFTER_EXPIRATION.month + DAYS_AFTER_EXPIRATION.days [
approximative_expiration_date_reference,
conservation_extension,
procedure.duree_conservation_dossiers_dans_ds.months
].sum - REMAINING_WEEKS_BEFORE_EXPIRATION.weeks
end
def close_to_expiration?
approximative_expiration_date < Time.zone.now
end end
def expiration_date def expiration_date
@ -565,12 +577,8 @@ class Dossier < ApplicationRecord
end end
end end
def close_to_expiration? def duration_after_notice
!en_instruction? && close_to_expiration_at < Time.zone.now MONTHS_AFTER_EXPIRATION.month + DAYS_AFTER_EXPIRATION.days
end
def close_to_expiration_notice_sent?
expiration_date.present?
end end
def expiration_can_be_extended? def expiration_can_be_extended?

View file

@ -0,0 +1,17 @@
- if dossier.expirable? && dossier.close_to_expiration?
.card.warning.mt-2.mb-3
.card-title Votre dossier va expirer
%p
- if dossier.brouillon?
Votre dossier est en brouillon, mais va bientôt expirer. Cela signifie quil va bientôt être supprimé sans avoir été déposé.
Si vous souhaitez le conserver afin de poursuivre la démarche, vous pouvez le conserver
un mois de plus en cliquant sur le bouton ci-dessous.
- elsif dossier.en_construction?
Votre dossier est en attente de prise en charge par l'administration. Le delais de prise en charge maximale est de 6 mois. Vous pouvez toutefois entendre cette durée d'un mois en cliquant sur le bouton suivant.
- elsif dossier.termine?
Le traitement de votre dossier est terminé, mais il va bientôt expirer. Cela signifie quil va bientôt être supprimé.
Si vous souhaitez conserver une trace, vous pouvez le télécharger au format PDF.
- if dossier.expiration_can_be_extended?
%br
= button_to 'Repousser sa suppression', users_dossier_repousser_expiration_path(dossier), class: 'button secondary mt-2'

View file

@ -1,6 +1,14 @@
%h1 = status_badge(dossier.state)
= procedure_libelle(dossier.procedure) .title-container
%span.icon.folder
%h1= procedure_libelle(dossier.procedure)
%h2
= t('views.users.dossiers.show.header.dossier_number', dossier_id: dossier.id)
= t('views.users.dossiers.show.header.created_date', date_du_dossier: I18n.l(dossier.created_at))
= render(partial: 'shared/dossiers/short_expires_message', locals: {dossier: dossier})
.header-actions
- if current_user.owns?(dossier)
= render partial: 'invites/dropdown', locals: { dossier: dossier }
.dossier-form-actions
- if current_user.owns?(dossier)
= render partial: 'invites/dropdown', locals: { dossier: dossier }

View file

@ -0,0 +1,9 @@
- if dossier.expirable?
%p.expires_at
%small= t("shared.dossiers.header.expires_at.#{dossier.state}", date: safe_expiration_date(dossier))
- else
%p.expires_at_en_instruction
%small= t("shared.dossiers.header.expires_at.en_instruction")
= render(partial: 'shared/dossiers/expiration_banner', locals: {dossier: dossier})

View file

@ -10,6 +10,9 @@
- if dossier.en_construction_at.present? - if dossier.en_construction_at.present?
= t('views.users.dossiers.show.header.submit_date', date_du_dossier: I18n.l(dossier.en_construction_at)) = t('views.users.dossiers.show.header.submit_date', date_du_dossier: I18n.l(dossier.en_construction_at))
= render(partial: 'shared/dossiers/short_expires_message', locals: {dossier: dossier})
- if current_user.owns?(dossier) - if current_user.owns?(dossier)
.header-actions .header-actions
= render partial: 'invites/dropdown', locals: { dossier: dossier } = render partial: 'invites/dropdown', locals: { dossier: dossier }
@ -22,25 +25,6 @@
%li %li
= link_to t('views.users.dossiers.show.header.print_dossier'), dossier_path(dossier, format: :pdf), target: "_blank", rel: "noopener", class: "menu-item menu-link" = link_to t('views.users.dossiers.show.header.print_dossier'), dossier_path(dossier, format: :pdf), target: "_blank", rel: "noopener", class: "menu-item menu-link"
- if dossier.close_to_expiration?
.card.warning
.card-title Votre dossier va expirer
%p
- if dossier.brouillon?
Votre dossier est en brouillon, mais va bientôt expirer. Cela signifie quil va bientôt être supprimé sans avoir été déposé.
Si vous souhaitez le conserver afin de poursuivre la démarche, vous pouvez le conserver
un mois de plus en cliquant sur le bouton ci-dessous.
- elsif dossier.termine?
Le traitement de votre dossier est terminé, mais il va bientôt expirer. Cela signifie quil va bientôt être supprimé.
Si vous souhaitez conserver une trace, vous pouvez le télécharger au format PDF.
- else
Votre dossier a été déposé, mais va bientôt expirer. Cela signifie quil va bientôt être supprimé sans avoir été traité par ladministration.
Si vous souhaitez le conserver afin de poursuivre la démarche, vous pouvez le conserver
un mois de plus en cliquant sur le bouton ci-dessous.
- if dossier.expiration_can_be_extended?
%br
= button_to 'Repousser sa suppression', users_dossier_repousser_expiration_path(dossier), class: 'button secondary'
%ul.tabs %ul.tabs
= dynamic_tab_item(t('views.users.dossiers.show.header.summary'), dossier_path(dossier)) = dynamic_tab_item(t('views.users.dossiers.show.header.summary'), dossier_path(dossier))

View file

@ -160,6 +160,7 @@ en:
request: "Request" request: "Request"
mailbox: "Mailbox" mailbox: "Mailbox"
dossier_number: "File n. %{dossier_id}" dossier_number: "File n. %{dossier_id}"
created_date: "- Draft on %{date_du_dossier}"
submit_date: "- Submit on %{date_du_dossier}" submit_date: "- Submit on %{date_du_dossier}"
print: "print" print: "print"
print_dossier: "All the file" print_dossier: "All the file"

View file

@ -156,6 +156,7 @@ fr:
request: "Demande" request: "Demande"
mailbox: "Messagerie" mailbox: "Messagerie"
dossier_number: "Dossier nº %{dossier_id}" dossier_number: "Dossier nº %{dossier_id}"
created_date: "- En brouillon depuis le %{date_du_dossier}"
submit_date: "- Déposé le %{date_du_dossier}" submit_date: "- Déposé le %{date_du_dossier}"
print: "imprimer" print: "imprimer"
print_dossier: "Tout le dossier" print_dossier: "Tout le dossier"

View file

@ -7,6 +7,14 @@ en:
numero_allocataire_notice: It is usually composed of 7 digits. numero_allocataire_notice: It is usually composed of 7 digits.
code_postal_label: postal code code_postal_label: postal code
code_postal_notice: It is usually composed of 5 digits. code_postal_notice: It is usually composed of 5 digits.
header:
expires_at:
brouillon: "Expires at %{date}"
en_construction: "Expires at %{date}"
en_instruction: "This file is being instructed, the administration will answer as soon as possible"
accepte: "Expires at %{date}"
refuse: "Expires at %{date}"
sans_suite: "Expires at %{date}"
champs: champs:
cnaf: cnaf:
show: show:

View file

@ -7,6 +7,14 @@ fr:
numero_allocataire_notice: Il est généralement composé de 7 chiffres. numero_allocataire_notice: Il est généralement composé de 7 chiffres.
code_postal_label: Le code postal code_postal_label: Le code postal
code_postal_notice: Il est généralement composé de 5 chiffres. code_postal_notice: Il est généralement composé de 5 chiffres.
header:
expires_at:
brouillon: "Expirera le %{date}"
en_construction: "Expirera le %{date}"
en_instruction: "Ce dossier est en instruction, il n'expirera pas"
accepte: "Expirera le %{date}"
refuse: "Expirera le %{date}"
sans_suite: "Expirera le %{date}"
champs: champs:
cnaf: cnaf:
show: show:

View file

@ -9,7 +9,7 @@ end
Capybara.register_driver :headless_chrome do |app| Capybara.register_driver :headless_chrome do |app|
options = Selenium::WebDriver::Chrome::Options.new options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless') options.add_argument('--headless') unless ENV['NO_HEADLESS']
options.add_argument('--window-size=1440,900') options.add_argument('--window-size=1440,900')
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome( capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(

View file

@ -165,6 +165,27 @@ describe 'The user' do
expect(page).to have_current_path(merci_dossier_path(user_dossier)) expect(page).to have_current_path(merci_dossier_path(user_dossier))
end end
scenario 'extends dossier experation date more than one time, ', js: true do
user_old_dossier = create(:dossier,
procedure: simple_procedure,
created_at: simple_procedure.duree_conservation_dossiers_dans_ds.month.ago,
user: user)
login_as(user, scope: :user)
visit brouillon_dossier_path(user_old_dossier)
expect(page).to have_css('.card-title', text: 'Votre dossier va expirer', visible: true)
click_on "Repousser sa suppression"
expect(page).not_to have_button("Repousser sa suppression")
Timecop.freeze(1.month.from_now) do
visit brouillon_dossier_path(user_old_dossier)
expect(page).to have_css('.card-title', text: 'Votre dossier va expirer', visible: true)
click_on "Repousser sa suppression"
expect(page).not_to have_button("Repousser sa suppression")
end
end
let(:procedure_with_pj) do let(:procedure_with_pj) do
tdcs = [build(:type_de_champ_piece_justificative, mandatory: true, libelle: 'Pièce justificative')] tdcs = [build(:type_de_champ_piece_justificative, mandatory: true, libelle: 'Pièce justificative')]
create(:procedure, :published, :for_individual, types_de_champ: tdcs) create(:procedure, :published, :for_individual, types_de_champ: tdcs)

View file

@ -0,0 +1,56 @@
describe 'shared/dossiers/short_expires_message.html.haml', type: :view do
include DossierHelper
let(:dossier) do
build(:dossier, state, attributes.merge(id: 1, state: state))
end
let(:i18n_key_state) { state }
subject do
render('shared/dossiers/short_expires_message.html.haml',
dossier: dossier,
current_user: build(:user))
end
context 'with dossier.brouillon?' do
let(:attributes) { { created_at: 6.months.ago } }
let(:state) { :brouillon }
it 'render estimated expiration date' do
expect(subject).to have_selector('.expires_at',
text: I18n.t("shared.dossiers.header.expires_at.#{i18n_key_state}",
date: safe_expiration_date(dossier)))
end
end
context 'with dossier.en_construction?' do
let(:attributes) { { en_construction_at: 6.months.ago } }
let(:state) { :en_construction }
it 'render estimated expiration date' do
expect(subject).to have_selector('.expires_at',
text: I18n.t("shared.dossiers.header.expires_at.#{i18n_key_state}",
date: safe_expiration_date(dossier)))
end
end
context 'with dossier.en_instruction?' do
let(:state) { :en_instruction }
let(:attributes) { {} }
it 'render estimated expiration date' do
expect(subject).to have_selector('p.expires_at_en_instruction',
text: I18n.t("shared.dossiers.header.expires_at.#{i18n_key_state}"))
end
end
context 'with dossier.en_processed_at?' do
let(:state) { :accepte }
let(:attributes) { {} }
it 'render estimated expiration date' do
allow(dossier).to receive(:processed_at).and_return(6.months.ago)
expect(subject).to have_selector('.expires_at',
text: I18n.t("shared.dossiers.header.expires_at.#{i18n_key_state}",
date: safe_expiration_date(dossier)))
end
end
end