Files
docuseal/app/controllers/api/submitters_controller.rb
T

237 lines
8.9 KiB
Ruby
Raw Normal View History

2023-10-01 01:57:47 +03:00
# frozen_string_literal: true
module Api
class SubmittersController < ApiBaseController
load_and_authorize_resource :submitter
2026-07-01 21:50:12 +03:00
before_action :maybe_return_submitter_error, only: :update
2023-10-18 02:14:44 +03:00
def index
2025-06-05 13:16:55 +03:00
submitters = Submitters.search(current_user, @submitters, params[:q])
2023-10-18 02:14:44 +03:00
2025-04-15 13:22:02 +03:00
submitters = filter_submitters(submitters, params)
2023-10-18 02:14:44 +03:00
submitters = paginate(
submitters.preload(:template, :submission, :submission_events,
documents_attachments: :blob, attachments_attachments: :blob)
)
2025-08-31 16:40:18 +03:00
expires_at = Accounts.link_expires_at(current_account)
2023-10-18 02:14:44 +03:00
render json: {
2024-07-15 12:56:02 +03:00
data: submitters.map do |s|
2025-08-31 16:40:18 +03:00
Submitters::SerializeForApi.call(s, with_template: true, with_events: true, params:, expires_at:)
2024-07-15 12:56:02 +03:00
end,
2023-10-18 02:14:44 +03:00
pagination: {
count: submitters.size,
next: submitters.last&.id,
prev: submitters.first&.id
}
}
end
2023-10-01 01:57:47 +03:00
def show
Submissions::EnsureResultGenerated.call(@submitter) if @submitter.completed_at?
2024-07-15 12:56:02 +03:00
render json: Submitters::SerializeForApi.call(@submitter, with_template: true, with_events: true, params:)
2023-10-01 01:57:47 +03:00
end
2023-12-17 18:39:10 +02:00
2026-02-20 12:27:39 +02:00
# rubocop:disable Metrics/MethodLength
2023-12-17 18:39:10 +02:00
def update
2025-06-11 23:30:40 +03:00
submission = @submitter.submission
role = submission.template_submitters.find { |e| e['uuid'] == @submitter.uuid }['name']
2023-12-17 18:39:10 +02:00
2025-06-11 23:30:40 +03:00
normalized_params, new_attachments = Submissions::NormalizeParamUtils.normalize_submitter_params!(
submitter_params.merge(role:),
@submitter.template || Template.new(submitters: submission.template_submitters, account: @submitter.account),
2026-04-10 15:20:35 +03:00
for_submitter: @submitter,
purpose: :api
2025-06-11 23:30:40 +03:00
)
2023-12-17 18:39:10 +02:00
2025-06-11 23:30:40 +03:00
Submissions::CreateFromSubmitters.maybe_set_template_fields(submission, [normalized_params],
default_submitter_uuid: @submitter.uuid)
2023-12-17 18:39:10 +02:00
assign_submitter_attrs(@submitter, normalized_params)
ApplicationRecord.transaction do
Submissions::NormalizeParamUtils.save_default_value_attachments!(new_attachments, [@submitter])
@submitter.save!
@submitter.submission.save!
2024-02-10 19:38:03 +02:00
2026-02-20 12:27:39 +02:00
if @submitter.completed_at?
Submitters::SubmitValues.maybe_invite_via_field(@submitter, request)
SubmissionEvents.create_with_tracking_data(@submitter, 'api_complete_form', request)
end
2023-12-17 18:39:10 +02:00
end
if @submitter.completed_at?
2026-07-01 18:10:08 +03:00
is_last = Submissions.maybe_update_completed_at(@submitter.submission)
ProcessSubmitterCompletionJob.perform_async('submitter_id' => @submitter.id, 'is_last' => is_last)
2023-12-17 18:39:10 +02:00
elsif normalized_params[:send_email] || normalized_params[:send_sms]
Submitters.send_signature_requests([@submitter])
end
2025-06-05 13:16:55 +03:00
SearchEntries.enqueue_reindex(@submitter)
2025-06-11 23:30:40 +03:00
render json: Submitters::SerializeForApi.call(@submitter, with_template: false, with_urls: true,
with_events: false, params:)
2024-09-07 01:30:34 +03:00
rescue Submitters::NormalizeValues::BaseError, DownloadUtils::UnableToDownload => e
2024-08-22 13:53:54 +03:00
Rollbar.warning(e) if defined?(Rollbar)
2025-08-14 09:25:35 +03:00
render json: { error: e.message }, status: :unprocessable_content
2023-12-17 18:39:10 +02:00
end
2026-02-20 12:27:39 +02:00
# rubocop:enable Metrics/MethodLength
2023-12-17 18:39:10 +02:00
def submitter_params
submitter_params = params.key?(:submitter) ? params.require(:submitter) : params
submitter_params.permit(
2024-04-08 10:51:18 +03:00
:send_email, :send_sms, :reply_to, :completed_redirect_url, :uuid, :name, :email, :role,
2025-12-09 11:46:57 +02:00
:completed, :phone, :application_key, :external_id, :go_to_last, :require_phone_2fa, :require_email_2fa,
2024-02-01 23:29:27 +02:00
{ metadata: {}, values: {}, readonly_fields: [], message: %i[subject body],
2025-06-10 11:26:12 +03:00
fields: [[:name, :uuid, :default_value, :value, :required,
2024-09-10 13:09:46 +03:00
:readonly, :validation_pattern, :invalid_message,
2024-06-09 20:25:19 +03:00
{ default_value: [], value: [], preferences: {} }]] }
2023-12-17 18:39:10 +02:00
)
end
private
2026-07-01 21:50:12 +03:00
def maybe_return_submitter_error
2026-07-09 11:40:55 +03:00
if @submitter.completed_at? || @submitter.submission.completed_at?
2026-07-01 21:50:12 +03:00
return render json: { error: 'Submitter has already completed the submission.' }, status: :unprocessable_content
end
return unless @submitter.declined_at?
render json: { error: 'Submitter has already declined the submission.' }, status: :unprocessable_content
end
2026-06-27 11:40:02 +03:00
def maybe_filter_by_completed_at(submitters, params)
2024-03-06 18:44:13 +02:00
if params[:completed_after].present?
submitters = submitters.where(completed_at: Time.zone.parse(params[:completed_after])..)
end
if params[:completed_before].present?
submitters = submitters.where(completed_at: ..Time.zone.parse(params[:completed_before]))
end
submitters
end
2023-12-17 18:39:10 +02:00
def assign_submitter_attrs(submitter, attrs)
2024-04-28 21:43:51 +03:00
values = attrs[:values]&.to_unsafe_h || {}
assign_submission_fields(submitter.submission)
phone_field_uuid = submitter.submission.template_fields.find do |f|
values[f['uuid']].present? && f['type'] == 'phone'
end&.dig('uuid')
2023-12-17 18:39:10 +02:00
submitter.email = Submissions.normalize_email(attrs[:email]) if attrs.key?(:email)
2024-10-23 10:44:55 +03:00
submitter.name = attrs[:name] if attrs.key?(:name)
2024-04-28 21:43:51 +03:00
if attrs.key?(:phone)
submitter.phone = attrs[:phone].to_s.gsub(/[^0-9+]/, '')
elsif values[phone_field_uuid].present?
submitter.phone = values[phone_field_uuid].to_s.gsub(/[^0-9+]/, '')
end
values = values.except(phone_field_uuid)
submitter.values = submitter.values.merge(values) if values.present?
2024-02-01 23:29:27 +02:00
submitter.metadata = attrs[:metadata] if attrs.key?(:metadata)
2023-12-17 18:39:10 +02:00
2024-06-13 22:57:29 +03:00
maybe_assign_completed_attributes(submitter, attrs)
2024-04-28 21:43:51 +03:00
assign_external_id(submitter, attrs)
2023-12-17 18:39:10 +02:00
assign_preferences(submitter, attrs)
submitter
end
2024-06-13 22:57:29 +03:00
def maybe_assign_completed_attributes(submitter, attrs)
submitter.completed_at = attrs[:completed] ? Time.current : submitter.completed_at
if attrs[:completed]
submitter.values = Submitters::SubmitValues.merge_default_values(submitter)
submitter.values = Submitters::SubmitValues.maybe_remove_condition_values(submitter)
2025-02-20 11:59:29 +02:00
formula_values = Submitters::SubmitValues.build_formula_values(submitter)
if formula_values.present?
submitter.values = submitter.values.merge(formula_values)
submitter.values = Submitters::SubmitValues.maybe_remove_condition_values(submitter)
end
2026-04-23 20:25:41 +03:00
submitter.values = Submitters::SubmitValues.replace_current_date_placeholders(submitter)
2024-06-13 22:57:29 +03:00
end
submitter
end
2025-04-15 13:22:02 +03:00
def filter_submitters(submitters, params)
submitters = submitters.where(external_id: params[:application_key]) if params[:application_key].present?
submitters = submitters.where(external_id: params[:external_id]) if params[:external_id].present?
submitters = submitters.where(slug: params[:slug]) if params[:slug].present?
submitters = submitters.where(submission_id: params[:submission_id]) if params[:submission_id].present?
if params[:template_id].present?
2025-05-12 15:38:13 +03:00
submitters = submitters.joins(:submission).where(submissions: { template_id: params[:template_id] })
2025-04-15 13:22:02 +03:00
end
2026-06-27 11:40:02 +03:00
maybe_filter_by_completed_at(submitters, params)
2025-04-15 13:22:02 +03:00
end
2024-04-28 21:43:51 +03:00
def assign_external_id(submitter, attrs)
submitter.external_id = attrs[:application_key] if attrs.key?(:application_key)
submitter.external_id = attrs[:external_id] if attrs.key?(:external_id)
submitter
end
2023-12-28 21:18:23 +02:00
def assign_submission_fields(submission)
submission.template_fields ||= submission.template.fields
submission.template_schema ||= submission.template.schema
end
2023-12-17 18:39:10 +02:00
def assign_preferences(submitter, attrs)
submitter_preferences = Submitters.normalize_preferences(submitter.account, current_user, attrs)
2023-12-29 18:54:48 +02:00
submitter.preferences['default_values'] = attrs[:values].to_unsafe_h if attrs[:values].present?
2023-12-17 18:39:10 +02:00
if submitter_preferences.key?('send_email')
submitter.preferences['send_email'] = submitter_preferences['send_email']
end
submitter.preferences['send_sms'] = submitter_preferences['send_sms'] if submitter_preferences.key?('send_sms')
2024-04-08 10:51:18 +03:00
submitter.preferences['reply_to'] = submitter_preferences['reply_to'] if submitter_preferences.key?('reply_to')
2026-04-27 12:21:23 +03:00
2025-06-28 10:37:10 +03:00
if submitter_preferences.key?('require_phone_2fa')
submitter.preferences['require_phone_2fa'] = submitter_preferences['require_phone_2fa']
end
2026-04-27 12:21:23 +03:00
if submitter_preferences.key?('require_email_2fa')
submitter.preferences['require_email_2fa'] = submitter_preferences['require_email_2fa']
end
2024-04-13 15:33:05 +03:00
if submitter_preferences.key?('go_to_last')
submitter.preferences['go_to_last'] = submitter_preferences['go_to_last']
end
2024-04-08 10:51:18 +03:00
if submitter_preferences.key?('completed_redirect_url')
submitter.preferences['completed_redirect_url'] = submitter_preferences['completed_redirect_url']
end
2023-12-17 18:39:10 +02:00
return unless submitter_preferences.key?('email_message_uuid')
submitter.preferences['email_message_uuid'] = submitter_preferences['email_message_uuid']
submitter
end
2023-10-01 01:57:47 +03:00
end
end