diff --git a/operating_unit/__manifest__.py b/operating_unit/__manifest__.py
index 6de0b0eace..b92aab9da6 100644
--- a/operating_unit/__manifest__.py
+++ b/operating_unit/__manifest__.py
@@ -6,7 +6,7 @@
"name": "Operating Unit",
"summary": "An operating unit (OU) is an organizational entity part of a "
"company",
- "version": "16.0.1.0.2",
+ "version": "17.0.1.0.0",
"author": "ForgeFlow, "
"Serpent Consulting Services Pvt. Ltd., "
"Odoo Community Association (OCA)",
diff --git a/operating_unit/data/operating_unit_data.xml b/operating_unit/data/operating_unit_data.xml
index 27b9bb0d9b..e101b6b9d9 100644
--- a/operating_unit/data/operating_unit_data.xml
+++ b/operating_unit/data/operating_unit_data.xml
@@ -8,10 +8,16 @@
-
+
-
+
diff --git a/operating_unit/models/__init__.py b/operating_unit/models/__init__.py
index b2dcf9371c..191c9807f0 100644
--- a/operating_unit/models/__init__.py
+++ b/operating_unit/models/__init__.py
@@ -1,2 +1,3 @@
+from . import ir_rule
from . import operating_unit
from . import res_users
diff --git a/operating_unit/models/ir_rule.py b/operating_unit/models/ir_rule.py
new file mode 100644
index 0000000000..d68da2d643
--- /dev/null
+++ b/operating_unit/models/ir_rule.py
@@ -0,0 +1,20 @@
+# Copyright 2024 NSI-SA
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
+
+
+from odoo import api, models
+
+
+class IrRule(models.Model):
+ _inherit = "ir.rule"
+
+ @api.model
+ def _eval_context(self):
+ res = super()._eval_context()
+ res.update(
+ {
+ "operating_unit_ids": self.env.user.operating_units().ids,
+ "operating_unit_id": self.env.user.default_operating_unit_id.id,
+ }
+ )
+ return res
diff --git a/operating_unit/models/operating_unit.py b/operating_unit/models/operating_unit.py
index 098a4a39c9..ca29bd7906 100644
--- a/operating_unit/models/operating_unit.py
+++ b/operating_unit/models/operating_unit.py
@@ -41,22 +41,18 @@ class OperatingUnit(models.Model):
),
]
- def name_get(self):
- res = []
+ @api.depends("name", "code")
+ def _compute_display_name(self):
for ou in self:
- name = ou.name
- if ou.code:
- name = f"[{ou.code}] {name}"
- res.append((ou.id, name))
- return res
+ ou.display_name = f"[{ou.code}] {ou.name}"
@api.model_create_multi
def create(self, vals_list):
res = super().create(vals_list)
res.write({"user_ids": [fields.Command.link(self.env.user.id)]})
- self.clear_caches()
+ self.env.registry.clear_cache()
return res
def write(self, vals):
- self.clear_caches()
+ self.env.registry.clear_cache()
return super().write(vals)
diff --git a/operating_unit/models/res_users.py b/operating_unit/models/res_users.py
index cf05d19724..66d253d924 100644
--- a/operating_unit/models/res_users.py
+++ b/operating_unit/models/res_users.py
@@ -8,33 +8,6 @@
class ResUsers(models.Model):
_inherit = "res.users"
- @api.model
- def operating_unit_default_get(self, uid2=False):
- if not uid2:
- uid2 = self.env.user.id
- user = self.env["res.users"].browse(uid2)
- # check if the company of the default OU is active
- if user.default_operating_unit_id.sudo().company_id in self.env.companies:
- return user.default_operating_unit_id
- else:
- # find an OU of the main active company
- for ou in user.assigned_operating_unit_ids:
- if ou.sudo().company_id in self.env.company:
- return ou
- # find an OU of any active company
- for ou in user.assigned_operating_unit_ids:
- if ou.sudo().company_id in self.env.companies:
- return ou
- return False
-
- @api.model
- def _default_operating_unit(self):
- return self.operating_unit_default_get()
-
- @api.model
- def _default_operating_units(self):
- return self._default_operating_unit()
-
operating_unit_ids = fields.One2many(
comodel_name="operating.unit",
compute="_compute_operating_unit_ids",
@@ -49,7 +22,7 @@ def _default_operating_units(self):
column1="user_id",
column2="operating_unit_id",
string="Operating Units",
- default=lambda self: self._default_operating_units(),
+ default=lambda self: self._default_operating_unit(),
)
default_operating_unit_id = fields.Many2one(
@@ -59,36 +32,32 @@ def _default_operating_units(self):
domain="[('company_id', '=', current_company_id)]",
)
- @api.onchange("operating_unit_ids")
- def _onchange_operating_unit_ids(self):
- for record in self:
- if (
- record.default_operating_unit_id
- and record.default_operating_unit_id
- not in record.operating_unit_ids._origin
- ):
- record.default_operating_unit_id = False
+ @api.model
+ def _get_default_operating_unit(self, uid2=False):
+ if not uid2:
+ uid2 = self.env.user.id
+ user = self.env["res.users"].browse(uid2)
+ # check if the company of the default OU is active
+ if user.default_operating_unit_id.sudo().company_id in self.env.companies:
+ return user.default_operating_unit_id
+ else:
+ # find an OU of the main active company
+ for ou in user.assigned_operating_unit_ids:
+ if ou.sudo().company_id in self.env.company:
+ return ou
+ # find an OU of any active company
+ for ou in user.assigned_operating_unit_ids:
+ if ou.sudo().company_id in self.env.companies:
+ return ou
+ return False
- @api.depends("groups_id", "assigned_operating_unit_ids")
- def _compute_operating_unit_ids(self):
- for user in self:
- if user._origin.has_group("operating_unit.group_manager_operating_unit"):
- dom = []
- if self.env.context.get("allowed_company_ids"):
- dom = [
- "|",
- ("company_id", "=", False),
- ("company_id", "in", self.env.context["allowed_company_ids"]),
- ]
- else:
- dom = []
- user.operating_unit_ids = self.env["operating.unit"].sudo().search(dom)
- else:
- user.operating_unit_ids = user.assigned_operating_unit_ids
+ @api.model
+ def _default_operating_unit(self):
+ return self._get_default_operating_unit()
@api.model
def default_get(self, fields):
- vals = super(ResUsers, self).default_get(fields)
+ vals = super().default_get(fields)
if (
self.env["ir.config_parameter"]
.sudo()
@@ -102,7 +71,37 @@ def default_get(self, fields):
vals["operating_unit_ids"] = [(6, 0, default_user.operating_unit_ids.ids)]
return vals
+ @api.depends("groups_id", "assigned_operating_unit_ids")
+ def _compute_operating_unit_ids(self):
+ for user in self:
+ if user._origin.has_group("operating_unit.group_manager_operating_unit"):
+ if self.env.context.get("allowed_company_ids"):
+ dom = [
+ "|",
+ ("company_id", "=", False),
+ ("company_id", "in", self.env.context["allowed_company_ids"]),
+ ]
+ else:
+ dom = []
+
+ user.operating_unit_ids = self.env["operating.unit"].sudo().search(dom)
+ else:
+ user.operating_unit_ids = user.assigned_operating_unit_ids
+
def _inverse_operating_unit_ids(self):
for user in self:
user.assigned_operating_unit_ids = user.operating_unit_ids
- self.clear_caches()
+ self.env.registry.clear_cache()
+
+ @api.onchange("operating_unit_ids")
+ def _onchange_operating_unit_ids(self):
+ for record in self:
+ if (
+ record.default_operating_unit_id
+ and record.default_operating_unit_id
+ not in record.operating_unit_ids._origin
+ ):
+ record.default_operating_unit_id = False
+
+ def operating_units(self):
+ return self.env.user.operating_unit_ids
diff --git a/operating_unit/security/operating_unit_security.xml b/operating_unit/security/operating_unit_security.xml
index c7f2572791..4f9dcd9871 100644
--- a/operating_unit/security/operating_unit_security.xml
+++ b/operating_unit/security/operating_unit_security.xml
@@ -27,7 +27,7 @@
- [('id','in',user.operating_unit_ids.ids)]
+ [('id','in',operating_unit_ids)]
Allowed operating units
diff --git a/operating_unit/tests/__init__.py b/operating_unit/tests/__init__.py
index 8096d86683..768fdaaba1 100644
--- a/operating_unit/tests/__init__.py
+++ b/operating_unit/tests/__init__.py
@@ -1 +1,2 @@
+from . import common
from . import test_operating_unit
diff --git a/operating_unit/tests/common.py b/operating_unit/tests/common.py
new file mode 100644
index 0000000000..ed3d6f9fde
--- /dev/null
+++ b/operating_unit/tests/common.py
@@ -0,0 +1,67 @@
+# © 2017-TODAY ForgeFlow S.L.
+# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
+
+from odoo.models import Command
+from odoo.tests import common
+
+
+class OperatingUnitCommon(common.TransactionCase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.res_users_model = cls.env["res.users"].with_context(
+ tracking_disable=True, no_reset_password=True
+ )
+ # Groups
+ cls.grp_ou_mngr = cls.env.ref("operating_unit.group_manager_operating_unit")
+ cls.grp_ou_multi = cls.env.ref("operating_unit.group_multi_operating_unit")
+ # Company
+ cls.company = cls.env.ref("base.main_company")
+ cls.company_2 = cls.env["res.company"].create({"name": "Second company"})
+ # Main Operating Unit
+ cls.ou1 = cls.env.ref("operating_unit.main_operating_unit")
+ # B2C Operating Unit
+ cls.b2c = cls.env.ref("operating_unit.b2c_operating_unit")
+ # B2B Operating Unit
+ cls.b2b = cls.env.ref("operating_unit.b2b_operating_unit")
+ # Create User 1 with Main OU
+ cls.user1 = cls._create_user("user_1", cls.grp_ou_mngr, cls.company, cls.ou1)
+ # Create User 2 with B2C OU
+ cls.user2 = cls._create_user("user_2", cls.grp_ou_multi, cls.company, cls.b2c)
+ # Partner
+ cls.partner1 = cls.env.ref("base.res_partner_1")
+
+ @classmethod
+ def _create_user(cls, login, group, company, operating_units, context=None):
+ """Create a user."""
+ user = cls.res_users_model.create(
+ {
+ "name": "Test User",
+ "login": login,
+ "password": "demo",
+ "email": "test@yourcompany.com",
+ "company_id": company.id,
+ "company_ids": [(4, company.id)],
+ "operating_unit_ids": [(4, ou.id) for ou in operating_units],
+ "groups_id": [Command.link(group.id)],
+ }
+ )
+ return user
+
+ def _create_operating_unit(self, uid, name, code, company_id=None):
+ """Create Operating Unit"""
+ if company_id is None:
+ company_id = self.company
+ ou = (
+ self.env["operating.unit"]
+ .with_user(uid)
+ .create(
+ {
+ "name": name,
+ "code": code,
+ "partner_id": company_id.partner_id.id,
+ "company_id": company_id.id,
+ }
+ )
+ )
+ return ou
diff --git a/operating_unit/tests/test_operating_unit.py b/operating_unit/tests/test_operating_unit.py
index 29dcf8ade1..95d9c12577 100644
--- a/operating_unit/tests/test_operating_unit.py
+++ b/operating_unit/tests/test_operating_unit.py
@@ -2,71 +2,14 @@
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html)
from odoo.exceptions import AccessError
-from odoo.tests import common
+from odoo.tests import tagged
from odoo.tests.common import Form
+from .common import OperatingUnitCommon
-class TestOperatingUnit(common.TransactionCase):
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
- cls.res_users_model = cls.env["res.users"].with_context(
- tracking_disable=True, no_reset_password=True
- )
-
- # Groups
- cls.grp_ou_mngr = cls.env.ref("operating_unit.group_manager_operating_unit")
- cls.grp_ou_multi = cls.env.ref("operating_unit.group_multi_operating_unit")
- # Company
- cls.company = cls.env.ref("base.main_company")
- cls.company_2 = cls.env["res.company"].create({"name": "Second company"})
- # Main Operating Unit
- cls.ou1 = cls.env.ref("operating_unit.main_operating_unit")
- # B2C Operating Unit
- cls.b2c = cls.env.ref("operating_unit.b2c_operating_unit")
- # B2B Operating Unit
- cls.b2b = cls.env.ref("operating_unit.b2b_operating_unit")
- # Create User 1 with Main OU
- cls.user1 = cls._create_user("user_1", cls.grp_ou_mngr, cls.company, cls.ou1)
- # Create User 2 with B2C OU
- cls.user2 = cls._create_user("user_2", cls.grp_ou_multi, cls.company, cls.b2c)
-
- @classmethod
- def _create_user(cls, login, group, company, operating_units, context=None):
- """Create a user."""
- user = cls.res_users_model.create(
- {
- "name": "Test User",
- "login": login,
- "password": "demo",
- "email": "test@yourcompany.com",
- "company_id": company.id,
- "company_ids": [(4, company.id)],
- "operating_unit_ids": [(4, ou.id) for ou in operating_units],
- "default_operating_unit_id": False,
- "sel_groups_13_14": group.id,
- }
- )
- return user
-
- def _create_operating_unit(self, uid, name, code, company_id=None):
- """Create Operating Unit"""
- if company_id is None:
- company_id = self.company
- ou = (
- self.env["operating.unit"]
- .with_user(uid)
- .create(
- {
- "name": name,
- "code": code,
- "partner_id": company_id.partner_id.id,
- "company_id": company_id.id,
- }
- )
- )
- return ou
+@tagged("post_install", "-at_install")
+class TestOperatingUnit(OperatingUnitCommon):
def test_01_operating_unit(self):
# User 1 tries to create and modify an OU
# Create
@@ -156,17 +99,17 @@ def test_find_operating_unit_by_name_or_code(self):
def test_03_operating_unit(self):
"""
- The method operating_unit_default_get should not return
+ The method _get_default_operating_unit should not return
operating units belonging to a company that is not active
"""
self.assertEqual(
- self.res_users_model.operating_unit_default_get(uid2=self.user1.id),
+ self.res_users_model._get_default_operating_unit(uid2=self.user1.id),
self.ou1,
)
self.assertEqual(
self.res_users_model.with_company(
self.company_2
- ).operating_unit_default_get(uid2=self.user1.id),
+ )._get_default_operating_unit(uid2=self.user1.id),
False,
)
@@ -178,7 +121,7 @@ def test_03_operating_unit(self):
self.assertEqual(
self.res_users_model.with_company(
self.company_2
- ).operating_unit_default_get(uid2=self.user1.id),
+ )._get_default_operating_unit(uid2=self.user1.id),
ou_company_2,
)