Merge PR #2824 into 16.0

Signed-off-by pedrobaeza
pull/2834/head
OCA-git-bot 2024-02-07 17:12:34 +00:00
commit 65db48ac11
4 changed files with 113 additions and 0 deletions

View File

@ -189,6 +189,42 @@ class IrUiView(models.Model):
node.attrib[attribute_name] = new_value node.attrib[attribute_name] = new_value
return source return source
@api.model
def inheritance_handler_attributes_attrs_domain_add(self, source, specs):
"""Implement attrs_domain_add
<attribute name="$attribute" operation="attrs_domain_add"
key="$attrs_key" join_operator="OR">
$domain_to_add_to_attrs_key
</attribute>
"""
node = self.locate_node(source, specs)
for attribute_node in specs:
attribute_name = attribute_node.get("name")
key = attribute_node.get("key")
join_operator = attribute_node.get("join_operator") or "AND"
old_value = node.get(attribute_name) or ""
if old_value:
old_value = ast.literal_eval(
self.var2str_domain_text(old_value.strip())
)
old_domain_attrs = old_value.get(key)
new_domain = ast.literal_eval(
self.var2str_domain_text(attribute_node.text.strip())
)
if join_operator == "OR":
new_value = expression.OR([old_domain_attrs, new_domain])
else:
new_value = expression.AND([old_domain_attrs, new_domain])
old_value[key] = new_value
new_value = self.str2var_domain_text(str(old_value))
else:
# We must ensure that the domain definition has not line breaks because
# in update mode the domain cause an invalid syntax error
new_value = "{'%s': %s}" % (key, attribute_node.text.strip())
node.attrib[attribute_name] = new_value
return source
@api.model @api.model
def var2str_domain_text(self, domain_str): def var2str_domain_text(self, domain_str):
"""Replaces var names with str names to allow eval without defined vars""" """Replaces var names with str names to allow eval without defined vars"""

View File

@ -6,3 +6,4 @@
* Carlos Dauden * Carlos Dauden
* Iván Todorovich <ivan.todorovich@camptocamp.com> * Iván Todorovich <ivan.todorovich@camptocamp.com>
* Carlos Serra-Toro <carlos.serra@braintec.com>

View File

@ -31,3 +31,12 @@ to refer to some xmlid, say ``%(xmlid)s``.
condition="$field_condition" join_operator="OR"> condition="$field_condition" join_operator="OR">
$domain_to_add $domain_to_add
</attribute> </attribute>
**Add domain with AND/OR join operator (AND if missed) for key in attrs**
.. code-block:: xml
<attribute name="$attribute" operation="attrs_domain_add"
key="$attrs_key" join_operator="OR">
$domain_to_add_to_attrs_key
</attribute>

View File

@ -240,3 +240,70 @@ class TestBaseViewInheritanceExtension(TransactionCase):
) )
with self.assertRaisesRegex(TypeError, "Attribute `domain` is not a dict"): with self.assertRaisesRegex(TypeError, "Attribute `domain` is not a dict"):
self.env["ir.ui.view"].apply_inheritance_specs(source, specs) self.env["ir.ui.view"].apply_inheritance_specs(source, specs)
def test_attrs_domain_add_join_operator_or(self):
"""Test that we can add an OR domain to an existing attrs key."""
self._test_attrs_domain_add(join_operator="OR")
def test_attrs_domain_add_join_operator_and(self):
"""Test that we can add an AND domain to an existing attrs key."""
self._test_attrs_domain_add(join_operator="AND")
def _test_attrs_domain_add(self, join_operator):
"""Test that we can add a domain to an existing attrs domain key."""
source = etree.fromstring(
"""
<form>
<field
name="ref"
attrs="{
'invisible': [('state', '=', 'draft')],
'required': [('state', '=', False)],
}"
/>
</form>
"""
)
specs = etree.fromstring(
"""
<field name="ref" position="attributes">
<attribute name="attrs" operation="attrs_domain_add"
key="required" join_operator="%s">
[('state', '!=', 'draft')]
</attribute>
</field>
"""
% (join_operator,)
)
res = self.env["ir.ui.view"].apply_inheritance_specs(source, specs)
self.assertEqual(
res.xpath('//field[@name="ref"]')[0].attrib["attrs"],
"{'invisible': [('state', '=', 'draft')], "
"'required': ['%s', ('state', '=', False), ('state', '!=', 'draft')]}"
% ("|" if join_operator == "OR" else "&"),
)
def test_attrs_domain_add_no_attrs(self):
"""Test attrs_domain_add if there is no attrs: attrs is created."""
source = etree.fromstring(
"""
<form>
<field name="ref"/>
</form>
"""
)
specs = etree.fromstring(
"""
<field name="ref" position="attributes">
<attribute name="attrs" operation="attrs_domain_add"
key="required" join_operator="OR">
[('state', '!=', 'draft')]
</attribute>
</field>
"""
)
res = self.env["ir.ui.view"].apply_inheritance_specs(source, specs)
self.assertEqual(
res.xpath('//field[@name="ref"]')[0].attrib["attrs"],
"{'required': [('state', '!=', 'draft')]}",
)