Skip to content

Commit 3f89576

Browse files
committed
[ADD][14.0] base_user_role_description
1 parent 3c5dc35 commit 3f89576

File tree

17 files changed

+1130
-0
lines changed

17 files changed

+1130
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
==========================
2+
Base User Role Description
3+
==========================
4+
5+
..
6+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7+
!! This file is generated by oca-gen-addon-readme !!
8+
!! changes will be overwritten. !!
9+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10+
!! source digest: sha256:93964ac49660d481575adb1bd0fafeae9d8ef78ce12d03c4e38e5ff89a7e55ea
11+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12+
13+
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
14+
:target: https://odoo-community.org/page/development-status
15+
:alt: Beta
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
17+
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
18+
:alt: License: AGPL-3
19+
.. |badge3| image:: https://img.shields.io/badge/github-akretion%2Fak--odoo--incubator-lightgray.png?logo=github
20+
:target: https://github.com/akretion/ak-odoo-incubator/tree/14.0/base_user_role_description
21+
:alt: akretion/ak-odoo-incubator
22+
23+
|badge1| |badge2| |badge3|
24+
25+
This module generates a concise HTML description of a user’s role, summarizing the main model access rights and the accessible menus. It aggregates permissions per model kind, presenting them in readable tables.
26+
The descriptions are on role and user views.
27+
28+
**Table of contents**
29+
30+
.. contents::
31+
:local:
32+
33+
Bug Tracker
34+
===========
35+
36+
Bugs are tracked on `GitHub Issues <https://github.com/akretion/ak-odoo-incubator/issues>`_.
37+
In case of trouble, please check there if your issue has already been reported.
38+
If you spotted it first, help us to smash it by providing a detailed and welcomed
39+
`feedback <https://github.com/akretion/ak-odoo-incubator/issues/new?body=module:%20base_user_role_description%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
40+
41+
Do not contact contributors directly about support or help with technical issues.
42+
43+
Credits
44+
=======
45+
46+
Authors
47+
~~~~~~~
48+
49+
* Akretion
50+
51+
Contributors
52+
~~~~~~~~~~~~
53+
54+
* Kévin Roche <kevin.roche@akretion.com>
55+
56+
Maintainers
57+
~~~~~~~~~~~
58+
59+
.. |maintainer-Kev-Roche| image:: https://github.com/Kev-Roche.png?size=40px
60+
:target: https://github.com/Kev-Roche
61+
:alt: Kev-Roche
62+
63+
Current maintainer:
64+
65+
|maintainer-Kev-Roche|
66+
67+
This module is part of the `akretion/ak-odoo-incubator <https://github.com/akretion/ak-odoo-incubator/tree/14.0/base_user_role_description>`_ project on GitHub.
68+
69+
You are welcome to contribute.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import models
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright 2025 Akretion (https://www.akretion.com).
2+
# @author Kévin Roche <kevin.roche@akretion.com>
3+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
4+
5+
{
6+
"name": "Base User Role Description",
7+
"summary": "Add short description to user roles by accesses and menus",
8+
"version": "14.0.1.0.0",
9+
"category": "tools",
10+
"website": "https://github.com/akretion/ak-odoo-incubator",
11+
"author": "Akretion, Odoo Community Association (OCA)",
12+
"license": "AGPL-3",
13+
"maintainers": ["Kev-Roche"],
14+
"application": False,
15+
"installable": True,
16+
"depends": [
17+
"base_user_role",
18+
],
19+
"data": [
20+
"views/res_users.xml",
21+
"views/res_users_role.xml",
22+
"data/cron.xml",
23+
],
24+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<!-- Copyright (C) 2026 Akretion (<http://www.akretion.com>).
3+
@author Kévin Roche <kevin.roche@akretion.com>
4+
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
5+
<odoo noupdate="1">
6+
<record id="ir_cron_update_model_for_role_description" model="ir.cron">
7+
<field name="name">Update Models for Role Description</field>
8+
<field name="model_id" ref="base.model_ir_model" />
9+
<field name="state">code</field>
10+
<field name="code">model._cron_update_model_for_role_descr()</field>
11+
<field name="interval_number">1</field>
12+
<field name="interval_type">days</field>
13+
<field name="numbercall">-1</field>
14+
</record>
15+
16+
</odoo>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from . import ir_model
2+
from . import res_users_role_description
3+
from . import res_users
4+
from . import res_users_role
5+
from . import ir_model_access
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# Copyright 2025 Akretion (https://www.akretion.com).
2+
# @author Kévin Roche <kevin.roche@akretion.com>
3+
4+
from odoo import fields, models
5+
6+
MAPPING_KIND_MODELS = {
7+
"Article": [
8+
"product.product",
9+
"product.template",
10+
"product.categorie",
11+
"product.attribute",
12+
"product.attribute.value",
13+
"uom.uom",
14+
"hs.code",
15+
"product.packaging.type",
16+
"product.packaging",
17+
],
18+
"Vente": [
19+
"sale.order",
20+
"product.pricelist",
21+
"product.pricelist.item",
22+
"crm.team",
23+
"delivery.carrier",
24+
],
25+
"Achat": [
26+
"purchase.order",
27+
"product.supplierinfo",
28+
],
29+
"Logistique": [
30+
"stock.picking",
31+
"stock.picking.type",
32+
"stock.quant",
33+
"stock.location",
34+
"stock.warehouse",
35+
"stock.lot",
36+
"stock.route",
37+
"stock.warehouse.orderpoint",
38+
"stock.putaway.rule",
39+
"stock.inventory",
40+
"stock.inventory.line",
41+
],
42+
"Production": [
43+
"mrp.bom",
44+
"mrp.production",
45+
"mrp.workorder",
46+
],
47+
"Comptabilité": [
48+
"account.account",
49+
"account.tax",
50+
"account.journal",
51+
"account.product.fiscal.classification",
52+
"account.fiscal.position",
53+
],
54+
"Immobilisation": [
55+
"account.asset",
56+
"account.asset.profile",
57+
"account.asset.category",
58+
],
59+
"Facturation": [
60+
"account.move",
61+
"account.payment",
62+
"account.account.type",
63+
"account.payment.term",
64+
"account.incoterms",
65+
],
66+
"Banque": [
67+
"account.reconcile.model",
68+
"account.bank.statement",
69+
"res.partner.bank",
70+
"res.bank",
71+
"online.bank.statement.provider",
72+
],
73+
"Projet": [
74+
"project.project",
75+
"project.task",
76+
],
77+
"Contact": [
78+
"res.partner",
79+
"res.country",
80+
"res.company",
81+
],
82+
"Calendrier": [
83+
"calendar.event",
84+
"resource.calendar",
85+
],
86+
"Support": [
87+
"helpdesk.ticket",
88+
],
89+
"Utilisateur": [
90+
"res.users",
91+
],
92+
"Sécurité": [
93+
"ir.model.access",
94+
"ir.rule",
95+
"res.groups",
96+
"res.users.role",
97+
],
98+
"CRM": [
99+
"crm.lead",
100+
"crm.stage",
101+
],
102+
"Employé": [
103+
"hr.employee",
104+
"hr.contract",
105+
"hr.leave",
106+
],
107+
"Point de vente": [
108+
"pos.order",
109+
"pos.session",
110+
"pos.config",
111+
],
112+
"File d'attente des travaux": [
113+
"queue.job",
114+
"attachment.queue",
115+
"queue.job.channel",
116+
],
117+
"Technique": [
118+
"ir.module.module",
119+
],
120+
"documents": [
121+
"dms.file",
122+
"dms.directory",
123+
],
124+
"Maintenance": [
125+
"maintenance.equipment",
126+
"maintenance.equipment.network",
127+
"maintenance.team",
128+
],
129+
}
130+
131+
132+
class IrModel(models.Model):
133+
_inherit = "ir.model"
134+
135+
model_for_role_descr = fields.Boolean(
136+
string="Model for Role Description",
137+
compute="_compute_for_role_descr",
138+
store=True,
139+
)
140+
141+
def get_mapping_kind_models(self):
142+
return MAPPING_KIND_MODELS
143+
144+
def get_kinds_for_role_descr(self):
145+
return [
146+
(kind, kind.capitalize()) for kind in self.get_mapping_kind_models().keys()
147+
] + [("other", "Other")]
148+
149+
kind_for_role_descr = fields.Selection(
150+
selection=get_kinds_for_role_descr,
151+
string="Kind for Role Description",
152+
compute="_compute_for_role_descr",
153+
store=True,
154+
)
155+
156+
def _compute_for_role_descr(self):
157+
mapping = self.get_mapping_kind_models()
158+
for rec in self:
159+
rec.kind_for_role_descr = "other"
160+
for kind, models in mapping.items():
161+
if rec.model in models:
162+
rec.kind_for_role_descr = kind
163+
rec.model_for_role_descr = True
164+
break
165+
166+
def _cron_update_model_for_role_descr(self):
167+
self.search([])._compute_for_role_descr()
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Copyright 2026 Akretion (https://www.akretion.com).
2+
# @author Kévin Roche <kevin.roche@akretion.com>
3+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
4+
5+
from odoo import api, fields, models
6+
7+
8+
class IrModelAccess(models.Model):
9+
_inherit = "ir.model.access"
10+
11+
access_type = fields.Selection(
12+
selection=[
13+
("no_access", "No Access"),
14+
("read", "Read Only"),
15+
("write", "Read and Write"),
16+
("create", "Read, Write and Create"),
17+
("full", "Full Access"),
18+
("other", "Other Combination of access rights"),
19+
],
20+
string="Access Type",
21+
compute="_compute_access_type",
22+
store=True,
23+
)
24+
25+
@api.depends("perm_read", "perm_write", "perm_create", "perm_unlink")
26+
def _compute_access_type(self):
27+
for rec in self:
28+
if (
29+
not rec.perm_read
30+
and not rec.perm_write
31+
and not rec.perm_create
32+
and not rec.perm_unlink
33+
):
34+
rec.access_type = "no_access"
35+
elif (
36+
rec.perm_read
37+
and not rec.perm_write
38+
and not rec.perm_create
39+
and not rec.perm_unlink
40+
):
41+
rec.access_type = "read"
42+
elif (
43+
rec.perm_read
44+
and rec.perm_write
45+
and not rec.perm_create
46+
and not rec.perm_unlink
47+
):
48+
rec.access_type = "write"
49+
elif (
50+
rec.perm_read
51+
and rec.perm_write
52+
and rec.perm_create
53+
and not rec.perm_unlink
54+
):
55+
rec.access_type = "create"
56+
elif (
57+
rec.perm_read and rec.perm_write and rec.perm_create and rec.perm_unlink
58+
):
59+
rec.access_type = "full"
60+
else:
61+
rec.access_type = "other"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright 2026 Akretion (https://www.akretion.com).
2+
# @author Kévin Roche <kevin.roche@akretion.com>
3+
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
4+
5+
from odoo import fields, models
6+
7+
8+
class Users(models.Model):
9+
_name = "res.users"
10+
_inherit = ["res.users", "res.users.role.description"]
11+
12+
recursive_model_access_ids = fields.Many2many(
13+
comodel_name="ir.model.access",
14+
compute="_compute_model_access_ids",
15+
string="Access Rights",
16+
)
17+
18+
def _get_all_implied_groups(self):
19+
self.ensure_one()
20+
groups = self.groups_id
21+
to_process = self.groups_id
22+
23+
while to_process:
24+
groups |= to_process
25+
to_process = to_process.implied_ids - groups
26+
27+
return groups
28+
29+
def _compute_model_access_ids(self):
30+
for rec in self:
31+
rec.recursive_model_access_ids = (
32+
rec._get_all_implied_groups().model_access.ids
33+
)

0 commit comments

Comments
 (0)