dossier: remove UI for uploading old pieces justificatives

This commit is contained in:
Pierre de La Morinerie 2019-07-24 12:41:56 +00:00
parent 0c4cb3b498
commit 5502f2e42e
5 changed files with 5 additions and 268 deletions

View file

@ -132,7 +132,6 @@ module Users
end end
# FIXME: # FIXME:
# - remove PiecesJustificativesService
# - delegate draft save logic to champ ? # - delegate draft save logic to champ ?
def update_brouillon def update_brouillon
@dossier = dossier_with_champs @dossier = dossier_with_champs
@ -158,8 +157,6 @@ module Users
@dossier = dossier_with_champs @dossier = dossier_with_champs
end end
# FIXME:
# - remove PiecesJustificativesService
def update def update
@dossier = dossier_with_champs @dossier = dossier_with_champs
@ -297,7 +294,7 @@ module Users
end end
def update_dossier_and_compute_errors def update_dossier_and_compute_errors
errors = PiecesJustificativesService.upload!(@dossier, current_user, params) errors = []
if champs_params[:dossier] && !@dossier.update(champs_params[:dossier]) if champs_params[:dossier] && !@dossier.update(champs_params[:dossier])
errors += @dossier.errors.full_messages errors += @dossier.errors.full_messages
@ -305,7 +302,6 @@ module Users
if !save_draft? if !save_draft?
errors += @dossier.check_mandatory_champs errors += @dossier.check_mandatory_champs
errors += PiecesJustificativesService.missing_pj_error_messages(@dossier)
end end
errors errors

View file

@ -1,37 +1,4 @@
class PiecesJustificativesService class PiecesJustificativesService
def self.upload!(dossier, user, params)
tpj_contents = dossier.types_de_piece_justificative
.map { |tpj| [tpj, params["piece_justificative_#{tpj.id}"]] }
.select { |_, content| content.present? }
without_virus, with_virus = tpj_contents
.partition { |_, content| ClamavService.safe_file?(content.path) }
errors = with_virus
.map { |_, content| "#{content.original_filename} : virus détecté" }
errors + without_virus
.map { |tpj, content| save_pj(content, dossier, tpj, user) }
.compact()
end
def self.save_pj(content, dossier, tpj, user)
pj = PieceJustificative.new(content: content,
dossier: dossier,
type_de_piece_justificative: tpj,
user: user)
pj.save ? nil : "le fichier #{content.original_filename} (#{pj.libelle.truncate(200)}) n'a pas pu être sauvegardé"
end
def self.missing_pj_error_messages(dossier)
mandatory_pjs = dossier.types_de_piece_justificative.select(&:mandatory)
present_pjs = dossier.pieces_justificatives.map(&:type_de_piece_justificative)
missing_pjs = mandatory_pjs - present_pjs
missing_pjs.map { |pj| "La pièce jointe #{pj.libelle.truncate(200)} doit être fournie." }
end
def self.types_pj_as_types_de_champ(procedure) def self.types_pj_as_types_de_champ(procedure)
max_order_place = procedure.types_de_champ.pluck(:order_place).compact.max || -1 max_order_place = procedure.types_de_champ.pluck(:order_place).compact.max || -1
order_place = max_order_place + 1 order_place = max_order_place + 1

View file

@ -31,45 +31,6 @@
= render partial: "shared/dossiers/editable_champs/editable_champ", = render partial: "shared/dossiers/editable_champs/editable_champ",
locals: { champ: champ, form: champ_form } locals: { champ: champ, form: champ_form }
- tpjs = dossier.types_de_piece_justificative.order('order_place ASC')
- if tpjs.present?
.card.featured
.card-title
Pièces jointes
.warning
- if tpjs.many?
Pour éviter toute erreur, nous vous conseillons de limiter la taille de chaque pièce jointe à 20 Mo, et de les ajouter une par une, en enregistrant votre
= dossier.brouillon? ? "brouillon" : "dossier"
après chaque ajout.
- else
Pour éviter toute erreur, nous vous conseillons de limiter la taille de votre pièce jointe à 20 Mo.
- tpjs.each do |tpj|
.pj-input
%label{ for: "piece_justificative_#{tpj.id}" }
= tpj.libelle
- if tpj.mandatory?
%span.mandatory *
%p.piece-description= tpj.description
- if tpj.lien_demarche.present?
%p.piece-description
Récupérer le formulaire vierge pour mon dossier :
= link_to "Télécharger", tpj.lien_demarche, target: :blank, rel: :noopener
- if dossier.was_piece_justificative_uploaded_for_type_id?(tpj.id)
- pj = dossier.retrieve_last_piece_justificative_by_type(tpj.id)
%p
Pièce jointe déjà importée :
= link_to pj.original_filename, pj.content_url, target: :blank, rel: :noopener
= file_field_tag "piece_justificative_#{tpj.id}",
accept: PieceJustificative.accept_format,
max_file_size: 6.megabytes,
required: (tpj.mandatory? && !dossier.was_piece_justificative_uploaded_for_type_id?(tpj.id))
- if !apercu - if !apercu
.send-wrapper .send-wrapper
- if dossier.brouillon? - if dossier.brouillon?

View file

@ -476,29 +476,16 @@ describe Users::DossiersController, type: :controller do
end end
end end
context 'when the pj service returns an error' do
before do
expect(PiecesJustificativesService).to receive(:upload!).and_return(['nop'])
subject
end
it { expect(response).to render_template(:brouillon) }
it { expect(flash.alert).to eq(['nop']) }
end
context 'when a mandatory champ is missing' do context 'when a mandatory champ is missing' do
let(:value) { nil } let(:value) { nil }
before do before do
first_champ.type_de_champ.update(mandatory: true, libelle: 'l') first_champ.type_de_champ.update(mandatory: true, libelle: 'l')
allow(PiecesJustificativesService).to receive(:missing_pj_error_messages).and_return(['pj'])
subject subject
end end
it { expect(response).to render_template(:brouillon) } it { expect(response).to render_template(:brouillon) }
it { expect(flash.alert).to eq(['Le champ l doit être rempli.', 'pj']) } it { expect(flash.alert).to eq(['Le champ l doit être rempli.']) }
context 'and the user saves a draft' do context 'and the user saves a draft' do
let(:payload) { submit_payload.merge(save_draft: true) } let(:payload) { submit_payload.merge(save_draft: true) }
@ -511,7 +498,7 @@ describe Users::DossiersController, type: :controller do
let!(:dossier) { create(:dossier, :en_construction, user: user) } let!(:dossier) { create(:dossier, :en_construction, user: user) }
it { expect(response).to render_template(:brouillon) } it { expect(response).to render_template(:brouillon) }
it { expect(flash.alert).to eq(['Le champ l doit être rempli.', 'pj']) } it { expect(flash.alert).to eq(['Le champ l doit être rempli.']) }
end end
end end
end end
@ -535,8 +522,6 @@ describe Users::DossiersController, type: :controller do
before do before do
first_champ.type_de_champ.update(mandatory: true, libelle: 'l') first_champ.type_de_champ.update(mandatory: true, libelle: 'l')
allow(PiecesJustificativesService).to receive(:missing_pj_error_messages).and_return(['pj'])
subject subject
end end
@ -644,29 +629,16 @@ describe Users::DossiersController, type: :controller do
end end
end end
context 'when the pj service returns an error' do
before do
expect(PiecesJustificativesService).to receive(:upload!).and_return(['nop'])
subject
end
it { expect(response).to render_template(:modifier) }
it { expect(flash.alert).to eq(['nop']) }
end
context 'when a mandatory champ is missing' do context 'when a mandatory champ is missing' do
let(:value) { nil } let(:value) { nil }
before do before do
first_champ.type_de_champ.update(mandatory: true, libelle: 'l') first_champ.type_de_champ.update(mandatory: true, libelle: 'l')
allow(PiecesJustificativesService).to receive(:missing_pj_error_messages).and_return(['pj'])
subject subject
end end
it { expect(response).to render_template(:modifier) } it { expect(response).to render_template(:modifier) }
it { expect(flash.alert).to eq(['Le champ l doit être rempli.', 'pj']) } it { expect(flash.alert).to eq(['Le champ l doit être rempli.']) }
end end
context 'when dossier has no champ' do context 'when dossier has no champ' do

View file

@ -1,159 +0,0 @@
require 'spec_helper'
describe PiecesJustificativesService do
let(:user) { create(:user) }
let(:safe_file) { true }
before :each do
allow(ClamavService).to receive(:safe_file?).and_return(safe_file)
end
let(:hash) { {} }
let!(:tpj_not_mandatory) do
TypeDePieceJustificative.create(libelle: 'not mandatory', mandatory: false)
end
let!(:tpj_mandatory) do
TypeDePieceJustificative.create(libelle: 'justificatif', mandatory: true)
end
let(:procedure) { Procedure.create(types_de_piece_justificative: tpjs) }
let(:dossier) { Dossier.create(procedure: procedure) }
let(:errors) { PiecesJustificativesService.upload!(dossier, user, hash) }
let(:tpjs) { [tpj_not_mandatory] }
let(:attachment_list) { PiecesJustificativesService.liste_pieces_justificatives(dossier) }
let(:poids_total) { PiecesJustificativesService.pieces_justificatives_total_size(dossier) }
describe 'self.upload!' do
context 'when no params are given' do
it { expect(errors).to eq([]) }
end
context 'when there is something wrong with file save' do
let(:hash) do
{
"piece_justificative_#{tpj_not_mandatory.id}" =>
double(path: '', original_filename: 'filename')
}
end
it { expect(errors).to match(["le fichier filename (not mandatory) n'a pas pu être sauvegardé"]) }
end
context 'when a virus is provided' do
let(:safe_file) { false }
let(:hash) do
{
"piece_justificative_#{tpj_not_mandatory.id}" =>
double(path: '', original_filename: 'bad_file')
}
end
it { expect(errors).to match(['bad_file : virus détecté']) }
end
context 'when a regular file is provided' do
let(:content) { double(path: '', original_filename: 'filename') }
let(:hash) do
{
"piece_justificative_#{tpj_not_mandatory.id}" =>
content
}
end
before :each do
expect(PiecesJustificativesService).to receive(:save_pj)
.with(content, dossier, tpj_not_mandatory, user)
.and_return(nil)
end
it 'is saved' do
expect(errors).to match([])
end
end
end
describe 'missing_pj_error_messages' do
let(:errors) { PiecesJustificativesService.missing_pj_error_messages(dossier) }
let(:tpjs) { [tpj_mandatory] }
context 'when no params are given' do
it { expect(errors).to match(['La pièce jointe justificatif doit être fournie.']) }
end
context 'when the piece justificative is provided' do
before :each do
# we are messing around piece_justificative
# because directly doubling carrierwave params seems complicated
piece_justificative_double = double(type_de_piece_justificative: tpj_mandatory)
expect(dossier).to receive(:pieces_justificatives).and_return([piece_justificative_double])
end
it {
expect(errors).to match([])
}
end
end
describe '#attachment_list' do
context 'when no piece_justificative is present' do
it { expect(attachment_list).to match([]) }
it { expect(poids_total).to be 0 }
end
context 'when there is a piece_justificative' do
let (:pj) { create(:champ, :piece_justificative, :with_piece_justificative_file) }
before do
dossier.champs = [pj]
end
it { expect(attachment_list).not_to be_empty }
it { expect(poids_total).to be pj.piece_justificative_file.byte_size }
end
end
describe 'types_pj_as_types_de_champ' do
subject { PiecesJustificativesService.types_pj_as_types_de_champ(procedure) }
it 'generates one header champ, plus one champ per PJ' do
expect(subject.pluck(:libelle)).to contain_exactly("Pièces jointes", "not mandatory")
end
it 'remembers the id of the PJ that got converted into a champ' do
expect(subject.map(&:old_pj)).to include({ 'stable_id' => tpj_not_mandatory.id })
end
context 'without pre-existing champs' do
it 'generates a sequence of order_places incrementing from zero' do
expect(subject.pluck(:order_place)).to contain_exactly(0, 1)
end
end
context 'with pre-existing champs' do
let(:procedure) do
create(
:procedure,
types_de_piece_justificative: tpjs,
types_de_champ: [build(:type_de_champ, order_place: 0), build(:type_de_champ, order_place: 1)]
)
end
it 'generates a sequence of incrementing order_places that continues where the last type de champ left off' do
expect(subject.pluck(:order_place)).to contain_exactly(2, 3)
end
end
context 'with pre-existing champs without an order place' do
let(:procedure) do
create(
:procedure,
types_de_piece_justificative: tpjs,
types_de_champ: [build(:type_de_champ, order_place: 0), build(:type_de_champ, order_place: nil)]
)
end
it 'ignores champs without an order place' do
expect(subject.pluck(:order_place)).to contain_exactly(1, 2)
end
end
end
end