Suite Utils
Back to Blog
NetSuite TipsSep 2, 2026 • 7 min read

Adding a Custom Sales Order Field to WMS Info Screen

Learn How to Add Custom Sales Order Fields to NetSuite WMS Info Screen.

Ethan James MarshalEthan James MarshalSenior SuiteScript Architect & Lead NetSuite Engineer
Adding a Custom Sales Order Field to WMS Info Screen
On this page

The Setup Problem

You've configured NetSuite WMS, configured a custom body field on the Sales Order record, and added a new Mobile – Info Screen Element under Setup → Custom → Mobile → Applications → (WMS App) → Pages → Information Screen Elements. You bind it to a state path like state:dataRecord:scriptParams:customer, the field renders, and everything works. Then you add a second element for your custom field custbody_tebi_aangemaakt_door, bind it to a similar path, and the screen shows nothing.

This trips people up because the WMS Info Screen doesn't expose arbitrary transaction fields. The default scriptParams object is a curated subset the SCM WMS team wired into their client scripts. A custom body field won't exist there until you push it there yourself. The NetSuite Connector documentation is a useful reminder here: every field has a permanent field ID (like custbody_tebi_aangemaakt_door) that the WMS framework will never guess from a label.

Why the State Path Doesn't Resolve

The WMS mobile app loads a transaction record into a client-side data model, then exposes selected values through state:dataRecord:scriptParams. The built-in fields you see today (customer, transaction name, subsidiary) are injected by the WMS user event script that fires before the mobile client requests the order. Per the Warehouse Management Guide on Mobile App Setup, the mobile app posts real-time updates to NetSuite as scanners work through warehouse transactions, which is why the script has to populate the data model before the client requests the order.

For your custom field, you have two paths:

  • Inject the field into scriptParams from a WMS-compatible User Event script on the Sales Order
  • Bind the Info Screen Element directly to a record field path if the WMS framework supports raw field access

The first approach is the recommended one because it keeps the mobile client code untouched and survives WMS bundle updates.

Building the WMS-Compatible User Event Script

The script has to deploy against the Sales Order record, fire in beforeLoad, and only target the WMS context. Otherwise you'll slow down every sales order entry by loading unnecessary data. Execution contexts are the standard mechanism for that, as covered in the SuiteFlow Execution Contexts documentation.

Create a User Event script with a WMS execution context filter:

/**
 * @NApiVersion 2.1
 * @NScriptType UserEventScript
 * @NModuleScope SameasAccount
 */
define(['N/runtime', 'N/record', 'N/log'], (runtime, record, log) => {
    const WMS_CONTEXT = 'WMS'; // execution context value for SCM WMS

    const beforeLoad = (scriptContext) => {
        const execCtx = runtime.executionContext;
        if (execCtx !== WMS_CONTEXT) return;
        if (scriptContext.type !== scriptContext.UserEventType.VIEW) return;

        const soRec = scriptContext.newRecord;
        const creatorField = 'custbody_tebi_aangemaakt_door';

        let creatorName = '';
        const creator = soRec.getValue(creatorField);
        if (creator) {
            try {
                const empLookup = record.load({
                    type: record.Type.EMPLOYEE,
                    id: creator,
                    isDynamic: false
                });
                creatorName = empLookup.getValue('entityid') || '';
            } catch (e) {
                log.error('WMS ScriptParams Inject', `Could not load employee ${creator}: ${e.message}`);
            }
        }

        // Push to scriptParams so the mobile Info Screen Element resolves
        scriptContext.form.addField({
            id: 'custpage_wms_creator',
            label: 'SO Created By',
            type: 'text'
        }).defaultValue = creatorName;
    };

    return { beforeLoad };
});

The runtime.executionContext check is what keeps this script out of the normal web sales order path. Skip it and you'll be paying governance units on every SO save.

After the script deploys, update the Info Screen Element binding in Setup → Custom → Mobile → Applications → (WMS App) → Pages → Information Screen Elements to:

state:dataRecord:scriptParams:custpage_wms_creator

Deploying Without Blowing the WMS Bundle

Here's the gotcha: the SCM WMS bundle ships its own User Event scripts on Sales Order. If you deploy a heavy script against the same record without proper filtering, you risk script queue contention and conflicts during bundle updates.

To stay governance-safe:

  • Deploy at a higher priority than the WMS bundle scripts (lower number = higher priority, so use a priority between 1 and the WMS bundle's priority)
  • Mark the deployment status as Released, never Testing, once verified
  • Disable the script in non-WMS contexts explicitly with the execution context check
  • Test in the WMS mobile app sandbox first; the web SO view should show zero behavior change

This will bite you during upgrades if you hardcode the WMS bundle's script internal IDs. Instead, rely on the execution context check, which is stable across bundle releases.

What About Using custbody_tebi_aangemaakt_door Directly?

You might be tempted to bind the Info Screen Element to a record field path that points straight at the body field. The WMS mobile framework generally doesn't traverse native transaction fields under state:dataRecord without explicit wiring. The pattern of injecting through scriptParams is the one the WMS development community has standardized on because it survives framework changes.

If you want to confirm whether direct binding works in your installed bundle version, test it in a sandbox first:

  1. Create a new Info Screen Element
  2. Bind it to a path like state:dataRecord:fields:custbody_tebi_aangemaakt_door
  3. Reload the WMS app and check the Single Order Picking Information Screen

If it resolves, you've saved yourself a script. If it doesn't, the User Event approach above is the fallback.

Verifying the Field Renders

After deploying, open the WMS mobile app, scan a sales order, tap the information icon, and confirm the creator name shows where the red box sits in your screenshot. If the field is blank:

  • Check the execution log for the script. Look for the error string WMS ScriptParams Inject
  • Confirm the script is Released and on the correct record type
  • Re-enter the sales order in WMS so beforeLoad fires fresh; the VIEW context doesn't replay on a cached screen

The cached screen is the silent killer here. If you edit the User Event script while a picking session is open, the mobile client won't see the new field until the user exits and re-enters the order.

Edge Case: Displaying an Employee Name vs. an ID

The custom field likely stores an employee ID, not a display name. The script above does a lookup against the Employee record to grab entityid (the display name). If your field is a free-text field, skip the lookup and pass the value directly:

creatorName = soRec.getValue(creatorField) || '';

For a multi-select or custom record reference, swap the record.load call for a targeted N/search.lookupFields to stay under the 1000-unit governance budget on a single order load.

A Cleaner Long-Term Pattern

If you find yourself injecting multiple custom fields this way, build a single User Event script with a config object that maps field IDs to script param names. Add a Saved Custom Record for the mapping so administrators can add fields without touching code. The WMS Info Screen Elements then bind to state:dataRecord:scriptParams:<your_defined_key>, and the script handles the field lookup and display formatting in one place.

Once the new field shows up on the Information Screen, run a full picking cycle on a test order to confirm nothing in the rest of the WMS flow regressed.

About the author

Put these ideas to work.

Suite Utils builds small NetSuite tools that fix the specific thing breaking your day. Each one runs as a native SuiteScript SuiteApp inside your account. No sales call, no onboarding.

Browse the Tools

Enjoyed this one?

Get NetSuite tips like this in your inbox. No spam. Practical guides only.

Keep reading