mirror of
https://github.com/OCA/server-backend.git
synced 2025-02-18 09:52:42 +02:00
[ADD][12.0] base_user_role_profile: Add to 12.0
fixup! Logic and permissions fixes, new demo module, changes JS-side that reloads in a cleaner way on profile change fixup! removed unused imports, beautified JS fixup! Test coverage increase [FIX] Use write instead of assignment operator on create function: assignment on multiple records raises error fixup! Removed leftover copyright Apply suggestions from code review Co-Authored-By: David Beal <david.beal@akretion.com>
This commit is contained in:
4
base_user_role_profile/models/__init__.py
Normal file
4
base_user_role_profile/models/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
from . import profile
|
||||
from . import user
|
||||
from . import role
|
||||
from . import ir_http
|
||||
26
base_user_role_profile/models/ir_http.py
Normal file
26
base_user_role_profile/models/ir_http.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import models
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class Http(models.AbstractModel):
|
||||
_inherit = "ir.http"
|
||||
|
||||
def session_info(self): # pragma: no cover
|
||||
result = super().session_info()
|
||||
user = request.env.user
|
||||
allowed_profiles = [
|
||||
(profile.id, profile.name) for profile in user.profile_ids
|
||||
]
|
||||
if len(allowed_profiles) > 1:
|
||||
current_profile = (user.profile_id.id, user.profile_id.name)
|
||||
result["user_profiles"] = {
|
||||
"current_profile": current_profile,
|
||||
"allowed_profiles": allowed_profiles,
|
||||
}
|
||||
else:
|
||||
result["user_profiles"] = False
|
||||
result["profile_id"] = (
|
||||
user.profile_id.id if request.session.uid else None
|
||||
)
|
||||
return result
|
||||
19
base_user_role_profile/models/profile.py
Normal file
19
base_user_role_profile/models/profile.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResUsersProfile(models.Model):
|
||||
_name = "res.users.profile"
|
||||
_description = "Role profile"
|
||||
|
||||
name = fields.Char("Name")
|
||||
user_ids = fields.Many2many(
|
||||
"res.users", string="Allowed users", compute="_compute_user_ids"
|
||||
)
|
||||
role_ids = fields.One2many("res.users.role", "profile_id", string="Roles")
|
||||
|
||||
def _compute_user_ids(self):
|
||||
for rec in self:
|
||||
rec.user_ids = self.env["res.users"].search(
|
||||
[("profile_ids", "in", rec.ids)]
|
||||
)
|
||||
14
base_user_role_profile/models/role.py
Normal file
14
base_user_role_profile/models/role.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class ResUsersRole(models.Model):
|
||||
_inherit = "res.users.role"
|
||||
|
||||
profile_id = fields.Many2one("res.users.profile", "Profile",)
|
||||
|
||||
|
||||
class ResUsersRoleLine(models.Model):
|
||||
_inherit = "res.users.role.line"
|
||||
|
||||
profile_id = fields.Many2one(related="role_id.profile_id")
|
||||
81
base_user_role_profile/models/user.py
Normal file
81
base_user_role_profile/models/user.py
Normal file
@@ -0,0 +1,81 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class ResUsers(models.Model):
|
||||
_inherit = "res.users"
|
||||
|
||||
def _get_default_profile(self):
|
||||
return self.env.ref("base_user_role_profile.default_profile")
|
||||
|
||||
profile_id = fields.Many2one(
|
||||
"res.users.profile",
|
||||
"Current profile",
|
||||
default=lambda self: self._get_default_profile,
|
||||
)
|
||||
|
||||
profile_ids = fields.Many2many(
|
||||
"res.users.profile", string="Currently allowed profiles",
|
||||
)
|
||||
|
||||
def _get_action_root_menu(self):
|
||||
# used JS-side. Reload the client; open the first available root menu
|
||||
menu = self.env["ir.ui.menu"].search([("parent_id", "=", False)])[:1]
|
||||
return {
|
||||
"type": "ir.actions.client",
|
||||
"tag": "reload",
|
||||
"params": {"menu_id": menu.id},
|
||||
}
|
||||
|
||||
def action_profile_change(self, vals):
|
||||
self.write(vals)
|
||||
return self._get_action_root_menu()
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
new_record = super().create(vals)
|
||||
if vals.get("company_id") or vals.get("role_line_ids"):
|
||||
new_record.sudo()._compute_profile_ids()
|
||||
return new_record
|
||||
|
||||
def write(self, vals):
|
||||
# inspired by base/models/res_users.py l. 491
|
||||
if self == self.env.user and vals.get("profile_id"):
|
||||
self.sudo().write({"profile_id": vals["profile_id"]})
|
||||
del vals["profile_id"]
|
||||
res = super().write(vals)
|
||||
if (
|
||||
vals.get("company_id")
|
||||
or vals.get("profile_id")
|
||||
or vals.get("role_line_ids")
|
||||
):
|
||||
self.sudo()._compute_profile_ids()
|
||||
return res
|
||||
|
||||
def _get_applicable_roles(self):
|
||||
res = super()._get_applicable_roles()
|
||||
res = res.filtered(
|
||||
lambda r: not r.profile_id
|
||||
or (r.profile_id.id == r.user_id.profile_id.id)
|
||||
)
|
||||
return res
|
||||
|
||||
def _update_profile_id(self):
|
||||
default_profile = self.env.ref(
|
||||
"base_user_role_profile.default_profile"
|
||||
)
|
||||
if not self.profile_ids:
|
||||
if self.profile_id != default_profile:
|
||||
self.profile_id = default_profile
|
||||
elif self.profile_id not in self.profile_ids:
|
||||
self.write({"profile_id": self.profile_ids[0].id})
|
||||
|
||||
def _compute_profile_ids(self):
|
||||
for rec in self:
|
||||
role_lines = rec.role_line_ids
|
||||
profiles = role_lines.filtered(
|
||||
lambda r: r.company_id == rec.company_id
|
||||
).mapped("profile_id")
|
||||
rec.profile_ids = profiles
|
||||
# set defaults in case applicable profile changes
|
||||
rec._update_profile_id()
|
||||
Reference in New Issue
Block a user