add preserve submitters order option
This commit is contained in:
@@ -26,6 +26,9 @@ Style/Documentation:
|
|||||||
Lint/MissingSuper:
|
Lint/MissingSuper:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
Metrics/ParameterLists:
|
||||||
|
Max: 10
|
||||||
|
|
||||||
Metrics/MethodLength:
|
Metrics/MethodLength:
|
||||||
Max: 25
|
Max: 25
|
||||||
Exclude:
|
Exclude:
|
||||||
|
|||||||
@@ -9,25 +9,26 @@ module Api
|
|||||||
template = current_account.templates.find(params[:template_id])
|
template = current_account.templates.find(params[:template_id])
|
||||||
|
|
||||||
submissions =
|
submissions =
|
||||||
if (params[:emails] || params[:email]).present?
|
if (emails = (params[:emails] || params[:email]).presence)
|
||||||
Submissions.create_from_emails(template:,
|
Submissions.create_from_emails(template:,
|
||||||
user: current_user,
|
user: current_user,
|
||||||
source: :api,
|
source: :api,
|
||||||
mark_as_sent: params[:send_email] != 'false',
|
mark_as_sent: params[:send_email] != 'false',
|
||||||
emails: params[:emails] || params[:email])
|
emails:)
|
||||||
else
|
else
|
||||||
submissions_attrs = normalize_submissions_params!(submissions_params[:submission], template)
|
submissions_attrs = normalize_submissions_params!(submissions_params[:submission], template)
|
||||||
|
|
||||||
Submissions.create_from_submitters(template:,
|
Submissions.create_from_submitters(
|
||||||
user: current_user,
|
template:,
|
||||||
source: :api,
|
user: current_user,
|
||||||
mark_as_sent: params[:send_email] != 'false',
|
source: :api,
|
||||||
submissions_attrs:)
|
mark_as_sent: params[:send_email] != 'false',
|
||||||
|
submitters_order: params[:submitters_order] || 'preserved',
|
||||||
|
submissions_attrs:
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
submitters = submissions.flat_map(&:submitters)
|
Submissions.send_signature_requests(submissions, send_email: params[:send_email] != 'false')
|
||||||
|
|
||||||
Submitters.send_signature_requests(submitters, send_email: params[:send_email] != 'false')
|
|
||||||
|
|
||||||
render json: submitters
|
render json: submitters
|
||||||
rescue UnknownFieldName, UnknownSubmitterName => e
|
rescue UnknownFieldName, UnknownSubmitterName => e
|
||||||
|
|||||||
@@ -26,16 +26,14 @@ class SubmissionsController < ApplicationController
|
|||||||
Submissions.create_from_submitters(template: @template,
|
Submissions.create_from_submitters(template: @template,
|
||||||
user: current_user,
|
user: current_user,
|
||||||
source: :invite,
|
source: :invite,
|
||||||
|
submitters_order: params[:preserve_order] == '1' ? 'preserved' : 'random',
|
||||||
mark_as_sent: params[:send_email] == '1',
|
mark_as_sent: params[:send_email] == '1',
|
||||||
submissions_attrs: submissions_params[:submission].to_h.values)
|
submissions_attrs: submissions_params[:submission].to_h.values)
|
||||||
end
|
end
|
||||||
|
|
||||||
submitters = submissions.flat_map(&:submitters)
|
Submissions.send_signature_requests(submissions, params)
|
||||||
|
|
||||||
Submitters.send_signature_requests(submitters, params)
|
redirect_to template_path(@template), notice: 'New recipients have been added'
|
||||||
|
|
||||||
redirect_to template_path(@template),
|
|
||||||
notice: "#{submitters.size} #{'recipient'.pluralize(submitters.size)} added"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ class ProcessSubmitterCompletionJob < ApplicationJob
|
|||||||
def perform(submitter)
|
def perform(submitter)
|
||||||
is_all_completed = !submitter.submission.submitters.exists?(completed_at: nil)
|
is_all_completed = !submitter.submission.submitters.exists?(completed_at: nil)
|
||||||
|
|
||||||
|
if !is_all_completed && submitter.submission.submitters_order_preserved?
|
||||||
|
enqueue_next_submitter_request_notification(submitter)
|
||||||
|
end
|
||||||
|
|
||||||
Submissions::EnsureResultGenerated.call(submitter)
|
Submissions::EnsureResultGenerated.call(submitter)
|
||||||
|
|
||||||
if submitter.account.encrypted_configs.exists?(key: EncryptedConfig::WEBHOOK_URL_KEY)
|
if submitter.account.encrypted_configs.exists?(key: EncryptedConfig::WEBHOOK_URL_KEY)
|
||||||
@@ -25,8 +29,23 @@ class ProcessSubmitterCompletionJob < ApplicationJob
|
|||||||
SubmitterMailer.completed_email(submitter, user, bcc:).deliver_later!
|
SubmitterMailer.completed_email(submitter, user, bcc:).deliver_later!
|
||||||
end
|
end
|
||||||
|
|
||||||
to = submitter.submission.submitters.order(:completed_at).select(&:email?).map(&:friendly_name).join(', ')
|
to = submitter.submission.submitters.sort_by(&:completed_at).select(&:email?).map(&:friendly_name).join(', ')
|
||||||
|
|
||||||
SubmitterMailer.documents_copy_email(submitter, to:).deliver_later! if to.present?
|
SubmitterMailer.documents_copy_email(submitter, to:).deliver_later! if to.present?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def enqueue_next_submitter_request_notification(submitter)
|
||||||
|
next_submitter_item =
|
||||||
|
submitter.submission.template_submitters.find do |e|
|
||||||
|
sub = submitter.submission.submitters.find { |s| s.uuid == e['uuid'] }
|
||||||
|
|
||||||
|
sub.completed_at.blank? && sub.sent_at.blank?
|
||||||
|
end
|
||||||
|
|
||||||
|
return unless next_submitter_item
|
||||||
|
|
||||||
|
next_submitter = submitter.submission.submitters.find { |s| s.uuid == next_submitter_item['uuid'] }
|
||||||
|
|
||||||
|
Submitters.send_signature_requests([next_submitter], send_email: true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class SendSubmitterInvitationEmailJob < ApplicationJob
|
||||||
|
def perform(submitter)
|
||||||
|
SubmitterMailer.invitation_email(submitter).deliver_now!
|
||||||
|
|
||||||
|
submitter.sent_at ||= Time.current
|
||||||
|
submitter.save
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
# id :bigint not null, primary key
|
# id :bigint not null, primary key
|
||||||
# deleted_at :datetime
|
# deleted_at :datetime
|
||||||
# source :text not null
|
# source :text not null
|
||||||
|
# submitters_order :string not null
|
||||||
# template_fields :text
|
# template_fields :text
|
||||||
# template_schema :text
|
# template_schema :text
|
||||||
# template_submitters :text
|
# template_submitters :text
|
||||||
@@ -37,6 +38,7 @@ class Submission < ApplicationRecord
|
|||||||
serialize :template_submitters, JSON
|
serialize :template_submitters, JSON
|
||||||
|
|
||||||
attribute :source, :string, default: 'link'
|
attribute :source, :string, default: 'link'
|
||||||
|
attribute :submitters_order, :string, default: 'random'
|
||||||
|
|
||||||
has_many :template_schema_documents,
|
has_many :template_schema_documents,
|
||||||
->(e) { where(uuid: (e.template_schema.presence || e.template.schema).pluck('attachment_uuid')) },
|
->(e) { where(uuid: (e.template_schema.presence || e.template.schema).pluck('attachment_uuid')) },
|
||||||
@@ -50,4 +52,9 @@ class Submission < ApplicationRecord
|
|||||||
embed: 'embed',
|
embed: 'embed',
|
||||||
link: 'link'
|
link: 'link'
|
||||||
}, scope: false, prefix: true
|
}, scope: false, prefix: true
|
||||||
|
|
||||||
|
enum :submitters_order, {
|
||||||
|
random: 'random',
|
||||||
|
preserved: 'preserved'
|
||||||
|
}, scope: false, prefix: true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</dynamic-list>
|
</dynamic-list>
|
||||||
<div>
|
<div>
|
||||||
|
<%= render('submitters_order', f:, template:) if Accounts.can_send_emails?(current_account) %>
|
||||||
<%= render 'send_email', f:, template: %>
|
<%= render 'send_email', f:, template: %>
|
||||||
<%= render 'send_sms', f: %>
|
<%= render 'send_sms', f: %>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -35,7 +35,10 @@
|
|||||||
</a>
|
</a>
|
||||||
</dynamic-list>
|
</dynamic-list>
|
||||||
<% end %>
|
<% end %>
|
||||||
<%= render 'send_email', f:, template: %>
|
<div>
|
||||||
|
<%= render 'send_email', f:, template: %>
|
||||||
|
<%= render('submitters_order', f:, template:) if Accounts.can_send_emails?(current_account) %>
|
||||||
|
</div>
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<%= f.button button_title(title: 'Add Recipients'), class: 'base-button' %>
|
<%= f.button button_title(title: 'Add Recipients'), class: 'base-button' %>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</dynamic-list>
|
</dynamic-list>
|
||||||
<%= render 'send_sms', f: %>
|
<%= render 'send_sms', f: %>
|
||||||
|
<%= render('submitters_order', f:, template:) if Accounts.can_send_emails?(current_account) %>
|
||||||
<div class="form-control">
|
<div class="form-control">
|
||||||
<%= f.button button_title(title: 'Add Recipients'), class: 'base-button' %>
|
<%= f.button button_title(title: 'Add Recipients'), class: 'base-button' %>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<% is_smtp_configured = Accounts.can_send_emails?(current_account) %>
|
<% is_smtp_configured = Accounts.can_send_emails?(current_account) %>
|
||||||
<%= f.label :send_email, for: uuid = SecureRandom.uuid, class: 'flex items-center cursor-pointer' do %>
|
<%= f.label :send_email, for: uuid = SecureRandom.uuid, class: 'flex items-center cursor-pointer' do %>
|
||||||
<%= f.check_box :send_email, id: uuid, class: 'base-checkbox', disabled: !is_smtp_configured, checked: is_smtp_configured %>
|
<%= f.check_box :send_email, id: uuid, class: 'base-checkbox', disabled: !is_smtp_configured, checked: is_smtp_configured %>
|
||||||
<span class="label">Send Email</span>
|
<span class="label">Send emails</span>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% unless is_smtp_configured %>
|
<% unless is_smtp_configured %>
|
||||||
<div class="alert my-4">
|
<div class="alert my-4">
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<% if template.submitters.size > 1 %>
|
||||||
|
<div class="form-control">
|
||||||
|
<%= f.label :preserve_order, for: uuid = SecureRandom.uuid, class: 'flex items-center cursor-pointer' do %>
|
||||||
|
<%= f.check_box :preserve_order, id: uuid, class: 'base-checkbox', checked: template.submissions.last&.submitters_order.in?(['preserved', nil]) %>
|
||||||
|
<span class="label">Preserve submitters order</span>
|
||||||
|
<span class="tooltip" data-tip="When checked, notifications will be sent to the second submitter once the form is completed by the previous submitter. Uncheck this option to send notifications to all submitters simultaneously right away.">
|
||||||
|
<%= svg_icon('info_circle', class: 'w-4 h-4') %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddSubmittersOrderToSubmissions < ActiveRecord::Migration[7.0]
|
||||||
|
class MigrationSubmission < ApplicationRecord
|
||||||
|
self.table_name = 'submissions'
|
||||||
|
end
|
||||||
|
|
||||||
|
def change
|
||||||
|
add_column :submissions, :submitters_order, :string
|
||||||
|
|
||||||
|
MigrationSubmission.where(submitters_order: nil).update_all(submitters_order: 'random')
|
||||||
|
|
||||||
|
change_column_null :submissions, :submitters_order, false
|
||||||
|
end
|
||||||
|
end
|
||||||
+2
-1
@@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[7.0].define(version: 2023_09_02_171216) do
|
ActiveRecord::Schema[7.0].define(version: 2023_09_09_213212) do
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
|
||||||
@@ -101,6 +101,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_09_02_171216) do
|
|||||||
t.text "template_schema"
|
t.text "template_schema"
|
||||||
t.text "template_submitters"
|
t.text "template_submitters"
|
||||||
t.text "source", null: false
|
t.text "source", null: false
|
||||||
|
t.string "submitters_order", null: false
|
||||||
t.index ["created_by_user_id"], name: "index_submissions_on_created_by_user_id"
|
t.index ["created_by_user_id"], name: "index_submissions_on_created_by_user_id"
|
||||||
t.index ["template_id"], name: "index_submissions_on_template_id"
|
t.index ["template_id"], name: "index_submissions_on_template_id"
|
||||||
end
|
end
|
||||||
|
|||||||
+28
-8
@@ -1,6 +1,8 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Submissions
|
module Submissions
|
||||||
|
DEFAULT_SUBMITTERS_ORDER = 'random'
|
||||||
|
|
||||||
module_function
|
module_function
|
||||||
|
|
||||||
def update_template_fields!(submission)
|
def update_template_fields!(submission)
|
||||||
@@ -24,9 +26,11 @@ module Submissions
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_from_submitters(template:, user:, submissions_attrs:, source:, mark_as_sent: false)
|
def create_from_submitters(template:, user:, submissions_attrs:, source:, mark_as_sent: false,
|
||||||
|
submitters_order: DEFAULT_SUBMITTERS_ORDER)
|
||||||
submissions_attrs.map do |attrs|
|
submissions_attrs.map do |attrs|
|
||||||
submission = template.submissions.new(created_by_user: user, source:, template_submitters: template.submitters)
|
submission = template.submissions.new(created_by_user: user, source:,
|
||||||
|
template_submitters: template.submitters, submitters_order:)
|
||||||
|
|
||||||
attrs[:submitters].each_with_index do |submitter_attrs, index|
|
attrs[:submitters].each_with_index do |submitter_attrs, index|
|
||||||
uuid =
|
uuid =
|
||||||
@@ -36,15 +40,31 @@ module Submissions
|
|||||||
|
|
||||||
next if uuid.blank?
|
next if uuid.blank?
|
||||||
|
|
||||||
submission.submitters.new(email: submitter_attrs[:email],
|
is_order_sent = submitters_order == 'random' || index.zero?
|
||||||
phone: submitter_attrs[:phone].to_s.gsub(/[^0-9+]/, ''),
|
|
||||||
name: submitter_attrs[:name],
|
submission.submitters.new(
|
||||||
sent_at: mark_as_sent && submitter_attrs[:email].present? ? Time.current : nil,
|
email: submitter_attrs[:email],
|
||||||
values: submitter_attrs[:values] || {},
|
phone: submitter_attrs[:phone].to_s.gsub(/[^0-9+]/, ''),
|
||||||
uuid:)
|
name: submitter_attrs[:name],
|
||||||
|
sent_at: mark_as_sent && submitter_attrs[:email].present? && is_order_sent ? Time.current : nil,
|
||||||
|
values: submitter_attrs[:values] || {},
|
||||||
|
uuid:
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
submission.tap(&:save!)
|
submission.tap(&:save!)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def send_signature_requests(submissions, params)
|
||||||
|
submissions.each do |submission|
|
||||||
|
if submission.submitters_order_preserved?
|
||||||
|
first_submitter = submission.submitters.find { |e| e.uuid == submission.template_submitters.first['uuid'] }
|
||||||
|
|
||||||
|
Submitters.send_signature_requests([first_submitter], params)
|
||||||
|
else
|
||||||
|
Submitters.send_signature_requests(submission.submitters, params)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ module Submitters
|
|||||||
submitters.each do |submitter|
|
submitters.each do |submitter|
|
||||||
next if submitter.email.blank?
|
next if submitter.email.blank?
|
||||||
|
|
||||||
SubmitterMailer.invitation_email(submitter, message: params[:message]).deliver_later!
|
SendSubmitterInvitationEmailJob.perform_later(submitter)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user