一套能跑起来的供应链系统,骨架上通常挂着六个模块。按从采购到履约的顺序排,是需求计划、采购与供应商管理、仓储管理(WMS)、运输管理(TMS)、订单管理(OMS)、结算与协同门户;质量与退换(RMA)一般作为附加块挂在末尾,按需启用。这六块的边界如果划不清,常见的结果是同一份库存数据在三个系统里各存一份,对账时谁也说不清哪份是准的。下面按模块逐一拆职责、关键指标与边界争议。
六类系统分别管什么
六类系统的分工能用一条主线串起来:计划决定买多少,采购负责买到,仓储负责存好,运输负责送到,订单串起客户需求,结算与协同负责收尾。任何一块缺失,链路上都会留下靠人工补的断点,而人工断点往往就是差错和延期的来源。
把六类模块和两项支撑能力摆在一起看,职责边界如下:
| 模块 | 主要职责 | 关键指标 | 典型输入 | 典型输出 |
|---|---|---|---|---|
| 需求计划 DP 与主计划 MPS/MRP | 决定买多少、什么时候买 | 计划准确率、库存周转天数 | 历史销量、在手库存 | 采购申请、生产工单 |
| 采购与供应商管理 SRM | 询价比价、下单、到货验收 | 供应商准时交付率、缺料率 | 采购申请、价格协议 | 采购订单、ASN 预告 |
| 仓储管理 WMS | 收货、上架、拣选、盘点 | 拣选效率、错发率 | ASN 预告、发货单 | 出库单、库存台账 |
| 运输管理 TMS | 配载、承运商分配、在途跟踪 | 满载率、准时率 | 出库单、收货地址 | 运单、POD 回单 |
| 订单管理 OMS | 订单拆并、库存可承诺判断 | 订单履约时长、履行完成率 | 各渠道订单 | 发货指令、退货单 |
| 结算与协同门户 | 计费核销、对账、伙伴协同 | 费用差异率、响应时长 | 运单、POD 回单 | 应付凭证、结算单 |
这张表的读法是从右往左看:谁输出,谁就是上游。表里每一行的输出都要成为下一行的输入,链条才闭合;如果某一行的输出没人接,说明这块模块上了线却没进流程。
按落地顺序盘一遍,搭架子时绕不开的是这八项:
- 需求计划:把销量与在手库存换算成采购申请与生产工单。
- 采购管理:管住询价、比价、合同与到货验收的全过程。
- 供应商管理:用交期协议与考核分数约束供货表现。
- 库存管理:维护库存台账,处理调拨、盘点与呆滞监控。
- 仓储管理:把收货、上架、拣选、复核、发货做成标准动作。
- 运输管理:按承运商费率与装载约束安排发运与在途跟踪。
- 订单管理:承接多渠道订单,做拆单、并单与可承诺判断。
- 结算协同:完成运费核销、对账与供应商、承运商门户协同。
前八项里,第 1 到第 4 项偏计划与账务,第 5 到第 8 项偏执行与结算。中小规模业务先做执行侧往往更快见效,因为拣货、发货的动作能立刻被量化;但只做执行侧不做计划侧,库存水位就只能靠经验拍,缺货和压货会同时出现。
计划类模块:先定买多少,再定什么时候买
计划类模块回答的是两件事——买多少、什么时候买,它输出的采购申请与生产工单,决定了后面所有环节的节奏。需求计划(DP)处理总量与分层,主计划(MPS/MRP)把它翻译成物料级的净需求,分销网络再按各仓的服务水平做补货推算。
这一块最容易出的问题是参数和主数据脱节。计划跑出离谱的采购量,回头看往往是提前期、最小起订量或替代料关系没维护对,而不是算法不行。多层 BOM 场景下,一个物料的最小包装量填错,整棵 BOM 的需求都会被放大,采购员只能靠人工砍单兜住。
真正决定计划质量的,是计划粒度和更新频率能不能跟得上业务节奏。按月跑一次计划,遇到促销或断供就只能被动响应;把计划做成周滚动、按物料分级调整颗粒度,既控制住计算成本,也留出了调整余地。计划结果是建议,不是命令,采购与生产环节要有回写实际执行结果的通道,下一轮计划才能收敛。
采购与供应商模块:从询价比价到到货验收
采购模块的职责是把采购申请变成带价格和交期的采购订单,并管到到货验收这一段。询价比价、合同条款、供应商交期确认、ASN 发货预告、到货质检、对账付款,构成了这条链上的主要动作。
比价环节有个常见偏差:只看单价,不看综合成本。账期、运费承担方、最小起订量、包装规格都会影响到岸成本,把这些字段一起纳入比价口径,才能避免选了单价低但总成本高的供应商。另一个高频问题是 ASN 预告缺失,货车到了仓库才开始核对单据,卸货排队时间直接变成仓储成本。
供应商侧的考核要落到可核对的字段上。交期履约率、来料不良率、响应时长这些指标从系统里直接取数,考核结果才有说服力;靠人工统计的分数,几个月后就没人看了。考核结果还要反向接进采购分配比例,形成约束,否则整条链路只是记录,没有牵引。
仓储与运输模块:WMS 管仓内动作,TMS 管仓外流转
WMS 负责仓内作业,TMS 负责仓外流转,两者以出库单为分界。仓内是收货、上架、拣选、复核、装车,仓外是配载、承运商分配、在途跟踪、签收回单。
| 维度 | WMS(仓储管理) | TMS(运输管理) | 结论 |
|---|---|---|---|
| 空间范围 | 仓内库区与库位 | 仓到收货点之间的路径 | 按物理边界切分 |
| 核心动作 | 上架、拣选、复核、盘点 | 配载、调度、跟踪、回单 | 动作对象不同 |
| 关键指标 | 拣选效率、错发率 | 满载率、准时率 | 指标不通用 |
| 主要约束 | 库位容量、作业波次 | 车辆载重、路线与时效 | 约束来源不同 |
| 交接点 | 装车完成、封签 | 接车起运 | 以出库单为界 |
装车环节的边界归属
边界争议通常出现在装车环节:装车动作在仓内做,装载方案却由运输侧算。常见做法是把装载方案作为出库单的附加指令下发给 WMS,仓内按方案装车、按封签交接,责任划分清楚,也避免两边各算一遍。
库内作业的优化方向
库内作业的优化点集中在拣选路径和波次策略上。订单结构分散时,按订单单独拣货的行走距离会迅速放大,改成波次拣选、把多张订单合并成一个批次,路径能明显压缩;越库作业适合整进整出的货品,跳过上架直接分流到出库暂存区。条码或 RFID 的作用是把这些动作变成可采集的数据点,没有采集,前面的策略调整就没有反馈信号。
订单履约模块:订单落到哪个仓由 OMS 决定
OMS 的职责是把一张客户订单拆成可以执行的发货指令,并决定由哪个仓、用哪种方式发出。它要处理拆单与并单、跨仓发货、预售与缺货场景,还要判断在途库存算不算可用。
拆单的触发条件要在系统里写清楚:单个仓库存不足、包裹超重、商品属性不能同包、赠品与主商品分开发,都可能触发拆分。规则如果只写在文档里、靠客服判断,同一类订单会出现好几种处理方式,履约时长自然失控。
库存可承诺(ATP)与可承诺量(CTP)是这一块的核心判断。ATP 看的是现货可分配量,CTP 还要把产能与在途补货算进去。促销期间只按 ATP 放单,会把超卖压力直接甩给仓库;把在途与预计到货纳入可承诺口径,再配合预售期限设定,超卖会明显收敛。逆向退货流程也要在 OMS 里闭环,退货单、质检结论、退款和库存回补要串成一条线,否则退回来的货既没入账也没上架。
结算与协同模块:把物流动作换算成钱
结算模块把运输与仓储的实际动作换算成费用,并与供应商、承运商完成对账。计费规则匹配、阶梯价格、附加费计算、运费核销、差异处理,是这条链上的主要动作。
计费出错多半不是因为算错,而是基础数据对不上:计费里程、站点归属、车型与费率表、附加费适用条件,任何一项缺失都会让同一趟运输算出两个金额。把计费规则的匹配结果在运单上留痕,对账时能直接比对差异来源,比逐单翻合同效率高得多。
对账周期本身也是成本。月度集中对账听起来整齐,实际上会积累大量争议单据,处理窗口又短。把对账切成按周或按批次滚动,让差异在发生时就被发现,结算周期和争议量都能压下来。协同门户的价值在于把交期确认、ASN 提交、回单上传这些动作交给伙伴自己录入,减少邮件与表格往返,同时留下可追溯的记录。
模块之间的数据流与集成方式
模块之间靠主数据和事件消息流动,主数据统一是前提,事件驱动是常态。物料、库位、供应商、承运商、地址这几类主数据必须全局唯一,同一批货在 WMS 和 TMS 里对应两个编码,后续的对账和追溯都会断在中间。
以事件驱动替代全量拉取
集成方式上,企业间以 EDI 报文为主,企业内部以接口调用和事件消息为主。近年的实践更偏向把关键状态变化做成标准事件,让各模块订阅,而不是让某一方反复拉取全量数据。下面这段定义了一个精简的供应链事件结构,附带履约链路的状态推进表:
from dataclasses import dataclass, field
from datetime import datetime
@dataclass
class SupplyEvent:
"""模块之间流转的标准事件。"""
topic: str # 如 wms.outbound.shipped
order_no: str
sku: str
qty: int
site: str # 仓库或承运商编码
ts: str = field(default_factory=lambda: datetime.now().isoformat(timespec="seconds"))
def validate(self) -> None:
if not self.order_no or self.qty <= 0:
raise ValueError("订单号与数量必须有效")
# 履约链路的状态推进:每个事件的下一跳
FLOW = {
"oms.order.paid": "wms.outbound.created",
"wms.outbound.shipped": "tms.shipment.created",
"tms.shipment.delivered": "oms.order.completed",
"oms.order.returned": "wms.inbound.created",
}
def next_topic(topic: str) -> str | None:
"""按链路表推算下一跳事件主题。"""
return FLOW.get(topic)
evt = SupplyEvent("oms.order.paid", "SO20260917001", "SKU-A", 20, "WH-SH-01")
evt.validate()
print(evt.topic, "->", next_topic(evt.topic))
这段代码的作用是给模块间通信立一个统一外壳:字段固定、主题命名固定,新增一个环节只需在链路表里补一行。要注意两点,一是事件必须带幂等键,重复投递不能让库存被扣两次;二是链路表要覆盖逆向流程,退货与换货如果不在表里,线上就只能靠人工补单。
到这里,从计划到结算的六类模块及其数据流就串完了。落地时不必一次上齐,但每上一个模块,都要同时确认它的输入从哪来、输出交给谁,这两头接不上,模块上得再多也只是多了一个孤岛。
常见问题(FAQ)
Q1:供应链系统一般分几类模块?
常见是六类:需求计划、采购与供应商、仓储、运输、订单履约、结算与协同。
Q2:WMS 和 TMS 的区别是什么?
WMS 管仓内作业,如拣选与盘点;TMS 管仓外运输,如配载与在途跟踪。
Q3:为什么上线 ERP 后还要单独配 OMS?
ERP 偏账务与主数据,多渠道拆单、并单与可承诺判断通常需要独立模块承接。