add preserve submitters order option

pull/105/head
Alex Turchyn 2 years ago
parent 07e49f9f07
commit 62cea05084

@ -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

@ -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

@ -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

@ -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

Loading…
Cancel
Save