add export template model

This commit is contained in:
Christophe Robillard 2024-03-02 22:13:09 +01:00 committed by simon lehericey
parent 474eb18016
commit d1c3b84ea2
No known key found for this signature in database
GPG key ID: CDE670D827C7B3C5
6 changed files with 238 additions and 0 deletions

View file

@ -0,0 +1,125 @@
class ExportTemplate < ApplicationRecord
include TagsSubstitutionConcern
belongs_to :groupe_instructeur
has_one :procedure, through: :groupe_instructeur
DOSSIER_STATE = Dossier.states.fetch(:en_construction)
def tiptap_default_dossier_directory=(body)
self.content["default_dossier_directory"] = JSON.parse(body)
end
def tiptap_default_dossier_directory
tiptap_content("default_dossier_directory")
end
def tiptap_pdf_name=(body)
self.content["pdf_name"] = JSON.parse(body)
end
def tiptap_pdf_name
tiptap_content("pdf_name")
end
def attachment_and_path(dossier, attachment, index: 0, row_index: nil)
[
attachment,
path(dossier, attachment, index, row_index)
]
end
def tiptap_convert(dossier, param)
if content[param]["content"]&.first&.[]("content")
render_attributes_for(content[param], dossier)
end
end
def tiptap_convert_pj(dossier, pj_stable_id)
if content_for_pj_id(pj_stable_id)["content"]&.first["content"]
render_attributes_for(content_for_pj_id(pj_stable_id), dossier)
end
end
def render_attributes_for(content_for, dossier)
tiptap = TiptapService.new
used_tags = tiptap.used_tags_and_libelle_for(content_for.deep_symbolize_keys)
substitutions = tags_substitutions(used_tags, dossier, escape: false)
tiptap.to_path(content_for.deep_symbolize_keys, substitutions)
end
def folder(dossier)
render_attributes_for(content["default_dossier_directory"], dossier)
end
def export_path(dossier)
File.join(folder(dossier), export_filename(dossier))
end
def export_filename(dossier)
"#{render_attributes_for(content["pdf_name"], dossier)}.pdf"
end
private
def tiptap_content(key)
content[key]&.to_json
end
def tiptap_json(prefix)
{
"type" => "doc",
"content" => [
{ "type" => "paragraph", "content" => [{ "text" => prefix, "type" => "text" }, { "type" => "mention", "attrs" => DOSSIER_ID_TAG.stringify_keys }] }
]
}
end
def content_for_pj_id(stable_id)
content_for_stable_id = content["pjs"].find { _1.symbolize_keys[:stable_id] == stable_id.to_s }
content_for_stable_id.symbolize_keys.fetch(:path)
end
def path(dossier, attachment, index, row_index)
if attachment.name == 'pdf_export_for_instructeur'
return export_path(dossier)
end
dir_path = case attachment.record_type
when 'Dossier'
'dossier'
when 'Commentaire'
'messagerie'
when 'Avis'
'avis'
else
# for attachment
return attachment_path(dossier, attachment, index, row_index)
end
File.join(folder(dossier), dir_path, attachment.filename.to_s)
end
def attachment_path(dossier, attachment, index, row_index)
type_de_champ_id = dossier.champs.find(attachment.record_id).type_de_champ_id
stable_id = TypeDeChamp.find(type_de_champ_id).stable_id
tiptap_pj = content["pjs"].find { |pj| pj["stable_id"] == stable_id.to_s }
if tiptap_pj
File.join(folder(dossier), tiptap_convert_pj(dossier, stable_id) + suffix(attachment, index, row_index))
else
File.join(folder(dossier), "erreur_renommage", attachment.filename.to_s)
end
end
def suffix(attachment, index, row_index)
suffix = ""
if index >= 1 && !row_index.nil?
suffix += "-#{index + 1}"
suffix += "-#{row_index + 1}" if row_index
end
suffix + attachment.filename.extension_with_delimiter
end
end

View file

@ -9,6 +9,7 @@ class GroupeInstructeur < ApplicationRecord
has_many :batch_operations, through: :dossiers, source: :batch_operations has_many :batch_operations, through: :dossiers, source: :batch_operations
has_many :assignments, class_name: 'DossierAssignment', dependent: :nullify, inverse_of: :groupe_instructeur has_many :assignments, class_name: 'DossierAssignment', dependent: :nullify, inverse_of: :groupe_instructeur
has_many :previous_assignments, class_name: 'DossierAssignment', dependent: :nullify, inverse_of: :previous_groupe_instructeur has_many :previous_assignments, class_name: 'DossierAssignment', dependent: :nullify, inverse_of: :previous_groupe_instructeur
has_many :export_templates
has_and_belongs_to_many :exports, dependent: :destroy has_and_belongs_to_many :exports, dependent: :destroy
has_one :defaut_procedure, -> { with_discarded }, class_name: 'Procedure', foreign_key: :defaut_groupe_instructeur_id, dependent: :nullify, inverse_of: :defaut_groupe_instructeur has_one :defaut_procedure, -> { with_discarded }, class_name: 'Procedure', foreign_key: :defaut_groupe_instructeur_id, dependent: :nullify, inverse_of: :defaut_groupe_instructeur

View file

@ -14,6 +14,7 @@ class Instructeur < ApplicationRecord
has_many :batch_operations, dependent: :nullify has_many :batch_operations, dependent: :nullify
has_many :assign_to_with_email_notifications, -> { with_email_notifications }, class_name: 'AssignTo', inverse_of: :instructeur has_many :assign_to_with_email_notifications, -> { with_email_notifications }, class_name: 'AssignTo', inverse_of: :instructeur
has_many :groupe_instructeur_with_email_notifications, through: :assign_to_with_email_notifications, source: :groupe_instructeur has_many :groupe_instructeur_with_email_notifications, through: :assign_to_with_email_notifications, source: :groupe_instructeur
has_many :export_templates, through: :groupe_instructeurs
has_many :commentaires, inverse_of: :instructeur, dependent: :nullify has_many :commentaires, inverse_of: :instructeur, dependent: :nullify
has_many :dossiers, -> { state_not_brouillon }, through: :unordered_groupe_instructeurs has_many :dossiers, -> { state_not_brouillon }, through: :unordered_groupe_instructeurs

View file

@ -153,6 +153,7 @@ class Procedure < ApplicationRecord
has_many :administrateurs, through: :administrateurs_procedures, after_remove: -> (procedure, _admin) { procedure.validate! } has_many :administrateurs, through: :administrateurs_procedures, after_remove: -> (procedure, _admin) { procedure.validate! }
has_many :groupe_instructeurs, -> { order(:label) }, inverse_of: :procedure, dependent: :destroy has_many :groupe_instructeurs, -> { order(:label) }, inverse_of: :procedure, dependent: :destroy
has_many :instructeurs, through: :groupe_instructeurs has_many :instructeurs, through: :groupe_instructeurs
has_many :export_templates, through: :groupe_instructeurs
has_many :active_groupe_instructeurs, -> { active }, class_name: 'GroupeInstructeur', inverse_of: false has_many :active_groupe_instructeurs, -> { active }, class_name: 'GroupeInstructeur', inverse_of: false
has_many :closed_groupe_instructeurs, -> { closed }, class_name: 'GroupeInstructeur', inverse_of: false has_many :closed_groupe_instructeurs, -> { closed }, class_name: 'GroupeInstructeur', inverse_of: false

View file

@ -0,0 +1,34 @@
FactoryBot.define do
factory :export_template do
name { "Mon export" }
groupe_instructeur
content {
{
"pdf_name" =>
{
"type" => "doc",
"content" => [
{ "type" => "paragraph", "content" => [{ "text" => "export_", "type" => "text" }, { "type" => "mention", "attrs" => { "id" => "dossier_id", "label" => "id dossier" } }, { "text" => " .pdf", "type" => "text" }] }
]
},
"default_dossier_directory" =>
{
"type" => "doc",
"content" =>
[
{
"type" => "paragraph",
"content" =>
[
{ "text" => "dossier_", "type" => "text" },
{ "type" => "mention", "attrs" => { "id" => "dossier_number", "label" => "numéro du dossier" } },
{ "text" => " ", "type" => "text" }
]
}
]
}
}
}
kind { "zip" }
end
end

View file

@ -0,0 +1,76 @@
describe ExportTemplate do
let(:groupe_instructeur) { create(:groupe_instructeur, procedure:) }
let(:export_template) { build(:export_template, groupe_instructeur:, content:) }
let(:procedure) { create(:procedure_with_dossiers) }
let(:content) do
{
"pdf_name" => {
"type" => "doc",
"content" => [
{ "type" => "paragraph", "content" => [{ "text" => "mon_export_", "type" => "text" }, { "type" => "mention", "attrs" => { "id" => "dossier_number", "label" => "numéro du dossier" } }] }
]
},
"default_dossier_directory" => {
"type" => "doc",
"content" => [
{ "type" => "paragraph", "content" => [{ "text" => "DOSSIER_", "type" => "text" }, { "type" => "mention", "attrs" => { "id" => "dossier_number", "label" => "numéro du dossier" } }, { "text" => " ", "type" => "text" }] }
]
},
"pjs" =>
[
{path: {"type"=>"doc", "content"=>[{"type"=>"paragraph", "content"=>[{"type"=>"mention", "attrs"=>{"id"=>"dossier_number", "label"=>"numéro du dossier"}}, {"text"=>" _justif", "type"=>"text"}]}]}, stable_id: "3"},
{ path:
{"type"=>"doc", "content"=>[{"type"=>"paragraph", "content"=>[{"text"=>"cni_", "type"=>"text"}, {"type"=>"mention", "attrs"=>{"id"=>"dossier_number", "label"=>"numéro du dossier"}}, {"text"=>" ", "type"=>"text"}]}]},
stable_id: "5"},
{ path: {"type"=>"doc", "content"=>[{"type"=>"paragraph", "content"=>[{"text"=>"pj_repet_", "type"=>"text"}, {"type"=>"mention", "attrs"=>{"id"=>"dossier_number", "label"=>"numéro du dossier"}}, {"text"=>" ", "type"=>"text"}]}]},
stable_id: "10"}
]
}
end
describe 'new' do
let(:export_template) { build(:export_template, groupe_instructeur: groupe_instructeur) }
let(:procedure) { create(:procedure, types_de_champ_public:) }
let(:types_de_champ_public) do
[
{ type: :integer_number, stable_id: 900 },
{ type: :piece_justificative, libelle: "Justificatif de domicile", mandatory: true, stable_id: 910 }
]
end
end
describe '#tiptap_default_dossier_directory' do
it 'returns tiptap_default_dossier_directory from content' do
expect(export_template.tiptap_default_dossier_directory).to eq({
"type" => "doc",
"content" => [
{ "type" => "paragraph", "content" => [{ "text" => "DOSSIER_", "type" => "text" }, { "type" => "mention", "attrs" => { "id" => "dossier_number", "label" => "numéro du dossier" } }, { "text" => " ", "type" => "text" }] }
]
}.to_json)
end
end
describe '#tiptap_pdf_name' do
it 'returns tiptap_pdf_name from content' do
expect(export_template.tiptap_pdf_name).to eq({
"type" => "doc",
"content" => [
{ "type" => "paragraph", "content" => [{ "text" => "mon_export_", "type" => "text" }, { "type" => "mention", "attrs" => { "id" => "dossier_number", "label" => "numéro du dossier" } }] }
]
}.to_json)
end
end
describe '#attachment_and_path' do
let(:dossier) { create(:dossier) }
context 'for export pdf' do
let(:attachment) { double("attachment") }
it 'gives absolute filename for export of specific dossier' do
allow(attachment).to receive(:name).and_return('pdf_export_for_instructeur')
expect(export_template.attachment_and_path(dossier, attachment)).to eq([attachment, "DOSSIER_#{dossier.id}/mon_export_#{dossier.id}.pdf"])
end
end
end
end