From 40b95ede3706ce2a2a103673363a1de5dfe384c8 Mon Sep 17 00:00:00 2001
From: bosd <5e2fd43-d292-4c90-9d1f-74ff3436329a@anonaddy.me>
Date: Mon, 18 May 2026 10:47:26 +0200
Subject: [PATCH] [ADD] base_tier_validation: manager group, menu out of
Technical
Managing tier definitions/exceptions previously required Settings >
Technical access (write gated to base.group_erp_manager /
base.group_system, menu nested under base.menu_custom). Giving a
trusted key user that access is dangerous -- they can damage the whole
system.
Add a dedicated "Tier Validation Administrator" group
(group_tier_validation_manager) with CRUD on tier.definition,
tier.validation.exception and tier.review, and relocate the
"Tier Validations" menu to a top-level entry gated by that group.
base.group_system implies the new group so existing administrators keep
full access and still see the (now top-level) menu.
Note: an erp_manager who is not also a system admin keeps model write
access via the existing access_tier_definition_settings row but loses
automatic menu visibility after the relocation. Left as-is per design;
flagged for reviewer input on whether base.group_erp_manager should
also imply the new group.
---
base_tier_validation/__manifest__.py | 1 +
base_tier_validation/readme/CONFIGURE.md | 10 ++++--
base_tier_validation/readme/HISTORY.md | 11 ++++++
.../security/ir.model.access.csv | 3 ++
.../security/tier_validation_groups.xml | 25 +++++++++++++
.../tests/test_tier_validation.py | 36 +++++++++++++++++--
.../views/tier_definition_view.xml | 4 ++-
7 files changed, 85 insertions(+), 5 deletions(-)
create mode 100644 base_tier_validation/security/tier_validation_groups.xml
diff --git a/base_tier_validation/__manifest__.py b/base_tier_validation/__manifest__.py
index 3d2ad910..9e5cd041 100644
--- a/base_tier_validation/__manifest__.py
+++ b/base_tier_validation/__manifest__.py
@@ -15,6 +15,7 @@
"depends": ["mail"],
"data": [
# Security
+ "security/tier_validation_groups.xml",
"security/ir.model.access.csv",
"security/tier_validation_security.xml",
# Data
diff --git a/base_tier_validation/readme/CONFIGURE.md b/base_tier_validation/readme/CONFIGURE.md
index 4bd817e6..423d7127 100644
--- a/base_tier_validation/readme/CONFIGURE.md
+++ b/base_tier_validation/readme/CONFIGURE.md
@@ -1,10 +1,16 @@
To configure this module, you need to:
-1. Go to *Settings \> Technical \> Tier Validations \> Tier
- Definition*.
+1. Go to *Tier Validations \> Tier Definition* (top-level menu, no
+ Settings / Technical access required).
2. Create as many tiers as you want for any model having tier
validation functionality.
+The *Tier Validations* menu is gated by the **Tier Validation
+Administrator** group. Assign it to trusted key users (Settings \>
+Users \> *Tier Validation* category) so they can manage definitions and
+exceptions **without** granting them Settings / Technical access.
+System administrators receive this group automatically.
+
**Note:**
- If check *Notify Reviewers on Creation*, all possible reviewers will
diff --git a/base_tier_validation/readme/HISTORY.md b/base_tier_validation/readme/HISTORY.md
index 740cd6ca..4812ccbb 100644
--- a/base_tier_validation/readme/HISTORY.md
+++ b/base_tier_validation/readme/HISTORY.md
@@ -1,3 +1,14 @@
+## 19.0.2.0.0 (2026-05-17)
+
+Features:
+
+- New **Tier Validation Administrator** security group. Trusted key
+ users can now manage tier definitions and exceptions without being
+ granted Settings / Technical access. System administrators receive
+ the group automatically (back-compat).
+- The *Tier Validations* menu has moved out of *Settings > Technical*
+ to a top-level menu, gated by the new group.
+
## 19.0.1.0.1 (2026-05-12)
Fixes:
diff --git a/base_tier_validation/security/ir.model.access.csv b/base_tier_validation/security/ir.model.access.csv
index 82c76c65..ef2066fa 100644
--- a/base_tier_validation/security/ir.model.access.csv
+++ b/base_tier_validation/security/ir.model.access.csv
@@ -9,3 +9,6 @@ access_tier_definition_settings,tier.definition.settings,model_tier_definition,b
access_comment_wizard,access.comment.wizard,model_comment_wizard,base.group_user,1,1,1,1
access_tier_validation_exceptions_all,tier.validation.exceptions,model_tier_validation_exception,base.group_user,1,0,0,0
access_tier_validation_exceptions_settings,tier.validation.exceptions,model_tier_validation_exception,base.group_system,1,1,1,1
+access_tier_definition_manager,tier.definition.manager,model_tier_definition,base_tier_validation.group_tier_validation_manager,1,1,1,1
+access_tier_validation_exceptions_manager,tier.validation.exceptions.manager,model_tier_validation_exception,base_tier_validation.group_tier_validation_manager,1,1,1,1
+access_tier_review_manager,tier.review.manager,model_tier_review,base_tier_validation.group_tier_validation_manager,1,1,1,1
diff --git a/base_tier_validation/security/tier_validation_groups.xml b/base_tier_validation/security/tier_validation_groups.xml
new file mode 100644
index 00000000..cea08a10
--- /dev/null
+++ b/base_tier_validation/security/tier_validation_groups.xml
@@ -0,0 +1,25 @@
+
+
+
+
+ Tier Validation
+ 20
+
+
+ Tier Validation
+
+
+
+ Administrator
+
+
+
+
+
+
+
diff --git a/base_tier_validation/tests/test_tier_validation.py b/base_tier_validation/tests/test_tier_validation.py
index 344004fd..a6b8b55b 100644
--- a/base_tier_validation/tests/test_tier_validation.py
+++ b/base_tier_validation/tests/test_tier_validation.py
@@ -7,9 +7,9 @@
from lxml import etree
from odoo import Command
-from odoo.exceptions import ValidationError
+from odoo.exceptions import AccessError, ValidationError
from odoo.fields import Domain
-from odoo.tests import Form
+from odoo.tests import Form, new_test_user
from odoo.tests.common import tagged
from ..models.tier_validation import BASE_EXCEPTION_FIELDS as BEF
@@ -1454,6 +1454,38 @@ def test_34_test_duplicate_new_user_should_not_have_review_ids(self):
# Review_ids should not be copied when duplicating a user
self.assertFalse(new_user.review_ids.ids)
+ def test_35_manager_group_can_configure_without_technical(self):
+ """A trusted key user holding only the Tier Validation
+ Administrator group (no system / erp_manager / Technical) can
+ manage tier definitions; a plain internal user cannot; and the
+ system admin implies the manager group for back-compat."""
+ manager = new_test_user(
+ self.env,
+ name="Tier Manager",
+ login="tier_manager",
+ groups="base.group_user,base_tier_validation.group_tier_validation_manager",
+ )
+ plain = new_test_user(
+ self.env, name="Plain", login="plain_user", groups="base.group_user"
+ )
+ vals = {
+ "model_id": self.tester_model.id,
+ "review_type": "individual",
+ "reviewer_id": self.test_user_1.id,
+ "definition_domain": "[('test_field', '=', 1.0)]",
+ }
+ definition = self.env["tier.definition"].with_user(manager).create(dict(vals))
+ self.assertTrue(definition.id)
+ definition.with_user(manager).write({"sequence": 99})
+ with self.assertRaises(AccessError):
+ self.env["tier.definition"].with_user(plain).create(dict(vals))
+ # Back-compat: system administrators implicitly get the new group.
+ self.assertTrue(
+ self.test_user_1.has_group(
+ "base_tier_validation.group_tier_validation_manager"
+ )
+ )
+
@tagged("at_install")
class TierTierValidationView(CommonTierValidation):
diff --git a/base_tier_validation/views/tier_definition_view.xml b/base_tier_validation/views/tier_definition_view.xml
index 922727ed..5203e9df 100644
--- a/base_tier_validation/views/tier_definition_view.xml
+++ b/base_tier_validation/views/tier_definition_view.xml
@@ -160,7 +160,9 @@