Multi-Company Setup Odoo 18
By Braincuber Team
Published on December 29, 2025
International corporation operating three subsidiaries USA Europe Asia creates multi-company data chaos: sales order from USA office showing European customer violating company boundaries creating accounting nightmare mixed revenue jurisdictions, product pricing 100 USD set once appearing same all companies ignoring regional cost differences currency variations causing incorrect margins, employee from Paris subsidiary accessing New York customer data violating privacy regulations creating compliance exposure, invoice sequence collision where Company A invoice INV-00042 conflicts Company B invoice same number causing payment confusion, and shared product record changing warehouse location one company accidentally affecting all companies disrupting logistics operations—generating regulatory violations accounting errors pricing inconsistencies security breaches and operational confusion from improper multi-company configuration without company-dependent fields access restrictions and data isolation requiring systematic multi-company architecture implementation.
Odoo 18 Multi-Company Setup enables enterprise-scale operations through company-dependent fields storing different values per company for shared records, multi-company consistency validation ensuring related records belong same company preventing cross-company data contamination, default company assignment automatically setting company context for new records, security rules restricting user access to authorized companies only, record domain isolation filtering data by user company permissions, automatic validation checks preventing incompatible company relationships, with_company method switching company context for field value retrieval, check_company parameter validating relational field consistency, required company fields enforcing company assignment on critical models, and company_ids user permission defining accessible companies—reducing data isolation errors 100 percent through automatic validation preventing compliance violations via access restrictions enabling shared resource management through company-specific configurations supporting intercompany transactions controlled workflows and achieving enterprise scalability regulatory compliance operational efficiency through systematic multi-company architecture designing proper field definitions implementing security rules and maintaining data consistency across legal entities.
Multi-Company Features: Company-dependent fields, Consistency validation, Default company, Security rules, Domain isolation, Automatic checks, Context switching, Relational validation, Required fields, Permission management
Multi-Company Architecture
Core mechanisms for multi-company operations:
Key Components:
| Component | Purpose | Implementation |
|---|---|---|
| Company-Dependent Fields | Different values per company for shared records | company_dependent=True |
| Multi-Company Consistency | Ensure related records same company | _check_company_auto=True |
| Default Company | Auto-assign company to new records | default=lambda self: self.env.company |
| Security Rules | Restrict access by company permissions | ir.rule domain filters |
| Context Switching | Read different company values | with_company() method |
Company-Dependent Fields
Storing different values per company:
Field Definition:
Python field definition:
display_name = fields.Char(company_dependent=True)
Field stores different values for each company. Same record different companies shows different display_name values.
Real-World Example:
Product Standard Price:
Scenario: Office Chair sold in USA and Europe
standard_price = fields.Float(
string='Cost',
company_dependent=True
)Company-specific values:
- USA Company: Cost = 50.00 USD
- Europe Company: Cost = 45.00 EUR
- Asia Company: Cost = 6000 JPY
Same product record. Different costs per company reflecting regional procurement shipping local suppliers.
Accessing Company-Specific Values:
Using with_company() method:
product = self.env['product.product'].browse(product_id) usa_cost = product.with_company(usa_company).standard_price europe_cost = product.with_company(europe_company).standard_price # usa_cost = 50.00, europe_cost = 45.00
Switch company context retrieving appropriate value without changing user current company.
Multi-Company Consistency
Preventing cross-company data contamination:
Problem Statement:
Data inconsistency scenario:
- Company A invoice references Company B customer
- Sales order from Company X links product from Company Y warehouse
- Account move Company 1 using journal from Company 2
Cross-company references cause accounting errors inventory confusion compliance violations.
Solution: Automatic Validation:
Model configuration:
class SaleOrder(models.Model):
_name = 'sale.order'
_check_company_auto = True
company_id = fields.Many2one('res.company', required=True)
partner_id = fields.Many2one('res.partner', check_company=True)
warehouse_id = fields.Many2one('stock.warehouse', check_company=True)What happens:
- _check_company_auto = True: Enables automatic company consistency validation
- check_company=True: Validates relational field partner warehouse belong same company as sale order
- System automatically checks during create() write() operations
- Raises validation error if company mismatch detected
Validation Example:
Attempting invalid cross-company reference:
sale_order = self.env['sale.order'].create({
'company_id': company_a.id, # USA Company
'partner_id': partner.id, # Customer belongs to Company B
'warehouse_id': warehouse.id # Warehouse belongs to Company A
})
# ERROR: Partner must belong to Company A
# Validation prevents creation with mismatched companyDefault Company Assignment
Automatic company context:
Field Definition:
company_id = fields.Many2one(
'res.company',
default=lambda self: self.env.company,
required=True
)Benefits:
- Automatic Assignment: New records automatically assigned current user company
- Prevents Errors: Required field satisfied even when hidden from UI for non-multi-company users
- Correct Context: Backend scripts automated actions wizards use appropriate company
- Validation Success: Ensures company_id present during create() preventing validation failures
Why Default is Critical:
Hidden field scenario:
Single-company users dont see company_id field in UI (hidden via groups). Without default value:
- User creates record invoice sale order
- Form submitted without company_id value field hidden
- Validation fails: required field missing
- User confused no way to provide value
Default value solves this auto-populating field ensuring successful creation.
Security Rules
Access control by company permissions:
Security Rule Definition:
XML security rule:
<record id="res_partner_multi_company_rule" model="ir.rule">
<field name="name">Partners of user's companies</field>
<field name="model_id" ref="base.model_res_partner"/>
<field name="domain_force">
[('company_id', 'in', user.company_ids.ids)]
</field>
<field name="groups" eval="[(4, ref('base.group_user'))]"/>
</record>Rule Explanation:
| Element | Meaning |
|---|---|
| model_id | Applies to res.partner model |
| domain_force | Filters records: company_id must be in user allowed companies |
| user.company_ids | List of companies user has access to |
| groups | Applies to all users in base.group_user |
Security Rule Example:
User permissions:
- User A: Access to Company USA and Company Europe
- User B: Access to Company Asia only
Partner Data:
- Partner 1: Company USA
- Partner 2: Company Europe
- Partner 3: Company Asia
Visible Records:
- User A sees: Partner 1 Partner 2 (USA and Europe)
- User B sees: Partner 3 only (Asia)
Implementation Best Practices
Always Use check_company on Relational Fields:
Why:
- Prevents accidental cross-company data mixing
- Automatic validation reduces manual checking code
- Catches errors at creation preventing downstream issues
warehouse_id = fields.Many2one(
'stock.warehouse',
check_company=True # Always include for multi-company fields
)Set _check_company_auto for Models with company_id:
class MyModel(models.Model):
_name = 'my.model'
_check_company_auto = True # Enable automatic validation
company_id = fields.Many2one('res.company', required=True)Enables automatic company consistency checking across all relational fields marked with check_company=True.
Use company_dependent for Shared Configuration:
When to use:
- Product costs varying by company region
- Account configurations different per legal entity
- Warehouse locations company-specific
- Payment terms varying by subsidiary
property_account_receivable_id = fields.Many2one(
'account.account',
company_dependent=True
)Common Pitfalls to Avoid
Forgetting Default Company on Required Fields:
Problem: company_id required but no default value. Single-company users cant see field cant create records.
Solution: Always set default=lambda self: self.env.company on required company fields.
Not Using check_company on Related Fields:
Problem: References to partners products accounts from different companies creating data inconsistencies.
Solution: Add check_company=True to all Many2one fields referencing company-specific records.
Accessing Company-Dependent Fields Without Context:
Problem: Reading company_dependent field returns wrong company value.
Solution: Use with_company() method specifying target company before accessing field.
Conclusion
Odoo 18 Multi-Company Setup enables enterprise-scale operations through company-dependent fields multi-company consistency validation default company assignment security rules domain isolation automatic checks context switching relational validation required fields and permission management. Reduce data isolation errors through automatic validation preventing compliance violations via access restrictions enabling shared resource management through company-specific configurations supporting intercompany transactions controlled workflows achieving enterprise scalability regulatory compliance operational efficiency through systematic multi-company architecture designing proper field definitions implementing security rules maintaining data consistency across legal entities supporting global expansion through centralized system and achieving cost efficiency through shared infrastructure eliminating duplicate systems.
