MES Production Receipt to Kingdee Production Report Sync: Closing the Last Mile from Shop Floor to Finance
What This Strategy Solves
In a discrete manufacturing shop floor, the MES issues production receipt requests keyed by production order — capturing actual completed quantities, received quantities, and shift information. On the finance and costing side, Kingdee Cloud needs this completion data landed into production report documents so it can feed cost collection and order closure.
It looks like a simple "document move," but three things make it hard: first, each receipt request must be tied back to a production order on the Kingdee side; second, completed quantity, accepted quantity, and reject quantity often differ by definition; third, since the shop runs from 7am to 10pm, high-frequency incremental data must reach downstream reliably. The Qeasy data integration platform is exactly the kind of "small, frequent, never-miss-a-record" synchronization scenario we built it for.
Data Flow and Field Mapping
The overall flow is: MES production receipt request → Qeasy middle layer (joined on production order, with code mapping, null cleaning, and exception handling) → Kingdee Cloud production report (with header and entity lines).
The source endpoint is common/search, a POST call that takes wsId and pagination parameters. The response carries business_no as the MES receipt number and id as the system-internal unique key.
The target endpoint is Kingdee's batchSave, with document type SCHBD01_SYS (the standard production report code). The key field mapping is:
| Business Meaning | Source Field (MES) | Target Field (Kingdee) | Mapping Notes |
|---|---|---|---|
| Document Number | business_no | FBillNo | Direct map, used as idempotency key |
| Document Date | create_time | FDate | Convert to yyyy-MM-dd |
| Production Org | Org code | FPrdOrgId | Maintained centrally in mapping table |
| Production Order No. | order_no | FEntity[].FSourceBillNo | Critical join field on entity line |
| Completed Qty | finish_qty | FEntity[].FFinishQty | UoM must be consistent |
| Accepted Qty | ok_qty | FEntity[].FQty | Drives inventory deduction |
| Remark | remark | FDescription | Optional, can tag as "interface sync" |
How to Configure in Qeasy
Step one: register the MES WebAPI under the source connector, including wsId, page size (start at 100 to validate stability), query keys, and filter conditions. Qeasy treats id as the idempotency field, which prevents duplicates on rerun.
Step two: register Kingdee's batchSave under the target connector. Mark FBillNo, FBillType (hardcoded as SCHBD01_SYS), and FDate as required so the platform blocks incomplete payloads before they ever reach Kingdee — this saves a lot of downstream troubleshooting time.
Step three — the most important step for this strategy — is to configure the header and entity in two phases. Our habit is to push the header alone first and confirm FBillNo, FDate, and FPrdOrgId write cleanly; only then do we open the entity and backfill the production order number into FEntity[].FSourceBillNo. Do not assemble the full JSON and push it on day one. When Kingdee rejects an entity line, root-cause analysis gets expensive.
Step four is centralized code mapping. Org, workshop, and shift master data should live in Qeasy's mapping center, not hardcoded inside transform scripts. On one real project, we saw a customer hardcode org codes in the script — when the org structure changed, the entire pipeline needed a new release.
Implementation Steps
Anchor the incremental start point: before go-live, freeze a time anchor (e.g., midnight on a chosen date) with the customer. Anything after the anchor is incremental; anything before is full-history. The incremental field is usually MES last-modified time, paired with idCheck to prevent drops.
Trigger the full backfill: push the pre-anchor history via a one-shot script; Qeasy supports manual full rerun. After it completes, pull 3–5 production orders and reconcile them in Kingdee line by line — focus on quantities, prices, and cost objects.
Schedule frequency: set the source cron to * 7-22 * * *, meaning every minute from 7am to 10pm, covering the full shift window. Qeasy supports second-level scheduling, but for MES query APIs, one minute is already enough — pushing it higher only stresses the source.
Pilot and rollback: start with one workshop or one production line for 3–5 days; once you see no duplicates and no drops, open up the rest. For rollback we use FBillNo as the idempotency key, paired with Qeasy's retry and manual intervention panel — single-document rollback is manageable.
Lessons From the Field
Pitfall 1: empty production order number on the source. MES operators occasionally leave the field blank; pushing these straight to Kingdee causes full-batch rejection. The robust pattern is a non-null check inside the Qeasy transformer — blank rows go to the exception queue, not downstream.
Pitfall 2: unit-of-measure mismatch. MES receipt quantity is in "pieces," but Kingdee's report defaults to the base UoM, and some materials carry multiple UoMs. We recommend doing UoM conversion at the mapping layer and registering conversion factors in the mapping table.
Pitfall 3: incremental start point misses manual back-entries. During downtime, operators manually key a few receipts whose last-modified time is earlier than the anchor. After the full backfill, run a safety-net pass that re-pulls by document number — no row left behind.
Pitfall 4: Kingdee truncates entity lines beyond a row count. batchSave has a per-call entity line limit. Configure Qeasy to cap rows per batch — splitting batches is safer than hitting the cap.
Pitfall 5: timezone and date format. In cross-region deployments, create_time can arrive in UTC and slip a day on the Kingdee side. Normalize date strings to local date in the transformer layer.
When to Use and When Not to
Use it when: discrete manufacturing, production organized by order, costs collected by quantity, and high-frequency shift-level sync required.
Don't use it when: process manufacturing runs by batch, costs settle by labor hours rather than quantity, or the source has no production-order constraint — forcing sync here will widen the definition gap.