Інструкції для мульти-компаній¶
Попередження
Цей посібник вимагає хороших знань Odoo. Будь ласка, спершу зверніться до базового підручника, якщо потрібно.
Починаючи з версії 13.0, користувач може входити в декілька компаній одночасно. Це дозволяє користувачеві отримувати доступ до інформації з кількох компаній, а також створювати/редагувати записи в середовищі кількох компаній.
Якщо не поводитися належним чином, це може бути джерелом багатьох непослідовних дій кількох компаній. Наприклад, користувач, який увійшов у систему обох компаній A і B, може створити замовлення на продаж у компанії A та додати до нього продукти, що належать компанії B. Лише коли користувач вийде з компанії B, для замовлення клієнта виникнуть помилки доступу.
Щоб правильно керувати поведінкою кількох компаній, ORM Odoo надає кілька функцій:
Залежні від компанії поля¶
Коли запис доступний від кількох компаній, ми маємо очікувати, що певному полю будуть призначені різні значення залежно від компанії, від якої встановлено значення.
Щоб поле одного запису підтримувало кілька значень, воно має бути визначено за допомогою атрибута company_dependent
зі значенням True
.
from odoo import api, fields, models
class Record(models.Model):
_name = 'record.public'
info = fields.Text()
company_info = fields.Text(company_dependent=True)
display_info = fields.Text(string='Infos', compute='_compute_display_info')
@api.depends_context('company')
def _compute_display_info(self):
for record in self:
record.display_info = record.info + record.company_info
Примітка
Метод _compute_display_info
прикрашено depends_context('company')
(див. depends_context
), щоб забезпечити переобчислення обчисленого поля залежно від поточної компанії (self.env.company
).
Коли зчитується залежне від компанії поле, поточна компанія використовується для отримання її значення. Іншими словами, якщо користувач увійшов у компанії A та B, де A є основною компанією, і створює запис для компанії B, значення полів, залежних від компанії, будуть відповідати полям компанії A.
Щоб прочитати значення полів, що залежать від компанії, встановлені іншою компанією, ніж поточна, нам потрібно переконатися, що компанія, яку ми використовуємо, правильна. Це можна зробити за допомогою with_company()
, який оновлює поточну компанію.
# Accessed as main company (self.env.company)
val = record.company_dependent_field
# Accessed as desired company (company_B)
val = record.with_company(company_B).company_dependent_field
# record.with_company(company_B).env.company == company_B
Попередження
Щоразу, коли ви обчислюєте/створюєте/… речі, які можуть поводитися по-різному в різних компаніях, ви повинні переконатися, що все, що ви робите, робиться в правильній компанії. Завжди використовувати with_company
, щоб уникнути проблем у подальшому, не потрібно багато коштувати.
@api.onchange('field_name')
def _onchange_field_name(self):
self = self.with_company(self.company_id)
...
@api.depends('field_2')
def _compute_field_3(self):
for record in self:
record = record.with_company(record.company_id)
...
Відповідність мульти-компаній¶
Якщо за допомогою поля company_id
запис доступний для спільного використання між декількома компаніями, ми повинні подбати про те, щоб його не можна було пов’язати із записом іншої компанії через реляційне поле. Наприклад, ми не хочемо, щоб замовлення клієнта та його рахунок належали різним компаніям.
Щоб забезпечити узгодженість між мульти-компаніями, ви повинні:
Встановіть для атрибута класу
_check_company_auto
значенняTrue
.Визначте реляційні поля з атрибутом
check_company
, встановленим наTrue
, якщо їхня модель має полеcompany_id
.
Для кожного create()
і write()
запускатимуться автоматичні перевірки, щоб забезпечити узгодженість запису для кількох компаній.
from odoo import fields, models
class Record(models.Model):
_name = 'record.shareable'
_check_company_auto = True
company_id = fields.Many2one('res.company')
other_record_id = fields.Many2one('other.record', check_company=True)
Примітка
Поле company_id
не можна визначати за допомогою check_company=True
.
- Model._check_company(fnames=None)[source]¶
Перевірте компанії значень наведених імен полів.
- Параметри
fnames (list) – назви реляційних полів для перевірки
- Викликає
UserError – якщо
company_id
значення будь-якого поля не входить до[False, self.company_id]
(абоself
, якщоres_company
).
Для реляційних полів
res_users перевіряє, що звукозаписна компанія є в полях `company_ids
.Користувача з основною компанією A, який має доступ до компаній A і B, можна призначити або пов’язати із записами в компанії B.
Попередження
Функція check_company
виконує сувору перевірку! Це означає, що якщо запис не має company_id
(тобто поле не є обов’язковим), його не можна пов’язати із записом, для якого встановлено company_id
.
Примітка
Якщо в полі не визначено домен і check_company
має значення True
, додається домен за умовчанням: ['|', '('company_id', '=', False), ('company_id', ' =', company_id)]
Компанія за замовчуванням¶
Якщо поле company_id
є обов’язковим у моделі, рекомендовано встановити компанію за умовчанням. Це полегшує процес налаштування для користувача або навіть гарантує його дійсність, коли компанія прихована від очей. Дійсно, компанія зазвичай прихована, якщо користувач не має доступу до кількох компаній (тобто, коли користувач не має групи base.group_multi_company
).
from odoo import api, fields, models
class Record(models.Model):
_name = 'record.restricted'
_check_company_auto = True
company_id = fields.Many2one(
'res.company', required=True, default=lambda self: self.env.company
)
other_record_id = fields.Many2one('other.record', check_company=True)
Представлення¶
Як зазначено в вище, компанія зазвичай прихована від очей, якщо користувач не має доступу до кількох компаній. Це перевірено за допомогою групи base.group_multi_company
.
<record model="ir.ui.view" id="record_form_view">
<field name="name">record.restricted.form</field>
<field name="model">record.restricted</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<group>
<field name="company_id" groups="base.group_multi_company"/>
<field name="other_record_id"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
Правила безпеки¶
Працюючи із записами, які спільно використовуються між компаніями або обмежено однією компанією, ми повинні подбати про те, щоб користувач не мав доступу до записів, що належать іншим компаніям.
Це досягається за допомогою правил безпеки на основі company_ids
, який містить поточні компанії користувача (компанії, які користувач позначив у віджеті кількох компаній).
<!-- Shareable Records -->
<record model="ir.rule" id="record_shared_company_rule">
<field name="name">Shared Record: multi-company</field>
<field name="model_id" ref="model_record_shared"/>
<field name="global" eval="True"/>
<field name="domain_force">
['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]
</field>
</record>
<!-- Company-restricted Records -->
<record model="ir.rule" id="record_restricted_company_rule">
<field name="name">Restricted Record: multi-company</field>
<field name="model_id" ref="model_record_restricted"/>
<field name="global" eval="True"/>
<field name="domain_force">
[('company_id', 'in', company_ids)]
</field>
</record>