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 journal entries, 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 Odoo fields, relationships, and business logic.
This article focuses on one of the most important models in Odoo Accounting: account.move. Whether you are building custom reports, integrating external systems, or configuring invoicing workflows, you will work with this model.
What is the account.move Model
The account.move model represents journal entries in Odoo. In Odoo 13 and later, it unified what used to be separate models: customer invoices, vendor bills, credit notes, and manual journal entries. Today, they all live in account.move.
This model in Odoo is used by the Accounting module. It is the parent of account.move.line, which holds the individual debit and credit lines. Every invoice, bill, or journal entry is one account.move record with one or more lines.
The model is defined in the account module. Other modules extend it through Odoo model inheritance. Sale adds invoice creation from orders. Purchase adds bill creation. 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 account.move model. Understanding these will help you work effectively with invoices, bills, and journal entries.
1. name
Type: Char. This field stores the journal entry number or name. It is typically auto-generated from the journal sequence. Displayed in list views and on printed documents.
2. move_type
Type: Selection. Determines the type of move: entry (manual journal entry), out_invoice (customer invoice), out_refund (customer credit note), in_invoice (vendor bill), in_refund (vendor credit note). This field drives which views and workflows apply.
3. state
Type: Selection. The workflow state: draft, posted, or cancel. Draft moves can be edited. Posted moves are locked and affect the general ledger. Cancel reverses the effect.
4. date
Type: Date. The document date. Used for reporting, aging, and period closing. For invoices, this is often the invoice date.
5. journal_id
Type: Many2one (account.journal). The journal this move belongs to. Sales, Purchase, Bank, and Misc journals each have their own. The journal determines the sequence and default accounts.
6. company_id
Type: Many2one (res.company). In multi-company setups, this indicates which company the move belongs to. Affects record visibility and consolidation.
7. partner_id
Type: Many2one (res.partner). The customer or vendor. Required for invoices and bills. Used for aging reports, payment matching, and document headers.
8. currency_id
Type: Many2one (res.currency). The currency of the move. Amounts are stored in this currency. Multi-currency moves use the company currency for reporting.
9. amount_total
Type: Monetary. The total amount of the move. For invoices, this is the amount due. Computed from the lines.
10. amount_residual
Type: Monetary. The unpaid amount. For paid invoices, this is zero. Used for aging and payment workflows.
11. payment_state
Type: Selection. Payment status: not_paid, in_payment, paid, partial, reversed, or invoicing_legacy. Drives payment reminders and reporting.
12. line_ids
Type: One2many (account.move.line). The journal entry lines. Each line has an account, debit, and credit. The sum of debits must equal the sum of credits.
13. invoice_line_ids
Type: One2many (account.move.line). For invoices and bills, these are the product or service lines. Each line generates one or more journal entry lines when posted.
14. invoice_date
Type: Date. The invoice date. Used for invoicing and tax periods. Can differ from the move date in some configurations.
15. invoice_date_due
Type: Date. The payment due date. Computed from payment terms or set manually. Used for aging and dunning.
16. ref
Type: Char. External reference or vendor bill number. Useful for matching payments and reconciling with external documents.
17. invoice_origin
Type: Char. The source document. For invoices from sales orders, this stores the SO number. Enables traceability from order to invoice.
18. create_date
Type: Datetime. Stores the date and time when the record was created. Automatically managed by Odoo.
19. write_date
Type: Datetime. Stores the date and time of the last modification. Also automatically managed.
20. narration
Type: Text. Internal notes or memo. Displayed on printed journal entries. Not shown to customers on invoices.
21. fiscal_position_id
Type: Many2one (account.fiscal.position). The fiscal position for tax rules. Determines which taxes apply based on partner and country.
22. invoice_payment_term_id
Type: Many2one (account.payment.term). Payment terms (e.g. Net 30). Used to compute invoice_date_due and split payments.
23. invoice_user_id
Type: Many2one (res.users). The salesperson or responsible user for the invoice. Used for commission and reporting.
24. reversed_entry_id
Type: Many2one (account.move). For reversed entries, this links to the reversal move. Enables audit trail of corrections.
25. to_check
Type: Boolean. Flag for moves that need review. Used in bank reconciliation and exception workflows.
26. active
Type: Boolean. Soft delete flag. When False, the record is archived. Canceled moves are typically set to active=False.
27. sequence_number
Type: Integer. The sequence number from the journal. Used for ordering and display. Managed by the sequence mixin.
28. amount_untaxed
Type: Monetary. The subtotal before tax. For invoices, this is the sum of line amounts before tax.
29. amount_tax
Type: Monetary. The total tax amount. Computed from invoice lines and tax configuration.
30. invoice_source_email
Type: Char. For vendor bills created from email, this stores the source email address. Used for automated bill ingestion.
How This Model Is Used in Business Workflows
1. Customer Invoicing
When a sales order is delivered, Odoo creates an account.move with move_type out_invoice. The invoice_line_ids come from the order lines. Posting the move creates the journal entry lines and updates receivables.
2. Vendor Bills
Purchase orders can generate bills, or bills are entered manually. Each bill is an account.move with move_type in_invoice. The partner_id is the vendor. Posting updates payables.
3. Payment Reconciliation
Payments are matched to invoices using the amount_residual and payment_state fields. The reconciliation process links payment moves to invoice moves and clears the residual.
4. Manual Journal Entries
Accountants create moves with move_type entry for adjustments, accruals, or corrections. They manually add line_ids with accounts, debits, and credits. The move must balance before posting.
5. Credit Notes and Refunds
Credit notes are moves with move_type out_refund or in_refund. They reverse the effect of the original invoice or bill. The reversed_entry_id links back to the original for audit.
How Developers Extend This Model
Developers extend account.move using several patterns. Odoo model inheritance is the main mechanism.
Model Inheritance
Use _inherit = 'account.move' 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. For invoice-specific fields, use a domain on move_type.
Python Extensions
Override create, write, _post, or button_draft to add logic. Use super() to call the original. Be careful with computed fields and their dependencies. The API model in Odoo decorators (@api.model, @api.depends) control when methods run.
Odoo Studio
Odoo Studio lets you add fields without code. Good for quick customizations like extra reference fields. For complex logic, validation, or automated actions, custom modules are more maintainable.
Note: account.move is a regular model, not an Odoo abstract model or Odoo transient model. Abstract models are used as templates and do not create database tables. Transient models are temporary and used for wizards. account.move stores permanent accounting data.
Best Practices
- Always filter by move_type when building reports or integrations. Different types have different required fields and behaviors.
- Use the correct journal for each move type. Mixing journals can break sequences and reporting.
- When creating moves via API, ensure line_ids balance (debits = credits) before posting. Unbalanced moves will fail validation.
- For invoice creation from external systems, map your document types to move_type correctly. out_invoice for sales, in_invoice for purchases.
- Use the
x_prefix for custom fields to avoid conflicts with future Odoo versions.
Common Mistakes
- Posting moves without balanced lines. Odoo will reject the post. Always verify debit and credit totals match.
- Modifying posted moves directly. Posted moves are locked. Use a reversal and create a new move instead.
- Forgetting to set partner_id on customer or vendor moves. Many reports and workflows depend on it.
- Using the wrong move_type. An out_refund is not the same as a negative out_invoice. Use the correct type for refunds and credit notes.
- Overriding core methods without calling super(). This can break other modules or future upgrades.
Conclusion
The account.move model is central to Odoo Accounting. It represents invoices, bills, and journal entries in a unified structure. Understanding its fields and how modules extend it will help you configure, customize, and integrate Odoo effectively.
Whether you are a functional consultant mapping business processes or a developer building custom modules, a solid grasp of account.move 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 account.move.
If you need help with your Odoo implementation, custom modules, or integrations, we are here to help. Book a demo to discuss your project.