2024-04-29 00:17:15 +02:00
# frozen_string_literal: true
2017-06-08 14:16:48 +02:00
class AttestationTemplate < ApplicationRecord
include ActionView :: Helpers :: NumberHelper
2018-01-02 15:33:11 +01:00
include TagsSubstitutionConcern
2017-06-08 14:16:48 +02:00
2024-05-29 11:31:49 +02:00
belongs_to :procedure , inverse_of : :attestation_template
2017-06-08 14:16:48 +02:00
2019-08-28 13:11:58 +02:00
has_one_attached :logo
has_one_attached :signature
2024-05-29 11:31:31 +02:00
enum state : {
draft : 'draft' ,
published : 'published'
}
2019-08-27 17:42:52 +02:00
2024-01-10 13:37:55 +01:00
validates :title , tags : true , if : - > { procedure . present? && version == 1 }
validates :body , tags : true , if : - > { procedure . present? && version == 1 }
validates :json_body , tags : true , if : - > { procedure . present? && version == 2 }
2017-06-27 13:07:06 +02:00
validates :footer , length : { maximum : 190 }
2021-09-14 18:03:40 +02:00
FILE_MAX_SIZE = 1 . megabytes
2021-11-24 10:04:20 +01:00
validates :logo , content_type : [ 'image/png' , 'image/jpg' , 'image/jpeg' ] , size : { less_than : FILE_MAX_SIZE }
validates :signature , content_type : [ 'image/png' , 'image/jpg' , 'image/jpeg' ] , size : { less_than : FILE_MAX_SIZE }
2020-02-24 11:17:52 +01:00
2018-08-28 14:10:55 +02:00
DOSSIER_STATE = Dossier . states . fetch ( :accepte )
2017-06-08 14:16:48 +02:00
2024-01-10 13:37:55 +01:00
scope :v1 , - > { where ( version : 1 ) }
scope :v2 , - > { where ( version : 2 ) }
2024-01-29 16:38:14 +01:00
TIPTAP_BODY_DEFAULT = {
" type " = > " doc " ,
" content " = > [
{
" type " = > " header " ,
" content " = > [
{
" type " = > " headerColumn " ,
" content " = > [
{
" type " = > " paragraph " ,
" attrs " = > { " textAlign " = > " left " } ,
" content " = > [ { " type " = > " mention " , " attrs " = > { " id " = > " dossier_service_name " , " label " = > " nom du service " } } ]
}
]
} ,
{
" type " = > " headerColumn " ,
" content " = > [
{
" type " = > " paragraph " ,
" attrs " = > { " textAlign " = > " left " } ,
" content " = > [
{ " text " = > " Fait le " , " type " = > " text " } ,
{ " type " = > " mention " , " attrs " = > { " id " = > " dossier_processed_at " , " label " = > " date de décision " } }
]
}
]
}
]
} ,
{ " type " = > " title " , " attrs " = > { " textAlign " = > " center " } , " content " = > [ { " text " = > " Titre de l’ attestation " , " type " = > " text " } ] } ,
{
" type " = > " paragraph " ,
" attrs " = > { " textAlign " = > " left " } ,
" content " = > [
{
" text " = > " Vous pouvez éditer ce texte pour personnaliser votre attestation. Pour ajouter du contenu issu du dossier, utilisez les balises situées sous cette zone de saisie. " ,
" type " = > " text "
}
]
}
]
} . freeze
2017-06-08 14:04:47 +02:00
def attestation_for ( dossier )
2024-05-29 23:00:34 +02:00
attestation = Attestation . new
attestation . title = replace_tags ( title , dossier , escape : false ) if version == 1
2019-08-28 13:11:58 +02:00
attestation . pdf . attach (
2024-05-29 23:00:34 +02:00
io : StringIO . new ( build_pdf ( dossier ) ) ,
2019-08-27 17:42:52 +02:00
filename : " attestation-dossier- #{ dossier . id } .pdf " ,
content_type : 'application/pdf' ,
# we don't want to run virus scanner on this file
metadata : { virus_scan_result : ActiveStorage :: VirusScanner :: SAFE }
)
attestation
2017-06-08 14:04:47 +02:00
end
2018-04-06 13:09:37 +02:00
def unspecified_champs_for_dossier ( dossier )
2024-09-20 14:54:26 +02:00
types_de_champ_by_tag_id = dossier . revision . types_de_champ . index_by { " tdc #{ _1 . stable_id } " }
2018-04-06 13:09:37 +02:00
2021-06-10 15:24:15 +02:00
used_tags . filter_map do | used_tag |
2024-09-20 14:54:26 +02:00
corresponding_type_de_champ = types_de_champ_by_tag_id [ used_tag ]
2018-04-06 13:09:37 +02:00
2024-09-20 14:54:26 +02:00
if corresponding_type_de_champ && dossier . project_champ ( corresponding_type_de_champ , nil ) . blank?
corresponding_type_de_champ
2018-04-06 19:22:42 +02:00
end
2021-06-10 15:24:15 +02:00
end
2018-04-06 13:09:37 +02:00
end
2017-06-08 14:16:48 +02:00
def dup
2024-05-28 16:22:47 +02:00
attestation_template = super
2024-02-07 17:29:47 +01:00
ClonePiecesJustificativesService . clone_attachments ( self , attestation_template )
2019-08-27 17:42:52 +02:00
attestation_template
end
def logo_url
2019-08-28 13:11:58 +02:00
if logo . attached?
2024-07-03 18:07:33 +02:00
logo_variant = logo . variant ( resize_to_limit : [ 400 , 400 ] )
logo_variant . key . present? ? logo_variant . processed . url : Rails . application . routes . url_helpers . url_for ( logo )
2019-08-27 17:42:52 +02:00
end
end
2017-06-08 14:16:48 +02:00
2019-08-27 17:42:52 +02:00
def signature_url
2019-08-28 13:11:58 +02:00
if signature . attached?
Rails . application . routes . url_helpers . url_for ( signature )
2017-06-08 14:16:48 +02:00
end
2019-08-27 17:42:52 +02:00
end
2017-06-08 14:16:48 +02:00
2019-08-28 14:27:41 +02:00
def render_attributes_for ( params = { } )
2024-01-18 12:38:46 +01:00
groupe_instructeur = params [ :groupe_instructeur ]
groupe_instructeur || = params [ :dossier ] & . groupe_instructeur
base_attributes = {
created_at : Time . current ,
2019-08-28 14:27:41 +02:00
footer : params . fetch ( :footer , footer ) ,
2024-01-18 12:38:46 +01:00
signature : signature_to_render ( groupe_instructeur )
2019-08-28 14:27:41 +02:00
}
2023-09-29 15:27:42 +02:00
2024-01-18 12:38:46 +01:00
if version == 2
render_attributes_for_v2 ( params , base_attributes )
2023-09-29 15:27:42 +02:00
else
2024-01-18 12:38:46 +01:00
render_attributes_for_v1 ( params , base_attributes )
2023-09-29 15:27:42 +02:00
end
2019-08-28 16:33:51 +02:00
end
2022-02-10 19:42:39 +01:00
def logo_checksum
logo . attached? ? logo . checksum : nil
end
def signature_checksum
signature . attached? ? signature . checksum : nil
end
def logo_filename
logo . attached? ? logo . filename : nil
end
def signature_filename
signature . attached? ? signature . filename : nil
end
2023-11-28 11:44:32 +01:00
def tiptap_body
json_body & . to_json
end
def tiptap_body = ( json )
self . json_body = JSON . parse ( json )
end
2017-06-08 14:16:48 +02:00
private
2024-01-18 12:38:46 +01:00
def render_attributes_for_v1 ( params , base_attributes )
attributes = base_attributes . merge (
logo : params . fetch ( :logo , logo . attached? ? logo : nil )
)
dossier = params [ :dossier ]
if dossier . present?
attributes . merge (
title : replace_tags ( title , dossier , escape : false ) ,
body : replace_tags ( body , dossier , escape : false )
)
else
attributes . merge (
title : params . fetch ( :title , title ) ,
body : params . fetch ( :body , body )
)
end
end
def render_attributes_for_v2 ( params , base_attributes )
dossier = params [ :dossier ]
json = json_body & . deep_symbolize_keys
tiptap = TiptapService . new
if dossier . present?
# 2x faster this way than with `replace_tags` which would reparse text
2024-05-29 23:00:34 +02:00
used_tags = TiptapService . used_tags_and_libelle_for ( json . deep_symbolize_keys )
2024-01-18 12:38:46 +01:00
substitutions = tags_substitutions ( used_tags , dossier , escape : false )
body = tiptap . to_html ( json , substitutions )
attributes . merge (
body :
)
else
attributes . merge (
body : params . fetch ( :body ) { tiptap . to_html ( json ) }
)
end
end
2023-09-29 15:27:42 +02:00
def signature_to_render ( groupe_instructeur )
if groupe_instructeur & . signature & . attached?
2023-09-19 15:41:51 +02:00
groupe_instructeur . signature
else
signature
end
end
2018-04-06 13:09:37 +02:00
def used_tags
2024-05-29 23:00:34 +02:00
if version == 2
json = json_body & . deep_symbolize_keys
2024-06-07 13:19:04 +02:00
TiptapService . used_tags_and_libelle_for ( json . deep_symbolize_keys ) . map ( & :first )
2024-05-29 23:00:34 +02:00
else
used_tags_for ( title ) + used_tags_for ( body )
end
2018-04-06 13:09:37 +02:00
end
2017-06-08 14:04:47 +02:00
def build_pdf ( dossier )
2024-05-29 23:00:34 +02:00
if version == 2
build_v2_pdf ( dossier )
else
build_v1_pdf ( dossier )
end
end
def build_v1_pdf ( dossier )
2019-08-28 14:27:41 +02:00
attestation = render_attributes_for ( dossier : dossier )
2024-05-29 23:00:34 +02:00
ApplicationController . render (
2021-11-25 16:26:55 +01:00
template : 'administrateurs/attestation_templates/show' ,
2020-08-04 16:53:46 +02:00
formats : :pdf ,
assigns : { attestation : attestation }
)
2024-05-29 23:00:34 +02:00
end
def build_v2_pdf ( dossier )
body = render_attributes_for ( dossier : ) . fetch ( :body )
html = ApplicationController . render (
template : '/administrateurs/attestation_template_v2s/show' ,
formats : [ :html ] ,
layout : 'attestation' ,
assigns : { attestation_template : self , body : body }
)
2017-06-08 14:04:47 +02:00
2024-05-29 23:00:34 +02:00
WeasyprintService . generate_pdf ( html , { procedure_id : procedure . id , dossier_id : dossier . id } )
2017-06-08 14:04:47 +02:00
end
2017-06-08 14:16:48 +02:00
end