One of the key features in Odoo is multi-company flexibility. When we customize modules we should make sure that it will fit the multi-company setup. In order to handle odoo multi-company features, Odoo ORM provides different features.let’s have a look.
First, we are going to discuss some of the field attributes, class attributes, security rules that we used to configure multiple companies.
class BlogDemo(models.Model):
_name = ‘blog.demo
company_id = fields.Many2one('res.company', string='Company', default=lambda self: self.env.company)
We should define a company field which is the basic thing that we should add while defining a model. We can make our record made shareable between several companies by defining a company field.setting up a default value for the company is a good practice.for that we can use different methods.
company_dependent
In many cases, there will be some fields whose value will be different for different companies so in order to handle that we have a special attribute called company_dependent.it can have two values True and False. if it is set to True if the particular field will be having different values based on the company.
company_dependent_value_ex = fields.Char(company_dependent=True)
The company dependent fields are not stored in the model's table. it is stored under `ir.property`. when the want to fetch the value of company dependent field an ‘ir.property’ is searched return the value linked to the current company.
If we changed the value of a field it modifies either existing property for the current record if it doesn't exist it will create a new one for the current company.
force_company
In order to read company dependent field values, we use this attribute. In this, we are trying to read the value of the field as the company Company Test.
record.with_context(force_company=Company Test.id).company_dependent_field
Check_company
When we make our records shareable between companies there may be a chance to link one company record to another. In order to handle that odoo provides two attributes.
BlogDemo(models.Model):
_name = ‘blog.demo’
_check_company_auto = True
Relational_field1 = fields.Many2one('other.relation model’, check_company=True)
We have to set the class attribute _check_company_auto to True on a model it will ensure ‘_check_company’ is called on creating and write methods enforcing the multi-company domain.
The field attribute ‘check_company=True’ will set a default domain ['|', '('company_id', '=', False), ('company_id', '=', company_id)] if no domain is defined on the relational field and also allows you to call _check_company on the records to ensure the domain is respected.
Views
If the user does not have access to multiple companies usually the company field is hidden from view. This is achieved by adding groups="base.group_multi_company" in our view
<field name="company_id" groups="base.group_multi_company"/>
Security rules
When we use multi-company set up we should make sure that the user in one company did not have access to the records in another company. For that, we should write security rules. We are adding the domain to the company_id field.
If the record is shareable by all companies we can have a rule like this
<record model="ir.rule" id="record_shared_multi_company_rule">
<field name="name">Shared Records:model</field>
<field name="model_id" ref="module.model_model"/>
<field name="global" eval="True"/>
<field name="domain_force">
['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]
</field>
</record>
company_ids contains current companies of the user
If the record is restricted to one company
<record model="ir.rule" id="record_not_shared_multi_company_rule">
<field name="name">Non Shared Records:model</field>
<field name="model_id" ref="module.model_model"/>
<field name="global" eval="True"/>
<field name="domain_force">
[('company_id', 'in', company_ids)]
</field>
</record>