merge preview docs

pull/572/head
Pete Matsyburka 2 months ago
parent 4523d38551
commit b88d99afe0

@ -5,43 +5,71 @@ module Api
load_and_authorize_resource :submission load_and_authorize_resource :submission
def index def index
is_merge = params[:merge] == 'true' &&
(@submission.schema_documents || @submission.template.schema_documents).size > 1
documents = documents =
if @submission.submitters.all?(&:completed_at?) if @submission.submitters.all?(&:completed_at?)
last_submitter = @submission.submitters.max_by(&:completed_at) build_completed_documents(@submission, merge: is_merge)
else
build_preview_documents(@submission, merge: is_merge)
end
if last_submitter.documents_attachments.blank? ActiveRecord::Associations::Preloader.new(records: documents, associations: [:blob]).call
last_submitter.documents_attachments = Submissions::EnsureResultGenerated.call(last_submitter)
expires_at = Accounts.link_expires_at(current_account)
render json: {
id: @submission.id,
documents: documents.map do |attachment|
{ name: attachment.filename.base, url: ActiveStorage::Blob.proxy_url(attachment.blob, expires_at:) }
end
}
end end
last_submitter.documents_attachments private
else
values_hash = Submissions::GeneratePreviewAttachments.build_values_hash(@submission)
if @submission.preview_documents.present? && def build_completed_documents(submission, merge: false)
@submission.preview_documents.all? { |s| s.metadata['values_hash'] == values_hash } last_submitter = submission.submitters.max_by(&:completed_at)
@submission.preview_documents
if merge
if submission.merged_document_attachment.blank?
submission.merged_document_attachment =
Submissions::GenerateCombinedAttachment.call(last_submitter, with_audit: false)
end
[submission.merged_document_attachment]
else else
ApplicationRecord.no_touching do if last_submitter.documents_attachments.blank?
@submission.preview_documents.each(&:destroy) last_submitter.documents_attachments = Submissions::EnsureResultGenerated.call(last_submitter)
end end
Submissions::GeneratePreviewAttachments.call(@submission, values_hash:) last_submitter.documents_attachments
end end
end end
ActiveRecord::Associations::Preloader.new( def build_preview_documents(submission, merge: false)
records: documents, values_hash = Submissions::GeneratePreviewAttachments.build_values_hash(submission)
associations: [:blob]
).call
expires_at = Accounts.link_expires_at(current_account) if merge
if submission.preview_merged_document_attachment.present? &&
submission.preview_merged_document_attachment.metadata['values_hash'] == values_hash
[submission.preview_merged_document_attachment]
else
ApplicationRecord.no_touching { submission.preview_merged_document_attachment&.destroy }
render json: { Submissions::GeneratePreviewAttachments.call(submission, values_hash:, merge: true)
id: @submission.id, end
documents: documents.map do |attachment| elsif submission.preview_documents.present? &&
{ name: attachment.filename.base, url: ActiveStorage::Blob.proxy_url(attachment.blob, expires_at:) } submission.preview_documents.all? { |s| s.metadata['values_hash'] == values_hash }
submission.preview_documents
else
ApplicationRecord.no_touching do
submission.preview_documents.each(&:destroy)
end
Submissions::GeneratePreviewAttachments.call(submission, values_hash:)
end end
}
end end
end end
end end

@ -63,6 +63,8 @@ class Submission < ApplicationRecord
has_one_attached :audit_trail has_one_attached :audit_trail
has_one_attached :combined_document has_one_attached :combined_document
has_one_attached :merged_document
has_one_attached :preview_merged_document
has_many_attached :preview_documents has_many_attached :preview_documents
has_many_attached :documents has_many_attached :documents

@ -4,8 +4,8 @@ module Submissions
module GenerateCombinedAttachment module GenerateCombinedAttachment
module_function module_function
def call(submitter) def call(submitter, with_audit: true)
pdf = build_combined_pdf(submitter) pdf = build_combined_pdf(submitter, with_audit:)
submission = submitter.submission submission = submitter.submission
account = submission.account account = submission.account
@ -39,7 +39,7 @@ module Submissions
blob: ActiveStorage::Blob.create_and_upload!( blob: ActiveStorage::Blob.create_and_upload!(
io: io.tap(&:rewind), filename: "#{submission.name || submission.template.name}.pdf" io: io.tap(&:rewind), filename: "#{submission.name || submission.template.name}.pdf"
), ),
name: 'combined_document', name: with_audit ? 'combined_document' : 'merged_document',
record: submission record: submission
) )
end end
@ -58,14 +58,16 @@ module Submissions
pdf.sign(io, write_options: { validate: false }, **sign_params) pdf.sign(io, write_options: { validate: false }, **sign_params)
end end
def build_combined_pdf(submitter) def build_combined_pdf(submitter, with_audit:)
pdfs_index = Submissions::GenerateResultAttachments.generate_pdfs(submitter) pdfs_index = Submissions::GenerateResultAttachments.generate_pdfs(submitter)
if with_audit
audit_trail = I18n.with_locale(submitter.account.locale) do audit_trail = I18n.with_locale(submitter.account.locale) do
Submissions::GenerateAuditTrail.build_audit_trail(submitter.submission) Submissions::GenerateAuditTrail.build_audit_trail(submitter.submission)
end end
audit_trail.dispatch_message(:complete_objects) audit_trail.dispatch_message(:complete_objects)
end
result = HexaPDF::Document.new result = HexaPDF::Document.new
@ -79,7 +81,7 @@ module Submissions
pdf.pages.each { |page| result.pages << result.import(page) } pdf.pages.each { |page| result.pages << result.import(page) }
end end
audit_trail.pages.each { |page| result.pages << result.import(page) } audit_trail&.pages&.each { |page| result.pages << result.import(page) }
result result
end end

@ -5,7 +5,7 @@ module Submissions
module_function module_function
# rubocop:disable Metrics # rubocop:disable Metrics
def call(submission, values_hash: nil, submitter: nil) def call(submission, values_hash: nil, submitter: nil, merge: false)
values_hash ||= if submitter values_hash ||= if submitter
build_submitter_values_hash(submitter) build_submitter_values_hash(submitter)
else else
@ -42,6 +42,31 @@ module Submissions
template = submission.template template = submission.template
if merge
result = HexaPDF::Document.new
(submission.template_schema || template.schema).each do |item|
pdf = pdfs_index[item['attachment_uuid']]
next unless pdf
pdf.dispatch_message(:complete_objects)
pdf.pages.each { |page| result.pages << result.import(page) }
end
attachment = build_pdf_attachment(
pdf: result,
submission:,
values_hash:,
name: 'preview_merged_document',
filename: "#{submission.name || template.name}.pdf"
)
ApplicationRecord.no_touching { attachment.save! }
[attachment]
else
image_pdfs = [] image_pdfs = []
original_documents = submission.schema_documents.preload(:blob) original_documents = submission.schema_documents.preload(:blob)
@ -60,7 +85,7 @@ module Submissions
build_pdf_attachment(pdf:, submission:, submitter:, build_pdf_attachment(pdf:, submission:, submitter:,
uuid: item['attachment_uuid'], uuid: item['attachment_uuid'],
values_hash:, values_hash:,
name: item['name']) filename: "#{item['name']}.pdf")
end end
return ApplicationRecord.no_touching { result_attachments.map { |e| e.tap(&:save!) } } if image_pdfs.size < 2 return ApplicationRecord.no_touching { result_attachments.map { |e| e.tap(&:save!) } } if image_pdfs.size < 2
@ -79,13 +104,14 @@ module Submissions
submitter:, submitter:,
uuid: GenerateResultAttachments.images_pdf_uuid(original_documents.select(&:image?)), uuid: GenerateResultAttachments.images_pdf_uuid(original_documents.select(&:image?)),
values_hash:, values_hash:,
name: submission.name || template.name filename: "#{submission.name || template.name}.pdf"
) )
ApplicationRecord.no_touching do ApplicationRecord.no_touching do
(result_attachments + [images_pdf_attachment]).map { |e| e.tap(&:save!) } (result_attachments + [images_pdf_attachment]).map { |e| e.tap(&:save!) }
end end
end end
end
def build_values_hash(submission) def build_values_hash(submission)
Digest::MD5.hexdigest( Digest::MD5.hexdigest(
@ -102,7 +128,8 @@ module Submissions
) )
end end
def build_pdf_attachment(pdf:, submission:, submitter:, uuid:, name:, values_hash:) def build_pdf_attachment(pdf:, submission:, filename:, values_hash:, submitter: nil, uuid: nil,
name: 'preview_documents')
io = StringIO.new io = StringIO.new
begin begin
@ -114,13 +141,13 @@ module Submissions
end end
ActiveStorage::Attachment.new( ActiveStorage::Attachment.new(
blob: ActiveStorage::Blob.create_and_upload!(io: io.tap(&:rewind), filename: "#{name}.pdf"), blob: ActiveStorage::Blob.create_and_upload!(io: io.tap(&:rewind), filename:),
io_data: io.string, io_data: io.string,
metadata: { original_uuid: uuid, metadata: { original_uuid: uuid,
values_hash:, values_hash:,
analyzed: true, analyzed: true,
sha256: Base64.urlsafe_encode64(Digest::SHA256.digest(io.string)) }, sha256: Base64.urlsafe_encode64(Digest::SHA256.digest(io.string)) }.compact,
name: 'preview_documents', name: name,
record: submitter || submission record: submitter || submission
) )
end end

Loading…
Cancel
Save