Skip to main content

Warehouse load shipped

Fires when a warehouse load completes outbound shipping and its load status transitions to Shipped. This is the moment a consolidated load (one or more shipments assigned to a carrier) physically leaves the warehouse, making it the natural trigger point for downstream transportation notifications, advance ship notices (ASN), customer shipment confirmations, and freight-cost reconciliation. It fires for load ship confirmation and for transport load ship confirmation, including the mobile app's transport loading flow.

Event classMGCLatticeWarehouseLoadShippedBusinessEvent
Contract classMGCLatticeWarehouseLoadShippedBusinessEventContract
CategoryWarehouse management
ModuleModuleAxapta::Warehouse (from the [BusinessEvents] attribute)
Label IDsWarehouseLoadShippedBusinessEventName / WarehouseLoadShippedBusinessEventDescription
TriggerWHSShipConfirm.shipConfirm(WHSLoadId) or WHSShipConfirmationActionTransportLoad.shipConfirm() -> a load's LoadStatus changes to WHSLoadStatus::Shipped

Trigger / Hook​

  • Extension class: MGCLatticeWHSShipConfirm_Class_Extension, decorated with [ExtensionOf(classStr(WHSShipConfirm))].

  • CoC method wrapped: WHSShipConfirm.shipConfirm(WHSLoadId). Exact signature in source:

    public void shipConfirm(WHSLoadId _loadId)
  • Hooks the outbound ship-confirm process method (the business moment) rather than the WHSLoadTable.update() table write. This funnels the single-load form action, shipConfirmAllLoads, and the batch/OData WHSShipConfirmService path for outbound loads while avoiding entity/import/set-based false-fires. The whole status flip happens inside this method's tts, so firing after next shipConfirm(_loadId) is post-commit; when ship confirmation runs inside a larger transaction, the event is delivered only if that transaction commits. Inbound loads, which WHSShipConfirmService confirms through WHSPostPackingSlip instead, don't raise this event.

  • Transport loads: MGCLatticeWHSShipConfirmationActionTransportLoad_Class_Extension, decorated with [ExtensionOf(classStr(WHSShipConfirmationActionTransportLoad))], wraps public void shipConfirm(WHSLoadShipConfirmUTCDateTime _shipDateTime). Transport load ship confirmation (the transport load page and the mobile app's transport loading flow) sets each related load's status directly and never calls WHSShipConfirm, so the wrapper records every related load's status (WHSTransportLoad::getAllRelatedLoads) before next and sends one event per load that moved into Shipped. It records nothing when the event is not activated. Loads that only become PartiallyShipped are not reported, and a load is never reported by both hooks.

  • Firing condition: each hook captures the load status before next, then calls MGCLatticeWarehouseLoadShippedBusinessEvent::raiseIfShipped(loadId, statusBefore). That method re-reads the load (WHSLoadTable::find) and sends when isShippedTransition(before, after) holds: the status before wasn't Shipped and the status after is Shipped. The status-delta guard suppresses the already-shipped no-op early return and partial loads that do not reach Shipped.

  • Enablement gate: BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeWarehouseLoadShippedBusinessEvent)) is checked before sending, so the event is only dispatched when activated against an endpoint.

// MGCLatticeWHSShipConfirm_Class_Extension
public void shipConfirm(WHSLoadId _loadId)
{
// The activation check is a cached lookup and comes first, so an environment that has not activated the
// event pays no database read. next is always called.
boolean eventEnabled = BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeWarehouseLoadShippedBusinessEvent));
WHSLoadStatus origStatus;

if (eventEnabled)
{
origStatus = WHSLoadTable::find(_loadId).LoadStatus;
}

next shipConfirm(_loadId);

if (eventEnabled)
{
MGCLatticeWarehouseLoadShippedBusinessEvent::raiseIfShipped(_loadId, origStatus);
}
}

// MGCLatticeWHSShipConfirmationActionTransportLoad_Class_Extension
public void shipConfirm(WHSLoadShipConfirmUTCDateTime _shipDateTime)
{
Map statusBefore = this.latticeRelatedLoadStatuses();

next shipConfirm(_shipDateTime);

if (statusBefore)
{
MapEnumerator enumerator = statusBefore.getEnumerator();

while (enumerator.moveNext())
{
WHSLoadStatus loadStatusBefore = enumerator.currentValue();

MGCLatticeWarehouseLoadShippedBusinessEvent::raiseIfShipped(enumerator.currentKey(), loadStatusBefore);
}
}
}

// MGCLatticeWarehouseLoadShippedBusinessEvent
public static void raiseIfShipped(WHSLoadId _loadId, WHSLoadStatus _statusBefore)
{
if (!_loadId
|| !BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeWarehouseLoadShippedBusinessEvent)))
{
return;
}

WHSLoadTable loadTable = WHSLoadTable::find(_loadId);

if (loadTable.RecId
&& MGCLatticeWarehouseLoadShippedBusinessEvent::isShippedTransition(_statusBefore, loadTable.LoadStatus))
{
MGCLatticeWarehouseLoadShippedBusinessEvent::newFromWHSLoadTable(loadTable).send();
}
}

Payload Contract​

Fields are listed in contract declaration order. Source expressions are taken verbatim from MGCLatticeWarehouseLoadShippedBusinessEventContract.initialize().

JSON fieldDisplay labelType / EDTSourceNotes
legalEntityLegal EntityDataAreaId_whsLoadTable.DataAreaIdCompany/data area of the load.
loadIdLoad IDWHSLoadId_whsLoadTable.LoadIdThe warehouse load identifier.
shipmentIdShipment IDWHSShipmentId_whsLoadTable.displayShipment()Display method on WHSLoadTable; returns the load's shipment ID when the load has exactly one shipment, and blank when it has none or several.
shipmentIdsShipment IDsList of strWHSShipmentTable.ShipmentId where LoadId = the loadEvery shipment on the load, in shipment ID order; use it instead of shipmentId for loads with several shipments. [] when the load has no shipment.
carrierCodeCarrier Codestr_whsLoadTable.CarrierCodeCarrier assigned to the load.
loadStatusLoad Statusintenum2int(_whsLoadTable.LoadStatus)Integer value of the WHSLoadStatus enum. For Shipped this is 6.
loadStatusNameLoad Status Namestrenum2Symbol(enumNum(WHSLoadStatus), enum2int(_whsLoadTable.LoadStatus))Symbolic (non-localized) name of the enum value, e.g. Shipped.

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​

{
"BusinessEventId": "MGCLatticeWarehouseLoadShippedBusinessEvent",
"ControlNumber": 587213,
"EventId": "1F8D3C2A-7B54-4E90-9A1C-2E6F4B8D0C11",
"EventTime": "\/Date(1790289000000)\/",
"EventTimeIso8601": "2026-09-24T22:30:00.5410395Z",
"MajorVersion": 0,
"MinorVersion": 0,
"BusinessEventLegalEntity": "USMF",
"ContextRecordSubject": "",
"InitiatingUserAADObjectId": "{58C80ED0-4923-C9F5-CF0B-13AAF5273332}",
"ParentContextRecordSubjects": [],
"eventSequence": 48615,
"correlationId": "Event:1cc78df7-9ae1-43c3-8649-19323646699a",
"schemaVersion": 1,
"legalEntity": "usmf",
"loadId": "USMF-000142",
"shipmentId": "USMF-000198",
"shipmentIds": [
"USMF-000198"
],
"carrierCode": "FEDEX",
"loadStatus": 6,
"loadStatusName": "Shipped"
}

Activation​

In the D365FO client, go to System administration > Setup > Business events > Business events catalog. Find this event by name ("Warehouse load shipped") or by filtering the Category column to Warehouse 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).