Skip to main content

Customer created

Fires when a new customer master record (CustTable) is created in a legal entity. This captures the moment a customer is onboarded to a company, so downstream systems (CRM, billing, credit, master-data hubs) can create the matching record the instant the customer account exists. The same event is also emitted for every existing customer when the Lattice customer resync job is run (see Trigger / Hook), so subscribers should treat it as an upsert keyed on legalEntity + customerAccount rather than as a strictly once-only signal.

Event classMGCLatticeCustomerCreatedBusinessEvent
Contract classMGCLatticeCustomerCreatedBusinessEventContract
CategoryAccounts receivable
ModuleModuleAxapta::Customer
Label IDsCustomerCreatedBusinessEventName / CustomerCreatedBusinessEventDescription
TriggerCustTable.insert() -> always fires on insert (no condition); also sent once per existing customer by the customer resync job

Trigger / Hook​

The event has two send sites.

1. Customer insert

  • Extension class: MGCLatticeCustTable_Table_Extension, [ExtensionOf(tableStr(CustTable))]
  • Exact CoC method signature: void insert(DirPartyType _partyType, Name _name, boolean _updateCRM)
  • Firing condition: fires unconditionally after next insert(...) returns - every customer created through CustTable.insert() (the customer form, data entities, X++) triggers the event. There is no orig() transition guard or type filter (this is an insert, so there is no prior record state to compare). Writes that bypass CustTable.insert() (doInsert(), or set-based inserts run with skipDataMethods(true)) do not raise it.
  • Timing: send() runs immediately after the insert 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(MGCLatticeCustomerCreatedBusinessEvent)) must return true (the event is activated for the current legal entity).
void insert(DirPartyType _partyType , Name _name,boolean _updateCRM)
{
next insert(_partyType, _name, _updateCRM);

if (BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeCustomerCreatedBusinessEvent)))
{
MGCLatticeCustomerCreatedBusinessEvent::newFromCustTable(this).send();
}
}

2. Customer resync (bulk publish)

  • Class and method: MGCLatticeBulkEventSourceCustomer.publishAll(MGCLatticeBulkEventPublisher _publisher), driven by MGCLatticeBulkEventPublisher. It is started from the action menu item MGCLatticeProcessAllCustomers ("Publish all customer business events (resync)"), which asks for confirmation and then runs the publish in a separate session.
  • Behavior: walks every CustTable record in the current company and sends this event for each one, pausing 250 ms after every 500 events (the publisher's default throttle). The loop is not wrapped in a transaction, so each event is committed as it is sent.
  • Enablement: before reading any record, the resync checks that the event is published in the current legal entity (business events framework on, event activated). If not, it stops with "The business event MGCLatticeCustomerCreatedBusinessEvent is not activated in legal entity <company>, so no events were published. Activate it in the business events catalog and run the job again." The finish message ("Bulk business event publish finished. Emitted n events for Customer.") counts only events actually published.
  • Availability: the menu item is at System administration > Periodic tasks > Lattice business events > Publish all customer business events (resync). The MGCLatticeProcessAllCustomersExecute privilege grants it to the integration administrator role (MGCLatticeIntegrationAdministratorRole) through the batch maintenance duty (MGCLatticeBatchMaintenanceDuty).
public void publishAll(MGCLatticeBulkEventPublisher _publisher)
{
CustTable custTable;

while select custTable
{
MGCLatticeCustomerCreatedBusinessEvent businessEvent = MGCLatticeCustomerCreatedBusinessEvent::newFromCustTable(custTable);

businessEvent.send();

_publisher.onPublished(businessEvent, custTable.AccountNum);
}
}

Payload Contract​

One row per [DataMember], in declaration order. All sources are read from the CustTable record in initialize().

JSON fieldDisplay labelType / EDTSourceNotes
legalEntityLegal EntityDataAreaIdCustTable.DataAreaIdCompany (data area) the customer belongs to, in lower case (for example usmf).
customerAccountCustomer AccountCustAccountCustTable.AccountNumCustomer account number.
customerNameCustomer NamestrCustTable.name()Display method that resolves the party name from the global address book when the contract is built (not a stored CustTable field).
customerGroupCustomer GroupstrCustTable.CustGroupCustomer group code (source EDT CustGroupId; the contract declares it as str).
crossReferencesCross referencesList of MGCLatticeCrossReferenceEventContractMGCLatticeCrossReferenceEventHelper::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": "MGCLatticeCustomerCreatedBusinessEvent",
"ControlNumber": 5637148472,
"EventId": "1F8B0C2A-7D3E-4A91-9C5B-2E6F0D4A1B73",
"EventTime": "\/Date(1790244775000)\/",
"EventTimeIso8601": "2026-09-24T10:12:55.7773705Z",
"MajorVersion": 0,
"MinorVersion": 0,
"BusinessEventLegalEntity": "USMF",
"ContextRecordSubject": "",
"InitiatingUserAADObjectId": "{0147389C-C6A1-794C-CE03-DD5050D02080}",
"ParentContextRecordSubjects": [],
"eventSequence": 48213,
"correlationId": "Event:3c9e7a21-5b4d-4e8f-9a61-0d2b7c4e8f15",
"schemaVersion": 1,
"legalEntity": "usmf",
"customerAccount": "US-042",
"customerName": "Contoso Retail Inc.",
"customerGroup": "30",
"crossReferences": [
{
"externalSystem": "CRM",
"externalKey": "ACC-000481"
}
]
}

Activation​

In the D365FO client, go to System administration > Setup > Business events > Business events catalog. Find this event by name ("Customer created") or by filtering the Category column to Accounts receivable. 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). To seed a subscriber with the customers that already exist, activate the event first and then run the customer resync job described under Trigger / Hook in each company to be loaded.