导言
在 Odoo 中,模型决定了数据在数据库中的组织方式。所有业务信息——从采购单、发票到库存记录——都以模型为载体保存,模型定义了这些数据的字段、关系与行为。
对开发人员和功能顾问来说,理解模型至关重要。模型构成了 Odoo 的数据骨架,它不仅规定了字段与关联,还承载了核心业务逻辑与约束。
本文聚焦于 Odoo 最关键的模型之一:purchase.order。无论你是在做插件开发、第三方系统对接,还是设计采购流程,都会频繁接触到这个模型。
什么是 purchase.order 模型
purchase.order 用来记录采购请求与正式采购单。所有未入库、未开票的采购事务先在这里汇总,后续再与库存、会计等模块联动完成收货与付款流程。
在采购模块中,买方创建的询价单(RFQ)就是一条 purchase.order 记录;当供应商确认或买方批准后,该记录从草稿状态变为已确认。同一模型既保存草稿的 RFQ,也保存已确认的采购单,状态字段负责跟踪整个生命周期。
其他模块会通过模型继承扩展 purchase.order:库存模块增加收货与拣货逻辑,会计模块添加应付单字段,制造模块可以从物料清单生成采购单。各模块在保留核心结构的前提下补充自身所需的数据与功能。
模型中的核心字段
下面列出 purchase.order 中最常用的字段,理解这些字段能帮助你更准确地配置、开发与排查问题。
1. name
类型:字符型。存放采购单号或参考编码(例如 PO00042)。通常系统自动生成并用于列表展示与单据打印,是采购单的主要标识。
2. state
类型:枚举。表示订单状态周期。常见值包括:draft(草稿/RFQ)、sent(已发送)、to approve(待审批)、purchase(已确认)、done(已完成)、cancel(已取消)。状态决定可执行的操作与工作流走向。
3. partner_id
类型:Many2one(res.partner)。供应商或卖方。必填字段,用于关联供应商信息、价格表和供应商账单等。
4. partner_ref
类型:字符型。供应商的订单号或引用,用于供应商提供自有编号的场景,有助于收货和对账时匹配单据。
5. date_order
类型:日期时间。订单日期:草稿时为创建时间,确认后为确认时间。用于报告、排序及作为默认期望交期的参考。
6. date_approve
类型:日期时间。审批或确认时间,通常在状态变为已确认时自动写入,用于审计与报表。
7. order_line
类型:One2many(purchase.order.line)。采购明细行,每行包含物料、数量、单价与税项,是采购单的核心内容。
8. amount_untaxed
类型:浮点。未税小计,由明细行计算得出,用于页面展示与汇总。
9. amount_tax
类型:浮点。税额总计,根据配置的税率与明细行计算,体现在采购单与供应商发票上。
10. amount_total
类型:浮点。含税总额,是开票与财务核算的关键金额字段。
11. currency_id
类型:Many2one(res.currency)。币种,通常继承自公司或供应商,所有与金额相关的字段均以此币种计量。
12. origin
类型:字符型。来源单据,例如由销售单或制造单触发生成的采购单,会把来源单号写入此字段以便追溯。
13. dest_address_id
类型:Many2one(res.partner)。收货地址;未设置时通常使用公司地址。在直发(dropship)场景中,此字段会设为客户地址。
14. priority
类型:枚举。订单优先级,常见值为普通或紧急,用于在列表、报表或审批时突出显示需要优先处理的订单。
15. invoice_status
类型:枚举。开票状态:no(未开票)、to invoice(待开票)、invoiced(已全部开票)。决定“创建发票”按钮是否可见以及财务流程的下一步。
16. invoice_count
类型:整数。关联的供应商账单数量,系统计算并用于快速导航到相关发票列表。
17. invoice_ids
类型:One2many(account.move)。关联的应付凭证或发票,用于采购单与会计凭证之间的三方匹配与付款跟踪。
18. picking_ids
类型:One2many(stock.picking)。相关的收货/出货单,当启用库存模块时用于记录收货流程与拣货单。
19. picking_count
类型:整数。关联的拣货/收货单数量,系统计算,用于展示和快速打开收货记录。
20. create_date
类型:日期时间。记录的创建时间,由系统自动维护,便于审计与历史追踪。
21. write_date
类型:日期时间。最后一次修改时间,同样由系统维护,用于追踪数据变更时间点。
22. notes
类型:文本。可存放对供应商的说明、交付条款或内部备注,有时会打印在采购单上作为补充信息。
23. company_id
类型:Many2one(res.company)。多公司环境下表明该采购单属于哪个公司,影响权限与可见性。
24. user_id
类型:Many2one(res.users)。负责采购的人员或采购员,用于审批流与任务分配。
25. fiscal_position_id
类型:Many2one(account.fiscal.position)。税务地点映射,用来处理跨境或特殊税制下的税率/科目映射。
26. payment_term_id
类型:Many2one(account.payment.term)。付款条件(如 30 天净额、预付 50% 等),在创建应付账款时会被带入。
27. display_name
类型:字符型(计算字段)。组合显示名,通常把单号与供应商简要信息组合后展示,用于下拉选择与搜索结果。
28. active
类型:布尔。归档标志。设置为 False 后记录不会被删除,只在默认视图中隐藏,便于保留历史数据。
该模型在业务流程中的应用场景
1. 从询价到确认采购单的流程
买方在系统中建立一条询价(草稿),添加明细并发送给供应商。供应商确认或买方手动批准后,订单状态切换为已确认(purchase),随后可生成收货单与应付发票。
2. 收货环节
货物到达时,可以从采购单创建收货单,收货单(picking)会与采购单关联,系统根据实收数量调整库存并据此影响成本。
3. 生成供应商发票
在已确认订单基础上创建供应商发票时,发票行会从采购明细带入,付款条件与税务位置也会沿用采购单的设置,invoice_status 字段用于跟踪开票进度。
4. 直发(Dropshipping)
当销售单触发采购时,采购单的 origin 字段会回写来源销售单号,dest_address_id 设为客户地址,供应商直接把货发给客户,采购单成为销售与采购之间的桥梁。
5. 制造与物料需求
当制造订单需要外购原料时,会由 MRP 创建采购单,并把来源写入 origin 字段,使采购与生产链路可追溯。purchase.order 在整个采购到付款(procure-to-pay)流程中处于核心位置。
开发者如何扩展该模型
开发者可通过若干模式扩展 purchase.order,模型继承是最常用的方式。
模型继承机制
在自定义模块中使用 _inherit = 'purchase.order' 来扩展原模型。你可以新增字段、重写方法或添加约束,将修改封装在独立模块中以便后续升级维护。
新增字段
在继承模型中定义新字段,选择合适的字段类型(Char、Many2one、Boolean、Integer、Text、Selection 等)。多公司环境下注意字段是否应为 company-dependent。
Python 层逻辑扩展
可重写方法如 button_confirm、create 或 write 来加入自定义逻辑,调用 super() 保留原行为。对计算字段要特别注意依赖关系,避免出现缓存或数据不一致问题。
使用 Odoo Studio
Odoo Studio 能在不写代码的情况下快速添加字段与界面调整,适合简单定制。但对于复杂逻辑或需长期维护的扩展,推荐通过自定义模块实现。purchase.order 的 API 也通过 XML-RPC/JSON-RPC 暴露,便于与外部系统集成。
最佳实践要点
- 每个阶段都应使用恰当的状态,不要跳过审批或绕过确认流程,这会破坏后续自动化与权限控制。
- 当供应商提供自己的订单号时,应把 partner_ref 填写好,这有助于收货与账单匹配,减少对账差异。
- 善用 origin 字段来记录采购的来源单据,对于直发与制造触发的采购单尤为重要,便于跨模块追踪流程。
- 做 API 对接时,通过 XML-RPC 或 JSON-RPC 调用 purchase.order 模型,把外部 ID 与 Odoo 记录正确映射,避免重复创建或错配。
- 为自定义字段加上 x_ 或以模块前缀命名,能降低将来与官方字段冲突的风险,便于升级。
常见误区
- 在已确认的采购单上随意修改字段会带来风险。已确认单通常对某些字段有约束,错误修改会破坏库存或财务一致性,应通过正常工作流或生成新单处理变更。
- 不要混淆 partner_id 与 dest_address_id:前者指供应商,后者是实际收货地址(用于直发场景)。误用会导致货物发错地点或对账困难。
- 重写 button_confirm 却不调用 super() 会导致原有逻辑被覆盖,可能破坏其他模块的兼容性或将来升级时出现问题。
- 新增必填自定义字段但未提供默认值,会导致历史记录在升级或安装新模块时校验失败,谨慎设定可空性与默认值。
- 处理多币种供应商时,务必正确设置 currency_id,币种错误会导致成本计算与发票金额不一致,进而影响财务报表。
总结
purchase.order 是 Odoo 采购模块的核心:它既保存询价也保存已确认采购单。弄清字段含义以及模块如何在此基础上扩展,能帮助你更好地配置系统、编写扩展并实现稳定的集成。
无论你是负责业务流程的顾问,还是编写功能模块的开发者,掌握 purchase.order 的运作细节都能显著减少实施时间并避免常见错误。
需要我们协助实施 Odoo 吗?
Dasolo 为企业提供 Odoo 实施、定制与优化服务,擅长 API 对接与模块开发。我们的团队对 Odoo 的数据结构与关键模型(如 purchase.order)有深入实战经验。
如果你需要在 Odoo 上实现定制功能、完成第三方集成或优化采购流程,我们可以协助你完成实施与交付。 预约演示 以便讨论您的项目需求。