Qeasy Cloud
Get Started

Sales Delivery Order Approval Result Feedback: A Closed-Loop Strategy from Kingdee Cloud Cosmos to MES

· 冯潇· Integration Solutions· 20 views· 5 min read

What This Strategy Solves

In a real manufacturing supply-chain integration project, the customer initiates sales delivery orders in their MES (MySQL) and pushes them to Kingdee Cloud Cosmos for approval. Once the approval request is submitted, the result—success/failure, message text, and the raw payload—needs to be written back to the MES label-approval table, so the shop floor can continue picking, printing, or stopping the order.

At its core, this strategy is a "feedback loop" for approval results: the delivery order status flows from MES to ERP, and then back from ERP to MES. We deliver this on the Qeasy (轻易云) data integration platform. The source side periodically queries ERP for delivery orders whose approval has been submitted, and the target side runs a SQL update that writes the flag and message fields back into the MES business table.

Data Flow and Field Mapping (Source → Middle Layer → Target)

Source: Kingdee Cloud Cosmos (WebAPI query)

The source invokes a "no-op request" style WebAPI (POST, QUERY semantics), which acts as a lightweight query hook and returns the set of sales delivery orders whose approval has been submitted.

Middle Layer: Qeasy Integration Platform

The platform normalizes the fields returned from the source and hands them off to the target for execution.

Target: MySQL (execute-style SQL)

The target side is a single update statement that writes the approval result back into the MES label-approval table.

Key field mapping:

Source field (Kingdee response)MeaningTarget field / SQL bind variableNotes
sd_codeSales delivery order number:sd_codePrimary key, locates a unique order
is_sucessWhether approval succeeded:is_successWritten into the flag column
result_messageApproval message text:messageWritten into the message column for shop-floor troubleshooting
json_dataRaw JSON payloadjson_dataKept for auditing and reconciliation
(Source N/A, SQL built-in)—update_date = now()Timestamp refreshed on every write

The full SQL looks like:

sql
update ty_mes.mt_so_delivery_not_label_approve
set flag = :is_success,
    message = :message,
    update_date = now()
where sd_code = :sd_code

How to Configure on Qeasy

On the source side, choose a WebAPI resource, select the "no-op request" API, set method to POST, and effect to QUERY. Bind the response fields directly to sd_code / is_sucess / result_message / json_data. Keep is_required as false, because the feedback scenario allows empty strings.

On the target side, choose a MySQL resource, type SQL, effect EXECUTE. Put the full main_sql (the update statement above) into otherRequest, and use request.main_params to receive the parameter object transformed from the source.

For field mapping, we recommend centralizing "code mapping" inside the Qeasy transformation script rather than scattering it across every strategy. In this specific scenario: sd_code passes through transparently; is_sucess is normalized to a boolean (mapping Y/N, 1/0, true/false all to 0/1); and result_message is truncated to avoid blowing up the message column. This is one of the common patterns among Qeasy customers: centralized code mapping management.

Implementation Steps

We typically break the rollout of this feedback strategy into three phases.

Phase 1: Initialize the incremental starting point. In Qeasy, run a one-time full sweep that re-queries all delivery orders whose approval was submitted in the past 7 days, so historical documents are aligned first. A manual trigger on Qeasy is sufficient for this phase.

Phase 2: Bring up the scheduled execution. The crontab on the Kingdee source is configured as 1 1 1 1 1 (the five-field expression only takes the last field here, meaning a single weekly fallback trigger on Friday), while the crontab on the MySQL target is */1 * * * *, executing the SQL update every minute. This combination of "low-frequency fallback on the source + high-frequency lightweight execution on the target" is a typical form of the dual-track incremental-and-full approach used on Qeasy.

Phase 3: Dependencies and monitoring. This strategy has no business dependency on a prior strategy—it is the last leg of the delivery loop, so depends_on stays empty. Still, we recommend adding an alert inside Qeasy: if the count of is_success = false rows exceeds a threshold for two consecutive cycles, push the alert to the ops group, so the shop floor does not silently stall.

Pitfalls and Lessons Learned

  1. Inconsistent field spelling. The source response uses is_sucess (missing the letter 'c'), while the SQL bind variable is :is_success. Don't "tidy up" the name in the docs—the Kingdee field name is fixed; if we rename it on our side, the mapping will break. The safe approach is to add an explicit rename inside the Qeasy transformation script, mapping is_sucess to is_success before feeding it to the SQL.

  2. Implicit semantics of the no-op interface. The source uses a "no-op request", which means the request body is empty and the query is actually driven by ERP's internal state machine. If the approval queue on the ERP side is backed up, no new orders will be returned here—a typical mistake is to stare only at the Qeasy logs without checking the ERP approval workflow.

  3. Re-entrancy of the SQL. The update uses set flag = :is_success, message = :message and looks idempotent, but if the source's result_message is empty, it will overwrite a previously non-empty message with an empty string. We recommend adding a check in the Qeasy transformation layer: only write back the message column when :message is non-empty, to avoid "a successful message being overwritten by an empty one".

  4. Side effects of timestamp refresh. update_date = now() is refreshed on every write. If the MES side has a "last modified" logic based on this column, it may misjudge that "the order has been updated again". The safe approach is to confirm with the business what update_date really means, and—when necessary—only refresh the timestamp when the flag actually flips.

  5. The cost of leaving depends_on empty. Because depends_on is an empty array, the platform will not automatically wait for a prior strategy to finish. If the upstream "sales delivery order push" has not pushed the order to ERP yet, the query here returns nothing—and the MES side stays "pending approval" forever. We recommend documenting "upstream push must run first" even when depends_on is empty, and manually verifying the order during go-live.

Applicable and Non-Applicable Scenarios

Applicable: Lightweight two-sided confirmation loops where MES initiates the outbound delivery, ERP approves it, and the result is written back to MES; small number of feedback fields (under 4), high document volume, near-real-time synchronization at minute-level granularity.

Not applicable: Scenarios where the approval process needs to feed back line-item details (line rows, serial numbers) or multi-node approval state—this strategy only returns header-level results, which is not enough. It is also unsuitable for complex cross-organization approval flows; in those cases, use Kingdee Cloud Cosmos's workflow callback rather than a periodic query.

Original content. Please credit the source when reposting: https://www.qeasy.cloud/insights/solutions/strat-mysql-kingdee-cloud-2246-mom-xsckd-f439e84d

Comments