Skip to main content

Opportunity Intake (O2C / pipeline capture)

A vertical intake accelerator that lands opportunity / qualified-lead extracts from a marketing automation or CRM platform and writes them to the LatticeOpportunity OData entity.

This is the catalog's exemplar for the odataEntity target style. The other bundles (vendor-invoice-intake, sales-order-intake, asn-product-receipt-intake, customer-payment-intake) use customService; this is the only bundle for the odataEntity style that schema/bundle.schema.json defines and Authoring, section 4a documents.

Flow​

Blob drop (OPPTY_*.csv)
-> File Ingestion connection (StorageType=Blob, FileFormat=Csv, CsvHasHeader=Yes)
-> one segment per data row
-> Liquid transform (transform.liquid, rendered ONCE PER SEGMENT) -> LatticeOpportunity record
-> POST /data/LatticeOpportunities <-- by an EXTERNAL client, see "Dispatch gap"

Target (verified against the AOT)​

ElementValue
AOT entityMGCLatticeOpportunityEntity
Public entity nameLatticeOpportunity
Public collectionLatticeOpportunities
Entity categoryTransaction
Primary keyEntityKey over OpportunityId
Company contextPrimaryCompanyContext = DataAreaId
IsReadOnlyNo (writable)
SubscriberAccessLevelRead only

Field names and types come from the entity and its DMF staging table (MGCLatticeOpportunityStaging), which mirrors the entity's field types exactly:

Entity fieldEDT / typeMapped?
dataAreaIdcompany (PrimaryCompanyContext)yes - from the dataAreaId activation parameter
OpportunityIdsmmOpportunityIdyes (key)
SubjectsmmOpportunitySubjectyes
SalesProcessNamesmmOpportunitySalesProcess (table field ProcessName)yes
ProbabilityIdsmmQuotationProbabilityIdyes
EstimatedRevenuesmmOpportunityEstimatedRevenueyes
OpenedDatesmmOpportunityOpenedDateyes
PrognosisIdsmmQuotationPrognosisIdyes
SalesUnitIdsmmSalesUnitIdyes - a blank column falls back to defaultSalesUnitId
ClosedDatesmmOpportunityClosedDateyes
PartyNumberDirPartyNumber (resolved to the party record)yes
OwnerPersonnelNumberHcmPersonnelNumberId (resolved to the worker record)yes
Statusenum smmOpportunityStatus, AllowEdit = Nono - not settable

Dispatch gap​

The file-ingestion pipeline cannot deliver to an OData entity today.

  • MGCLatticeFileIngestDispatcherFactory::construct always returns MGCLatticeFileIngestCustomServiceDispatcher.
  • The only class implementing MGCLatticeIFileIngestServiceTarget is MGCLatticeFileIngestServiceInvokeTarget, which invokes Lattice service operations - not entity writes.

So an odataEntity bundle is currently a design-time contract (entity identity, field mapping, payload shape) that an external OData client fulfils; it is not executable through the pipeline the way a customService bundle is. Closing this gap needs a change to the Lattice model; it is tracked in productDecisions.

Write-access gap - model-wide, not bundle-specific​

MGCLatticeOpportunityEntity grants SubscriberAccessLevel = Read only, so an integration subscriber cannot create rows until that grant is widened. This is not specific to this bundle: no entity in the Lattice model grants subscriber Create or Update. Every odataEntity bundle therefore inherits a "widen the grant" provisioning step, and because that is a metadata change it cannot be done at deploy time by a customer. Hence the required entityWriteAccessGranted activation parameter.

Other gaps​

  • Company scoping. PrimaryCompanyContext = DataAreaId means writes are company-scoped; a record without dataAreaId lands in the OData client's default company. The transform therefore writes dataAreaId into every record from the dataAreaId activation parameter.
  • No request id. Unlike the customService bundles, an entity write carries no RequestId and gets no run context: the record is identified by its key, OpportunityId.

Files​

  • manifest.json - bundle manifest (conforms to schema/bundle.schema.json).
  • sample.csv - three opportunities, including two deliberately unmapped columns.
  • mapping.json - column -> entity-field mapping (targetKind: odataEntity, record-level lines).
  • transform.liquid - Liquid template producing a single-element entity-record array.

Status​

draft, not preview - deliberately. The target entity is real and every mapped field is verified, but unlike the customService bundles this one has no executable delivery path in the pipeline today. It earns preview once an OData dispatcher exists, and released once subscriber write access and natural-key party resolution are settled.