diff --git a/app/controllers/api/submissions_controller.rb b/app/controllers/api/submissions_controller.rb index 17d961dd..fc89c1d3 100644 --- a/app/controllers/api/submissions_controller.rb +++ b/app/controllers/api/submissions_controller.rb @@ -183,7 +183,7 @@ module Api def submissions_params permitted_attrs = [ :send_email, :send_sms, :bcc_completed, :completed_redirect_url, :reply_to, :go_to_last, - :expire_at, + :expire_at, :name, { message: %i[subject body], submitters: [[:send_email, :send_sms, :completed_redirect_url, :uuid, :name, :email, :role, diff --git a/app/controllers/api/templates_clone_controller.rb b/app/controllers/api/templates_clone_controller.rb index 7879abfd..bf9aa671 100644 --- a/app/controllers/api/templates_clone_controller.rb +++ b/app/controllers/api/templates_clone_controller.rb @@ -21,12 +21,13 @@ module Api ) cloned_template.source = :api - cloned_template.save! schema_documents = Templates::CloneAttachments.call(template: cloned_template, original_template: @template, documents: params[:documents]) + cloned_template.save! + WebhookUrls.for_account_id(cloned_template.account_id, 'template.created').each do |webhook_url| SendTemplateCreatedWebhookRequestJob.perform_async('template_id' => cloned_template.id, 'webhook_url_id' => webhook_url.id) diff --git a/app/controllers/start_form_controller.rb b/app/controllers/start_form_controller.rb index 415adab4..b2957c1c 100644 --- a/app/controllers/start_form_controller.rb +++ b/app/controllers/start_form_controller.rb @@ -142,7 +142,7 @@ class StartFormController < ApplicationController end def filter_undefined_submitters(template) - Templates.filter_undefined_submitters(template) + Templates.filter_undefined_submitters(template.submitters) end def submitter_params diff --git a/app/controllers/submissions_archived_controller.rb b/app/controllers/submissions_archived_controller.rb index 3ad5d936..9bd67da2 100644 --- a/app/controllers/submissions_archived_controller.rb +++ b/app/controllers/submissions_archived_controller.rb @@ -4,7 +4,7 @@ class SubmissionsArchivedController < ApplicationController load_and_authorize_resource :submission, parent: false def index - @submissions = @submissions.joins(:template) + @submissions = @submissions.left_joins(:template) @submissions = @submissions.where.not(archived_at: nil) .or(@submissions.where.not(templates: { archived_at: nil })) .preload(:template_accesses, :created_by_user, template: :author) diff --git a/app/controllers/submissions_dashboard_controller.rb b/app/controllers/submissions_dashboard_controller.rb index 55fb6ae0..3d0950a6 100644 --- a/app/controllers/submissions_dashboard_controller.rb +++ b/app/controllers/submissions_dashboard_controller.rb @@ -4,7 +4,7 @@ class SubmissionsDashboardController < ApplicationController load_and_authorize_resource :submission, parent: false def index - @submissions = @submissions.joins(:template) + @submissions = @submissions.left_joins(:template) @submissions = @submissions.where(archived_at: nil) .where(templates: { archived_at: nil }) diff --git a/app/controllers/submit_form_controller.rb b/app/controllers/submit_form_controller.rb index a9a489c8..46b28128 100644 --- a/app/controllers/submit_form_controller.rb +++ b/app/controllers/submit_form_controller.rb @@ -8,6 +8,7 @@ class SubmitFormController < ApplicationController skip_authorization_check before_action :load_submitter, only: %i[show update completed] + before_action :maybe_render_locked_page, only: :show CONFIG_KEYS = [].freeze @@ -15,19 +16,14 @@ class SubmitFormController < ApplicationController submission = @submitter.submission return redirect_to submit_form_completed_path(@submitter.slug) if @submitter.completed_at? - return render :archived if submission.template.archived_at? || - submission.archived_at? || - @submitter.account.archived_at? - return render :expired if submission.expired? - return render :declined if @submitter.declined_at? @form_configs = Submitters::FormConfigs.call(@submitter, CONFIG_KEYS) return render :awaiting if (@form_configs[:enforce_signing_order] || - submission.template.preferences['submitters_order'] == 'preserved') && + submission.template&.preferences&.dig('submitters_order') == 'preserved') && !Submitters.current_submitter_order?(@submitter) - Submitters.preload_with_pages(@submitter) + Submissions.preload_with_pages(submission) Submitters::MaybeUpdateDefaultValues.call(@submitter, current_user) @@ -54,7 +50,7 @@ class SubmitFormController < ApplicationController return render json: { error: I18n.t('form_has_been_completed_already') }, status: :unprocessable_entity end - if @submitter.template.archived_at? || @submitter.submission.archived_at? + if @submitter.template&.archived_at? || @submitter.submission.archived_at? return render json: { error: I18n.t('form_has_been_archived') }, status: :unprocessable_entity end @@ -84,6 +80,15 @@ class SubmitFormController < ApplicationController private + def maybe_render_locked_page + return render :archived if @submitter.submission.template&.archived_at? || + @submitter.submission.archived_at? || + @submitter.account.archived_at? + return render :expired if @submitter.submission.expired? + + render :declined if @submitter.declined_at? + end + def load_submitter @submitter = Submitter.find_by!(slug: params[:slug] || params[:submit_form_slug]) end diff --git a/app/controllers/submit_form_decline_controller.rb b/app/controllers/submit_form_decline_controller.rb index 94099b0d..15572da1 100644 --- a/app/controllers/submit_form_decline_controller.rb +++ b/app/controllers/submit_form_decline_controller.rb @@ -11,7 +11,7 @@ class SubmitFormDeclineController < ApplicationController submitter.completed_at? || submitter.submission.archived_at? || submitter.submission.expired? || - submitter.submission.template.archived_at? + submitter.submission.template&.archived_at? ApplicationRecord.transaction do submitter.update!(declined_at: Time.current) diff --git a/app/controllers/submit_form_download_controller.rb b/app/controllers/submit_form_download_controller.rb index 07447940..574d520a 100644 --- a/app/controllers/submit_form_download_controller.rb +++ b/app/controllers/submit_form_download_controller.rb @@ -14,7 +14,7 @@ class SubmitFormDownloadController < ApplicationController return head :unprocessable_entity if @submitter.declined_at? || @submitter.submission.archived_at? || @submitter.submission.expired? || - @submitter.submission.template.archived_at? + @submitter.submission.template&.archived_at? last_completed_submitter = @submitter.submission.submitters .where.not(id: @submitter.id) @@ -25,7 +25,7 @@ class SubmitFormDownloadController < ApplicationController if last_completed_submitter Submitters.select_attachments_for_download(last_completed_submitter) else - @submitter.submission.template.schema_documents.preload(:blob) + @submitter.submission.schema_documents.preload(:blob) end urls = attachments.map do |attachment| diff --git a/app/controllers/submitters_resubmit_controller.rb b/app/controllers/submitters_resubmit_controller.rb index fb893d98..6ab28731 100644 --- a/app/controllers/submitters_resubmit_controller.rb +++ b/app/controllers/submitters_resubmit_controller.rb @@ -6,13 +6,15 @@ class SubmittersResubmitController < ApplicationController def update return redirect_to submit_form_path(slug: @submitter.slug) if @submitter.email != current_user.email - submission = @submitter.template.submissions.new(created_by_user: current_user, - submitters_order: :preserved, - **@submitter.submission.slice(:template_fields, - :account_id, - :template_schema, - :template_submitters, - :preferences)) + submission = @submitter.account.submissions.new(created_by_user: current_user, + submitters_order: :preserved, + **@submitter.submission.slice(:template_fields, + :account_id, + :name, + :template_id, + :template_schema, + :template_submitters, + :preferences)) @submitter.submission.submitters.each do |submitter| new_submitter = submission.submitters.new(submitter.slice(:uuid, :email, :phone, :name, @@ -27,6 +29,10 @@ class SubmittersResubmitController < ApplicationController submission.save! + @submitter.submission.documents_attachments.each do |attachment| + submission.documents_attachments.create!(uuid: attachment.uuid, blob_id: attachment.blob_id) + end + redirect_to submit_form_path(slug: @new_submitter.slug) end diff --git a/app/controllers/templates_form_preview_controller.rb b/app/controllers/templates_form_preview_controller.rb index f7a1a396..5c4f23c6 100644 --- a/app/controllers/templates_form_preview_controller.rb +++ b/app/controllers/templates_form_preview_controller.rb @@ -13,7 +13,7 @@ class TemplatesFormPreviewController < ApplicationController @submitter.submission.submitters = @template.submitters.map { |item| Submitter.new(uuid: item['uuid']) } - Submitters.preload_with_pages(@submitter) + Submissions.preload_with_pages(@submitter.submission) @attachments_index = ActiveStorage::Attachment.where(record: @submitter.submission.submitters, name: :attachments) .preload(:blob).index_by(&:uuid) diff --git a/app/jobs/generate_attachment_preview_job.rb b/app/jobs/generate_attachment_preview_job.rb new file mode 100644 index 00000000..6d032711 --- /dev/null +++ b/app/jobs/generate_attachment_preview_job.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class GenerateAttachmentPreviewJob + include Sidekiq::Job + + InvalidFormat = Class.new(StandardError) + + sidekiq_options queue: :images + + def perform(params = {}) + attachment = ActiveStorage::Attachment.find(params['attachment_id']) + + if attachment.content_type == Templates::ProcessDocument::PDF_CONTENT_TYPE + Templates::ProcessDocument.generate_pdf_preview_images(attachment, attachment.download) + elsif attachment.image? + Templates::ProcessDocument.generate_preview_image(attachment, attachment.download) + else + raise InvalidFormat, attachment.id + end + end +end diff --git a/app/jobs/process_submission_expired_job.rb b/app/jobs/process_submission_expired_job.rb index 99bee5e8..8e9d6fb2 100644 --- a/app/jobs/process_submission_expired_job.rb +++ b/app/jobs/process_submission_expired_job.rb @@ -7,7 +7,7 @@ class ProcessSubmissionExpiredJob submission = Submission.find(params['submission_id']) return if submission.archived_at? - return if submission.template.archived_at? + return if submission.template&.archived_at? return if submission.submitters.where.not(declined_at: nil).exists? return unless submission.submitters.exists?(completed_at: nil) diff --git a/app/jobs/process_submitter_completion_job.rb b/app/jobs/process_submitter_completion_job.rb index 9c3a4b26..c53baaf5 100644 --- a/app/jobs/process_submitter_completion_job.rb +++ b/app/jobs/process_submitter_completion_job.rb @@ -82,7 +82,7 @@ class ProcessSubmitterCompletionJob user = submission.created_by_user || submitter.template.author if submitter.account.users.exists?(id: user.id) && submission.preferences['send_email'] != false && - submitter.template.preferences['completed_notification_email_enabled'] != false + submitter.template&.preferences&.dig('completed_notification_email_enabled') != false if submission.submitters.map(&:email).exclude?(user.email) && user.user_configs.find_by(key: UserConfig::RECEIVE_COMPLETED_EMAIL)&.value != false && user.role != 'integration' @@ -98,7 +98,7 @@ class ProcessSubmitterCompletionJob end def maybe_enqueue_copy_emails(submitter) - return if submitter.template.preferences['documents_copy_email_enabled'] == false + return if submitter.template&.preferences&.dig('documents_copy_email_enabled') == false configs = AccountConfigs.find_or_initialize_for_key(submitter.account, AccountConfig::SUBMITTER_DOCUMENTS_COPY_EMAIL_KEY) @@ -119,7 +119,7 @@ class ProcessSubmitterCompletionJob def build_bcc_addresses(submission) bcc = submission.preferences['bcc_completed'].presence || - submission.template.preferences['bcc_completed'].presence || + submission.template&.preferences&.dig('bcc_completed').presence || submission.account.account_configs .find_by(key: AccountConfig::BCC_EMAILS)&.value diff --git a/app/mailers/submitter_mailer.rb b/app/mailers/submitter_mailer.rb index 769995ed..c4627969 100644 --- a/app/mailers/submitter_mailer.rb +++ b/app/mailers/submitter_mailer.rb @@ -23,11 +23,11 @@ class SubmitterMailer < ApplicationMailer @body = @email_message&.body.presence || template_submitters_index.dig(@submitter.uuid, 'request_email_body').presence || - @submitter.template.preferences['request_email_body'].presence + @submitter.template&.preferences&.dig('request_email_body').presence @subject = @email_message&.subject.presence || template_submitters_index.dig(@submitter.uuid, 'request_email_subject').presence || - @submitter.template.preferences['request_email_subject'].presence + @submitter.template&.preferences&.dig('request_email_subject').presence @email_config = AccountConfigs.find_for_account(@current_account, AccountConfig::SUBMITTER_INVITATION_EMAIL_KEY) @@ -53,6 +53,8 @@ class SubmitterMailer < ApplicationMailer @submission = submitter.submission @user = user + template_preferences = @submission.template&.preferences || {} + Submissions::EnsureResultGenerated.call(submitter) @email_config = AccountConfigs.find_for_account(@current_account, AccountConfig::SUBMITTER_COMPLETED_EMAIL_KEY) @@ -60,15 +62,15 @@ class SubmitterMailer < ApplicationMailer add_completed_email_attachments!( submitter, with_documents: @email_config&.value&.dig('attach_documents') != false && - @submitter.template.preferences['completed_notification_email_attach_documents'] != false, + template_preferences['completed_notification_email_attach_documents'] != false, with_audit_log: @email_config&.value&.dig('attach_audit_log') != false && - @submitter.template.preferences['completed_notification_email_attach_audit'] != false + template_preferences['completed_notification_email_attach_audit'] != false ) - @subject = @submitter.template.preferences['completed_notification_email_subject'].presence + @subject = template_preferences['completed_notification_email_subject'].presence @subject ||= @email_config.value['subject'] if @email_config - @body = @submitter.template.preferences['completed_notification_email_body'].presence + @body = template_preferences['completed_notification_email_body'].presence @body ||= @email_config.value['body'] if @email_config assign_message_metadata('submitter_completed', @submitter) @@ -97,7 +99,7 @@ class SubmitterMailer < ApplicationMailer to: user.role == 'integration' ? user.friendly_name.sub(/\+\w+@/, '@') : user.friendly_name, reply_to: @submitter.friendly_name, subject: I18n.t(:name_declined_by_submitter, - name: @submission.template.name.truncate(20), + name: (@submission.name || @submission.template.name).truncate(20), submitter: @submitter.name || @submitter.email || @submitter.phone)) end end @@ -107,22 +109,24 @@ class SubmitterMailer < ApplicationMailer @submitter = submitter @sig = submitter.signed_id(expires_in: SIGN_TTL, purpose: :download_completed) if sig + template_preferences = @submitter.template&.preferences || {} + Submissions::EnsureResultGenerated.call(@submitter) @email_config = AccountConfigs.find_for_account(@current_account, AccountConfig::SUBMITTER_DOCUMENTS_COPY_EMAIL_KEY) add_completed_email_attachments!( submitter, - with_documents: @submitter.template.preferences['documents_copy_email_attach_documents'] != false && - (@email_config.nil? || @email_config.value['attach_documents'] != false), - with_audit_log: @submitter.template.preferences['documents_copy_email_attach_audit'] != false && - (@email_config.nil? || @email_config.value['attach_audit_log'] != false) + with_documents: template_preferences['documents_copy_email_attach_documents'] != false && + (@email_config.nil? || @email_config.value['attach_documents'] != false), + with_audit_log: template_preferences['documents_copy_email_attach_audit'] != false && + (@email_config.nil? || @email_config.value['attach_audit_log'] != false) ) - @subject = @submitter.template.preferences['documents_copy_email_subject'].presence + @subject = template_preferences['documents_copy_email_subject'].presence @subject ||= @email_config.value['subject'] if @email_config - @body = @submitter.template.preferences['documents_copy_email_body'].presence + @body = template_preferences['documents_copy_email_body'].presence @body ||= @email_config.value['body'] if @email_config assign_message_metadata('submitter_documents_copy', @submitter) @@ -130,11 +134,7 @@ class SubmitterMailer < ApplicationMailer I18n.with_locale(@current_account.locale) do subject = - if @subject.present? - ReplaceEmailVariables.call(@subject, submitter:) - else - I18n.t(:your_document_copy) - end + @subject.present? ? ReplaceEmailVariables.call(@subject, submitter:) : I18n.t(:your_document_copy) mail(from: from_address_for_submitter(submitter), to: to || @submitter.friendly_name, @@ -147,7 +147,7 @@ class SubmitterMailer < ApplicationMailer def build_submitter_reply_to(submitter, email_config: nil, documents_copy_email: nil) reply_to = submitter.preferences['reply_to'].presence - reply_to ||= submitter.template.preferences['documents_copy_email_reply_to'].presence if documents_copy_email + reply_to ||= submitter.template&.preferences&.dig('documents_copy_email_reply_to').presence if documents_copy_email reply_to ||= email_config.value['reply_to'].presence if email_config if reply_to.blank? && (submitter.submission.created_by_user || submitter.template.author)&.email != submitter.email @@ -212,7 +212,7 @@ class SubmitterMailer < ApplicationMailer end def build_submitter_preferences_index(submitter) - submitter.template.preferences['submitters'].to_a.index_by { |e| e['uuid'] } + submitter.template&.preferences&.dig('submitters').to_a.index_by { |e| e['uuid'] } end def add_attachments_with_size_limit(submitter, storage_attachments, current_size, filename_format = nil) diff --git a/app/models/completed_submitter.rb b/app/models/completed_submitter.rb index e34f65d2..6ada62f3 100644 --- a/app/models/completed_submitter.rb +++ b/app/models/completed_submitter.rb @@ -13,7 +13,7 @@ # account_id :bigint not null # submission_id :bigint not null # submitter_id :bigint not null -# template_id :bigint not null +# template_id :bigint # # Indexes # @@ -24,7 +24,7 @@ class CompletedSubmitter < ApplicationRecord belongs_to :submitter belongs_to :submission belongs_to :account - belongs_to :template + belongs_to :template, optional: true has_many :completed_documents, dependent: :destroy, primary_key: :submitter_id, diff --git a/app/models/submission.rb b/app/models/submission.rb index d5f17a2f..f0fe283c 100644 --- a/app/models/submission.rb +++ b/app/models/submission.rb @@ -7,6 +7,7 @@ # id :bigint not null, primary key # archived_at :datetime # expire_at :datetime +# name :text # preferences :text not null # slug :string not null # source :text not null @@ -18,7 +19,7 @@ # updated_at :datetime not null # account_id :bigint not null # created_by_user_id :bigint -# template_id :bigint not null +# template_id :bigint # # Indexes # @@ -33,7 +34,7 @@ # fk_rails_... (template_id => templates.id) # class Submission < ApplicationRecord - belongs_to :template + belongs_to :template, optional: true belongs_to :account belongs_to :created_by_user, class_name: 'User', optional: true @@ -56,6 +57,7 @@ class Submission < ApplicationRecord has_one_attached :combined_document has_many_attached :preview_documents + has_many_attached :documents has_many :template_accesses, primary_key: :template_id, foreign_key: :template_id, dependent: nil, inverse_of: false @@ -96,6 +98,14 @@ class Submission < ApplicationRecord expire_at && expire_at <= Time.current end + def schema_documents + if template_id? + template_schema_documents + else + documents_attachments + end + end + def fields_uuid_index @fields_uuid_index ||= (template_fields || template.fields).index_by { |f| f['uuid'] } end diff --git a/app/views/start_form/completed.html.erb b/app/views/start_form/completed.html.erb index f629d6ab..003005d8 100644 --- a/app/views/start_form/completed.html.erb +++ b/app/views/start_form/completed.html.erb @@ -26,7 +26,7 @@ <%= button_to button_title(title: t('send_copy_to_email'), disabled_with: t('sending'), icon: svg_icon('mail_forward', class: 'w-6 h-6')), send_submission_email_index_path, params: { template_slug: @template.slug, email: params[:email] }, class: 'base-button w-full' %> <% end %> - <% if Templates.filter_undefined_submitters(@template).size == 1 && %w[api embed].exclude?(@submitter.submission.source) && @submitter.account.account_configs.find_or_initialize_by(key: AccountConfig::ALLOW_TO_RESUBMIT).value != false && @template.shared_link? %> + <% if Templates.filter_undefined_submitters(@template.submitters).size == 1 && %w[api embed].exclude?(@submitter.submission.source) && @submitter.account.account_configs.find_or_initialize_by(key: AccountConfig::ALLOW_TO_RESUBMIT).value != false && @template.shared_link? %> <%= button_to button_title(title: t('resubmit'), disabled_with: t('resubmit'), icon: svg_icon('reload', class: 'w-6 h-6')), start_form_path(@template.slug), params: { submitter: { email: params[:email] }, resubmit: true }, method: :put, class: 'white-button w-full' %> diff --git a/app/views/submissions/show.html.erb b/app/views/submissions/show.html.erb index 75fe1ea7..ded86629 100644 --- a/app/views/submissions/show.html.erb +++ b/app/views/submissions/show.html.erb @@ -4,9 +4,9 @@ <% with_signature_id, is_combined_enabled = AccountConfig.where(account_id: @submission.account_id, key: [AccountConfig::COMBINE_PDF_RESULT_KEY, AccountConfig::WITH_SIGNATURE_ID], value: true).then { |configs| [configs.any? { |e| e.key == AccountConfig::WITH_SIGNATURE_ID }, configs.any? { |e| e.key == AccountConfig::COMBINE_PDF_RESULT_KEY }] } %>
- + <%= render 'submissions/logo' %> - <% @submission.template.name.split(/(_)/).each do |item| %><%= item %><% end %> + <% (@submission.name || @submission.template.name).split(/(_)/).each do |item| %><%= item %><% end %>
<% last_submitter = @submission.submitters.to_a.select(&:completed_at?).max_by(&:completed_at) %> @@ -73,7 +73,7 @@ <% values = @submission.submitters.reduce({}) { |acc, sub| acc.merge(sub.values) } %> <% schema = Submissions.filtered_conditions_schema(@submission, values:) %> <% schema.each do |item| %> - <% document = @submission.template_schema_documents.find { |a| item['attachment_uuid'] == a.uuid } %> + <% document = @submission.schema_documents.find { |a| item['attachment_uuid'] == a.uuid } %> " onclick="[event.preventDefault(), window[event.target.closest('a').href.split('#')[1]].scrollIntoView({ behavior: 'smooth', block: 'start' })]" class="block cursor-pointer">
@@ -89,7 +89,7 @@ <% attachments_index = ActiveStorage::Attachment.where(record: @submission.submitters, name: :attachments).preload(:blob).index_by(&:uuid) %> <% page_blob_struct = Struct.new(:url, :metadata, keyword_init: true) %> <% schema.each do |item| %> - <% document = @submission.template_schema_documents.find { |e| e.uuid == item['attachment_uuid'] } %> + <% document = @submission.schema_documents.find { |e| e.uuid == item['attachment_uuid'] } %> <% document_annots_index = document.metadata.dig('pdf', 'annotations')&.group_by { |e| e['page'] } || {} %> <% preview_images_index = document.preview_images.loaded? ? document.preview_images.index_by { |e| e.filename.base.to_i } : {} %> <% lazyload_metadata = document.preview_images.first.metadata %> diff --git a/app/views/submissions_preview/completed.html.erb b/app/views/submissions_preview/completed.html.erb index 657eec51..f8346117 100644 --- a/app/views/submissions_preview/completed.html.erb +++ b/app/views/submissions_preview/completed.html.erb @@ -11,7 +11,7 @@ <%= svg_icon('writing_sign', class: 'w-10 h-10') %>
-

<%= @submission.template.name %>

+

<%= @submission.name || @submission.template.name %>

<% last_submitter = @submission.submitters.completed.order(:completed_at).last %> <% if last_submitter %>

diff --git a/app/views/submit_form/_submission_form.html.erb b/app/views/submit_form/_submission_form.html.erb index 8b7af020..bccf174b 100644 --- a/app/views/submit_form/_submission_form.html.erb +++ b/app/views/submit_form/_submission_form.html.erb @@ -2,4 +2,4 @@ <% data_fields = Submissions.filtered_conditions_fields(submitter).to_json %> <% invite_submitters = (submitter.submission.template_submitters || submitter.submission.template.submitters).select { |s| s['invite_by_uuid'] == submitter.uuid && submitter.submission.submitters.none? { |e| e.uuid == s['uuid'] } }.to_json %> <% optional_invite_submitters = (submitter.submission.template_submitters || submitter.submission.template.submitters).select { |s| s['optional_invite_by_uuid'] == submitter.uuid && submitter.submission.submitters.none? { |e| e.uuid == s['uuid'] } }.to_json %> - + diff --git a/app/views/submit_form/archived.html.erb b/app/views/submit_form/archived.html.erb index bacbfc1d..7e59aece 100644 --- a/app/views/submit_form/archived.html.erb +++ b/app/views/submit_form/archived.html.erb @@ -10,7 +10,7 @@ <%= svg_icon('writing_sign', class: 'w-10 h-10') %>

-

<%= @submitter.submission.template.name %>

+

<%= @submitter.submission.name || @submitter.submission.template.name %>

<%= t('form_has_been_deleted_by_html', name: @submitter.account.name) %>

diff --git a/app/views/submit_form/awaiting.html.erb b/app/views/submit_form/awaiting.html.erb index a1205824..34c0acc8 100644 --- a/app/views/submit_form/awaiting.html.erb +++ b/app/views/submit_form/awaiting.html.erb @@ -10,7 +10,7 @@ <%= svg_icon('writing_sign', class: 'w-10 h-10') %>
-

<%= @submitter.submission.template.name %>

+

<%= @submitter.submission.name || @submitter.submission.template.name %>

<%= t('awaiting_completion_by_the_other_party') %>

diff --git a/app/views/submit_form/completed.html.erb b/app/views/submit_form/completed.html.erb index a5492dbf..004c9027 100644 --- a/app/views/submit_form/completed.html.erb +++ b/app/views/submit_form/completed.html.erb @@ -10,7 +10,7 @@ <%= svg_icon('writing_sign', class: 'w-10 h-10') %>
-

<%= @submitter.submission.template.name %>

+

<%= @submitter.submission.name || @submitter.submission.template.name %>

<%= t(@submitter.with_signature_fields? ? 'signed_on_time' : 'completed_on_time', time: l(@submitter.completed_at.to_date, format: :long)) %>

@@ -23,7 +23,7 @@ <%= button_to button_title(title: t('send_copy_to_email'), disabled_with: t('sending'), icon: svg_icon('mail_forward', class: 'w-6 h-6')), send_submission_email_index_path, params: { submitter_slug: @submitter.slug }, class: 'white-button w-full' %> - <% if Templates.filter_undefined_submitters(@submitter.submission.template).size != 1 %> + <% if Templates.filter_undefined_submitters(@submitter.submission.template_submitters).size != 1 %>
<%= t('or') %>
<% else %>
@@ -42,8 +42,8 @@ <% end %>
- <% undefined_submitters = Templates.filter_undefined_submitters(@submitter.submission.template) %> - <% if undefined_submitters.size == 1 && undefined_submitters.first['uuid'] == @submitter.uuid && %w[api embed].exclude?(@submitter.submission.source) && @submitter.account.account_configs.find_or_initialize_by(key: AccountConfig::ALLOW_TO_RESUBMIT).value != false %> + <% undefined_submitters = Templates.filter_undefined_submitters(@submitter.submission.template_submitters) %> + <% if undefined_submitters.size == 1 && undefined_submitters.first['uuid'] == @submitter.uuid && %w[api embed].exclude?(@submitter.submission.source) && @submitter.account.account_configs.find_or_initialize_by(key: AccountConfig::ALLOW_TO_RESUBMIT).value != false && @submitter.template && !@submitter.template.archived_at? %>
<%= t('or') %>
<%= button_to button_title(title: t('resubmit'), disabled_with: t('resubmit'), icon: svg_icon('reload', class: 'w-6 h-6')), resubmit_form_path, params: { resubmit: @submitter.slug }, method: :put, class: 'white-button w-full' %> diff --git a/app/views/submit_form/declined.html.erb b/app/views/submit_form/declined.html.erb index f0e06b3f..cc45cc23 100644 --- a/app/views/submit_form/declined.html.erb +++ b/app/views/submit_form/declined.html.erb @@ -10,7 +10,7 @@ <%= svg_icon('writing_sign', class: 'w-10 h-10') %>
-

<%= @submitter.submission.template.name %>

+

<%= @submitter.submission.name || @submitter.submission.template.name %>

<%= t('form_has_been_declined_on_html', time: l(@submitter.declined_at, format: :long)) %>

diff --git a/app/views/submit_form/expired.html.erb b/app/views/submit_form/expired.html.erb index 8a85d5e8..d012185f 100644 --- a/app/views/submit_form/expired.html.erb +++ b/app/views/submit_form/expired.html.erb @@ -10,7 +10,7 @@ <%= svg_icon('writing_sign', class: 'w-10 h-10') %>
-

<%= @submitter.submission.template.name %>

+

<%= @submitter.submission.name || @submitter.submission.template.name %>

<%= t('form_expired_at_html', time: l(@submitter.submission.expire_at, format: :long)) %>

diff --git a/app/views/submit_form/show.html.erb b/app/views/submit_form/show.html.erb index 491256a6..2a9f0dc7 100644 --- a/app/views/submit_form/show.html.erb +++ b/app/views/submit_form/show.html.erb @@ -1,4 +1,4 @@ -<% content_for(:html_title, "#{@submitter.submission.template.name} | DocuSeal") %> +<% content_for(:html_title, "#{@submitter.submission.name || @submitter.submission.template.name} | DocuSeal") %> <% content_for(:html_description, "#{@submitter.account.name} has invited you to fill and sign documents online effortlessly with a secure, fast, and user-friendly digital document signing solution.") %> <% fields_index = Templates.build_field_areas_index(@submitter.submission.template_fields || @submitter.submission.template.fields) %> <% values = @submitter.submission.submitters.reduce({}) { |acc, sub| acc.merge(sub.values) } %> @@ -13,7 +13,7 @@ <%= render('submit_form/banner') %>
- <%= @submitter.submission.template.name %> + <%= @submitter.submission.name || @submitter.submission.template.name %>
<% if @form_configs[:with_decline] %> @@ -58,11 +58,11 @@ <% end %> <% schema.each do |item| %> - <% document = @submitter.submission.template_schema_documents.find { |a| a.uuid == item['attachment_uuid'] } %> + <% document = @submitter.submission.schema_documents.find { |a| a.uuid == item['attachment_uuid'] } %>
<% document_annots_index = document.metadata.dig('pdf', 'annotations')&.group_by { |e| e['page'] } || {} %> <% preview_images_index = document.preview_images.loaded? ? document.preview_images.index_by { |e| e.filename.base.to_i } : {} %> - <% lazyload_metadata = document.preview_images.last.metadata %> + <% lazyload_metadata = document.preview_images.last&.metadata || {} %> <% (document.metadata.dig('pdf', 'number_of_pages') || (document.preview_images.loaded? ? preview_images_index.size : document.preview_images.size)).times do |index| %> <% page = preview_images_index[index] || page_blob_struct.new(metadata: lazyload_metadata, url: preview_document_page_path(document.signed_uuid, "#{index}.jpg")) %>
diff --git a/app/views/submitter_mailer/completed_email.html.erb b/app/views/submitter_mailer/completed_email.html.erb index 7269fb39..382efb16 100644 --- a/app/views/submitter_mailer/completed_email.html.erb +++ b/app/views/submitter_mailer/completed_email.html.erb @@ -2,6 +2,6 @@ <%= render 'custom_content', content: @body, submitter: @submitter %> <% else %>

<%= t('hi_there') %>,

-

<%= I18n.t(:name_has_been_completed_by_submitters, name: @submitter.submission.template.name, submitters: @submitter.submission.submitters.order(:completed_at).map { |e| e.name || e.email || e.phone }.uniq.join(', ')) %>

+

<%= I18n.t(:name_has_been_completed_by_submitters, name: @submitter.submission.name || @submitter.submission.template.name, submitters: @submitter.submission.submitters.order(:completed_at).map { |e| e.name || e.email || e.phone }.uniq.join(', ')) %>

<%= link_to submission_url(@submitter.submission), submission_url(@submitter.submission) %>

<% end %> diff --git a/app/views/submitter_mailer/declined_email.html.erb b/app/views/submitter_mailer/declined_email.html.erb index 0e6ce535..07b877c9 100644 --- a/app/views/submitter_mailer/declined_email.html.erb +++ b/app/views/submitter_mailer/declined_email.html.erb @@ -1,4 +1,4 @@

<%= t('hi_there') %>,

-

<%= t('name_declined_by_submitter_with_the_following_reason', name: @submitter.submission.template.name, submitter: @submitter.name || @submitter.email || @submitter.phone) %>

+

<%= t('name_declined_by_submitter_with_the_following_reason', name: @submitter.submission.name || @submitter.submission.template.name, submitter: @submitter.name || @submitter.email || @submitter.phone) %>

<%= simple_format(h(@submitter.submission_events.find_by(event_type: :decline_form).data['reason'])) %>

<%= link_to submission_url(@submitter.submission), submission_url(@submitter.submission) %>

diff --git a/app/views/submitter_mailer/documents_copy_email.html.erb b/app/views/submitter_mailer/documents_copy_email.html.erb index 0312a0bc..3117481d 100644 --- a/app/views/submitter_mailer/documents_copy_email.html.erb +++ b/app/views/submitter_mailer/documents_copy_email.html.erb @@ -2,10 +2,10 @@ <%= render 'custom_content', content: @body, submitter: @submitter, sig: @sig %> <% else %>

<%= t('hi_there') %>,

-

<%= t('please_check_the_copy_of_your_name_in_the_email_attachments', name: @submitter.submission.template.name) %> +

<%= t('please_check_the_copy_of_your_name_in_the_email_attachments', name: @submitter.submission.name || @submitter.submission.template.name) %>

<%= t('alternatively_you_can_review_and_download_your_copy_using_the_link_below') %>

- <%= link_to @submitter.template.name, submissions_preview_url(@submitter.submission.slug, { sig: @sig }.compact) %> + <%= link_to @submitter.submission.name || @submitter.submission.template.name, submissions_preview_url(@submitter.submission.slug, { sig: @sig }.compact) %>

<%= t('thanks') %>,
<%= @current_account.name %> diff --git a/app/views/submitter_mailer/invitation_email.html.erb b/app/views/submitter_mailer/invitation_email.html.erb index 968ec02b..06eaef30 100644 --- a/app/views/submitter_mailer/invitation_email.html.erb +++ b/app/views/submitter_mailer/invitation_email.html.erb @@ -6,7 +6,7 @@ <% end %> <% else %>

<%= t('hi_there') %>,

-

<%= I18n.t(@submitter.with_signature_fields? ? :you_have_been_invited_to_sign_the_name : :you_have_been_invited_to_submit_the_name_form, name: @submitter.submission.template.name) %>

+

<%= I18n.t(@submitter.with_signature_fields? ? :you_have_been_invited_to_sign_the_name : :you_have_been_invited_to_submit_the_name_form, name: @submitter.submission.name || @submitter.submission.template.name) %>

<%= link_to I18n.t(@submitter.with_signature_fields? ? :review_and_sign : :review_and_submit), submit_form_url(slug: @submitter.slug, t: SubmissionEvents.build_tracking_param(@submitter, 'click_email'), host: ENV.fetch('EMAIL_HOST', Docuseal.default_url_options[:host])) %>

<%= t('please_contact_us_by_replying_to_this_email_if_you_didn_t_request_this') %>

diff --git a/app/views/templates/_submission.html.erb b/app/views/templates/_submission.html.erb index 5d75a047..473e9114 100644 --- a/app/views/templates/_submission.html.erb +++ b/app/views/templates/_submission.html.erb @@ -2,12 +2,12 @@

- <% elsif !submission.archived_at? && !template.archived_at? && !submission.expired? && !submitter.declined_at? %> + <% elsif !submission.archived_at? && !template&.archived_at? && !submission.expired? && !submitter.declined_at? %> <% if current_user.email == submitter.email %> - <% if !submission.archived_at? && !template.archived_at? && can?(:destroy, submission) %> + <% if !submission.archived_at? && !template&.archived_at? && can?(:destroy, submission) %> <%= button_to button_title(title: nil, disabled_with: t(:archive).first(4), icon: svg_icon('archive', class: 'w-6 h-6')), submission_path(submission), class: 'btn btn-outline btn-sm w-full md:w-fit', form: { class: 'flex' }, title: t('archive'), method: :delete %> @@ -164,7 +164,7 @@ <%= t('download')[..-2] %>... - <% elsif !template.archived_at? && !submission.archived_at? && !is_submission_completed && !submission.expired? && !submitter.declined_at? %> + <% elsif !template&.archived_at? && !submission.archived_at? && !is_submission_completed && !submission.expired? && !submitter.declined_at? %>
<% if current_user.email == submitter.email %> diff --git a/db/migrate/20250527102542_add_name_to_submissions.rb b/db/migrate/20250527102542_add_name_to_submissions.rb new file mode 100644 index 00000000..66166de3 --- /dev/null +++ b/db/migrate/20250527102542_add_name_to_submissions.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddNameToSubmissions < ActiveRecord::Migration[8.0] + def change + add_column :submissions, :name, :text + end +end diff --git a/db/migrate/20250527102550_remove_not_null_template_id.rb b/db/migrate/20250527102550_remove_not_null_template_id.rb new file mode 100644 index 00000000..1ad542bb --- /dev/null +++ b/db/migrate/20250527102550_remove_not_null_template_id.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class RemoveNotNullTemplateId < ActiveRecord::Migration[8.0] + def change + change_column_null :submissions, :template_id, true + end +end diff --git a/db/migrate/20250531085328_remove_completed_submitter_template_not_null.rb b/db/migrate/20250531085328_remove_completed_submitter_template_not_null.rb new file mode 100644 index 00000000..dc52a162 --- /dev/null +++ b/db/migrate/20250531085328_remove_completed_submitter_template_not_null.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class RemoveCompletedSubmitterTemplateNotNull < ActiveRecord::Migration[8.0] + def change + change_column_null :completed_submitters, :template_id, true + end +end diff --git a/db/schema.rb b/db/schema.rb index b024ff66..1e789e2b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_05_30_080846) do +ActiveRecord::Schema[8.0].define(version: 2025_05_31_085328) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -110,7 +110,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_05_30_080846) do t.bigint "submitter_id", null: false t.bigint "submission_id", null: false t.bigint "account_id", null: false - t.bigint "template_id", null: false + t.bigint "template_id" t.string "source", null: false t.integer "sms_count", null: false t.datetime "completed_at", null: false @@ -270,7 +270,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_05_30_080846) do end create_table "submissions", force: :cascade do |t| - t.bigint "template_id", null: false + t.bigint "template_id" t.bigint "created_by_user_id" t.datetime "archived_at" t.datetime "created_at", null: false @@ -284,6 +284,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_05_30_080846) do t.text "preferences", null: false t.bigint "account_id", null: false t.datetime "expire_at" + t.text "name" t.index ["account_id", "id"], name: "index_submissions_on_account_id_and_id" t.index ["created_by_user_id"], name: "index_submissions_on_created_by_user_id" t.index ["slug"], name: "index_submissions_on_slug", unique: true diff --git a/lib/replace_email_variables.rb b/lib/replace_email_variables.rb index 6b3efacd..3cd2d698 100644 --- a/lib/replace_email_variables.rb +++ b/lib/replace_email_variables.rb @@ -2,6 +2,7 @@ module ReplaceEmailVariables TEMPLATE_NAME = /\{+template\.name\}+/i + SUBMISSION_NAME = /\{+submission\.name\}+/i TEMPLATE_ID = /\{+template\.id\}+/i SUBMITTER_LINK = /\{+submitter\.link\}+/i ACCOUNT_NAME = /\{+account\.name\}+/i @@ -31,7 +32,10 @@ module ReplaceEmailVariables # rubocop:disable Metrics def call(text, submitter:, tracking_event_type: 'click_email', html_escape: false, sig: nil) - text = replace(text, TEMPLATE_NAME, html_escape:) { (submitter.template || submitter.submission.template).name } + text = replace(text, TEMPLATE_NAME, html_escape:) do + (submitter.template || submitter.submission.template || submitter.submission).name + end + text = replace(text, SUBMISSION_NAME, html_escape:) { submitter.submission.name } text = replace(text, TEMPLATE_ID, html_escape:) { submitter.template.id } text = replace(text, SUBMITTER_ID, html_escape:) { submitter.id } text = replace(text, SUBMITTER_SLUG, html_escape:) { submitter.slug } diff --git a/lib/submissions.rb b/lib/submissions.rb index 92e715ed..33bbab5c 100644 --- a/lib/submissions.rb +++ b/lib/submissions.rb @@ -21,7 +21,7 @@ module Submissions arel = arel.or(Arel::Table.new(:submitters)[:values].matches(term)) if search_values if search_template - submissions = submissions.joins(:template) + submissions = submissions.left_joins(:template) arel = arel.or(Template.arel_table[:name].lower.matches("%#{keyword.downcase}%")) end @@ -40,15 +40,17 @@ module Submissions def preload_with_pages(submission) ActiveRecord::Associations::Preloader.new( records: [submission], - associations: [:template, { template_schema_documents: :blob }] + associations: [ + submission.template_id? ? { template_schema_documents: :blob } : { documents_attachments: :blob } + ] ).call total_pages = - submission.template_schema_documents.sum { |e| e.metadata.dig('pdf', 'number_of_pages').to_i } + submission.schema_documents.sum { |e| e.metadata.dig('pdf', 'number_of_pages').to_i } if total_pages < PRELOAD_ALL_PAGES_AMOUNT ActiveRecord::Associations::Preloader.new( - records: submission.template_schema_documents, + records: submission.schema_documents, associations: [:blob, { preview_images_attachments: :blob }] ).call end @@ -90,10 +92,10 @@ module Submissions emails end - def create_from_submitters(template:, user:, submissions_attrs:, source:, + def create_from_submitters(template:, user:, submissions_attrs:, source:, with_template: true, submitters_order: DEFAULT_SUBMITTERS_ORDER, params: {}) Submissions::CreateFromSubmitters.call( - template:, user:, submissions_attrs:, source:, submitters_order:, params: + template:, user:, submissions_attrs:, source:, submitters_order:, params:, with_template: ) end diff --git a/lib/submissions/create_from_submitters.rb b/lib/submissions/create_from_submitters.rb index 44adf95e..91997560 100644 --- a/lib/submissions/create_from_submitters.rb +++ b/lib/submissions/create_from_submitters.rb @@ -7,7 +7,7 @@ module Submissions module_function # rubocop:disable Metrics - def call(template:, user:, submissions_attrs:, source:, submitters_order:, params: {}) + def call(template:, user:, submissions_attrs:, source:, submitters_order:, params: {}, with_template: true) preferences = Submitters.normalize_preferences(user.account, user, params) submissions = Array.wrap(submissions_attrs).filter_map do |attrs| @@ -21,6 +21,7 @@ module Submissions submission = template.submissions.new(created_by_user: user, source:, account_id: user.account_id, preferences: set_submission_preferences, + name: with_template ? attrs[:name] : (attrs[:name] || template.name), expire_at:, template_submitters: [], submitters_order:) @@ -60,7 +61,7 @@ module Submissions preferences: preferences.merge(submission_preferences)) end - maybe_set_template_fields(submission, attrs[:submitters]) + maybe_set_template_fields(submission, attrs[:submitters], with_template:) if submission.submitters.size > template.submitters.size raise BaseError, 'Defined more signing parties than in template' @@ -76,6 +77,8 @@ module Submissions maybe_add_invite_submitters(submission, template) + submission.template = nil unless with_template + submission.tap(&:save!) end @@ -118,7 +121,7 @@ module Submissions }.compact_blank end - def maybe_set_template_fields(submission, submitters_attrs, default_submitter_uuid: nil) + def maybe_set_template_fields(submission, submitters_attrs, default_submitter_uuid: nil, with_template: true) template_fields = (submission.template_fields || submission.template.fields).deep_dup submitters = submission.template_submitters || submission.template.submitters @@ -133,7 +136,7 @@ module Submissions end if template_fields != (submission.template_fields || submission.template.fields) || - submitters_attrs.any? { |e| e[:completed].present? } + submitters_attrs.any? { |e| e[:completed].present? } || !with_template submission.template_fields = template_fields submission.template_schema = submission.template.schema if submission.template_schema.blank? end diff --git a/lib/submissions/generate_audit_trail.rb b/lib/submissions/generate_audit_trail.rb index cdd5945a..02c1b02a 100644 --- a/lib/submissions/generate_audit_trail.rb +++ b/lib/submissions/generate_audit_trail.rb @@ -58,7 +58,8 @@ module Submissions ActiveStorage::Attachment.create!( blob: ActiveStorage::Blob.create_and_upload!( - io: io.tap(&:rewind), filename: "#{I18n.t('audit_log')} - #{submission.template.name}.pdf" + io: io.tap(&:rewind), filename: "#{I18n.t('audit_log')} - " \ + "#{submission.name || submission.template.name}.pdf" ), name: 'audit_trail', record: submission @@ -186,7 +187,7 @@ module Submissions last_submitter = submission.submitters.select(&:completed_at).max_by(&:completed_at) documents_data = Submitters.select_attachments_for_download(last_submitter).map do |document| - original_documents = submission.template.documents.select do |e| + original_documents = submission.schema_documents.select do |e| e.uuid == (document.metadata['original_uuid'] || document.uuid) end.presence diff --git a/lib/submissions/generate_combined_attachment.rb b/lib/submissions/generate_combined_attachment.rb index 7cda0b46..4caa2104 100644 --- a/lib/submissions/generate_combined_attachment.rb +++ b/lib/submissions/generate_combined_attachment.rb @@ -32,7 +32,7 @@ module Submissions ActiveStorage::Attachment.create!( blob: ActiveStorage::Blob.create_and_upload!( - io: io.tap(&:rewind), filename: "#{submission.template.name}.pdf" + io: io.tap(&:rewind), filename: "#{submission.name || submission.template.name}.pdf" ), name: 'combined_document', record: submission diff --git a/lib/submissions/generate_preview_attachments.rb b/lib/submissions/generate_preview_attachments.rb index 742f96f4..43fd658d 100644 --- a/lib/submissions/generate_preview_attachments.rb +++ b/lib/submissions/generate_preview_attachments.rb @@ -70,7 +70,7 @@ module Submissions submitter:, uuid: GenerateResultAttachments.images_pdf_uuid(original_documents.select(&:image?)), values_hash:, - name: template.name + name: submission.name || template.name ) ApplicationRecord.no_touching do diff --git a/lib/submissions/generate_result_attachments.rb b/lib/submissions/generate_result_attachments.rb index 7dfdb6d9..4c773d89 100644 --- a/lib/submissions/generate_result_attachments.rb +++ b/lib/submissions/generate_result_attachments.rb @@ -72,17 +72,17 @@ module Submissions pdfs_index = generate_pdfs(submitter) - template = submitter.submission.template account = submitter.account + submission = submitter.submission pkcs = Accounts.load_signing_pkcs(account) tsa_url = Accounts.load_timeserver_url(account) image_pdfs = [] - original_documents = template.documents.preload(:blob) + original_documents = submission.schema_documents.preload(:blob) result_attachments = - submitter.submission.template_schema.filter_map do |item| + submission.template_schema.filter_map do |item| pdf = pdfs_index[item['attachment_uuid']] next if pdf.nil? @@ -114,7 +114,7 @@ module Submissions tsa_url:, pkcs:, uuid: images_pdf_uuid(original_documents.select(&:image?)), - name: template.name + name: submission.name || template.name ) ApplicationRecord.no_touching do @@ -656,14 +656,14 @@ module Submissions Submissions::EnsureResultGenerated.call(latest_submitter) if latest_submitter documents = latest_submitter&.documents&.preload(:blob).to_a.presence - documents ||= submission.template_schema_documents.preload(:blob) + documents ||= submission.schema_documents.preload(:blob) attachment_uuids = Submissions.filtered_conditions_schema(submission).pluck('attachment_uuid') attachments_index = documents.index_by { |a| a.metadata['original_uuid'] || a.uuid } attachment_uuids.each_with_object({}) do |uuid, acc| attachment = attachments_index[uuid] - attachment ||= submission.template_schema_documents.preload(:blob).find { |a| a.uuid == uuid } + attachment ||= submission.schema_documents.preload(:blob).find { |a| a.uuid == uuid } next unless attachment diff --git a/lib/submissions/serialize_for_api.rb b/lib/submissions/serialize_for_api.rb index e32d7b48..e7271699 100644 --- a/lib/submissions/serialize_for_api.rb +++ b/lib/submissions/serialize_for_api.rb @@ -3,7 +3,7 @@ module Submissions module SerializeForApi SERIALIZE_PARAMS = { - only: %i[id slug source submitters_order expire_at created_at updated_at archived_at], + only: %i[id name slug source submitters_order expire_at created_at updated_at archived_at], methods: %i[audit_log_url combined_document_url], include: { submitters: { only: %i[id] }, diff --git a/lib/submitters.rb b/lib/submitters.rb index 32e97720..bb467068 100644 --- a/lib/submitters.rb +++ b/lib/submitters.rb @@ -27,7 +27,7 @@ module Submitters return [submitter.submission.combined_document_attachment] end - original_documents = submitter.submission.template_schema_documents.preload(:blob) + original_documents = submitter.submission.schema_documents.preload(:blob) is_more_than_two_images = original_documents.count(&:image?) > 1 submitter.documents.preload(:blob).reject do |attachment| @@ -36,25 +36,6 @@ module Submitters end end - def preload_with_pages(submitter) - ActiveRecord::Associations::Preloader.new( - records: [submitter], - associations: [submission: [:template, { template_schema_documents: :blob }]] - ).call - - total_pages = - submitter.submission.template_schema_documents.sum { |e| e.metadata.dig('pdf', 'number_of_pages').to_i } - - if total_pages < PRELOAD_ALL_PAGES_AMOUNT - ActiveRecord::Associations::Preloader.new( - records: submitter.submission.template_schema_documents, - associations: [:blob, { preview_images_attachments: :blob }] - ).call - end - - submitter - end - def create_attachment!(submitter, params) blob = if (file = params[:file]) diff --git a/lib/templates.rb b/lib/templates.rb index 35651634..953ef034 100644 --- a/lib/templates.rb +++ b/lib/templates.rb @@ -43,8 +43,8 @@ module Templates templates.where(Template.arel_table[:name].lower.matches("%#{keyword.downcase}%")) end - def filter_undefined_submitters(template) - template.submitters.to_a.select do |item| + def filter_undefined_submitters(template_submitters) + template_submitters.to_a.select do |item| item['invite_by_uuid'].blank? && item['optional_invite_by_uuid'].blank? && item['linked_to_uuid'].blank? && item['is_requester'].blank? && item['email'].blank? end diff --git a/lib/templates/clone_attachments.rb b/lib/templates/clone_attachments.rb index 2cbcb3b3..11484c1f 100644 --- a/lib/templates/clone_attachments.rb +++ b/lib/templates/clone_attachments.rb @@ -4,7 +4,7 @@ module Templates module CloneAttachments module_function - def call(template:, original_template:, documents: [], excluded_attachment_uuids: []) + def call(template:, original_template:, documents: [], excluded_attachment_uuids: [], save: true) schema_uuids_replacements = {} template.schema.each_with_index do |schema_item, index| @@ -29,32 +29,31 @@ module Templates end end - template.save! + attachments = + original_template.schema_documents.filter_map do |document| + new_attachment_uuid = schema_uuids_replacements[document.uuid] - original_template.schema_documents.filter_map do |document| - new_attachment_uuid = schema_uuids_replacements[document.uuid] + next unless new_attachment_uuid - next unless new_attachment_uuid - - new_document = - ApplicationRecord.no_touching do - template.documents_attachments.create!( + new_document = + template.documents_attachments.new( uuid: new_attachment_uuid, blob_id: document.blob_id ) - end - clone_document_preview_images_attachments(document:, new_document:) + clone_document_preview_images_attachments(document:, new_document:) - new_document - end + new_document + end + + template.save! if save + + attachments end def clone_document_preview_images_attachments(document:, new_document:) - ApplicationRecord.no_touching do - document.preview_images_attachments.each do |preview_image| - new_document.preview_images_attachments.create!(blob_id: preview_image.blob_id) - end + document.preview_images_attachments.each do |preview_image| + new_document.preview_images_attachments.new(blob_id: preview_image.blob_id) end end end diff --git a/lib/templates/process_document.rb b/lib/templates/process_document.rb index 1a5e5ae1..77aeaacd 100644 --- a/lib/templates/process_document.rb +++ b/lib/templates/process_document.rb @@ -36,6 +36,24 @@ module Templates attachment end + def process(attachment, data, extract_fields: false) + if attachment.content_type == PDF_CONTENT_TYPE && extract_fields && data.size < MAX_FLATTEN_FILE_SIZE + pdf = HexaPDF::Document.new(io: StringIO.new(data)) + + fields = Templates::FindAcroFields.call(pdf, attachment, data) + end + + pdf ||= HexaPDF::Document.new(io: StringIO.new(data)) + + number_of_pages = pdf.pages.size + + attachment.metadata['pdf'] ||= {} + attachment.metadata['pdf']['number_of_pages'] = number_of_pages + attachment.metadata['pdf']['fields'] = fields if fields + + attachment + end + def generate_preview_image(attachment, data) ActiveStorage::Attachment.where(name: ATTACHMENT_NAME, record: attachment).destroy_all