Qeasy Cloud
Get Started

Master Data Sync from Kingdee Cloud to JKY: A Single-Strategy Tutorial

· 吕修远· Integration Solutions· 32 views· 4 min read
吉客云Kingdee Cloud物料主数据供应链集成Incremental Sync轻易云

What This Strategy Solves

Material master data is the foundation of any supply chain. A retail enterprise uses Kingdee Cloud for finance and planning, while its front-end business runs on JKY. Both systems need to maintain the same item file — once codes or names drift apart, downstream orders, inventory, and reconciliation all break. This strategy does one thing: push approved materials from Kingdee Cloud to JKY's SKU file incrementally, keeping master data consistent across the chain.

Data Flow and Field Mapping

The flow is unidirectional: Kingdee Cloud (source) → JKY (target). No intermediate storage — it streams through Qeasy's integration pipeline.

The source object is Kingdee's material master form BD_MATERIAL, fetched via executeBillQuery. The target is JKY's SKU file, written in batches through erp.goods.skuimportbatch.

Key field mapping:

Target (JKY)Source (Kingdee)Mapping TypeNotes
goodsNameFNameDIRECTItem name
goodsNoFNumberDIRECTItem code (business key)
outSkuCodeFNumberDIRECTExternal code, same as material code
unitNameFSaleUnitIdDIRECTSales unit (watch for nested structure)
skuNameFSpecificationDIRECTSpecification
skuBarcodeFNumberDIRECTCurrently uses material code as placeholder
isBatchManagementConstant 0CONSTANTDefaults to No, extensible
cateCode / cateNameemptyCONSTANTLeft empty, extend later via collection mapping

Source fields like FMATERIALID, FBARCODE, FCategoryID, FExpPeriod are fetched but unmapped — kept in Qeasy for future activation as needed.

How to Configure in Qeasy

In Qeasy, the strategy splits into two nodes: source QUERY + target EXECUTE.

Source configuration:

  • api: executeBillQuery, FormId hard-coded as BD_MATERIAL
  • FieldKeys: select only the fields used this run (FNumber, FName, FSpecification, FSaleUnitId) to slim down responses
  • number and id both set to FNumber, idCheck: false (source does not enforce check)
  • FilterString: FApproveDate>='{{LAST_SYNC_TIME|datetime}}' — this is the core of incremental sync
  • Limit: 2000, StartRow uses platform variable {{PAGINATION_START_ROW}} for auto pagination

Target configuration:

  • api: erp.goods.skuimportbatch, method POST
  • idCheck: true, so the target decides insert vs update based on goodsNo / outSkuCode
  • Field mapping per the table above, constants written directly

Centralized code mapping: Qeasy supports placing cross-strategy code lookups (such as the future FCategoryID → cateCode mapping) in a hub or dedicated strategy, accessed via _findCollection. This is a common pattern — keeping encoding rules in one place avoids the trap of fixing one strategy and forgetting another.

Implementation Steps

Three phases.

Phase 1 — initialize the incremental anchor. For the first run, do a full historical pull: set LAST_SYNC_TIME to a very early date (e.g. 2000-01-01) so the platform pushes every approved material to JKY. After this run, LAST_SYNC_TIME is automatically updated to the current sync timestamp.

Phase 2 — full trigger and validation. Once the full sync completes, manually spot-check that codes, names and specs match on both sides. Pay special attention to two cases: unit fields that look wrong (when FSaleUnitId returns nested objects, unitName is written as-is), and SKUs whose barcode is a material code placeholder.

Phase 3 — steady-state scheduling. Set the crontab to */15 7-23 * * *, running every 15 minutes during business hours. Qeasy's scheduler maintains LAST_SYNC_TIME automatically — no manual intervention needed.

Dual-track full + incremental: another common Qeasy customer pattern — full sync only runs manually during initialization or data repair; day-to-day relies entirely on incremental, which is both stable and fast.

Lessons Learned

First, nested structures on unit fields. FSaleUnitId in Kingdee usually returns a nested object. If you write {{FSaleUnitId}} directly, the target receives a JSON string and the unit name becomes something like [object Object]. The safe move is to expand it in Qeasy — write {{FSaleUnitId.FName}} — or use a COLLECTION lookup against the unit table.

Second, the barcode placeholder risk. The current skuBarcode uses {{FNumber}} as a placeholder. Once the business side finds scanned codes are not real barcodes, troubleshooting becomes painful. The recommendation: switch skuBarcode to {{FBARCODE}} from the first deployment, and use _function to handle nulls — fall back to the material code when the barcode is empty.

Third, incremental anchor rollback. If someone accidentally rewinds LAST_SYNC_TIME to a much earlier date, the system triggers a full re-push, and the target may reject duplicates. In Qeasy, enable idCheck on the target and watch alert logs right after the first push.

Fourth, FCategoryID left empty as an extension point. The source material leaves cateCode and cateName as empty constants — a "get it running first, fill in later" compromise. When extending to category mapping, always use COLLECTION rather than hard-coding, or categories will desync the moment they change.

Fifth, scheduling window trade-offs. */15 7-23 * * * is a rule of thumb. Material approvals are rare at night, so narrowing to 7–23 reduces wasted calls. But if the customer has cross-time-zone night shifts, extend the window to 24 hours.

When to Use and When Not to Use

Use when: there is one ERP source of truth for master data, the target needs to mirror the material file, and incremental sync on approval date covers all changes. Do not use when: bidirectional material sync is required, related master data (supplier, customer) must be joined and pushed together, or the target carries many manually maintained local fields that need a dedicated conflict-merge strategy.

Original content. Please credit the source when reposting: https://www.qeasy.cloud/insights/solutions/strat-p2ea595-kingdee-cloud-3393-n4f0313cd-56ac27e0

Comments