Merge pull request #10190 from demarches-simplifiees/add-AR-feature-ldu
ETQ Admin je peux configurer une démarche avec accusé de lecture
This commit is contained in:
commit
7a80574afc
47 changed files with 491 additions and 96 deletions
5
app/components/dossiers/accuse_lecture_component.rb
Normal file
5
app/components/dossiers/accuse_lecture_component.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
class Dossiers::AccuseLectureComponent < ApplicationComponent
|
||||||
|
def initialize(dossier:)
|
||||||
|
@dossier = dossier
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
en:
|
||||||
|
text_accuse_lecture: This procedure is subject to a reading acknowledgment. By requesting the display of the decision taken on your file, you accept the reading acknowledgment and thereby the triggering of the legal deadline in the event of an appeal.
|
||||||
|
btn_accuse_lecture: I would like to display the decision
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
fr:
|
||||||
|
text_accuse_lecture: Cette démarche est soumise à un accusé de lecture. En demandant l’affichage de la décision prise sur votre dossier, vous acceptez l’accusé de lecture et par là même le démarrage du délai légal en cas de recours.
|
||||||
|
btn_accuse_lecture: Je souhaite afficher la décision
|
|
@ -0,0 +1,10 @@
|
||||||
|
= render Dsfr::CalloutComponent.new(title: nil) do |c|
|
||||||
|
- c.with_body do
|
||||||
|
= t('.text_accuse_lecture')
|
||||||
|
|
||||||
|
= form_for @dossier,
|
||||||
|
method: :get,
|
||||||
|
url: set_accuse_lecture_agreement_at_dossier_path(@dossier),
|
||||||
|
data: { controller: 'autosubmit', turbo: 'true' } do |f|
|
||||||
|
|
||||||
|
= f.submit t('.btn_accuse_lecture'), class: "fr-btn fr-mt-2w"
|
|
@ -0,0 +1,5 @@
|
||||||
|
class Procedure::Card::AccuseLectureComponent < ApplicationComponent
|
||||||
|
def initialize(procedure:)
|
||||||
|
@procedure = procedure
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
fr:
|
||||||
|
title: Accusé de lecture
|
||||||
|
subtitle: Pour les démarches avec voies de recours
|
|
@ -0,0 +1,11 @@
|
||||||
|
.fr-col-6.fr-col-md-4.fr-col-lg-3
|
||||||
|
= link_to accuse_lecture_admin_procedure_path(@procedure), class: 'fr-tile fr-enlarge-link' do
|
||||||
|
.fr-tile__body.flex.column.align-center.justify-between
|
||||||
|
- if @procedure.accuse_lecture.present?
|
||||||
|
%p.fr-badge.fr-badge--success Activé
|
||||||
|
- else
|
||||||
|
%p.fr-badge.fr-badge--info Désactivé
|
||||||
|
%div
|
||||||
|
%h3.fr-h6.fr-mt-10v= t('.title')
|
||||||
|
%p.fr-tile-subtitle= t('.subtitle')
|
||||||
|
%p.fr-btn.fr-btn--tertiary= t('views.shared.actions.edit')
|
|
@ -3,7 +3,7 @@ module Administrateurs
|
||||||
layout 'all', only: [:all, :administrateurs]
|
layout 'all', only: [:all, :administrateurs]
|
||||||
respond_to :html, :xlsx
|
respond_to :html, :xlsx
|
||||||
|
|
||||||
before_action :retrieve_procedure, only: [:champs, :annotations, :modifications, :edit, :zones, :monavis, :update_monavis, :jeton, :update_jeton, :publication, :publish, :transfert, :close, :confirmation, :allow_expert_review, :allow_expert_messaging, :experts_require_administrateur_invitation, :reset_draft, :publish_revision, :check_path]
|
before_action :retrieve_procedure, only: [:champs, :annotations, :modifications, :edit, :zones, :monavis, :update_monavis, :accuse_lecture, :update_accuse_lecture, :jeton, :update_jeton, :publication, :publish, :transfert, :close, :confirmation, :allow_expert_review, :allow_expert_messaging, :experts_require_administrateur_invitation, :reset_draft, :publish_revision, :check_path]
|
||||||
before_action :draft_valid?, only: [:apercu]
|
before_action :draft_valid?, only: [:apercu]
|
||||||
after_action :reset_procedure, only: [:update]
|
after_action :reset_procedure, only: [:update]
|
||||||
|
|
||||||
|
@ -276,6 +276,13 @@ module Administrateurs
|
||||||
render 'monavis'
|
render 'monavis'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def accuse_lecture
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_accuse_lecture
|
||||||
|
@procedure.update!(procedure_params)
|
||||||
|
end
|
||||||
|
|
||||||
def jeton
|
def jeton
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -515,6 +522,7 @@ module Administrateurs
|
||||||
:logo,
|
:logo,
|
||||||
:auto_archive_on,
|
:auto_archive_on,
|
||||||
:monavis_embed,
|
:monavis_embed,
|
||||||
|
:accuse_lecture,
|
||||||
:api_entreprise_token,
|
:api_entreprise_token,
|
||||||
:duree_conservation_dossiers_dans_ds,
|
:duree_conservation_dossiers_dans_ds,
|
||||||
{ zone_ids: [] },
|
{ zone_ids: [] },
|
||||||
|
|
|
@ -124,6 +124,13 @@ module Users
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_accuse_lecture_agreement_at
|
||||||
|
@dossier = dossier
|
||||||
|
@dossier.update!(accuse_lecture_agreement_at: Time.zone.now)
|
||||||
|
flash.notice = 'Accusé de lecture accepté'
|
||||||
|
redirect_back(fallback_location: demande_dossier_path(@dossier))
|
||||||
|
end
|
||||||
|
|
||||||
def identite
|
def identite
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
@user = current_user
|
@user = current_user
|
||||||
|
|
|
@ -78,6 +78,14 @@ module DossierHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def status_badge_user(dossier, alignment_class = '')
|
||||||
|
if dossier.hide_info_with_accuse_lecture?
|
||||||
|
tag.span 'traité', role: 'status', class: "fr-badge fr-badge--sm fr-badge--no-icon #{alignment_class}"
|
||||||
|
else
|
||||||
|
status_badge(dossier.state, alignment_class)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def status_badge(state, alignment_class = '')
|
def status_badge(state, alignment_class = '')
|
||||||
status_text = dossier_display_state(state, lower: true)
|
status_text = dossier_display_state(state, lower: true)
|
||||||
tag.span status_text, role: 'status', class: class_names(
|
tag.span status_text, role: 'status', class: class_names(
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# The subject and body of a Notification can be customized by each demarche.
|
# The subject and body of a Notification can be customized by each demarche.
|
||||||
#
|
#
|
||||||
class NotificationMailer < ApplicationMailer
|
class NotificationMailer < ApplicationMailer
|
||||||
before_action :set_dossier, except: [:send_notification_for_tiers]
|
before_action :set_dossier, except: [:send_notification_for_tiers, :send_accuse_lecture_notification]
|
||||||
before_action :set_services_publics_plus, only: :send_notification
|
before_action :set_services_publics_plus, only: :send_notification
|
||||||
|
|
||||||
helper ServiceHelper
|
helper ServiceHelper
|
||||||
|
@ -42,6 +42,16 @@ class NotificationMailer < ApplicationMailer
|
||||||
mail(subject: @subject, to: @email, template_name: 'send_notification_for_tiers')
|
mail(subject: @subject, to: @email, template_name: 'send_notification_for_tiers')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def send_accuse_lecture_notification(dossier)
|
||||||
|
@dossier = dossier
|
||||||
|
@subject = "La décision a été rendue pour votre démarche #{@dossier.procedure.libelle.truncate_words(50)}"
|
||||||
|
@email = @dossier.user_email_for(:notification)
|
||||||
|
|
||||||
|
@logo_url = procedure_logo_url(@dossier.procedure)
|
||||||
|
|
||||||
|
mail(subject: @subject, to: @email, template_name: 'send_accuse_lecture_notification')
|
||||||
|
end
|
||||||
|
|
||||||
def self.send_en_construction_notification(dossier)
|
def self.send_en_construction_notification(dossier)
|
||||||
with(dossier: dossier, state: Dossier.states.fetch(:en_construction)).send_notification
|
with(dossier: dossier, state: Dossier.states.fetch(:en_construction)).send_notification
|
||||||
end
|
end
|
||||||
|
|
|
@ -120,7 +120,11 @@ module DossierStateConcern
|
||||||
disable_notification = h.fetch(:disable_notification, false)
|
disable_notification = h.fetch(:disable_notification, false)
|
||||||
|
|
||||||
if !disable_notification
|
if !disable_notification
|
||||||
|
if procedure.accuse_lecture?
|
||||||
|
NotificationMailer.send_accuse_lecture_notification(self).deliver_later
|
||||||
|
else
|
||||||
NotificationMailer.send_accepte_notification(self).deliver_later
|
NotificationMailer.send_accepte_notification(self).deliver_later
|
||||||
|
end
|
||||||
NotificationMailer.send_notification_for_tiers(self).deliver_later if self.for_tiers?
|
NotificationMailer.send_notification_for_tiers(self).deliver_later if self.for_tiers?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -152,7 +156,11 @@ module DossierStateConcern
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_commit_accepter_automatiquement
|
def after_commit_accepter_automatiquement
|
||||||
|
if procedure.accuse_lecture?
|
||||||
|
NotificationMailer.send_accuse_lecture_notification(self).deliver_later
|
||||||
|
else
|
||||||
NotificationMailer.send_accepte_notification(self).deliver_later
|
NotificationMailer.send_accepte_notification(self).deliver_later
|
||||||
|
end
|
||||||
NotificationMailer.send_notification_for_tiers(self).deliver_later if self.for_tiers?
|
NotificationMailer.send_notification_for_tiers(self).deliver_later if self.for_tiers?
|
||||||
|
|
||||||
send_dossier_decision_to_experts(self)
|
send_dossier_decision_to_experts(self)
|
||||||
|
@ -184,7 +192,11 @@ module DossierStateConcern
|
||||||
disable_notification = h.fetch(:disable_notification, false)
|
disable_notification = h.fetch(:disable_notification, false)
|
||||||
|
|
||||||
if !disable_notification
|
if !disable_notification
|
||||||
|
if procedure.accuse_lecture?
|
||||||
|
NotificationMailer.send_accuse_lecture_notification(self).deliver_later
|
||||||
|
else
|
||||||
NotificationMailer.send_refuse_notification(self).deliver_later
|
NotificationMailer.send_refuse_notification(self).deliver_later
|
||||||
|
end
|
||||||
NotificationMailer.send_notification_for_tiers(self).deliver_later if self.for_tiers?
|
NotificationMailer.send_notification_for_tiers(self).deliver_later if self.for_tiers?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -209,7 +221,11 @@ module DossierStateConcern
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_commit_refuser_automatiquement
|
def after_commit_refuser_automatiquement
|
||||||
|
if procedure.accuse_lecture?
|
||||||
|
NotificationMailer.send_accuse_lecture_notification(self).deliver_later
|
||||||
|
else
|
||||||
NotificationMailer.send_refuse_notification(self).deliver_later
|
NotificationMailer.send_refuse_notification(self).deliver_later
|
||||||
|
end
|
||||||
NotificationMailer.send_notification_for_tiers(self).deliver_later if self.for_tiers?
|
NotificationMailer.send_notification_for_tiers(self).deliver_later if self.for_tiers?
|
||||||
|
|
||||||
send_dossier_decision_to_experts(self)
|
send_dossier_decision_to_experts(self)
|
||||||
|
@ -241,7 +257,11 @@ module DossierStateConcern
|
||||||
disable_notification = h.fetch(:disable_notification, false)
|
disable_notification = h.fetch(:disable_notification, false)
|
||||||
|
|
||||||
if !disable_notification
|
if !disable_notification
|
||||||
|
if procedure.accuse_lecture?
|
||||||
|
NotificationMailer.send_accuse_lecture_notification(self).deliver_later
|
||||||
|
else
|
||||||
NotificationMailer.send_sans_suite_notification(self).deliver_later
|
NotificationMailer.send_sans_suite_notification(self).deliver_later
|
||||||
|
end
|
||||||
NotificationMailer.send_notification_for_tiers(self).deliver_later if self.for_tiers?
|
NotificationMailer.send_notification_for_tiers(self).deliver_later if self.for_tiers?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1180,6 +1180,14 @@ class Dossier < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def hide_info_with_accuse_lecture?
|
||||||
|
procedure.accuse_lecture? && termine? && accuse_lecture_agreement_at.blank?
|
||||||
|
end
|
||||||
|
|
||||||
|
def termine_and_accuse_lecture?
|
||||||
|
procedure.accuse_lecture? && termine?
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def champs_by_public_id
|
def champs_by_public_id
|
||||||
|
|
|
@ -23,6 +23,7 @@ class DossiersFilter
|
||||||
dossiers_result = dossiers
|
dossiers_result = dossiers
|
||||||
dossiers_result = dossiers_result.where(state: state) if state.present? && state != Dossier::A_CORRIGER
|
dossiers_result = dossiers_result.where(state: state) if state.present? && state != Dossier::A_CORRIGER
|
||||||
dossiers_result = dossiers_result.with_pending_corrections if state.present? && state == Dossier::A_CORRIGER
|
dossiers_result = dossiers_result.with_pending_corrections if state.present? && state == Dossier::A_CORRIGER
|
||||||
|
dossiers_result = exclude_accuse_lecture(dossiers_result) if state.present? && Dossier::TERMINE.include?(state)
|
||||||
dossiers_result = dossiers_result.where('dossiers.created_at >= ?', from_created_at_date) if from_created_at_date.present?
|
dossiers_result = dossiers_result.where('dossiers.created_at >= ?', from_created_at_date) if from_created_at_date.present?
|
||||||
dossiers_result = dossiers_result.where('dossiers.depose_at >= ?', from_depose_at_date) if from_depose_at_date.present?
|
dossiers_result = dossiers_result.where('dossiers.depose_at >= ?', from_depose_at_date) if from_depose_at_date.present?
|
||||||
dossiers_result
|
dossiers_result
|
||||||
|
@ -47,4 +48,8 @@ class DossiersFilter
|
||||||
rescue Date::Error
|
rescue Date::Error
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def exclude_accuse_lecture(dossiers)
|
||||||
|
dossiers.joins(:procedure).where.not('dossiers.accuse_lecture_agreement_at IS NULL AND procedures.accuse_lecture = TRUE ')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,10 +3,14 @@ class MailTemplatePresenterService
|
||||||
include ActionView::Helpers::TextHelper
|
include ActionView::Helpers::TextHelper
|
||||||
|
|
||||||
def self.create_commentaire_for_state(dossier, state)
|
def self.create_commentaire_for_state(dossier, state)
|
||||||
|
if dossier.procedure.accuse_lecture? && Dossier::TERMINE.include?(state)
|
||||||
|
CommentaireService.create!(CONTACT_EMAIL, dossier, body: I18n.t('layouts.mailers.accuse_lecture.commentaire_html', service: dossier.procedure.service.nom))
|
||||||
|
else
|
||||||
service = new(dossier, state)
|
service = new(dossier, state)
|
||||||
body = ["<p>[#{service.safe_subject}]</p>", service.safe_body].join('')
|
body = ["<p>[#{service.safe_subject}]</p>", service.safe_body].join('')
|
||||||
CommentaireService.create!(CONTACT_EMAIL, dossier, body: body)
|
CommentaireService.create!(CONTACT_EMAIL, dossier, body: body)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def safe_body
|
def safe_body
|
||||||
sanitize(@email_template.body_for_dossier(@dossier), scrubber: Sanitizers::MailScrubber.new)
|
sanitize(@email_template.body_for_dossier(@dossier), scrubber: Sanitizers::MailScrubber.new)
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
= render partial: 'administrateurs/breadcrumbs',
|
||||||
|
locals: { steps: [['Démarches', admin_procedures_back_path(@procedure)],
|
||||||
|
[@procedure.libelle.truncate_words(10), admin_procedure_path(@procedure)],
|
||||||
|
['Accusé de lecture']] }
|
||||||
|
|
||||||
|
.fr-container
|
||||||
|
.fr-grid-row
|
||||||
|
.fr-col-12.fr-col-offset-md-2.fr-col-md-8
|
||||||
|
%h1.page-title
|
||||||
|
Accusé de lecture
|
||||||
|
|
||||||
|
= render Dsfr::CalloutComponent.new(title: nil) do |c|
|
||||||
|
- c.with_body do
|
||||||
|
%p
|
||||||
|
Pour les démarches avec voies de recours, il est possible d’activer l’accusé de lecture.
|
||||||
|
%br
|
||||||
|
%p
|
||||||
|
Cette fonctionnalité permet à l’instructeur de connaître la date de lecture de la décision finale par l’usager.
|
||||||
|
%br
|
||||||
|
%p
|
||||||
|
L’usager n’a plus accès à la décision finale par mail, mais il doit se connecter sur la plateforme #{Current.application_name} pour en prendre connaissance et en accuser lecture.
|
||||||
|
|
||||||
|
%ul.fr-toggle__list
|
||||||
|
%li
|
||||||
|
= form_for @procedure,
|
||||||
|
method: :patch,
|
||||||
|
url: update_accuse_lecture_admin_procedure_path(@procedure),
|
||||||
|
data: { controller: 'autosubmit', turbo: 'true' } do |f|
|
||||||
|
|
||||||
|
= render Dsfr::ToggleComponent.new(form: f,
|
||||||
|
target: :accuse_lecture,
|
||||||
|
title: "Accusé de lecture de la démarche",
|
||||||
|
hint: "L’accusé de lecture est à activer uniquement pour les démarches avec voies de recours car il complexifie l’accès à la décision finale pour les usagers",
|
||||||
|
opt: {"checked" => @procedure.accuse_lecture})
|
||||||
|
|
||||||
|
.padded-fixed-footer
|
||||||
|
.fixed-footer
|
||||||
|
.fr-container
|
||||||
|
.fr-grid-row
|
||||||
|
.fr-col-12.fr-col-offset-md-2.fr-col-md-8
|
||||||
|
%ul.fr-btns-group.fr-btns-group--inline-md
|
||||||
|
%li
|
||||||
|
= link_to 'Enregistrer et revenir à la page de suivi', admin_procedure_path(id: @procedure), class: 'fr-btn'
|
|
@ -89,3 +89,4 @@
|
||||||
= render Procedure::Card::MonAvisComponent.new(procedure: @procedure)
|
= render Procedure::Card::MonAvisComponent.new(procedure: @procedure)
|
||||||
= render Procedure::Card::DossierSubmittedMessageComponent.new(procedure: @procedure)
|
= render Procedure::Card::DossierSubmittedMessageComponent.new(procedure: @procedure)
|
||||||
= render Procedure::Card::ChorusComponent.new(procedure: @procedure)
|
= render Procedure::Card::ChorusComponent.new(procedure: @procedure)
|
||||||
|
= render Procedure::Card::AccuseLectureComponent.new(procedure: @procedure)
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
- content_for :procedure_logo do
|
||||||
|
= render 'layouts/mailers/logo', url: @logo_url
|
||||||
|
|
||||||
|
%p
|
||||||
|
= t("layouts.mailers.accuse_lecture.good_morning")
|
||||||
|
|
||||||
|
%p
|
||||||
|
= t("layouts.mailers.accuse_lecture.first_part",
|
||||||
|
dossier_id: number_with_delimiter(@dossier.id))
|
||||||
|
|
||||||
|
%span{ :style => "font-weight: bold;" }
|
||||||
|
= @dossier.procedure.libelle
|
||||||
|
|
||||||
|
= t("layouts.mailers.accuse_lecture.second_part")
|
||||||
|
%p
|
||||||
|
= t("layouts.mailers.accuse_lecture.third_part")
|
||||||
|
= link_to APPLICATION_NAME, dossier_url(@dossier)
|
||||||
|
|
||||||
|
%p
|
||||||
|
= t(:best_regards, scope: [:views, :shared, :greetings])
|
||||||
|
%br
|
||||||
|
= t('layouts.mailers.signature.team')
|
||||||
|
= APPLICATION_NAME
|
|
@ -15,8 +15,10 @@
|
||||||
|
|
||||||
- if @repasser_en_instruction
|
- if @repasser_en_instruction
|
||||||
= t("layouts.mailers.for_tiers.repasser_en_instruction")
|
= t("layouts.mailers.for_tiers.repasser_en_instruction")
|
||||||
|
- elsif @dossier.hide_info_with_accuse_lecture?
|
||||||
|
= t("layouts.mailers.for_tiers.accuse_lecture", processed_at: l(@dossier.updated_at.to_date))
|
||||||
- else
|
- else
|
||||||
= t("layouts.mailers.for_tiers.#{@dossier.state}", processed_at: l(@dossier.updated_at.to_date) )
|
= t("layouts.mailers.for_tiers.#{@dossier.state}", processed_at: l(@dossier.updated_at.to_date))
|
||||||
|
|
||||||
%p
|
%p
|
||||||
= t("layouts.mailers.for_tiers.second_part")
|
= t("layouts.mailers.for_tiers.second_part")
|
||||||
|
|
|
@ -5,11 +5,20 @@
|
||||||
.fr-container.counter-start-header-section.dossier-show{ class: class_names("dossier-show-instructeur" => profile =="instructeur") }
|
.fr-container.counter-start-header-section.dossier-show{ class: class_names("dossier-show-instructeur" => profile =="instructeur") }
|
||||||
.fr-grid-row.fr-grid-row--center
|
.fr-grid-row.fr-grid-row--center
|
||||||
.fr-col-12.fr-col-xl-8
|
.fr-col-12.fr-col-xl-8
|
||||||
|
- if profile == 'instructeur' && dossier.termine_and_accuse_lecture?
|
||||||
|
= render Dsfr::CalloutComponent.new(title: nil) do |c|
|
||||||
|
- c.with_html_body do
|
||||||
|
= t('views.shared.dossiers.demande.accuse_lecture')
|
||||||
|
- if dossier.accuse_lecture_agreement_at.present?
|
||||||
|
= t('views.shared.dossiers.demande.accuse_lecture_with_agreement', agreement: l(dossier.accuse_lecture_agreement_at, format: :long))
|
||||||
|
- else
|
||||||
|
= t('views.shared.dossiers.demande.accuse_lecture_without_agreement')
|
||||||
|
|
||||||
%h2.fr-h6.fr-background-alt--grey.fr-mb-0
|
%h2.fr-h6.fr-background-alt--grey.fr-mb-0
|
||||||
.flex-grow.fr-py-3v.fr-px-2w= t('views.shared.dossiers.demande.en_construction')
|
.flex-grow.fr-py-3v.fr-px-2w= t('views.shared.dossiers.demande.en_construction')
|
||||||
|
|
||||||
- if dossier.depose_at.present?
|
- if dossier.depose_at.present?
|
||||||
= render partial: "shared/dossiers/infos_generales", locals: { dossier: dossier }
|
= render partial: "shared/dossiers/infos_generales", locals: { dossier: dossier, profile: profile }
|
||||||
|
|
||||||
|
|
||||||
- if dossier.for_tiers?
|
- if dossier.for_tiers?
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
%h1
|
%h1
|
||||||
= procedure_libelle(dossier.procedure)
|
= procedure_libelle(dossier.procedure)
|
||||||
= status_badge(dossier.state, 'super')
|
= status_badge_user(dossier, 'super')
|
||||||
%h2
|
%h2
|
||||||
= t('views.users.dossiers.show.header.dossier_number', dossier_id: dossier.id)
|
= 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))
|
= t('views.users.dossiers.show.header.created_date', date_du_dossier: I18n.l(dossier.created_at))
|
||||||
|
|
|
@ -9,6 +9,10 @@
|
||||||
.fr-highlight
|
.fr-highlight
|
||||||
%p.fr-text--sm.fr-text-mention--grey Sauf mention contraire, les champs ont été saisis à la date du dépôt du dossier.
|
%p.fr-text--sm.fr-text-mention--grey Sauf mention contraire, les champs ont été saisis à la date du dépôt du dossier.
|
||||||
|
|
||||||
|
- if profile == 'usager' && dossier.hide_info_with_accuse_lecture?
|
||||||
|
= render Dossiers::AccuseLectureComponent.new(dossier: dossier)
|
||||||
|
|
||||||
|
- else
|
||||||
- if dossier.justificatif_motivation.attached?
|
- if dossier.justificatif_motivation.attached?
|
||||||
= render Dossiers::RowShowComponent.new(label: "Justificatif") do |c|
|
= render Dossiers::RowShowComponent.new(label: "Justificatif") do |c|
|
||||||
- c.with_value do
|
- c.with_value do
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
%span.fr-badge.fr-badge--sm.fr-badge--warning
|
%span.fr-badge.fr-badge--sm.fr-badge--warning
|
||||||
= t('views.users.dossiers.dossiers_list.deleted_badge')
|
= t('views.users.dossiers.dossiers_list.deleted_badge')
|
||||||
- else
|
- else
|
||||||
= status_badge(dossier.state, 'fr-mb-1w')
|
= status_badge_user(dossier, 'fr-mb-1w')
|
||||||
|
|
||||||
- if dossier.pending_correction?
|
- if dossier.pending_correction?
|
||||||
%br
|
%br
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
.fr-container
|
.fr-container
|
||||||
%h1
|
%h1
|
||||||
= dossier.procedure.libelle
|
= dossier.procedure.libelle
|
||||||
= status_badge(dossier.state, 'super')
|
= status_badge_user(dossier, 'super')
|
||||||
= pending_correction_badge(:for_user) if dossier.pending_correction?
|
= pending_correction_badge(:for_user) if dossier.pending_correction?
|
||||||
%h2
|
%h2
|
||||||
= t('views.users.dossiers.show.header.dossier_number', dossier_id: dossier.id)
|
= t('views.users.dossiers.show.header.dossier_number', dossier_id: dossier.id)
|
||||||
|
|
|
@ -54,6 +54,10 @@
|
||||||
%p
|
%p
|
||||||
= t('views.users.dossiers.show.status_overview.use_mailbox_for_questions_html', mailbox_url: messagerie_dossier_url(dossier))
|
= t('views.users.dossiers.show.status_overview.use_mailbox_for_questions_html', mailbox_url: messagerie_dossier_url(dossier))
|
||||||
|
|
||||||
|
- elsif dossier.termine?
|
||||||
|
- if dossier.hide_info_with_accuse_lecture?
|
||||||
|
= render Dossiers::AccuseLectureComponent.new(dossier: dossier)
|
||||||
|
|
||||||
- elsif dossier.accepte?
|
- elsif dossier.accepte?
|
||||||
.accepte
|
.accepte
|
||||||
%p.decision{ role: 'status' }
|
%p.decision{ role: 'status' }
|
||||||
|
@ -68,7 +72,7 @@
|
||||||
|
|
||||||
- if dossier.attestation.present?
|
- if dossier.attestation.present?
|
||||||
.action
|
.action
|
||||||
= link_to attestation_dossier_path(dossier), class: "fr-btn fr-icon-download-line fr-btn--icon-left", target: '_blank', rel: 'noopener' do
|
= link_to attestation_dossier_path(dossier), class: "fr-btn fr-icon-download-line fr-btn--icon-left", **external_link_attributes do
|
||||||
= t('views.users.dossiers.show.status_overview.accepte_attestation')
|
= t('views.users.dossiers.show.status_overview.accepte_attestation')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -362,6 +362,9 @@ en:
|
||||||
form: "Form"
|
form: "Form"
|
||||||
edit_siret: "Edit SIRET"
|
edit_siret: "Edit SIRET"
|
||||||
edit_identity: "Edit identity data"
|
edit_identity: "Edit identity data"
|
||||||
|
accuse_lecture: This procedure is subject to a reading receipt.
|
||||||
|
accuse_lecture_with_agreement: The user has read the decision taken on his file on %{agreement}.
|
||||||
|
accuse_lecture_without_agreement: The user has not yet learned of the decision on their file.
|
||||||
gestionnaires:
|
gestionnaires:
|
||||||
groupe_gestionnaires:
|
groupe_gestionnaires:
|
||||||
delete: Delete
|
delete: Delete
|
||||||
|
|
|
@ -365,6 +365,9 @@ fr:
|
||||||
form: "Sections du formulaire"
|
form: "Sections du formulaire"
|
||||||
edit_siret: "Modifier le SIRET"
|
edit_siret: "Modifier le SIRET"
|
||||||
edit_identity: "Modifier l’identité"
|
edit_identity: "Modifier l’identité"
|
||||||
|
accuse_lecture: Cette démarche est soumise à un accusé de lecture.
|
||||||
|
accuse_lecture_with_agreement: L’usager a pris connaissance de la décision concernant son dossier le %{agreement}.
|
||||||
|
accuse_lecture_without_agreement: L’usager n’a pas encore pris connaissance de la décision concernant son dossier.
|
||||||
gestionnaires:
|
gestionnaires:
|
||||||
groupe_gestionnaires:
|
groupe_gestionnaires:
|
||||||
delete: Supprimer
|
delete: Supprimer
|
||||||
|
|
|
@ -4,4 +4,4 @@ fr:
|
||||||
mail:
|
mail:
|
||||||
initiated_mail:
|
initiated_mail:
|
||||||
default_subject: Votre dossier nº %{dossier_number} a bien été déposé (%{procedure_libelle})
|
default_subject: Votre dossier nº %{dossier_number} a bien été déposé (%{procedure_libelle})
|
||||||
proof_of_receipt: Accusé de réception
|
proof_of_receipt: Accusé de lecture
|
||||||
|
|
|
@ -13,9 +13,9 @@ en:
|
||||||
brouillon: "Expires on %{date} (%{duree_conservation_totale} months after this file was created)"
|
brouillon: "Expires on %{date} (%{duree_conservation_totale} months after this file was created)"
|
||||||
en_construction: "Expires on %{date} (%{duree_conservation_totale} months after this file was last modified)"
|
en_construction: "Expires on %{date} (%{duree_conservation_totale} months after this file was last modified)"
|
||||||
en_instruction: "This file is being instructed, the administration will answer as soon as possible"
|
en_instruction: "This file is being instructed, the administration will answer as soon as possible"
|
||||||
accepte: "Expires on %{date} (%{duree_conservation_totale} months after this file was accepted)"
|
accepte: "Expires on %{date} (%{duree_conservation_totale} months after this file was processed)"
|
||||||
refuse: "Expires on %{date} (%{duree_conservation_totale} months after this file was rejected)"
|
refuse: "Expires on %{date} (%{duree_conservation_totale} months after this file was processed)"
|
||||||
sans_suite: "Expires on %{date} (%{duree_conservation_totale} months after this file was closed)"
|
sans_suite: "Expires on %{date} (%{duree_conservation_totale} months after this file was processed)"
|
||||||
champs:
|
champs:
|
||||||
cnaf:
|
cnaf:
|
||||||
show:
|
show:
|
||||||
|
|
|
@ -13,9 +13,9 @@ fr:
|
||||||
brouillon: "Expirera le %{date} (%{duree_conservation_totale} mois après la création du dossier)"
|
brouillon: "Expirera le %{date} (%{duree_conservation_totale} mois après la création du dossier)"
|
||||||
en_construction: "Expirera le %{date} (%{duree_conservation_totale} mois après le dépôt du dossier)"
|
en_construction: "Expirera le %{date} (%{duree_conservation_totale} mois après le dépôt du dossier)"
|
||||||
en_instruction: "Ce dossier est en instruction, il n’expirera pas"
|
en_instruction: "Ce dossier est en instruction, il n’expirera pas"
|
||||||
accepte: "Expirera le %{date} (%{duree_conservation_totale} mois après l’acceptation du dossier)"
|
accepte: "Expirera le %{date} (%{duree_conservation_totale} mois après le traitement du dossier)"
|
||||||
refuse: "Expirera le %{date} (%{duree_conservation_totale} mois après le refus du dossier)"
|
refuse: "Expirera le %{date} (%{duree_conservation_totale} mois après le traitement du dossier)"
|
||||||
sans_suite: "Expirera le %{date} (%{duree_conservation_totale} mois après le classement sans suite du dossier)"
|
sans_suite: "Expirera le %{date} (%{duree_conservation_totale} mois après le traitement dossier)"
|
||||||
|
|
||||||
|
|
||||||
champs:
|
champs:
|
||||||
|
|
|
@ -24,3 +24,10 @@ en:
|
||||||
accepte: has been accepted on %{processed_at}.
|
accepte: has been accepted on %{processed_at}.
|
||||||
refuse: has been refused on %{processed_at}.
|
refuse: has been refused on %{processed_at}.
|
||||||
sans_suite: has been closed without continuation on %{processed_at}.
|
sans_suite: has been closed without continuation on %{processed_at}.
|
||||||
|
accuse_lecture: has been processed on %{processed_at}.
|
||||||
|
accuse_lecture:
|
||||||
|
good_morning: Hello,
|
||||||
|
first_part: We inform you that a decision on file no. %{dossier_id} of the procedure
|
||||||
|
second_part: has been rendered.
|
||||||
|
third_part: To find out its nature, please log in to your account
|
||||||
|
commentaire_html: <p>Hello,</p><p>We inform you that a decision on your file has been rendered.</p>Sincerely,<br>%{service}
|
||||||
|
|
|
@ -25,5 +25,13 @@ fr:
|
||||||
accepte: a été accepté le %{processed_at}.
|
accepte: a été accepté le %{processed_at}.
|
||||||
refuse: a été refusé le %{processed_at}.
|
refuse: a été refusé le %{processed_at}.
|
||||||
sans_suite: a été classé sans suite le %{processed_at}.
|
sans_suite: a été classé sans suite le %{processed_at}.
|
||||||
|
accuse_lecture: a été traité le %{processed_at}.
|
||||||
|
accuse_lecture:
|
||||||
|
good_morning: Bonjour,
|
||||||
|
first_part: Nous vous informons qu'une décision sur le dossier nº %{dossier_id} de la démarche
|
||||||
|
second_part: a été rendue.
|
||||||
|
third_part: Pour en connaitre la nature, veuillez vous connecter à votre compte
|
||||||
|
commentaire_html: <p>Bonjour,</p><p>Nous vous informons qu'une décision sur votre dossier a été rendue.</p>Cordialement,<br>%{service}
|
||||||
|
|
||||||
commentaire_groupe_gestionnaire_footer:
|
commentaire_groupe_gestionnaire_footer:
|
||||||
do_not_reply_html: Merci de ne pas répondre à cet email. Consultez votre message sur %{application_name} ou contactez votre expéditeur par <a href="mailto:%{sender_email}">mail</a>
|
do_not_reply_html: Merci de ne pas répondre à cet email. Consultez votre message sur %{application_name} ou contactez votre expéditeur par <a href="mailto:%{sender_email}">mail</a>
|
||||||
|
|
|
@ -369,6 +369,7 @@ Rails.application.routes.draw do
|
||||||
get 'attestation'
|
get 'attestation'
|
||||||
get 'transferer', to: 'dossiers#transferer'
|
get 'transferer', to: 'dossiers#transferer'
|
||||||
get 'papertrail', format: :pdf
|
get 'papertrail', format: :pdf
|
||||||
|
get 'set_accuse_lecture_agreement_at'
|
||||||
end
|
end
|
||||||
|
|
||||||
collection do
|
collection do
|
||||||
|
@ -571,6 +572,8 @@ Rails.application.routes.draw do
|
||||||
get 'modifications'
|
get 'modifications'
|
||||||
get 'monavis'
|
get 'monavis'
|
||||||
patch 'update_monavis'
|
patch 'update_monavis'
|
||||||
|
get 'accuse_lecture'
|
||||||
|
patch 'update_accuse_lecture'
|
||||||
get 'jeton'
|
get 'jeton'
|
||||||
patch 'update_jeton'
|
patch 'update_jeton'
|
||||||
put :allow_expert_review
|
put :allow_expert_review
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddAccuseLectureToProcedures < ActiveRecord::Migration[7.0]
|
||||||
|
def change
|
||||||
|
add_column :procedures, :accuse_lecture, :boolean, default: false, null: false
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddAccuseLectureAgreementToDossiers < ActiveRecord::Migration[7.0]
|
||||||
|
def change
|
||||||
|
add_column :dossiers, :accuse_lecture_agreement_at, :date
|
||||||
|
end
|
||||||
|
end
|
|
@ -442,6 +442,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_04_16_062900) do
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "dossiers", id: :serial, force: :cascade do |t|
|
create_table "dossiers", id: :serial, force: :cascade do |t|
|
||||||
|
t.date "accuse_lecture_agreement_at"
|
||||||
t.string "api_entreprise_job_exceptions", array: true
|
t.string "api_entreprise_job_exceptions", array: true
|
||||||
t.boolean "archived", default: false
|
t.boolean "archived", default: false
|
||||||
t.datetime "archived_at", precision: nil
|
t.datetime "archived_at", precision: nil
|
||||||
|
@ -857,6 +858,7 @@ ActiveRecord::Schema[7.0].define(version: 2024_04_16_062900) do
|
||||||
|
|
||||||
create_table "procedures", id: :serial, force: :cascade do |t|
|
create_table "procedures", id: :serial, force: :cascade do |t|
|
||||||
t.string "aasm_state", default: "brouillon"
|
t.string "aasm_state", default: "brouillon"
|
||||||
|
t.boolean "accuse_lecture", default: false, null: false
|
||||||
t.boolean "allow_expert_messaging", default: true, null: false
|
t.boolean "allow_expert_messaging", default: true, null: false
|
||||||
t.boolean "allow_expert_review", default: true, null: false
|
t.boolean "allow_expert_review", default: true, null: false
|
||||||
t.string "api_entreprise_token"
|
t.string "api_entreprise_token"
|
||||||
|
|
|
@ -6,7 +6,9 @@ describe Instructeurs::DossiersController, type: :controller do
|
||||||
let(:administration) { create(:administration) }
|
let(:administration) { create(:administration) }
|
||||||
let(:instructeurs) { [instructeur] }
|
let(:instructeurs) { [instructeur] }
|
||||||
let(:procedure) { create(:procedure, :published, :for_individual, instructeurs: instructeurs) }
|
let(:procedure) { create(:procedure, :published, :for_individual, instructeurs: instructeurs) }
|
||||||
|
let(:procedure_accuse_lecture) { create(:procedure, :published, :for_individual, :accuse_lecture, instructeurs: instructeurs) }
|
||||||
let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) }
|
let(:dossier) { create(:dossier, :en_construction, :with_individual, procedure: procedure) }
|
||||||
|
let(:dossier_accuse_lecture) { create(:dossier, :en_construction, :with_individual, procedure: procedure_accuse_lecture) }
|
||||||
let(:dossier_for_tiers) { create(:dossier, :en_construction, :for_tiers_with_notification, procedure: procedure) }
|
let(:dossier_for_tiers) { create(:dossier, :en_construction, :for_tiers_with_notification, procedure: procedure) }
|
||||||
let(:dossier_for_tiers_without_notif) { create(:dossier, :en_construction, :for_tiers_without_notification, procedure: procedure) }
|
let(:dossier_for_tiers_without_notif) { create(:dossier, :en_construction, :for_tiers_without_notification, procedure: procedure) }
|
||||||
let(:fake_justificatif) { fixture_file_upload('spec/fixtures/files/piece_justificative_0.pdf', 'application/pdf') }
|
let(:fake_justificatif) { fixture_file_upload('spec/fixtures/files/piece_justificative_0.pdf', 'application/pdf') }
|
||||||
|
@ -376,6 +378,34 @@ describe Instructeurs::DossiersController, type: :controller do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "with accuse de lecture procedure" do
|
||||||
|
before do
|
||||||
|
dossier_accuse_lecture.passer_en_instruction!(instructeur: instructeur)
|
||||||
|
sign_in(instructeur.user)
|
||||||
|
end
|
||||||
|
context 'with classer_sans_suite' do
|
||||||
|
subject { post :terminer, params: { process_action: "classer_sans_suite", procedure_id: procedure_accuse_lecture.id, dossier_id: dossier_accuse_lecture.id }, format: :turbo_stream }
|
||||||
|
|
||||||
|
it 'Notification accuse de lecture email is sent and not the others' do
|
||||||
|
expect(NotificationMailer).to receive(:send_accuse_lecture_notification)
|
||||||
|
.with(dossier_accuse_lecture).and_return(NotificationMailer)
|
||||||
|
expect(NotificationMailer).to receive(:deliver_later)
|
||||||
|
|
||||||
|
expect(NotificationMailer).not_to receive(:send_sans_suite_notification)
|
||||||
|
.with(dossier_accuse_lecture)
|
||||||
|
|
||||||
|
subject
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(subject.body).to include('header-top') }
|
||||||
|
|
||||||
|
it 'creates a commentaire' do
|
||||||
|
expect { subject }.to change { Commentaire.count }.by(1)
|
||||||
|
expect(dossier_accuse_lecture.commentaires.last.body).to eq("<p>Bonjour,</p><p>Nous vous informons qu'une décision sur votre dossier a été rendue.</p>Cordialement,<br>#{procedure_accuse_lecture.service.nom}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "with classer_sans_suite" do
|
context "with classer_sans_suite" do
|
||||||
before do
|
before do
|
||||||
dossier.passer_en_instruction!(instructeur: instructeur)
|
dossier.passer_en_instruction!(instructeur: instructeur)
|
||||||
|
|
|
@ -283,6 +283,10 @@ FactoryBot.define do
|
||||||
referentiel_de_programmation: { c: 3 })
|
referentiel_de_programmation: { c: 3 })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
trait :accuse_lecture do
|
||||||
|
accuse_lecture { true }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,25 @@ RSpec.describe NotificationMailer, type: :mailer do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'send_notification_for_tiers with accuse lecture procedure' do
|
||||||
|
let(:dossier_for_tiers) { create(:dossier, :accepte, :for_tiers_with_notification, procedure: create(:procedure, :accuse_lecture, :for_individual)) }
|
||||||
|
|
||||||
|
subject { described_class.send_notification_for_tiers(dossier_for_tiers) }
|
||||||
|
|
||||||
|
it { expect(subject.subject).to include("Votre dossier rempli par le mandataire #{dossier_for_tiers.mandataire_first_name} #{dossier_for_tiers.mandataire_last_name} a été mis à jour") }
|
||||||
|
it { expect(subject.to).to eq([dossier_for_tiers.individual.email]) }
|
||||||
|
it { expect(subject.body).to include("a été traité le") }
|
||||||
|
it { expect(subject.body).to include("Pour en savoir plus, veuillez vous rapprocher de\r\n<a href=\"mailto:#{dossier_for_tiers.user.email}\">#{dossier_for_tiers.user.email}</a>.") }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'send_accuse_lecture_notification' do
|
||||||
|
let(:dossier) { create(:dossier, :accepte, procedure: create(:procedure, :accuse_lecture)) }
|
||||||
|
subject { described_class.send_accuse_lecture_notification(dossier) }
|
||||||
|
|
||||||
|
it { expect(subject.subject).to include("La décision a été rendue pour votre démarche #{dossier.procedure.libelle}") }
|
||||||
|
it { expect(subject.body).to include("Pour en connaitre la nature, veuillez vous connecter à votre compte\r\n<a href=\"#{dossier_url(dossier)}\">demarches-simplifiees.fr</a>") }
|
||||||
|
end
|
||||||
|
|
||||||
describe 'send_en_construction_notification' do
|
describe 'send_en_construction_notification' do
|
||||||
let(:dossier) { create(:dossier, :en_construction, :with_individual, user: user, procedure:) }
|
let(:dossier) { create(:dossier, :en_construction, :with_individual, user: user, procedure:) }
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,10 @@ class NotificationMailerPreview < ActionMailer::Preview
|
||||||
NotificationMailer.send_notification_for_tiers(dossier)
|
NotificationMailer.send_notification_for_tiers(dossier)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def send_accuse_lecture_notification
|
||||||
|
NotificationMailer.send_accuse_lecture_notification(dossier)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def dossier
|
def dossier
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
describe 'user access to the list of their dossiers', js: true do
|
describe 'user access to the list of their dossiers', js: true do
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
|
let(:procedure_accuse_lecture) { create(:procedure, :accuse_lecture) }
|
||||||
let!(:dossier_brouillon) { create(:dossier, user: user) }
|
let!(:dossier_brouillon) { create(:dossier, user: user) }
|
||||||
let!(:dossier_en_construction) { create(:dossier, :with_populated_champs, :en_construction, user: user) }
|
let!(:dossier_en_construction) { create(:dossier, :with_populated_champs, :en_construction, user: user) }
|
||||||
let!(:dossier_en_construction_2) { create(:dossier, :en_construction, user: user) }
|
let!(:dossier_en_construction_2) { create(:dossier, :en_construction, user: user) }
|
||||||
|
@ -9,6 +10,8 @@ describe 'user access to the list of their dossiers', js: true do
|
||||||
let!(:dossier_a_corriger) { create(:dossier_correction, dossier: dossier_en_construction_2) }
|
let!(:dossier_a_corriger) { create(:dossier_correction, dossier: dossier_en_construction_2) }
|
||||||
let!(:dossier_archived) { create(:dossier, :en_instruction, :archived, user: user) }
|
let!(:dossier_archived) { create(:dossier, :en_instruction, :archived, user: user) }
|
||||||
let!(:dossier_for_tiers) { create(:dossier, :en_instruction, :for_tiers_with_notification, user: user) }
|
let!(:dossier_for_tiers) { create(:dossier, :en_instruction, :for_tiers_with_notification, user: user) }
|
||||||
|
let!(:dossier_en_construction_with_accuse_lecture) { create(:dossier, :en_construction, user: user, procedure: procedure_accuse_lecture) }
|
||||||
|
let!(:dossier_accepte_with_accuse_lecture) { create(:dossier, :accepte, user: user, procedure: procedure_accuse_lecture) }
|
||||||
let(:dossiers_per_page) { 25 }
|
let(:dossiers_per_page) { 25 }
|
||||||
let(:last_updated_dossier) { dossier_en_construction }
|
let(:last_updated_dossier) { dossier_en_construction }
|
||||||
|
|
||||||
|
@ -31,8 +34,8 @@ describe 'user access to the list of their dossiers', js: true do
|
||||||
expect(page).to have_content(dossier_en_construction.procedure.libelle)
|
expect(page).to have_content(dossier_en_construction.procedure.libelle)
|
||||||
expect(page).to have_content(dossier_en_instruction.procedure.libelle)
|
expect(page).to have_content(dossier_en_instruction.procedure.libelle)
|
||||||
expect(page).to have_content(dossier_archived.procedure.libelle)
|
expect(page).to have_content(dossier_archived.procedure.libelle)
|
||||||
expect(page).to have_text('6 en cours')
|
expect(page).to have_text('7 en cours')
|
||||||
expect(page).to have_text('2 traités')
|
expect(page).to have_text('3 traités')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'the list must be ordered by last updated' do
|
it 'the list must be ordered by last updated' do
|
||||||
|
@ -55,8 +58,8 @@ describe 'user access to the list of their dossiers', js: true do
|
||||||
page.click_link("Suivant")
|
page.click_link("Suivant")
|
||||||
page.click_link("Suivant")
|
page.click_link("Suivant")
|
||||||
expect(page).to have_link(dossier_en_instruction.procedure.libelle)
|
expect(page).to have_link(dossier_en_instruction.procedure.libelle)
|
||||||
expect(page).to have_text('6 en cours')
|
expect(page).to have_text('7 en cours')
|
||||||
expect(page).to have_text('2 traités')
|
expect(page).to have_text('3 traités')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -70,9 +73,9 @@ describe 'user access to the list of their dossiers', js: true do
|
||||||
|
|
||||||
context 'when user uses filter' do
|
context 'when user uses filter' do
|
||||||
scenario 'user filters state on tab "en-cours"' do
|
scenario 'user filters state on tab "en-cours"' do
|
||||||
expect(page).to have_text('6 en cours')
|
expect(page).to have_text('7 en cours')
|
||||||
expect(page).to have_text('2 traités')
|
expect(page).to have_text('3 traités')
|
||||||
expect(page).to have_text('6 sur 6 dossiers')
|
expect(page).to have_text('7 sur 7 dossiers')
|
||||||
|
|
||||||
click_on('Sélectionner un filtre')
|
click_on('Sélectionner un filtre')
|
||||||
expect(page).to have_select 'Statut', selected: 'Sélectionner un statut', options: ['Sélectionner un statut', 'Brouillon', 'En construction', 'En instruction', 'À corriger']
|
expect(page).to have_select 'Statut', selected: 'Sélectionner un statut', options: ['Sélectionner un statut', 'Brouillon', 'En construction', 'En instruction', 'À corriger']
|
||||||
|
@ -92,9 +95,9 @@ describe 'user access to the list of their dossiers', js: true do
|
||||||
|
|
||||||
scenario 'user filters state on tab "traité"' do
|
scenario 'user filters state on tab "traité"' do
|
||||||
visit dossiers_path(statut: 'traites')
|
visit dossiers_path(statut: 'traites')
|
||||||
expect(page).to have_text('6 en cours')
|
expect(page).to have_text('7 en cours')
|
||||||
expect(page).to have_text('2 traités')
|
expect(page).to have_text('3 traités')
|
||||||
expect(page).to have_text('2 sur 2 dossiers')
|
expect(page).to have_text('3 sur 3 dossiers')
|
||||||
|
|
||||||
click_on('Sélectionner un filtre')
|
click_on('Sélectionner un filtre')
|
||||||
expect(page).to have_select 'Statut', selected: 'Sélectionner un statut', options: ['Sélectionner un statut', 'Accepté', 'Refusé', 'Classé sans suite']
|
expect(page).to have_select 'Statut', selected: 'Sélectionner un statut', options: ['Sélectionner un statut', 'Accepté', 'Refusé', 'Classé sans suite']
|
||||||
|
@ -105,18 +108,29 @@ describe 'user access to the list of their dossiers', js: true do
|
||||||
|
|
||||||
click_on('Sélectionner un filtre')
|
click_on('Sélectionner un filtre')
|
||||||
click_on('Annuler')
|
click_on('Annuler')
|
||||||
expect(page).to have_text('2 sur 2 dossiers')
|
|
||||||
|
click_on('Sélectionner un filtre')
|
||||||
|
expect(page).to have_select 'Statut', selected: 'Sélectionner un statut', options: ['Sélectionner un statut', 'Accepté', 'Refusé', 'Classé sans suite']
|
||||||
|
select('Accepté', from: 'Statut')
|
||||||
|
click_on('Appliquer les filtres')
|
||||||
|
# we expect 1 dossier because we want do hide decision for dossier with accuse de lecture
|
||||||
|
expect(page).to have_text('1 dossier')
|
||||||
|
expect(page).to have_select 'Statut', selected: 'Accepté', options: ['Sélectionner un statut', 'Accepté', 'Refusé', 'Classé sans suite']
|
||||||
|
|
||||||
|
click_on('Sélectionner un filtre')
|
||||||
|
click_on('Annuler')
|
||||||
|
expect(page).to have_text('3 sur 3 dossiers')
|
||||||
expect(page).to have_select 'Statut', selected: 'Sélectionner un statut', options: ['Sélectionner un statut', 'Accepté', 'Refusé', 'Classé sans suite']
|
expect(page).to have_select 'Statut', selected: 'Sélectionner un statut', options: ['Sélectionner un statut', 'Accepté', 'Refusé', 'Classé sans suite']
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'user filters by created_at' do
|
scenario 'user filters by created_at' do
|
||||||
dossier_en_construction.update!(created_at: Date.yesterday)
|
dossier_en_construction.update!(created_at: Date.yesterday)
|
||||||
|
|
||||||
expect(page).to have_text('6 sur 6 dossiers')
|
expect(page).to have_text('7 sur 7 dossiers')
|
||||||
click_on('Sélectionner un filtre')
|
click_on('Sélectionner un filtre')
|
||||||
fill_in 'from_created_at_date', with: Date.today
|
fill_in 'from_created_at_date', with: Date.today
|
||||||
click_on('Appliquer les filtres')
|
click_on('Appliquer les filtres')
|
||||||
expect(page).to have_text('5 sur 5 dossiers')
|
expect(page).to have_text('6 sur 6 dossiers')
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'user uses multiple filters' do
|
scenario 'user uses multiple filters' do
|
||||||
|
@ -124,26 +138,26 @@ describe 'user access to the list of their dossiers', js: true do
|
||||||
|
|
||||||
expect(page).to have_select 'Statut', selected: 'Sélectionner un statut', options: ['Sélectionner un statut', 'Brouillon', 'En construction', 'En instruction', 'À corriger']
|
expect(page).to have_select 'Statut', selected: 'Sélectionner un statut', options: ['Sélectionner un statut', 'Brouillon', 'En construction', 'En instruction', 'À corriger']
|
||||||
|
|
||||||
expect(page).to have_text('6 sur 6 dossiers')
|
expect(page).to have_text('7 sur 7 dossiers')
|
||||||
click_on('Sélectionner un filtre')
|
click_on('Sélectionner un filtre')
|
||||||
fill_in 'from_created_at_date', with: Date.today
|
fill_in 'from_created_at_date', with: Date.today
|
||||||
click_on('Appliquer les filtres')
|
click_on('Appliquer les filtres')
|
||||||
expect(page).to have_text('5 sur 5 dossiers')
|
expect(page).to have_text('6 sur 6 dossiers')
|
||||||
expect(page).to have_text('1 filtre actif')
|
expect(page).to have_text('1 filtre actif')
|
||||||
|
|
||||||
click_on('Sélectionner un filtre')
|
click_on('Sélectionner un filtre')
|
||||||
select('En construction', from: 'Statut')
|
select('En construction', from: 'Statut')
|
||||||
click_on('Appliquer les filtres')
|
click_on('Appliquer les filtres')
|
||||||
expect(page).to have_text('1 dossier')
|
expect(page).to have_text('2 dossiers')
|
||||||
expect(page).to have_text('2 filtres actifs')
|
expect(page).to have_text('2 filtres actifs')
|
||||||
|
|
||||||
click_on('Sélectionner un filtre')
|
click_on('Sélectionner un filtre')
|
||||||
fill_in 'from_depose_at_date', with: Date.today
|
fill_in 'from_depose_at_date', with: Date.today
|
||||||
click_on('Appliquer les filtres')
|
click_on('Appliquer les filtres')
|
||||||
expect(page).to have_text('1 dossier')
|
expect(page).to have_text('2 sur 2 dossiers')
|
||||||
expect(page).to have_text('3 filtres actifs')
|
expect(page).to have_text('3 filtres actifs')
|
||||||
click_on('3 filtres actifs')
|
click_on('3 filtres actifs')
|
||||||
expect(page).to have_text('6 sur 6 dossiers')
|
expect(page).to have_text('7 sur 7 dossiers')
|
||||||
expect(page).not_to have_text('5 filtres actifs')
|
expect(page).not_to have_text('5 filtres actifs')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -285,8 +299,8 @@ describe 'user access to the list of their dossiers', js: true do
|
||||||
describe "filter by procedure" do
|
describe "filter by procedure" do
|
||||||
context "when dossiers are on different procedures" do
|
context "when dossiers are on different procedures" do
|
||||||
it "can filter by procedure" do
|
it "can filter by procedure" do
|
||||||
expect(page).to have_text('6 en cours')
|
expect(page).to have_text('7 en cours')
|
||||||
expect(page).to have_text('2 traités')
|
expect(page).to have_text('3 traités')
|
||||||
expect(page).to have_select('procedure_id', selected: 'Toutes les démarches')
|
expect(page).to have_select('procedure_id', selected: 'Toutes les démarches')
|
||||||
select dossier_brouillon.procedure.libelle, from: 'procedure_id'
|
select dossier_brouillon.procedure.libelle, from: 'procedure_id'
|
||||||
expect(page).to have_text('1 en cours')
|
expect(page).to have_text('1 en cours')
|
||||||
|
|
|
@ -173,4 +173,32 @@ describe 'instructeurs/dossiers/show', type: :view do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'accuse de lecture ' do
|
||||||
|
context 'dossier not termine' do
|
||||||
|
let(:dossier) { create(:dossier, :en_instruction, procedure: create(:procedure, :accuse_lecture)) }
|
||||||
|
|
||||||
|
it 'does not display a text about accuse de lecture for instructeur' do
|
||||||
|
expect(subject).not_to have_text('Cette démarche est soumise à un accusé de lecture')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'dossier termine with accuse de lecture not accepted by user' do
|
||||||
|
let(:dossier) { create(:dossier, :accepte, procedure: create(:procedure, :accuse_lecture)) }
|
||||||
|
|
||||||
|
it 'displays a text about accuse de lecture for instructeur' do
|
||||||
|
expect(subject).to have_text('Cette démarche est soumise à un accusé de lecture')
|
||||||
|
expect(subject).to have_text('L’usager n’a pas encore pris connaissance de la décision concernant son dossier')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'dossier termine with accuse de lecture accepted by user' do
|
||||||
|
let(:dossier) { create(:dossier, :accepte, accuse_lecture_agreement_at: Time.zone.now, procedure: create(:procedure, :accuse_lecture)) }
|
||||||
|
|
||||||
|
it 'displays a text about accuse de lecture for instructeur' do
|
||||||
|
expect(subject).to have_text('Cette démarche est soumise à un accusé de lecture')
|
||||||
|
expect(subject).to have_text('L’usager a pris connaissance de la décision concernant son dossier le')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
describe 'shared/dossiers/_infos_generales', type: :view do
|
describe 'shared/dossiers/_infos_generales', type: :view do
|
||||||
let(:dossier) { create(:dossier, :en_construction) }
|
let(:dossier) { create(:dossier, :en_construction) }
|
||||||
subject { render }
|
subject { render 'shared/dossiers/infos_generales', dossier: dossier, profile: 'instructeur' }
|
||||||
before do
|
before do
|
||||||
sign_in(current_role.user)
|
sign_in(current_role.user)
|
||||||
allow(view).to receive(:current_instructeur).and_return(current_role)
|
allow(view).to receive(:current_instructeur).and_return(current_role)
|
||||||
|
@ -32,6 +32,14 @@ describe 'shared/dossiers/_infos_generales', type: :view do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with a motivation and procedure with accuse de lecture' do
|
||||||
|
let(:dossier) { create :dossier, :accepte, :with_justificatif, procedure: create(:procedure, :accuse_lecture) }
|
||||||
|
|
||||||
|
it 'still displays the motivation text for the instructeur' do
|
||||||
|
expect(subject).to have_content(dossier.motivation)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'with an attestation' do
|
context 'with an attestation' do
|
||||||
let(:dossier) { create :dossier, :accepte, :with_attestation }
|
let(:dossier) { create :dossier, :accepte, :with_attestation }
|
||||||
|
|
||||||
|
|
|
@ -59,4 +59,23 @@ describe 'users/dossiers/demande', type: :view do
|
||||||
expect(rendered).to have_text(dossier.individual.email.to_s)
|
expect(rendered).to have_text(dossier.individual.email.to_s)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when a dossier is accepte with motivation' do
|
||||||
|
let(:dossier) { create(:dossier, :accepte, :with_motivation) }
|
||||||
|
|
||||||
|
it 'displays the motivation' do
|
||||||
|
expect(rendered).not_to have_text('Cette démarche est soumise à un accusé de lecture.')
|
||||||
|
expect(rendered).to have_text('Motivation')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when a dossier is accepte with motivation and with accuse de lecture' do
|
||||||
|
let(:dossier) { create(:dossier, :accepte, :with_motivation, procedure: create(:procedure, :accuse_lecture)) }
|
||||||
|
|
||||||
|
it 'display information about accuse de lecture and not the motivation' do
|
||||||
|
expect(rendered).to have_text('Cette démarche est soumise à un accusé de lecture.')
|
||||||
|
expect(rendered).not_to have_text('Motivation')
|
||||||
|
expect(rendered).not_to have_text('L’usager n’a pas encore pris connaissance de la décision concernant son dossier')
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
describe 'users/dossiers/index', type: :view do
|
describe 'users/dossiers/index', type: :view do
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
|
let(:procedure_accuse_lecture) { create(:procedure, :accuse_lecture) }
|
||||||
let(:dossier_brouillon) { create(:dossier, state: Dossier.states.fetch(:brouillon), user: user) }
|
let(:dossier_brouillon) { create(:dossier, state: Dossier.states.fetch(:brouillon), user: user) }
|
||||||
let(:dossier_en_construction) { create(:dossier, state: Dossier.states.fetch(:en_construction), user: user) }
|
let(:dossier_en_construction) { create(:dossier, state: Dossier.states.fetch(:en_construction), user: user) }
|
||||||
|
let(:dossier_en_construction_with_accuse_lecture) { create(:dossier, state: Dossier.states.fetch(:en_construction), user: user, procedure: procedure_accuse_lecture) }
|
||||||
let(:dossier_termine) { create(:dossier, state: Dossier.states.fetch(:accepte), user: user) }
|
let(:dossier_termine) { create(:dossier, state: Dossier.states.fetch(:accepte), user: user) }
|
||||||
|
let(:dossier_termine_with_accuse_lecture) { create(:dossier, state: Dossier.states.fetch(:accepte), user: user, procedure: procedure_accuse_lecture) }
|
||||||
let(:dossiers_invites) { [] }
|
let(:dossiers_invites) { [] }
|
||||||
let(:user_dossiers) { Kaminari.paginate_array([dossier_brouillon, dossier_en_construction, dossier_termine]).page(1) }
|
let(:user_dossiers) { Kaminari.paginate_array([dossier_brouillon, dossier_en_construction, dossier_termine, dossier_en_construction_with_accuse_lecture, dossier_termine_with_accuse_lecture]).page(1) }
|
||||||
let(:statut) { 'en-cours' }
|
let(:statut) { 'en-cours' }
|
||||||
let(:filter) { DossiersFilter.new(user, ActionController::Parameters.new(random_param: 'random_param')) }
|
let(:filter) { DossiersFilter.new(user, ActionController::Parameters.new(random_param: 'random_param')) }
|
||||||
|
|
||||||
|
@ -28,7 +31,7 @@ describe 'users/dossiers/index', type: :view do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'affiche les dossiers' do
|
it 'affiche les dossiers' do
|
||||||
expect(rendered).to have_selector('.card', count: 3)
|
expect(rendered).to have_selector('.card', count: 5)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'affiche les informations des dossiers' do
|
it 'affiche les informations des dossiers' do
|
||||||
|
@ -40,6 +43,9 @@ describe 'users/dossiers/index', type: :view do
|
||||||
expect(rendered).to have_text(dossier_en_construction.id.to_s)
|
expect(rendered).to have_text(dossier_en_construction.id.to_s)
|
||||||
expect(rendered).to have_text(dossier_en_construction.procedure.libelle)
|
expect(rendered).to have_text(dossier_en_construction.procedure.libelle)
|
||||||
expect(rendered).to have_link(dossier_en_construction.procedure.libelle, href: dossier_path(dossier_en_construction))
|
expect(rendered).to have_link(dossier_en_construction.procedure.libelle, href: dossier_path(dossier_en_construction))
|
||||||
|
|
||||||
|
expect(rendered).to have_selector('.fr-badge', text: 'traité', count: 1)
|
||||||
|
expect(rendered).to have_selector('.fr-badge', text: 'en construction', count: 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'n’affiche pas une alerte pour continuer à remplir un dossier' do
|
it 'n’affiche pas une alerte pour continuer à remplir un dossier' do
|
||||||
|
@ -132,13 +138,13 @@ describe 'users/dossiers/index', type: :view do
|
||||||
|
|
||||||
it "cache key depends on dossiers list" do
|
it "cache key depends on dossiers list" do
|
||||||
render
|
render
|
||||||
expect(rendered).to have_text(/3\s+en cours/)
|
expect(rendered).to have_text(/5\s+en cours/)
|
||||||
|
|
||||||
assign(:user_dossiers, Kaminari.paginate_array(user_dossiers.concat([create(:dossier, :en_construction, user: user)])).page(1))
|
assign(:user_dossiers, Kaminari.paginate_array(user_dossiers.concat([create(:dossier, :en_construction, user: user)])).page(1))
|
||||||
user.reload
|
user.reload
|
||||||
|
|
||||||
render
|
render
|
||||||
expect(rendered).to have_text(/4\s+en cours/)
|
expect(rendered).to have_text(/6\s+en cours/)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "cache key dpeends on dossier invites" do
|
it "cache key dpeends on dossier invites" do
|
||||||
|
|
|
@ -18,6 +18,26 @@ describe 'users/dossiers/show/header', type: :view do
|
||||||
expect(rendered).to have_link("Demande", href: demande_dossier_path(dossier))
|
expect(rendered).to have_link("Demande", href: demande_dossier_path(dossier))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when the procedure is with accuse de lecture with a dossier en construction" do
|
||||||
|
let(:procedure) { create(:procedure, :accuse_lecture) }
|
||||||
|
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
|
||||||
|
|
||||||
|
it "affiche les informations du dossier" do
|
||||||
|
expect(rendered).to have_text("Dossier nº #{dossier.id}")
|
||||||
|
expect(rendered).to have_text("en construction")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when the procedure is with accuse de lecture with a dossier termine" do
|
||||||
|
let(:procedure) { create(:procedure, :accuse_lecture) }
|
||||||
|
let(:dossier) { create(:dossier, :accepte, procedure: procedure) }
|
||||||
|
|
||||||
|
it "n'affiche pas les informations de décision" do
|
||||||
|
expect(rendered).to have_text("Dossier nº #{dossier.id}")
|
||||||
|
expect(rendered).to have_text("traité")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "when the procedure is closed with a dossier en construction" do
|
context "when the procedure is closed with a dossier en construction" do
|
||||||
let(:procedure) { create(:procedure, :closed) }
|
let(:procedure) { create(:procedure, :closed) }
|
||||||
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
|
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
|
||||||
|
|
|
@ -92,4 +92,12 @@ describe 'users/dossiers/show/_status_overview', type: :view do
|
||||||
it { is_expected.to have_selector('.status-explanation .sans-suite') }
|
it { is_expected.to have_selector('.status-explanation .sans-suite') }
|
||||||
it { is_expected.to have_text(dossier.motivation) }
|
it { is_expected.to have_text(dossier.motivation) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when terminé but the procedure has an accuse de lecture' do
|
||||||
|
let(:dossier) { create(:dossier, :sans_suite, :with_motivation, procedure: create(:procedure, :accuse_lecture)) }
|
||||||
|
|
||||||
|
it { is_expected.not_to have_selector('.status-explanation .sans-suite') }
|
||||||
|
it { is_expected.not_to have_text(dossier.motivation) }
|
||||||
|
it { is_expected.to have_text('Cette démarche est soumise à un accusé de lecture.') }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue