mirror of https://github.com/docusealco/docuseal
				
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							88 lines
						
					
					
						
							2.5 KiB
						
					
					
				
			
		
		
	
	
							88 lines
						
					
					
						
							2.5 KiB
						
					
					
				# frozen_string_literal: true
 | 
						|
 | 
						|
module Submissions
 | 
						|
  module GenerateCombinedAttachment
 | 
						|
    module_function
 | 
						|
 | 
						|
    def call(submitter)
 | 
						|
      pdf = build_combined_pdf(submitter)
 | 
						|
 | 
						|
      submission = submitter.submission
 | 
						|
      account = submission.account
 | 
						|
 | 
						|
      pkcs = Accounts.load_signing_pkcs(account)
 | 
						|
      tsa_url = Accounts.load_timeserver_url(account)
 | 
						|
 | 
						|
      io = StringIO.new
 | 
						|
 | 
						|
      pdf.trailer.info[:Creator] = "#{Docuseal.product_name} (#{Docuseal::PRODUCT_URL})"
 | 
						|
 | 
						|
      if Docuseal.pdf_format == 'pdf/a-3b'
 | 
						|
        pdf.task(:pdfa, level: '3b')
 | 
						|
        pdf.config['font.map'] = GenerateResultAttachments::PDFA_FONT_MAP
 | 
						|
      end
 | 
						|
 | 
						|
      if pkcs
 | 
						|
        sign_params = {
 | 
						|
          reason: Submissions::GenerateResultAttachments.single_sign_reason(submitter),
 | 
						|
          **Submissions::GenerateResultAttachments.build_signing_params(submitter, pkcs, tsa_url)
 | 
						|
        }
 | 
						|
 | 
						|
        sign_pdf(io, pdf, sign_params)
 | 
						|
 | 
						|
        Submissions::GenerateResultAttachments.maybe_enable_ltv(io, sign_params)
 | 
						|
      else
 | 
						|
        pdf.write(io, incremental: true, validate: true)
 | 
						|
      end
 | 
						|
 | 
						|
      ActiveStorage::Attachment.create!(
 | 
						|
        blob: ActiveStorage::Blob.create_and_upload!(
 | 
						|
          io: io.tap(&:rewind), filename: "#{submission.name || submission.template.name}.pdf"
 | 
						|
        ),
 | 
						|
        name: 'combined_document',
 | 
						|
        record: submission
 | 
						|
      )
 | 
						|
    end
 | 
						|
 | 
						|
    def sign_pdf(io, pdf, sign_params)
 | 
						|
      pdf.sign(io, **sign_params)
 | 
						|
    rescue HexaPDF::MalformedPDFError => e
 | 
						|
      Rollbar.error(e) if defined?(Rollbar)
 | 
						|
 | 
						|
      pdf.sign(io, write_options: { incremental: false }, **sign_params)
 | 
						|
    rescue HexaPDF::Error => e
 | 
						|
      Rollbar.error(e) if defined?(Rollbar)
 | 
						|
 | 
						|
      pdf.validate(auto_correct: true)
 | 
						|
 | 
						|
      pdf.sign(io, write_options: { validate: false }, **sign_params)
 | 
						|
    end
 | 
						|
 | 
						|
    def build_combined_pdf(submitter)
 | 
						|
      pdfs_index = Submissions::GenerateResultAttachments.generate_pdfs(submitter)
 | 
						|
 | 
						|
      audit_trail = I18n.with_locale(submitter.account.locale) do
 | 
						|
        Submissions::GenerateAuditTrail.build_audit_trail(submitter.submission)
 | 
						|
      end
 | 
						|
 | 
						|
      audit_trail.dispatch_message(:complete_objects)
 | 
						|
 | 
						|
      result = HexaPDF::Document.new
 | 
						|
 | 
						|
      submitter.submission.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
 | 
						|
 | 
						|
      audit_trail.pages.each { |page| result.pages << result.import(page) }
 | 
						|
 | 
						|
      result
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |