Picking list canceled
Fires when picking lines are canceled: when a picking list (a WMSPickingRoute picking route) is canceled as a whole and that cancels at least one of its lines, or when an individual line of a picking list is canceled. The payload lists only the lines the cancellation canceled. These are the picking lists of the inventory picking-list process (for example, sales order and transfer order picking lists handled through picking list registration); work in warehouse management (WHS) is covered by Warehouse Work Completed and Warehouse Picking Completed instead. Downstream systems can use this event to stop pick tasks in an external warehouse or automation system, release reserved pick capacity, or alert customer service.
| Event class | MGCLatticePickingListCanceledBusinessEvent |
| Contract class | MGCLatticeOrderPickingBusinessEventContract (shared with Transfer order picking list created) |
| Category | Inventory management |
| Module | ModuleAxapta::Inventory |
| Label IDs | PickingListCancelledBusinessEventName / PickingListCancelledBusinessEventDescription |
| Trigger | WMSPickingRoute.cancel() when it cancels at least one line (whole picking list), or WMSOrderTransType_Output_OrderPick.cancel() with _checkRoute = true (single line) |
Trigger / Hook
- Whole picking list: extension class
MGCLatticeWMSPickingRoute_Table_Extension,[ExtensionOf(tableStr(WMSPickingRoute))], CoC methodpublic void cancel().- The standard
cancel()does nothing when the route has no record, is already Canceled, or is physically updated (Picked, Staged, Loaded or Complete); otherwise it cancels every line that is Registered, Activated or Started. - Before
next cancel(), when the event is activated and the route is one the standard method acts on, the extension records the route's Registered, Activated and Started lines. Afternext cancel(), it keeps those of them that are now Canceled and sends one event listing exactly those lines. When no line was canceled, nothing is sent. - Lines that were canceled earlier on their own (and raised their own event then) and lines that are already picked are never listed.
- The standard
- Single line: handler class
MGCLatticePickingListCancelledEventHandlers,[PostHandlerFor(classStr(WmsOrderTransType_Output_OrderPick), methodStr(WmsOrderTransType_Output_OrderPick, cancel))]onpublic static void WmsOrderTransType_Output_OrderPick_Post_cancel(XppPrePostArgs _args). The event is sent only when the method's_checkRouteargument is true, which is the case when a line is canceled on its own; the standard callers of that path cancel only a line that can be canceled, and the method always sets the line to Canceled. The event is built withnewFromWMSOrderTrans(orderTrans)from the line the order-pick type object holds. - No double events: the standard
WMSPickingRoute.cancel()cancels each line with_checkRoute = false, so canceling a whole picking list sends one route-level event, not one event per line. Canceling several lines individually sends one event per line. - Transaction:
WMSPickingRoute.cancel()runs its ownttsbegin/ttscommit, and the event is sent after it. When a cancellation runs inside a larger transaction, the event is written to the business events commit log inside it and is delivered only if that transaction commits. - Enablement gate: both hooks check
BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticePickingListCanceledBusinessEvent)).
public void cancel()
{
Set openLineRecIds;
// The cached activation check comes first; isRouteCancellable reads the route's physical updates.
if (BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticePickingListCanceledBusinessEvent))
&& MGCLatticePickingListCanceledBusinessEvent::isRouteCancellable(this))
{
openLineRecIds = MGCLatticePickingListCanceledBusinessEvent::openLineRecIds(this.PickingRouteID);
}
next cancel();
if (openLineRecIds && openLineRecIds.elements() > 0)
{
Set cancelledLineRecIds = MGCLatticePickingListCanceledBusinessEvent::cancelledLineRecIds(this.PickingRouteID, openLineRecIds);
if (cancelledLineRecIds.elements() > 0)
{
MGCLatticePickingListCanceledBusinessEvent::newFromCancelledRouteLines(this, cancelledLineRecIds).send();
}
}
}
Payload Contract
One row per [DataMember], in declaration order. MGCLatticeOrderPickingBusinessEventContract is shared with Transfer order picking list created; the payload carries no cancellation flag: the event id says the lines were canceled. Header fields come from the picking route: the canceled route, or for a single-line cancel, the route of the canceled line (WMSOrderTrans.wmsPickingRoute()).
| JSON field | Display label | Type / EDT | Source | Notes |
|---|---|---|---|---|
legalEntity | Legal Entity | DataAreaId | WMSPickingRoute.dataAreaId | Company of the picking list |
pickingRouteId | Picking Route | WMSPickingRouteID | WMSPickingRoute.pickingRouteID | Picking list (route) number |
orderNumber | Order Number | InventTransRefId | WMSPickingRoute.transRefId | Source order, for example the sales order or transfer order |
transType | Transaction Type | int | enum2int(WMSPickingRoute.transType) | InventTransType value, for example 0 = Sales, 21 = TransferOrderShip |
transTypeName | Transaction Type Name | str | enum2Symbol(enumNum(InventTransType), ...) | Symbol, for example Sales |
routeStatus | Picking Route Status | int | enum2int(WMSPickingRoute.ExpeditionStatus) | Status of the picking route after the cancellation, as the WMSExpeditionStatus integer (20 = Canceled when every line of the route is now canceled) |
routeStatusName | Picking Route Status Name | str | enum2Symbol(enumNum(WMSExpeditionStatus), routeStatus) | Symbol of routeStatus, for example "Cancelled" (the Microsoft enum symbol) |
deliveryModeId | Delivery Mode | DlvModeId | WMSPickingRoute.DlvModeId | |
deliveryTermsId | Delivery Terms | DlvTermId | WMSPickingRoute.DlvTermId | |
lines | Lines | List of MGCLatticeOrderPickingLineContract | See below | JSON array. Whole-list cancel: the lines this cancellation canceled, in record order. Single-line cancel: just the canceled line |
Each element of lines (MGCLatticeOrderPickingLineContract, built by newFromWMSOrderTrans() from a WMSOrderTrans picking line):
| JSON field | Display label | Type / EDT | Source | Notes |
|---|---|---|---|---|
itemId | Item Number | ItemId | WMSOrderTrans.itemId | |
quantity | Quantity | Qty | WMSOrderTrans.qty | Quantity of the picking line |
inventTransId | Inventory Transaction ID | InventTransId | WMSOrderTrans.inventTransId | Lot ID of the source order line |
lineNumber | Line Number | LineNum | SalesLine.LineNum, otherwise InventTransferLine.LineNum, matched on InventTransId | 0 when the line belongs to neither a sales line nor a transfer order line |
inventDimId | Inventory Dimension ID | InventDimId | WMSOrderTrans.inventDim().InventDimId | |
siteId | Site | InventSiteId | WMSOrderTrans.inventDim().InventSiteId | |
warehouseId | Warehouse | InventLocationId | WMSOrderTrans.inventDim().InventLocationId | |
locationId | Location | WMSLocationId | WMSOrderTrans.inventDim().wMSLocationId |
Every Lattice event also carries the Lattice ordering and correlation envelope, inherited from MGCLatticeBusinessEventContractBase: eventSequence (Int64 - increasing across the whole catalog and all companies, allocated when the event is raised inside the business transaction rather than when it commits; it orders the events of one business record, gaps are permanent and normal, and it must not be used to re-sequence the whole stream), correlationId (String, always Scope:Key - groups emissions that belong to one logical run; Event:<GUID> unique to this emission when the event belongs to no run) and schemaVersion (Int - the payload shape version; 1 for this contract). D365 F&O also adds its standard envelope fields to every business event payload: BusinessEventId, BusinessEventLegalEntity, ContextRecordSubject, ControlNumber, EventId, EventTime, EventTimeIso8601, InitiatingUserAADObjectId, MajorVersion, MinorVersion, and ParentContextRecordSubjects. Do not rely on the order of members in the delivered JSON.
Example Payload
A whole sales order picking list canceled:
{
"BusinessEventId": "MGCLatticePickingListCanceledBusinessEvent",
"ControlNumber": 5637146325,
"EventId": "B85D0E3A-6F12-4C9B-8D47-3A1E9C0F5B62",
"EventTime": "\/Date(1790260337000)\/",
"EventTimeIso8601": "2026-09-24T14:32:17.9383437Z",
"MajorVersion": 0,
"MinorVersion": 0,
"BusinessEventLegalEntity": "USMF",
"ContextRecordSubject": "",
"InitiatingUserAADObjectId": "{4B6ECBDD-25B5-766D-78CB-ED43EB4E6817}",
"ParentContextRecordSubjects": [],
"eventSequence": 48451,
"correlationId": "Event:44bdb86d-783a-4198-86c1-63f2dc847b34",
"schemaVersion": 1,
"legalEntity": "usmf",
"pickingRouteId": "000318",
"orderNumber": "000874",
"transType": 0,
"transTypeName": "Sales",
"routeStatus": 20,
"routeStatusName": "Cancelled",
"deliveryModeId": "10",
"deliveryTermsId": "FOB",
"lines": [
{
"itemId": "A0001",
"quantity": 12.0,
"inventTransId": "012587",
"lineNumber": 1.0,
"inventDimId": "002147",
"siteId": "1",
"warehouseId": "11",
"locationId": "11-01-02"
},
{
"itemId": "A0002",
"quantity": 4.0,
"inventTransId": "012588",
"lineNumber": 2.0,
"inventDimId": "002166",
"siteId": "1",
"warehouseId": "11",
"locationId": "11-03-01"
}
]
}
Activation
In the D365FO client, go to System administration > Setup > Business events > Business events catalog. Find this event by name ("Picking list canceled") or by filtering the Category column to Inventory management. Select it and use Activate to bind it to a configured endpoint (for example, an Azure Service Bus queue, Event Grid topic, or HTTPS webhook).
No other setup is needed.