mirror of https://github.com/docusealco/docuseal
				
				
				
			
							parent
							
								
									d9f314898b
								
							
						
					
					
						commit
						3ee41975fd
					
				| @ -0,0 +1,45 @@ | |||||||
|  | # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | module Api | ||||||
|  |   class SubmissionDocumentsController < ApiBaseController | ||||||
|  |     load_and_authorize_resource :submission | ||||||
|  | 
 | ||||||
|  |     def index | ||||||
|  |       documents = | ||||||
|  |         if @submission.submitters.all?(&:completed_at?) | ||||||
|  |           last_submitter = @submission.submitters.max_by(&:completed_at) | ||||||
|  | 
 | ||||||
|  |           if last_submitter.documents_attachments.blank? | ||||||
|  |             last_submitter.documents_attachments = Submissions::EnsureResultGenerated.call(submitter) | ||||||
|  |           end | ||||||
|  | 
 | ||||||
|  |           last_submitter.documents_attachments | ||||||
|  |         else | ||||||
|  |           values_hash = Submissions::GeneratePreviewAttachments.build_values_hash(@submission) | ||||||
|  | 
 | ||||||
|  |           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 | ||||||
|  | 
 | ||||||
|  |       ActiveRecord::Associations::Preloader.new( | ||||||
|  |         records: documents, | ||||||
|  |         associations: [:blob] | ||||||
|  |       ).call | ||||||
|  | 
 | ||||||
|  |       render json: { | ||||||
|  |         id: @submission.id, | ||||||
|  |         documents: documents.map do |attachment| | ||||||
|  |           { name: attachment.filename.base, url: ActiveStorage::Blob.proxy_url(attachment.blob) } | ||||||
|  |         end | ||||||
|  |       } | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,96 @@ | |||||||
|  | # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | module Submissions | ||||||
|  |   module GeneratePreviewAttachments | ||||||
|  |     module_function | ||||||
|  | 
 | ||||||
|  |     # rubocop:disable Metrics | ||||||
|  |     def call(submission, values_hash: nil) | ||||||
|  |       values_hash ||= build_values_hash(submission) | ||||||
|  | 
 | ||||||
|  |       with_signature_id = submission.account.account_configs | ||||||
|  |                                     .exists?(key: AccountConfig::WITH_SIGNATURE_ID, value: true) | ||||||
|  | 
 | ||||||
|  |       is_flatten = | ||||||
|  |         submission.account.account_configs | ||||||
|  |                   .find_or_initialize_by(key: AccountConfig::FLATTEN_RESULT_PDF_KEY).value != false | ||||||
|  | 
 | ||||||
|  |       pdfs_index = GenerateResultAttachments.build_pdfs_index(submission, flatten: is_flatten) | ||||||
|  | 
 | ||||||
|  |       submission.submitters.where(completed_at: nil).preload(attachments_attachments: :blob).each do |submitter| | ||||||
|  |         GenerateResultAttachments.fill_submitter_fields(submitter, submission.account, pdfs_index, | ||||||
|  |                                                         with_signature_id:, is_flatten:) | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       template = submission.template | ||||||
|  | 
 | ||||||
|  |       image_pdfs = [] | ||||||
|  |       original_documents = template.documents.preload(:blob) | ||||||
|  | 
 | ||||||
|  |       result_attachments = | ||||||
|  |         submission.template_schema.map do |item| | ||||||
|  |           pdf = pdfs_index[item['attachment_uuid']] | ||||||
|  | 
 | ||||||
|  |           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:, | ||||||
|  |                                uuid: item['attachment_uuid'], | ||||||
|  |                                values_hash:, | ||||||
|  |                                name: item['name']) | ||||||
|  |         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:, | ||||||
|  |           uuid: GenerateResultAttachments.images_pdf_uuid(original_documents.select(&:image?)), | ||||||
|  |           values_hash:, | ||||||
|  |           name: template.name | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |       ApplicationRecord.no_touching do | ||||||
|  |         (result_attachments + [images_pdf_attachment]).map { |e| e.tap(&:save!) } | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def build_values_hash(submission) | ||||||
|  |       submission.submitters.reduce({}) { |acc, s| acc.merge(s.values) }.hash | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     def build_pdf_attachment(pdf:, submission:, uuid:, name:, values_hash:) | ||||||
|  |       io = StringIO.new | ||||||
|  | 
 | ||||||
|  |       begin | ||||||
|  |         pdf.write(io, incremental: true, validate: false) | ||||||
|  |       rescue HexaPDF::MalformedPDFError => e | ||||||
|  |         Rollbar.error(e) if defined?(Rollbar) | ||||||
|  | 
 | ||||||
|  |         pdf.write(io, incremental: false, validate: false) | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       ActiveStorage::Attachment.new( | ||||||
|  |         blob: ActiveStorage::Blob.create_and_upload!(io: io.tap(&:rewind), filename: "#{name}.pdf"), | ||||||
|  |         metadata: { original_uuid: uuid, | ||||||
|  |                     values_hash:, | ||||||
|  |                     analyzed: true, | ||||||
|  |                     sha256: Base64.urlsafe_encode64(Digest::SHA256.digest(io.string)) }, | ||||||
|  |         name: 'preview_documents', | ||||||
|  |         record: submission | ||||||
|  |       ) | ||||||
|  |     end | ||||||
|  |     # rubocop:enable Metrics | ||||||
|  |   end | ||||||
|  | end | ||||||
					Loading…
					
					
				
		Reference in new issue