Qeasy Cloud
Get Started

Step-by-Step Stock Transfer Out Sync: Kingdee Cloud to MySQL in Practice

· 系统管理员· Integration Solutions· 6 views· 4 min read
MySQLKingdee Cloud分步式调出单轻易云供应链集成调度策略

What This Strategy Solves

In one retail client we worked with, warehousing and finance live in two different systems: business documents flow through Kingdee Cloud, while analytics and downstream reporting sit in MySQL. The "deceptively simple" stock transfer-out document is exactly where things tend to break—organization fields in the source come back as localized composites, and if you don't normalize them at the integration layer, the numbers on both sides drift apart within three months, and you'll be digging through logs at 2 a.m. The goal here is to land Kingdee Cloud's step-by-step stock transfer-out documents into MySQL in a stable and traceable way, so downstream reports always reconcile with upstream documents.

Data Flow and Field Mapping

The end-to-end path is: Kingdee Cloud → Qeasy Data Integration Platform → MySQL. On the source side we use Kingdee's executeBillQuery to pull the transfer-out header and lines in one shot; on the target side we use batchexecute to write them into MySQL via SQL batching.

Key field mapping (excerpted from the source):

Business meaningSource field (Kingdee)Target field (MySQL)Notes
Document primary keyFSTKTRSOUTENTRY_FEntryIDidUsed as idempotency key
Document numberFBillNoFBillNoBusiness-visible number
Document statusFDocumentStatusFDocumentStatusString
Source organizationFStockOrgID.FNameFStockOrgIDSource has .FName suffix; target keeps code only
Business dateFDateFDateString
Document typeFBillTypeIDFBillTypeIDType code

Pay attention to how the source organization field is referenced: the metadata uses {{FStockOrgID.FName}}, while the target only receives the raw code. This single step is the linchpin of any organization-level reconciliation later, and it's also where the "centralized code mapping" pattern commonly used by Qeasy customers comes in.

How to Configure It in Qeasy

Source (Kingdee Cloud): choose API executeBillQuery, method POST, effect QUERY. Use FBillNo as the business number, and FSTKTRSOUTENTRY_FEntryID as the line id. There's no need to model header and body separately; keep autoFillResponse on and let it flatten the response into mappable fields.

Target (MySQL): choose API batchexecute, method SQL, effect EXUTE. Turn idCheck on for the id field so Qeasy de-duplicates by primary key before writing—never trust "the source won't repeat". number also points to id to make lookup by document number easy.

Mapping in the middle: build a single "field mapping view" in Qeasy and rewrite every source-side .FName-style reference into a plain code on the target. We strongly recommend maintaining a dedicated mapping table for master data (organizations, customers, warehouses) and referencing it from the main strategy—this is the "master data synced once, reused everywhere" pattern that Qeasy customers use heavily, so you don't rewrite mapping logic per document type.

Implementation Steps

Phased scheduling is what keeps this strategy stable. The two crontabs in the source material are worth a closer look:

  • Source extraction: */7 * * * *, every 7 minutes. Near-real-time cadence, suitable for business hours.
  • Target write: 3-59/7 * * * *, offset by 3 minutes from the source to avoid both ends hitting the same batch at the same second.

A pragmatic schedule plan:

  1. Incremental starting point: on go-live day, run one full load to backfill historical transfer-out documents. For the incremental watermark, use a combination of FDate + FBillNo instead of a bare timestamp, to avoid missing documents.
  2. Full load trigger: only run full loads during initialization and recovery. In Qeasy, model it as a separate "full strategy" that you trigger manually or schedule during off-peak hours.
  3. Scheduling frequency: keep 7-minute intervals during business hours (typically 08:00–22:00); drop to 30 minutes or stop outside business hours to save resources and reduce log noise.

The "dual-track incremental + full" pattern is another common Qeasy customer approach: incremental for everyday freshness, full load on demand whenever reconciliation goes off.

Pitfalls and Lessons Learned

  1. Don't pass .FName through directly. FStockOrgID.FName is a display name; in multi-language environments or after an organization rename, historical values drift. The safe path is to pull an org-code mapping and join by code at the integration layer.
  2. Stage header and body separately. If the transfer-out has many lines, a single query response can get bulky. A robust pattern—widely used by Qeasy customers—is to land the header first, then backfill the body by line key. This keeps blast radius small on partial failures.
  3. Always declare an idempotency key explicitly. Turn idCheck on the target and de-duplicate by FSTKTRSOUTENTRY_FEntryID. Don't trust "the upstream won't repeat"—network jitter plus retries will eventually produce duplicates.
  4. Don't store status codes raw. Kingdee's FDocumentStatus is a code like "A"/"B". In MySQL, add a status_name column for the human-readable label, otherwise downstream report builders won't understand it.
  5. The 3-minute crontab offset is not a coincidence. There's network and transaction latency between source commit and target visibility. Running both ends on the same */7 will, in some cycles, read data that is "just committed but not yet landed." A few minutes of offset dramatically improves stability.

When This Fits (and When It Doesn't)

Fit: step-by-step transfer-out and other outbound documents; near-real-time sync into an analytics or downstream operational database; source is Kingdee Cloud with header and body returned in one interface. Doesn't fit: scenarios requiring strong transactional consistency (e.g., "transfer triggers immediate inventory deduction"), extremely large document volumes that need sharding, or cases without a stable primary key.

Original content. Please credit the source when reposting: https://www.qeasy.cloud/insights/solutions/strat-mysql-kingdee-cloud-8096-mysql-970f09d3

Comments