Merge pull request #9372 from colinux/svr
Admin: permet l'activation du SVR
This commit is contained in:
commit
f28739d648
17 changed files with 261 additions and 36 deletions
|
@ -3,6 +3,8 @@
|
||||||
class Instructeurs::EnConstructionMenuComponent < ApplicationComponent
|
class Instructeurs::EnConstructionMenuComponent < ApplicationComponent
|
||||||
attr_reader :dossier
|
attr_reader :dossier
|
||||||
|
|
||||||
|
delegate :sva_svr_enabled?, to: :"dossier.procedure"
|
||||||
|
|
||||||
def initialize(dossier:)
|
def initialize(dossier:)
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
end
|
end
|
||||||
|
@ -22,11 +24,11 @@ class Instructeurs::EnConstructionMenuComponent < ApplicationComponent
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def sva?
|
def sva_svr_resume_method
|
||||||
dossier.procedure.sva?
|
|
||||||
end
|
|
||||||
|
|
||||||
def sva_resume_method
|
|
||||||
dossier.procedure.sva_svr_configuration.resume
|
dossier.procedure.sva_svr_configuration.resume
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def sva_svr_human_decision
|
||||||
|
dossier.procedure.sva_svr_configuration.human_decision
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
%h4= t('.request_correction')
|
%h4= t('.request_correction')
|
||||||
L’usager sera informé que des modifications sont attendues.
|
L’usager sera informé que des modifications sont attendues.
|
||||||
|
|
||||||
- if sva?
|
- if sva_svr_enabled?
|
||||||
- if sva_resume_method == :reset
|
- if sva_svr_resume_method == :reset
|
||||||
Le délai du SVA sera réinitialisé lorqu’il déclarera avoir complété le dossier.
|
Le délai du #{sva_svr_human_decision} sera réinitialisé lorqu’il déclarera avoir complété le dossier.
|
||||||
- else
|
- else
|
||||||
Le délai du SVA reprendra lorsqu’il déclarera avoir corrigé le dossier.
|
Le délai du #{sva_svr_human_decision} reprendra lorsqu’il déclarera avoir corrigé le dossier.
|
||||||
|
|
||||||
- menu.with_item(class: "inactive form-inside fr-pt-1v") do
|
- menu.with_item(class: "inactive form-inside fr-pt-1v") do
|
||||||
= render partial: 'instructeurs/dossiers/instruction_button_motivation', locals: { dossier:,
|
= render partial: 'instructeurs/dossiers/instruction_button_motivation', locals: { dossier:,
|
||||||
|
@ -36,14 +36,14 @@
|
||||||
title: 'Marquer en attente de corrections',
|
title: 'Marquer en attente de corrections',
|
||||||
confirm: 'Envoyer la demande de corrections ?'}
|
confirm: 'Envoyer la demande de corrections ?'}
|
||||||
|
|
||||||
- if sva?
|
- if sva_svr_enabled?
|
||||||
- menu.with_item do
|
- menu.with_item do
|
||||||
= link_to('#', onclick: "DS.showMotivation(event, 'pending_completion');", role: 'menuitem') do
|
= link_to('#', onclick: "DS.showMotivation(event, 'pending_completion');", role: 'menuitem') do
|
||||||
%span.fr-icon.fr-icon-error-warning-line.fr-text-default--warning.fr-mt-1v{ "aria-hidden": "true" }
|
%span.fr-icon.fr-icon-error-warning-line.fr-text-default--warning.fr-mt-1v{ "aria-hidden": "true" }
|
||||||
|
|
||||||
.dropdown-description
|
.dropdown-description
|
||||||
%h4= t('.request_completion')
|
%h4= t('.request_completion')
|
||||||
L’usager sera informé que son dossier est incomplet. Le délai du SVA sera réinitialisé lorque il déclarera avoir complété le dossier.
|
L’usager sera informé que son dossier est incomplet. Le délai du #{sva_svr_human_decision} sera réinitialisé lorque il déclarera avoir complété le dossier.
|
||||||
|
|
||||||
- menu.with_item(class: "inactive form-inside fr-pt-1v") do
|
- menu.with_item(class: "inactive form-inside fr-pt-1v") do
|
||||||
= render partial: 'instructeurs/dossiers/instruction_button_motivation', locals: { dossier:,
|
= render partial: 'instructeurs/dossiers/instruction_button_motivation', locals: { dossier:,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
fr:
|
fr:
|
||||||
title: "Silence Vaut Accord"
|
title: "Silence Vaut Accord ou Rejet"
|
||||||
subtitle: "Accepter ou Refuser un dossier après un délai"
|
subtitle: "Accepter ou Refuser un dossier après un délai"
|
||||||
ready: "Configuré"
|
ready: "Configuré"
|
||||||
needs_configuration: "À configurer"
|
needs_configuration: "À configurer"
|
||||||
|
|
|
@ -20,7 +20,7 @@ class Procedure::SVASVRFormComponent < ApplicationComponent
|
||||||
[
|
[
|
||||||
{ label: t("disabled", scope:), value: "disabled", disabled: form_disabled? },
|
{ label: t("disabled", scope:), value: "disabled", disabled: form_disabled? },
|
||||||
{ label: t("sva", scope:), value: "sva", hint: t("sva_hint", scope:) },
|
{ label: t("sva", scope:), value: "sva", hint: t("sva_hint", scope:) },
|
||||||
{ label: t("svr", scope:), value: "svr", hint: t("svr_hint", scope:), disabled: true, after_label: tag.span("Disponible prochainement", class: "fr-badge fr-badge--sm fr-ml-1w") }
|
{ label: t("svr", scope:), value: "svr", hint: t("svr_hint", scope:) }
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,8 @@ fr:
|
||||||
svr_hint: "Un dossier est automatiquement refusé si aucun n’instructeur ne s’est prononcé avant le délai imparti"
|
svr_hint: "Un dossier est automatiquement refusé si aucun n’instructeur ne s’est prononcé avant le délai imparti"
|
||||||
resume_buttons:
|
resume_buttons:
|
||||||
continue_label: "Reprendre le décompte depuis le moment où il s’était arrêté"
|
continue_label: "Reprendre le décompte depuis le moment où il s’était arrêté"
|
||||||
continue_hint: "Exemple: si l’instructeur demande des corrections d’un dossier complet alors qu’il reste 10 jours avant la décision automatique, et que le dossier est re-déposé le 15 avril, il sera automatiquement accepté le 25 avril, sauf à ce que l’instructeur se prononce d’ici là ou demande à nouveau des corrections. En revanche si l’instructeur demande à compléter le dossier, le délai sera réinitialisé."
|
continue_hint: "Exemple: si l’instructeur demande des corrections d’un dossier complet alors qu’il reste 10 jours avant la décision automatique, et que le dossier est re-déposé le 15 avril, il sera automatiquement accepté le 26 avril, sauf à ce que l’instructeur se prononce d’ici là ou demande à nouveau des corrections. En revanche si l’instructeur demande à compléter le dossier, le délai sera réinitialisé."
|
||||||
reset_label: "Réinitialiser le délai"
|
reset_label: "Réinitialiser le délai"
|
||||||
reset_hint: "Exemple: si le dossier est re-déposé le 15 avril et que le délai est de 2 mois, la décision sera automatiquement prise le 15 juin, sauf à ce que l’instructeur se prononce d’ici là ou demande à nouveau des corrections."
|
reset_hint: "Exemple: si le dossier est re-déposé le 15 avril et que le délai est de 2 mois, la décision sera automatiquement prise le 16 juin, sauf à ce que l’instructeur se prononce d’ici là ou demande à nouveau des corrections."
|
||||||
notice_new_files_only: "Information : si vous activez cette règle, seuls les nouveaux dossiers déposés y seront soumis."
|
notice_new_files_only: "Information : si vous activez cette règle, seuls les nouveaux dossiers déposés y seront soumis."
|
||||||
notice_edit_denied: "Avertissement : le changement ou la désactivation du SVA/SVR est impossible."
|
notice_edit_denied: "Avertissement : le changement ou la désactivation du SVA/SVR est impossible."
|
||||||
|
|
|
@ -96,6 +96,12 @@ class Dossier < ApplicationRecord
|
||||||
processed_at: processed_at)
|
processed_at: processed_at)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def refuser_automatiquement(processed_at: Time.zone.now, motivation:)
|
||||||
|
build(state: Dossier.states.fetch(:refuse),
|
||||||
|
motivation: motivation,
|
||||||
|
processed_at: processed_at)
|
||||||
|
end
|
||||||
|
|
||||||
def classer_sans_suite(motivation: nil, instructeur: nil, processed_at: Time.zone.now)
|
def classer_sans_suite(motivation: nil, instructeur: nil, processed_at: Time.zone.now)
|
||||||
build(state: Dossier.states.fetch(:sans_suite),
|
build(state: Dossier.states.fetch(:sans_suite),
|
||||||
instructeur_email: instructeur&.email,
|
instructeur_email: instructeur&.email,
|
||||||
|
@ -177,6 +183,10 @@ class Dossier < ApplicationRecord
|
||||||
transitions from: :en_instruction, to: :refuse, guard: :can_terminer?
|
transitions from: :en_instruction, to: :refuse, guard: :can_terminer?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
event :refuser_automatiquement, after: :after_refuser_automatiquement do
|
||||||
|
transitions from: :en_instruction, to: :refuse, guard: :can_refuser_automatiquement?
|
||||||
|
end
|
||||||
|
|
||||||
event :classer_sans_suite, after: :after_classer_sans_suite do
|
event :classer_sans_suite, after: :after_classer_sans_suite do
|
||||||
transitions from: :en_instruction, to: :sans_suite, guard: :can_terminer?
|
transitions from: :en_instruction, to: :sans_suite, guard: :can_terminer?
|
||||||
end
|
end
|
||||||
|
@ -526,7 +536,14 @@ class Dossier < ApplicationRecord
|
||||||
def can_accepter_automatiquement?
|
def can_accepter_automatiquement?
|
||||||
return false unless can_terminer?
|
return false unless can_terminer?
|
||||||
return true if declarative_triggered_at.nil? && procedure.declarative_accepte? && en_construction?
|
return true if declarative_triggered_at.nil? && procedure.declarative_accepte? && en_construction?
|
||||||
return true if procedure.sva? && sva_svr_decision_triggered_at.nil? && !pending_correction? && (sva_svr_decision_on.today? || sva_svr_decision_on.past?)
|
return true if procedure.sva? && can_terminer_automatiquement_by_sva_svr?
|
||||||
|
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
def can_refuser_automatiquement?
|
||||||
|
return false unless can_terminer?
|
||||||
|
return true if procedure.svr? && can_terminer_automatiquement_by_sva_svr?
|
||||||
|
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
@ -559,6 +576,10 @@ class Dossier < ApplicationRecord
|
||||||
termine? || reason == :procedure_removed
|
termine? || reason == :procedure_removed
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def can_terminer_automatiquement_by_sva_svr?
|
||||||
|
sva_svr_decision_triggered_at.nil? && !pending_correction? && (sva_svr_decision_on.today? || sva_svr_decision_on.past?)
|
||||||
|
end
|
||||||
|
|
||||||
def any_etablissement_as_degraded_mode?
|
def any_etablissement_as_degraded_mode?
|
||||||
return true if etablissement&.as_degraded_mode?
|
return true if etablissement&.as_degraded_mode?
|
||||||
return true if champs_public_all.any? { _1.etablissement&.as_degraded_mode? }
|
return true if champs_public_all.any? { _1.etablissement&.as_degraded_mode? }
|
||||||
|
@ -996,7 +1017,7 @@ class Dossier < ApplicationRecord
|
||||||
if procedure.declarative_accepte?
|
if procedure.declarative_accepte?
|
||||||
self.en_instruction_at = self.processed_at
|
self.en_instruction_at = self.processed_at
|
||||||
self.declarative_triggered_at = self.processed_at
|
self.declarative_triggered_at = self.processed_at
|
||||||
elsif procedure.sva_svr_enabled?
|
elsif procedure.sva?
|
||||||
self.sva_svr_decision_triggered_at = self.processed_at
|
self.sva_svr_decision_triggered_at = self.processed_at
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1040,6 +1061,23 @@ class Dossier < ApplicationRecord
|
||||||
log_dossier_operation(instructeur, :refuser, self)
|
log_dossier_operation(instructeur, :refuser, self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def after_refuser_automatiquement
|
||||||
|
# Only SVR can refuse automatically
|
||||||
|
I18n.with_locale(user.locale || I18n.default_locale) do
|
||||||
|
self.motivation = I18n.t("shared.dossiers.motivation.refused_by_svr")
|
||||||
|
end
|
||||||
|
|
||||||
|
self.processed_at = traitements.refuser_automatiquement(motivation:).processed_at
|
||||||
|
self.sva_svr_decision_triggered_at = self.processed_at
|
||||||
|
|
||||||
|
save!
|
||||||
|
|
||||||
|
remove_titres_identite!
|
||||||
|
MailTemplatePresenterService.create_commentaire_for_state(self)
|
||||||
|
NotificationMailer.send_refuse_notification(self).deliver_later
|
||||||
|
log_automatic_dossier_operation(:refuser, self)
|
||||||
|
end
|
||||||
|
|
||||||
def after_classer_sans_suite(h)
|
def after_classer_sans_suite(h)
|
||||||
instructeur = h[:instructeur]
|
instructeur = h[:instructeur]
|
||||||
motivation = h[:motivation]
|
motivation = h[:motivation]
|
||||||
|
@ -1090,6 +1128,8 @@ class Dossier < ApplicationRecord
|
||||||
passer_automatiquement_en_instruction!
|
passer_automatiquement_en_instruction!
|
||||||
elsif en_instruction? && procedure.sva? && may_accepter_automatiquement?
|
elsif en_instruction? && procedure.sva? && may_accepter_automatiquement?
|
||||||
accepter_automatiquement!
|
accepter_automatiquement!
|
||||||
|
elsif en_instruction? && procedure.svr? && may_refuser_automatiquement?
|
||||||
|
refuser_automatiquement!
|
||||||
elsif will_save_change_to_sva_svr_decision_on?
|
elsif will_save_change_to_sva_svr_decision_on?
|
||||||
save! # we always want the most up to date decision when there is a pending correction
|
save! # we always want the most up to date decision when there is a pending correction
|
||||||
end
|
end
|
||||||
|
@ -1187,7 +1227,7 @@ class Dossier < ApplicationRecord
|
||||||
['Dernière mise à jour le', :updated_at],
|
['Dernière mise à jour le', :updated_at],
|
||||||
['Déposé le', :depose_at],
|
['Déposé le', :depose_at],
|
||||||
['Passé en instruction le', :en_instruction_at],
|
['Passé en instruction le', :en_instruction_at],
|
||||||
procedure.sva_svr_enabled? ? ["Date #{procedure.sva_svr_configuration.human_decision}", :sva_svr_decision_on] : nil,
|
procedure.sva_svr_enabled? ? ["Date décision #{procedure.sva_svr_configuration.human_decision}", :sva_svr_decision_on] : nil,
|
||||||
['Traité le', :processed_at],
|
['Traité le', :processed_at],
|
||||||
['Motivation de la décision', :motivation],
|
['Motivation de la décision', :motivation],
|
||||||
['Instructeurs', followers_instructeurs.map(&:email).join(' ')]
|
['Instructeurs', followers_instructeurs.map(&:email).join(' ')]
|
||||||
|
|
|
@ -26,8 +26,6 @@ class ProcedurePresentation < ApplicationRecord
|
||||||
validate :check_filters_max_length
|
validate :check_filters_max_length
|
||||||
|
|
||||||
def self_fields
|
def self_fields
|
||||||
sva_svr_enabled = procedure.sva_svr_enabled?
|
|
||||||
|
|
||||||
[
|
[
|
||||||
field_hash('self', 'created_at', type: :date),
|
field_hash('self', 'created_at', type: :date),
|
||||||
field_hash('self', 'updated_at', type: :date),
|
field_hash('self', 'updated_at', type: :date),
|
||||||
|
@ -35,8 +33,7 @@ class ProcedurePresentation < ApplicationRecord
|
||||||
field_hash('self', 'en_construction_at', type: :date),
|
field_hash('self', 'en_construction_at', type: :date),
|
||||||
field_hash('self', 'en_instruction_at', type: :date),
|
field_hash('self', 'en_instruction_at', type: :date),
|
||||||
field_hash('self', 'processed_at', type: :date),
|
field_hash('self', 'processed_at', type: :date),
|
||||||
sva_svr_enabled && field_hash('self', 'sva_svr_decision_on', type: :date),
|
*sva_svr_fields(for_filters: true),
|
||||||
sva_svr_enabled && field_hash('self', 'sva_svr_decision_before', type: :date, virtual: true),
|
|
||||||
field_hash('self', 'updated_since', type: :date, virtual: true),
|
field_hash('self', 'updated_since', type: :date, virtual: true),
|
||||||
field_hash('self', 'depose_since', type: :date, virtual: true),
|
field_hash('self', 'depose_since', type: :date, virtual: true),
|
||||||
field_hash('self', 'en_construction_since', type: :date, virtual: true),
|
field_hash('self', 'en_construction_since', type: :date, virtual: true),
|
||||||
|
@ -112,15 +109,32 @@ class ProcedurePresentation < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def displayed_fields_for_headers
|
def displayed_fields_for_headers
|
||||||
array = [
|
[
|
||||||
field_hash('self', 'id', classname: 'number-col'),
|
field_hash('self', 'id', classname: 'number-col'),
|
||||||
*displayed_fields,
|
*displayed_fields,
|
||||||
field_hash('self', 'state', classname: 'state-col')
|
field_hash('self', 'state', classname: 'state-col'),
|
||||||
|
*sva_svr_fields
|
||||||
]
|
]
|
||||||
|
end
|
||||||
|
|
||||||
array << field_hash('self', 'sva_svr_decision_on', classname: 'sva-col') if procedure.sva_svr_enabled?
|
def sva_svr_fields(for_filters: false)
|
||||||
|
return if !procedure.sva_svr_enabled?
|
||||||
|
|
||||||
array
|
i18n_scope = [:activerecord, :attributes, :procedure_presentation, :fields, :self]
|
||||||
|
|
||||||
|
fields = []
|
||||||
|
fields << field_hash('self', 'sva_svr_decision_on',
|
||||||
|
type: :date,
|
||||||
|
label: I18n.t("#{procedure.sva_svr_decision}_decision_on", scope: i18n_scope),
|
||||||
|
classname: for_filters ? '' : 'sva-col')
|
||||||
|
|
||||||
|
if for_filters
|
||||||
|
fields << field_hash('self', 'sva_svr_decision_before',
|
||||||
|
label: I18n.t("#{procedure.sva_svr_decision}_decision_before", scope: i18n_scope),
|
||||||
|
type: :date, virtual: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
fields
|
||||||
end
|
end
|
||||||
|
|
||||||
def sorted_ids(dossiers, count)
|
def sorted_ids(dossiers, count)
|
||||||
|
|
|
@ -11,7 +11,7 @@ class SVASVRConfiguration
|
||||||
UNIT_OPTIONS = ['days', 'weeks', 'months']
|
UNIT_OPTIONS = ['days', 'weeks', 'months']
|
||||||
RESUME_OPTIONS = ['continue', 'reset']
|
RESUME_OPTIONS = ['continue', 'reset']
|
||||||
|
|
||||||
validates :decision, inclusion: { in: DECISION_OPTIONS.without('svr') }
|
validates :decision, inclusion: { in: DECISION_OPTIONS }
|
||||||
validates :period, presence: true, numericality: { only_integer: true }, if: -> { enabled? }
|
validates :period, presence: true, numericality: { only_integer: true }, if: -> { enabled? }
|
||||||
validates :unit, presence: true, inclusion: { in: UNIT_OPTIONS }, if: -> { enabled? }
|
validates :unit, presence: true, inclusion: { in: UNIT_OPTIONS }, if: -> { enabled? }
|
||||||
validates :resume, presence: true, inclusion: { in: RESUME_OPTIONS }, if: -> { enabled? }
|
validates :resume, presence: true, inclusion: { in: RESUME_OPTIONS }, if: -> { enabled? }
|
||||||
|
|
|
@ -11,7 +11,7 @@ def maybe_start_new_page(pdf, size)
|
||||||
end
|
end
|
||||||
|
|
||||||
def clean_string(str)
|
def clean_string(str)
|
||||||
str.tr(' ', ' ') # replace non breaking space, which are invalid in pdf
|
str&.gsub(/[[:space:]]/, ' ') # replace non breaking space, which are invalid in pdf
|
||||||
end
|
end
|
||||||
|
|
||||||
def text_box(pdf, text, x, width)
|
def text_box(pdf, text, x, width)
|
||||||
|
@ -209,7 +209,7 @@ def add_message(pdf, message)
|
||||||
end
|
end
|
||||||
|
|
||||||
format_in_2_lines(pdf, "#{sender}, #{try_format_date(message.created_at)}",
|
format_in_2_lines(pdf, "#{sender}, #{try_format_date(message.created_at)}",
|
||||||
ActionView::Base.full_sanitizer.sanitize(message.body))
|
ActionView::Base.full_sanitizer.sanitize(clean_string(message.body)))
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_avis(pdf, avis)
|
def add_avis(pdf, avis)
|
||||||
|
@ -276,7 +276,7 @@ prawn_document(page_size: "A4") do |pdf|
|
||||||
add_etat_dossier(pdf, @dossier)
|
add_etat_dossier(pdf, @dossier)
|
||||||
|
|
||||||
if @dossier.motivation.present?
|
if @dossier.motivation.present?
|
||||||
format_in_2_columns(pdf, "Motif de la décision", @dossier.motivation)
|
format_in_2_columns(pdf, "Motif de la décision", clean_string(@dossier.motivation))
|
||||||
end
|
end
|
||||||
add_title(pdf, 'Historique')
|
add_title(pdf, 'Historique')
|
||||||
add_etats_dossier(pdf, @dossier)
|
add_etats_dossier(pdf, @dossier)
|
||||||
|
|
|
@ -17,8 +17,10 @@ en:
|
||||||
en_construction_since: Submitted since
|
en_construction_since: Submitted since
|
||||||
en_instruction_since: Instructed since
|
en_instruction_since: Instructed since
|
||||||
processed_since: Finished since
|
processed_since: Finished since
|
||||||
sva_svr_decision_on: SVA decision date
|
sva_decision_on: SVA decision date
|
||||||
sva_svr_decision_before: SVA decision date before
|
sva_decision_before: SVA decision date before
|
||||||
|
svr_decision_on: SVR decision date
|
||||||
|
svr_decision_before: SVR decision date before
|
||||||
user:
|
user:
|
||||||
email: Requester
|
email: Requester
|
||||||
followers_instructeurs:
|
followers_instructeurs:
|
||||||
|
|
|
@ -17,8 +17,10 @@ fr:
|
||||||
en_construction_since: En construction depuis
|
en_construction_since: En construction depuis
|
||||||
en_instruction_since: En instruction depuis
|
en_instruction_since: En instruction depuis
|
||||||
processed_since: Terminé depuis
|
processed_since: Terminé depuis
|
||||||
sva_svr_decision_on: Date décision SVA
|
sva_decision_on: Date décision SVA
|
||||||
sva_svr_decision_before: Date décision SVA avant
|
sva_decision_before: Date décision SVA avant
|
||||||
|
svr_decision_on: Date décision SVR
|
||||||
|
svr_decision_before: Date décision SVR avant
|
||||||
user:
|
user:
|
||||||
email: Demandeur
|
email: Demandeur
|
||||||
followers_instructeurs:
|
followers_instructeurs:
|
||||||
|
|
|
@ -5,6 +5,8 @@ en:
|
||||||
details_no_name: "The file was submitted by a FranceConnect account."
|
details_no_name: "The file was submitted by a FranceConnect account."
|
||||||
details: "The file was submitted by the account of %{name}."
|
details: "The file was submitted by the account of %{name}."
|
||||||
details_updated: "The file was submitted by the account of %{name}, authenticated by FranceConnect on %{date}."
|
details_updated: "The file was submitted by the account of %{name}, authenticated by FranceConnect on %{date}."
|
||||||
|
motivation:
|
||||||
|
refused_by_svr: "The service handling your file was unable to process it within the time limit set by the Silence Vaut Rejet law."
|
||||||
header:
|
header:
|
||||||
expires_at:
|
expires_at:
|
||||||
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)"
|
||||||
|
|
|
@ -5,6 +5,8 @@ fr:
|
||||||
details_no_name: "Le dossier a été déposé par un compte FranceConnect."
|
details_no_name: "Le dossier a été déposé par un compte FranceConnect."
|
||||||
details: "Le dossier a été déposé par le compte de %{name}."
|
details: "Le dossier a été déposé par le compte de %{name}."
|
||||||
details_updated: "Le dossier a été déposé par le compte de %{name}, authentifié par FranceConnect le %{date}."
|
details_updated: "Le dossier a été déposé par le compte de %{name}, authentifié par FranceConnect le %{date}."
|
||||||
|
motivation:
|
||||||
|
refused_by_svr: "Le service traitant n’a pas été en mesure de traiter votre demande dans le délai imparti par la règle du Silence Vaut Rejet."
|
||||||
header:
|
header:
|
||||||
expires_at:
|
expires_at:
|
||||||
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)"
|
||||||
|
|
|
@ -58,6 +58,19 @@ RSpec.describe Instructeurs::EnConstructionMenuComponent, type: :component do
|
||||||
expect(subject).to have_dropdown_item('Demander une correction')
|
expect(subject).to have_dropdown_item('Demander une correction')
|
||||||
expect(subject).to have_dropdown_item('Demander à compléter')
|
expect(subject).to have_dropdown_item('Demander à compléter')
|
||||||
expect(subject).to have_dropdown_items(count: 4)
|
expect(subject).to have_dropdown_items(count: 4)
|
||||||
|
expect(subject).to have_text('Le délai du SVA')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when procedure is svr' do
|
||||||
|
let(:dossier) { create(:dossier, :en_instruction, procedure: create(:procedure, :svr)) }
|
||||||
|
|
||||||
|
it 'renders a dropdown' do
|
||||||
|
expect(subject).to have_dropdown_title('Demander une correction')
|
||||||
|
expect(subject).to have_dropdown_item('Demander une correction')
|
||||||
|
expect(subject).to have_dropdown_item('Demander à compléter')
|
||||||
|
expect(subject).to have_dropdown_items(count: 4)
|
||||||
|
expect(subject).to have_text('Le délai du SVR')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -48,6 +48,42 @@ RSpec.describe ProcedureSVASVRProcessDossierJob, type: :job do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when procedure is SVR' do
|
||||||
|
let(:procedure) { create(:procedure, :published, :svr, :for_individual) }
|
||||||
|
|
||||||
|
it 'should refuse dossier' do
|
||||||
|
expect(subject.sva_svr_decision_on).to eq(Date.current)
|
||||||
|
expect(subject).to be_refuse
|
||||||
|
expect(subject.processed_at).to within(1.second).of(Time.current)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when decision is scheduled in the future' do
|
||||||
|
let!(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure:, depose_at: 1.day.ago, sva_svr_decision_on: 2.months.from_now.to_date) }
|
||||||
|
|
||||||
|
it 'should not refuses dossier' do
|
||||||
|
expect { subject }.not_to change { dossier.reload.updated_at }
|
||||||
|
expect(subject).to be_en_instruction
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when dossier has pending correction / is en_construction' do
|
||||||
|
before do
|
||||||
|
travel_to 2.days.ago do # create correction in past so it will be 3 days of delay
|
||||||
|
dossier.flag_as_pending_correction!(build(:commentaire, dossier: dossier))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not refuses dossier' do
|
||||||
|
subject
|
||||||
|
expect(dossier).to be_en_construction
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should update sva_svr_decision_on with corrections delay' do
|
||||||
|
expect { subject }.to change { dossier.reload.sva_svr_decision_on }.from(Date.current).to(Date.current + 3.days)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when dossier was submitted before sva was enabled' do
|
context 'when dossier was submitted before sva was enabled' do
|
||||||
let!(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure:, depose_at: 2.months.ago) }
|
let!(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure:, depose_at: 2.months.ago) }
|
||||||
|
|
||||||
|
|
|
@ -1103,6 +1103,46 @@ describe Dossier, type: :model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#refuser_automatiquement' do
|
||||||
|
context 'as svr procedure' do
|
||||||
|
let(:last_operation) { dossier.dossier_operation_logs.last }
|
||||||
|
let(:procedure) { create(:procedure, :for_individual, :published, :svr) }
|
||||||
|
let(:dossier) { create(:dossier, :en_instruction, :with_individual, procedure:, sva_svr_decision_on: Date.current, en_instruction_at: DateTime.new(2021, 5, 1, 12)) }
|
||||||
|
|
||||||
|
before {
|
||||||
|
freeze_time
|
||||||
|
allow(NotificationMailer).to receive(:send_refuse_notification).and_return(double(deliver_later: true))
|
||||||
|
}
|
||||||
|
|
||||||
|
subject {
|
||||||
|
dossier.refuser_automatiquement!
|
||||||
|
dossier.reload
|
||||||
|
}
|
||||||
|
|
||||||
|
it 'refuses dossier automatiquement' do
|
||||||
|
expect(subject.en_instruction_at).to eq(DateTime.new(2021, 5, 1, 12))
|
||||||
|
expect(subject.processed_at).to eq(Time.current)
|
||||||
|
expect(subject.declarative_triggered_at).to be_nil
|
||||||
|
expect(subject.sva_svr_decision_triggered_at).to eq(Time.current)
|
||||||
|
expect(subject.motivation).to include("dans le délai imparti")
|
||||||
|
expect(subject).to be_refuse
|
||||||
|
expect(last_operation.operation).to eq('refuser')
|
||||||
|
expect(last_operation.automatic_operation?).to be_truthy
|
||||||
|
expect(NotificationMailer).to have_received(:send_refuse_notification).with(dossier)
|
||||||
|
expect(subject.attestation).to be_nil
|
||||||
|
expect(dossier.commentaires.count).to eq(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'for an user having english locale' do
|
||||||
|
before { dossier.user.update!(locale: 'en') }
|
||||||
|
|
||||||
|
it 'translates the motivation' do
|
||||||
|
expect(subject.motivation).to include('within the time limit')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#passer_en_instruction!' do
|
describe '#passer_en_instruction!' do
|
||||||
let(:dossier) { create(:dossier, :en_construction, en_construction_close_to_expiration_notice_sent_at: Time.zone.now) }
|
let(:dossier) { create(:dossier, :en_construction, en_construction_close_to_expiration_notice_sent_at: Time.zone.now) }
|
||||||
let(:last_operation) { dossier.dossier_operation_logs.last }
|
let(:last_operation) { dossier.dossier_operation_logs.last }
|
||||||
|
@ -1324,6 +1364,60 @@ describe Dossier, type: :model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '#can_refuser_automatiquement?' do
|
||||||
|
let(:dossier) { create(:dossier, state: initial_state) }
|
||||||
|
let(:initial_state) { :en_instruction }
|
||||||
|
|
||||||
|
it { expect(dossier.can_refuser_automatiquement?).to be_falsey }
|
||||||
|
|
||||||
|
context 'when procedure is sva/svr' do
|
||||||
|
let(:decision) { :svr }
|
||||||
|
|
||||||
|
before do
|
||||||
|
dossier.procedure.update!(sva_svr: SVASVRConfiguration.new(decision:).attributes)
|
||||||
|
dossier.update!(sva_svr_decision_on: Date.current)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(dossier.can_refuser_automatiquement?).to be_truthy }
|
||||||
|
|
||||||
|
context 'when procedure is svr' do
|
||||||
|
let(:decision) { :svr }
|
||||||
|
|
||||||
|
before do
|
||||||
|
dossier.procedure.update!(sva_svr: SVASVRConfiguration.new(decision:).attributes)
|
||||||
|
dossier.update!(sva_svr_decision_on: Date.current)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(dossier.can_refuser_automatiquement?).to be_truthy }
|
||||||
|
|
||||||
|
context 'when sva_svr_decision_on is in the future' do
|
||||||
|
before { dossier.update!(sva_svr_decision_on: 1.day.from_now) }
|
||||||
|
|
||||||
|
it { expect(dossier.can_refuser_automatiquement?).to be_falsey }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when dossier has pending correction' do
|
||||||
|
let(:dossier) { create(:dossier, :en_construction) }
|
||||||
|
let!(:dossier_correction) { create(:dossier_correction, dossier:) }
|
||||||
|
|
||||||
|
it { expect(dossier.can_refuser_automatiquement?).to be_falsey }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when decision is sva' do
|
||||||
|
let(:decision) { :sva }
|
||||||
|
|
||||||
|
it { expect(dossier.can_refuser_automatiquement?).to be_falsey }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when dossier was already processed by svr' do
|
||||||
|
before { dossier.update!(sva_svr_decision_triggered_at: 1.hour.ago) }
|
||||||
|
|
||||||
|
it { expect(dossier.can_refuser_automatiquement?).to be_falsey }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "can't transition to terminer when etablissement is in degraded mode" do
|
describe "can't transition to terminer when etablissement is in degraded mode" do
|
||||||
let(:instructeur) { create(:instructeur) }
|
let(:instructeur) { create(:instructeur) }
|
||||||
let(:motivation) { 'motivation' }
|
let(:motivation) { 'motivation' }
|
||||||
|
@ -1955,7 +2049,13 @@ describe Dossier, type: :model do
|
||||||
context 'procedure sva' do
|
context 'procedure sva' do
|
||||||
let(:dossier) { create(:dossier, :en_instruction, procedure: create(:procedure, :sva)) }
|
let(:dossier) { create(:dossier, :en_instruction, procedure: create(:procedure, :sva)) }
|
||||||
|
|
||||||
it { expect(dossier.spreadsheet_columns(types_de_champ: [])).to include(["Date SVA", :sva_svr_decision_on]) }
|
it { expect(dossier.spreadsheet_columns(types_de_champ: [])).to include(["Date décision SVA", :sva_svr_decision_on]) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'procedure svr' do
|
||||||
|
let(:dossier) { create(:dossier, :en_instruction, procedure: create(:procedure, :svr)) }
|
||||||
|
|
||||||
|
it { expect(dossier.spreadsheet_columns(types_de_champ: [])).to include(["Date décision SVR", :sva_svr_decision_on]) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -116,7 +116,7 @@ describe ProcedurePresentation do
|
||||||
it { is_expected.to include(name_field, surname_field, gender_field) }
|
it { is_expected.to include(name_field, surname_field, gender_field) }
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the procedure is sva/svr' do
|
context 'when the procedure is sva' do
|
||||||
let(:procedure) { create(:procedure, :for_individual, :sva) }
|
let(:procedure) { create(:procedure, :for_individual, :sva) }
|
||||||
let(:procedure_presentation) { create(:procedure_presentation, assign_to: assign_to) }
|
let(:procedure_presentation) { create(:procedure_presentation, assign_to: assign_to) }
|
||||||
|
|
||||||
|
@ -127,6 +127,18 @@ describe ProcedurePresentation do
|
||||||
|
|
||||||
it { is_expected.to include(decision_on, decision_before_field) }
|
it { is_expected.to include(decision_on, decision_before_field) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when the procedure is svr' do
|
||||||
|
let(:procedure) { create(:procedure, :for_individual, :svr) }
|
||||||
|
let(:procedure_presentation) { create(:procedure_presentation, assign_to: assign_to) }
|
||||||
|
|
||||||
|
let(:decision_on) { { "label" => "Date décision SVR", "table" => "self", "column" => "sva_svr_decision_on", 'classname' => '', 'virtual' => false, "type" => :date, "scope" => '', "value_column" => :value, 'filterable' => true } }
|
||||||
|
let(:decision_before_field) { { "label" => "Date décision SVR avant", "table" => "self", "column" => "sva_svr_decision_before", 'classname' => '', 'virtual' => true, "type" => :date, "scope" => '', "value_column" => :value, 'filterable' => true } }
|
||||||
|
|
||||||
|
subject { procedure_presentation.fields }
|
||||||
|
|
||||||
|
it { is_expected.to include(decision_on, decision_before_field) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#displayable_fields_for_select" do
|
describe "#displayable_fields_for_select" do
|
||||||
|
|
Loading…
Add table
Reference in a new issue