Form Capturing (AOE Modal)
AOE modal architecture, rendering pipeline, field prop preparation, skip logic, and multi-section navigation.
Form Capturing โ AOE Modal
The AOE Modal (AOEModal) is the primary capture interface for Ask at Order Entry forms during the billing workflow. It handles multi-form, multi-section navigation, conditional skip logic, prefilling, confirmation messages, and validation.
6.1 AOE Modal Architecture
Component: src/components/reusable/Billing/components/AOE/AOEModal.tsx
Props:
aoeForms: AOEForm[]โ array of forms to captureoldPatientData: JsonObjectโ existing patient data used for prefillingcloseHandler()โ callback invoked on save/close
Redux State (from GENERIC slice):
activeAOEFormIndexโ which form is currently activeactiveAOEFormSectionIndexโ which section within the active formactiveAOEFormMetaโ computed metadata for the active section:{ process, subprocess, questions, testDetails }
6.2 Form Rendering Pipeline
aoeForms (source data)
โ
โผ
prepareActiveAOEFormDetails()
โ Reads activeAOEFormIndex + activeAOEFormSectionIndex
โ Resolves active form โ active subprocess โ ordered questions
โ
โผ
activeAOEFormMeta: { process, subprocess, questions, testDetails }
โ
โผ
AOEForm component
โ Iterates questions[]
โ
โผ For each question:
โ
โโโ getLabFormInputComponent(type, field_type) โ React Component
โ Priority: Date types โ LabFormDatePicker
โ Signature โ CustomSignature
โ Others โ getInputComponent(field_type) via inputMapper
โ Fallback โ CustomInput
โ
โโโ prepareLabFormFieldProps() โ Full prop object
Includes: type, label, value, onChange, validation, errors
โผ
<InputComponent {...fieldProps} />6.3 Field Prop Preparation
prepareLabFormFieldProps() is the master prop builder that adapts each question's configuration into props for the input component:
| Field Type Family | Special Prop Handling |
|---|---|
| Text / TextArea / Email / Barcode | Standard value, onChange, placeholder, maxLength |
| Number / Float | min, max, step, number validation |
| CheckBox / RadioButton | isChecked computed from stored value, options |
| CheckBoxGroup / RadioGroup / Select | options array, multi-select handling |
| Address | singleLineAddress mode, Google Places integration |
| Date / DateTime / Time | dateFormat, timeFormat, minDate/maxDate from validation attrs |
| File / Upload | S3 presigned URL generation, upload callbacks, allowedFileTypes |
| Signature | Signature pad rendering, S3 upload, bucketPath validation |
| Camera | Webcam capture, S3 upload |
onChange Callback Chain:
6.4 Value Storage
Values live in Redux.GENERIC.aoeFormValues with a nested structure:
aoeFormValues = {
billLevel: {
[processId: number]: {
[questionId: number]: string | any
}
},
testLevel: {
[testId: number]: {
[processId: number]: {
[questionId: number]: string | any
}
}
}
}Determining Level:
testDetails === nullโ bill-level โaoeFormValues.billLevel[processId][questionId]testDetails !== nullโ test-level โaoeFormValues.testLevel[testId][processId][questionId]
6.5 Prefilling
setPrefillingValue() runs on form initialization, iterating all questions:
-
Today's Date Prefill: If
todays_dateattribute istrueโ setsmoment()formatted by the question's date format. -
Source-Based Prefill: If
allow_prefillingistrue:- Reads
prefilling_source(Patient, Bill, Home Collection) - Reads
prefilling_options.source_fieldโ a dot-path (e.g.,"patient.dob") - Traverses the source data using the dot-path to extract the value
- Handles date format conversion if the source value is a date
- Falls back to
default_valueattribute if source value is empty
- Reads
6.6 Skip-To Logic (Conditional Navigation)
The skip-to system allows questions to redirect form navigation based on the answer given.
Configuration (stored as a serialized string in question attributes):
{
"skip_to_conditions": "[{\"value\": \"Yes\", \"skip_type\": \"Process\", \"target_id\": 42}]"
}Skip Types:
| Skip Type | Behavior |
|---|---|
Process | Jump to a specific process (form), removing intermediate forms |
SubProcess | Jump to a specific section, removing intermediate sections |
End Process | End the current form, move to next (or finish) |
Execution Flow:
Data cleanup during skip:
- Intermediate forms removed from
aoeForms - Intermediate sections removed from targeted forms
- Questions below trigger point removed from current section
- All affected values removed from
aoeFormValues
Skip-to navigation physically modifies the aoeForms array in-memory โ removing intermediate forms, sections, and questions. This is a destructive operation on runtime state; it does not affect the persisted configuration.
6.7 Confirmation Messages
When a question has requires_confirmation_message: true and the user enters a value:
afterFieldOnChange()detects the flag- Shows
AOEQuestionValueConfirmationModalwith the configured message (HTML-rendered) - Confirm & Proceed โ continues (triggers skip-to if also configured)
- Cancel โ
removeQuestionValueOnCancelConfirmation()clears the entered value
6.8 Form-Level Validation
Field-Level Validation via labFormQuestionValidatorMapper(field_type, attributes):
| Field Type | Validation |
|---|---|
text, textarea, address, phonenumber | Min/max length |
number | Min/max integer value |
float | Min/max value + max decimal places |
date, datetime | Past/future date constraints |
time | Past/future time constraints |
signature | bucketPath must exist |
| Others | No validation beyond mandatory check |
Form-Level Validation via checkIsValidFormSection() / checkIsAOEFormValid():
- Iterates all questions in the current section (or all forms)
- For each question: checks if mandatory + empty, then runs the type-specific validator
- Returns
falseon first error โ disables the Next/Save button
6.9 Multi-Section / Form Navigation
Navigation Functions:
| Function | Behavior |
|---|---|
goToNextSectionOrForm() | Increment section index. If last section โ increment form index, reset section to 0 |
goToPreviousSectionOrForm() | Decrement section index. If first section โ decrement form index, set section to last of previous form |
isFirstSectionOfFirstForm() | Returns true if at [formIndex=0, sectionIndex=0] โ hides Previous button |
isLastSectionOfLastForm() | Returns true if at last form's last section โ changes Next to "Save & Close" |
Footer Behavior:
- Previous: Hidden on first section of first form
- Next: Calls
handleNextClick(), which validates the current section before navigating - Save & Close: Shown on last section of last form โ calls
closeHandler()
File Reference: src/components/reusable/Billing/components/AOE/utils.ts (1726 lines โ navigation, validation, field props, skip logic, prefilling)