提成最难的不是“算一次”,而是计划改了、币种变了、经理和销售看的口径还得对得上。
这篇文章主要参考了以下企业版源码与测试入口:
enterprise/sale_commission/tests/test_sale_commission_plan.pyenterprise/sale_commission/tests/test_sale_commission_user.pyenterprise/sale_commission/wizard/sale_commission_add_multiple_user.py
一、这个模块真正解决的不是表面动作,而是跨模块语义对齐
企业版 sale_commission 处理的不是一个简单公式,而是一整套计划管理:计划周期拉长或缩短时 target 怎么保留、不同销售或经理视角下 achievement 怎么算、多币种订单怎么入同一业绩口径。
如果只看 UI,很容易把它理解成一个按钮、一张表或一个新视图。但从 sale_commission 的模型、测试和桥接关系看,官方真正关心的是:前台动作发生以后,后端主链路能不能继续保持同一套业务语义。
二、核心机制链路
1. plan 是主对象,不是附属配置
测试 targets_preserved_when_extending_date_range 与 targets_removed_when_shortening_date_range 说明,提成不是对历史订单临时求和,而是围绕时间区间与目标切分持续维护。
2. achievement 有角色视角差异
manager / user 两组测试分别覆盖经理查看团队表现和销售查看个人目标,说明同一套提成数据会在不同角色下被重新组织,不是简单共享一张金额表。
3. 多币种必须先统一口径
test_commission_user_achievement_SO_different_currency 直接点出不同币种订单的 achievement 需要转换到可比口径,否则目标完成率会被汇率噪声污染。
三、最容易被误解的边界
- 把 commission 当作订单确认时一次性写死的数字,忽略 plan 调整与目标周期变更。
- 只给销售看个人金额,不考虑经理视角下团队 achievement 的聚合逻辑。
- 多币种环境里直接按原币相加,最后目标完成率毫无意义。
这些误解之所以常见,往往是因为大家只看见“入口动作”,却没有继续追到模型方法、状态切换、聚合口径和测试场景里去看 Odoo 究竟把什么当成事实、把什么当成辅助信息。
四、实施与排查时,建议按这个顺序看
- 先查 plan 日期区间与 target 变更历史。
- 再查 achievement 取数是否按用户/经理角色切换。
- 最后确认不同币种订单在 achievement 层是否统一换算。
对企业版功能来说,排查顺序非常重要。很多看似是“结果不对”的问题,真正根因往往更早:字段上下文没带过去、桥接对象没建、状态机没推进、或者权限/公司边界一开始就错了。
五、结论
销售提成真正复杂的地方,是它既是激励制度,又是时间与组织口径管理问题;企业版正是在这里补足了“不能只靠一个乘法公式”的部分。
DISCUSSION
评论区