销售报价

Odoo 报价模板为什么不只是“预填几行”:Quotation Template、可选产品与 PDF 附件链路讲透

很多人把 Odoo Quotation Template 理解成复制几条默认行,但官方实现其实把有效期、签署/付款要求、可选产品区、以及报价 PDF 附件一起串成了一套“成交前台”。本文从 sale_management 与 sale_pdf_quote_builder 的源码把这条链路讲清楚。

销售
进阶 开发者 1 分钟阅读
0 评论 0 点赞 0 收藏 6 阅读

先说结论

Odoo 的报价模板,不是“把历史销售单复制一下”

它真正做的是:

先定义一套可复用的成交脚手架,再把默认行、有效期、签署/付款要求、可选产品,甚至报价 PDF 附件,一起带进新的报价单。

所以 Quotation Template 更像“销售打法模板”,而不是简单的草稿复制器。


这篇文章主要看了哪些官方源码

我这次主要参考了这些实现:

  • /home/ubuntu/odoo-temp/addons/sale_management/models/sale_order_template.py
  • /home/ubuntu/odoo-temp/addons/sale_pdf_quote_builder/models/sale_order.py
  • /home/ubuntu/odoo-temp/addons/sale_pdf_quote_builder/models/sale_order_template.py
  • /home/ubuntu/odoo-temp/addons/sale/controllers/product_configurator.py
  • /home/ubuntu/odoo-temp/addons/sale/models/product_template.py

其中最关键的信号有三个:

  1. sale.order.template 本身就带 require_signaturerequire_paymentprepayment_percent
  2. 模板行里可以出现 is_optional 语义,说明“可选项”本来就是模板的一部分
  3. sale_pdf_quote_builder 会在切换模板时同步装配 quotation_document_ids

这说明模板从一开始就不是单纯的“默认商品清单”。


报价模板到底在替销售团队节省什么

一个成熟销售流程里,重复的通常不是客户,而是:

  • 报价有效期规则
  • 是否要求在线签字
  • 是否要求预付款
  • 常见主商品组合
  • 常见附加项 / 增购项
  • 附带的品牌页、封面、页脚、产品资料 PDF

如果这些每次都靠销售手动拼,系统再强也会退化成“高级 Word”。

Odoo 的做法是把这些重复决策前移到模板层:

  • 模板先定义成交规则
  • 销售单再承接客户差异

这样新建报价单时,销售不是从零开始写,而是在一条既定成交路径上微调。


模板为什么能影响“签署”和“付款”

sale_management/models/sale_order_template.py 里,模板上直接有:

  • require_signature
  • require_payment
  • prepayment_percent
  • number_of_days

这非常关键。

它说明 Odoo 认为模板不仅决定“卖什么”,还决定:

  • 客户是否必须在线签字
  • 客户是否必须在线付款
  • 需要付多少比例才算确认
  • 报价有效期怎么算

也就是说,模板已经部分承载了成交政策

新手最容易误解的一点是:

以为这些设置应该都在公司级别统一控制。

但源码给出的设计是:

  • 公司级设置提供默认值
  • 模板级可以按销售场景微调

这就很符合真实业务。

比如:

  • 标准小单:只要求签字
  • 定制项目:要求 50% 预付款
  • 长周期方案:报价有效期更长

如果这些差异不能落到模板层,销售最终只能靠人记忆。


为什么“可选产品”不是普通备注

很多人第一次看到 Optional Products,会觉得这只是个“推荐配件列表”。

但从源码看,它不是备注,而是可被系统理解的增购结构

sale/models/product_template.py 里,optional_product_ids 明确挂在产品模板上;在 sale/controllers/product_configurator.py 里,系统会在主产品配置时同步拉出 optional_products

这说明 Odoo 处理的不是:

  • “下面写一句你也可以买 A、B、C”

而是:

  • 当前主商品是什么
  • 当前属性组合是什么
  • 在这个组合下,哪些可选产品应该展示
  • 展示时还要跟着价目表、币种、日期一起算

这就把 Optional Products 从“备注区”抬升成了“可配置加购链路”。


模板里的“可选项区”到底在干什么

在 demo 配置里,Odoo 甚至会主动生成一个 Optional Products Section,后面跟几条数量为 0 的行。

这个设计很有意思。

它不是为了做数学计算,而是为了表达:

这些行不是默认成交内容,而是给客户二次选择的空间。

所以模板里常见会同时存在两种内容:

1)主成交内容

  • 默认就带入报价单
  • 数量通常大于 0
  • 是本次方案的主体

2)可选成交内容

  • 默认不一定进入成交金额
  • 目的是引导增购、升级、补充方案
  • 更像“结构化 upsell”

这比销售在邮件里说“另外你也可以考虑延保服务”要强很多,因为系统可以继续围绕它做:

  • 门户展示
  • 价格计算
  • 客户选择
  • 后续转正式订单

PDF Quote Builder 为什么值得和模板一起看

如果只看 sale.order.template,你会以为模板只是“表单默认值集合”。

sale_pdf_quote_builder 把这件事又往前推了一层。

sale_pdf_quote_builder/models/sale_order.py 里,订单有:

  • available_quotation_document_ids
  • quotation_document_ids
  • customizable_pdf_form_fields

并且在 @api.onchange('sale_order_template_id') 中,会根据模板自动补入可用的 quotation_document_ids

这意味着:

模板不仅决定报价单里有哪些行,也决定这份报价要带哪些“销售材料”。

比如:

  • 品牌封面
  • 方案介绍页
  • 法务页脚
  • 产品附件 PDF

这样一来,报价模板就不只是“商品模板”,而是“成交文档包模板”。


为什么这套设计比“复制旧报价单”高级得多

复制旧单当然也能快,但它有三个问题:

1. 容易把历史脏数据一起复制过去

旧客户地址、旧付款条款、旧说明、旧附件,都会被无脑继承。

2. 难以统一销售打法

每个销售都复制自己最顺手的旧单,久了以后公司根本不知道“标准报价长什么样”。

3. 增购逻辑无法沉淀

可选产品、附带文档、默认签字/付款要求,都散在个人经验里,团队无法复用。

而模板的价值就在于:

  • 把共性抽成标准
  • 把差异留给当前订单

这才像一套可运营的销售系统。


实战里最容易踩的 4 个坑

1. 把模板当“静态商品包”

结果模板只填了几条产品,没配置签署、付款、有效期,也没设计可选项,最后模板价值极低。

2. 可选产品和主产品没有业务边界

如果什么都做成 optional,客户会觉得报价像菜单;如果什么都塞进主行,报价又会显得太重。

3. 模板与文档附件分离维护

销售改了模板,却忘了同步 PDF 封面或产品材料,最终客户看到的前台体验依然割裂。

4. 以为 Optional Products 只在网站商城有用

源码其实表明它和销售配置器、报价前台是打通的,不只是电商推荐。


该怎么设计一套真正好用的报价模板

我的建议是按三层来想:

第一层:成交底盘

  • 默认产品行
  • 报价有效期
  • 是否要求签字
  • 是否要求付款
  • 预付款比例

第二层:增购结构

  • 延保
  • 服务包
  • 升级版模块
  • 安装培训

第三层:文档包装

  • 封面 / 页脚
  • 产品资料页
  • 行业方案页
  • 合规说明页

当这三层都放进模板体系后,报价单才真的从“单据”变成“成交工具”。


一句话记忆法

Odoo 的 Quotation Template 不是复制几条默认行,而是在预设成交规则、增购结构和报价文档包装。

DISCUSSION

评论区

想参与讨论?先 登录 再发表评论。
还没有评论,你可以成为第一个留言的人。