先说结论
Odoo 里的折扣,不是一个字段打天下。
至少要分三层来看:
- 价目表折扣:价格规则算出来的折扣语义
- 行折扣:
sale.order.line.discount - 全局折扣:通过向导或折扣产品落成单独折扣行
所以你在页面上看到的一个 discount,背后未必只有一种来源。
为什么价目表折扣和行折扣不是一回事
从 sale_order_line.py 可以看到:
- 行上有
discount字段 - 同时行还缓存了
pricelist_item_id _compute_discount()会根据价目表规则决定要不要把折扣显示出来
这说明:
价目表规则可能是折扣来源,但最终显示在行上的 discount 只是它的一种表现形式。
所以“价目表打折”和“手工改行折扣”不是同一个动作。
为什么有时价目表明明生效了,discount 却是 0
源码里 product.pricelist.item._show_discount() 很关键。
它说明只有某些规则形态下,系统才会把价差显式展示成 discount 百分比。
换句话说:
- 有时系统直接给你一个最终价格
- 不一定把它翻译成可见的折扣列
所以价格变了而 discount 还是 0,并不一定是错。
行折扣真正影响什么
sale.order.line.discount 最终会参与:
_get_discounted_price()- subtotal / total 计算
- 开票金额链路
也就是说,行折扣是实打实影响金额的业务字段,不是备注。
但它既可能来自手工输入,也可能来自价目表折扣显示逻辑。
全局折扣为什么常常像“多出一行”
在 sale.order.discount 向导和相关逻辑里,Odoo 往往会把全局折扣落成:
- 一条特殊折扣行
- 用公司配置的
sale_discount_product_id
这背后的设计非常务实:
全单折扣不一定适合隐身塞进每个行折扣里,单独落成一行更好对账、计税、开票。
所以全局折扣不是“把所有行的 discount 平均改一遍”。
新手最容易误解的 4 件事
1. 以为 discount 列就是全部折扣来源
其实价目表和全局折扣都可能参与。
2. 以为价目表折扣一定显示成百分比
很多时候只体现为结果价格。
3. 以为全局折扣就是改所有行
Odoo 往往单独生成折扣行。
4. 以为折扣只影响销售页展示
它会继续影响税、发票和金额链路。
一句话记忆法
价目表决定价格逻辑,行折扣决定单行减值,全局折扣决定整单减值;它们能相关,但不是一回事。
DISCUSSION
评论区