Acumatica · Customization

Acumatica Warehouse Management — Wave Pick

How to use Acumatica's WMS — wave picking, pick lists, putaway, cycle counts, and the configurations that turn a chaotic warehouse into a tight operation.

John Kihiu12 min read

A distribution client came to me with a warehouse team picking one order at a time, walking the same aisles repeatedly across dozens of orders a day, and asked whether Acumatica's Warehouse Management edition could batch that work. Wave picking was the right answer, but explaining it took longer than implementing it, because wave picking is a planning and grouping concept layered on top of Acumatica's existing pick/pack/ship workflow, not a separate module you bolt on. Here's how the pieces actually connect.

A wave is a grouping of shipments, not a new document type

In Acumatica's Warehouse Management functionality, a Wave groups multiple Shipments together based on selection criteria, ship date, carrier, warehouse zone, order priority, so the warehouse can generate one consolidated pick list covering many orders' demand at once, instead of pickers working shipment-by-shipment. The underlying documents haven't changed: you still have Sales Orders generating Shipments, and Shipments still generate the pick, pack, and confirm workflow. A wave just changes how picking is batched and sequenced across those shipments.

C# · creating a wave programmatically from eligible shipments
WMSWaveManagementEntry graph = PXGraph.CreateInstance<WMSWaveManagementEntry>();
graph.WaveHeader.Insert(new WMSWave
{
    WarehouseID = warehouseID,
    WaveType = WMSWaveType.Pick,
    ShipVia = shipVia   // one of several possible grouping criteria
});

var eligibleShipments = PXSelect<SOShipment,
    Where<SOShipment.status, Equal<SOShipmentStatus.open>,
    And<SOShipment.confirmed, Equal<False>,
    And<SOShipment.siteID, Equal<Required<SOShipment.siteID>>>>>
    .Select(Base, warehouseID);

foreach (SOShipment shipment in eligibleShipments)
    graph.WaveDetails.Insert(new WMSWaveDetail { ShipmentNbr = shipment.ShipmentNbr });

graph.Save.Press();

Pick list generation: consolidated by item, not by shipment

The actual value of wave picking shows up in how the generated pick list is organized: instead of forty separate pick lists for forty shipments, each requiring a separate walk through the warehouse, a wave-generated pick list can consolidate demand by item and bin location across all shipments in the wave, so a picker collects the total quantity of an item needed across every order in one pass, then the system handles allocating what was picked back to individual shipments during pack. This only pays off when pick strategies (single-order pick, batch pick, or zone pick, configured per warehouse or per wave type) are matched to how the physical warehouse is actually laid out.

Zone picking without correctly configured warehouse zones is worse than no wave picking at all

Zone-based wave picking assumes your Warehouse Location records are accurately zoned and that pickers are actually assigned to specific zones. I've seen an implementation go live with wave picking enabled but warehouse locations left with default or inconsistent zone assignments, and pickers ended up crossing zones constantly anyway, all the wave batching overhead with none of the walking-distance benefit. Get the physical warehouse's zone and location data accurate before flipping on zone-based wave strategies, not after.

Allocation happens at pick confirmation, and lot/serial tracking complicates the consolidation

When a picker confirms a consolidated pick (via the Warehouse Mobile app in most real deployments), the system has to allocate what was actually picked back down to the individual shipment lines that generated the demand. For non-tracked items this is straightforward quantity math. For lot- or serial-tracked items, the allocation has to also decide which specific lot or serial goes to which shipment, which matters enormously if the client has any FEFO (first-expired-first-out) or specific-lot-per-customer requirements, because a naive consolidated pick can hand a soon-to-expire lot to whichever shipment happens to get allocated first rather than respecting expiration-driven priority.

C# · lot-aware allocation during wave pick confirmation
protected virtual void _(Events.RowUpdated<WMSPickDetail> e)
{
    var row = (WMSPickDetail)e.Row;
    if (row == null || row.LotSerialNbr == null) return;

    // Respect FEFO: verify the confirmed lot is the earliest-expiring
    // available lot for this item/site, not just whatever was scanned
    var earliestLot = PXSelect<INLotSerStatus,
        Where<INLotSerStatus.inventoryID, Equal<Required<INLotSerStatus.inventoryID>>,
        And<INLotSerStatus.qtyOnHand, Greater<decimal0>>>,
        OrderBy<Asc<INLotSerStatus.expireDate>>>
        .SelectWindowed(Base, 0, 1, row.InventoryID);

    if (earliestLot != null && ((INLotSerStatus)earliestLot).LotSerialNbr != row.LotSerialNbr)
    {
        // Warn or block depending on how strict the client's FEFO policy is
        e.Cache.RaiseExceptionHandling<WMSPickDetail.lotSerialNbr>(row, row.LotSerialNbr,
            new PXSetPropertyException("A lot with an earlier expiration date is available.", PXErrorLevel.Warning));
    }
}

Wave picking is a throughput optimization, not a universal upgrade

For a warehouse shipping a handful of large, complex orders a day, wave consolidation adds overhead (wave planning, more complex allocation logic) without meaningful walking-distance savings, because there's little overlapping demand across orders to consolidate in the first place. Wave picking earns its complexity specifically when there's high order volume with meaningful item overlap across orders, which is the actual pattern to check for before recommending it, not just "the client wants WMS features." I've talked more than one prospective client out of wave picking after looking at their actual order profile and finding each order's item mix was different enough that consolidation wouldn't have saved meaningful picker time.

Wrapping up

Wave picking is a grouping and sequencing layer over Acumatica's existing shipment and pick/pack/ship workflow, not a separate system, and its value depends entirely on whether the warehouse's actual order profile has enough item overlap to make consolidated picking worthwhile. Get warehouse zone data accurate before turning on zone-based strategies, treat lot/serial allocation during consolidated picks as a place that needs explicit FEFO-aware logic rather than first-come allocation, and validate the throughput case with real order data before committing a client to the added complexity.

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.