Browse Source

[ADD] base_user_role_company: add per company user roles

14.0
Chandresh Thakkar OSI 4 years ago
committed by Daniel Reis
parent
commit
0051dd00e9
  1. 4
      base_user_role_company/__init__.py
  2. 19
      base_user_role_company/__manifest__.py
  3. 5
      base_user_role_company/models/__init__.py
  4. 23
      base_user_role_company/models/ir_http.py
  5. 65
      base_user_role_company/models/role.py
  6. 6
      base_user_role_company/readme/CONFIGURE.rst
  7. 4
      base_user_role_company/readme/CONTRIBUTORS.rst
  8. 9
      base_user_role_company/readme/DESCRIPTION.rst
  9. 17
      base_user_role_company/readme/USAGE.rst
  10. 1
      base_user_role_company/tests/__init__.py
  11. 62
      base_user_role_company/tests/test_role_per_company.py
  12. 14
      base_user_role_company/views/role.xml
  13. 1
      setup/base_user_role_company/odoo/addons/base_user_role_company
  14. 6
      setup/base_user_role_company/setup.py

4
base_user_role_company/__init__.py

@ -0,0 +1,4 @@
# Copyright (C) 2021 Open Source Integrators
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import models

19
base_user_role_company/__manifest__.py

@ -0,0 +1,19 @@
# Copyright (C) 2021 Open Source Integrators
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "User roles by company",
"version": "14.0.1.0.0",
"category": "Tools",
"author": "Open Source Integrators, Odoo Community Association (OCA)",
"license": "AGPL-3",
"website": "https://github.com/OCA/server-backend",
"depends": ["base_user_role"],
"data": [
"views/role.xml",
],
"installable": True,
"auto_install": True,
"maintainer": "dreispt",
"development_status": "Beta",
}

5
base_user_role_company/models/__init__.py

@ -0,0 +1,5 @@
# Copyright (C) 2021 Open Source Integrators
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import role
from . import ir_http

23
base_user_role_company/models/ir_http.py

@ -0,0 +1,23 @@
# Copyright (C) 2021 Open Source Integrators
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models
from odoo.http import request
class IrHttp(models.AbstractModel):
_inherit = "ir.http"
def session_info(self):
"""
Based on the selected companies (cids),
calculate the roles to enable.
A role should be enabled only when it applies to all selected companies.
"""
result = super(IrHttp, self).session_info()
if self.env.user.role_line_ids:
cids_str = request.httprequest.cookies.get("cids", str(self.env.company.id))
cids = [int(cid) for cid in cids_str.split(",")]
self.env.user._set_session_active_roles(cids)
self.env.user.set_groups_from_roles()
return result

65
base_user_role_company/models/role.py

@ -0,0 +1,65 @@
# Copyright (C) 2021 Open Source Integrators
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class ResUsersRoleLine(models.Model):
_inherit = "res.users.role.line"
company_id = fields.Many2one(
"res.company",
"Company",
help="If set, this role only applies when this is the main company selected."
" Otherwise it applies to all companies.",
)
active_role = fields.Boolean(string="Active Role", default=True)
@api.constrains("user_id", "company_id")
def _check_company(self):
for record in self:
if (
record.company_id
and record.company_id != record.user_id.company_id
and record.company_id not in record.user_id.company_ids
):
raise ValidationError(
_('User "{}" does not have access to the company "{}"').format(
record.user_id.name, record.company_id.name
)
)
_sql_constraints = [
(
"user_role_uniq",
"unique (user_id,role_id,company_id)",
"Roles can be assigned to a user only once at a time",
)
]
class ResUsers(models.Model):
_inherit = "res.users"
def _get_enabled_roles(self):
res = super()._get_enabled_roles()
return res.filtered("active_role")
@api.model
def _set_session_active_roles(self, cids):
"""
Based on the selected companies (cids),
calculate the roles to enable.
A role should be enabled only when it applies to all selected companies.
"""
for role_line in self.env.user.role_line_ids:
if not role_line.company_id:
role_line.active_role = True
elif role_line.company_id.id in cids:
is_on_companies = self.env.user.role_line_ids.filtered(
lambda x: x.role_id == role_line.role_id and x.company_id.id in cids
)
role_line.active_role = len(is_on_companies) == len(cids)
else:
role_line.active_role = False

6
base_user_role_company/readme/CONFIGURE.rst

@ -0,0 +1,6 @@
Roles are set on the User form.
The "Company" additional column allows to set a Role as only valid for specific companies.
There is also a "Active Role" techincal field, only visible in developer mode.
It shows what roles are active, after applying the company selection rules.

4
base_user_role_company/readme/CONTRIBUTORS.rst

@ -0,0 +1,4 @@
`Open Source Integrators <http://opensourceintegrators.com>`_
* Daniel Reis <dreis@opensourceintegrators.com>
* Chandresh Thakkar <cthakkr@opensourceintegrators.com>

9
base_user_role_company/readme/DESCRIPTION.rst

@ -0,0 +1,9 @@
Enable User Roles depending on the Companies selected.
A company specific Role will only be enabled
if it is set for **all** the currently selected companies.
For example, if a user is "Sales Manager" only for Company A,
it will see that role enabled only if Company A is selected.
If the user selects Company A and Company B,
then the "Sales Manager" role won't be enabled.

17
base_user_role_company/readme/USAGE.rst

@ -0,0 +1,17 @@
Select the active companies from the web client widget, near the top right corner.
When doing so, the User's security Groups are recomputed, based on the Roles.
When the user changes the company selection, only the groups available to all active companies will be activated.
For example:
* A "SALES PERSON" and a "SALES MANAGER" roles are created.
* A user is assigned to the roles:
* "SALES PERSON", with no specific company assigned (meaning all)
* "SALES MANAGER" only to "My Company (Chicago)"
* When selecting active companies from the UI widget:
* If only "My Company (San Francisco)" is active, "SALES PERSON" will be active.
* If only "My Company (Chicago)" is active, "SALES PERSON" and "SALES MANAGER" will be active.
* If both "My Company (San Francisco)" and "My Company (Chicago)" is active, "SALES PERSON" will be active.

1
base_user_role_company/tests/__init__.py

@ -0,0 +1 @@
from . import test_role_per_company

62
base_user_role_company/tests/test_role_per_company.py

@ -0,0 +1,62 @@
# Copyright 2021 Open Source Integrators
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
from odoo.tests.common import TransactionCase
class TestUserRoleCompany(TransactionCase):
def setUp(self):
super().setUp()
# COMPANIES
self.Company = self.env["res.company"]
self.company1 = self.env.ref("base.main_company")
self.company2 = self.Company.create({"name": "company2"})
# ROLES
self.Role = self.env["res.users.role"]
self.roleA = self.Role.create({"name": "ROLE All Companies"})
self.roleB = self.Role.create({"name": "ROLE Company 1"})
self.roleC = self.Role.create({"name": "ROLE Company 1 and 2"})
# USER
# ==Role=== ==Company== C1 C2 C1+C2
# Role A Yes Yes Yes
# Role B Company1 Yes
# Role C Company1 Yes Yes
# Role C Company2 Yes Yes
self.User = self.env["res.users"]
user_vals = {
"name": "ROLES TEST USER",
"login": "test_user",
"company_ids": [(6, 0, [self.company1.id, self.company2.id])],
"role_line_ids": [
(0, 0, {"role_id": self.roleA.id}),
(0, 0, {"role_id": self.roleB.id, "company_id": self.company1.id}),
(0, 0, {"role_id": self.roleC.id, "company_id": self.company1.id}),
(0, 0, {"role_id": self.roleC.id, "company_id": self.company2.id}),
],
}
self.test_user = self.User.create(user_vals)
self.User = self.User.with_user(self.test_user)
def test_110_company_1(self):
"Company 1 selected: Tech and Settings roles are activated"
self.User._set_session_active_roles([self.company1.id])
active_roles = self.test_user.role_line_ids.filtered("active_role").mapped(
"role_id"
)
self.assertEqual(active_roles, self.roleA | self.roleB | self.roleC)
def test_120_company_2(self):
"Company 2 selected: only Tech role enabled"
self.User._set_session_active_roles([self.company2.id])
active_roles = self.test_user.role_line_ids.filtered("active_role").mapped(
"role_id"
)
self.assertEqual(active_roles, self.roleA | self.roleC)
def test_130_company_1_2(self):
"Settings Role enabled for Company 1 and 2"
self.User._set_session_active_roles([self.company1.id, self.company2.id])
active_roles = self.test_user.role_line_ids.filtered("active_role").mapped(
"role_id"
)
self.assertEqual(active_roles, self.roleA | self.roleC)

14
base_user_role_company/views/role.xml

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_res_users_form_inherit_company" model="ir.ui.view">
<field name="name">res.users.form.inherit.company</field>
<field name="model">res.users</field>
<field name="inherit_id" ref="base_user_role.view_res_users_form_inherit" />
<field name="arch" type="xml">
<field name="role_id" position="after">
<field name="company_id" groups="base.group_multi_company" />
<field name="active_role" groups="base.group_no_one" readonly="1" />
</field>
</field>
</record>
</odoo>

1
setup/base_user_role_company/odoo/addons/base_user_role_company

@ -0,0 +1 @@
../../../../base_user_role_company

6
setup/base_user_role_company/setup.py

@ -0,0 +1,6 @@
import setuptools
setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
Loading…
Cancel
Save