先说结论
Odoo 里的 Purchase Agreement 不是“更复杂的采购单”,而是用来表达采购前的约定结构。
它更像一句话:
先把采购规则、范围、供应商关系和后续下单边界定下来,再按这个框架去生成或约束 RFQ / PO。
所以它关心的不是某一张单,而是“一段采购关系”。
为什么它不是普通 PO
普通采购单解决的是:
- 这次向谁买
- 买什么
- 买多少
- 什么价
但采购协议要解决的是:
- 未来一段时间是不是按约定价格持续买
- 需不需要对多个供应商做并行报价比较
- 采购线是不是应该从一个共同来源拆出去
也就是说,PO 是执行单,Agreement 更像采购策略容器。
官方模块里最关键的区分
purchase_requisition 模块里,purchase.requisition 有关键字段 requisition_type,至少能表达:
blanket_orderpurchase_template
从官方 manifest 说明看,这个模块核心目标就是:
- Blanket Orders:和供应商建立阶段性价格/数量约定
- Calls for Tenders:向多个供应商发起竞争性报价
这就已经说明,它不是一个单一路径功能,而是两种采购治理方式。
Blanket Order 真正在解决什么
Blanket Order 最适合的场景是:
- 你会反复买某类物料
- 价格、交付条件提前谈好了
- 但不是一次性全下完
所以它不是“一张大采购单”,而是:
先锁采购关系,再按实际节奏去释放采购单。
源码里也能看到,确认 Blanket Order 时会校验:
- 行上必须有价格
- 行上必须有数量
因为如果连约定价格和数量边界都没有,那就不算真正的协议。
为什么它会影响 supplierinfo
在 purchase_requisition_line 相关逻辑里,Blanket Order 会把协议信息和 product.supplierinfo 连起来。
这很关键。
因为系统不是把协议当成一份“纯文档”,而是试图把它沉淀进后续采购选价逻辑里。
你可以把它理解成:
Agreement 不只是给人看,还要给系统后面选供应商和带价格时参考。
招标比价和 Blanket Order 的脑回路完全不同
这两者经常被混着讲,但本质不同:
Blanket Order
先谈好长期条件,再分批执行。
Call for Tender
先把需求摊开,让多个供应商竞争报价,再选一个或多个结果。
前者偏“长期合作框架”,后者偏“一次需求的竞争式采购”。
新手最容易误解的 4 件事
1. 以为 Agreement 只是 PO 的前置页面
其实它表达的是采购治理结构,不只是流程前一步。
2. 以为 Blanket Order = 一次性大单
更准确地说,它是分批释放的长期约定。
3. 以为确认 Agreement 后采购就结束了
真正执行往往还要生成 RFQ / PO。
4. 以为比价招标只是“多发几封询价邮件”
在系统层,它是把多个报价挂在同一采购语义下对比。
一句话记忆法
PO 是执行单,Purchase Agreement 是采购框架;Blanket Order 管长期约定,招标比价管竞争选择。
DISCUSSION
评论区