Sales Order Sync Strategy: Integrating Xiaoman OKKICRM with Lingmao
What This Strategy Solves
Pushing sales orders from CRM to downstream ERP/SCM looks like simple data搬运, but misaligned codes, sloppy time windows, and a poorly set incremental starting point will cause the numbers on both sides to drift within three months. In a project for a retail enterprise, the business pain was direct: sales orders placed in Xiaoman OKKICRM had to enter the Lingmao system quickly for downstream procurement, production, and shipment scheduling. Manual export was slow and error-prone. This strategy pulls CRM orders incrementally by time window, cleanses them, and writes them into Lingmao via WebAPI, achieving near-real-time sync.
Data Flow and Field Mapping
The flow is unidirectional: Source (Xiaoman OKKICRM) → Qeasy Integration Platform (middleware) → Target (Lingmao).
The source is a query interface /v1/invoices/order/list, method GET, paginated by start_time / end_time window, with primary key order_id and document number name. The target is an execute interface /v1/ReqOrder/UpdateSaleOrder, method POST, with primary key id and idCheck enabled (the target is verified before write).
Key field mapping (from source/target metadata):
| Business Meaning | Source Field (Xiaoman OKKICRM) | Target Field (Lingmao) | Mapping Note |
|---|---|---|---|
| Document Number | name | id | Business key shared across both sides |
| Order Date | create_time | OrderDate | Datetime passed through |
| Customer Code | company.serial_id | CustomerCode | Pulls associated customer code |
| Order Type | (enum) | OrderType | Managed via Qeasy centralized code mapping |
| Warehouse Code | (default) | WarehouseCode | Fixed as A01 at the customer site |
| Production Type | (fixed value) | ProductionType | Defaults to "Finished Goods Procurement" |
| Start Index | start_index | — | Pagination control |
| Page Size | count | — | Pagination control |
Code mappings (order type, customer code, etc.) are maintained centrally in Qeasy, so adding a new enum value later requires a single edit without touching strategy scripts.
How to Configure in Qeasy
In the Qeasy console, this strategy has four core configuration points:
- Source platform action: Select type QUERY, fill in API
/v1/invoices/order/list, method GET. Bindstart_time/end_timeto Qeasy's built-in time variables (LAST_SYNC_TIME,CURRENT_TIME) to enable incremental pulls by last sync time.start_indexdefaults to 1,countdefaults to 10, and pagination is handled by the platform. - Target platform action: Select type WebAPI (EXECUTE), fill in API
/v1/ReqOrder/UpdateSaleOrder, method POST, and map source fields into the request body per the mapping table. KeepidCheckenabled — the platform queries the target byidbefore writing, routing to update if it exists or create if not. - Data transformation: Use Qeasy's field mapping and cleansing nodes to handle date format, null values, and units. Enums like order type should go through the code mapping table rather than being hard-coded in scripts.
- Scheduling and dependencies: Source cron set to
1-59/10 7-23 * * *(every 10 minutes during business hours, avoiding the top of the hour); target cron set to*/10 * * * *(triggered asynchronously by source events; the platform guarantees dependency order).
Implementation Steps
We recommend a three-phase rollout to proceed safely:
Phase 1: Initialize the incremental starting point. Run a one-time full historical backfill first (set start_time back to the business starting point), then switch to incremental. The LAST_SYNC_TIME variable must come from "the last successful completion timestamp", not "this run's start time" — this is a classic mistake.
Phase 2: Full trigger and validation. Manually trigger a full run in Qeasy and verify that source pagination returns complete data, the target returns 200, order numbers are unique, and amounts and customer codes are consistent. A common pattern at customer sites is "header and line items in phases": write document headers first; once confirmed OK, trigger line items, making it easier to localize errors to header or line.
Phase 3: Confirm scheduling frequency. Source pulls every 10 minutes; target is triggered by source events and does not need its own high-frequency cron. Reconcile daily for the first week after launch, then weekly; freeze the strategy immediately on anomalies.
Pitfalls and Lessons Learned
- Wrong timestamp for incremental starting point: A common mistake is using "this schedule's start time" as the incremental anchor, leading to missing or duplicate data. The safe approach is to use the platform-provided "last successful sync time" variable.
idCheckdisabled causing duplicate documents: Without verification, hard-writes produce duplicate numbers and break downstream production scheduling. KeepidCheckenabled in Qeasy.- Enums scattered across scripts: Hard-coding order type or production type means nobody knows what to change after a business adjustment. Always go through Qeasy's centralized code mapping.
- Cron pinned to the top of the hour: Top-of-hour scheduling causes database contention when multiple strategies run concurrently. Source-side offset patterns like
1-59/10are more stable. - Time desync in on-premise environments: When source, platform, and target machines have different timezones or NTP states, time windows miss records. Standardize the timezone and enable NTP.
Suitable and Unsuitable Scenarios
Suitable: Near-real-time sync of sales orders between CRM and downstream ERP/SCM, with header-dominated fields, an order volume a single strategy can handle, and on-premise deployment where both ends expose OpenAPIs. Unsuitable: Bidirectional sync, very large order volumes that require sharding, or interfaces rate-limited below 1 request/minute — the latter should use async queues or file exchange.