From 2389c3fc405b36614353c6e5ef1ae0dcb7a4ab72 Mon Sep 17 00:00:00 2001 From: Pete Matsyburka Date: Tue, 11 Jun 2024 18:19:21 +0300 Subject: [PATCH] prefill signature --- app/controllers/submit_form_controller.rb | 5 +++ app/javascript/form.js | 1 + app/javascript/submission_form/form.vue | 7 +++- .../submission_form/signature_step.vue | 2 +- app/models/submitter.rb | 2 + .../submit_form/_submission_form.html.erb | 2 +- app/views/submit_form/show.html.erb | 5 +-- .../maybe_assign_default_signature.rb | 38 +++++++++++++++++++ lib/submitters/submit_values.rb | 35 +++++++++++------ 9 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 lib/submitters/maybe_assign_default_signature.rb diff --git a/app/controllers/submit_form_controller.rb b/app/controllers/submit_form_controller.rb index e4ffa3cf..21de7bac 100644 --- a/app/controllers/submit_form_controller.rb +++ b/app/controllers/submit_form_controller.rb @@ -31,6 +31,11 @@ class SubmitFormController < ApplicationController Submitters::MaybeUpdateDefaultValues.call(@submitter, current_user) + @attachments_index = ActiveStorage::Attachment.where(record: @submitter.submission.submitters, name: :attachments) + .preload(:blob).index_by(&:uuid) + + @signature_attachment = Submitters::MaybeAssignDefaultSignature.call(@submitter, params, @attachments_index) + render(@submitter.submission.template.archived_at? || @submitter.submission.archived_at? ? :archived : :show) end diff --git a/app/javascript/form.js b/app/javascript/form.js index 1f15737b..a63b2846 100644 --- a/app/javascript/form.js +++ b/app/javascript/form.js @@ -15,6 +15,7 @@ safeRegisterElement('submission-form', class extends HTMLElement { this.app = createApp(Form, { submitter: JSON.parse(this.dataset.submitter), canSendEmail: this.dataset.canSendEmail === 'true', + previousSignatureValue: this.dataset.previousSignatureValue, goToLast: this.dataset.goToLast === 'true', isDemo: this.dataset.isDemo === 'true', attribution: this.dataset.attribution !== 'false', diff --git a/app/javascript/submission_form/form.vue b/app/javascript/submission_form/form.vue index 46815f92..2179806e 100644 --- a/app/javascript/submission_form/form.vue +++ b/app/javascript/submission_form/form.vue @@ -321,7 +321,7 @@ :key="currentField.uuid" v-model="values[currentField.uuid]" :field="currentField" - :previous-value="previousSignatureValueFor(currentField)" + :previous-value="previousSignatureValueFor(currentField) || previousSignatureValue" :with-typed-signature="withTypedSignature" :attachments-index="attachmentsIndex" :button-text="buttonText" @@ -609,6 +609,11 @@ export default { required: false, default: '' }, + previousSignatureValue: { + type: String, + required: false, + default: '' + }, allowToSkip: { type: Boolean, required: false, diff --git a/app/javascript/submission_form/signature_step.vue b/app/javascript/submission_form/signature_step.vue index 800669f9..44ce5069 100644 --- a/app/javascript/submission_form/signature_step.vue +++ b/app/javascript/submission_form/signature_step.vue @@ -129,7 +129,7 @@
<% data_fields = (submitter.submission.template_fields || submitter.submission.template.fields).select { |f| f['submitter_uuid'] == submitter.uuid }.to_json %> <% configs = Submitters::FormConfigs.call(submitter) %> - + diff --git a/app/views/submit_form/show.html.erb b/app/views/submit_form/show.html.erb index 7b68b9db..721cf219 100644 --- a/app/views/submit_form/show.html.erb +++ b/app/views/submit_form/show.html.erb @@ -2,7 +2,6 @@ <% 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) } %> -<% attachments_index = ActiveStorage::Attachment.where(record: @submitter.submission.submitters, name: :attachments).preload(:blob).index_by(&:uuid) %> <% page_blob_struct = Struct.new(:url, :metadata, keyword_init: true) %>
@@ -29,7 +28,7 @@ <% next if field['redacted'] && field['submitter_uuid'] != @submitter.uuid %> <% next if value == '{{date}}' && field['submitter_uuid'] != @submitter.uuid %> <% next if field.dig('preferences', 'formula') && field['submitter_uuid'] == @submitter.uuid %> - <%= render 'submissions/value', area:, field:, attachments_index:, value:, locale: @submitter.account.locale, timezone: @submitter.account.timezone %> + <%= render 'submissions/value', area:, field:, attachments_index: @attachments_index, value:, locale: @submitter.account.locale, timezone: @submitter.account.timezone %> <% end %>
@@ -42,7 +41,7 @@ diff --git a/lib/submitters/maybe_assign_default_signature.rb b/lib/submitters/maybe_assign_default_signature.rb new file mode 100644 index 00000000..fa8aaf6a --- /dev/null +++ b/lib/submitters/maybe_assign_default_signature.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Submitters + module MaybeAssignDefaultSignature + module_function + + def call(submitter, params, attachments_index) + return if params[:t].present? && params[:t] != SubmissionEvents.build_tracking_param(submitter, 'click_email') + return if params[:t].blank? && !submitter.submission_events.exists?(event_type: :click_email) + + signature_attachment = find_previous_signature(submitter) + + return if signature_attachment.blank? + + existing_attachment = attachments_index.values.find { |a| a.blob_id == signature_attachment.blob_id } + + return existing_attachment if existing_attachment + + attachment = submitter.attachments_attachments.create!(blob_id: signature_attachment.blob_id) + + attachments_index[attachment.uuid] = attachment + + attachment + end + + def find_previous_signature(submitter) + return if submitter.email.blank? + + submitters_query = + Submitter.where(email: submitter.email) + .where.not(completed_at: nil) + .where(SubmissionEvent.where(Submitter.arel_table[:id].eq(SubmissionEvent.arel_table[:submitter_id])) + .where(event_type: :click_email).limit(1).arel.exists) + + ActiveStorage::Attachment.where(name: :signature, record: submitters_query).order(:id).last + end + end +end diff --git a/lib/submitters/submit_values.rb b/lib/submitters/submit_values.rb index 9068f086..3e4f16a8 100644 --- a/lib/submitters/submit_values.rb +++ b/lib/submitters/submit_values.rb @@ -32,17 +32,7 @@ module Submitters submitter.values.merge!(values) submitter.opened_at ||= Time.current - if params[:completed] == 'true' - submitter.completed_at = Time.current - submitter.ip = request.remote_ip - submitter.ua = request.user_agent - submitter.values = merge_default_values(submitter) - submitter.values = merge_formula_values(submitter) - submitter.values = maybe_remove_condition_values(submitter) - submitter.values = submitter.values.transform_values do |v| - v == '{{date}}' ? Time.current.in_time_zone(submitter.account.timezone).to_date.to_s : v - end - end + assign_completed_attributes(submitter, request) if params[:completed] == 'true' ApplicationRecord.transaction do validate_values!(values, submitter, params, request) @@ -55,6 +45,29 @@ module Submitters submitter end + def assign_completed_attributes(submitter, request) + submitter.completed_at = Time.current + submitter.ip = request.remote_ip + submitter.ua = request.user_agent + submitter.values = merge_default_values(submitter) + submitter.values = merge_formula_values(submitter) + submitter.values = maybe_remove_condition_values(submitter) + submitter.values = submitter.values.transform_values do |v| + v == '{{date}}' ? Time.current.in_time_zone(submitter.account.timezone).to_date.to_s : v + end + + signature_attachment = + submitter.submission.template_fields.reduce(nil) do |_, field| + next nil if field['submitter_uuid'] != submitter.uuid || field['type'] != 'signature' + + break submitter.attachments_attachments.find_by(uuid: submitter.values[field['uuid']]) + end + + submitter.build_signature_attachment(blob_id: signature_attachment.blob_id) if signature_attachment + + submitter + end + def normalized_values(params) params.fetch(:values, {}).to_unsafe_h.transform_values do |v| if params[:cast_boolean] == 'true'