企业销售 / 订阅履约

Odoo 企业版订阅卖实物为什么不是“每期自动开票 + 正常出库”而已:期间拣货、已交付数量与下一期开单讲透

sale_subscription_stock 把订阅实物履约按“账期”切开:哪些 move 算本期开票、何时重置 qty_to_deliver、为什么 invoice 后还会重新 launch stock rule。

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

当订阅里卖的是消耗品或实物,最大的难点不是“能不能出库”,而是每一期该算哪些 move、哪些已经开过票、下一个周期又该何时补货。

核心链路

  1. sale_order_line.py_get_stock_subscription_lines() 先把“订阅 + consumable”挑出来,说明这套逻辑只针对会随账期反复履约的实物线。
  2. _get_outgoing_incoming_moves()_get_incoming_outgoing_moves_filter() 都按 last_invoice_date/start_date/next_invoice_date 划定期间窗口,只统计当前账期内的 move。企业版不是简单看累计已出库。
  3. _reset_subscription_qty_to_invoice() 在每期开始时把 qty_to_deliver 重新拉回订阅行数量;而 _reset_subscription_quantity_post_invoice() 在开票后又会重新 _action_launch_stock_rule(),为下一期准备补货动作。
  4. _prepare_procurement_values() 还会把本期开票日期区间写进 product_description_variants,让库存单据能带着 “2026-03-01 to 2026-03-31” 这类期间信息。
  5. stock_picking.py_action_done() 则专门抓“已经开过票但此后又确认的新 picking”,并通过 _post_subscription_activity() 给订阅单打告警。它提醒企业:实物流晚于账单,也必须被管理。

关键源码位置

  • /home/ubuntu/odoo-temp/enterprise/sale_subscription_stock/models/sale_order_line.py
  • /home/ubuntu/odoo-temp/enterprise/sale_subscription_stock/models/stock_picking.py

容易误解的地方

  • 误区一:订阅实物履约跟普通销售出库一样。这里最核心的是账期切片。
  • 误区二:开票后库存逻辑就结束。企业版会为下一期重新发起 stock rule。
  • 误区三:delivered qty 看累计历史即可。源码按本期开票窗口过滤 move。

实战注意事项

  • 卖“月配一箱耗材”这类业务时,测试一定要跨两个账期,别只测首期开票。
  • 若仓库抱怨拣货单说明不清楚,先看 product_description_variants 是否已经带上期间。
  • 发现“已开票后又出库”时,不要只补库存单,要查看系统生成的 subscription activity 是否已提示销售跟进。

结语

企业版这些代码共同说明一件事:真正可上线的业务流程,靠的不是“页面上看起来能点通”,而是权限、状态、时机、对账口径和跨模块回写都被收紧。理解这些边界,实施和二开时就不容易走进“功能演示能跑、真实业务一用就散”的坑。

DISCUSSION

评论区

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