From Replenishment Suggestion to Purchase Order: Closing the Loop with Your ERP
Why the last mile decides success
Many replenishment projects die in the last mile: suggestions are computed well, but buyers still retype them into the ERP — mistyped lines, missed orders, duplicates. Once suggestions and documents drift apart, traceability breaks and the system slides back to Excel. The loop-closing requirement: a confirmed plan must become compliant ERP purchase orders in one action, and arrival data must flow back to correct the next computation cycle.
This walkthrough uses Kingdee Cloud (K3Cloud WebAPI); the same pattern applies to Yonyou or SAP.
The pipeline
- Plan confirmation — all rows settled and confirmed.
- Order splitting — rows split by supplier × warehouse (orderKey); one PO carries exactly one supplier and one receiving warehouse.
- Creation —
Savethe purchase order via WebAPI. - Submission and approval —
SubmitthenAudit, moving the document into the ERP's formal workflow. - Arrival backfill — scheduled polling of PO / inbound documents writes received quantities back, closing the suggestion lifecycle.
Kingdee Cloud purchase order API essentials
K3Cloud WebAPI locates document types by FormId; the purchase order is PUR_PurchaseOrder. The core operations are Save, Submit, Audit and ExecuteBillQuery. A trimmed Save payload:
{
"FormId": "PUR_PurchaseOrder",
"Data": {
"Model": {
"FBillTypeID": { "FNUMBER": "CGDD01_SYS" },
"FDate": "2026-07-30",
"FSupplierId": { "FNumber": "S000123" },
"FPurchaseOrgId": { "FNumber": "100" },
"FPOOrderEntry": [
{ "FMaterialId": { "FNumber": "SKU-10086" }, "FQty": 200, "FTaxPrice": 12.5 }
]
}
}
}
Master-data fields link by FNumber, so codes on the replenishment side must align strictly with ERP codes — the first hard constraint of the mapping layer.
Mapping and idempotency
Three mapping rules: align SKU / supplier / warehouse / unit codes with the ERP via a mapping table; pick the right bill type per scenario (standard PO CGDD01_SYS vs. subcontracting or drop-ship types); take tax-inclusive price and tax rate from supplier price lists rather than letting the compute layer guess.
For idempotency, derive a stable orderKey = hash(planBatchId + rowNo) per plan line and keep a local PO registry. Before creating, look up the orderKey: if a bill number exists, reuse it. Because Save / Submit / Audit are separate calls, each step's status must be resumable — if Save succeeded but Submit failed, retry only Submit/Audit, never re-Save. That is where duplicate POs come from.
Arrival backfill: the other half of the loop
A scheduled job (e.g. hourly) uses ExecuteBillQuery to pull received quantities on open POs, or aggregates purchase inbound documents (STK_InStock) by source order. Remaining arrivals = total arrivals − arrived, feeding the next cycle's in-transit math. Overdue or anomalous lines raise alerts for humans. Without reliable backfill, "in-transit" in the formula is fiction — and the next cycle re-buys what is already on the truck.
Once the loop is closed, suggestions, documents and arrivals reconcile line by line: every purchased unit traces back to the plan row that justified it — the foundation for both auditing and model improvement.
Related API Docs
- Third-party App Login (LoginByAppSecret)
POST https://{数据中心地址}/k3cloud/Kingdee.BOS.WebApi.ServicesStub.AuthService.LoginByAppSecret.common.kdsvc
- Generic Bill Query (ExecuteBillQuery · Sales Order)
POST https://{数据中心地址}/k3cloud/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc
- Real-time Inventory Query (STK_Inventory)
POST https://{数据中心地址}/k3cloud/Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.ExecuteBillQuery.common.kdsvc