app: add controller and view to generate a deposit receipt
This commit is contained in:
parent
fe56b7bb68
commit
9bc5364ca2
15 changed files with 235 additions and 1 deletions
|
@ -5,7 +5,7 @@ module Users
|
||||||
layout 'procedure_context', only: [:identite, :update_identite, :siret, :update_siret]
|
layout 'procedure_context', only: [:identite, :update_identite, :siret, :update_siret]
|
||||||
|
|
||||||
ACTIONS_ALLOWED_TO_ANY_USER = [:index, :recherche, :new, :transferer_all]
|
ACTIONS_ALLOWED_TO_ANY_USER = [:index, :recherche, :new, :transferer_all]
|
||||||
ACTIONS_ALLOWED_TO_OWNER_OR_INVITE = [:show, :demande, :messagerie, :brouillon, :update_brouillon, :modifier, :update, :create_commentaire]
|
ACTIONS_ALLOWED_TO_OWNER_OR_INVITE = [:show, :demande, :messagerie, :brouillon, :update_brouillon, :modifier, :update, :create_commentaire, :papertrail]
|
||||||
ACTIONS_ALLOWED_TO_OWNER_OR_INVITE_HIDDEN = [:restore]
|
ACTIONS_ALLOWED_TO_OWNER_OR_INVITE_HIDDEN = [:restore]
|
||||||
|
|
||||||
before_action :ensure_ownership!, except: ACTIONS_ALLOWED_TO_ANY_USER + ACTIONS_ALLOWED_TO_OWNER_OR_INVITE + ACTIONS_ALLOWED_TO_OWNER_OR_INVITE_HIDDEN
|
before_action :ensure_ownership!, except: ACTIONS_ALLOWED_TO_ANY_USER + ACTIONS_ALLOWED_TO_OWNER_OR_INVITE + ACTIONS_ALLOWED_TO_OWNER_OR_INVITE_HIDDEN
|
||||||
|
@ -69,6 +69,11 @@ module Users
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def papertrail
|
||||||
|
raise ActionController::BadRequest if dossier.brouillon?
|
||||||
|
@dossier = dossier
|
||||||
|
end
|
||||||
|
|
||||||
def identite
|
def identite
|
||||||
@dossier = dossier
|
@dossier = dossier
|
||||||
@user = current_user
|
@user = current_user
|
||||||
|
|
19
app/helpers/papertrail_helper.rb
Normal file
19
app/helpers/papertrail_helper.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
module PapertrailHelper
|
||||||
|
def papertrail_requester_identity(dossier)
|
||||||
|
if dossier.etablissement.present?
|
||||||
|
raison_sociale_or_name(dossier.etablissement)
|
||||||
|
else
|
||||||
|
[dossier.individual.prenom, dossier.individual.nom.upcase].join(' ')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def papertrail_dossier_state(dossier)
|
||||||
|
raise "Dossiers in 'brouillon' state are not supported" if dossier.brouillon?
|
||||||
|
# i18n-tasks-use t('users.dossiers.papertrail.dossier_state.en_construction')
|
||||||
|
# i18n-tasks-use t('users.dossiers.papertrail.dossier_state.en_instruction')
|
||||||
|
# i18n-tasks-use t('users.dossiers.papertrail.dossier_state.accepte')
|
||||||
|
# i18n-tasks-use t('users.dossiers.papertrail.dossier_state.refuse')
|
||||||
|
# i18n-tasks-use t('users.dossiers.papertrail.dossier_state.sans_suite')
|
||||||
|
I18n.t("users.dossiers.papertrail.states.#{dossier.state}")
|
||||||
|
end
|
||||||
|
end
|
99
app/views/users/dossiers/papertrail.pdf.prawn
Normal file
99
app/views/users/dossiers/papertrail.pdf.prawn
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
require 'prawn/measurement_extensions'
|
||||||
|
|
||||||
|
#----- A4 page size
|
||||||
|
page_size = 'A4'
|
||||||
|
page_width = 595
|
||||||
|
|
||||||
|
#----- margins
|
||||||
|
top_margin = 20
|
||||||
|
right_margin = 20
|
||||||
|
bottom_margin = 20
|
||||||
|
left_margin = 20
|
||||||
|
|
||||||
|
header_width = page_width - left_margin - right_margin
|
||||||
|
body_width = 400
|
||||||
|
|
||||||
|
body_left_margin = (page_width - body_width - left_margin - right_margin) / 2
|
||||||
|
|
||||||
|
prawn_document(margin: [top_margin, right_margin, bottom_margin, left_margin], page_size: page_size) do |pdf|
|
||||||
|
pdf.font_families.update('marianne' => {
|
||||||
|
normal: Rails.root.join('lib/prawn/fonts/marianne/marianne-regular.ttf'),
|
||||||
|
bold: Rails.root.join('lib/prawn/fonts/marianne/marianne-bold.ttf')
|
||||||
|
})
|
||||||
|
pdf.font 'marianne'
|
||||||
|
|
||||||
|
grey = '555555'
|
||||||
|
black = '333333'
|
||||||
|
|
||||||
|
pdf.float do
|
||||||
|
pdf.svg IO.read(DOSSIER_DEPOSIT_RECEIPT_LOGO_SRC), height: 64
|
||||||
|
end
|
||||||
|
|
||||||
|
pdf.bounding_box([110, pdf.cursor - 18], width: header_width - 200) do
|
||||||
|
pdf.fill_color black
|
||||||
|
pdf.text APPLICATION_NAME, size: 20, style: :bold
|
||||||
|
|
||||||
|
pdf.fill_color grey
|
||||||
|
pdf.text t('.receipt'), size: 14
|
||||||
|
end
|
||||||
|
|
||||||
|
pdf.bounding_box([body_left_margin, pdf.cursor - 20], width: body_width) do
|
||||||
|
pdf.fill_color black
|
||||||
|
pdf.pad_top(40) { pdf.text @dossier.procedure.libelle, size: 14, character_spacing: -0.2, align: :center }
|
||||||
|
|
||||||
|
pdf.fill_color grey
|
||||||
|
description = t('.description', user_name: papertrail_requester_identity(@dossier), procedure: @dossier.procedure.libelle, date: l(@dossier.created_at, format: '%e %B %Y'))
|
||||||
|
pdf.pad_top(30) { pdf.text description, size: 10, character_spacing: -0.2, align: :left }
|
||||||
|
|
||||||
|
pdf.fill_color black
|
||||||
|
pdf.pad_top(30) { pdf.text t('views.shared.dossiers.demande.requester_identity'), size: 14, character_spacing: -0.2, align: :justify }
|
||||||
|
|
||||||
|
if @dossier.individual.present?
|
||||||
|
pdf.pad_top(7) do
|
||||||
|
pdf.fill_color grey
|
||||||
|
pdf.text "#{Individual.human_attribute_name(:prenom)} : #{@dossier.individual.prenom}", size: 10, character_spacing: -0.2, align: :justify
|
||||||
|
pdf.text "#{Individual.human_attribute_name(:nom)} : #{@dossier.individual.nom.upcase}", size: 10, character_spacing: -0.2, align: :justify
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if @dossier.etablissement.present?
|
||||||
|
pdf.pad_top(7) do
|
||||||
|
pdf.fill_color grey
|
||||||
|
pdf.text "Dénomination : " + raison_sociale_or_name(@dossier.etablissement), size: 10, character_spacing: -0.2, align: :justify
|
||||||
|
pdf.text "SIRET : " + @dossier.etablissement.siret, size: 10, character_spacing: -0.2, align: :justify
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
pdf.fill_color black
|
||||||
|
pdf.pad_top(30) { pdf.text Dossier.model_name.human, size: 14, character_spacing: -0.2, align: :justify }
|
||||||
|
|
||||||
|
pdf.fill_color grey
|
||||||
|
pdf.pad_top(7) do
|
||||||
|
pdf.text "#{Dossier.human_attribute_name(:id)} : #{@dossier.id.to_s}", size: 10, character_spacing: -0.2, align: :justify
|
||||||
|
pdf.text t('.file_submitted_at') + ' : ' + l(@dossier.en_construction_at, format: '%e %B %Y'), size: 10, character_spacing: -0.2, align: :justify
|
||||||
|
pdf.text t('.dossier_state') + ' : ' + papertrail_dossier_state(@dossier), size: 10, character_spacing: -0.2, align: :justify
|
||||||
|
end
|
||||||
|
|
||||||
|
service = @dossier.procedure.service
|
||||||
|
if service.present?
|
||||||
|
pdf.fill_color black
|
||||||
|
pdf.pad_top(30) { pdf.text t('.administrative_service'), size: 14, character_spacing: -0.2, align: :justify }
|
||||||
|
|
||||||
|
pdf.fill_color grey
|
||||||
|
pdf.pad_top(7) do
|
||||||
|
pdf.text "#{Service.model_name.human} : " + [service.nom, service.organisme].join(", "), size: 10, character_spacing: -0.2, align: :justify
|
||||||
|
pdf.text "#{Service.human_attribute_name(:adresse)} : #{service.adresse}", size: 10, character_spacing: -0.2, align: :justify
|
||||||
|
pdf.text "#{Service.human_attribute_name(:email)} : #{service.email}", size: 10, character_spacing: -0.2, align: :justify
|
||||||
|
if service.telephone.present?
|
||||||
|
pdf.text "#{Service.human_attribute_name(:telephone)} : #{service.telephone}", size: 10, character_spacing: -0.2, align: :justify
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
pdf.fill_color black
|
||||||
|
pdf.pad_top(100) do
|
||||||
|
pdf.text t('.generated_at', date: l(Time.zone.now.to_date, format: :long)), size: 10, character_spacing: -0.2, align: :right
|
||||||
|
pdf.text t('.signature', app_name: APPLICATION_NAME), size: 10, character_spacing: -0.2, align: :right
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -9,5 +9,8 @@
|
||||||
.container
|
.container
|
||||||
= render partial: 'users/dossiers/show/status_overview', locals: { dossier: @dossier }
|
= render partial: 'users/dossiers/show/status_overview', locals: { dossier: @dossier }
|
||||||
|
|
||||||
|
- if @dossier.procedure.feature_enabled?(:procedure_dossier_papertrail)
|
||||||
|
= render partial: 'users/dossiers/show/papertrail', locals: { dossier: @dossier }
|
||||||
|
|
||||||
- if !@dossier.termine?
|
- if !@dossier.termine?
|
||||||
= render partial: 'users/dossiers/show/latest_message', locals: { dossier: @dossier }
|
= render partial: 'users/dossiers/show/latest_message', locals: { dossier: @dossier }
|
||||||
|
|
|
@ -68,6 +68,9 @@ DS_ENV="staging"
|
||||||
# Instance customization: Procedure default logo ---> to be put in "app/assets/images"
|
# Instance customization: Procedure default logo ---> to be put in "app/assets/images"
|
||||||
# PROCEDURE_DEFAULT_LOGO_SRC="republique-francaise-logo.svg"
|
# PROCEDURE_DEFAULT_LOGO_SRC="republique-francaise-logo.svg"
|
||||||
|
|
||||||
|
# Instance customization: Deposit receipt logo ---> to be put in "app/assets/images"
|
||||||
|
# DOSSIER_DEPOSIT_RECEIPT_LOGO_SRC="app/assets/images/republique-francaise-logo.svg"
|
||||||
|
|
||||||
# Instance customization: PDF export logo ---> to be put in "app/assets/images"
|
# Instance customization: PDF export logo ---> to be put in "app/assets/images"
|
||||||
# DOSSIER_PDF_EXPORT_LOGO_SRC="app/assets/images/header/logo-ds-wide.svg"
|
# DOSSIER_PDF_EXPORT_LOGO_SRC="app/assets/images/header/logo-ds-wide.svg"
|
||||||
|
|
||||||
|
|
|
@ -16,5 +16,8 @@ MAILER_FOOTER_LOGO_SRC = ENV.fetch("MAILER_FOOTER_LOGO_SRC", "mailer/instructeur
|
||||||
# Default logo of a procedure
|
# Default logo of a procedure
|
||||||
PROCEDURE_DEFAULT_LOGO_SRC = ENV.fetch("PROCEDURE_DEFAULT_LOGO_SRC", "republique-francaise-logo.svg")
|
PROCEDURE_DEFAULT_LOGO_SRC = ENV.fetch("PROCEDURE_DEFAULT_LOGO_SRC", "republique-francaise-logo.svg")
|
||||||
|
|
||||||
|
# Deposit receipt logo
|
||||||
|
DOSSIER_DEPOSIT_RECEIPT_LOGO_SRC = ENV.fetch("DOSSIER_DEPOSIT_RECEIPT_LOGO_SRC", "app/assets/images/republique-francaise-logo.svg")
|
||||||
|
|
||||||
# Logo in PDF export of a "Dossier"
|
# Logo in PDF export of a "Dossier"
|
||||||
DOSSIER_PDF_EXPORT_LOGO_SRC = ENV.fetch("DOSSIER_PDF_EXPORT_LOGO_SRC", "app/assets/images/header/logo-ds-wide.svg")
|
DOSSIER_PDF_EXPORT_LOGO_SRC = ENV.fetch("DOSSIER_PDF_EXPORT_LOGO_SRC", "app/assets/images/header/logo-ds-wide.svg")
|
||||||
|
|
|
@ -453,6 +453,20 @@ 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."
|
||||||
|
papertrail:
|
||||||
|
receipt: "Deposit receipt"
|
||||||
|
description: "This document attests that on the %{date}, %{user_name} submitted a file on the procedure “%{procedure}”."
|
||||||
|
file_submitted_at: "File submission date"
|
||||||
|
dossier_state: "File status"
|
||||||
|
states:
|
||||||
|
en_construction: "submitted, pending processing"
|
||||||
|
en_instruction: "processing"
|
||||||
|
accepte: "accepted"
|
||||||
|
refuse: "declined"
|
||||||
|
sans suite: "closed, no further action"
|
||||||
|
administrative_service: "Administrative department"
|
||||||
|
generated_at: "Made on %{date},"
|
||||||
|
signature: "%{app_name}"
|
||||||
instructeurs:
|
instructeurs:
|
||||||
dossiers:
|
dossiers:
|
||||||
deleted_by_instructeur: "The folder has been deleted"
|
deleted_by_instructeur: "The folder has been deleted"
|
||||||
|
|
|
@ -461,6 +461,20 @@ fr:
|
||||||
identity_saved: "Identité enregistrée"
|
identity_saved: "Identité enregistrée"
|
||||||
attestation:
|
attestation:
|
||||||
no_longer_available: "L’attestation n'est plus disponible sur ce dossier."
|
no_longer_available: "L’attestation n'est plus disponible sur ce dossier."
|
||||||
|
papertrail:
|
||||||
|
receipt: "Accusé de dépôt"
|
||||||
|
description: "Ce document atteste que %{user_name} a déposé le %{date} un dossier sur la démarche « %{procedure} »."
|
||||||
|
file_submitted_at: "Dossier déposé le"
|
||||||
|
dossier_state: "État du dossier"
|
||||||
|
states:
|
||||||
|
en_construction: "déposé, en attente d’examen par l’administration"
|
||||||
|
en_instruction: "en cours d’instruction par l’administration"
|
||||||
|
accepte: "accepté"
|
||||||
|
refuse: "refusé"
|
||||||
|
sans suite: "classé sans suite"
|
||||||
|
administrative_service: "Service administratif"
|
||||||
|
generated_at: "Fait le %{date},"
|
||||||
|
signature: "La direction de %{app_name}"
|
||||||
instructeurs:
|
instructeurs:
|
||||||
dossiers:
|
dossiers:
|
||||||
deleted_by_instructeur: "Le dossier a bien été supprimé de votre interface"
|
deleted_by_instructeur: "Le dossier a bien été supprimé de votre interface"
|
||||||
|
|
|
@ -6,6 +6,7 @@ en:
|
||||||
other: "Files"
|
other: "Files"
|
||||||
attributes:
|
attributes:
|
||||||
dossier:
|
dossier:
|
||||||
|
id: "File number"
|
||||||
state: "State"
|
state: "State"
|
||||||
dossier/state: &state
|
dossier/state: &state
|
||||||
brouillon: "Draft"
|
brouillon: "Draft"
|
||||||
|
|
|
@ -6,6 +6,7 @@ fr:
|
||||||
other: "Dossiers"
|
other: "Dossiers"
|
||||||
attributes:
|
attributes:
|
||||||
dossier:
|
dossier:
|
||||||
|
id: "Numéro de dossier"
|
||||||
montant_projet: 'Le montant du projet'
|
montant_projet: 'Le montant du projet'
|
||||||
montant_aide_demande: "Le montant d’aide demandée"
|
montant_aide_demande: "Le montant d’aide demandée"
|
||||||
date_previsionnelle: "La date de début prévisionnelle"
|
date_previsionnelle: "La date de début prévisionnelle"
|
||||||
|
|
11
config/locales/models/service/en.yml
Normal file
11
config/locales/models/service/en.yml
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
en:
|
||||||
|
activerecord:
|
||||||
|
models:
|
||||||
|
service:
|
||||||
|
one: 'Service'
|
||||||
|
other: 'Services'
|
||||||
|
attributes:
|
||||||
|
service:
|
||||||
|
adresse: 'Mail address'
|
||||||
|
email: 'Email'
|
||||||
|
telephone: 'Phone'
|
|
@ -1,4 +1,14 @@
|
||||||
fr:
|
fr:
|
||||||
|
activerecord:
|
||||||
|
models:
|
||||||
|
service:
|
||||||
|
one: 'Service'
|
||||||
|
other: 'Services'
|
||||||
|
attributes:
|
||||||
|
service:
|
||||||
|
adresse: 'Adresse postale'
|
||||||
|
email: 'Email de contact'
|
||||||
|
telephone: 'Téléphone'
|
||||||
type_organisme:
|
type_organisme:
|
||||||
administration_centrale: 'Administration centrale'
|
administration_centrale: 'Administration centrale'
|
||||||
association: 'Association'
|
association: 'Association'
|
||||||
|
|
|
@ -273,6 +273,7 @@ Rails.application.routes.draw do
|
||||||
patch 'restore', to: 'dossiers#restore'
|
patch 'restore', to: 'dossiers#restore'
|
||||||
get 'attestation'
|
get 'attestation'
|
||||||
get 'transferer', to: 'dossiers#transferer'
|
get 'transferer', to: 'dossiers#transferer'
|
||||||
|
get 'papertrail', format: :pdf
|
||||||
end
|
end
|
||||||
|
|
||||||
collection do
|
collection do
|
||||||
|
|
|
@ -1011,6 +1011,31 @@ describe Users::DossiersController, type: :controller do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#papertrail" do
|
||||||
|
before { sign_in(user) }
|
||||||
|
|
||||||
|
subject do
|
||||||
|
get :papertrail, format: :pdf, params: { id: dossier.id }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the dossier has been submitted' do
|
||||||
|
let(:dossier) { create(:dossier, :en_construction, user: user) }
|
||||||
|
|
||||||
|
it 'renders a PDF document' do
|
||||||
|
subject
|
||||||
|
expect(response).to render_template(:papertrail)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the dossier is still a draft' do
|
||||||
|
let(:dossier) { create(:dossier, :brouillon, user: user) }
|
||||||
|
|
||||||
|
it 'raises an error' do
|
||||||
|
expect { subject }.to raise_error(ActionController::BadRequest)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe '#delete_dossier' do
|
describe '#delete_dossier' do
|
||||||
before { sign_in(user) }
|
before { sign_in(user) }
|
||||||
|
|
||||||
|
|
25
spec/views/users/dossiers/papertrail.pdf.prawl_spec.rb
Normal file
25
spec/views/users/dossiers/papertrail.pdf.prawl_spec.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
describe 'users/dossiers/papertrail.pdf.prawn', type: :view do
|
||||||
|
before do
|
||||||
|
assign(:dossier, dossier)
|
||||||
|
end
|
||||||
|
|
||||||
|
subject { render }
|
||||||
|
|
||||||
|
context 'for a dossier with an individual' do
|
||||||
|
let(:dossier) { create(:dossier, :en_construction, :with_service, :with_individual) }
|
||||||
|
|
||||||
|
it 'renders a PDF document with the dossier state' do
|
||||||
|
subject
|
||||||
|
expect(rendered).to be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'for a dossier with a SIRET' do
|
||||||
|
let(:dossier) { create(:dossier, :en_construction, :with_service, :with_entreprise) }
|
||||||
|
|
||||||
|
it 'renders a PDF document with the dossier state' do
|
||||||
|
subject
|
||||||
|
expect(rendered).to be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue