Multi-company is one of Odoo's most powerful - and most misunderstood - features. The promise is straightforward: one database, multiple legal entities, each with its own chart of accounts, bank accounts, and reporting. The reality involves a tangle of sharing decisions, security rules, and intercompany transaction flows that can produce subtle errors if configured carelessly.
This guide covers what gets shared across companies, how intercompany transactions work, and how Odoo enforces company-level access control.
Enabling multi-company mode#
Multi-company is always active in Odoo - every database has at least one company. The switch at Settings → Users & Companies → Companies → New creates additional companies within the same database.
Adding a second company does several things automatically:
- Activates the company switcher in the top navigation bar
- Adds a
company_idfilter to all relevant model views - Applies company-domain record rules to partition data by company
Each user's allowed companies are configured on the user form (Settings → Users → select user → Companies tab). The company_id field on the user sets their default company; the list of allowed companies determines which company records they can access in a single session.
Branch companies vs. independent companies#
Before configuring anything, decide the relationship between your entities:
Branch companies share a chart of accounts, products, and contacts. They typically have the same parent. The intercompany transactions between them are mostly internal journals and consolidated reporting.
Independent companies have separate charts of accounts, separate tax configurations, and separate vendor/customer bases. They share minimal data. Intercompany transactions cross legal entity boundaries and require proper billing entries on both sides.
Most Odoo multi-company setups are one of these two patterns. A single database handling both patterns at once requires careful scoping of which records are shared at which level.
What gets shared across companies#
In a multi-company setup, some records belong to one company (company-specific) and others are shared across all companies (global):
Always shared (no company_id field):
- Contacts (
res.partner) - shared by default; all companies see all partners - Products (
product.template) - shared by default; all companies can sell/buy the same products - Units of measure, product categories
- Countries, currencies, languages
Company-specific by default:
- Journal entries and moves (
account.move) - Bank accounts
- Fiscal years and tax periods
- Pricelists (can be shared if needed)
- Employees (linked to one company)
- Sales orders, purchase orders, invoices
The shared/isolated distinction for contacts and products is the one that trips integrators up most often. By default, a contact created in Company A is visible in Company B. This is intentional - you probably want to call the same vendor from both entities - but it means that if you archive a contact in one company, it disappears from the other. Always confirm with the client whether contacts and products should be truly global or per-company before going live.
Making contacts or products company-specific#
To restrict a contact to a single company, set the company_id field on res.partner to the target company. Odoo then applies the standard company-domain record rule and hides the partner from other companies.
# In code: filter partners to the current company
partners = self.env['res.partner'].search([
'|',
('company_id', '=', False),
('company_id', '=', self.env.company.id),
])The |, ('company_id', '=', False) clause is the standard pattern for models that can be either shared (company_id = False) or restricted (company_id set). Use it in custom module domains wherever you want company-aware filtering.
For products, the same logic applies: leave company_id empty on product.template to share across all companies, or set it to restrict the product to one entity.
Intercompany transactions#
When Company A sells to Company B (both in the same database), Odoo can generate the corresponding purchase order in Company B automatically. This is the intercompany transaction feature.
Setup: Settings → Accounting → Inter-Company Transactions
Options for each company:
- Synchronize Sales Order / Purchase Order: when a SO is confirmed in Company A with Company B as the customer, Odoo creates a draft PO in Company B pointing back to Company A.
- Synchronize Invoices: customer invoices in Company A create vendor bills in Company B.
Both rules must be configured in both companies (A→B and B→A) for bidirectional flow.
The generated intercompany documents are linked via the auto_generated flag and reference each other in the chatter. Confirm one side and the other updates its status accordingly.
Intercompany journal: each company that participates in intercompany transactions needs a dedicated Intercompany journal (type: miscellaneous). Odoo uses this journal to post the elimination entries when generating consolidated reports.
Chart of accounts in multi-company#
Each company has its own chart of accounts in Odoo. You cannot share a chart of accounts across companies at the database level - each company's accounting is fully isolated.
This is a common point of confusion: contacts and products are shared, but accounting is always company-specific. When you post an invoice for the same product in Company A and Company B, each company uses its own revenue account, its own tax configuration, and its own currency.
If two companies use the same accounting structure (a branch model), you still need to configure each company's COA separately. Using a localization module (e.g., l10n_us or l10n_fr) applies the same structure to both during setup, but they remain independent after that.
Company-scoped record rules#
Odoo enforces company separation through ir.rule records with a company domain. The standard rule on models with a company_id field looks like:
<record id="res_company_rule_private_employee" model="ir.rule">
<field name="name">Company access rule</field>
<field name="model_id" ref="model_account_move"/>
<field name="domain_force">[('company_id', 'in', company_ids)]</field>
</record>The magic variable company_ids expands to the list of companies the current user is allowed to access in their session. When a user switches companies using the top-bar switcher, company_ids updates and the record rules re-evaluate automatically.
For custom modules that add a company_id field to a new model, add the corresponding record rule or the model will not respect company isolation.
Users and company switching#
A user can have access to multiple companies. The top-right company switcher lets them activate one or several companies simultaneously. When multiple companies are active, Odoo shows records from all active companies combined.
Key distinctions:
- Default company (
company_idonres.users): the company used when creating new records - Allowed companies (
company_idsonres.users): companies the user can switch to - Active session companies (
company_idsin the security context): determined by what the user has selected in the switcher
A common support issue: a user sees invoices from two companies and doesn't understand why. The answer is almost always that they have two companies active in their session. Teach users to switch to a single company when they need to see company-isolated views.
Consolidated reporting#
Odoo does not have a built-in consolidated P&L or balance sheet that automatically eliminates intercompany transactions. The Accounting module provides a multi-company report view that sums across active companies, but manual elimination of intercompany balances is still required.
For true consolidated reporting, most Odoo implementations use one of:
- Export each company's financials and consolidate in a spreadsheet or BI tool
- Install the
account_consolidationmodule (Enterprise) which adds journal-entry-based elimination - Use Odoo's Spreadsheet app with multi-company pivot views
Common mistakes#
Creating contacts with company_id set by default: Some localizations or workflows set the company_id on new partners automatically. Check Settings → Technical → Companies → Company to ensure partner creation defaults match your sharing policy.
Forgetting to configure intercompany rules in both directions: if you configure Company A to generate POs in Company B when a SO is confirmed, you also need Company B's intercompany rule to generate the invoice when the PO is received. One-directional setup leaves half the transaction manual.
Activating multi-company after live data exists: migrating an existing single-company Odoo instance to multi-company after posting real transactions is painful. Contact records need company assignment, journal entries need migration, and opening balances in the new company need manual entry. Plan multi-company mode before go-live.
Using multi-company for business units that do not require separate legal entities: if two units share a bank account, a single COA, and file one VAT return, they are not separate companies in the Odoo sense. Use analytical accounts or branches instead.
For access control at the user/group level, see the Odoo security model guide. For intercompany journal entries and consolidation, see the Odoo multi-company accounting guide.

