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
- A user adds a non-signature-controlled item to the cart and proceeds to the Checkout Review Page.
- In a new browser tab, the user adds a Signature Controlled item to the cart.
- The original tab (with the review page) is not refreshed, so frontend validation logic is unaware of the updated cart.
- The user clicks Place Order—but the required prescriber fields are missing.
- 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.