Customer updated
Fires whenever an existing customer master record (CustTable) is saved through CustTable.update() - for example after a change to the customer group, credit limit, blocked status, or payment terms. Downstream systems can use this to keep customer master data in sync, refresh CRM/portal caches, or audit changes to the customer book. The payload identifies the customer (account, name, group) but does not say which fields changed; a subscriber that needs the full record reads it back after receiving the event. Changes saved only to related global address book records (for example a postal address) do not update the CustTable row and do not raise this event.
| Event class | MGCLatticeCustomerUpdatedBusinessEvent |
| Contract class | MGCLatticeCustomerUpdatedBusinessEventContract |
| Category | Accounts receivable |
| Module | ModuleAxapta::Customer |
| Label IDs | CustomerUpdatedBusinessEventName / CustomerUpdatedBusinessEventDescription |
| Trigger | CustTable.update(boolean, boolean) -> fires on every update (no field-change guard) |
Trigger / Hook
- Extension class
MGCLatticeCustTable_Table_Extension, decorated with[ExtensionOf(tableStr(CustTable))]. - Chain of Command wraps the table method with the exact signature:
void update(boolean _updateSmmBusRelTable, boolean _updateParty) - Firing condition: the event is sent after every successful
update()of aCustTablerecord - there is no field-change guard, so a save that changes none of the payload fields still raises it. The method capturesthis.orig().Blockedbefore callingnext(only when the hold status event is activated), but that captured value is only used to gate the separateMGCLatticeCustomerHoldStatusChangedBusinessEvent, not this one. - The same
update()override also sendsMGCLatticeCustomerHoldStatusChangedBusinessEventwhenorigBlocked != this.Blocked; in that case both events are raised by one save, this one first. The customer-created counterpart is sent from theinsert()override in the same extension. - Writes that bypass
CustTable.update()(doUpdate(), or set-based updates run withskipDataMethods(true)) do not raise it. - Timing:
send()runs immediately after the update and writes the event to the business events commit log within whatever transaction the caller has open; if that transaction is rolled back, the event is rolled back with it and never delivered. Delivery happens asynchronously after commit. - Enablement gate:
BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeCustomerUpdatedBusinessEvent))must return true (the event is activated for the current legal entity) before the event is built and sent.
void update(boolean _updateSmmBusRelTable, boolean _updateParty)
{
// The activation check is a cached lookup; read the original buffer only when the event is on.
boolean holdEventEnabled = BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeCustomerHoldStatusChangedBusinessEvent));
CustVendorBlocked origBlocked = holdEventEnabled ? this.orig().Blocked : this.Blocked;
next update(_updateSmmBusRelTable, _updateParty);
if (BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeCustomerUpdatedBusinessEvent)))
{
MGCLatticeCustomerUpdatedBusinessEvent::newFromCustTable(this).send();
}
if (holdEventEnabled && origBlocked != this.Blocked)
{
MGCLatticeCustomerHoldStatusChangedBusinessEvent::newFromCustTable(this, origBlocked).send();
}
}
Payload Contract
One row per [DataMember], in declaration order, populated by MGCLatticeCustomerUpdatedBusinessEventContract.initialize(CustTable) from the record after the update:
| JSON field | Display label | Type / EDT | Source | Notes |
|---|---|---|---|---|
legalEntity | Legal Entity | DataAreaId | CustTable.DataAreaId | Company/data area of the customer record, in lower case (for example usmf). |
customerAccount | Customer Account | CustAccount | CustTable.AccountNum | Customer account number. |
customerName | Customer Name | str | CustTable.name() | Resolved via the CustTable.name() display method (DirParty name), not a raw stored field. |
customerGroup | Customer Group | str | CustTable.CustGroup | Customer group code (source EDT CustGroupId; the contract declares it as str). |
crossReferences | Cross references | List of MGCLatticeCrossReferenceEventContract | MGCLatticeCrossReferenceEventHelper::listFor(CustTable) | Keys external systems hold for the customer: 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 inside the business transaction, not 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; an event that joins no run carries Event: followed by a lower-case 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": "MGCLatticeCustomerUpdatedBusinessEvent",
"ControlNumber": 5637148501,
"EventId": "5F3C2B18-7A4D-4E9C-8F12-9B3A6D2E1C44",
"EventTime": "\/Date(1790247806000)\/",
"EventTimeIso8601": "2026-09-24T11:03:26.6881969Z",
"MajorVersion": 0,
"MinorVersion": 0,
"BusinessEventLegalEntity": "USMF",
"ContextRecordSubject": "",
"InitiatingUserAADObjectId": "{5D3E6105-E97F-A1B7-AA91-01B416A74462}",
"ParentContextRecordSubjects": [],
"eventSequence": 48227,
"correlationId": "Event:a7d24e90-1c3b-4f65-8e2a-5b9c0d7f3e11",
"schemaVersion": 1,
"legalEntity": "usmf",
"customerAccount": "US-004",
"customerName": "Cave Wholesales",
"customerGroup": "30",
"crossReferences": [
{
"externalSystem": "CRM",
"externalKey": "ACC-000481"
}
]
}
Activation
- Go to System administration > Setup > Business events > Business events catalog.
- Filter the Category column to Accounts receivable (or search for Customer updated) to locate this event.
- Select the event and choose Activate to bind it to a configured endpoint (for example, an Azure Service Bus queue, Event Grid topic, or HTTPS webhook).
Related Events
- Customer created - created/updated pair; fired from the
insert()override of the sameMGCLatticeCustTable_Table_Extension. - Customer hold status changed - fired from the same
update()override when the customer'sBlockedstatus changes. - Customer credit limit exceeded - fired when a credit limit check finds the customer over the limit.
- Vendor updated - the Accounts payable counterpart for vendor master records.