Enforcing Mandatory Field Validation for Signature Controlled Items via Backend (LiveOrder Model)

Overview

In SuiteCommerce, certain items classified as “Controlled : Signature Controlled” require prescriber information before an order can be submitted. While frontend validation handles this in most cases, there are edge scenarios—such as multi-tab cart updates—where frontend checks may be bypassed. This article outlines a backend validation strategy using the LiveOrder.Model to ensure data integrity and compliance.

Scenario: Multi-Tab Cart Update Bypasses Frontend Validation

  1. A user adds a non-signature-controlled item to the cart and proceeds to the Checkout Review Page.
  2. In a new browser tab, the user adds a Signature Controlled item to the cart.
  3. The original tab (with the review page) is not refreshed, so frontend validation logic is unaware of the updated cart.
  4. The user clicks Place Order—but the required prescriber fields are missing.
  5. Frontend validation fails silently, allowing the order to proceed unless backend validation is enforced.

Solution: Backend Validation via LiveOrder.Model

To ensure mandatory fields are validated regardless of frontend state, extend the LiveOrder.Model and hook into the before:LiveOrder.submit event.

define('JJ.CheckoutMandatoryCheck.CheckoutMandatoryCheck',
[
    'JJ.CheckoutMandatoryCheck.CheckoutMandatoryCheck.ServiceController',
    'Application',
    'LiveOrder.Model',
    'SC.Models.Init'
],
function (
    CheckoutMandatoryCheckServiceController,
    Application,
    LiveOrderModel,
    ModelsInit
) {
    'use strict';


    // Hook into order submission
    Application.on('before:LiveOrder.submit', function beforeLiveOrderSubmit(LiveOrderModel) {
        const validationDeferred = LiveOrderModel.validatemandatory();
        nlapiLogExecution('ERROR', 'Validation Triggered', JSON.stringify(validationDeferred));
    });


    // Extend LiveOrderModel with validation logic
    _.extend(LiveOrderModel, {
        validatemandatory: function () {
            const fieldValues = this.getFieldValues({ keys: [], items: null });
            nlapiLogExecution('ERROR', 'Field Values:', JSON.stringify(fieldValues, null, 2));


            let hasSignatureControlledItem = false;


            // Check if any item is signature-controlled
            _.each(ModelsInit.order.getItems(['class']), function (item) {
                const itemClass = (item.class || '').trim();
                if (itemClass === 'Controlled : Signature Controlled') {
                    hasSignatureControlledItem = true;
                }
            });


            if (!hasSignatureControlledItem) {
                nlapiLogExecution('ERROR', 'No Signature Controlled Item', 'Skipping validation.');
                return null;
            }


            // Fetch custom fields from the order
            const order_fields = ModelsInit.order.getCustomFieldValues();
            const prescriberName = (_.find(order_fields, { name: 'custbody_prescriber_name' }) || {}).value || '';
            const prescriberEmail = (_.find(order_fields, { name: 'custbody_prescriber_email' }) || {}).value || '';
            const licenseNumber = (_.find(order_fields, { name: 'custbody_licensing_number' }) || {}).value || '';


            const missingFields = [];
            if (!prescriberName) missingFields.push('Prescriber Name');
            if (!prescriberEmail) {
                missingFields.push('Prescriber Email');
            } else if (!/^[^s@]+@[^s@]+.[^s@]+$/.test(prescriberEmail)) {
                missingFields.push('Valid Email');
            }
            if (!licenseNumber) missingFields.push('License Number');


            if (missingFields.length > 0) {
                const errorMessage = 'The following fields are required before placing the order: ' + missingFields.join(', ');
                nlapiLogExecution('ERROR', 'Missing Mandatory Fields', missingFields.join(', '));
                const error = new Error('Validation failed!');
                error.name = 'ERROR';
                error.message = errorMessage;
                throw error; // 🚫 BLOCK SUBMISSION
            }
        }
    });
});

Key Benefits

  • Failsafe validation: Ensures compliance even when frontend logic is bypassed.
  • 🔄 Handles multi-tab scenarios: Prevents stale review pages from submitting incomplete data.
  • 🔐 Improved data integrity: Guarantees that signature-controlled items always include required prescriber details.

Leave a comment

Your email address will not be published. Required fields are marked *