From 6d89d914e2c2615b6c8dfee002245013d6f869bb Mon Sep 17 00:00:00 2001 From: kara Diaby Date: Mon, 27 Sep 2021 15:07:32 +0200 Subject: [PATCH 1/6] modify expert avis controller --- app/controllers/experts/avis_controller.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/app/controllers/experts/avis_controller.rb b/app/controllers/experts/avis_controller.rb index 1bc066d91..3848397e4 100644 --- a/app/controllers/experts/avis_controller.rb +++ b/app/controllers/experts/avis_controller.rb @@ -1,11 +1,12 @@ module Experts class AvisController < ExpertController include CreateAvisConcern + include Zipline before_action :authenticate_expert!, except: [:sign_up, :update_expert] before_action :check_if_avis_revoked, only: [:show] before_action :redirect_if_no_sign_up_needed, only: [:sign_up, :update_expert] - before_action :set_avis_and_dossier, only: [:show, :instruction, :messagerie, :create_commentaire, :update] + before_action :set_avis_and_dossier, only: [:show, :instruction, :messagerie, :create_commentaire, :update, :telecharger_pjs] A_DONNER_STATUS = 'a-donner' DONNES_STATUS = 'donnes' @@ -120,6 +121,14 @@ module Experts end end + def telecharger_pjs + return head(:forbidden) if !avis.dossier.export_and_attachments_downloadable? + + files = ActiveStorage::DownloadableFile.create_list_from_dossier(@dossier, true) + + zipline(files, "dossier-#{@dossier.id}.zip") + end + private def redirect_if_no_sign_up_needed From bfee9c275c0addb46f35812569a263dabe4b4895 Mon Sep 17 00:00:00 2001 From: kara Diaby Date: Mon, 27 Sep 2021 15:07:42 +0200 Subject: [PATCH 2/6] layout --- app/views/experts/avis/_header.html.haml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/views/experts/avis/_header.html.haml b/app/views/experts/avis/_header.html.haml index 803e317f4..ce3fa5f8c 100644 --- a/app/views/experts/avis/_header.html.haml +++ b/app/views/experts/avis/_header.html.haml @@ -5,6 +5,16 @@ %li= link_to(dossier.procedure.libelle, procedure_expert_avis_index_path(avis.procedure)) %li= link_to("Dossier nº #{dossier.id}", expert_avis_path(avis.procedure, avis)) + %span.dropdown.print-menu-opener + %button.button.dropdown-button.icon-only{ 'aria-expanded' => 'false', 'aria-controls' => 'print-pj-menu' } + %span.icon.attached + %ul#print-pj-menu.print-menu.dropdown-content + %li + - if dossier.export_and_attachments_downloadable? + = link_to "Télécharger le dossier et toutes ses pièces jointes", telecharger_pjs_expert_avis_path(avis), target: "_blank", rel: "noopener", class: "menu-item menu-link" + - else + %p.menu-item Le téléchargement des pièces jointes est désactivé pour les dossiers de plus de #{number_to_human_size Dossier::TAILLE_MAX_ZIP}. + %ul.tabs = dynamic_tab_item('Demande', expert_avis_path(avis.procedure, avis)) = dynamic_tab_item('Avis', instruction_expert_avis_path(avis.procedure, avis), notification: avis.answer.blank?) From 6c82e40ddb2955418b1183cbcb6a648478c89fd8 Mon Sep 17 00:00:00 2001 From: kara Diaby Date: Mon, 27 Sep 2021 15:07:50 +0200 Subject: [PATCH 3/6] routes --- config/routes.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/config/routes.rb b/config/routes.rb index dcb922acb..2c8bb1c31 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -295,6 +295,7 @@ Rails.application.routes.draw do post 'commentaire' => 'avis#create_commentaire' post 'avis' => 'avis#create_avis' get 'bilans_bdf' + get 'telecharger_pjs' => 'avis#telecharger_pjs' get 'sign_up' => 'avis#sign_up' post 'sign_up' => 'avis#update_expert' From cbedef996be174295e30fb1df4a539e989db5eea Mon Sep 17 00:00:00 2001 From: kara Diaby Date: Mon, 27 Sep 2021 15:07:56 +0200 Subject: [PATCH 4/6] tests --- spec/features/experts/expert_spec.rb | 39 ++++++++++++++++++- .../active_storage/downloadable_file_spec.rb | 20 ++++++++++ .../pieces_justificatives_service_spec.rb | 2 +- 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/spec/features/experts/expert_spec.rb b/spec/features/experts/expert_spec.rb index 5a1398da7..06eaa6126 100644 --- a/spec/features/experts/expert_spec.rb +++ b/spec/features/experts/expert_spec.rb @@ -5,9 +5,10 @@ feature 'Inviting an expert:' do context 'as an invited Expert' do let(:expert) { create(:expert) } let(:instructeur) { create(:instructeur) } - let(:procedure) { create(:procedure, :published, instructeurs: [instructeur]) } + let(:procedure) { create(:procedure, :published, :with_piece_justificative, instructeurs: [instructeur]) } let(:experts_procedure) { create(:experts_procedure, expert: expert, procedure: procedure) } let(:dossier) { create(:dossier, :en_construction, :with_dossier_link, procedure: procedure) } + let(:champ) { dossier.champs.first } let(:avis) { create(:avis, dossier: dossier, claimant: instructeur, experts_procedure: experts_procedure, confidentiel: true) } context 'when I don’t already have an account' do @@ -83,6 +84,42 @@ feature 'Inviting an expert:' do # scenario 'I can invite other experts' do # end + + context 'with dossiers having attached files', js: true do + let(:path) { 'spec/fixtures/files/piece_justificative_0.pdf' } + let(:commentaire) { create(:commentaire, instructeur: instructeur, dossier: dossier) } + + before do + champ.piece_justificative_file.attach(io: File.open(path), filename: "piece_justificative_0.pdf", content_type: "application/pdf") + dossier.champs_private << create(:champ_piece_justificative, :with_piece_justificative_file, private: true, dossier: dossier) + end + + scenario 'An Expert can download an archive containing attachments without any private champ, bill signature and operations logs' do + avis # create avis + login_as expert.user, scope: :user + visit expert_all_avis_path + + click_on '1 avis à donner' + click_on avis.dossier.user.email + + find(:css, '.attached').click + click_on 'Télécharger le dossier et toutes ses pièces jointes' + # For some reason, clicking the download link does not trigger the download in the headless browser ; + # So we need to go to the download link directly + visit telecharger_pjs_expert_avis_path(avis.dossier.procedure, avis) + + DownloadHelpers.wait_for_download + files = ZipTricks::FileReader.read_zip_structure(io: File.open(DownloadHelpers.download)) + expect(DownloadHelpers.download).to include "dossier-#{dossier.id}.zip" + expect(files.size).to be 2 + expect(files[0].filename.include?('export')).to be_truthy + expect(files[1].filename.include?('piece_justificative_0')).to be_truthy + expect(files[1].uncompressed_size).to be File.size(path) + end + + before { DownloadHelpers.clear_downloads } + after { DownloadHelpers.clear_downloads } + end end context 'when there are two experts' do diff --git a/spec/lib/active_storage/downloadable_file_spec.rb b/spec/lib/active_storage/downloadable_file_spec.rb index 835e8b731..755a0643c 100644 --- a/spec/lib/active_storage/downloadable_file_spec.rb +++ b/spec/lib/active_storage/downloadable_file_spec.rb @@ -50,5 +50,25 @@ describe ActiveStorage::DownloadableFile do it { expect(list.length).to eq 2 } end + + context 'when the files are asked by an expert with piece justificative and private piece justificative' do + let(:expert) { create(:expert) } + let(:instructeur) { create(:instructeur) } + let(:procedure) { create(:procedure, :published, :with_piece_justificative, instructeurs: [instructeur]) } + let(:experts_procedure) { create(:experts_procedure, expert: expert, procedure: procedure) } + let(:dossier) { create(:dossier, :en_construction, :with_dossier_link, procedure: procedure) } + let(:champ) { dossier.champs.first } + let(:avis) { create(:avis, dossier: dossier, claimant: instructeur, experts_procedure: experts_procedure, confidentiel: true) } + + subject(:list) { ActiveStorage::DownloadableFile.create_list_from_dossier(dossier, true) } + + before do + dossier.champs_private << create(:champ_piece_justificative, :with_piece_justificative_file, private: true, dossier: dossier) + + dossier.champs << create(:champ_piece_justificative, :with_piece_justificative_file, dossier: dossier) + end + + it { expect(list.length).to eq 2 } + end end end diff --git a/spec/services/pieces_justificatives_service_spec.rb b/spec/services/pieces_justificatives_service_spec.rb index a9a78742c..32e46303d 100644 --- a/spec/services/pieces_justificatives_service_spec.rb +++ b/spec/services/pieces_justificatives_service_spec.rb @@ -33,7 +33,7 @@ describe PiecesJustificativesService do end describe '.liste_documents' do - subject { PiecesJustificativesService.liste_documents(dossier) } + subject { PiecesJustificativesService.liste_documents(dossier, false) } it "doesn't return sensitive documents like titre_identite" do expect(champ_identite.piece_justificative_file).to be_attached From 6ef5b5d47486eaf66faf7f0fb4e9c9fc5088d2f1 Mon Sep 17 00:00:00 2001 From: kara Diaby Date: Tue, 28 Sep 2021 11:23:54 +0200 Subject: [PATCH 5/6] modify downloable file --- app/lib/active_storage/downloadable_file.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/lib/active_storage/downloadable_file.rb b/app/lib/active_storage/downloadable_file.rb index bdfe5760b..49bd45f32 100644 --- a/app/lib/active_storage/downloadable_file.rb +++ b/app/lib/active_storage/downloadable_file.rb @@ -1,7 +1,7 @@ class ActiveStorage::DownloadableFile - def self.create_list_from_dossier(dossier) + def self.create_list_from_dossier(dossier, for_expert = false) dossier_export = PiecesJustificativesService.generate_dossier_export(dossier) - pjs = [dossier_export] + PiecesJustificativesService.liste_documents(dossier) + pjs = [dossier_export] + PiecesJustificativesService.liste_documents(dossier, for_expert) pjs.map do |piece_justificative| [ piece_justificative, From 0bd879ec9baa222f0cce8878cdcb1968c5d07168 Mon Sep 17 00:00:00 2001 From: kara Diaby Date: Tue, 28 Sep 2021 11:24:06 +0200 Subject: [PATCH 6/6] modify pj service --- app/services/pieces_justificatives_service.rb | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/app/services/pieces_justificatives_service.rb b/app/services/pieces_justificatives_service.rb index 8b1d59a7c..da59962b4 100644 --- a/app/services/pieces_justificatives_service.rb +++ b/app/services/pieces_justificatives_service.rb @@ -1,8 +1,8 @@ class PiecesJustificativesService - def self.liste_documents(dossier) - pjs_champs = pjs_for_champs(dossier) + def self.liste_documents(dossier, for_expert) + pjs_champs = pjs_for_champs(dossier, for_expert) pjs_commentaires = pjs_for_commentaires(dossier) - pjs_dossier = pjs_for_dossier(dossier) + pjs_dossier = pjs_for_dossier(dossier, for_expert) (pjs_champs + pjs_commentaires + pjs_dossier) .filter(&:attached?) @@ -120,8 +120,8 @@ class PiecesJustificativesService private - def self.pjs_for_champs(dossier) - allowed_champs = dossier.champs + dossier.champs_private + def self.pjs_for_champs(dossier, for_expert = false) + allowed_champs = for_expert ? dossier.champs : dossier.champs + dossier.champs_private allowed_child_champs = allowed_champs .filter { |c| c.type_champ == TypeDeChamp.type_champs.fetch(:repetition) } @@ -138,17 +138,22 @@ class PiecesJustificativesService .map(&:piece_jointe) end - def self.pjs_for_dossier(dossier) - bill_signatures = dossier.dossier_operation_logs.filter_map(&:bill_signature).uniq - - [ + def self.pjs_for_dossier(dossier, for_expert = false) + pjs = [ dossier.justificatif_motivation, dossier.attestation&.pdf, dossier.etablissement&.entreprise_attestation_sociale, - dossier.etablissement&.entreprise_attestation_fiscale, - dossier.dossier_operation_logs.map(&:serialized), - bill_signatures.map(&:serialized), - bill_signatures.map(&:signature) + dossier.etablissement&.entreprise_attestation_fiscale ].flatten.compact + + if !for_expert + bill_signatures = dossier.dossier_operation_logs.filter_map(&:bill_signature).uniq + pjs += [ + dossier.dossier_operation_logs.map(&:serialized), + bill_signatures.map(&:serialized), + bill_signatures.map(&:signature) + ].flatten.compact + end + pjs end end