Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions analytic_restrictions/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .hooks import uninstall_hook
9 changes: 8 additions & 1 deletion analytic_restrictions/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,17 @@
"license": "AGPL-3",
"author": "Escodoo",
"website": "https://github.com/Escodoo/account-addons",
"depends": ["analytic", "account_analytic_tag", "account"],
"depends": [
"analytic",
"account_analytic_tag",
"account",
"project",
"hr_timesheet",
],
"data": [
"security/analytic_security.xml",
"security/ir.model.access.csv",
],
"demo": [],
"uninstall_hook": "uninstall_hook",
}
40 changes: 40 additions & 0 deletions analytic_restrictions/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2026 - TODAY, Wesley Oliveira <wesley.oliveira@escodoo.com.br>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import SUPERUSER_ID, api

_ORIGINAL_PERMS = {
"analytic.access_account_analytic_account": (1, 1, 1, 1),
"analytic.access_account_analytic_line": (1, 1, 1, 1),
"analytic.access_account_analytic_distribution_model": (1, 1, 1, 1),
"analytic.access_account_analytic_plan": (1, 1, 1, 1),
"analytic.access_account_analytic_applicability": (1, 1, 1, 1),
"account_analytic_tag.access_account_analytic_tag_manager": (1, 1, 1, 1),
"project.access_account_analytic_line_project": (1, 1, 1, 1),
"account.access_account_analytic_accountant": (1, 1, 1, 1),
"account.access_account_analytic_plan_accountant": (1, 1, 1, 1),
"account.access_account_analytic_applicability_accountant": (1, 1, 1, 1),
"account.access_account_analytic_distribution_invoice": (1, 1, 1, 1),
"hr_timesheet.access_account_analytic_user": (1, 1, 0, 0),
}


def uninstall_hook(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {})
for xmlid, (
perm_read,
perm_write,
perm_create,
perm_unlink,
) in _ORIGINAL_PERMS.items():
acl = env.ref(xmlid, raise_if_not_found=False)
if not acl:
continue
acl.write(
{
"perm_read": bool(perm_read),
"perm_write": bool(perm_write),
"perm_create": bool(perm_create),
"perm_unlink": bool(perm_unlink),
}
)
151 changes: 150 additions & 1 deletion analytic_restrictions/security/analytic_security.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,156 @@
<field name="category_id" ref="base.module_category_hidden" />
<field
name="implied_ids"
eval="[(Command.link(ref('analytic.group_analytic_accounting')))]"
eval="[
Command.link(ref('analytic.group_analytic_accounting')),
Command.link(ref('account_analytic_tag.group_analytic_tags')),
]"
/>
</record>

<!-- analytic -->
<record id="analytic.access_account_analytic_account" model="ir.model.access">
<field name="name">account.analytic.account.read</field>
<field name="model_id" ref="analytic.model_account_analytic_account" />
<field name="group_id" ref="analytic.group_analytic_accounting" />
<field name="perm_read" eval="True" />
<field name="perm_write" eval="False" />
<field name="perm_create" eval="False" />
<field name="perm_unlink" eval="False" />
</record>

<record id="analytic.access_account_analytic_line" model="ir.model.access">
<field name="name">account.analytic.line.read</field>
<field name="model_id" ref="analytic.model_account_analytic_line" />
<field name="group_id" ref="analytic.group_analytic_accounting" />
<field name="perm_read" eval="True" />
<field name="perm_write" eval="False" />
<field name="perm_create" eval="False" />
<field name="perm_unlink" eval="False" />
</record>

<record
id="analytic.access_account_analytic_distribution_model"
model="ir.model.access"
>
<field name="name">account.analytic.distribution.model.read</field>
<field
name="model_id"
ref="analytic.model_account_analytic_distribution_model"
/>
<field name="group_id" ref="analytic.group_analytic_accounting" />
<field name="perm_read" eval="True" />
<field name="perm_write" eval="False" />
<field name="perm_create" eval="False" />
<field name="perm_unlink" eval="False" />
</record>

<record id="analytic.access_account_analytic_plan" model="ir.model.access">
<field name="name">account.analytic.plan.read</field>
<field name="model_id" ref="analytic.model_account_analytic_plan" />
<field name="group_id" ref="analytic.group_analytic_accounting" />
<field name="perm_read" eval="True" />
<field name="perm_write" eval="False" />
<field name="perm_create" eval="False" />
<field name="perm_unlink" eval="False" />
</record>

<record id="analytic.access_account_analytic_applicability" model="ir.model.access">
<field name="name">account.analytic.applicability.read</field>
<field name="model_id" ref="analytic.model_account_analytic_applicability" />
<field name="group_id" ref="analytic.group_analytic_accounting" />
<field name="perm_read" eval="True" />
<field name="perm_write" eval="False" />
<field name="perm_create" eval="False" />
<field name="perm_unlink" eval="False" />
</record>

<!-- account_analytic_tag -->
<record
id="account_analytic_tag.access_account_analytic_tag_manager"
model="ir.model.access"
>
<field name="name">account.analytic.tag.read</field>
<field name="model_id" ref="account_analytic_tag.model_account_analytic_tag" />
<field name="group_id" ref="account.group_account_manager" />
<field name="perm_read" eval="True" />
<field name="perm_write" eval="False" />
<field name="perm_create" eval="False" />
<field name="perm_unlink" eval="False" />
</record>

<!-- project -->
<record id="project.access_account_analytic_line_project" model="ir.model.access">
<field name="name">account.analytic.line.read</field>
<field name="model_id" ref="analytic.model_account_analytic_line" />
<field name="group_id" ref="project.group_project_manager" />
<field name="perm_read" eval="True" />
<field name="perm_write" eval="False" />
<field name="perm_create" eval="False" />
<field name="perm_unlink" eval="False" />
</record>

<!-- account -->
<record id="account.access_account_analytic_accountant" model="ir.model.access">
<field name="name">account.analytic.account.read</field>
<field name="model_id" ref="analytic.model_account_analytic_account" />
<field name="group_id" ref="account.group_account_user" />
<field name="perm_read" eval="True" />
<field name="perm_write" eval="False" />
<field name="perm_create" eval="False" />
<field name="perm_unlink" eval="False" />
</record>

<record
id="account.access_account_analytic_plan_accountant"
model="ir.model.access"
>
<field name="name">account.analytic.plan.read</field>
<field name="model_id" ref="analytic.model_account_analytic_plan" />
<field name="group_id" ref="account.group_account_user" />
<field name="perm_read" eval="True" />
<field name="perm_write" eval="False" />
<field name="perm_create" eval="False" />
<field name="perm_unlink" eval="False" />
</record>

<record
id="account.access_account_analytic_applicability_accountant"
model="ir.model.access"
>
<field name="name">account.analytic.applicability.read</field>
<field name="model_id" ref="analytic.model_account_analytic_applicability" />
<field name="group_id" ref="account.group_account_user" />
<field name="perm_read" eval="True" />
<field name="perm_write" eval="False" />
<field name="perm_create" eval="False" />
<field name="perm_unlink" eval="False" />
</record>

<record
id="account.access_account_analytic_distribution_invoice"
model="ir.model.access"
>
<field name="name">account.analytic.distribution.model.read</field>
<field
name="model_id"
ref="analytic.model_account_analytic_distribution_model"
/>
<field name="group_id" ref="account.group_account_invoice" />
<field name="perm_read" eval="True" />
<field name="perm_write" eval="False" />
<field name="perm_create" eval="False" />
<field name="perm_unlink" eval="False" />
</record>

<!-- hr_timesheet -->
<record id="hr_timesheet.access_account_analytic_user" model="ir.model.access">
<field name="name">account.analytic.account.read</field>
<field name="model_id" ref="analytic.model_account_analytic_account" />
<field name="group_id" ref="hr_timesheet.group_hr_timesheet_user" />
<field name="perm_read" eval="True" />
<field name="perm_write" eval="False" />
<field name="perm_create" eval="False" />
<field name="perm_unlink" eval="False" />
</record>
</odoo>
7 changes: 3 additions & 4 deletions analytic_restrictions/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_analytic_account,access_account_analytic_account,analytic.model_account_analytic_account,analytic.group_analytic_accounting,1,0,0,0
access_account_analytic_line,access_account_analytic_line,analytic.model_account_analytic_line,analytic.group_analytic_accounting,1,0,0,0
access_account_analytic_distribution,access_account_analytic_distribution,analytic.model_account_analytic_distribution_model,analytic.group_analytic_accounting,1,0,0,0

access_account_analytic_account_admin,access_account_analytic_account_admin,analytic.model_account_analytic_account,analytic_restrictions.group_analytic_accounting_admin,1,1,1,1
access_account_analytic_line_admin,access_account_analytic_line_admin,analytic.model_account_analytic_line,analytic_restrictions.group_analytic_accounting_admin,1,1,1,1
access_account_analytic_distribution_admin,access_account_analytic_distribution_admin,analytic.model_account_analytic_distribution_model,analytic_restrictions.group_analytic_accounting_admin,1,1,1,1
access_account_analytic_tag_admin,access_account_analytic_tag_admin,account_analytic_tag.model_account_analytic_tag,analytic_restrictions.group_analytic_accounting_admin,1,1,1,1
access_account_analytic_plan_admin,access_account_analytic_plan_admin,analytic.model_account_analytic_plan,analytic_restrictions.group_analytic_accounting_admin,1,1,1,1
access_account_analytic_applicability_admin,access_account_analytic_applicability_admin,analytic.model_account_analytic_applicability,analytic_restrictions.group_analytic_accounting_admin,1,1,1,1
23 changes: 9 additions & 14 deletions analytic_restrictions/tests/test_analytic_restrictions.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ def setUpClass(cls):
cls.env.ref("analytic.model_account_analytic_account").model,
cls.env.ref("analytic.model_account_analytic_line").model,
cls.env.ref("analytic.model_account_analytic_distribution_model").model,
cls.env.ref("analytic.model_account_analytic_plan").model,
cls.env.ref("analytic.model_account_analytic_applicability").model,
cls.env.ref("account_analytic_tag.model_account_analytic_tag").model,
]

cls.user_analytic = cls.env["res.users"].create(
Expand All @@ -39,16 +42,8 @@ def setUpClass(cls):
}
)

def test_admin_group_implies_analytic_group(self):
self.assertTrue(
self.user_admin.has_group(
"analytic_restrictions.group_analytic_accounting_admin"
)
)
self.assertTrue(self.user_admin.has_group("analytic.group_analytic_accounting"))

def test_acl_records_loaded(self):
ro = self.env.ref("analytic_restrictions.access_account_analytic_account")
ro = self.env.ref("analytic.access_account_analytic_account")
self.assertTrue(ro.perm_read)
self.assertFalse(ro.perm_write)
self.assertFalse(ro.perm_create)
Expand All @@ -64,18 +59,18 @@ def test_acl_records_loaded(self):
self.assertTrue(admin.perm_unlink)
self.assertEqual(admin.group_id, self.group_admin)

def test_admin_group_full_access_rights(self):
def test_analytic_group_is_read_only(self):
for model_name in self.model_names:
m = self.env[model_name].with_user(self.user_admin)
m = self.env[model_name].with_user(self.user_analytic)
self.assertTrue(
m.check_access_rights("read", raise_exception=False), model_name
)
self.assertTrue(
self.assertFalse(
m.check_access_rights("create", raise_exception=False), model_name
)
self.assertTrue(
self.assertFalse(
m.check_access_rights("write", raise_exception=False), model_name
)
self.assertTrue(
self.assertFalse(
m.check_access_rights("unlink", raise_exception=False), model_name
)
Loading