|
|
|
@ -5,6 +5,8 @@ module Submissions
|
|
|
|
FONT_SIZE = 11
|
|
|
|
FONT_SIZE = 11
|
|
|
|
FONT_NAME = 'Helvetica'
|
|
|
|
FONT_NAME = 'Helvetica'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A4_SIZE = [595, 842].freeze
|
|
|
|
|
|
|
|
|
|
|
|
module_function
|
|
|
|
module_function
|
|
|
|
|
|
|
|
|
|
|
|
# rubocop:disable Metrics
|
|
|
|
# rubocop:disable Metrics
|
|
|
|
@ -126,42 +128,101 @@ module Submissions
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
template.schema.map do |item|
|
|
|
|
image_pdfs = []
|
|
|
|
template.documents.find { |a| a.uuid == item['attachment_uuid'] }
|
|
|
|
original_documents = template.documents.preload(:blob)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
results =
|
|
|
|
|
|
|
|
template.schema.map do |item|
|
|
|
|
|
|
|
|
pdf = pdfs_index[item['attachment_uuid']]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
attachment = save_signed_pdf(pdf:, submitter:, cert:, uuid: item['attachment_uuid'], name: item['name'])
|
|
|
|
|
|
|
|
|
|
|
|
io = StringIO.new
|
|
|
|
image_pdfs << pdf if original_documents.find { |a| a.uuid == item['attachment_uuid'] }.image?
|
|
|
|
|
|
|
|
|
|
|
|
pdf = pdfs_index[item['attachment_uuid']]
|
|
|
|
attachment
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return results if image_pdfs.size < 2
|
|
|
|
|
|
|
|
|
|
|
|
pdf.sign(io, reason: "Signed by #{submitter.email}",
|
|
|
|
images_pdf =
|
|
|
|
certificate: OpenSSL::X509::Certificate.new(cert['cert']),
|
|
|
|
image_pdfs.each_with_object(HexaPDF::Document.new) do |pdf, doc|
|
|
|
|
key: OpenSSL::PKey::RSA.new(cert['key']),
|
|
|
|
pdf.pages.each { |page| doc.pages << doc.import(page) }
|
|
|
|
certificate_chain: [OpenSSL::X509::Certificate.new(cert['sub_ca']),
|
|
|
|
end
|
|
|
|
OpenSSL::X509::Certificate.new(cert['root_ca'])])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ActiveStorage::Attachment.create!(
|
|
|
|
images_pdf_result =
|
|
|
|
uuid: item['attachment_uuid'],
|
|
|
|
save_signed_pdf(
|
|
|
|
blob: ActiveStorage::Blob.create_and_upload!(
|
|
|
|
pdf: images_pdf,
|
|
|
|
io: StringIO.new(io.string), filename: "#{item['name']}.pdf"
|
|
|
|
submitter:,
|
|
|
|
),
|
|
|
|
cert:,
|
|
|
|
name: 'documents',
|
|
|
|
uuid: images_pdf_uuid(original_documents.select(&:image?)),
|
|
|
|
record: submitter
|
|
|
|
name: template.name
|
|
|
|
)
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
results + [images_pdf_result]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
# rubocop:enable Metrics
|
|
|
|
# rubocop:enable Metrics
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def save_signed_pdf(pdf:, submitter:, cert:, uuid:, name:)
|
|
|
|
|
|
|
|
io = StringIO.new
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pdf.sign(io, reason: "Signed by #{submitter.email}",
|
|
|
|
|
|
|
|
certificate: OpenSSL::X509::Certificate.new(cert['cert']),
|
|
|
|
|
|
|
|
key: OpenSSL::PKey::RSA.new(cert['key']),
|
|
|
|
|
|
|
|
certificate_chain: [OpenSSL::X509::Certificate.new(cert['sub_ca']),
|
|
|
|
|
|
|
|
OpenSSL::X509::Certificate.new(cert['root_ca'])])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ActiveStorage::Attachment.create!(
|
|
|
|
|
|
|
|
uuid:,
|
|
|
|
|
|
|
|
blob: ActiveStorage::Blob.create_and_upload!(
|
|
|
|
|
|
|
|
io: StringIO.new(io.string), filename: "#{name}.pdf"
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
name: 'documents',
|
|
|
|
|
|
|
|
record: submitter
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def images_pdf_uuid(attachments)
|
|
|
|
|
|
|
|
Digest::UUID.uuid_v5(Digest::UUID::OID_NAMESPACE, attachments.map(&:uuid).sort.join(':'))
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
def build_pdfs_index(submitter)
|
|
|
|
def build_pdfs_index(submitter)
|
|
|
|
latest_submitter = submitter.submission.submitters
|
|
|
|
latest_submitter = submitter.submission.submitters
|
|
|
|
.select { |e| e.id != submitter.id && e.completed_at? }
|
|
|
|
.select { |e| e.id != submitter.id && e.completed_at? }
|
|
|
|
.max_by(&:completed_at)
|
|
|
|
.max_by(&:completed_at)
|
|
|
|
|
|
|
|
|
|
|
|
documents = latest_submitter&.documents.to_a.presence
|
|
|
|
documents = latest_submitter&.documents&.preload(:blob).to_a.presence
|
|
|
|
documents ||= submitter.submission.template.documents
|
|
|
|
documents ||= submitter.submission.template.documents.preload(:blob)
|
|
|
|
|
|
|
|
|
|
|
|
documents.to_h do |attachment|
|
|
|
|
documents.to_h do |attachment|
|
|
|
|
[attachment.uuid, HexaPDF::Document.new(io: StringIO.new(attachment.download))]
|
|
|
|
pdf =
|
|
|
|
|
|
|
|
if attachment.image?
|
|
|
|
|
|
|
|
build_pdf_from_image(attachment)
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
HexaPDF::Document.new(io: StringIO.new(attachment.download))
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[attachment.uuid, pdf]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def build_pdf_from_image(attachment)
|
|
|
|
|
|
|
|
pdf = HexaPDF::Document.new
|
|
|
|
|
|
|
|
page = pdf.pages.add
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
scale = [A4_SIZE.first / attachment.metadata['width'].to_f,
|
|
|
|
|
|
|
|
A4_SIZE.last / attachment.metadata['height'].to_f].min
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page.box.width = attachment.metadata['width'] * scale
|
|
|
|
|
|
|
|
page.box.height = attachment.metadata['height'] * scale
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
page.canvas.image(
|
|
|
|
|
|
|
|
StringIO.new(attachment.download),
|
|
|
|
|
|
|
|
at: [0, 0],
|
|
|
|
|
|
|
|
width: page.box.width,
|
|
|
|
|
|
|
|
height: page.box.height
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pdf
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|