调拨单对接YS调拨订单:从旺店通到用友BIP的库存调拨同步实战
这个策略解决什么问题(场景与价值)
在一次零售企业的多仓调拨项目中,我们遇到一个很典型的痛点:旺店通侧根据出库进度会不断刷新调拨单状态(从"待出库"到"部分出库"再到"调拨完成"),而用友BIP作为后端财务与库存核算系统,需要拿到同一张调拨单做组织间结算。如果两边靠人工导出再导入,一周之内账就平不了。这个策略的本质,就是把"调拨单"作为一个跨系统的业务对象,在轻易云数据集成平台(Qeasy)上做准实时的单向同步,让调出组织、调入组织、交易类型、行项目数量等关键信息在两个系统里始终一致。
数据流向与字段映射
整体流向是单向的:旺店通(企业奇门) → 轻易云(Qeasy)中间层 → 用友BIP。源端通过 wdt.stock.transfer.query 按 start_time/end_time 增量拉取,目标端通过 /yonbip/scm/transferapply/save 写入调拨订单。下面是核心字段对照。
| 业务含义 | 源端(旺店通) | 中间层映射逻辑 | 目标端(用友BIP) |
|---|---|---|---|
| 单据编号 | transfer_no | 直接透传 | code |
| 单据日期 | created | 格式化为 yyyy-MM-dd HH:mm:ss | vouchdate |
| 调出组织/会计主体 | from_warehouse_no + to_warehouse_no | _findCollection 查组织映射集 | outorg、outaccount |
| 交易类型 | 固定值 | 写死 | bustype = A03002 |
| 调拨退货标志 | 业务约定 | 静态值 | breturn |
值得重点说的是 outorg。它不是一个简单字段,而是一条查找表达式:从组织仓库映射集合里,根据源端传入的 from_warehouse_no、to_warehouse_no 反查用友BIP里的组织 code。这就是轻易云做"编码映射集中管理"的典型姿势——把多对多的仓库—组织对应关系收口在一张映射表里,而不是散落在每条策略里。
在轻易云上如何配置
源端接口配置时,start_time 用 {{LAST_SYNC_TIME|datetime}} 取上次同步时间,end_time 用 {{CURRENT_TIME|datetime}} 取当前时间,实现真正的增量窗口;status 这里默认传 90(调拨完成),意思是只把最终态推给用友BIP做结算,避免过程中态反复回写把目标系统打花。
目标端写单接口的 number、id 都设为 transfer_no,idCheck 打开,这样同一张单据第二次进系统时会被识别为更新而非新增,避免一张单据推成两条。
轻易云上有两个细节建议打开:一是autoFillResponse,让平台把返回结构自动补齐,排查问题时不用手动拼 JSON;二是 buildModel 关闭,因为调拨单的请求结构是固定的,不需要平台动态建模。
实施步骤
我们把上线拆成三个阶段,稳妥推进:
- 增量起点校准。先在轻易云里把
LAST_SYNC_TIME初始化为一个历史时间点,跑一次全量回灌,把历史已完成调拨单补齐到用友BIP。这一步必须在目标系统为空或可幂等覆盖的环境下做。 - 分阶段调度。源端
crontab = 4-59/10 * * * *,每 10 分钟一抽,故意错开 4 分钟,避免和目标端写入高峰撞车;目标端crontab = 9-59/10 6-23 * * *,营业时段(6–23 点)每 10 分钟落一次,夜间暂停,减少对用友BIP的压力。 - 增量与全量双轨运行。增量策略按上面节奏持续跑,同时每周定时触发一次"全量校核"任务,重新拉取近 7 天已完成状态的调拨单,做幂等回放,弥补漏单。
踩坑复盘
- 漏传
outorg的连锁反应:outorg和outaccount是_findCollection查找出来的,如果映射集里漏配某个仓库,整张单据会在用友BIP侧报错,且错误不指向字段名。稳妥的做法是上线前用select count(*)验证源端所有出现过的from_warehouse_no/to_warehouse_no组合在映射集里都有值。 status=90的隐性代价:只同步完成态,意味着过程态(部分出库等)在用友BIP里看不到。有些财务对账需要中间态,所以"表头表体分阶段"在这里很合适——表头只推完成态,行项目数量变化另起一条策略推。- 时间窗口过窄丢单:增量窗口只有 10 分钟,如果某次抽取出问题跳过了一拍,那段时间窗口内的单据就丢了。双轨全量校核正是为此兜底。
- 编码规则冲突:用友BIP
code字段允许自定义,旺店通transfer_no是平台生成的,直接透传后可能出现前缀不合规。建议在中间层加一层transfer_no→ 内部单据号的转换函数,而不是直接喂给目标。 - 空体单据:源端偶发返回只有表头、没有行项目的"空壳调拨单",写过去会让用友BIP报行项目为空。在轻易云的脚本里加一行
if line_items.length == 0 then skip是最低成本的兜底。
适用场景与不适用场景
适用:多仓网络下,源端 ERP/OMS 已经做了调拨业务,但目标财务/核算系统需要拿到结构化调拨订单做组织间结算,且对实时性要求在分钟级。不适用:目标系统需要看到调拨全过程(从创建到出库到入库的完整状态机),或者源端调拨单会被人工修改后需要回写——这两种情况需要换双向同步或事件驱动方案。