|  |  | @ -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,12 +128,42 @@ module Submissions | 
			
		
	
		
		
			
				
					
					|  |  |  |         end |  |  |  |         end | 
			
		
	
		
		
			
				
					
					|  |  |  |       end |  |  |  |       end | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       image_pdfs = [] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       original_documents = template.documents.preload(:blob) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       results = | 
			
		
	
		
		
			
				
					
					|  |  |  |         template.schema.map do |item| |  |  |  |         template.schema.map do |item| | 
			
		
	
		
		
			
				
					
					|  |  |  |         template.documents.find { |a| a.uuid == item['attachment_uuid'] } |  |  |  |           pdf = pdfs_index[item['attachment_uuid']] | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         io = StringIO.new |  |  |  |           attachment = save_signed_pdf(pdf:, submitter:, cert:, uuid: item['attachment_uuid'], name: item['name']) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         pdf = pdfs_index[item['attachment_uuid']] |  |  |  |           image_pdfs << pdf if original_documents.find { |a| a.uuid == item['attachment_uuid'] }.image? | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           attachment | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         end | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       return results 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_result = | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         save_signed_pdf( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           pdf: images_pdf, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           submitter:, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           cert:, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           uuid: images_pdf_uuid(original_documents.select(&:image?)), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           name: template.name | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         ) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       results + [images_pdf_result] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     end | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     # rubocop:enable Metrics | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     def save_signed_pdf(pdf:, submitter:, cert:, uuid:, name:) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       io = StringIO.new | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |       pdf.sign(io, reason: "Signed by #{submitter.email}", |  |  |  |       pdf.sign(io, reason: "Signed by #{submitter.email}", | 
			
		
	
		
		
			
				
					
					|  |  |  |                    certificate: OpenSSL::X509::Certificate.new(cert['cert']), |  |  |  |                    certificate: OpenSSL::X509::Certificate.new(cert['cert']), | 
			
		
	
	
		
		
			
				
					|  |  | @ -140,28 +172,57 @@ module Submissions | 
			
		
	
		
		
			
				
					
					|  |  |  |                                        OpenSSL::X509::Certificate.new(cert['root_ca'])]) |  |  |  |                                        OpenSSL::X509::Certificate.new(cert['root_ca'])]) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |       ActiveStorage::Attachment.create!( |  |  |  |       ActiveStorage::Attachment.create!( | 
			
		
	
		
		
			
				
					
					|  |  |  |           uuid: item['attachment_uuid'], |  |  |  |         uuid:, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         blob: ActiveStorage::Blob.create_and_upload!( |  |  |  |         blob: ActiveStorage::Blob.create_and_upload!( | 
			
		
	
		
		
			
				
					
					|  |  |  |             io: StringIO.new(io.string), filename: "#{item['name']}.pdf" |  |  |  |           io: StringIO.new(io.string), filename: "#{name}.pdf" | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         ), |  |  |  |         ), | 
			
		
	
		
		
			
				
					
					|  |  |  |         name: 'documents', |  |  |  |         name: 'documents', | 
			
		
	
		
		
			
				
					
					|  |  |  |         record: submitter |  |  |  |         record: submitter | 
			
		
	
		
		
			
				
					
					|  |  |  |       ) |  |  |  |       ) | 
			
		
	
		
		
			
				
					
					|  |  |  |     end |  |  |  |     end | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     def images_pdf_uuid(attachments) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       Digest::UUID.uuid_v5(Digest::UUID::OID_NAMESPACE, attachments.map(&:uuid).sort.join(':')) | 
			
		
	
		
		
			
				
					
					|  |  |  |     end |  |  |  |     end | 
			
		
	
		
		
			
				
					
					|  |  |  |     # rubocop:enable Metrics |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     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 | 
			
		
	
	
		
		
			
				
					|  |  | 
 |