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

[16.0][ADD] base_tier_validation: compute validation flag dynamically #694

Closed
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
29 changes: 29 additions & 0 deletions base_tier_validation/models/tier_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,32 @@
rec.valid_reviewer_field_ids = self.env["ir.model.fields"].search(
[("model", "=", rec.model), ("relation", "=", "res.users")]
)

@api.model_create_multi
def create(self, vals_list):
result = super().create(vals_list)
result._update_registry()
return result

def write(self, vals):
result = super().write(vals)
if "definition_domain" in vals:
self._update_registry()
return result

def unlink(self):
models = set(self.mapped("model"))
result = super().unlink()
self._update_registry(models)
return result

def _update_registry(self, models=None):
"""Update dependencies of validation flag"""
for model in models or set(self.mapped("model")):
depends = self.env[model]._compute_need_validation._depends
if not callable(depends):
continue

Check warning on line 112 in base_tier_validation/models/tier_definition.py

View check run for this annotation

Codecov / codecov/patch

base_tier_validation/models/tier_definition.py#L112

Added line #L112 was not covered by tests
self.pool.field_depends[
self.env[model]._fields["need_validation"]
] = depends(self.env[model])
self.pool.registry_invalidated = True
39 changes: 36 additions & 3 deletions base_tier_validation/models/tier_validation.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Copyright 2017-19 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

import json
from ast import literal_eval

from lxml import etree

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.osv.expression import OR, is_leaf
from odoo.tools.misc import frozendict


Expand Down Expand Up @@ -185,17 +187,36 @@ def _calc_reviews_rejected(self, reviews):
"""Override for different rejection policy."""
return any([s == "rejected" for s in reviews.mapped("status")])

@api.depends(lambda self: self._compute_need_validation_dependencies())
def _compute_need_validation(self):
for rec in self:
if isinstance(rec.id, models.NewId):
rec.need_validation = False
continue
tiers = self.env["tier.definition"].search([("model", "=", self._name)])
valid_tiers = any([rec.evaluate_tier(tier) for tier in tiers])
rec.need_validation = (
not rec.review_ids and valid_tiers and rec._check_state_from_condition()
)

def _compute_need_validation_dependencies(self):
"""Return the fields the validation flag depends on"""
if self._abstract:
return []
tiers = self.env["tier.definition"].search([("model", "=", self._name)])
tier_domains = sum(
# we can't browse because this is called during updates too
(
literal_eval(
tier.read(["definition_domain"])[0]["definition_domain"] or "[]"
)
for tier in tiers
),
[],
)
return list(
leaf[0]
for leaf in tier_domains
if is_leaf(leaf) and leaf[0] in self._fields
)

def evaluate_tier(self, tier):
if tier.definition_domain:
domain = literal_eval(tier.definition_domain)
Expand Down Expand Up @@ -532,6 +553,18 @@ def get_view(self, view_id=None, view_type="form", **options):
all_models[model] = res["models"][model]
new_node = etree.fromstring(new_arch)
node.append(new_node)
for node in doc.xpath("//field[@name][not(ancestor::field)]"):
modifiers = json.loads(
node.attrib.get("modifiers", '{"readonly": false}')
)
if modifiers.get("readonly") is not True:
modifiers["readonly"] = OR(
[
modifiers.get("readonly", []) or [],
[("review_ids", "!=", [])],
]
)
node.attrib["modifiers"] = json.dumps(modifiers)
res["arch"] = etree.tostring(doc)
res["models"] = frozendict(all_models)
return res
16 changes: 16 additions & 0 deletions base_tier_validation/tests/test_tier_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,22 @@ def test_18_test_review_by_res_users_field(self):
self.assertTrue(review)
self.assertEqual(review.reviewer_ids, self.test_user_2)

def test_19_update_registry(self):
"""Test that changes to the tier definition reloads the registry"""
tier = self.env["tier.definition"].search(
[
("model_id", "=", self.tester_model.id),
]
)
field = self.env[self.test_model._name]._fields["need_validation"]
self.assertIn("test_field", self.env.registry.field_depends[field])
tier.write({"definition_domain": "[]"})
self.assertNotIn("test_field", self.env.registry.field_depends[field])
tier.unlink()
self.assertNotIn("test_field", self.env.registry.field_depends[field])
self.assertTrue(self.env.registry.registry_invalidated)
self.env.registry.registry_invalidated = False


@tagged("at_install")
class TierTierValidationView(CommonTierValidation):
Expand Down
Loading