Merge pull request #7137 from betagouv/faster_pdf

refactor(pdf)!: accélère la génération des pdf (*2 à *4)
This commit is contained in:
LeSim 2022-04-12 12:01:17 +02:00 committed by GitHub
commit 9da44bd913
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 60 additions and 37 deletions

View file

@ -59,7 +59,6 @@ gem 'openid_connect'
gem 'pg' gem 'pg'
gem 'phonelib' gem 'phonelib'
gem 'prawn-rails' # PDF Generation gem 'prawn-rails' # PDF Generation
gem 'prawn-svg'
gem 'premailer-rails' gem 'premailer-rails'
gem 'puma' # Use Puma as the app server gem 'puma' # Use Puma as the app server
gem 'pundit' gem 'pundit'

View file

@ -459,9 +459,6 @@ GEM
prawn prawn
prawn-table prawn-table
rails (>= 3.1.0) rails (>= 3.1.0)
prawn-svg (0.31.0)
css_parser (~> 1.6)
prawn (>= 0.11.1, < 3)
prawn-table (0.2.2) prawn-table (0.2.2)
prawn (>= 1.3.0, < 3.0.0) prawn (>= 1.3.0, < 3.0.0)
premailer (1.14.2) premailer (1.14.2)
@ -840,7 +837,6 @@ DEPENDENCIES
pg pg
phonelib phonelib
prawn-rails prawn-rails
prawn-svg
premailer-rails premailer-rails
pry-byebug pry-byebug
puma puma

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -1,7 +1,6 @@
class ActiveStorage::DownloadableFile class ActiveStorage::DownloadableFile
def self.create_list_from_dossiers(dossiers, for_expert = false) def self.create_list_from_dossiers(dossiers, for_expert = false)
dossiers PiecesJustificativesService.generate_dossier_export(dossiers) +
.map { |d| pj_and_path(d.id, PiecesJustificativesService.generate_dossier_export(d)) } +
PiecesJustificativesService.liste_documents(dossiers, for_expert) PiecesJustificativesService.liste_documents(dossiers, for_expert)
end end

View file

@ -485,9 +485,10 @@ class Dossier < ApplicationRecord
end end
def motivation def motivation
return nil if !termine? if termine?
traitement&.motivation || read_attribute(:motivation) traitement&.motivation || read_attribute(:motivation)
end end
end
def update_search_terms def update_search_terms
self.search_terms = [ self.search_terms = [

View file

@ -107,21 +107,44 @@ class PiecesJustificativesService
end end
end end
def self.generate_dossier_export(dossier) def self.generate_dossier_export(dossiers)
return [] if dossiers.empty?
pdfs = []
procedure = dossiers.first.procedure
tdc_by_id = TypeDeChamp
.joins(:revisions)
.where(revisions: { id: procedure.revisions })
.to_a
.group_by(&:id)
dossiers
.includes(:champs, :champs_private, :commentaires, :individual,
:traitement, :etablissement,
user: :france_connect_information, avis: :expert)
.find_each do |dossier|
pdf = ApplicationController pdf = ApplicationController
.render(template: 'dossiers/show', formats: [:pdf], .render(template: 'dossiers/show', formats: [:pdf],
assigns: { assigns: {
include_infos_administration: true, include_infos_administration: true,
dossier: dossier dossier: dossier,
procedure: procedure,
tdc_by_id: tdc_by_id
}) })
FakeAttachment.new( a = FakeAttachment.new(
file: StringIO.new(pdf), file: StringIO.new(pdf),
filename: "export-#{dossier.id}.pdf", filename: "export-#{dossier.id}.pdf",
name: 'pdf_export_for_instructeur', name: 'pdf_export_for_instructeur',
id: dossier.id, id: dossier.id,
created_at: dossier.updated_at created_at: dossier.updated_at
) )
pdfs << ActiveStorage::DownloadableFile.pj_and_path(dossier.id, a)
end
pdfs
end end
private private

View file

@ -181,7 +181,7 @@ prawn_document(page_size: "A4") do |pdf|
italic: Rails.root.join('lib/prawn/fonts/marianne/marianne-thin.ttf' ), italic: Rails.root.join('lib/prawn/fonts/marianne/marianne-thin.ttf' ),
}) })
pdf.font 'marianne' pdf.font 'marianne'
pdf.svg IO.read(DOSSIER_PDF_EXPORT_LOGO_SRC), width: 300, position: :center pdf.image DOSSIER_PDF_EXPORT_LOGO_SRC, width: 300, position: :center
pdf.move_down(40) pdf.move_down(40)
render_in_2_columns(pdf, 'Démarche', @dossier.procedure.libelle) render_in_2_columns(pdf, 'Démarche', @dossier.procedure.libelle)

View file

@ -130,28 +130,30 @@ def add_identite_etablissement(pdf, etablissement)
end end
def add_single_champ(pdf, champ) def add_single_champ(pdf, champ)
tdc = @tdc_by_id[champ.type_de_champ_id].first
case champ.type case champ.type
when 'Champs::PieceJustificativeChamp', 'Champs::TitreIdentiteChamp' when 'Champs::PieceJustificativeChamp', 'Champs::TitreIdentiteChamp'
return return
when 'Champs::HeaderSectionChamp' when 'Champs::HeaderSectionChamp'
add_section_title(pdf, champ.libelle) add_section_title(pdf, tdc.libelle)
when 'Champs::ExplicationChamp' when 'Champs::ExplicationChamp'
format_in_2_lines(pdf, champ.libelle, champ.description) format_in_2_lines(pdf, tdc.libelle, tdc.description)
when 'Champs::CarteChamp' when 'Champs::CarteChamp'
format_in_2_lines(pdf, champ.libelle, champ.to_feature_collection.to_json) format_in_2_lines(pdf, tdc.libelle, champ.to_feature_collection.to_json)
when 'Champs::SiretChamp' when 'Champs::SiretChamp'
pdf.font 'marianne', style: :bold do pdf.font 'marianne', style: :bold do
pdf.text champ.libelle pdf.text tdc.libelle
end end
if champ.etablissement.present? if champ.etablissement.present?
add_identite_etablissement(pdf, champ.etablissement) add_identite_etablissement(pdf, champ.etablissement)
end end
when 'Champs::NumberChamp' when 'Champs::NumberChamp'
value = champ.to_s.empty? ? 'Non communiqué' : number_with_delimiter(champ.to_s) value = champ.to_s.empty? ? 'Non communiqué' : number_with_delimiter(champ.to_s)
format_in_2_lines(pdf, champ.libelle, value) format_in_2_lines(pdf, tdc.libelle, value)
else else
value = champ.to_s.empty? ? 'Non communiqué' : champ.to_s value = champ.to_s.empty? ? 'Non communiqué' : champ.to_s
format_in_2_lines(pdf, champ.libelle, value) format_in_2_lines(pdf, tdc.libelle, value)
end end
end end
@ -205,6 +207,9 @@ def add_etats_dossier(pdf, dossier)
end end
prawn_document(page_size: "A4") do |pdf| prawn_document(page_size: "A4") do |pdf|
@procedure ||= @dossier.procedure
@tdc_by_id ||= @dossier.champs.map(&:type_de_champ).group_by(&:id)
pdf.font_families.update( 'marianne' => { pdf.font_families.update( 'marianne' => {
normal: Rails.root.join('lib/prawn/fonts/marianne/marianne-regular.ttf' ), normal: Rails.root.join('lib/prawn/fonts/marianne/marianne-regular.ttf' ),
bold: Rails.root.join('lib/prawn/fonts/marianne/marianne-bold.ttf' ), bold: Rails.root.join('lib/prawn/fonts/marianne/marianne-bold.ttf' ),
@ -212,12 +217,12 @@ prawn_document(page_size: "A4") do |pdf|
pdf.font 'marianne' pdf.font 'marianne'
pdf.pad_bottom(40) do pdf.pad_bottom(40) do
pdf.svg IO.read(DOSSIER_PDF_EXPORT_LOGO_SRC), width: 300, position: :center pdf.image DOSSIER_PDF_EXPORT_LOGO_SRC, width: 300, position: :center
end end
format_in_2_columns(pdf, 'Dossier Nº', @dossier.id.to_s) format_in_2_columns(pdf, 'Dossier Nº', @dossier.id.to_s)
format_in_2_columns(pdf, 'Démarche', @dossier.procedure.libelle) format_in_2_columns(pdf, 'Démarche', @procedure.libelle)
format_in_2_columns(pdf, 'Organisme', @dossier.procedure.organisation_name) format_in_2_columns(pdf, 'Organisme', @procedure.organisation_name)
add_etat_dossier(pdf, @dossier) add_etat_dossier(pdf, @dossier)

View file

@ -69,7 +69,7 @@ DS_ENV="staging"
# PROCEDURE_DEFAULT_LOGO_SRC="republique-francaise-logo.svg" # PROCEDURE_DEFAULT_LOGO_SRC="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.png"
# Instance customization: watermark for identity documents # Instance customization: watermark for identity documents
# WATERMARK_FILE="" # WATERMARK_FILE=""

View file

@ -17,4 +17,4 @@ MAILER_FOOTER_LOGO_SRC = ENV.fetch("MAILER_FOOTER_LOGO_SRC", "mailer/instructeur
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")
# 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.png")

View file

@ -160,7 +160,7 @@ describe PiecesJustificativesService do
describe '.generate_dossier_export' do describe '.generate_dossier_export' do
let(:dossier) { create(:dossier) } let(:dossier) { create(:dossier) }
subject { PiecesJustificativesService.generate_dossier_export(dossier) } subject { PiecesJustificativesService.generate_dossier_export(Dossier.where(id: dossier.id)) }
it "doesn't update dossier" do it "doesn't update dossier" do
expect { subject }.not_to change { dossier.updated_at } expect { subject }.not_to change { dossier.updated_at }