跳至内容

深入解析 Odoo 的 sales.order 模型与销售订单架构

面向开发者与功能顾问的 Odoo 销售订单模型全解析:从数据结构到扩展要点,带你系统掌握订单行、定价逻辑、税务处理与工作流定制,快速上手二次开发与配置优化
2026年3月10日
深入解析 Odoo 的 sales.order 模型与销售订单架构
Dasolo
| 还没有评论

导读:打开订单系统的黑匣子


在 Odoo 中,模型就是数据在数据库里的“表与规则”。每一类业务信息——从客户到发票、从报价到交付——都以模型的形式定义,模型决定了这些信息怎么保存、怎么关联、哪些操作合法。


不论是业务顾问还是开发人员,理解模型是使用 Odoo 的第一步。模型不仅定义字段,还规定了数据之间的关系与业务逻辑,是整个系统数据架构的基石。


本文聚焦一个常被触及的关键模型:sales.order。无论你是在搭建模块、对接外部系统,还是配置销售流程,这个模型几乎不可避免地会成为你的工作中心。

什么是 sales.order 模型


sales.order 表示系统中的报价与销售订单——所有销售相关的交易、价格明细与客户信息都会先记录到这里,随后再根据状态生成发票或发运单。


这个模型属于 Odoo 的销售(Sales)模块,是销售流程的核心数据结构。


典型流程是:业务员在系统中创建报价(draft),填写明细并发送给客户;客户确认后,记录状态切换为已确认(sale),随后触发开票与发货流程。草稿与已确认的订单都保存在同一个模型中,通过 state 字段区分生命周期阶段。


Odoo 的模块化设计允许其他应用对 sales.order 进行扩展:CRM 会把商机与订单关联,财务模块会增加发票相关字段,库存模块会加入交付与承诺时间等。各模块通过继承共同使用同一套核心结构,避免重复建模。

模型中的核心字段一览


下面列出在实际工作中最常用、最值得熟悉的字段。掌握这些字段能让你更准确地配置报表、进行系统集成和排查问题。


1. 订单编号(name)

类型:字符。保存订单或报价的唯一参考编号(如S00042),通常由系统自动生成。它是用户识别与打印文件时最直观的标识。


2. 状态(state)

类型:选项。记录订单所处阶段:draft(草稿)、sent(已发送)、sale(已确认)、done(已完成)、cancel(已取消)等。状态决定了用户可执行的后续操作与流程走向。


3. 客户(partner_id)

类型:Many2one(res.partner)。主客户或联系人,必填。几乎所有与客户相关的规则、价格和报表都会基于该字段展开。


4. 发票抬头(partner_invoice_id)

类型:Many2one(res.partner)。账单地址。如果不填写,默认使用 partner_id。用于结算方与寄账单地址与主客户不一致的场景。


5. 收货地址(partner_shipping_id)

类型:Many2one(res.partner)。发货地址。不填写时同样回退到 partner_id。用于配送单与运费计算。


6. 负责人(user_id)

类型:Many2one(res.users)。负责跟进的业务员或用户。常用于业绩统计、佣金计算与日程分配。


7. 销售团队(team_id)

类型:Many2one(crm.team)。用于将业务员归组,驱动团队报表与配额管理。


8. 订单日期(date_order)

类型:Datetime。草稿阶段为创建时间,确认后为确认时间。常用于报表的时间维度和列表排序。


9. 报价有效期(validity_date)

类型:Date。报价到期日,过期后通常需要重新确认或重新报价,适用于有限期促销的管理。


10. 承诺交期(commitment_date)

类型:Datetime。客户承诺的交货时间点。当设置后,系统会以此为基准安排发运,而非仅依赖物料提前期。对客户承诺管理尤为重要。


11. 订单行(order_line)

类型:One2many(sale.order.line)。订单的明细行:包含商品、数量、单价与税项,是订单的核心数据单元。


12. 不含税金额(amount_untaxed)

类型:Float。订单行合计的税前小计,自动计算并用于显示与报表。


13. 税额(amount_tax)

类型:Float。按税码与配置计算出的总税额,显示在订单和发票上。


14. 含税总额(amount_total)

类型:Float。含税后的最终金额,是开票与财务核算的关键数值。


15. 币种(currency_id)

类型:Many2one(res.currency)。通常继承公司或价格表设置。所有货币字段以该币种计价,跨币种对接时需注意换算。


16. 价格表(pricelist_id)

类型:Many2one(product.pricelist)。决定行项目单价的定价策略,可由客户默认或手工选择。


17. 付款条件(payment_term_id)

类型:Many2one(account.payment.term)。例如“票期30天”或“预付50%”,影响生成发票时的到期日计算。


18. 税务规则(fiscal_position_id)

类型:Many2one(account.fiscal.position)。用于税率映射,跨境或特殊税制客户时需配置正确的财务规则。


19. 客户订单号(client_order_ref)

类型:字符。客户方给出的采购单号或参考号,常印在单据上以便对账。


20. 来源(origin)

类型:字符。记录订单来源(例如来自某个商机或交互),便于事后追溯与报表聚合。


21. 创建时间(create_date)

类型:Datetime。记录记录被创建的时间,由系统自动管理,常用于审计与统计。


22. 最后修改时间(write_date)

类型:Datetime。记录最后一次变更时间,便于追踪数据更新时间点。


23. 备注(note)

类型:Text。用于写入合同条款、内部说明或特殊交付要求,可选择显示在报价或发票上。


24. 是否需要签名(require_signature)

类型:Boolean。启用后客户需在线签署才能确认订单,常见于电商或客户门户场景。


25. 是否需付款(require_payment)

类型:Boolean。为 True 时要求客户先付款才能确认订单,适用于订金或预付模式。


26. 开票状态(invoice_status)

类型:选项。显示开票进度:no(无需开票 / 未开票)、to invoice(待开票)、invoiced(已完全开票)等,便于财务跟进。


27. 锁定标记(locked)

类型:Boolean。被锁定的订单不可修改,通常在确认、记账或关联凭证生成后设为真,防止越权更改。


28. 公司(company_id)

类型:Many2one(res.company)。多公司环境下标识此订单所属公司,影响可见性与会计科目等。


29. 标签(tag_ids)

类型:Many2many(crm.tag)。用于灵活分类与筛选,便于运营与销售分群管理。


30. 签署人(signed_by)

类型:字符。当启用签名时保存签署人的姓名,用于审计记录。


31. 签署时间(signed_on)

类型:Datetime。保存实际签署的时间戳,作为确认交接的凭证。


32. 定金比例(prepayment_percent)

类型:Float。表示需预付的百分比,配合 require_payment 实现分期或订金逻辑。

在实际业务流程中的使用场景


流程示例一:从报价到订单的标准路径

业务员先建报价:填明细、套价格、发给客户;客户确认后报价转为订单(state 从 draft 变为 sale),随后可生成发票与发货单完成履约。


场景示例二:电商与客户门户下单

网站下的订单直接写入 sales.order,系统可通过 require_payment 或 require_signature 强制在线付款或签名后才完成确认。


场景示例三:CRM 到销售的闭环

赢单后的商机可一键生成报价,origin 字段记录来源,user_id 与 team_id 则帮助归因与业绩拆分。


场景示例四:从订单到财务开票

确认后的订单用于生成发票;发票行会拉取订单行数据,付款条件与税务设置随订单传递,invoice_status 用于跟踪开票进度。


场景示例五:交付安排与承诺日管理

使用 commitment_date 来规划发运优先级与排产,当客户有特定交期要求时,应在订单上明确该字段并据此调度库存与物流。

开发者如何在此模型上扩展功能


开发扩展的总体思路


Odoo 主要通过模型继承来扩展已有模型:在你自己的模块中继承 sales.order,添加字段或覆盖方法,而不会直接改写核心代码。

模型继承实操要点


通过设置 _inherit = 'sale.order' 在自定义模块中添加字段与约束,或对已有方法进行增强。这样做能把自定义改动封装到独立模块,便于升级与维护。

新增字段的建议


在继承模型里声明新字段,选择合适的数据类型(Char、Many2one、Boolean、Integer、Text、Selection 等)。多公司环境下注意是否需要 company-dependent 设置。

Python 层面的扩展策略


如需改写业务逻辑,可重载 action_confirm、create、write 等方法,并在适当位置调用 super() 保留原有行为。对计算字段尤其要注意依赖关系与缓存问题。

使用 Odoo Studio 的利弊

实施与定制时的最佳实践


  • Odoo Studio 可无代码快速添加字段与视图,适合小改动或试验。但对复杂逻辑、长期维护或多实例升级,自建模块更稳妥。
  • 遵循流程状态,别跳过必要步骤
  • 不要跳过确认或直接修改状态以绕过验证。正确使用 state 与相应动作能避免数据不一致与流程异常。
  • 设定承诺交期以改善交付管理
  • 当客户要求明确交期时务必填写 commitment_date,它将影响发运计划并提升客户满意度。

常见错误与陷阱(以及如何避免)


  • 在需要归并企业主体时用 commercial_partner_id
  • 如果公司存在子公司/分支结构,使用 commercial_partner_id 可按顶层客户聚合信用与报表数据。
  • 外部系统对接时使用官方 API 并管理外部 ID
  • 通过 XML-RPC 或 JSON-RPC 与 Odoo 交互,sales.order 在 API 层可完整操作。对接时务必维护外部系统的唯一标识(external id)以便双向同步。
  • 自定义字段命名要有前缀以避免冲突

总结:把握订单模型,减少变更风险


给自定义字段加模块前缀或使用 x_ 前缀(例如 x_my_field 或 mymodule_x_field),能降低与未来 Odoo 版本字段命名冲突的风险。


不要直接改动已确认且被锁定的订单

需要 Odoo 实施支持?


被标记为 locked 的订单不能直接编辑。若需变更,应走修订流程或通过官方支持的解锁机制,避免数据完整性问题。


常见错误 1:混淆不同地址字段的用途 把 partner_id、partner_invoice_id 与 partner_shipping_id 搞混会导致发票或物流单据寄错人。客户地址不同请同时设置三者。 常见错误 2:覆盖关键方法却不调用 super()

深入解析 Odoo 的 sales.order 模型与销售订单架构
Dasolo 2026年3月10日
分析这篇文章
登录 留下评论