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
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)
base_url = "https://annuaire-entreprises.data.gouv.fr"
return base_url if siren.blank?

View file

@ -539,20 +539,32 @@ class Dossier < ApplicationRecord
!brouillon? && !user_deleted? && !archived
end
def close_to_expiration_at
def expirable?
[brouillon?, en_construction?, termine?].any?
end
def approximative_expiration_date_reference
if brouillon?
created_at
elsif en_construction?
en_construction_at
elsif en_instruction?
en_instruction_at
else
elsif termine?
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
def duration_after_notice
MONTHS_AFTER_EXPIRATION.month + DAYS_AFTER_EXPIRATION.days
def approximative_expiration_date
[
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
def expiration_date
@ -565,12 +577,8 @@ class Dossier < ApplicationRecord
end
end
def close_to_expiration?
!en_instruction? && close_to_expiration_at < Time.zone.now
end
def close_to_expiration_notice_sent?
expiration_date.present?
def duration_after_notice
MONTHS_AFTER_EXPIRATION.month + DAYS_AFTER_EXPIRATION.days
end
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
= procedure_libelle(dossier.procedure)
= status_badge(dossier.state)
.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?
= 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)
.header-actions
= render partial: 'invites/dropdown', locals: { dossier: dossier }
@ -22,25 +25,6 @@
%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"
- 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
= dynamic_tab_item(t('views.users.dossiers.show.header.summary'), dossier_path(dossier))

View file

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

View file

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

View file

@ -7,6 +7,14 @@ en:
numero_allocataire_notice: It is usually composed of 7 digits.
code_postal_label: postal code
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:
cnaf:
show:

View file

@ -7,6 +7,14 @@ fr:
numero_allocataire_notice: Il est généralement composé de 7 chiffres.
code_postal_label: Le code postal
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:
cnaf:
show:

View file

@ -9,7 +9,7 @@ end
Capybara.register_driver :headless_chrome do |app|
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')
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))
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
tdcs = [build(:type_de_champ_piece_justificative, mandatory: true, libelle: 'Pièce justificative')]
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