很多企业一说毛利提成,就想在订单上加个字段算一下;但只要涉及跨产品、跨币种、跨团队统计,这个问题本质上就进入了报表层。
核心链路
sale_commission_margin/report/achievement_report.py覆写了sale.commission.achievement.report的_get_sale_rates(),把margin追加到可计算指标里。也就是说,企业版不是在佣金计划 UI 上临时塞个选项,而是先扩展底层报表支持的 rate 集合。- 真正的计算表达式在
_get_sale_rates_product():+ (rules.margin_rate * COALESCE(sol.margin, 0)) / fo.currency_rate。这个表达式直接说明毛利提成是基于销售行 margin,而不是订单总额,也不是 invoice 毛利。 - 更关键的是最后的
/ fo.currency_rate。企业版默认把结果归一到报表所需币种,否则多个币种的 margin 根本无法公平地进入同一 achievement 口径。 - 因此毛利提成的主链路是:销售行 margin -> achievement report SQL -> 汇率归一 -> 计划规则 rate,而不是“确认订单时现场算完存死”。
- 这也解释了为什么企业在调佣金时,常会出现“订单行 margin 看起来对,佣金却不对”的情况:错误不一定在业务单据,可能在报表层的汇率、规则或 SQL 聚合。
关键源码位置
/home/ubuntu/odoo-temp/enterprise/sale_commission_margin/report/achievement_report.py
容易误解的地方
- 误区一:毛利提成就是订单金额减成本再乘系数。企业版按销售行 margin 并走 achievement report 聚合。
- 误区二:币种不同也能直接合算。源码明确做了 currency_rate 归一。
- 误区三:只要改前端表单就能支持毛利提成。真正控制结果的是报表 SQL。
实战注意事项
- 发现毛利提成异常时,先核对销售行
margin是否可靠,再核对报表用的汇率日期。 - 若企业要按品牌、产品线做毛利提成,优先顺着 achievement report 扩展,不要散落在订单按钮里。
- 多公司场景下,先统一“佣金以哪种公司币种看齐”,否则争议会一直存在。
结语
企业版这些代码共同说明一件事:真正可上线的业务流程,靠的不是“页面上看起来能点通”,而是权限、状态、时机、对账口径和跨模块回写都被收紧。理解这些边界,实施和二开时就不容易走进“功能演示能跑、真实业务一用就散”的坑。
DISCUSSION
评论区