Master Data Sync Strategy Deep Dive: From Guanyi Cloud to Kingdee Cosmic
What This Strategy Solves
In one retail project we ran, the e-commerce business lived in Guanyi Cloud while finance and supply-chain accounting ran on Kingdee Cosmic — both sides maintained their own copy of the master data. After three months the codes drifted, specs diverged, and units got messy: the same SKU had quietly grown into two different things on each side. In that engagement we used the Qeasy integration platform to build a single strategy that incrementally pushes Guanyi Cloud item master data to Kingdee Cosmic's material archive, using the business code as the single key, so a change in one place is reflected everywhere.
Data Flow and Field Mapping
The flow is straightforward: Guanyi Cloud items (QUERY) → Qeasy intermediate layer → Kingdee Cosmic material (EXECUTE). The source side pulls incrementally by modify_date; the target side locates by code and performs upsert.
Key field mapping:
| Target field (Kingdee Cosmic) | Source field / rule (Guanyi Cloud) | Mapping type |
|---|---|---|
| number (material code) | code (item code) | DIRECT |
| name (item name) | name | DIRECT |
| model (spec/model) | skus | DIRECT |
| base_unit_id (unit id) | item_unit_name → cross-strategy lookup | COLLECTION |
| id (update key) | reverse lookup by number via _mongoQuery | COLLECTION |
| ignore_warn | constant true | CONSTANT |
Note: barcode is required on the target but currently null; a business-side mapping rule must be added (covered in the pitfalls section below).
How to Configure on Qeasy
When configuring this strategy on Qeasy, our first rule is always "centralize code mappings." Both cross-strategy lookups are implemented via _mongoQuery:
- id lookup (upsert decision): from the "Query Kingdee Item List" strategy, look up
content.idwherecontent.numberequals{{code}}. If found, pass it as the update key; if not, leave it blank and trigger an insert. - base_unit_id (unit mapping): from the unit strategy, look up
content.idwherecontent.numberequals{{item_unit_name}}, converting names like "pcs" / "box" directly to Kingdee unit keys.
The target's idCheck=true, combined with _mongoQuery, delivers standard upsert semantics. This is the classic "header / body in stages" pattern we use on Qeasy — first fetch the business key, then write the master record, leaving room to hang image or attachment body fields off the same key later.
Implementation Steps
Step 1: Confirm the incremental starting point. In the Qeasy scheduler, set start_date to {{LAST_SYNC_TIME|datetime}} and end_date to {{CURRENT_TIME|datetime}}. For the first run, manually specify an early time as the starting point to avoid missing data.
Step 2: Full backfill trigger. Temporarily change the source crontab to one-shot, pull all historical items, and write them to Kingdee. After verifying row counts and code consistency on both sides, switch back to incremental.
Step 3: Frequency and staggering. Source recommended */3 7-21 * * * (every 3 minutes during business hours). Target recommended 2-59/3 7-21 * * * — staggered by one minute from the source so they don't pile up at the same instant. This is a common pattern on Qeasy: incremental by default, periodic full backfills as safety nets.
Step 4: Warm up lookup strategies. The unit and item-list strategies must be online before the material sync, otherwise the first writes will fail because unit ids cannot be resolved.
Step 5: Observation window and alerts. Monitor logs for 3 days after go-live, focusing on ignore_warn content, missing barcode errors, and unresolved unit lookups.
Lessons From the Field
1. The barcode field is required but unmapped — the most common crash site. Kingdee's material API has barcode marked is_required: true, while Guanyi items don't always carry one. The safe approach: first try to parse the barcode out of the skus array; if there's truly none, fall back to code as a placeholder, or confirm with the business whether empty-string is tolerated.
2. skus is an array, model is a string. Source skus is array, target model is string — direct passthrough will fail serialization. A classic failure: first batch of 200 records, 199 errors. The safe move is to add a TRANSFORM that takes the first spec or concatenates multiple specs; do not pass {{skus}} through directly.
3. Unit lookup hit rate rarely hits 100%. If Guanyi uses mixed simplified/traditional names like "件/件/件", or if Kingdee's unit number stores a code instead of a name, the lookup will miss. The safe approach is to run a unit-dictionary reconciliation before go-live: either clean the source-side names, or switch the lookup condition from item_unit_name to item_unit_code.
4. Wrong incremental start point silently drops a batch. If LAST_SYNC_TIME is taken as "last successful end time" rather than "last pull start time", the gap gets swallowed. Easy to miss — the safe practice is to overlap the window by 1–2 minutes.
5. idCheck only works correctly when paired with _mongoQuery. Setting idCheck=true without the _mongoQuery reverse lookup means every record goes through as an insert, creating duplicates. Always put _mongoQuery in the id field's value expression so the logic closes the loop.
When to Use and When Not to Use
Use when: Guanyi Cloud is the source of truth for items, Kingdee Cosmic is the downstream finance / supply-chain system, both sides share a unified code rule, and code is the single business key for item-level sync.
Do not use when: items that don't exist in Guanyi Cloud, master data that must be isolated by organization or store, or scenarios with sub-3-minute real-time requirements — this strategy runs at a 3-minute cadence at best.