Sales Return Currency Strategy in Practice: Multi-Currency Field Mapping from Jikeyun to Kingdee Cloud
What This Strategy Solves
A retail enterprise running multi-currency sales returns ran into a real finance pain point: their sales return inbound documents had already been pushed from Jikeyun to Kingdee Cloud, but the settlement currency and exchange rate fields in the financial sub-table were always blank, causing mismatches during month-end reconciliation. The root cause was simple — the basic sales return sync lacked a dedicated sub-strategy to fill in currency and exchange rate fields.
We use the Qeasy data integration platform to deliver the "Sales Return – Currency" strategy, designed exactly for this gap: on top of the existing sales return sync, it focuses on populating settlement currency, exchange rate, and other fields in SubHeadEntity, ensuring accurate accounting for multi-currency return transactions on the Kingdee side.
Data Flow and Field Mapping
The data flow is unidirectional: Jikeyun (sales return inbound document, inouttype=105) → Qeasy → Kingdee Cloud (sales return document SAL_RETURNSTOCK).
The table below lists only the currency-related key fields for clarity.
| Source Field (Jikeyun) | Target Field (Kingdee SubHeadEntity) | Mapping Type | Rule |
|---|---|---|---|
| chargeCurrencyCode | FSettleCurrId | Direct/Transform | Take this first |
| currencyCode | FSettleCurrId | Fallback | Use when chargeCurrencyCode is empty |
| currencyCode | FCURRENCYID | Direct | Transaction currency |
| localExchangeRate | ExchangeRate | Direct | Local-to-foreign rate, preferred |
| currencyRate | ExchangeRate | Fallback | Use when localExchangeRate is empty |
Other header fields follow the base strategy: goodsdocNo → FBillNo, companyCode → FSaleOrgId / FStockOrgId, inOutDate → FDate. The return customer FRetcustId, related document number F_LSJC_Text, and receipt number F_LSJC_Text2 are obtained via _mongoQuery from the return-change-replenish order data source, using returnChangeNo = billNo OR sourceBillNo.
How to Configure on Qeasy
In the Qeasy integration platform, this strategy is structured as Source → Middle Layer → Target.
Source (Jikeyun)
- API:
erp.storage.goodsdocin.v2, POST query - Key filter:
inouttype=105 - Additional pulled fields:
currencyCode,currencyRate,localExchangeRate,chargeCurrencyCode - Document number field:
goodsdocNo; idempotency field:recId;idCheck=true
Middle Layer (Qeasy)
- Header currency mappings live under
SubHeadEntityusing a "preferred + fallback" CASE expression - Lookups use
_mongoQuery, with$orsyntax to support bothbillNoandsourceBillNo - No custom scripts needed — mappings plus lookups are sufficient
Target (Kingdee Cloud)
- API:
batchSave, POST execute - FormId:
SAL_RETURNSTOCK; Operation:Save IsVerifyBaseDataField=true(validates currency codes against base data)IsAutoSubmitAndAudit=false(no auto submit/audit after save)InterationFlags=STK_InvCheckResult(allow negative inventory)SubHeadEntityis currently null and must be populated per this design
Implementation Steps
We recommend a phased rollout to clients so reconciliation stays manageable.
Phase 1: Base data and currency archive
The currency archive must exist before any document sync, otherwise IsVerifyBaseDataField=true will reject the document. Material archive (P3-057), customer archive, and organization archive follow the same logic. In Qeasy, treat these base-data sync strategies as a dependency checklist.
Phase 2: Incremental anchor calibration
The source pulls incrementally by creation time: from_unixtime((LAST_SYNC_TIME - 18000), '%Y-%m-%d %H:%i:%s') to from_unixtime((CURRENT_TIME - 7200), '%Y-%m-%d %H:%i:%s'). The 5-hour leading and 2-hour trailing buffer handles source-side time drift and prevents missed documents. On first go-live, manually rewind LAST_SYNC_TIME to a clear business anchor and observe a few cycles.
Phase 3: Schedule frequency and full reconciliation
Source crontab 40 */2 * * * (every 2 hours at minute 40); target */20 * * * * (every 20 minutes). Staggered scheduling is the safer choice — pull a bit slower at source, execute faster at target, so data lands promptly without pile-up.
If historical data is missing during early go-live, run a one-time full trigger to backfill, then switch back to the incremental dual-track mode.
Pitfalls and Lessons Learned
-
Syncing documents before the currency archive exists. This is the most typical failure —
IsVerifyBaseDataField=truecauses Kingdee to reject outright. The safe approach is to make currency archive sync a hard prerequisite. -
Exchange rate direction inverted. Whether the Kingdee exchange rate field is "local/foreign" or "foreign/local" varies by version. This is a classic trap. Always verify with a USD document in the test environment before going live.
-
Empty
billNocausing lookup failures. SourcebillNocan be empty, so querying on it alone misses documents. You must use$orto also matchsourceBillNo. We hit this exact issue at one client site. -
Both
chargeCurrencyCodeandcurrencyCodeempty. In rare cases both are blank. Don't hard-fail; instead configure a default currency (e.g., CNY) as a fallback and let finance correct it later. -
SubHeadEntityforgotten in configuration. In the base sales return strategy this field is null. This strategy must populate it, otherwise currency fields never reach Kingdee. This is subtle and easy to miss during initial configuration.
When to Use and When Not to Use
Use when: multi-currency sales return business, finance needs currency/exchange rate accounting in Kingdee, or an existing base sales return sync needs the financial sub-table completed.
Do not use when: single-currency (e.g., CNY-only) business, no need for currency accounting in Kingdee, or prerequisite base-data syncs have not yet completed.