Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[14.0][ADD] base_rule_override: new module #820

Open
wants to merge 1 commit into
base: 14.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
117 changes: 117 additions & 0 deletions base_rule_override/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
====================
Record Rule Override
====================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:f3ef453ceddc10e3dbbfc8c25430e92b9471f84a597ac1e63ef0988a9e2c69aa
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--ux-lightgray.png?logo=github
:target: https://github.com/OCA/server-ux/tree/14.0/base_rule_override
:alt: OCA/server-ux
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/server-ux-14-0/server-ux-14-0-base_rule_override
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/server-ux&target_branch=14.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module adds a new boolean on Record rules that changes
the way they are evaluated.

If a Record Rule is of type "override", then it must pass
in order for the record to be visible.

In other words, "override" record rules are in AND with other
rules, not in OR as they normally are.

Use with caution!

**Table of contents**

.. contents::
:local:

Usage
=====

In debug mode, navigate to Settings > Technical > Record Rules.

Create a new rule, or edit an existing one, and check the
"Override" checkbox.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-ux/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/server-ux/issues/new?body=module:%20base_rule_override%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
~~~~~~~

* PyTech SRL
* Ooops404

Contributors
~~~~~~~~~~~~

* PyTech SRL <info@pytech.it>:

* Alessandro Uffreduzzi <alessandro.uffreduzzi@pytech.it>

* Ooops404 <info@ooops404.com>:

* Francesco Foresti <francesco.foresti@ooops404.com>

Maintainers
~~~~~~~~~~~

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

.. |maintainer-ilyasProgrammer| image:: https://github.com/ilyasProgrammer.png?size=40px
:target: https://github.com/ilyasProgrammer
:alt: ilyasProgrammer
.. |maintainer-aleuffre| image:: https://github.com/aleuffre.png?size=40px
:target: https://github.com/aleuffre
:alt: aleuffre
.. |maintainer-renda-dev| image:: https://github.com/renda-dev.png?size=40px
:target: https://github.com/renda-dev
:alt: renda-dev
.. |maintainer-PicchiSeba| image:: https://github.com/PicchiSeba.png?size=40px
:target: https://github.com/PicchiSeba
:alt: PicchiSeba

Current `maintainers <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-ilyasProgrammer| |maintainer-aleuffre| |maintainer-renda-dev| |maintainer-PicchiSeba|

This module is part of the `OCA/server-ux <https://github.com/OCA/server-ux/tree/14.0/base_rule_override>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions base_rule_override/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from .hooks import uninstall_hook
13 changes: 13 additions & 0 deletions base_rule_override/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "Record Rule Override",
"version": "14.0.1.0.0",
"author": "PyTech SRL, Ooops404, Odoo Community Association (OCA)",
"maintainers": ["ilyasProgrammer", "aleuffre", "renda-dev", "PicchiSeba"],
"depends": ["base"],
"data": ["views/ir_rule_views.xml"],
"website": "https://github.com/OCA/server-ux",
"license": "AGPL-3",
"installable": True,
"uninstall_hook": "uninstall_hook",
}
9 changes: 9 additions & 0 deletions base_rule_override/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright 2024 Ooops404
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import SUPERUSER_ID, api


def uninstall_hook(cr, registry):
"""Set all "is_override" rules to inactive before uninstalling."""
env = api.Environment(cr, SUPERUSER_ID, {})
env["ir.rule"].search([("is_override", "=", True)]).write({"active": False})
1 change: 1 addition & 0 deletions base_rule_override/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import ir_rule
81 changes: 81 additions & 0 deletions base_rule_override/models/ir_rule.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Copyright 2024 Ooops404
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl).

from odoo import api, fields, models, tools
from odoo.osv import expression
from odoo.tools import config
from odoo.tools.safe_eval import safe_eval


class IrRule(models.Model):
_inherit = "ir.rule"

is_override = fields.Boolean(
string="Override",
help="Unlike other rules, override rules "
"must be passed in order to allow visibility to the record",
)

def _get_failing(self, for_records, mode="read"):
res = super()._get_failing(for_records, mode)
if res:
return res
Model = for_records.browse(()).sudo()
eval_context = self._eval_context()
override_rules = self._get_rules(Model._name, mode=mode).sudo()

def is_failing(r, ids=for_records.ids):
dom = safe_eval(r.domain_force, eval_context) if r.domain_force else []
return Model.search_count(
expression.AND([[("id", "in", ids)], expression.normalize_domain(dom)])
) < len(ids)

return override_rules.filtered(lambda r: is_failing(r)).with_user(self.env.user)

def _get_rules(self, model_name, mode="read"):
"""
Return non-override rules by default
"""
res = super()._get_rules(model_name, mode).sudo()
if self.env.context.get("get_rule_override"):
res = res.filtered(lambda x: x.is_override)
else:
res = res.filtered(lambda x: not x.is_override)
return res.with_user(self.env.user)

@api.model
@tools.conditional(
"xml" not in config["dev_mode"],
tools.ormcache(
"self.env.uid",
"self.env.su",
"model_name",
"mode",
"tuple(self._compute_domain_context_values())",
),
)
def _compute_domain(self, model_name, mode="read"):
"""
Override domains are in AND with other domains
regardless of groups
"""
res = super()._compute_domain(model_name, mode)
override_rules = self.with_context(get_rule_override=True)._get_rules(
model_name, mode=mode
)
if not override_rules:
return res

# browse user and rules as SUPERUSER_ID to avoid access errors!
eval_context = self._eval_context()
override_domains = []
for rule in override_rules.sudo():
# evaluate the domain for the current user
dom = (
safe_eval(rule.domain_force, eval_context) if rule.domain_force else []
)
dom = expression.normalize_domain(dom)
override_domains.append(dom)
if res is None:
return expression.AND(override_domains)
return expression.AND(override_domains + [res])
7 changes: 7 additions & 0 deletions base_rule_override/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
* PyTech SRL <info@pytech.it>:

* Alessandro Uffreduzzi <alessandro.uffreduzzi@pytech.it>

* Ooops404 <info@ooops404.com>:

* Francesco Foresti <francesco.foresti@ooops404.com>
10 changes: 10 additions & 0 deletions base_rule_override/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
This module adds a new boolean on Record rules that changes
the way they are evaluated.

If a Record Rule is of type "override", then it must pass
in order for the record to be visible.

In other words, "override" record rules are in AND with other
rules, not in OR as they normally are.

Use with caution!
4 changes: 4 additions & 0 deletions base_rule_override/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
In debug mode, navigate to Settings > Technical > Record Rules.

Create a new rule, or edit an existing one, and check the
"Override" checkbox.