跨公司销售自动补采购,看上去像是“确认 SO 后顺手建一张 PO”。但企业版真正做的是把销售语义翻译成采购语义,而不是复制一份表单。
入口在 sale.order._action_confirm()。系统先完成正常销售确认,再根据客户 partner 反查目标公司;只有对方公司启用了 intercompany_generate_purchase_orders,而且当前 SO 不是自动生成单据时,才会继续进入 inter_company_create_purchase_order()。这一步和采购转销售相互对称,本质上仍是防止跨公司单据递归爆炸。
进入创建逻辑后,Odoo 同样会切到对方公司的 intercompany user,并检查这个用户是否拥有 purchase.order 创建权限。也就是说,销售人员点确认,并不意味着他跨公司拥有采购权限;企业版是借助专用用户来保证审计边界清楚。
_prepare_purchase_order_data() 特别值得看。它把 origin 和 partner_ref 都指回原 SO,把 partner_id 设成源公司 partner,把 payment_term_id 切成供应商付款条件,并保留 currency_id。这说明跨公司采购并不是“客户视角的销售单副本”,而是站在收货公司的采购视角重新组织字段。
_prepare_purchase_order_line_data() 更体现这种翻译关系:数量会转换到产品主单位,价格会按产品单位重算,而 date_planned 优先取 commitment_date,其次才是 expected_date 或订单日期。测试 test_05_inter_company_delivery_date() 也在强调这个点:采购交期不是随便写今天,而是尽量继承销售侧已经承诺给下游的时间。
另一个容易被忽略的点是自动确认。若对方公司把 intercompany_document_state 配成 posted,创建出的采购单会立刻 button_confirm();否则只停留在草稿。很多团队误以为“自动生成 = 自动生效”,其实 Odoo 把“生成单据”和“推进状态”拆成了两个治理开关。
实战中如果发现 SO 确认后没长出 PO,别先怀疑触发器;优先核对 partner 与 company 对应关系、intercompany user、采购权限,以及 commitment date 是否合理。跨公司采购最怕的不是少一张单,而是生成了一张交期、伙伴、付款条件都错位的单。
所以这条功能真正厉害的地方,不是省掉录单动作,而是把销售承诺、采购执行和公司权限三件事放在同一条受控链里。
DISCUSSION
评论区