add dynamic documents

This commit is contained in:
Pete Matsyburka
2026-02-12 09:22:08 +02:00
parent b50d982497
commit 37196ff89f
65 changed files with 4372 additions and 485 deletions
@@ -47,6 +47,7 @@ module Params
email_format(params, :bcc_completed, message: 'bcc_completed email is invalid')
email_format(params, :reply_to, message: 'reply_to email is invalid')
type(params, :message, Hash)
type(params, :variables, Hash)
type(params, :submitters, Array)
in_path(params, :message, skip_blank: true) do |message_params|
+1 -1
View File
@@ -37,7 +37,7 @@ Puma::Plugin.create do
wait_for_redis!
configs = Sidekiq.configure_embed do |config|
config.logger.level = Logger::INFO
config.logger.level = Rails.env.development? ? Logger::DEBUG : Logger::INFO
sidekiq_config = YAML.load_file('config/sidekiq.yml')
sidekiq_config['queues'] << 'fields' if ENV['DEMO'] == 'true'
config.queues = sidekiq_config['queues']
+5 -5
View File
@@ -80,10 +80,8 @@ module Submissions
def preload_with_pages(submission)
ActiveRecord::Associations::Preloader.new(
records: [submission],
associations: [
submission.template_id? ? { template_schema_documents: :blob } : { documents_attachments: :blob }
]
records: submission.schema_documents,
associations: [:blob]
).call
total_pages =
@@ -92,7 +90,7 @@ module Submissions
if total_pages < PRELOAD_ALL_PAGES_AMOUNT
ActiveRecord::Associations::Preloader.new(
records: submission.schema_documents,
associations: [:blob, { preview_images_attachments: :blob }]
associations: [{ preview_images_attachments: :blob }]
).call
end
@@ -117,6 +115,8 @@ module Submissions
preferences:,
sent_at: mark_as_sent ? Time.current : nil)
Submissions::CreateFromSubmitters.maybe_set_dynamic_documents(submission)
submission.save!
if submission.expire_at?
+41 -1
View File
@@ -71,6 +71,7 @@ module Submissions
preferences: preferences.merge(submission_preferences))
end
maybe_set_dynamic_documents(submission)
maybe_set_template_fields(submission, attrs[:submitters], with_template:, new_fields:)
if submission.submitters.size > template.submitters.size
@@ -97,6 +98,44 @@ module Submissions
submissions
end
def maybe_set_dynamic_documents(submission)
return submission unless submission.template_id?
template = submission.template
return submission if template.variables_schema.present? ||
submission.variables_schema.present?
areas_index = {}
submission.template_schema = []
template.schema.each do |item|
if item['dynamic']
dynamic_document = template.schema_dynamic_documents.find { |e| e.uuid == item['attachment_uuid'] }
dynamic_document_version = DynamicDocuments::EnsureVersionGenerated.call(dynamic_document)
dynamic_document_version.areas.each { |area| areas_index[area['uuid']] = area }
submission.template_schema << item.deep_dup.merge('dynamic_document_sha1' => dynamic_document.sha1)
else
submission.template_schema << item.deep_dup
end
end
submission.template_fields = template.fields.deep_dup
submission.template_fields.each do |field|
field['areas'].to_a.each do |area|
dynamic_area = areas_index[area['uuid']]
area.merge!(dynamic_area) if dynamic_area
end
end
submission
end
def maybe_enqueue_expire_at(submissions)
submissions.each do |submission|
next unless submission.expire_at?
@@ -159,7 +198,8 @@ module Submissions
end
if template_fields != (submission.template_fields || submission.template.fields) || new_fields.present? ||
submitters_attrs.any? { |e| e[:completed].present? } || !with_template || submission.variables.present?
submitters_attrs.any? { |e| e[:completed].present? } || !with_template || submission.variables.present? ||
submission.template&.variables_schema.present?
submission.template_fields = new_fields ? new_fields + template_fields : template_fields
submission.template_schema = submission.template.schema if submission.template_schema.blank?
submission.variables_schema = submission.template.variables_schema if submission.template &&
+1
View File
@@ -10,6 +10,7 @@ module Templates
template.external_id = external_id
template.shared_link = original_template.shared_link
template.variables_schema = original_template.variables_schema
template.author = author
template.name = name.presence || "#{original_template.name} (#{I18n.t('clone')})"
+28 -4
View File
@@ -36,11 +36,9 @@ module Templates
next unless new_attachment_uuid
new_document =
template.documents_attachments.new(
uuid: new_attachment_uuid,
blob_id: document.blob_id
)
template.documents_attachments.new(uuid: new_attachment_uuid, blob_id: document.blob_id)
maybe_clone_dynamic_document(template, original_template, new_document, document)
clone_document_preview_images_attachments(document:, new_document:)
new_document
@@ -51,6 +49,32 @@ module Templates
attachments
end
def maybe_clone_dynamic_document(template, original_template, document, original_document)
schema_item = original_template.schema.find { |e| e['attachment_uuid'] == original_document.uuid }
return unless schema_item
return unless schema_item['dynamic']
dynamic_document = original_template.dynamic_documents.find { |e| e.uuid == original_document.uuid }
return unless dynamic_document
new_dynamic_document = template.dynamic_documents.new(
uuid: document.uuid,
body: dynamic_document.body,
head: dynamic_document.head
)
dynamic_document.attachments_attachments.each do |attachment|
new_dynamic_document.attachments_attachments.new(
uuid: attachment.uuid,
blob_id: attachment.blob_id
)
end
new_dynamic_document
end
def clone_document_preview_images_attachments(document:, new_document:)
document.preview_images_attachments.each do |preview_image|
new_document.preview_images_attachments.new(blob_id: preview_image.blob_id)
+14 -6
View File
@@ -24,10 +24,18 @@ module Templates
module_function
def call(template, params, extract_fields: false)
extract_zip_files(params[:files].presence || params[:file]).flat_map do |file|
handle_file_types(template, file, params, extract_fields:)
def call(template, params, extract_fields: false, dynamic: false)
documents = []
dynamic_documents = []
extract_zip_files(params[:files].presence || params[:file]).each do |file|
docs, dynamic_docs = handle_file_types(template, file, params, extract_fields:, dynamic:)
documents.push(*docs)
dynamic_documents.push(*dynamic_docs)
end
[documents, dynamic_documents]
end
def handle_pdf_or_image(template, file, document_data = nil, params = {}, extract_fields: false)
@@ -108,12 +116,12 @@ module Templates
extracted_files
end
def handle_file_types(template, file, params, extract_fields:)
def handle_file_types(template, file, params, extract_fields:, dynamic: false)
if file.content_type.include?('image') || file.content_type == PDF_CONTENT_TYPE
return handle_pdf_or_image(template, file, file.read, params, extract_fields:)
return [handle_pdf_or_image(template, file, file.read, params, extract_fields:), []]
end
raise InvalidFileType, file.content_type
raise InvalidFileType, "#{file.content_type}/#{dynamic}"
end
end
end
+1 -1
View File
@@ -6,7 +6,7 @@ module Templates
# rubocop:disable Metrics
def call(template, params = {}, extract_fields: false)
documents = Templates::CreateAttachments.call(template, params, extract_fields:)
documents, = Templates::CreateAttachments.call(template, params, extract_fields:)
submitter = template.submitters.first
documents.each_with_index do |document, index|