implementation du systeme de PJ de motivation

This commit is contained in:
clemkeirua 2019-02-18 17:52:15 +01:00
parent 5477bd67ee
commit 4aab72be68
14 changed files with 144 additions and 45 deletions

View file

@ -93,16 +93,17 @@ module Gestionnaires
def terminer
motivation = params[:dossier] && params[:dossier][:motivation]
justificatif = params[:dossier] && params[:dossier][:justificatif_motivation]
case params[:process_action]
when "refuser"
dossier.refuser!(current_gestionnaire, motivation)
dossier.refuser!(current_gestionnaire, motivation, justificatif)
flash.notice = "Dossier considéré comme refusé."
when "classer_sans_suite"
dossier.classer_sans_suite!(current_gestionnaire, motivation)
dossier.classer_sans_suite!(current_gestionnaire, motivation, justificatif)
flash.notice = "Dossier considéré comme sans suite."
when "accepter"
dossier.accepter!(current_gestionnaire, motivation)
dossier.accepter!(current_gestionnaire, motivation, justificatif)
flash.notice = "Dossier traité avec succès."
end

View file

@ -11,3 +11,8 @@ export function motivationCancel() {
document.querySelectorAll('.motivation').forEach(hide);
show(document.querySelector('.dropdown-items'));
}
export function showImportJustificatif(name) {
show(document.querySelector('#justificatif_motivation_import_' + name));
hide(document.querySelector('#justificatif_motivation_suggest_' + name));
}

View file

@ -29,7 +29,11 @@ import '../new_design/champs/repetition';
import { toggleCondidentielExplanation } from '../new_design/avis';
import { scrollMessagerie } from '../new_design/messagerie';
import { showMotivation, motivationCancel } from '../new_design/state-button';
import {
showMotivation,
motivationCancel,
showImportJustificatif
} from '../new_design/state-button';
import { toggleChart } from '../new_design/toggle-chart';
import { replaceSemicolonByComma } from '../new_design/avis';
@ -40,6 +44,7 @@ const DS = {
scrollMessagerie,
showMotivation,
motivationCancel,
showImportJustificatif,
toggleChart,
replaceSemicolonByComma
};

View file

@ -17,20 +17,20 @@ class NotificationMailer < ApplicationMailer
end
def send_closed_notification(dossier)
send_notification(dossier, dossier.procedure.closed_mail_template)
send_final_notification(dossier, dossier.procedure.closed_mail_template, dossier.justificatif_motivation)
end
def send_refused_notification(dossier)
send_notification(dossier, dossier.procedure.refused_mail_template)
send_final_notification(dossier, dossier.procedure.refused_mail_template, dossier.justificatif_motivation)
end
def send_without_continuation_notification(dossier)
send_notification(dossier, dossier.procedure.without_continuation_mail_template)
send_final_notification(dossier, dossier.procedure.without_continuation_mail_template, dossier.justificatif_motivation)
end
private
def send_notification(dossier, mail_template)
def send_notification(dossier, mail_template, attachment_file = nil)
email = dossier.user.email
subject = mail_template.subject_for_dossier(dossier)

View file

@ -20,6 +20,8 @@ class Dossier < ApplicationRecord
has_one :attestation, dependent: :destroy
has_many :pieces_justificatives, dependent: :destroy
has_one_attached :justificatif_motivation
has_many :champs, -> { root.public_only.ordered }, dependent: :destroy
has_many :champs_private, -> { root.private_only.ordered }, class_name: 'Champ', dependent: :destroy
has_many :commentaires, dependent: :destroy
@ -296,10 +298,12 @@ class Dossier < ApplicationRecord
log_dossier_operation(gestionnaire, :repasser_en_construction)
end
def accepter!(gestionnaire, motivation)
def accepter!(gestionnaire, motivation, justificatif = nil)
self.motivation = motivation
self.en_instruction_at ||= Time.zone.now
if justificatif
self.justificatif_motivation.attach(justificatif)
end
accepte!
if attestation.nil?
@ -330,20 +334,24 @@ class Dossier < ApplicationRecord
DeletedDossier.create_from_dossier(self)
end
def refuser!(gestionnaire, motivation)
def refuser!(gestionnaire, motivation, justificatif = nil)
self.motivation = motivation
self.en_instruction_at ||= Time.zone.now
if justificatif
self.justificatif_motivation.attach(justificatif)
end
refuse!
NotificationMailer.send_refused_notification(self).deliver_later
log_dossier_operation(gestionnaire, :refuser)
end
def classer_sans_suite!(gestionnaire, motivation)
def classer_sans_suite!(gestionnaire, motivation, justificatif = nil)
self.motivation = motivation
self.en_instruction_at ||= Time.zone.now
if justificatif
self.justificatif_motivation.attach(justificatif)
end
sans_suite!
NotificationMailer.send_without_continuation_notification(self).deliver_later

View file

@ -22,6 +22,7 @@ class DossierSerializer < ActiveModel::Serializer
has_many :champs_private
has_many :pieces_justificatives
has_many :types_de_piece_justificative
has_one :justificatif_motivation
has_many :champs, serializer: ChampSerializer
@ -52,6 +53,12 @@ class DossierSerializer < ActiveModel::Serializer
PiecesJustificativesService.serialize_champs_as_pjs(object)
end
def justificatif_motivation
if object.justificatif_motivation.attached?
Rails.application.routes.url_helpers.url_for(object.justificatif_motivation)
end
end
def types_de_piece_justificative
ActiveModelSerializers::SerializableResource.new(object.types_de_piece_justificative).serializable_hash +
PiecesJustificativesService.serialize_types_de_champ_as_type_pj(object)

View file

@ -28,6 +28,10 @@
%li= unspecified_annotations_privee.libelle
- else
= text_area :dossier, :motivation, class: 'motivation-text-area', placeholder: placeholder, required: true
%span{ id: "justificatif_motivation_suggest_#{popup_class}", onclick: "DS.showImportJustificatif('#{popup_class}');" }
.button Ajouter un justificatif (optionnel)
.hidden{ id: "justificatif_motivation_import_#{popup_class}" }
= file_field :dossier, :justificatif_motivation, direct_upload: true
.text-right
- if title == 'Accepter' && dossier.procedure.attestation_template&.activated?
= link_to "Voir l'attestation", apercu_attestation_gestionnaire_dossier_path(dossier.procedure, dossier), target: '_blank', rel: 'noopener', class: 'button', title: "Voir l'attestation qui sera envoyée au demandeur"

View file

@ -0,0 +1,7 @@
- if dossier.present?
- justificatif = dossier.justificatif_motivation
- if dossier.justificatif_motivation.attached?
.action
= link_to (justificatif), target: '_blank', class: 'button primary' do
%span.icon.download
Télécharger le justificatif

View file

@ -1,7 +1,7 @@
.container
- if dossier.en_construction_at.present?
.card
= render partial: "shared/dossiers/horodatage", locals: { dossier: dossier }
= render partial: "shared/dossiers/infos_generales", locals: { dossier: dossier }
.tab-title Identité du demandeur
.card

View file

@ -1,5 +0,0 @@
%table.table.vertical.dossier-champs
%tbody
%tr
%th.libelle Déposé le :
%td= l(dossier.en_construction_at, format: '%d %B %Y')

View file

@ -0,0 +1,14 @@
%table.table.vertical.dossier-champs
%tbody
%tr
%th.libelle Déposé le :
%td= l(dossier.en_construction_at, format: '%d %B %Y')
- if dossier.justificatif_motivation.attached?
- justificatif = dossier.justificatif_motivation
%tr
%th.libelle Justificatif :
%td
.action
= link_to url_for(justificatif), target: '_blank', class: 'button primary' do
%span.icon.download
Télécharger le justificatif

View file

@ -50,12 +50,15 @@
%h3 Motif de lacceptation
%blockquote= dossier.motivation
= render partial: 'new_user/dossiers/show/download_justificatif', locals: { dossier: dossier }
- if dossier.attestation.present?
.action
= link_to attestation_dossier_path(dossier), target: '_blank', rel: 'noopener', class: 'button primary' do
%span.icon.download
Télécharger lattestation
- elsif dossier.refuse?
.refuse
%p.decision
@ -68,6 +71,7 @@
%h3 Motif du refus
%blockquote= dossier.motivation
= render partial: 'new_user/dossiers/show/download_justificatif', locals: { dossier: @dossier }
.action
= link_to 'Envoyer un message à ladministration', messagerie_dossier_url(dossier, anchor: 'new_commentaire'), class: 'button'
@ -79,6 +83,8 @@
= succeed '.' do
%strong sans suite
= render partial: 'new_user/dossiers/show/download_justificatif', locals: { dossier: @dossier }
- if dossier.motivation.present?
%h3 Motif du classement sans suite
%blockquote= dossier.motivation

View file

@ -139,7 +139,7 @@ describe API::V1::DossiersController do
let!(:dossier) { Timecop.freeze(date_creation) { create(:dossier, :with_entreprise, :en_construction, procedure: procedure, motivation: "Motivation") } }
let(:dossier_id) { dossier.id }
let(:body) { JSON.parse(retour.body, symbolize_names: true) }
let(:field_list) { [:id, :created_at, :updated_at, :archived, :individual, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :champs_private, :commentaires, :state, :simplified_state, :initiated_at, :processed_at, :received_at, :motivation, :email, :instructeurs] }
let(:field_list) { [:id, :created_at, :updated_at, :archived, :individual, :entreprise, :etablissement, :cerfa, :types_de_piece_justificative, :pieces_justificatives, :champs, :champs_private, :commentaires, :state, :simplified_state, :initiated_at, :processed_at, :received_at, :motivation, :email, :instructeurs, :justificatif_motivation] }
subject { body[:dossier] }
it 'return REST code 200', :show_in_doc do

View file

@ -7,6 +7,7 @@ describe Gestionnaires::DossiersController, type: :controller do
let(:gestionnaires) { [gestionnaire] }
let(:procedure) { create(:procedure, :published, gestionnaires: gestionnaires) }
let(:dossier) { create(:dossier, :en_construction, procedure: procedure) }
let(:fake_justificatif) { Rack::Test::UploadedFile.new("./spec/fixtures/files/piece_justificative_0.pdf", 'application/pdf') }
before { sign_in(gestionnaire) }
@ -141,24 +142,39 @@ describe Gestionnaires::DossiersController, type: :controller do
sign_in gestionnaire
end
subject { post :terminer, params: { process_action: "refuser", procedure_id: procedure.id, dossier_id: dossier.id }, format: 'js' }
context 'simple refusal' do
subject { post :terminer, params: { process_action: "refuser", procedure_id: procedure.id, dossier_id: dossier.id }, format: 'js' }
it 'change state to refuse' do
subject
it 'change state to refuse' do
subject
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:refuse))
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:refuse))
expect(dossier.justificatif_motivation).to_not be_attached
end
it 'Notification email is sent' do
expect(NotificationMailer).to receive(:send_refused_notification)
.with(dossier).and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_later)
subject
end
end
it 'Notification email is sent' do
expect(NotificationMailer).to receive(:send_refused_notification)
.with(dossier).and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_later)
context 'refusal with a justificatif' do
subject { post :terminer, params: { process_action: "refuser", procedure_id: procedure.id, dossier_id: dossier.id, dossier: { justificatif_motivation: fake_justificatif } }, format: 'js' }
subject
it 'attachs a justificatif' do
subject
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:refuse))
expect(dossier.justificatif_motivation).to be_attached
end
it { expect(subject.body).to include('.state-button') }
end
it { expect(subject.body).to include('.state-button') }
end
context "with classer_sans_suite" do
@ -166,25 +182,41 @@ describe Gestionnaires::DossiersController, type: :controller do
dossier.en_instruction!
sign_in gestionnaire
end
context 'without attachment' do
subject { post :terminer, params: { process_action: "classer_sans_suite", procedure_id: procedure.id, dossier_id: dossier.id }, format: 'js' }
subject { post :terminer, params: { process_action: "classer_sans_suite", procedure_id: procedure.id, dossier_id: dossier.id }, format: 'js' }
it 'change state to sans_suite' do
subject
it 'change state to sans_suite' do
subject
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:sans_suite))
expect(dossier.justificatif_motivation).to_not be_attached
end
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:sans_suite))
it 'Notification email is sent' do
expect(NotificationMailer).to receive(:send_without_continuation_notification)
.with(dossier).and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_later)
subject
end
it { expect(subject.body).to include('.state-button') }
end
it 'Notification email is sent' do
expect(NotificationMailer).to receive(:send_without_continuation_notification)
.with(dossier).and_return(NotificationMailer)
expect(NotificationMailer).to receive(:deliver_later)
context 'with attachment' do
subject { post :terminer, params: { process_action: "classer_sans_suite", procedure_id: procedure.id, dossier_id: dossier.id, dossier: { justificatif_motivation: fake_justificatif } }, format: 'js' }
subject
it 'change state to sans_suite' do
subject
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:sans_suite))
expect(dossier.justificatif_motivation).to be_attached
end
it { expect(subject.body).to include('.state-button') }
end
it { expect(subject.body).to include('.state-button') }
end
context "with accepter" do
@ -206,6 +238,7 @@ describe Gestionnaires::DossiersController, type: :controller do
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:accepte))
expect(dossier.justificatif_motivation).to_not be_attached
end
context 'when the dossier does not have any attestation' do
@ -261,6 +294,20 @@ describe Gestionnaires::DossiersController, type: :controller do
it { subject }
end
context 'with an attachment' do
subject { post :terminer, params: { process_action: "accepter", procedure_id: procedure.id, dossier_id: dossier.id, dossier: { justificatif_motivation: fake_justificatif } }, format: 'js' }
it 'change state to accepte' do
subject
dossier.reload
expect(dossier.state).to eq(Dossier.states.fetch(:accepte))
expect(dossier.justificatif_motivation).to be_attached
end
it { expect(subject.body).to include('.state-button') }
end
end
end