add submitter update endpoint
This commit is contained in:
@@ -85,7 +85,8 @@ module Api
|
|||||||
emails:,
|
emails:,
|
||||||
params:)
|
params:)
|
||||||
else
|
else
|
||||||
submissions_attrs, attachments = normalize_submissions_params!(submissions_params, template)
|
submissions_attrs, attachments =
|
||||||
|
Submissions::NormalizeParamUtils.normalize_submissions_params!(submissions_params, template)
|
||||||
|
|
||||||
submissions = Submissions.create_from_submitters(
|
submissions = Submissions.create_from_submitters(
|
||||||
template:,
|
template:,
|
||||||
@@ -97,7 +98,8 @@ module Api
|
|||||||
params:
|
params:
|
||||||
)
|
)
|
||||||
|
|
||||||
save_default_value_attachments!(attachments, submissions.flat_map(&:submitters))
|
Submissions::NormalizeParamUtils.save_default_value_attachments!(attachments,
|
||||||
|
submissions.flat_map(&:submitters))
|
||||||
|
|
||||||
submissions
|
submissions
|
||||||
end
|
end
|
||||||
@@ -133,49 +135,5 @@ module Api
|
|||||||
]
|
]
|
||||||
).fetch(key, [])
|
).fetch(key, [])
|
||||||
end
|
end
|
||||||
|
|
||||||
def normalize_submissions_params!(submissions_params, template)
|
|
||||||
attachments = []
|
|
||||||
|
|
||||||
Array.wrap(submissions_params).each do |submission|
|
|
||||||
submission[:submitters].each_with_index do |submitter, index|
|
|
||||||
default_values = submitter[:values] || {}
|
|
||||||
|
|
||||||
submitter[:fields]&.each { |f| default_values[f[:name]] = f[:default_value] if f[:default_value].present? }
|
|
||||||
|
|
||||||
next if default_values.blank?
|
|
||||||
|
|
||||||
values, new_attachments =
|
|
||||||
Submitters::NormalizeValues.call(template,
|
|
||||||
default_values,
|
|
||||||
submitter[:role] || template.submitters[index]['name'],
|
|
||||||
throw_errors: true)
|
|
||||||
|
|
||||||
attachments.push(*new_attachments)
|
|
||||||
|
|
||||||
submitter[:values] = values
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
[submissions_params, attachments]
|
|
||||||
end
|
|
||||||
|
|
||||||
def save_default_value_attachments!(attachments, submitters)
|
|
||||||
return if attachments.blank?
|
|
||||||
|
|
||||||
attachments_index = attachments.index_by(&:uuid)
|
|
||||||
|
|
||||||
submitters.each do |submitter|
|
|
||||||
submitter.values.to_a.each do |_, value|
|
|
||||||
attachment = attachments_index[value]
|
|
||||||
|
|
||||||
next unless attachment
|
|
||||||
|
|
||||||
attachment.record = submitter
|
|
||||||
|
|
||||||
attachment.save!
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -30,5 +30,79 @@ module Api
|
|||||||
|
|
||||||
render json: Submitters::SerializeForApi.call(@submitter, with_template: true, with_events: true)
|
render json: Submitters::SerializeForApi.call(@submitter, with_template: true, with_events: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @submitter.completed_at?
|
||||||
|
return render json: { error: 'Submitter has already completed the submission.' }, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
|
||||||
|
role = @submitter.submission.template_submitters.find { |e| e['uuid'] == @submitter.uuid }['name']
|
||||||
|
|
||||||
|
normalized_params, new_attachments =
|
||||||
|
Submissions::NormalizeParamUtils.normalize_submitter_params!(submitter_params.merge(role:), @submitter.template,
|
||||||
|
for_submitter: @submitter)
|
||||||
|
|
||||||
|
Submissions::CreateFromSubmitters.maybe_set_template_fields(@submitter.submission,
|
||||||
|
[normalized_params],
|
||||||
|
submitter_uuid: @submitter.uuid)
|
||||||
|
|
||||||
|
assign_submitter_attrs(@submitter, normalized_params)
|
||||||
|
|
||||||
|
ApplicationRecord.transaction do
|
||||||
|
Submissions::NormalizeParamUtils.save_default_value_attachments!(new_attachments, [@submitter])
|
||||||
|
|
||||||
|
@submitter.save!
|
||||||
|
|
||||||
|
@submitter.submission.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
if @submitter.completed_at?
|
||||||
|
ProcessSubmitterCompletionJob.perform_later(@submitter)
|
||||||
|
elsif normalized_params[:send_email] || normalized_params[:send_sms]
|
||||||
|
Submitters.send_signature_requests([@submitter])
|
||||||
|
end
|
||||||
|
|
||||||
|
render json: Submitters::SerializeForApi.call(@submitter, with_template: false, with_events: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
def submitter_params
|
||||||
|
submitter_params = params.key?(:submitter) ? params.require(:submitter) : params
|
||||||
|
|
||||||
|
submitter_params.permit(
|
||||||
|
:send_email, :send_sms, :uuid, :name, :email, :role, :completed, :phone, :application_key,
|
||||||
|
{ values: {}, readonly_fields: [], message: %i[subject body],
|
||||||
|
fields: [%i[name default_value readonly validation_pattern invalid_message]] }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def assign_submitter_attrs(submitter, attrs)
|
||||||
|
submitter.email = Submissions.normalize_email(attrs[:email]) if attrs.key?(:email)
|
||||||
|
submitter.phone = attrs[:phone].to_s.gsub(/[^0-9+]/, '') if attrs.key?(:phone)
|
||||||
|
submitter.values = submitter.values.merge(attrs[:values].to_unsafe_h) if attrs[:values]
|
||||||
|
submitter.completed_at = attrs[:completed] ? Time.current : submitter.completed_at
|
||||||
|
submitter.application_key = attrs[:application_key] if attrs.key?(:application_key)
|
||||||
|
|
||||||
|
assign_preferences(submitter, attrs)
|
||||||
|
|
||||||
|
submitter
|
||||||
|
end
|
||||||
|
|
||||||
|
def assign_preferences(submitter, attrs)
|
||||||
|
submitter_preferences = Submitters.normalize_preferences(submitter.account, current_user, attrs)
|
||||||
|
|
||||||
|
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')
|
||||||
|
|
||||||
|
return unless submitter_preferences.key?('email_message_uuid')
|
||||||
|
|
||||||
|
submitter.preferences['email_message_uuid'] = submitter_preferences['email_message_uuid']
|
||||||
|
|
||||||
|
submitter
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+1
-1
@@ -35,7 +35,7 @@ Rails.application.routes.draw do
|
|||||||
resources :template_folders_autocomplete, only: %i[index]
|
resources :template_folders_autocomplete, only: %i[index]
|
||||||
resources :submitter_email_clicks, only: %i[create]
|
resources :submitter_email_clicks, only: %i[create]
|
||||||
resources :submitter_form_views, only: %i[create]
|
resources :submitter_form_views, only: %i[create]
|
||||||
resources :submitters, only: %i[index show]
|
resources :submitters, only: %i[index show update]
|
||||||
resources :submissions, only: %i[index show create destroy] do
|
resources :submissions, only: %i[index show create destroy] do
|
||||||
collection do
|
collection do
|
||||||
resources :emails, only: %i[create], controller: 'submissions', as: :submissions_emails
|
resources :emails, only: %i[create], controller: 'submissions', as: :submissions_emails
|
||||||
|
|||||||
@@ -39,11 +39,11 @@ module Submissions
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def maybe_set_template_fields(submission, submitters_attrs)
|
def maybe_set_template_fields(submission, submitters_attrs, submitter_uuid: nil)
|
||||||
template_fields = submission.template.fields.deep_dup
|
template_fields = (submission.template_fields || submission.template.fields).deep_dup
|
||||||
|
|
||||||
submitters_attrs.each_with_index do |submitter_attrs, index|
|
submitters_attrs.each_with_index do |submitter_attrs, index|
|
||||||
submitter_uuid = find_submitter_uuid(submission.template, submitter_attrs, index)
|
submitter_uuid ||= find_submitter_uuid(submission.template, submitter_attrs, index)
|
||||||
|
|
||||||
process_readonly_fields_param(submitter_attrs[:readonly_fields], template_fields, submitter_uuid)
|
process_readonly_fields_param(submitter_attrs[:readonly_fields], template_fields, submitter_uuid)
|
||||||
|
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ module Submissions
|
|||||||
Submissions::EnsureResultGenerated.call(latest_submitter) if latest_submitter
|
Submissions::EnsureResultGenerated.call(latest_submitter) if latest_submitter
|
||||||
|
|
||||||
documents = latest_submitter&.documents&.preload(:blob).to_a.presence
|
documents = latest_submitter&.documents&.preload(:blob).to_a.presence
|
||||||
documents ||= submitter.submission.template.documents.preload(:blob)
|
documents ||= submitter.submission.template.schema_documents.preload(:blob)
|
||||||
|
|
||||||
documents.to_h do |attachment|
|
documents.to_h do |attachment|
|
||||||
pdf =
|
pdf =
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Submissions
|
||||||
|
module NormalizeParamUtils
|
||||||
|
module_function
|
||||||
|
|
||||||
|
def normalize_submissions_params!(submissions_params, template)
|
||||||
|
attachments = []
|
||||||
|
|
||||||
|
Array.wrap(submissions_params).each do |submission|
|
||||||
|
submission[:submitters].each_with_index do |submitter, index|
|
||||||
|
_, new_attachments = normalize_submitter_params!(submitter, template, index)
|
||||||
|
|
||||||
|
attachments.push(*new_attachments)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
[submissions_params, attachments]
|
||||||
|
end
|
||||||
|
|
||||||
|
def normalize_submitter_params!(submitter_params, template, index = nil, for_submitter: nil)
|
||||||
|
default_values = submitter_params[:values] || {}
|
||||||
|
|
||||||
|
submitter_params[:fields]&.each do |f|
|
||||||
|
default_values[f[:name]] = f[:default_value] if f[:default_value].present?
|
||||||
|
end
|
||||||
|
|
||||||
|
return submitter_params if default_values.blank?
|
||||||
|
|
||||||
|
values, new_attachments =
|
||||||
|
Submitters::NormalizeValues.call(template,
|
||||||
|
default_values,
|
||||||
|
submitter_name: submitter_params[:role] ||
|
||||||
|
template.submitters.dig(index, 'name'),
|
||||||
|
for_submitter:,
|
||||||
|
throw_errors: true)
|
||||||
|
|
||||||
|
submitter_params[:values] = values
|
||||||
|
|
||||||
|
[submitter_params, new_attachments]
|
||||||
|
end
|
||||||
|
|
||||||
|
def save_default_value_attachments!(attachments, submitters)
|
||||||
|
return if attachments.blank?
|
||||||
|
|
||||||
|
attachments_index = attachments.index_by(&:uuid)
|
||||||
|
|
||||||
|
submitters.each do |submitter|
|
||||||
|
submitter.values.to_a.each do |_, value|
|
||||||
|
attachment = attachments_index[value]
|
||||||
|
|
||||||
|
next unless attachment
|
||||||
|
|
||||||
|
attachment.record = submitter
|
||||||
|
|
||||||
|
attachment.save!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -9,12 +9,8 @@ module Submitters
|
|||||||
|
|
||||||
module_function
|
module_function
|
||||||
|
|
||||||
def call(template, values, submitter_name, throw_errors: false)
|
def call(template, values, submitter_name: nil, for_submitter: nil, throw_errors: false)
|
||||||
submitter =
|
fields = fetch_fields(template, submitter_name:, for_submitter:)
|
||||||
template.submitters.find { |e| e['name'] == submitter_name } ||
|
|
||||||
raise(UnknownSubmitterName, "Unknown submitter: #{submitter_name}")
|
|
||||||
|
|
||||||
fields = template.fields.select { |e| e['submitter_uuid'] == submitter['uuid'] }
|
|
||||||
|
|
||||||
fields_uuid_index = fields.index_by { |e| e['uuid'] }
|
fields_uuid_index = fields.index_by { |e| e['uuid'] }
|
||||||
fields_name_index = build_fields_index(fields)
|
fields_name_index = build_fields_index(fields)
|
||||||
@@ -31,7 +27,7 @@ module Submitters
|
|||||||
next if key.blank?
|
next if key.blank?
|
||||||
|
|
||||||
if fields_uuid_index[key]['type'].in?(%w[initials signature image file])
|
if fields_uuid_index[key]['type'].in?(%w[initials signature image file])
|
||||||
new_value, new_attachments = normalize_attachment_value(value, template.account)
|
new_value, new_attachments = normalize_attachment_value(value, template.account, for_submitter)
|
||||||
|
|
||||||
attachments.push(*new_attachments)
|
attachments.push(*new_attachments)
|
||||||
|
|
||||||
@@ -44,27 +40,45 @@ module Submitters
|
|||||||
[normalized_values, attachments]
|
[normalized_values, attachments]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fetch_fields(template, submitter_name: nil, for_submitter: nil)
|
||||||
|
if submitter_name
|
||||||
|
submitter =
|
||||||
|
template.submitters.find { |e| e['name'] == submitter_name } ||
|
||||||
|
raise(UnknownSubmitterName, "Unknown submitter: #{submitter_name}")
|
||||||
|
end
|
||||||
|
|
||||||
|
fields = for_submitter&.submission&.template_fields || template.fields
|
||||||
|
|
||||||
|
fields.select { |e| e['submitter_uuid'] == (for_submitter&.uuid || submitter['uuid']) }
|
||||||
|
end
|
||||||
|
|
||||||
def build_fields_index(fields)
|
def build_fields_index(fields)
|
||||||
fields.index_by { |e| e['name'] }.merge(fields.index_by { |e| e['name'].to_s.parameterize.underscore })
|
fields.index_by { |e| e['name'] }.merge(fields.index_by { |e| e['name'].to_s.parameterize.underscore })
|
||||||
end
|
end
|
||||||
|
|
||||||
def normalize_attachment_value(value, account)
|
def normalize_attachment_value(value, account, for_submitter = nil)
|
||||||
if value.is_a?(Array)
|
if value.is_a?(Array)
|
||||||
new_attachments = value.map { |v| build_attachment(v, account) }
|
new_attachments = value.map { |v| find_or_build_attachment(v, account, for_submitter) }
|
||||||
|
|
||||||
[new_attachments.map(&:uuid), new_attachments]
|
[new_attachments.map(&:uuid), new_attachments]
|
||||||
else
|
else
|
||||||
new_attachment = build_attachment(value, account)
|
new_attachment = find_or_build_attachment(value, account, for_submitter)
|
||||||
|
|
||||||
[new_attachment.uuid, new_attachment]
|
[new_attachment.uuid, new_attachment]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_attachment(value, account)
|
def find_or_build_attachment(value, account, for_submitter = nil)
|
||||||
ActiveStorage::Attachment.new(
|
blob = find_or_create_blobs(account, value)
|
||||||
blob: find_or_create_blobs(account, value),
|
|
||||||
|
attachment = for_submitter.attachments.find_by(blob_id: blob.id) if for_submitter
|
||||||
|
|
||||||
|
attachment ||= ActiveStorage::Attachment.new(
|
||||||
|
blob:,
|
||||||
name: 'attachments'
|
name: 'attachments'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
attachment
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_or_create_blobs(account, url)
|
def find_or_create_blobs(account, url)
|
||||||
|
|||||||
Reference in New Issue
Block a user