Practical Guide: Synchronizing Offline Sales Outbound Documents to JKY Sales Orders
What This Strategy Solves
Offline transactions from stores, direct sales, and wholesale operations remain in the financial and supply-chain system, while the target business platform cannot see the corresponding orders and therefore cannot continue warehouse fulfillment and logistics tracking. In one project, we used the Qeasy Data Integration Platform to handle this flow: retrieve offline sales outbound documents by approval time, group them by document number, and then create target sales orders. This preserves the source document number as the business key and prevents a document with multiple lines from being split into multiple orders.
Data Flow and Field Mapping
The overall flow is: Kingdee Cloud → Qeasy Data Integration Platform → JKY. The source returns flattened records, so header fields are repeated for every line belonging to the same document. The intermediate layer must group the records by FBillNo and form one header document with one detail array. Qeasy provides centralized code mapping for maintaining relationships among customers, materials, warehouses, and other master data.
| Object | Key Field | Target Field | Processing Rule |
|---|---|---|---|
| Header | FBillNo | tradeNo | Direct mapping; the source number is the business key |
| Header | FDate | consignTime/orderTime | Direct mapping |
| Header | FCustomerID_FNumber | customerCode/shopCode | Map the customer code |
| Header | FCustomerID_FName | receiverName | Use the customer name as a default |
| Header | F_recipient | receiverName | Recipient contact takes priority |
| Header | F_Receiving_phone_number | receiverPhone | Direct mapping |
| Header | Province/city/district/detail address | receiverProvince and related fields | Prefer separate fields; concatenate when required |
| Header | FStockID_FNumber | warehouseCode | Map the warehouse code |
| Header | FSalesManID_FNumber/Name | sellerCode/sellerName | Map salesperson data |
| Header | FSaleOrgId_FNumber | orgCode | Map the organization code |
| Constant | — | tradeType | Set to “offline” or the agreed code |
| Constant | — | source | Set to OPEN |
| Detail | details_list | goodsDetail | Generate one target line for each grouped line |
| Detail | FMaterialID_FNumber | goodsNo | Map the material code |
| Detail | Barcode field | barcode | Use as an auxiliary identifier |
| Detail | FRealQty | sellCount | Use the actual outbound quantity |
| Detail | FPrice/FTaxPrice | sellPrice/taxPrice | Map unit prices |
| Detail | FAmount | sellTotal | Map the amount |
| Detail | FEntrynote | goodsMemo | Map the line note |
| Detail | Entry identifier | recId/id | Optional; used to locate a detail line |
How to Configure It in Qeasy
Configure the source query object as SAL_OUTSTOCK, retrieving the document number, entry identifier, date, customer, salesperson, material, quantity, price, warehouse, and receiving information. The filter must constrain the offline document type, approval time, and the required business exclusions. Use Limit and StartRow for pagination, and disable automatic filling of missing values so that nonexistent relationships are not fabricated.
The intermediate layer should group records by document. The source configuration currently has buildModel disabled, while the target interface requires an object. Therefore, explicitly aggregate the records into details_list using FBillNo; do not treat each flattened row as a separate sales-order request.
On the target side, set tradeOrder as an object and expand its child fields. Reference details_list for goodsDetail. Perform duplicate checking with tradeNo=FBillNo, and send failures to a retry or exception queue. Qeasy is suitable for centrally managing header mappings, detail mappings, constants, and filters. If customer or material master data has not been standardized, establish the mappings first instead of converting codes while processing a document.
Implementation Steps
- Prepare master data: Standardize customer, material, and warehouse codes first, and confirm which fields may be empty as well as the accepted date format.
- Set the incremental start point: Initialize the platform’s
LAST_SYNC_TIMEto the first full-sync boundary and retrieve data using the approval-date condition. Run the initial full load during a low-business period. - Trigger the full load: Retrieve offline outbound documents in the defined range, group them by document number, and write them to the target. Record the source, target response, and processing status for every document.
- Run incremental jobs: Offset the source and target schedules and run them every five minutes. Advance the incremental cursor only after the previous batch succeeds, preventing data loss.
- Perform compensation checks: Retry documents that fail, time out, or return an abnormal response manually or automatically. Reconcile quantities by date and document number rather than judging success by the total number of rows.
- Observe the cutover: Monitor creation, warehouse fulfillment, and logistics status for new documents. Close the project only after confirming that duplicate orders are not being created.
Lessons Learned
- A typical mistake is pushing flattened rows directly. The source can return multiple lines for one document. Without grouping by
FBillNo, the target receives multiple orders. Aggregate first, then usedetails_listto generategoodsDetail. - Using only the update time for incremental sync can cause omissions. Use the approval date as the synchronization condition and update the cursor only after successful processing. If master data changes, compensate the affected documents.
- Matching field names is not enough. Identical names do not mean identical codes. A common Qeasy customer practice is to centralize customer, material, and warehouse code mappings and block processing when a required mapping is missing.
- The wrong quantity basis causes inconsistencies. This strategy prioritizes the actual outbound quantity
FRealQty. Using the planned quantity instead would make the order inconsistent with the outbound fact and affect warehouse operations. - Incremental and full synchronization should not be mutually exclusive. Use a dual-track model: incremental processing by approval date for daily operations, and a clearly bounded full load for initialization or master-data repair. The full-load range must not conflict with the incremental cursor. Another common rollout pattern is to implement headers and details in phases: first enforce required header and product-detail fields, then add tax rates, expiration dates, and other extended fields.
Suitable and Unsuitable Scenarios
This strategy is suitable for private deployments that need to bring offline outbound transactions from stores, direct sales, or wholesale into a target platform for warehouse fulfillment and logistics tracking. It is not suitable when real-time outbound processing is mandatory, source documents are frequently reversed and changed, or online and offline orders must be merged or split. Those cases require explicit change-capture and order-aggregation rules.