Quality order passed
Fires when a quality order passes validation - the moment an InventQualityOrderTable record's order status transitions to Pass. This signals that the inspected item/lot tied to the referenced source document has met its test group criteria and is cleared, enabling downstream consumers (release-to-stock, supplier scorecards, downstream production) to react to a successful quality result.
| Event class | MGCLatticeQualityOrderPassedBusinessEvent |
| Contract class | MGCLatticeQualityOrderPassedBusinessEventContract |
| Category | Inventory management |
| Module | ModuleAxapta::Inventory |
| Label IDs | QualityOrderValidatedBusinessEventName / QualityOrderValidatedBusinessEventDescription |
| Trigger | InventQualityOrderValidate.run() -> OrderStatus transitions to InventTestOrderStatus::Pass |
Trigger / Hook
- Extension class:
MGCLatticeInventQualityOrderValidate_Class_Extension,[ExtensionOf(classStr(InventQualityOrderValidate))] - CoC method signature:
void run()(no params) - Hooked on the validation process method, rather than the underlying
InventQualityOrderTable.update(). The process method is the true business moment; the table write is only its side effect (and table hooks false-fire for entity/import writes and are skipped by set-based DML). The status write happens inupdateInventQualityOrder()insiderun()'s ownttsbegin/ttscommit, so the event is sent after that transaction commits. When validation 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. - Firing condition: the pre-validation status is captured via
InventQualityOrderTable::find(this.parmQualityOrderId()).OrderStatusbeforenext run(), and the committed record is re-read (InventQualityOrderTable::find(qualityOrderId)) afterward. The event sends only on a genuine transition (origStatus != qo.OrderStatus) intoInventTestOrderStatus::Pass, preventing re-fires on no-ops, re-runs, and already-in-state calls. The same wrapper also fires the siblingMGCLatticeQualityOrderFailedBusinessEventon a transition toInventTestOrderStatus::Fail(the branches are mutually exclusive - Pass XOR Fail). - Enablement gate:
BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeQualityOrderPassedBusinessEvent))must return true before.send()is called.
void run()
{
// The activation checks are cached lookups and come first, so an environment that has activated neither
// event pays no database read. next run() is always called.
boolean passedEnabled = BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeQualityOrderPassedBusinessEvent));
boolean failedEnabled = BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeQualityOrderFailedBusinessEvent));
InventQualityOrderId qualityOrderId = this.parmQualityOrderId();
InventTestOrderStatus origStatus;
if (passedEnabled || failedEnabled)
{
origStatus = InventQualityOrderTable::find(qualityOrderId).OrderStatus;
}
next run();
if (passedEnabled || failedEnabled)
{
InventQualityOrderTable qo = InventQualityOrderTable::find(qualityOrderId);
if (origStatus != qo.OrderStatus)
{
if (qo.OrderStatus == InventTestOrderStatus::Pass && passedEnabled)
{
MGCLatticeQualityOrderPassedBusinessEvent::newFromInventQualityOrderTable(qo).send();
}
else if (qo.OrderStatus == InventTestOrderStatus::Fail && failedEnabled)
{
MGCLatticeQualityOrderFailedBusinessEvent::newFromInventQualityOrderTable(qo).send();
}
}
}
}
Payload Contract
| JSON field | Display label | Type / EDT | Source | Notes |
|---|---|---|---|---|
| legalEntity | Legal Entity | DataAreaId | _inventQualityOrderTable.DataAreaId | Company/legal entity of the quality order. |
| qualityOrderId | Quality Order ID | InventTestId | _inventQualityOrderTable.QualityOrderId | Identifier of the quality order. |
| itemId | Item ID | ItemId | _inventQualityOrderTable.ItemId | Item being inspected. |
| testGroupId | Test Group ID | InventTestGroupId | _inventQualityOrderTable.TestGroupId | Test group governing the validation criteria. |
| referenceId | Reference ID | InventRefId | _inventQualityOrderTable.InventRefId | Source/reference document ID for the order. |
| orderStatus | Order Status | int | enum2int(_inventQualityOrderTable.OrderStatus) | Integer value of the InventTestOrderStatus enum; 2 (Pass) for this event. |
| orderStatusName | Order Status Name | str | enum2Symbol(enumNum(InventTestOrderStatus), enum2int(_inventQualityOrderTable.OrderStatus)) | Symbol/name of the InventTestOrderStatus enum value; Pass for this event. |
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": "MGCLatticeQualityOrderPassedBusinessEvent",
"ControlNumber": 305412,
"EventId": "B3F1C2A4-7E9D-4F1A-9C3B-2A8E5D6F7A10",
"EventTime": "\/Date(1790278008000)\/",
"EventTimeIso8601": "2026-09-24T19:26:48.3545524Z",
"MajorVersion": 0,
"MinorVersion": 0,
"BusinessEventLegalEntity": "USMF",
"ContextRecordSubject": "",
"InitiatingUserAADObjectId": "{B6FC4F74-F4A3-A337-AC96-64F29525FE7F}",
"ParentContextRecordSubjects": [],
"eventSequence": 48574,
"correlationId": "Event:9b8879f9-9007-4f2f-8c90-d232d6e235c3",
"schemaVersion": 1,
"legalEntity": "usmf",
"qualityOrderId": "QO-000142",
"itemId": "D0001",
"testGroupId": "TG-FINISHED",
"referenceId": "PO-000087",
"orderStatus": 2,
"orderStatusName": "Pass"
}
Activation
In the D365FO client, go to System administration > Setup > Business events > Business events catalog. Find this event by name ("Quality order passed") 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).
Related Events
- Quality Order Failed - sibling event raised from the same
MGCLatticeInventQualityOrderValidate_Class_Extension.run()wrapper on a status transition toFail.
The two events are the two outcomes of one validation and carry different payloads: this event carries the order, item, test group, reference and status; Quality order failed also carries the item search name, quantities, route, operation, work center, inventory transaction, the validating worker and the validation time. Microsoft's catalog also contains a Warehouse management event for quality order validation (WHSQualityOrderValidatedBusinessEvent); a subscriber that needs only passed orders uses this event.