Merge pull request #6789 from betagouv/main

2022-01-03-02
This commit is contained in:
Kara Diaby 2022-01-03 14:57:44 +01:00 committed by GitHub
commit 6324def470
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 158 additions and 69 deletions

View file

@ -12,13 +12,13 @@ module Experts
DONNES_STATUS = 'donnes' DONNES_STATUS = 'donnes'
def index def index
avis = current_expert.avis.includes(dossier: [groupe_instructeur: :procedure]) avis = current_expert.avis.includes(dossier: [groupe_instructeur: :procedure]).not_hidden_by_administration
@avis_by_procedure = avis.to_a.group_by(&:procedure) @avis_by_procedure = avis.to_a.group_by(&:procedure)
end end
def procedure def procedure
@procedure = Procedure.find(params[:procedure_id]) @procedure = Procedure.find(params[:procedure_id])
expert_avis = current_expert.avis.includes(:dossier).where(dossiers: { groupe_instructeur: GroupeInstructeur.where(procedure: @procedure.id) }) expert_avis = current_expert.avis.includes(:dossier).not_hidden_by_administration.where(dossiers: { groupe_instructeur: GroupeInstructeur.where(procedure: @procedure.id) })
@avis_a_donner = expert_avis.without_answer @avis_a_donner = expert_avis.without_answer
@avis_donnes = expert_avis.with_answer @avis_donnes = expert_avis.with_answer

View file

@ -140,9 +140,6 @@ module Instructeurs
def repasser_en_instruction def repasser_en_instruction
begin begin
if dossier.hidden_by_user_at.present?
dossier.update!(hidden_by_user_at: nil)
end
flash.notice = "Le dossier #{dossier.id} a été repassé en instruction." flash.notice = "Le dossier #{dossier.id} a été repassé en instruction."
dossier.repasser_en_instruction!(instructeur: current_instructeur) dossier.repasser_en_instruction!(instructeur: current_instructeur)
rescue AASM::InvalidTransition => e rescue AASM::InvalidTransition => e
@ -232,10 +229,10 @@ module Instructeurs
def delete_dossier def delete_dossier
if dossier.termine? if dossier.termine?
dossier.discard_and_keep_track!(current_instructeur, :instructeur_request) dossier.discard_and_keep_track!(current_instructeur, :instructeur_request)
flash.notice = 'Le dossier a bien été supprimé' flash.notice = t('instructeurs.dossiers.deleted_by_instructeur')
redirect_to instructeur_procedure_path(procedure) redirect_to instructeur_procedure_path(procedure)
else else
flash.alert = "Suppression impossible : le dossier nest pas traité" flash.alert = t('instructeurs.dossiers.impossible_deletion')
redirect_back(fallback_location: instructeur_procedures_url) redirect_back(fallback_location: instructeur_procedures_url)
end end
end end

View file

@ -16,7 +16,7 @@ module Instructeurs
@dossiers_count_per_procedure = dossiers.all_state.group('groupe_instructeurs.procedure_id').reorder(nil).count @dossiers_count_per_procedure = dossiers.all_state.group('groupe_instructeurs.procedure_id').reorder(nil).count
@dossiers_a_suivre_count_per_procedure = dossiers.without_followers.en_cours.group('groupe_instructeurs.procedure_id').reorder(nil).count @dossiers_a_suivre_count_per_procedure = dossiers.without_followers.en_cours.group('groupe_instructeurs.procedure_id').reorder(nil).count
@dossiers_archived_count_per_procedure = dossiers.archived.group('groupe_instructeurs.procedure_id').count @dossiers_archived_count_per_procedure = dossiers.archived.group('groupe_instructeurs.procedure_id').count
@dossiers_termines_count_per_procedure = dossiers.termine.group('groupe_instructeurs.procedure_id').reorder(nil).count @dossiers_termines_count_per_procedure = dossiers.termine.not_hidden_by_administration.group('groupe_instructeurs.procedure_id').reorder(nil).count
@dossiers_expirant_count_per_procedure = dossiers.termine_or_en_construction_close_to_expiration.group('groupe_instructeurs.procedure_id').count @dossiers_expirant_count_per_procedure = dossiers.termine_or_en_construction_close_to_expiration.group('groupe_instructeurs.procedure_id').count
groupe_ids = current_instructeur.groupe_instructeurs.pluck(:id) groupe_ids = current_instructeur.groupe_instructeurs.pluck(:id)
@ -69,7 +69,7 @@ module Instructeurs
@followed_dossiers_id = @followed_dossiers.pluck(:id) @followed_dossiers_id = @followed_dossiers.pluck(:id)
@termines_dossiers = dossiers_visibles.termine @termines_dossiers = dossiers_visibles.termine.not_hidden_by_administration
@all_state_dossiers = dossiers_visibles.all_state @all_state_dossiers = dossiers_visibles.all_state
@archived_dossiers = dossiers_visibles.archived @archived_dossiers = dossiers_visibles.archived
@expirant_dossiers = dossiers_visibles.termine_or_en_construction_close_to_expiration @expirant_dossiers = dossiers_visibles.termine_or_en_construction_close_to_expiration

View file

@ -212,16 +212,15 @@ module Users
end end
end end
def ask_deletion def delete_dossier
dossier = current_user.dossiers.includes(:user, procedure: :administrateurs).find(params[:id]) dossier = current_user.dossiers.includes(:user, procedure: :administrateurs).find(params[:id])
if dossier.can_be_deleted_by_user? if dossier.can_be_deleted_by_user?
dossier.discard_and_keep_track!(current_user, :user_request) dossier.discard_and_keep_track!(current_user, :user_request)
flash.notice = t('.soft_deleted_dossier') flash.notice = t('users.dossiers.ask_deletion.soft_deleted_dossier')
redirect_to dossiers_path redirect_to dossiers_path
else else
flash.notice = t('.undergoingreview') flash.alert = t('users.dossiers.ask_deletion.undergoingreview')
redirect_to dossier_path(dossier) redirect_to dossiers_path
end end
end end
@ -288,13 +287,6 @@ module Users
@transfer = DossierTransfer.new(dossiers: current_user.dossiers) @transfer = DossierTransfer.new(dossiers: current_user.dossiers)
end end
def hide_dossier
dossier = current_user.dossiers.includes(:user, procedure: :administrateurs).find(params[:id])
dossier.update(hidden_by_user_at: Time.zone.now)
flash.notice = t('users.dossiers.ask_deletion.soft_deleted_dossier')
redirect_to dossiers_path
end
private private
# if the status tab is filled, then this tab # if the status tab is filled, then this tab

View file

@ -50,7 +50,7 @@ class Avis < ApplicationRecord
scope :updated_since?, -> (date) { where('avis.updated_at > ?', date) } scope :updated_since?, -> (date) { where('avis.updated_at > ?', date) }
scope :discarded_termine_expired, -> { unscope(:joins).where(dossier: Dossier.discarded_termine_expired) } scope :discarded_termine_expired, -> { unscope(:joins).where(dossier: Dossier.discarded_termine_expired) }
scope :discarded_en_construction_expired, -> { unscope(:joins).where(dossier: Dossier.discarded_en_construction_expired) } scope :discarded_en_construction_expired, -> { unscope(:joins).where(dossier: Dossier.discarded_en_construction_expired) }
scope :not_hidden_by_administration, -> { where(dossiers: { hidden_by_administration_at: nil }) }
# The form allows subtmitting avis requests to several emails at once, # The form allows subtmitting avis requests to several emails at once,
# hence this virtual attribute. # hence this virtual attribute.
attr_accessor :emails attr_accessor :emails

View file

@ -16,6 +16,7 @@
# en_instruction_at :datetime # en_instruction_at :datetime
# groupe_instructeur_updated_at :datetime # groupe_instructeur_updated_at :datetime
# hidden_at :datetime # hidden_at :datetime
# hidden_by_administration_at :datetime
# hidden_by_user_at :datetime # hidden_by_user_at :datetime
# identity_updated_at :datetime # identity_updated_at :datetime
# last_avis_updated_at :datetime # last_avis_updated_at :datetime
@ -205,7 +206,9 @@ class Dossier < ApplicationRecord
scope :archived, -> { where(archived: true) } scope :archived, -> { where(archived: true) }
scope :not_archived, -> { where(archived: false) } scope :not_archived, -> { where(archived: false) }
scope :hidden_by_administration, -> { where.not(hidden_by_administration_at: nil) }
scope :not_hidden_by_user, -> { where(hidden_by_user_at: nil) } scope :not_hidden_by_user, -> { where(hidden_by_user_at: nil) }
scope :not_hidden_by_administration, -> { where(hidden_by_administration_at: nil) }
scope :order_by_updated_at, -> (order = :desc) { order(updated_at: order) } scope :order_by_updated_at, -> (order = :desc) { order(updated_at: order) }
scope :order_by_created_at, -> (order = :asc) { order(depose_at: order, created_at: order, id: order) } scope :order_by_created_at, -> (order = :asc) { order(depose_at: order, created_at: order, id: order) }
@ -234,6 +237,7 @@ class Dossier < ApplicationRecord
end end
scope :downloadable_sorted, -> { scope :downloadable_sorted, -> {
state_not_brouillon state_not_brouillon
.not_hidden_by_administration
.includes( .includes(
:user, :user,
:individual, :individual,
@ -524,7 +528,7 @@ class Dossier < ApplicationRecord
end end
def can_be_deleted_by_user? def can_be_deleted_by_user?
brouillon? || en_construction? brouillon? || en_construction? || termine?
end end
def can_be_deleted_by_manager? def can_be_deleted_by_manager?
@ -680,6 +684,22 @@ class Dossier < ApplicationRecord
!procedure.brouillon? && !brouillon? !procedure.brouillon? && !brouillon?
end end
def hidden_by_user?
hidden_by_user_at.present?
end
def hidden_by_administration?
hidden_by_administration_at.present?
end
def deleted_by_instructeur_and_user?
termine? && hidden_by_administration? && hidden_by_user?
end
def can_be_restored_by_manager?
hidden_by_administration? || discarded? && !procedure.discarded?
end
def expose_legacy_carto_api? def expose_legacy_carto_api?
procedure.expose_legacy_carto_api? procedure.expose_legacy_carto_api?
end end
@ -731,17 +751,30 @@ class Dossier < ApplicationRecord
end end
def discard_and_keep_track!(author, reason) def discard_and_keep_track!(author, reason)
author_is_user = author.is_a?(User)
author_is_administration = author.is_a?(Instructeur) || author.is_a?(Administrateur) || author.is_a?(SuperAdmin)
if termine? && author_is_administration
update(hidden_by_administration_at: Time.zone.now)
end
if termine? && author_is_user
update(hidden_by_user_at: Time.zone.now)
end
user_email = user_deleted? ? nil : user_email_for(:notification) user_email = user_deleted? ? nil : user_email_for(:notification)
deleted_dossier = nil deleted_dossier = nil
transaction do transaction do
if keep_track_on_deletion? if deleted_by_instructeur_and_user? || en_construction? || brouillon?
log_dossier_operation(author, :supprimer, self) if keep_track_on_deletion?
deleted_dossier = DeletedDossier.create_from_dossier(self, reason) log_dossier_operation(author, :supprimer, self)
end deleted_dossier = DeletedDossier.create_from_dossier(self, reason)
end
update!(dossier_transfer_id: nil) update!(dossier_transfer_id: nil)
discard! discard!
end
end end
if deleted_dossier.present? if deleted_dossier.present?
@ -765,7 +798,9 @@ class Dossier < ApplicationRecord
def restore(author) def restore(author)
if discarded? if discarded?
transaction do transaction do
if undiscard && keep_track_on_deletion? if hidden_by_administration?
update(hidden_by_administration_at: nil)
elsif undiscard && keep_track_on_deletion?
deleted_dossier&.destroy! deleted_dossier&.destroy!
log_dossier_operation(author, :restaurer, self) log_dossier_operation(author, :restaurer, self)
end end
@ -773,12 +808,6 @@ class Dossier < ApplicationRecord
end end
end end
def restore_if_discarded_with_procedure(author)
if deleted_dossier&.procedure_removed?
restore(author)
end
end
def attestation_activated? def attestation_activated?
termine? && procedure.attestation_template&.activated? termine? && procedure.attestation_template&.activated?
end end
@ -838,6 +867,7 @@ class Dossier < ApplicationRecord
create_missing_traitemets create_missing_traitemets
self.hidden_by_user_at = nil
self.archived = false self.archived = false
self.termine_close_to_expiration_notice_sent_at = nil self.termine_close_to_expiration_notice_sent_at = nil
self.conservation_extension = 0.days self.conservation_extension = 0.days
@ -1120,10 +1150,6 @@ class Dossier < ApplicationRecord
end end
end end
def hidden_by_user?
self.hidden_by_user_at.present?
end
private private
def create_missing_traitemets def create_missing_traitemets

View file

@ -29,7 +29,7 @@ class Expert < ApplicationRecord
@avis_summary @avis_summary
else else
query = <<~EOF query = <<~EOF
COUNT(*) FILTER (where answer IS NULL) AS unanswered, COUNT(*) FILTER (where answer IS NULL AND dossiers.hidden_by_administration_at IS NULL) AS unanswered,
COUNT(*) AS total COUNT(*) AS total
EOF EOF
result = avis.select(query)[0] result = avis.select(query)[0]

View file

@ -256,6 +256,7 @@ class Instructeur < ApplicationRecord
ON follows.dossier_id = dossiers.id ON follows.dossier_id = dossiers.id
AND follows.unfollowed_at IS NULL AND follows.unfollowed_at IS NULL
WHERE "dossiers"."hidden_at" IS NULL WHERE "dossiers"."hidden_at" IS NULL
AND "dossiers"."hidden_by_administration_at" IS NULL
AND "dossiers"."state" != 'brouillon' AND "dossiers"."state" != 'brouillon'
AND "dossiers"."groupe_instructeur_id" in (:groupe_instructeur_ids) AND "dossiers"."groupe_instructeur_id" in (:groupe_instructeur_ids)
EOF EOF

View file

@ -673,7 +673,10 @@ class Procedure < ApplicationRecord
def restore(author) def restore(author)
if discarded? && undiscard if discarded? && undiscard
dossiers.with_discarded.discarded.find_each do |dossier| dossiers.with_discarded.discarded.find_each do |dossier|
dossier.restore_if_discarded_with_procedure(author) dossier.restore(author)
end
dossiers.hidden_by_administration.find_each do |dossier|
dossier.restore(author)
end end
end end
end end

View file

@ -119,4 +119,3 @@
.dropdown-description .dropdown-description
%h4 Supprimer le dossier %h4 Supprimer le dossier
Lusager sera notifié que son dossier est supprimé. Lusager sera notifié que son dossier est supprimé.

View file

@ -26,7 +26,7 @@
= link_to supprimer_dossier_instructeur_dossier_path(procedure_id, dossier_id), method: :patch, data: { confirm: "Voulez vous vraiment supprimer le dossier #{dossier_id} ? Cette action est irréversible. \nNous vous suggérons de télécharger le dossier au format PDF au préalable." } do = link_to supprimer_dossier_instructeur_dossier_path(procedure_id, dossier_id), method: :patch, data: { confirm: "Voulez vous vraiment supprimer le dossier #{dossier_id} ? Cette action est irréversible. \nNous vous suggérons de télécharger le dossier au format PDF au préalable." } do
%span.icon.delete %span.icon.delete
.dropdown-description .dropdown-description
Supprimer le dossier = t('views.instructeurs.dossiers.delete_dossier')
- elsif Dossier::EN_CONSTRUCTION_OU_INSTRUCTION.include?(state) - elsif Dossier::EN_CONSTRUCTION_OU_INSTRUCTION.include?(state)
- if dossier_is_followed - if dossier_is_followed

View file

@ -33,7 +33,7 @@ as well as a link to its edit page.
<% end %> <% end %>
<% if dossier.can_be_deleted_by_manager? %> <% if dossier.can_be_deleted_by_manager? %>
<%= link_to 'Supprimer le dossier', discard_manager_dossier_path(dossier), method: :post, class: 'button', data: { confirm: "Confirmez vous la suppression du dossier ?" } %> <%= link_to 'Supprimer le dossier', discard_manager_dossier_path(dossier), method: :post, class: 'button', data: { confirm: "Confirmez vous la suppression du dossier ?" } %>
<% elsif dossier.discarded? && !dossier.procedure.discarded? %> <% elsif dossier.can_be_restored_by_manager? %>
<%= link_to 'Restaurer le dossier', restore_manager_dossier_path(dossier), method: :post, class: 'button', data: { confirm: "Confirmez vous la restauration du dossier ?" } %> <%= link_to 'Restaurer le dossier', restore_manager_dossier_path(dossier), method: :post, class: 'button', data: { confirm: "Confirmez vous la restauration du dossier ?" } %>
<% end %> <% end %>
</div> </div>

View file

@ -2,8 +2,7 @@
- has_delete_action = dossier.can_be_deleted_by_user? - has_delete_action = dossier.can_be_deleted_by_user?
- has_new_dossier_action = dossier.procedure.accepts_new_dossiers? - has_new_dossier_action = dossier.procedure.accepts_new_dossiers?
- has_transfer_action = dossier.user == current_user - has_transfer_action = dossier.user == current_user
- has_hide_action = dossier.termine? && dossier.hidden_by_user_at.nil? - has_actions = has_edit_action || has_delete_action || has_new_dossier_action || has_transfer_action
- has_actions = has_edit_action || has_delete_action || has_new_dossier_action || has_transfer_action || has_hide_action
- if has_actions - if has_actions
.dropdown.user-dossier-actions .dropdown.user-dossier-actions
@ -41,14 +40,8 @@
- if has_delete_action - if has_delete_action
%li.danger %li.danger
= link_to ask_deletion_dossier_path(dossier), method: :post, data: { disable: true, confirm: "En continuant, vous allez supprimer ce dossier ainsi que les informations quil contient. Toute suppression entraîne lannulation de la démarche en cours.\n\nConfirmer la suppression ?" } do = link_to delete_dossier_dossier_path(dossier), method: :patch, data: { disable: true, confirm: "En continuant, vous allez supprimer ce dossier ainsi que les informations quil contient. Toute suppression entraîne lannulation de la démarche en cours.\n\nConfirmer la suppression ?" } do
%span.icon.delete %span.icon.delete
.dropdown-description .dropdown-description
= t('views.users.dossiers.dossier_action.delete_dossier') = t('views.users.dossiers.dossier_action.delete_dossier')
- if has_hide_action
%li
= link_to hide_dossier_dossier_path(dossier), method: :patch do
%span.icon.delete
.dropdown-description
= t('views.users.dossiers.dossier_action.hide_dossier')

View file

@ -135,6 +135,7 @@ en:
instructeurs: instructeurs:
dossiers: dossiers:
archived_dossier: "This file will be kept for an additional month" archived_dossier: "This file will be kept for an additional month"
delete_dossier: "Delete file"
deleted_by_user: "File deleted by user" deleted_by_user: "File deleted by user"
avis: avis:
introduction_file_explaination: "File attached to the request for advice" introduction_file_explaination: "File attached to the request for advice"
@ -198,7 +199,6 @@ en:
edit_dossier: "Edit the file" edit_dossier: "Edit the file"
start_other_dossier: "Start an other file" start_other_dossier: "Start an other file"
delete_dossier: "Delete the file" delete_dossier: "Delete the file"
hide_dossier: "Delete from your screen"
transfer_dossier: "Transfer the file" transfer_dossier: "Transfer the file"
edit_draft: "Edit the draft" edit_draft: "Edit the draft"
actions: "Actions" actions: "Actions"
@ -407,6 +407,10 @@ en:
identity_saved: "Identity data is registred" identity_saved: "Identity data is registred"
attestation: attestation:
no_longer_available: "The certificate is no longer available on this file." no_longer_available: "The certificate is no longer available on this file."
instructeurs:
dossiers:
deleted_by_instructeur: "The folder has been deleted"
impossible_deletion: "Unable to delete : the folder is not processed"
france_connect: france_connect:
particulier: particulier:
password_confirmation: password_confirmation:

View file

@ -132,6 +132,7 @@ fr:
instructeurs: instructeurs:
dossiers: dossiers:
archived_dossier: "Le dossier sera conservé 1 mois supplémentaire" archived_dossier: "Le dossier sera conservé 1 mois supplémentaire"
delete_dossier: "Supprimer le dossier"
deleted_by_user: "Dossier supprimé par l'usager" deleted_by_user: "Dossier supprimé par l'usager"
avis: avis:
introduction_file_explaination: "Fichier joint à la demande davis" introduction_file_explaination: "Fichier joint à la demande davis"
@ -195,7 +196,6 @@ fr:
edit_dossier: "Modifier le dossier" edit_dossier: "Modifier le dossier"
start_other_dossier: "Commencer un autre dossier" start_other_dossier: "Commencer un autre dossier"
delete_dossier: "Supprimer le dossier" delete_dossier: "Supprimer le dossier"
hide_dossier: "Supprimer de votre interface"
transfer_dossier: "Transferer le dossier" transfer_dossier: "Transferer le dossier"
edit_draft: "Modifier le brouillon" edit_draft: "Modifier le brouillon"
actions: "Actions" actions: "Actions"
@ -415,6 +415,10 @@ fr:
identity_saved: "Identité enregistrée" identity_saved: "Identité enregistrée"
attestation: attestation:
no_longer_available: "Lattestation n'est plus disponible sur ce dossier." no_longer_available: "Lattestation n'est plus disponible sur ce dossier."
instructeurs:
dossiers:
deleted_by_instructeur: "Le dossier a bien été supprimé de votre interface"
impossible_deletion: "Supression impossible : le dossier n'est pas traité"
administrateurs: administrateurs:
procedures: procedures:
show: show:

View file

@ -268,8 +268,7 @@ Rails.application.routes.draw do
get 'demande' get 'demande'
get 'messagerie' get 'messagerie'
post 'commentaire' => 'dossiers#create_commentaire' post 'commentaire' => 'dossiers#create_commentaire'
post 'ask_deletion' patch 'delete_dossier'
patch 'hide_dossier'
get 'attestation' get 'attestation'
get 'transferer', to: 'dossiers#transferer' get 'transferer', to: 'dossiers#transferer'
end end

View file

@ -0,0 +1,5 @@
class AddHiddenByAdministrationToDossiers < ActiveRecord::Migration[6.1]
def change
add_column :dossiers, :hidden_by_administration_at, :datetime
end
end

View file

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2021_12_02_135804) do ActiveRecord::Schema.define(version: 2021_12_02_133139) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"
@ -326,6 +326,7 @@ ActiveRecord::Schema.define(version: 2021_12_02_135804) do
t.datetime "hidden_by_user_at" t.datetime "hidden_by_user_at"
t.index "to_tsvector('french'::regconfig, (search_terms || private_search_terms))", name: "index_dossiers_on_search_terms_private_search_terms", using: :gin t.index "to_tsvector('french'::regconfig, (search_terms || private_search_terms))", name: "index_dossiers_on_search_terms_private_search_terms", using: :gin
t.index "to_tsvector('french'::regconfig, search_terms)", name: "index_dossiers_on_search_terms", using: :gin t.index "to_tsvector('french'::regconfig, search_terms)", name: "index_dossiers_on_search_terms", using: :gin
t.datetime "hidden_by_administration_at"
t.index ["archived"], name: "index_dossiers_on_archived" t.index ["archived"], name: "index_dossiers_on_archived"
t.index ["dossier_transfer_id"], name: "index_dossiers_on_dossier_transfer_id" t.index ["dossier_transfer_id"], name: "index_dossiers_on_dossier_transfer_id"
t.index ["groupe_instructeur_id"], name: "index_dossiers_on_groupe_instructeur_id" t.index ["groupe_instructeur_id"], name: "index_dossiers_on_groupe_instructeur_id"

View file

@ -762,9 +762,10 @@ describe Instructeurs::DossiersController, type: :controller do
end end
end end
context 'when the instructeur want to delete a dossier with a decision' do context 'when the instructeur want to delete a dossier with a decision and already hidden by user' do
before do before do
dossier.accepter!(instructeur: instructeur, motivation: "le dossier est correct") dossier.accepter!(instructeur: instructeur, motivation: "le dossier est correct")
dossier.update!(hidden_by_user_at: Time.zone.now.beginning_of_day.utc)
allow(DossierMailer).to receive(:notify_instructeur_deletion_to_user).and_return(double(deliver_later: nil)) allow(DossierMailer).to receive(:notify_instructeur_deletion_to_user).and_return(double(deliver_later: nil))
subject subject
end end
@ -790,6 +791,31 @@ describe Instructeurs::DossiersController, type: :controller do
end end
end end
context 'when the instructeur want to delete a dossier with a decision and not hidden by user' do
before do
dossier.accepter!(instructeur: instructeur, motivation: "le dossier est correct")
allow(DossierMailer).to receive(:notify_instructeur_deletion_to_user).and_return(double(deliver_later: nil))
subject
end
it 'does not deletes previous logs and does not add a suppression log' do
expect(DossierOperationLog.where(dossier_id: dossier.id).count).to eq(2)
expect(DossierOperationLog.where(dossier_id: dossier.id).last.operation).not_to eq('supprimer')
end
it 'does not send an email to the user' do
expect(DossierMailer).not_to have_received(:notify_instructeur_deletion_to_user).with(DeletedDossier.where(dossier_id: dossier.id).first, dossier.user.email)
end
it 'add a record into deleted_dossiers table' do
expect(DeletedDossier.where(dossier_id: dossier.id).count).to eq(0)
end
it 'does not discard the dossier' do
expect(dossier.reload.hidden_at).to eq(nil)
end
end
context 'when the instructeur want to delete a dossier without a decision' do context 'when the instructeur want to delete a dossier without a decision' do
before do before do
subject subject

View file

@ -1000,10 +1000,10 @@ describe Users::DossiersController, type: :controller do
end end
end end
describe '#ask_deletion' do describe '#delete_dossier' do
before { sign_in(user) } before { sign_in(user) }
subject { post :ask_deletion, params: { id: dossier.id } } subject { patch :delete_dossier, params: { id: dossier.id } }
shared_examples_for "the dossier can not be deleted" do shared_examples_for "the dossier can not be deleted" do
it "doesnt notify the deletion" do it "doesnt notify the deletion" do
@ -1043,7 +1043,7 @@ describe Users::DossiersController, type: :controller do
let(:dossier) { create(:dossier, :en_instruction, user: user, autorisation_donnees: true) } let(:dossier) { create(:dossier, :en_instruction, user: user, autorisation_donnees: true) }
it_behaves_like "the dossier can not be deleted" it_behaves_like "the dossier can not be deleted"
it { is_expected.to redirect_to(dossier_path(dossier)) } it { is_expected.to redirect_to(dossiers_path) }
end end
end end
@ -1054,6 +1054,15 @@ describe Users::DossiersController, type: :controller do
it_behaves_like "the dossier can not be deleted" it_behaves_like "the dossier can not be deleted"
it { is_expected.to redirect_to(root_path) } it { is_expected.to redirect_to(root_path) }
end end
context 'when the dossier is already deleted by instructeur' do
let!(:dossier) { create(:dossier, :with_individual, state: :accepte, en_construction_at: Time.zone.yesterday.beginning_of_day.utc, user: user, autorisation_donnees: true, hidden_by_administration_at: Time.zone.now.beginning_of_day.utc) }
before { subject }
it 'discard the dossier' do
expect(dossier.reload.hidden_at).to be_present
end
end
end end
describe '#new' do describe '#new' do

View file

@ -62,9 +62,9 @@ describe 'user access to the list of their dossiers' do
describe 'deletion' do describe 'deletion' do
it 'should have links to delete dossiers' do it 'should have links to delete dossiers' do
expect(page).to have_link(nil, href: ask_deletion_dossier_path(dossier_brouillon)) expect(page).to have_link(nil, href: delete_dossier_dossier_path(dossier_brouillon))
expect(page).to have_link(nil, href: ask_deletion_dossier_path(dossier_en_construction)) expect(page).to have_link(nil, href: delete_dossier_dossier_path(dossier_en_construction))
expect(page).not_to have_link(nil, href: ask_deletion_dossier_path(dossier_en_instruction)) expect(page).not_to have_link(nil, href: delete_dossier_dossier_path(dossier_en_instruction))
end end
context 'when user clicks on delete button', js: true do context 'when user clicks on delete button', js: true do

View file

@ -0,0 +1,30 @@
describe 'experts/avis/index.html.haml', type: :view do
let!(:expert) { create(:expert) }
let!(:claimant) { create(:instructeur) }
let!(:procedure) { create(:procedure) }
let!(:avis) { create(:avis, claimant: claimant, experts_procedure: experts_procedure) }
let!(:experts_procedure) { create(:experts_procedure, expert: expert, procedure: procedure) }
before do
allow(view).to receive(:current_expert).and_return(avis.expert)
assign(:dossier, avis.dossier)
allow(view).to receive(:current_expert).and_return(avis.expert)
end
subject { render }
context 'when the dossier is deleted by instructeur' do
before do
avis.dossier.update!(state: "accepte", hidden_by_administration_at: Time.zone.now.beginning_of_day.utc)
assign(:avis_by_procedure, avis.expert.avis.includes(dossier: [groupe_instructeur: :procedure]).where(dossiers: { hidden_by_administration_at: nil }).to_a.group_by(&:procedure))
end
it { is_expected.not_to have_text("avis à donner") }
end
context 'when the dossier is not deleted by instructeur' do
before do
assign(:avis_by_procedure, avis.expert.avis.includes(dossier: [groupe_instructeur: :procedure]).where(dossiers: { hidden_by_administration_at: nil }).to_a.group_by(&:procedure))
end
it { is_expected.to have_text("avis à donner") }
end
end

View file

@ -6,12 +6,12 @@ describe 'users/dossiers/dossier_actions.html.haml', type: :view do
subject { render 'users/dossiers/dossier_actions.html.haml', dossier: dossier, current_user: user } subject { render 'users/dossiers/dossier_actions.html.haml', dossier: dossier, current_user: user }
it { is_expected.to have_link('Commencer un autre dossier', href: commencer_url(path: procedure.path)) } it { is_expected.to have_link('Commencer un autre dossier', href: commencer_url(path: procedure.path)) }
it { is_expected.to have_link('Supprimer le dossier', href: ask_deletion_dossier_path(dossier)) } it { is_expected.to have_link('Supprimer le dossier', href: delete_dossier_dossier_path(dossier)) }
it { is_expected.to have_link('Transferer le dossier', href: transferer_dossier_path(dossier)) } it { is_expected.to have_link('Transferer le dossier', href: transferer_dossier_path(dossier)) }
context 'when the dossier cannot be deleted' do context 'when the dossier is termine' do
let(:dossier) { create(:dossier, :accepte, procedure: procedure) } let(:dossier) { create(:dossier, :accepte, procedure: procedure) }
it { is_expected.not_to have_link('Supprimer le dossier') } it { is_expected.to have_link('Supprimer le dossier') }
end end
context 'when the procedure is closed' do context 'when the procedure is closed' do