Qeasy Cloud
Get Started

From Kingdee Cloud Material to JKY Goods SKU: A Single-Strategy Integration Tutorial

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

What This Strategy Solves

Syncing material master data from the ERP to downstream business systems looks simple, but it is the most common source of integration pain: inconsistent code rules, missing unit names, and un-extended hooks for batch/expiry/serial management mean numbers stop matching within three months of going live. In real projects, we use the Qeasy iPaaS to host this pipeline—pulling Kingdee Cloud materials incrementally by approval date and writing them into JKY goods SKUs, forming the foundation for upstream-downstream master-data unification across the supply chain.

Data Flow & Field Mapping

The data flow is straightforward: Kingdee Cloud (Material BD_MATERIAL) → Qeasy middleware → JKY (Goods SKU). The source uses the executeBillQuery API; the target uses the erp.goods.skuimportbatch bulk-import API.

Target Field (JKY)Source/Rule (Kingdee)Mapping TypeNotes
goodsName{{FName}}DIRECTGoods name
goodsNo{{FNumber}}DIRECTGoods code, business key
goodsAlias{{FName}}DIRECTAlias same as name
unitName{{FPurchaseUnitId_FName}}DIRECT/COLLECTIONUnit name; source only returns base-unit code, lookup needed
outSkuCode{{FNumber}}DIRECTExternal SKU code
skuBarcode{{FBARCODE}}DIRECTBarcode
skuName{{FSpecification}}DIRECTSpecification
isBatchManagement0CONSTANTBatch management; later extend to TRANSFORM
isPeriodManage0CONSTANTExpiry management
isSerialManagement0CONSTANTSerial-number management
goodsAttr1CONSTANTGoods attribute: 1 = finished goods

Centralized code mapping: Qeasy's COLLECTION (collection mapping) and _findCollection cross-strategy lookup keep unit names, material attributes, and inventory categories translated in one mapping table rather than scattered across every strategy.

How to Configure on Qeasy

Source configuration highlights:

  • api: executeBillQuery, type QUERY, method POST
  • FormId: fixed as BD_MATERIAL
  • number/id/idCheck: FNumber / FMasterId / true
  • Pagination: Limit=2000, StartRow uses the {{PAGINATION_START_ROW}} placeholder
  • FilterString: FApproveDate>='{{LAST_SYNC_TIME|dateTime}}'—only pulls rows approved after the last sync timestamp
  • crontab: 0-59/5 7-22 * * *, every 5 minutes during business hours

Target configuration highlights:

  • api: erp.goods.skuimportbatch, type EXECUTE
  • crontab: 1-59/5 7-22 * * *, offset by one minute from the source to avoid race conditions where the next round fires before the previous one commits
  • idCheck: true, uses goodsNo / outSkuCode as the business key to determine insert vs. update

The field-mapping layer binds the {{source field}} placeholders to target fields one by one; constant fields take 0 or 1 directly with no expression needed.

Implementation Steps

  1. Initialize the incremental watermark: In the Qeasy scheduler, set LAST_SYNC_TIME to a historical timestamp (e.g., the day before go-live) and run one full backfill round to ensure all historical materials land in JKY. This step is often skipped—and results in an empty JKY in week one.
  2. Full trigger & validation: Manually trigger one Source → Target end-to-end run; reconcile the goods count and spot-check key fields in the target; only then switch to scheduled execution.
  3. Bring the schedule online: Source 0-59/5 7-22 * * *, target 1-59/5 7-22 * * *. Roll out header (basic) fields first, then body/extended fields in stages to limit per-change blast radius.
  4. Reserve extension points: Ship isBatchManagement, isPeriodManage, isSerialManagement as constant 0 first, then convert to _function expressions reading Kingdee's FIsBatchManage, FIsKFPeriod, FIsSNManage whenever needed.
  5. Monitoring & alerts: Configure "3 consecutive rounds with zero data" and "retry-failure over threshold" alerts in Qeasy's run monitor, so newly approved materials land within 5 minutes.

Post-Mortem Lessons

  • Classic mistake #1: unit name comes back empty. The source executeBillQuery returns only FBaseUnitId_FNumber (base-unit code), but the target wants a name. The safe approach is to use _findCollection in Qeasy to look up FName from the unit-of-measure scheme—rather than hard-coding unitName as a constant.
  • Classic mistake #2: filter only on approval date. If someone changes a material's specification without re-approving, the target never updates. Later you can fold FModifyDate or FForbidStatus into FilterString for a dual-condition increment.
  • Classic mistake #3: batch/expiry/serial hard-coded as constants. At go-live the business is indeed all finished goods with no batch, but three months later they enable batch management—changing three fields is ten times more painful than changing one. Bind them to source fields via _function from day one; fix the values later if needed.
  • Classic mistake #4: source and target crontabs perfectly aligned. Both fire at the same second; the target tries to match keys while the source is still paging, causing duplicate writes or missed updates. Offsetting by one minute is the safest pattern.
  • Classic mistake #5: goodsAttr fixed to finished goods. Kingdee's FErpClsID is a material-attribute code; JKY uses a 1/2/3/4 enumeration. Long-term hard-coding misaligns all semi-finished and raw-material data. Build the code-mapping table from the start and maintain it via COLLECTION.

When to Use / Not Use

Use when: the ERP is the master-data source of truth and downstream e-commerce/OMS/WMS systems consume by code; material attributes are stable with manageable change frequency; traceable incremental sync is required.

Don't use when: you need bidirectional master-data sync where both code schemes must coexist; the source system frequently merges/splits records without an approval flow; you require sub-minute real-time push via messaging instead of polling.

Original content. Please credit the source when reposting: https://www.qeasy.cloud/insights/solutions/strat-p2ea595-kingdee-cloud-3711-ok-fc3aaa5c

Comments