Wangdiantong Other-Outbound to Kingdee Other-Outbound: A Fault-Tolerant Sync Strategy in Practice
What This Strategy Solves
In a retail enterprise's warehouse, a large number of "Other-Outbound" stock documents are generated every day — inventory shrinkage, internal requisitions, sample gifts, and other non-sales outflows. These documents must be recorded in Wangdiantong and also posted to the financial inventory ledger in Kingdee Cloud Celestial. In one real project, the customer reported that the workload peaked at 8 PM and 10 AM, and three recurring issues appeared: "source has the document, target does not", "amounts differ by a few cents", and "documents stuck in pending approval".
The core goal of this strategy is to use Wangdiantong·QiMen as the source and Kingdee Cloud Celestial as the target. It pulls outbound documents within a time window, cleans the fields, writes them downstream, and guarantees eventual consistency under network jitter, duplicate documents, and missing codes.
Data Flow and Field Mapping
Overall flow: Wangdiantong (source) → Qeasy middleware layer → Kingdee Cloud Celestial (target). The middleware layer handles three things: time cursors, field mapping, and fault-tolerant accumulation.
| Business Meaning | Wangdiantong Source Field | Qeasy Middleware Variable | Kingdee Target Field |
|---|---|---|---|
| Document Number | order_no | order_no | FBillNo |
| Document Type | order_type=7 | — | FBillTypeID (QTCKD01_SYS) |
| Stock Org | warehouse_no | org_code | FStockOrgId |
| Requisition Org | warehouse_no | org_code | FPickOrgId |
| Outbound Date | consign_time | consign_time | FDate |
| Requisition Dept | dept_no | dept_id | FDeptId |
The source-side start_time / end_time uses the two global variables LAST_SYNC_TIME and CURRENT_TIME to define the time window. The target-side batchSave uses batch submission. The header and body are processed in phases — the header lands first, then the body — preventing a single failed line from rolling back the entire document.
How to Configure on Qeasy
On the Qeasy Data Integration Platform, this strategy exists as a combination of a "source strategy" and a "target strategy":
- Source strategy: The API is
wdt.stockout.order.query. The request body bindsstart_time / end_timeto cursor variables,order_typeis hard-coded to7(other outbound),statusis left blank to pull all statuses, andidCheckis enabled for deduplication. - Target strategy: The API is
batchSave. Theidfield is used as the idempotency key. The document number reuses the source number directly through{{order_no}}, achieving consistent document numbers on both sides. - Code mapping: Fields prone to errors (stock organization, department, warehouse position, product code) are consolidated into the platform's "Code Mapping Table" for centralized maintenance. Subsequent field adjustments only require changing one table, not every strategy.
- Fault tolerance configuration: Enable "retry 3 times on failure + error queue isolation" so that a single failure does not block the entire batch. Idempotency keys combined with cursor persistence prevent duplicate documents during reruns.
Implementation Steps
We generally recommend a three-phase rollout:
- Incremental starting point (Day T0): Set the access moment as the starting point. Initialize
LAST_SYNC_TIMEto 24 hours before access. Run a "historical window backfill" first to fill in stock data around the breakpoint. At the same time, verify whether the document numbers match on both sides. - Full-volume trigger (Day T0+1): Use a small window (e.g., 3 days) for a full rerun to verify the coverage of the code mapping table and fill in any missing values.
- Scheduling frequency: The source uses
*/23 7-21 * * *, and the target uses*/28 7-21 * * *. The two times are staggered by 5 minutes. This ensures high-frequency coverage of business peaks (7 AM to 9 PM) while avoiding the instantaneous pressure caused by simultaneous pulls from both ends. During the off-peak period from 9 PM to 7 AM the next day, the cursor automatically bridges the gap.
After going live, reconciliation inspections are still required: compare "source document count vs. target landed document count" at 9 AM, 2 PM, and 9 PM every day. An alert is triggered if the difference exceeds the threshold.
Pitfall Review
- Typical error 1: hard-coding the status field. Someone set the default value of the source API's
statusto "approved", filtering out all pending requisition documents. The business side only discovered the next day that the documents had not arrived. The safer approach is to leavestatusblank for full pulls and let the target system determine the approval state itself. - Typical error 2: wrong idempotency key. In an early version, someone used
order_no + consign_timeas the idempotency key, causing duplicate landings when the same document's time was modified. Binding the idempotency key to the source system's unique ID (such asstockout_id) is the most stable approach. - Typical error 3: cursor drift. If the middleware layer uses "current time" as the cursor while scheduling occasionally delays, the same document gets pulled repeatedly in different windows. Always make the cursor use "the timestamp of the last successful landing" instead of the current time.
- Typical error 4: submitting the body all at once. When there are many product lines, a single
batchSavecall tends to time out. Submitting header and body in phases ensures that only the body is rerun on failure, which is more efficient and more fault-tolerant. - Typical error 5: overdone fault tolerance. With "unlimited retries" enabled, a single erroneous record repeatedly consumes quota. Setting an upper limit of 3 retries plus a dead-letter queue and involving manual intervention for recovery is more controllable.
Applicable and Non-Applicable Scenarios
Applicable: Retail or manufacturing enterprises syncing other-outbound documents from an e-commerce ERP (Wangdiantong) to a financial ERP (Kingdee Cloud Celestial), with moderate document volume (hundreds to thousands per day), requiring idempotency and fault tolerance.
Not applicable: Scenarios with extremely high real-time requirements (below minute-level), bidirectional write-back needs, or very large document volumes (tens of thousands of lines) without a batching mechanism. For the latter, it is recommended to first go through an asynchronous message middleware and let Qeasy consume from it.