improve required field handling

pull/475/head
Pete Matsyburka 7 months ago
parent f1a2b71b59
commit 28e3d65e63

@ -72,6 +72,10 @@ class SubmitFormController < ApplicationController
Submitters::SubmitValues.call(submitter, params, request) Submitters::SubmitValues.call(submitter, params, request)
head :ok head :ok
rescue Submitters::SubmitValues::RequiredFieldError => e
Rollbar.warning("Required field #{submitter.id}: #{e.message}") if defined?(Rollbar)
render json: { field_uuid: e.message }, status: :unprocessable_entity
rescue Submitters::SubmitValues::ValidationError => e rescue Submitters::SubmitValues::ValidationError => e
render json: { error: e.message }, status: :unprocessable_entity render json: { error: e.message }, status: :unprocessable_entity
end end

@ -1404,7 +1404,13 @@ export default {
if (response.status === 422 || response.status === 500) { if (response.status === 422 || response.status === 500) {
const data = await response.json() const data = await response.json()
if (data.error) { if (data.field_uuid) {
const field = this.fieldsUuidIndex[data.field_uuid]
this.goToStep(this.stepFields.findIndex((fields) => fields.includes(field)), this.autoscrollFields)
this.showFillAllRequiredFields = true
} else if (data.error) {
const i18nKey = data.error.replace(/\s+/g, '_').toLowerCase() const i18nKey = data.error.replace(/\s+/g, '_').toLowerCase()
alert(this.t(i18nKey) !== i18nKey ? this.t(i18nKey) : data.error) alert(this.t(i18nKey) !== i18nKey ? this.t(i18nKey) : data.error)

@ -3,6 +3,7 @@
module Submitters module Submitters
module SubmitValues module SubmitValues
ValidationError = Class.new(StandardError) ValidationError = Class.new(StandardError)
RequiredFieldError = Class.new(StandardError)
VARIABLE_REGEXP = /\{\{?(\w+)\}\}?/ VARIABLE_REGEXP = /\{\{?(\w+)\}\}?/
@ -55,19 +56,26 @@ module Submitters
submitter.ua = request.user_agent submitter.ua = request.user_agent
submitter.values = merge_default_values(submitter) submitter.values = merge_default_values(submitter)
submitter.values = maybe_remove_condition_values(submitter)
required_field_uuids_acc = Set.new
submitter.values = maybe_remove_condition_values(submitter, required_field_uuids_acc:)
formula_values = build_formula_values(submitter) formula_values = build_formula_values(submitter)
if formula_values.present? if formula_values.present?
submitter.values = submitter.values.merge(formula_values) submitter.values = submitter.values.merge(formula_values)
submitter.values = maybe_remove_condition_values(submitter) submitter.values = maybe_remove_condition_values(submitter, required_field_uuids_acc:)
end end
submitter.values = submitter.values.transform_values do |v| submitter.values = submitter.values.transform_values do |v|
v == '{{date}}' ? Time.current.in_time_zone(submitter.account.timezone).to_date.to_s : v v == '{{date}}' ? Time.current.in_time_zone(submitter.account.timezone).to_date.to_s : v
end end
required_field_uuids_acc.each do |uuid|
raise RequiredFieldError, uuid if submitter.values[uuid].blank?
end
submitter submitter
end end
@ -188,37 +196,59 @@ module Submitters
with_time:) with_time:)
end end
def maybe_remove_condition_values(submitter) def maybe_remove_condition_values(submitter, required_field_uuids_acc: nil)
fields_uuid_index = submitter.submission.template_fields.index_by { |e| e['uuid'] } fields_uuid_index = submitter.submission.template_fields.index_by { |e| e['uuid'] }
submitters_values = nil
has_other_submitters = submitter.submission.template_submitters.size > 1
has_document_conditions = submitter.submission.template_schema.any? { |e| e['conditions'].present? }
attachments_index = attachments_index =
if has_document_conditions
Submissions.filtered_conditions_schema(submitter.submission).index_by { |i| i['attachment_uuid'] } Submissions.filtered_conditions_schema(submitter.submission).index_by { |i| i['attachment_uuid'] }
end
submitter_values = nil
is_other_submitter_conditions = submitter.submission.template_submitters.size > 1
submitter.submission.template_fields.each do |field| submitter.submission.template_fields.each do |field|
next if field['submitter_uuid'] != submitter.uuid next if field['submitter_uuid'] != submitter.uuid
submitter_values ||= submitter.values required_field_uuids_acc.add(field['uuid']) if required_field_uuids_acc && required_editable_field?(field)
is_other_submitter_conditions &&= field_conditions_other_submitter?(submitter, field, fields_uuid_index) if has_document_conditions && check_field_areas_attachments(field, attachments_index)
submitter.values.delete(field['uuid'])
if is_other_submitter_conditions required_field_uuids_acc.delete(field['uuid'])
submitter_values = submitter.submission.submitters.reduce({}) { |acc, sub| acc.merge(sub.values) }
end end
submitter.values.delete(field['uuid']) unless check_field_conditions(submitter_values, field, fields_uuid_index) if has_other_submitters && !submitters_values &&
field_conditions_other_submitter?(submitter, field, fields_uuid_index)
submitters_values = merge_submitters_values(submitter)
end
if field['areas'].present? && field['areas'].none? { |area| attachments_index[area['attachment_uuid']] } unless check_field_conditions(submitters_values || submitter.values, field, fields_uuid_index)
submitter.values.delete(field['uuid']) submitter.values.delete(field['uuid'])
required_field_uuids_acc.delete(field['uuid'])
end end
end end
submitter.values submitter.values
end end
def required_editable_field?(field)
field['required'].present? && field['readonly'].blank?
end
def check_field_areas_attachments(field, attachments_index)
field['areas'].present? && field['areas'].none? { |area| attachments_index[area['attachment_uuid']] }
end
def merge_submitters_values(submitter)
submitter.submission.submitters
.reduce({}) { |acc, sub| acc.merge(sub.values) }
.merge(submitter.values)
end
def field_conditions_other_submitter?(submitter, field, fields_uuid_index) def field_conditions_other_submitter?(submitter, field, fields_uuid_index)
return false if field['conditions'].blank?
field['conditions'].to_a.any? do |c| field['conditions'].to_a.any? do |c|
fields_uuid_index.dig(c['field_uuid'], 'submitter_uuid') != submitter.uuid fields_uuid_index.dig(c['field_uuid'], 'submitter_uuid') != submitter.uuid
end end

Loading…
Cancel
Save