Acumatica · Mobile

Acumatica Mobile Barcode Scanning — A Complete Guide

Acumatica Mobile Barcode Scanning — A Complete Guide is one of those Acumatica topics that is both obvious and subtle.

John Kihiu12 min read

Barcode scanning is the single most requested Acumatica Mobile customization I get, and also the one clients most consistently underestimate the complexity of. "Just make the field scannable" sounds like a checkbox, but it's actually a decision about which of three device capability containers to use, how the scanned value maps to a lookup, and what happens when the scan doesn't match anything — and getting those decisions wrong produces a warehouse app nobody trusts.

Three ways a field becomes scannable

The Acumatica Mobile Framework exposes barcode input through the MSDL (Mobile Screen Definition Language) patching applied to a mobile screen's container definitions. The container type you choose determines the scanning UX entirely:

Most botched implementations pick the inline single-field pattern for a picking screen that genuinely needed continuous scan mode, and the resulting app gets abandoned by warehouse staff within a week because it's slower than paper.

Wiring it up: MSDL patches a container, it doesn't replace the screen

Mobile screens are defined declaratively and modified through XML patches applied to the base screen's container definitions — the same extend-don't-replace philosophy as the rest of the platform, expressed in XML rather than C#:

XML
<mobile>
  <screen key="IN301020">
    <container name="Details">
      <field name="InventoryID">
        <scanning enabled="true" mode="inline" />
      </field>
    </container>
  </screen>
</mobile>

That XML lives inside a customization project alongside your DAC and graph extensions, deploying with everything else — mobile UI changes are not a separate release process, which is easy to forget if you've only worked on the classic or Modern UI screens before and expect mobile changes to live somewhere else.

Scanned value doesn't always equal field value

The naive assumption — the barcode's raw content is the value you want in the field — breaks constantly in real warehouses. A GS1-128 barcode on a case label typically encodes multiple application identifiers (lot number, expiry date, quantity, GTIN) concatenated in one string, not a single Inventory ID. The mobile screen's scan handler needs a parsing step before the value lands in the field, which in practice means backing the scan with a graph-side lookup rather than a raw string assignment:

C#
// Server-side: resolve a scanned barcode (which may be a case-pack
// barcode, not the item's own InventoryCD) to the correct InventoryID
protected virtual void _(Events.FieldUpdated<INTran.usrScannedBarcode> e)
{
    var row = (INTran)e.Row;
    if (row == null || string.IsNullOrEmpty(row.UsrScannedBarcode)) return;

    var match = PXSelect<INItemBarcode,
        Where<INItemBarcode.barCode, Equal<Required<INItemBarcode.barCode>>>>
        .Select(Base, row.UsrScannedBarcode);

    if (match == null)
    {
        // Fail loud — a silent no-op here is how pickers scan the wrong item
        e.Cache.RaiseExceptionHandling<INTran.usrScannedBarcode>(row, row.UsrScannedBarcode,
            new PXSetPropertyException("Barcode not recognized. Rescan or enter the item manually."));
        return;
    }
    row.InventoryID = ((INItemBarcode)match).InventoryID;
}
Design for the failed scan, not just the successful one

Every barcode scanning implementation I've shipped that succeeded in production spent real design effort on the unhappy path: barcode not found, barcode matches an item not valid for this transaction type (wrong warehouse, inactive item, wrong UOM), or a case-pack barcode scanned where a single-unit barcode was expected. A picker who scans and gets silence, with no feedback about why, stops trusting the scanner and reverts to typing — which defeats the entire point of the feature.

Device hardware: camera scan vs dedicated scanner emulation

Acumatica Mobile runs on both consumer phones (using the camera as a scanner, through the device's native scanning capability) and on ruggedized handheld scanners running the mobile app, where the physical scanner often emulates keyboard input directly into whatever field has focus. These are different failure modes to test: camera-based scanning is slower and more error-prone in poor lighting or on damaged labels, while keyboard-emulation scanners bypass your inline scan icon entirely and just "type" into whatever's focused — which means your field-level scan handler logic needs to trigger on the field's value-changed event, not exclusively on an explicit "scan button tapped" action, or keyboard-emulation scanners will silently not invoke your barcode resolution logic at all.

Wrapping up

Barcode scanning on Acumatica Mobile is a UX decision first and an MSDL configuration second: pick inline, navigate, or continuous mode based on the actual warehouse workflow, not by default. Parse scanned values through a proper lookup rather than assuming barcode content equals field value, design the failed-scan path as carefully as the happy path, and test against both camera-based and keyboard-emulation hardware before calling it done — the two behave differently enough to matter.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.