← 返回文章列表

采购入库最容易踩坑的地方,不是收货,而是关单

2026-05-23 采购订单采购收货通知单采购入库单采购

采购入库最容易踩坑的地方,不是收货,而是关单

做ERP的人都知道,采购入库这个模块看起来流程清晰,实际落地的时候,坑一个接一个。

尤其是在国内新零售、跨境电商、大批量B2B采购这类场景里,采购入库往往会涉及多仓协同、供应商分批发货、ERP和WMS系统对接。单据流转稍微设计不好,库存数据就会出问题,财务对账就会打架,仓库和采购互相甩锅。

这篇文章想把这个问题拆开来聊。

从采购订单、采购收货通知单、采购入库单这三层单据讲起,到WMS回传的两种处理方式,再到最后那个很多团队都没想清楚的问题:

关单这个动作,到底应该放在哪里?


一、先搞清楚三层单据是怎么跑的

在我们的设计里,采购入库这条链路,在ERP侧一般会拆成三层单据:

采购订单→采购收货通知单→采购入库单

为什么要拆成三层?

因为现实里的供应商送货,很多时候不是一次送完的。

比如一张采购订单采了1000件,供应商可能分三批发货,第一批400件,第二批400件,第三批200件。如果直接拿采购订单去对接仓库,仓库其实并不知道这次来的货对应哪一批、应该收多少、收完以后订单应该是什么状态。

所以我们需要从采购订单里拆出采购收货通知单

采购订单表达的是采购意图,采购收货通知单表达的是本次收货指令,采购入库单记录的是最终执行结果。

采购收货通知单生成之后,会下推给WMS。WMS收到通知单,生成自己的入库作业单,然后仓库开始执行收货、质检、上架。

执行完成后,WMS把结果回传给ERP,ERP再根据回传数据生成采购入库单,完成库存记录。

整个流程如下:

sequenceDiagram actor 采购员 participant ERP participant WMS actor 仓库人员 采购员->>ERP: 创建采购订单 ERP->>ERP: 拆分生成采购收货通知单 ERP->>WMS: 下推采购收货通知单 Note over WMS: 生成WMS入库作业单 仓库人员->>WMS: 执行收货、质检、上架 WMS->>ERP: 回传实收结果 ERP->>ERP: 更新采购收货通知单实收数据 ERP->>ERP: 生成采购入库单 ERP->>ERP: 回写累计入库数量至采购订单

流程图画出来很干净,但问题就藏在WMS回传​这一步里。


二、WMS多次回传:看起来灵活,问题不少

实际情况是,WMS往往不是一次把结果推回来的。

原因大概有两种。

一种是仓库操作本身就是分批完成的。货是分几辆车送到的,仓库卸一批、扫一批、收一批,系统也就分批产生收货结果。

另一种是WMS接口本身是事件驱动设计。收货完成推一次,质检完成再推一次,上架完成再推一次,每个节点都会触发回传,而不是等整张单据全部完成后再统一推送。

不管哪种原因,ERP这边面对的都是同一个问题:

同一张采购收货通知单,WMS推过来好几次数据,我怎么处理?

问题一:通知单和入库单的关系变复杂

如果每次回传都生成一张采购入库单,那一张采购收货通知单就会对应多张采购入库单。

再往上看,一张采购订单又可能对应多张采购收货通知单。整条链路就会变成这样:

flowchart LR A["采购订单"] --> B["采购收货通知单#1"] A --> C["采购收货通知单#2"] B --> D["采购入库单#1-1"] B --> E["采购入库单#1-2"] B --> F["采购入库单#1-3"] C --> G["采购入库单#2-1"] C --> H["采购入库单#2-2"]

层级深了,不是说不能做,而是每一层的关联关系都要维护。

采购订单要回写累计入库数量,采购收货通知单要累计实收数量,采购入库单要记录每次实收结果。后面查数、对账、追溯都会变复杂。

问题二:如果只维护一张入库单,库存什么时候加

如果不想让通知单对应多张入库单,另一种做法是:

第一次回传时生成采购入库单,后续回传不新建单据,而是在同一张采购入库单上追加数量或SKU明细。

这个设计看起来减少了单据数量,但会出现一个新问题:

库存到底什么时候加?

每次追加立即加库存,库存是实时的,但入库单还没完结,财务不知道能不能用这个数据。

等入库单完结后再统一加库存,单据状态是干净的,但库存会延迟。货已经上架了,系统里还查不到库存,后续销售、调拨、补货都会受影响。

所以这里最好把库存口径和财务口径拆开。

库存可以按WMS实收结果及时入账,但财务对账、暂估、应付匹配,要通过单据状态控制。不能把“库存可用”和“财务可结算”混成一个动作。

两个选择都有代价,必须显式做取舍,不能假装两个都能满足。

问题三:完结信号迟迟不来,单据一直挂着

正常来说,WMS分批推数据,最后一次回传应该带完结标识,告诉ERP:

这张单收完了。

最怕的是这个标识一直没来。

可能是WMS侧操作中断了,可能是仓库主管忘了确认,也可能是系统异常没有触发。ERP这边就一直等,单据挂在“收货中”,没有办法自动完结。

这种单据一多,后面就会变成历史包袱。

采购看着烦,仓库查着乱,财务对账的时候还要绕开一堆中间态单据。


三、WMS只回传一次:看起来干净,执行层容易破防

既然多次回传这么麻烦,一个自然的想法是:

那就约定好,一张采购收货通知单只允许WMS回传一次。

仓库把货收完、确认完,统一推给ERP。

这个设计语义确实很清楚。通知单和入库单1:1,库存一次性入账,财务对账也简单。

sequenceDiagram participant ERP participant WMS ERP->>WMS: 下推采购收货通知单(应收100件) Note over WMS: 仓库执行收货、质检、上架 Note over WMS: 仓库主管确认收货完成 WMS->>ERP: 一次性回传实收数量和完结标识 ERP->>ERP: 更新采购收货通知单实收数据 ERP->>ERP: 生成采购入库单,库存入账 ERP->>ERP: 回写累计入库数量至采购订单 ERP->>ERP: 采购收货通知单完结

这个方案本身没有问题,真正的挑战来自供应商。

供应商不一定会完全按照你的系统设计来送货。

上午送了一车,仓库收完,按约定触发回传,采购收货通知单完结。下午供应商又送来一车,仓库一看,对应的采购收货通知单已经关了,这批货就没有单据可以收。

这时候只能临时创建新单,或者让采购员重新处理。

所以“一次回传”的约定没有问题,问题是供应商的送货行为打破了这个前提。

更准确地说,不是要求一张采购订单必须一次送齐,而是要求每次实际送货前,都要先生成一张边界清晰的采购收货通知单。

采购订单可以分批,但每次送货都要有对应的通知单。否则仓库现场一定会遇到无单可收的问题。

仓库主管知道“我收完了”,但不知道“这单该不该关”

这是一个信息不对称的问题。

仓库主管能判断的是:今天这批货卸完了,现场没有车在等了,WMS作业可以结束了。

但他不知道:供应商后面是不是还有补货?通知单上差的20件,是应该继续等,还是直接关?

这些信息更多在采购侧。

采购员知道供应商发了多少,知道有没有后续补货,也知道缺量以后要不要继续追。仓库只知道实物收了多少,不掌握采购履约的完整上下文。

所以“一次回传”真正要解决的,不只是系统接口问题,而是送货规范问题。

如果供应商送货前没有按批次形成通知单,仓库就会在执行层被动挨打。


四、两种回传方案的影响对比

一次回传的系统设计更简单,单据关系清晰,财务对账也容易。

但它能跑通有一个前提:

供应商送货前必须先发起送货通知,在系统里生成对应的采购收货通知单,而且这张通知单要对应一次边界清晰的送货计划。

仓库收完货,触发一次回传,采购收货通知单完结。

如果供应商后来又送了一批,对应的单据已经关了,仓库无单可收,只能重新发起一张新的采购收货通知单,或者走异常收货流程。

多次回传则把这个压力转移到系统侧。

供应商送货节奏可以更灵活,但ERP要处理更复杂的单据关系、数量累计、库存入账、状态联动和完结判断。

维度 多次回传 一次回传
系统复杂度 高,需处理追加、累计、完结信号 低,单据关系简单
单据结构 采购收货通知单:采购入库单可能1:N 通常1:1
库存入账 可以分批入账,库存更实时 一次性入账,口径更清楚
财务对账 需要状态隔离,中间态不能随便开放 相对简单
完结风险 完结信号迟迟不来,单据挂起 供应商分批送货,单据提前关闭
核心约束 依赖WMS接口协议完整 依赖供应商送货规范落地

两种方案没有绝对好坏,关键看你们更能管住哪一侧。

如果能管住供应商送货规范,尽量用一次回传,系统会简单很多。

如果供应商送货节奏不可控,或者WMS天然就是分批作业,那就不要强行追求1:1,系统要老老实实支持多次回传。


五、我们的建议方案

这里给两个版本。

建议优先推简单版,推不动再上兼容版。

不要一开始就把系统做得很重。很多复杂设计看起来很稳,最后其实是把业务管理问题全部丢给系统兜底。

简单版:一次送货,一次回传,一张入库单

前提是先和供应商对齐送货规范。

一张采购订单可以拆成多张采购收货通知单,但每张采购收货通知单要对应一次明确的送货计划。

供应商按通知单送货,仓库按通知单收货,WMS收完后一次性回传,ERP生成一张采购入库单,通知单完结。

sequenceDiagram participant ERP participant WMS ERP->>WMS: 下推采购收货通知单(应收数量) Note over WMS: 仓库执行收货、质检、上架 WMS->>ERP: 一次性回传实收数量和完结标识 ERP->>ERP: 更新采购收货通知单实收数据 ERP->>ERP: 生成采购入库单,库存入账 ERP->>ERP: 回写累计入库数量至采购订单 ERP->>ERP: 采购收货通知单完结

这个方案的好处很明显:单据关系清晰,系统逻辑简单,财务对账也容易。

代价也很明确:供应商必须配合送货规范。

如果供应商经常不按通知单送货,或者一张通知单拆成多次到仓,那简单版就会在执行层不断出问题。

兼容版:支持多次回传,通过标识判断是否完结

如果供应商送货节奏无法保证一次完成,或者WMS本身就是分节点回传,那就需要支持多次回传。

核心设计是:

接口协议层,要求WMS回传时带两个字段:

字段 说明
received_qty 本次实收数量
is_final 仓库侧是否已完成本次收货操作

ERP处理逻辑,每次收到回传:

超时关单机制,如果超过约定时间仍未收到完结信号,系统自动向仓库发出关单通知,告知后续货物不再接收,采购收货通知单强制完结。

flowchart LR A["WMS回传数据"] --> B["生成采购入库单\n记录库存流水"] B --> C["累计更新采购收货通知单已收数量"] C --> D{{"完结条件满足?"}} D -->|"累计数量=通知数量"| E["系统自动完结"] D -->|"is_final=true"| F["系统触发完结"] D -->|"超时未完结"| G["系统通知仓库关单\n强制完结"] D -->|"否"| H["继续等待下次回传"]

这套方案比简单版复杂,但更能适配真实业务。

供应商分批送货,WMS分批回传,ERP分批生成采购入库单,库存也可以按实际收货节奏入账。

只要接口协议和状态机设计清楚,这条链路是可以跑稳的。

维度 简单版 兼容版
通知单:入库单 1:1 1:N
回传方式 WMS一次性回传 WMS支持多次回传
库存入账 一次性入账 分批入账
完结时机 回传完成即完结 根据数量、is_final、超时机制判断
系统复杂度
前提条件 供应商配合送货规范 接口协议和状态机要设计清楚

六、关单这个动作,应该放在哪里

采购入库这条链路里,最容易被忽视的,其实不是收货,而是关单。

很多团队一开始只会讨论:

采购订单怎么下推?

通知单怎么生成?

WMS怎么回传?

采购入库单怎么入账?

但真正上线以后,问题往往出在:

这张单到底什么时候算结束?谁有权让它结束?结束以后,后面的货还能不能收?

这才是采购入库单据流转里最容易踩坑的地方。

WMS能告诉ERP的是执行事实。

比如这次收了多少,哪些SKU收了,哪些SKU少了,哪些批次入库了,仓库作业是否已经完成。

ERP要承接的是业务闭环。

比如采购收货通知单是否完结,采购订单累计入库数量是否回写,后续还能不能继续收货,缺量是否要进入异常处理。

这两个东西不能混在一起。

flowchart LR A["WMS执行事实"] --> B["实收数量"] A --> C["质检结果"] A --> D["上架结果"] A --> E["is_final完结标识"] F["ERP业务闭环"] --> G["更新通知单已收数量"] F --> H["生成采购入库单"] F --> I["回写采购订单"] F --> J["判断是否关单"] B --> F C --> F D --> F E --> F

所以更准确的说法是:

WMS负责反馈执行事实,ERP负责完成业务闭环。

如果累计实收数量已经等于通知数量,ERP可以自动完结。

如果WMS回传is_final=true,说明仓库侧本次收货操作已经完成,ERP可以根据接口协议触发通知单完结。

如果长时间没有收到完结信号,ERP可以按超时规则通知仓库关单,并强制完结采购收货通知单,避免单据长期挂起。

这里的关键不是“谁点了按钮”,而是关单规则必须在ERP侧被清楚定义

WMS可以反馈作业结果,也可以反馈完结标识,但最终这张采购收货通知单怎么完结、完结后怎么影响采购订单、库存和财务口径,必须由ERP来承接。

这也是很多项目容易出问题的地方。

接口一开始没说清楚,后来就变成:

WMS说我已经推完了。

ERP说我不知道你这是不是最后一次。

采购说供应商后面可能还有货。

仓库说我现场已经收完了。

最后每个系统都觉得自己没错,但单据就是卡住了。


写在最后

采购入库这件事,表面看是采购订单、采购收货通知单、采购入库单之间的流转问题。

但真正落到系统设计里,最关键的是三件事:

第一,单据语义有没有拆清楚。

采购订单是采购意图,采购收货通知单是收货指令,采购入库单是执行结果。三层单据不能混用,否则后面的状态一定会乱。

第二,WMS回传协议有没有对齐。

到底是一次回传,还是多次回传?每次回传代表什么?回传数量是本次数量,还是累计数量?is_final代表什么?异常时怎么补偿?这些不提前说清楚,后面一定会靠代码补洞。

第三,关单规则有没有定义清楚。

什么时候自动关?什么时候按is_final关?什么时候超时强制关?关单以后后续到货怎么处理?这些规则如果没有在ERP侧设计清楚,后面就会变成仓库、采购、系统三方互相拉扯。

做供应链ERP久了会发现,很多「系统复杂度」本质上是「沟通欠债」。

当初没有把接口语义、完结时机、异常处理说清楚,后来就只能靠状态机、补偿逻辑和人工介入去兜底。系统看起来是跑起来了,但每次出问题,都要重新翻旧账。

所以如果你正在设计采购入库这条链路,有一件事比把流程图画漂亮更重要:

把WMS侧、采购侧、仓库侧的人拉到一起,把回传字段、完结规则、异常处理,一条一条对清楚。

复杂不一定是坏事。

但如果复杂的原因是「当初没说清楚」,那就值得停下来重新对一遍。