Purchase return order created
Fires when a purchase return order (a purchase order of type Returned order) is created. A purchase return order represents goods being sent back to a vendor. Downstream systems can use this event to track returns to vendors, start reverse-logistics workflows, begin vendor credit or RMA processing, or update return analytics as soon as the return order header is saved.
| Event class | MGCLatticePurchReturnOrderCreatedBusinessEvent |
| Contract class | MGCLatticePurchReturnOrderCreatedBusinessEventContract |
| Category | Purchase orders |
| Module | ModuleAxapta::PurchaseOrder |
| Label IDs | PurchReturnOrderCreatedBusinessEventName / PurchReturnOrderCreatedBusinessEventDescription |
| Trigger | PurchTableType_ReturnItem.inserted() -> after a purchase order header of type Returned order is inserted |
Trigger / Hook
- Extension class:
MGCLatticePurchTableType_ReturnItem_Class_Extension, decorated with[ExtensionOf(classStr(PurchTableType_ReturnItem))]. - CoC method signature:
void inserted()(no parameters).PurchTableType_ReturnIteminherits the method fromPurchTableType; the wrapper applies to return-order instances only. - Firing condition:
PurchTable.insert()callsinserted()on the order's type class at the end of the insert, and the return-item type class is the one used for orders whosePurchaseTypeisReturnItem(Returned order). Afternext inserted(), the order is taken fromthis.parmPurchTable()and the event is sent. There is no further condition, because the type class already limits the hook to return orders. - Coverage: raised once for every purchase return order header that is saved through
PurchTable.insert(), whichever process creates it. Only the insert raises it; later updates to the order don't, and records written without callinginsert()don't either. - Transaction:
PurchTable.insert()requires an open transaction, so the event is always sent inside the transaction that creates the order.BusinessEventsBase.send()only writes to the commit log inside that transaction and delivery is asynchronous post-commit, so an order creation that rolls back never delivers. - Enablement gate: guarded by
BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticePurchReturnOrderCreatedBusinessEvent)), so the event only sends when activated in the business events catalog.
void inserted()
{
next inserted();
PurchTable purchTable = this.parmPurchTable();
if (BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticePurchReturnOrderCreatedBusinessEvent)))
{
MGCLatticePurchReturnOrderCreatedBusinessEvent::newFromPurchTable(purchTable).send();
}
}
Payload Contract
One row per [DataMember], in declaration order. All sources are fields on the inserted PurchTable record, mapped in initialize().
| JSON field | Display label | Type / EDT | Source | Notes |
|---|---|---|---|---|
legalEntity | Legal Entity | DataAreaId | PurchTable.DataAreaId | Company of the return order, in lower case. |
purchaseOrderId | Purchase Order ID | PurchId | PurchTable.PurchId | Purchase order number of the return order. |
vendorAccount | Vendor Account | VendAccount | PurchTable.OrderAccount | Vendor the goods are returned to (the order account). |
returnReasonCodeId | Return Reason Code | ReturnReasonCodeId | PurchTable.ReturnReasonCodeId | Return reason code as saved when the header is created; empty if no reason code is set at that point. A reason code added later isn't reported by this event. |
crossReferences | Cross references | List of MGCLatticeCrossReferenceEventContract | MGCLatticeCrossReferenceEventHelper::listFor(PurchTable) | Keys external systems hold for the purchase return order (a purchase order of type Returned order): one { externalSystem, externalKey } object per external system, ordered by external system, historical keys included; [] when it has none. See Cross-reference keys. |
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; it orders the events of one record, gaps are normal and permanent, see the README), correlationId (String - always Scope:Key; groups emissions that belong to one logical run and defaults to Event: plus a GUID unique to this emission) 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": "MGCLatticePurchReturnOrderCreatedBusinessEvent",
"ControlNumber": 5637151824,
"EventId": "6CFAB1CF-F6D7-4337-BF2B-5D360D1C3897",
"EventTime": "\/Date(1790252329000)\/",
"EventTimeIso8601": "2026-09-24T12:18:49.3638183Z",
"MajorVersion": 0,
"MinorVersion": 0,
"BusinessEventLegalEntity": "USMF",
"ContextRecordSubject": "",
"InitiatingUserAADObjectId": "{D9770065-B77C-EE99-96DD-C8E4FEEB0333}",
"ParentContextRecordSubjects": [],
"eventSequence": 48224,
"correlationId": "Event:baad61dc-a6fe-4407-acc7-9fac59f50bb6",
"schemaVersion": 1,
"legalEntity": "usmf",
"purchaseOrderId": "00001027",
"vendorAccount": "US-101",
"returnReasonCodeId": "21",
"crossReferences": [
{
"externalSystem": "LEGACYERP",
"externalKey": "PRT-30914"
}
]
}
Activation
In the D365FO client, go to System administration > Setup > Business events > Business events catalog. Find this event by name ("Purchase return order created") or by filtering the Category column to Purchase orders. 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).