Qeasy Cloud
Get Started

Syncing Kingdee Payment Application to DingTalk Supplier Monthly Settlement Approval: A Qeasy Single-Strategy Tutorial

· 系统管理员· Integration Solutions· 12 views· 5 min read
Kingdee CloudDingTalk金蝶钉钉集成付款申请单同步供应商月结付款轻易云Incremental Sync编码映射

What This Strategy Solves

In one manufacturing client scenario, after finance approved a supplier monthly-settlement payment application in Kingdee Cloud, they still had to manually re-create the same approval in DingTalk — retyping the amount, supplier, and bank details for every document. At month-end, with over 200 documents, this ran well past midnight, and a single typo triggered a full rejection and re-submission. The goal of this strategy is to make the "Kingdee approved → DingTalk approval initiated" path fully automatic, eliminating manual transcription and latency.

Data Flow and Field Mapping

The flow is unidirectional: Kingdee Cloud CN_PAYAPPLY (payment application) → Qeasy Data Integration Platform → DingTalk topapi/processinstance/create (OA approval creation). Kingdee is polled via executeBillQuery, the middle layer transforms the payload, and DingTalk receives a complete approval-instance request body.

Key field mapping (DIRECT = direct passthrough, CONSTANT = constant, COLLECTION = lookup):

Target Field (DingTalk)Source Field (Kingdee)Mapping TypeNotes
process_codePROC-22EDF4E6-5CC9-4712-B9A3-34AEAF37B8ACCONSTANTSupplier monthly settlement process code
originator_user_idF_VAOJ_FQR (originator name)COLLECTIONLookup "DingTalk Directory → Kingdee Employee" hub by name
dept_idF_VAOJ_FQR (originator name)COLLECTIONSame hub, return leader_in_dept.0.dept_id
Document numberFBillNoDIRECTKingdee bill number
Counterparty / SupplierFCONTACTUNIT.fnameDIRECTTake name attribute
Apply amountFAPPLYAMOUNTFOR_HDIRECTHeader apply amount (book currency)
Payable amountFPAYAMOUNTFOR_HDIRECTHeader payable amount
Apply dateFDATEDIRECTBusiness date
Expected pay dateFEXPECTPAYDATEDIRECTExpected payment date
Due dateFENDDATEDIRECTApplication deadline
Settlement orgFSETTLEORGID.fnameDIRECTBase data, take name
Pay orgFPAYORGID.fnumberDIRECTBase data, take code
Apply orgFAPPLYORGID.fnumberDIRECTBase data, take code
Settlement currencyFSETTLECUR.FnumberDIRECTBase data, take code
Bill typeFBILLTYPEID.fnumberDIRECTBase data, take code
RemarksFDescription / F_VAOJ_RemarksDIRECTRemarks or extended field
Payment categoryF_VAOJ_HKSXDIRECTExtended field
Source bill noFSRCBILLNODIRECTUpstream document number
Payee account nameFEACHCCOUNTNAMEDIRECTReceiver account name
Payee bank nameFEACHBANKNAMEDIRECTReceiver bank name
Payee bank accountFEACHBANKACCOUNTDIRECTReceiver bank account

Kingdee Cloud base-data fields require a sub-property (e.g. .fname for name, .fnumber for code, Fnumber for currency code). This is the most common pitfall for newcomers and is reiterated below.

How to Configure on Qeasy

In on-site deployments we follow this pattern: first wire both endpoints into Qeasy's "Data Sources" — Kingdee Cloud needs the tenant authorization and the executeBillQuery FormId (CN_PAYAPPLY); DingTalk needs the open-platform AppKey/AppSecret and topapi/processinstance/create.

Then we build the strategy canvas in three layers:

  1. Source pull: FilterString set to FApproveDate>='{{LAST_SYNC_TIME|dateTime}}', incremental by approval date; schedule at */7 9-22 * * *.
  2. Middle-layer mapping: Map Kingdee header fields one-to-one to the DingTalk approval-initiation parameters. Among the four top-level DingTalk params, process_code is a constant; originator_user_id and dept_id use _findCollection against the "DingTalk Directory → Kingdee Employee" hub; form_component_values is configured control-by-control in the platform UI.
  3. Target push: Request body uses EXECUTE POST, schedule at */5 9-22 * * * so the queue drains slightly faster than it fills.

For code mappings, a common Qeasy customer pattern is "centralized code-mapping management" — all user_id/dept_id lookups are consolidated into the "DingTalk Directory → Kingdee Employee" hub strategy. The current strategy only references that hub rather than duplicating pulls, so when upstream directory data changes, all downstream consumers stay in sync without editing many strategies.

Implementation Steps

Our typical on-site rollout runs in three phases:

Phase 1: Incremental start point confirmation. Before first launch, pin down what LAST_SYNC_TIME should start from. The usual approach is to query one recently approved payment application in Kingdee and use its FApproveDate as the start, to avoid pulling all historical data at once. We recommend hard-coding this timestamp as a strategy variable for "cold start", then switching to normal incremental after verification.

Phase 2: Full-volume validation. Once cold start succeeds and the middle-layer mapping looks clean, run a separate full-volume pass — change FilterString to a time window or empty (subject to Kingdee API support) to pull a batch of historical data and push to DingTalk. This step mainly validates lookup hit rates at scale, whether bank-account fields are truncated, and whether amount precision is preserved.

Phase 3: Staged scheduling go-live. Source polls at */7 9-22 * * *, target pushes at */5 9-22 * * *, offset so they don't run "pull-while-push" concurrently. Another common Qeasy customer pattern is "header and detail in stages" — this strategy only pushes the header (since DingTalk's monthly-settlement approval is itself a header-only document). If we later need to extend to detail line items, we open a second strategy instead of overloading the first, which avoids breaking the header path.

Once steady, switch to a "dual-track incremental + full-volume" mode: incremental every 7 minutes for daily traffic, plus a full-volume reconciliation at 1 AM on the 1st of each month to catch any missed records.

Lessons from the Trenches

  1. Forgetting the sub-property on base-data fields. The classic mistake is passing the entire FSETTLEORGID object straight into a DingTalk field, leaving DingTalk with a JSON string it cannot render. The safe approach: for any Kingdee base-data field, always take .fname or .fnumber — whichever matches whether the DingTalk control is a text input or a dropdown.
  2. _findCollection on leader_in_dept with no fallback. When a DingTalk user has no department assigned, or their primary department is the root, leader_in_dept.0.dept_id can be null or missing, and the DingTalk API rejects outright. This is where things break — we typically add a fallback in the transform layer: if the value is empty, pass -1 (DingTalk's conventional root-department ID), so the document does not stall at the originator lookup.
  3. Wrong field chosen as the incremental anchor. Using FDATE (business date) is incorrect because business date can be earlier than approval date and is mutable when documents are un-approved then re-approved. Use FApproveDate, and strictly use "greater than" (not "greater than or equal to") the last sync time — otherwise boundary records at the same instant get silently dropped.
  4. form_component_values control names misaligned. The DingTalk approval-template control name is fixed by the template itself — what Kingdee calls "Apply Amount" may be labeled "Payment Amount" in DingTalk. Misalign one and the entire approval form renders with empty fields. Before configuration we always export the DingTalk template's control JSON and match every name one by one.

Suitable and Unsuitable Scenarios

Suitable: when Kingdee Cloud payment applications are the sole approval source, you want DingTalk OA to run monthly-settlement approvals, and DingTalk only needs header-level data. Not suitable: when DingTalk needs to maintain detail line items (e.g. multiple payment entries merged) or when DingTalk's approval controls cannot be mapped one-to-one against Kingdee fields — in the latter case we recommend a "master-data pre-generation + approval trigger" multi-strategy combination instead.

Original content. Please credit the source when reposting: https://www.qeasy.cloud/insights/solutions/strat-kingdee-cloud-dingtalk-2294-nf65a3228-f51027d3

Comments