Se rendre au contenu

The sales.order Model: Understanding Odoo's Sales Order Architecture

A complete guide to Odoo's sales order model for developers and functional consultants
10 mars 2026 par
The sales.order Model: Understanding Odoo's Sales Order Architecture
Dasolo
| Aucun commentaire pour l'instant

Introduction


In Odoo, models define how data is structured and stored in the database. Every piece of business data you work with, from sales orders to invoices to contacts, lives in a model.


Understanding Odoo models is essential for both developers and functional consultants. Models are the foundation of the Odoo data architecture. They define fields, relationships, and business logic.


This article focuses on one of the most important models in Odoo: sales.order. Whether you are building custom modules, integrating external systems, or configuring sales workflows, you will work with this model.

What is the sales.order Model


The sales.order model represents quotations and sales orders in Odoo. It is the central place where all sales transactions are captured before they become invoiced or delivered.


This model in Odoo is used by the Sales module.


When a salesperson creates a quotation, they create a sales.order record. When the customer confirms, the order moves from draft to confirmed. The same model in Odoo holds both draft quotations and confirmed orders. The state field tracks the lifecycle.


Other modules extend this model through Odoo model inheritance. CRM links opportunities to orders. Accounting adds invoice fields. Inventory adds delivery and commitment dates. Each module adds what it needs without duplicating the core structure.

Key Fields in the Model


Here are the most important Odoo fields in the sales.order model. Understanding these will help you work effectively with quotations and orders.


1. name

Type: Char. This field stores the order reference or quotation number. It is typically auto-generated (e.g. S00042) and displayed in list views and on documents. It is the primary identifier for the order.


2. state

Type: Selection. Tracks the order lifecycle. Values: draft (quotation), sent (quotation sent to customer), sale (confirmed order), done (fully delivered and invoiced), cancel (cancelled). The state drives which actions are available.


3. partner_id

Type: Many2one (res.partner). The customer. Required. This is the main contact or company for the order. Used for all customer-related logic and reporting.


4. partner_invoice_id

Type: Many2one (res.partner). The billing address. If not set, it defaults to the partner_id. Use this when the invoice address differs from the main contact (e.g. central billing).


5. partner_shipping_id

Type: Many2one (res.partner). The delivery address. If not set, defaults to partner_id. Used for delivery orders and shipping calculations.


6. user_id

Type: Many2one (res.users). The salesperson or responsible user. Used for CRM, commissions, and activity assignment. Often set from the sales team or opportunity.


7. team_id

Type: Many2one (crm.team). The sales team. Groups salespeople and drives reporting. Used for team-based dashboards and quotas.


8. date_order

Type: Datetime. The order date. For draft orders: creation date. For confirmed orders: confirmation date. Used for reporting and sorting.


9. validity_date

Type: Date. The expiration date of the quotation. After this date, the quotation may become invalid. Useful for time-limited offers.


10. commitment_date

Type: Datetime. The promised delivery date. When set, delivery orders are scheduled based on this date rather than product lead times. Important for customer commitments.


11. order_line

Type: One2many (sale.order.line). The order lines. Each line contains product, quantity, price, and tax. This is the core detail of the order.


12. amount_untaxed

Type: Float. The subtotal before tax. Computed from order lines. Used for reporting and display.


13. amount_tax

Type: Float. The total tax amount. Computed from order lines based on tax configuration. Displayed on the order and invoice.


14. amount_total

Type: Float. The total amount including tax. The main amount for invoicing and reporting.


15. currency_id

Type: Many2one (res.currency). The currency. Usually inherited from the company or pricelist. All monetary fields use this currency.


16. pricelist_id

Type: Many2one (product.pricelist). The price list used for the order. Determines unit prices on lines. Can be set from the partner or manually.


17. payment_term_id

Type: Many2one (account.payment.term). Payment terms (e.g. Net 30, 50% advance). Used when creating invoices.


18. fiscal_position_id

Type: Many2one (account.fiscal.position). The fiscal position for tax mapping. Applied when the customer is in a different country or has special tax regime.


19. client_order_ref

Type: Char. The customer reference or PO number. Used when the customer provides their own order reference. Displayed on documents and in reports.


20. origin

Type: Char. The source document. For example, when an order is created from an opportunity, the opportunity name is stored here. Used for traceability.


21. create_date

Type: Datetime. Stores the date and time when the record was created. Automatically managed by Odoo. Useful for reporting and auditing.


22. write_date

Type: Datetime. Stores the date and time of the last modification. Also automatically managed. Helps track when data was last updated.


23. note

Type: Text. Terms and conditions or internal notes. Can be displayed on the quotation and invoice. Used for legal text or special instructions.


24. require_signature

Type: Boolean. When True, the customer must sign online before the order is confirmed. Used for e-commerce and portal flows.


25. require_payment

Type: Boolean. When True, payment is required before confirmation. Used for prepaid or deposit-based orders.


26. invoice_status

Type: Selection. Tracks invoicing: no (not invoiced), to invoice (ready to invoice), invoiced (fully invoiced), or upsell (additional lines to invoice).


27. locked

Type: Boolean. When True, the order cannot be modified. Set automatically when the order is confirmed or when related documents are posted.


28. company_id

Type: Many2one (res.company). In multi-company setups, this indicates which Odoo company the order belongs to. Affects record visibility and access.


29. tag_ids

Type: Many2many (crm.tag). Tags for categorization. Used for filtering, reporting, and segmentation. Flexible for custom workflows.


30. signed_by

Type: Char. Name of the person who signed the order when require_signature is used. Stored for audit.


31. signed_on

Type: Datetime. Date and time of signature. Used when signature is required for confirmation.


32. prepayment_percent

Type: Float. The percentage of the order that must be paid as prepayment. Used with require_payment for deposit-based orders.

How This Model Is Used in Business Workflows


1. Quotation to Order

Salesperson creates a quotation (draft). Adds lines, sets prices, sends to customer. Customer confirms. The order is confirmed (state = sale). Invoices and delivery orders can be created.


2. E-commerce and Portal

Customers place orders on the website. Orders are created as sales.order records. require_signature and require_payment can enforce online payment or signature before confirmation.


3. CRM to Sales

When an opportunity is won, a quotation is created from it. The origin field links back to the opportunity. user_id and team_id drive sales reporting and commissions.


4. Invoicing

From a confirmed order, users create invoices. Invoice lines are pulled from order lines. payment_term_id and fiscal_position_id come from the order. invoice_status tracks progress.


5. Delivery and Commitment

commitment_date drives delivery scheduling. When set, delivery orders are planned around it. partner_shipping_id defines the delivery address.

How Developers Extend This Model


Developers extend sales.order using several patterns. Odoo model inheritance is the main mechanism.


Model Inheritance

Use _inherit = 'sale.order' to extend the model. Add new Odoo fields, override methods, or add constraints. The inherit model in Odoo keeps your changes in a separate module for easy upgrades.


Adding Fields

Define new Odoo fields in your inherited model. Use the right field type: Char, Many2one, Boolean, Integer, Text, Selection. Consider company-dependent fields for multi-company.


Python Extensions

Override action_confirm, create, or write to add logic. Use super() to call the original. Be careful with computed fields and their dependencies.


Odoo Studio

Odoo Studio lets you add fields without code. Good for quick customizations. For complex logic or upgrades, custom modules are more maintainable.

Best Practices


  • Use the correct state for each stage. Do not skip states or bypass confirmation logic.
  • Set commitment_date when the customer has a promised date. It improves delivery planning.
  • Use commercial_partner_id when you need the top-level entity for grouping (e.g. for credit or reporting).
  • When building API integrations, use the XML-RPC or JSON-RPC API. The sales.order model is fully exposed. Map external IDs carefully.
  • For custom fields, use the x_ prefix or a module prefix to avoid conflicts with future Odoo versions.

Common Mistakes


  • Modifying confirmed orders without checking locked. Locked orders cannot be edited. Create a new revision or use the proper workflow.
  • Mixing up partner_id, partner_invoice_id, and partner_shipping_id. Each has a distinct purpose. Set all three when addresses differ.
  • Overriding action_confirm without calling super(). This can break other modules or future upgrades.
  • Adding required custom fields without defaults. Existing orders will fail validation on upgrade.
  • Forgetting to set pricelist_id when the currency or pricing differs from the default. Wrong prices can lead to incorrect invoicing.

Conclusion


The sales.order model is central to Odoo Sales. It stores quotations and confirmed orders. Understanding its fields and how modules extend it will help you configure, customize, and integrate Odoo effectively.


Whether you are a functional consultant mapping sales processes or a developer building custom modules, a solid grasp of sales.order will save time and prevent errors.

Need Help With Your Odoo Implementation?


Dasolo helps companies implement, customize, and optimize Odoo. We specialize in API integrations and Odoo development. Our team has deep experience with the Odoo data architecture and models like sales.order.


If you need help with your Odoo implementation, custom modules, or integrations, we are here to help. Book a demo to discuss your project.

The sales.order Model: Understanding Odoo's Sales Order Architecture
Dasolo 10 mars 2026
Partager cet article
Se connecter pour laisser un commentaire.