add export template model
This commit is contained in:
parent
474eb18016
commit
d1c3b84ea2
6 changed files with 238 additions and 0 deletions
125
app/models/export_template.rb
Normal file
125
app/models/export_template.rb
Normal 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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
34
spec/factories/export_template.rb
Normal file
34
spec/factories/export_template.rb
Normal 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
|
76
spec/models/export_template_spec.rb
Normal file
76
spec/models/export_template_spec.rb
Normal 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
|
Loading…
Reference in a new issue