Qeasy Cloud
Get Started

Master Data Sync from ERP to MES: A Single-Strategy Playbook for Kingdee Cloud → MES

· 系统管理员· Integration Solutions· 1 views· 5 min read
四化智造MES(API)Kingdee Cloud物料主数据MES基础资料同步轻易云私有化集成

What this strategy solves

Material master data is the common language between ERP and MES. At one manufacturer, the material master lives in the ERP side (Kingdee Cloud) while the downstream MES consumes the same set of records for routing, inventory, and barcoding. On paper it looks like a simple push; in practice, after three months the codes, names and specifications drift apart on both sides. The root cause is rarely the API itself — it is the lack of upfront governance on field mapping, incremental anchors, and coding rules.

This strategy has a single goal: push material master records from Kingdee Cloud into the MES under a fixed field-mapping contract, so the shop floor always works against the latest revision. In customer engagements we consistently use the Qeasy data integration platform (轻易云) for this kind of base-data sync, because it turns source/target metadata, scheduling and exception handling into a visible strategy — no more living on top of cron scripts.

Data flow and field mapping

Direction: Kingdee Cloud (source, QUERY) → Qeasy middleware → MES (target, EXECUTE). The schedule window sits inside business hours (* 7-22 * * *), meaning this is a high-frequency, small-batch channel.

Key field mapping table

Business meaningSource field (Kingdee Cloud)Target field (MES API)Notes
Material primary keyFMasterIdmaterialUuidUse source PK as target UUID
Material codeFNumberpartNoCode is the main alignment anchor
Material nameFNamegradeNameName changes must be traceable
SpecificationFSpecificationspecPlain text, pass through
Old codeFOldNumberoldPartNoRequired for renumbering
Material groupFMaterialGroupclassifyNo / parentClassifyNoStaged header/body
Company codeFixed valuecompanyCodeConfigure per book in on-prem

The source side calls executeBillQuery to pull material records as a structured payload; the target side hits /api/updateMaterialInfo with an upsert semantics — update if exists, create by UUID if not. On the surface this is just field translation, but underneath it is rewriting Kingdee's field semantics (MasterId, Number, MaterialGroup) into the MES contract (materialUuid, partNo, classifyNo). This is the foundation every downstream sync leans on.

How to configure it in Qeasy

In Qeasy, three things carry this strategy end-to-end:

  1. Source metadata: Pull the request fields of executeBillQuery, fix number to FNumber and id to FMasterId, and turn off idCheck — the Kingdee query side does not need id validation; let the target side handle it. Enable autoFillResponse so the platform builds the response tree from the actual return structure.
  2. Target metadata: /api/updateMaterialInfo is POST, type WebAPI, effect EXECUTE. Here idCheck must be on, because the MES performs idempotent upserts keyed by UUID; the write key is materialUuid, mapped from source FMasterId. Leave buildModel off so the model structure is not rebuilt on every run.
  3. Field mapping: The group field appears twice — classifyNo and parentClassifyNo. In this strategy both map from FMaterialGroup. The reason is that the MES side stores categories as a self-referencing tree: the platform first creates the top-level category by parentClassifyNo, then attaches leaves via classifyNo. In Qeasy this "parent-before-child" dependency is handled by staging header/body as separate strategies, not by stuffing both into one request. A classic mistake is merging category creation with material persistence — the material then fails with "category does not exist" before the category ever lands.

Centralised code mapping is another common pattern we see Qeasy customers adopt: every ERP→MES code translation rule sits in a single mapping set, so a code change in ERP propagates to all downstream strategies at once, instead of every strategy carrying its own translation script.

Implementation steps

We typically split base-data sync into three phases: incremental bootstrap, full reconciliation, and steady-state scheduling.

  • Incremental bootstrap: Start from the last modification timestamp of FMasterId in Kingdee and persist it as Qeasy's incremental cursor. The first run is incremental only — usually thousands to tens of thousands of records — to validate mapping, idempotency and the retry chain.
  • Full reconciliation: Once incremental is stable, schedule a full reconciliation — usually in the early-morning window — that repushes every material record from Kingdee. The MES upserts by materialUuid, so after a full run the row counts on both sides must match. This is the "reconciliation safety net". A common Qeasy pattern is to run incremental and full side-by-side (dual track): the full run only surfaces drift, it does not overwrite the latest incremental state.
  • Scheduling cadence: Steady state runs incremental every hour on * 7-22 * * *, plus a full reconciliation at night. In on-prem environments watch the concurrency ceiling of /api/updateMaterialInfo — the Qeasy rate limit must be tuned to what the MES can absorb, not to the cloud default.

Pitfalls from real projects

  1. Using code as the write key: The first version often uses FNumber as the write key. The moment Kingdee renumbers a code, the MES ends up with a "new material plus a stale old one". The safe approach is to use FMasterId as the cross-system primary key, with FNumber only as the displayed business code.
  2. Mixing category and material in one request: The MES stores categories as a tree, so parents must exist before leaves. Putting category creation inside the material payload causes repeated "category does not exist" errors. On Qeasy we split this into two strategies: material groups first (sequence B), material master after (sequence A), chained via depends_on.
  3. idCheck not enabled: It is correct to disable idCheck on the source query side, but the target EXECUTE must enable it. Otherwise the MES upserts by the UUID in the request body, the first write looks fine, but a rerun treats existing records as new and the row count doubles.
  4. Hard-coding company code from the sample value: The default value of companyCode is just an example — it must not be hard-coded to a placeholder like 59a462d6. In on-prem multi-book deployments, configure it as a per-book constant or read it from the login context, otherwise materials land in the wrong company.
  5. Swallowing failures silently: If material-sync failures are not parked in a retry queue, a field rename on the source side silently kills the whole pipeline. In Qeasy we route target EXECUTE failures into an exception table and require manual confirmation before replay, instead of dropping them on the floor.

When this applies — and when it does not

Applies: One-way ERP → MES material master sync where coding rules are stable, category depth is shallow, the cross-system primary key (MasterId) is reliable, deployment is on-prem, and freshness requirements sit inside the hourly range.

Does not apply: Scenarios where the MES needs to modify material records and write them back to ERP — bidirectional sync introduces conflict-resolution issues that fall outside a single strategy. Also not suited for materials with multi-language or complex UoM conversions, nor for cases where the MES category table is structurally incompatible with the ERP and cannot be aligned by a single parentClassifyNo field — the latter needs a dedicated category-mapping workstream first.

Original content. Please credit the source when reposting: https://www.qeasy.cloud/insights/solutions/strat-mes-api-kingdee-cloud-5066-mes-3963a8aa

Comments