Skip to main content

Purchase requisition approved

Fires when a purchase requisition completes its approval workflow and its status is set to Approved. This is the signal that a request for goods or services has cleared review and can be released to purchase orders. Downstream systems can use it to start sourcing, budgeting, or notification flows.

Event classMGCLatticePurchReqApprovedBusinessEvent
Contract classMGCLatticePurchReqApprovedBusinessEventContract
CategoryPurchase orders
ModuleModuleAxapta::PurchaseOrder
Label IDsPurchReqApprovedBusinessEventName / PurchReqApprovedBusinessEventDescription
TriggerPurchReqWFStatusTransitionHelper::setPurchReqTable2Approved() -> requisition set to Approved by workflow completion (!_isReset2Approved)

Trigger / Hook​

  • Extension class: MGCLatticePurchReqWFStatusTransitionHelper_Class_Extension, decorated with [ExtensionOf(classStr(PurchReqWFStatusTransitionHelper))].
  • CoC method signature: static void setPurchReqTable2Approved(RecId _purchReqTableRecId, boolean _isReset2Approved). This is the workflow status-transition method that sets a requisition to Approved, not the PurchReqTable.update() table write.
  • Firing condition: after next setPurchReqTable2Approved(...), the event is sent when _isReset2Approved is false. The requisition is re-read with PurchReqTable::find(_purchReqTableRecId), so the payload reflects the saved record.
  • Where the call comes from: the purchase requisition workflow's completed event handler (PurchReqWFTypeEventHandler.completed()) calls the method with _isReset2Approved false when the workflow completes, unless the requisition is Closed. The same method is also called with _isReset2Approved true to reset a requisition back to Approved (from PurchReqLine and from budget reservation lines, BudgetReservationLine_PSN); those calls don't raise the event. So the event is raised once per completed approval workflow, and only through the workflow.
  • Transaction: setPurchReqTable2Approved() updates the requisition and its lines inside its own ttsbegin/ttscommit, and the event is sent after it returns. BusinessEventsBase.send() only writes to the commit log inside the current transaction and delivery is asynchronous post-commit, so an event raised inside a larger transaction that rolls back is never delivered.
  • Enablement gate: guarded by BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticePurchReqApprovedBusinessEvent)), so the event only sends when activated in the business events catalog.
static void setPurchReqTable2Approved(RecId _purchReqTableRecId, boolean _isReset2Approved)
{
next setPurchReqTable2Approved(_purchReqTableRecId, _isReset2Approved);

if (!_isReset2Approved
&& BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticePurchReqApprovedBusinessEvent)))
{
MGCLatticePurchReqApprovedBusinessEvent::newFromPurchReqTable(PurchReqTable::find(_purchReqTableRecId)).send();
}
}

Payload Contract​

One row per [DataMember], in declaration order. The sources are the re-read PurchReqTable record and its lines (PurchReqLine), mapped in initialize(). Purchase requisitions are shared across legal entities (the tables have no company column), and one requisition can buy for several legal entities: each line carries its own buying legal entity.

JSON fieldDisplay labelType / EDTSourceNotes
legalEntityLegal EntityDataAreaIdBuying legal entity of the first requisition line (PurchReqLine.BuyingLegalEntity, by line number); if no line has one, the requisition's default buying legal entity (PurchReqTable.CompanyInfoDefault)Company id in lowercase. When the lines buy for more than one legal entity, all of them are in buyingLegalEntities. BusinessEventLegalEntity is the company in which the approval was processed, which can differ.
buyingLegalEntitiesBuying Legal EntitiesList of strDistinct PurchReqLine.BuyingLegalEntity values of the requisition's linesCompany ids in lowercase, each listed once, in the order of the first line that uses it. Empty when no line has a buying legal entity.
purchReqIdRequisition IDPurchReqIdPurchReqTable.PurchReqIdPurchase requisition number.
requisitionNameRequisition NamePurchReqNamePurchReqTable.PurchReqNameName of the requisition.
requesterPersonnelNumberRequester Personnel NumberHcmPersonnelNumberIdHcmWorker.PersonnelNumber of PurchReqTable.OriginatorPersonnel number of the worker who prepared the requisition, labeled Preparer in the client. Line-level requesters aren't included.
crossReferencesCross referencesList of MGCLatticeCrossReferenceEventContractMGCLatticeCrossReferenceEventHelper::listFor(PurchReqTable)Keys external systems hold for the purchase requisition: one { externalSystem, externalKey } object per external system, ordered by external system, historical keys included; [] when it has none. See Cross-reference keys. Read in the legal entity of the requisition's default buying legal entity, where its keys are set.

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": "MGCLatticePurchReqApprovedBusinessEvent",
"ControlNumber": 5637151819,
"EventId": "184EF5D1-E9E0-4552-8283-210F2758DDAE",
"EventTime": "\/Date(1790249822000)\/",
"EventTimeIso8601": "2026-09-24T11:37:02.2782934Z",
"MajorVersion": 0,
"MinorVersion": 0,
"BusinessEventLegalEntity": "USMF",
"ContextRecordSubject": "",
"InitiatingUserAADObjectId": "{0028E98B-AD1D-B341-ECAF-5423B427D2D2}",
"ParentContextRecordSubjects": [],
"eventSequence": 48219,
"correlationId": "Event:ab1b426e-b511-4b6c-8c4f-f4a5f227fcc5",
"schemaVersion": 1,
"legalEntity": "usmf",
"buyingLegalEntities": ["usmf"],
"purchReqId": "000912",
"requisitionName": "Office furniture for new hires",
"requesterPersonnelNumber": "000020",
"crossReferences": [
{
"externalSystem": "PROCURE",
"externalKey": "REQ-88120"
}
]
}

Activation​

In the D365FO client, go to System administration > Setup > Business events > Business events catalog. Find this event by name ("Purchase requisition approved") 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). The event is only raised when a purchase requisition approval workflow completes, so requisitions must be submitted to an active purchase requisition workflow.