merge preview docs
This commit is contained in:
@@ -5,34 +5,17 @@ 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)
|
||||||
|
|
||||||
if last_submitter.documents_attachments.blank?
|
|
||||||
last_submitter.documents_attachments = Submissions::EnsureResultGenerated.call(last_submitter)
|
|
||||||
end
|
|
||||||
|
|
||||||
last_submitter.documents_attachments
|
|
||||||
else
|
else
|
||||||
values_hash = Submissions::GeneratePreviewAttachments.build_values_hash(@submission)
|
build_preview_documents(@submission, merge: is_merge)
|
||||||
|
|
||||||
if @submission.preview_documents.present? &&
|
|
||||||
@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
|
||||||
|
|
||||||
ActiveRecord::Associations::Preloader.new(
|
ActiveRecord::Associations::Preloader.new(records: documents, associations: [:blob]).call
|
||||||
records: documents,
|
|
||||||
associations: [:blob]
|
|
||||||
).call
|
|
||||||
|
|
||||||
expires_at = Accounts.link_expires_at(current_account)
|
expires_at = Accounts.link_expires_at(current_account)
|
||||||
|
|
||||||
@@ -43,5 +26,50 @@ module Api
|
|||||||
end
|
end
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def build_completed_documents(submission, merge: false)
|
||||||
|
last_submitter = submission.submitters.max_by(&:completed_at)
|
||||||
|
|
||||||
|
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
|
||||||
|
if last_submitter.documents_attachments.blank?
|
||||||
|
last_submitter.documents_attachments = Submissions::EnsureResultGenerated.call(last_submitter)
|
||||||
|
end
|
||||||
|
|
||||||
|
last_submitter.documents_attachments
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_preview_documents(submission, merge: false)
|
||||||
|
values_hash = Submissions::GeneratePreviewAttachments.build_values_hash(submission)
|
||||||
|
|
||||||
|
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 }
|
||||||
|
|
||||||
|
Submissions::GeneratePreviewAttachments.call(submission, values_hash:, merge: true)
|
||||||
|
end
|
||||||
|
elsif submission.preview_documents.present? &&
|
||||||
|
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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|
||||||
audit_trail = I18n.with_locale(submitter.account.locale) do
|
if with_audit
|
||||||
Submissions::GenerateAuditTrail.build_audit_trail(submitter.submission)
|
audit_trail = I18n.with_locale(submitter.account.locale) do
|
||||||
end
|
Submissions::GenerateAuditTrail.build_audit_trail(submitter.submission)
|
||||||
|
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,48 +42,74 @@ module Submissions
|
|||||||
|
|
||||||
template = submission.template
|
template = submission.template
|
||||||
|
|
||||||
image_pdfs = []
|
if merge
|
||||||
original_documents = submission.schema_documents.preload(:blob)
|
result = HexaPDF::Document.new
|
||||||
|
|
||||||
result_attachments =
|
(submission.template_schema || template.schema).each do |item|
|
||||||
(submission.template_schema || template.schema).filter_map do |item|
|
|
||||||
pdf = pdfs_index[item['attachment_uuid']]
|
pdf = pdfs_index[item['attachment_uuid']]
|
||||||
|
|
||||||
next if pdf.nil?
|
next unless pdf
|
||||||
|
|
||||||
if original_documents.find { |a| a.uuid == item['attachment_uuid'] }.image?
|
pdf.dispatch_message(:complete_objects)
|
||||||
pdf = GenerateResultAttachments.normalize_image_pdf(pdf)
|
|
||||||
|
|
||||||
image_pdfs << pdf
|
pdf.pages.each { |page| result.pages << result.import(page) }
|
||||||
end
|
|
||||||
|
|
||||||
build_pdf_attachment(pdf:, submission:, submitter:,
|
|
||||||
uuid: item['attachment_uuid'],
|
|
||||||
values_hash:,
|
|
||||||
name: item['name'])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return ApplicationRecord.no_touching { result_attachments.map { |e| e.tap(&:save!) } } if image_pdfs.size < 2
|
attachment = build_pdf_attachment(
|
||||||
|
pdf: result,
|
||||||
images_pdf =
|
|
||||||
image_pdfs.each_with_object(HexaPDF::Document.new) do |pdf, doc|
|
|
||||||
pdf.pages.each { |page| doc.pages << doc.import(page) }
|
|
||||||
end
|
|
||||||
|
|
||||||
images_pdf = GenerateResultAttachments.normalize_image_pdf(images_pdf)
|
|
||||||
|
|
||||||
images_pdf_attachment =
|
|
||||||
build_pdf_attachment(
|
|
||||||
pdf: images_pdf,
|
|
||||||
submission:,
|
submission:,
|
||||||
submitter:,
|
|
||||||
uuid: GenerateResultAttachments.images_pdf_uuid(original_documents.select(&:image?)),
|
|
||||||
values_hash:,
|
values_hash:,
|
||||||
name: submission.name || template.name
|
name: 'preview_merged_document',
|
||||||
|
filename: "#{submission.name || template.name}.pdf"
|
||||||
)
|
)
|
||||||
|
|
||||||
ApplicationRecord.no_touching do
|
ApplicationRecord.no_touching { attachment.save! }
|
||||||
(result_attachments + [images_pdf_attachment]).map { |e| e.tap(&:save!) }
|
|
||||||
|
[attachment]
|
||||||
|
else
|
||||||
|
image_pdfs = []
|
||||||
|
original_documents = submission.schema_documents.preload(:blob)
|
||||||
|
|
||||||
|
result_attachments =
|
||||||
|
(submission.template_schema || template.schema).filter_map do |item|
|
||||||
|
pdf = pdfs_index[item['attachment_uuid']]
|
||||||
|
|
||||||
|
next if pdf.nil?
|
||||||
|
|
||||||
|
if original_documents.find { |a| a.uuid == item['attachment_uuid'] }.image?
|
||||||
|
pdf = GenerateResultAttachments.normalize_image_pdf(pdf)
|
||||||
|
|
||||||
|
image_pdfs << pdf
|
||||||
|
end
|
||||||
|
|
||||||
|
build_pdf_attachment(pdf:, submission:, submitter:,
|
||||||
|
uuid: item['attachment_uuid'],
|
||||||
|
values_hash:,
|
||||||
|
filename: "#{item['name']}.pdf")
|
||||||
|
end
|
||||||
|
|
||||||
|
return ApplicationRecord.no_touching { result_attachments.map { |e| e.tap(&:save!) } } if image_pdfs.size < 2
|
||||||
|
|
||||||
|
images_pdf =
|
||||||
|
image_pdfs.each_with_object(HexaPDF::Document.new) do |pdf, doc|
|
||||||
|
pdf.pages.each { |page| doc.pages << doc.import(page) }
|
||||||
|
end
|
||||||
|
|
||||||
|
images_pdf = GenerateResultAttachments.normalize_image_pdf(images_pdf)
|
||||||
|
|
||||||
|
images_pdf_attachment =
|
||||||
|
build_pdf_attachment(
|
||||||
|
pdf: images_pdf,
|
||||||
|
submission:,
|
||||||
|
submitter:,
|
||||||
|
uuid: GenerateResultAttachments.images_pdf_uuid(original_documents.select(&:image?)),
|
||||||
|
values_hash:,
|
||||||
|
filename: "#{submission.name || template.name}.pdf"
|
||||||
|
)
|
||||||
|
|
||||||
|
ApplicationRecord.no_touching do
|
||||||
|
(result_attachments + [images_pdf_attachment]).map { |e| e.tap(&:save!) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user