Sales Order Intake (O2C)
A vertical intake accelerator that lands JSON order files and creates a sales order (header +
lines) through the Lattice sales-order capture Lattice service. This bundle uses the
customService target style (like vendor-invoice-intake), backed by the standard
AxSalesTable / AxSalesLine business-document framework.
Flow
Blob drop (ORDERS_*.json)
-> File Ingestion connection (StorageType=Blob, FileFormat=Json, RecordPath="" -> the root order object is one record)
-> Liquid transform (transform.liquid) -> { service, operation, requestKey, request } routing envelope
-> MGCLatticeFileIngestServiceInvokeTarget.handleIngestedContent
fills RequestId / LegalEntityId / UserContext / CorrelationId the request leaves empty
-> MGCLatticeSalesOrderCaptureService.createSalesOrder (AxSalesTable/AxSalesLine)
-> new SalesTable + SalesLine rows
Target (X++ objects)
| Element | Value |
|---|---|
| Service group | MGCLatticeAccountsReceivableServiceGroup |
| AxService / class | MGCLatticeSalesOrderCaptureService |
| Operation | createSalesOrder (also createSalesOrderBatch) |
| Request contract | MGCLatticeCreateSalesOrderRequestContract |
| Line contract | MGCLatticeSalesOrderCaptureLineContract |
| Security privilege | MGCLatticeSalesOrderCaptureServiceMaintain (Invoke) |
The operation creates the order via AxSalesTable::construct() (header: CustAccount, SalesType::Sales,
optional CurrencyCode / SalesOrderId / CustomerRef) and AxSalesLine::construct() per line (ItemId, SalesQty,
optional UnitId / UnitPrice, and a site/warehouse resolved to an InventDimId via
InventDim::findOrCreate). It reuses MGCLatticeOrderPostingServiceBase for the response contract
(MGCLatticeOrderOperationResponseContract), claim-first idempotency by RequestId, error
classification, and audit logging. A duplicate RequestId replays the created SalesId and never
creates a second order.
Request shape (routing envelope)
{
"service": "MGCLatticeSalesOrderCaptureService",
"operation": "createSalesOrder",
"requestKey": "MKT-2026-77120",
"request": {
"LegalEntityId": "USMF",
"CustAccount": "US-004",
"CurrencyCode": "USD",
"CustomerRef": "MKT-2026-77120",
"Lines": [
{ "ItemId": "D0001", "Qty": 10, "UnitId": "ea", "UnitPrice": 24.99, "SiteId": "1", "WarehouseId": "11" }
]
}
}
createSalesOrder refuses a request without RequestId (a GUID), LegalEntityId and
UserContext. The template writes LegalEntityId from the legalEntityId activation parameter
and names the order's stable id in requestKey; the service-invoke target fills every common
member the request leaves empty:
| Member | Filled with |
|---|---|
RequestId | A name-based GUID of the connection, the legal entity, MGCLatticeSalesOrderCaptureService.createSalesOrder and the requestKey. The same order ingested again, in any file, gets the same RequestId, and the service replays the created SalesId instead of creating a second order. Without a requestKey it is derived from the ingested file and record, which still makes a retried record replay. |
LegalEntityId | The company the processing batch job runs in. |
UserContext | The user the processing batch job runs as. |
CorrelationId | A name-based GUID of the connection and the ingested file, shared by all records of the file. |
A value the template writes always wins. requestKey itself never reaches the request.
The requestKey comes from the source field named by the requestIdSourceField activation
parameter (default orderReference): its token in transform.liquid is replaced with the field
name at provisioning.
The connection must list MGCLatticeSalesOrderCaptureService.createSalesOrder in Allowed service
operations; an empty list allows no operation, and every record is rejected.
Files
manifest.json- bundle manifest (conforms toschema/bundle.schema.json).sample.json- one order header with three lines;recordPath=""with a root order object makes the whole file one record.mapping.json- source-key -> contract-field mapping (header + lines).transform.liquid- Liquid template producing the{ service, operation, requestKey, request }envelope. It reads the order's members at the top level (orderReference,lines).
Status
preview. Order capture is a real service. The remaining open item (see productDecisions) is
whether to force explicit pricing or trust master data.