diff --git a/trytond/trytond/model/modelsql.py b/trytond/trytond/model/modelsql.py index 96bde29b9b..26422f8d42 100644 --- a/trytond/trytond/model/modelsql.py +++ b/trytond/trytond/model/modelsql.py @@ -22,6 +22,7 @@ from trytond.pool import Pool from trytond.pyson import PYSONDecoder, PYSONEncoder from trytond.rpc import RPC from trytond.tools import cursor_dict, grouped_slice, reduce_ids +from trytond.tools.domain_inversion import simplify from trytond.transaction import ( Transaction, inactive_records, record_cache_size, without_check_access) @@ -1691,6 +1692,21 @@ class ModelSQL(ModelStorage): pool = Pool() Rule = pool.get('ir.rule') + def convert(domain): + if is_leaf(domain): + fname, *_ = domain[0].split('.', 1) + field = cls._fields[fname] + if isinstance(field, fields.Function) and field.searcher: + new_leaf = getattr(cls, field.searcher)(fname, domain) + return new_leaf + else: + return domain + elif isinstance(domain, str): + return domain + else: + return [convert(d) for d in domain] + + domain = simplify(convert(domain)) rule_domain = Rule.domain_get(cls.__name__, mode='read') joined_domains = None if domain and domain[0] == 'OR': diff --git a/trytond/trytond/tests/modelsql.py b/trytond/trytond/tests/modelsql.py index c2fa05dcb7..669441dee9 100644 --- a/trytond/trytond/tests/modelsql.py +++ b/trytond/trytond/tests/modelsql.py @@ -152,6 +152,13 @@ class ModelSQLSearchOR2Union(ModelSQL): } return [table.integer + target.id] + @classmethod + def search_rec_name(cls, name, clause): + return ['OR', + ('name',) + clause[1:], + ('targets.name',) + clause[1:], + ] + class ModelSQLSearchOR2UnionTarget(ModelSQL): "ModelSQL Target to test read" diff --git a/trytond/trytond/tests/test_modelsql.py b/trytond/trytond/tests/test_modelsql.py index 72d9f54e7d..4a2347dcaf 100644 --- a/trytond/trytond/tests/test_modelsql.py +++ b/trytond/trytond/tests/test_modelsql.py @@ -1251,6 +1251,27 @@ class ModelSQLTestCase(TestCase): self.assertEqual(Model.search(domain), [model_c, model_a]) self.assertIn('UNION', str(Model.search(domain, query=True))) + @with_transaction() + def test_search_or_to_union_function_field(self): + pool = Pool() + Model = pool.get('test.modelsql.search.or2union') + + model_a, model_b, model_c = Model.create([{ + 'name': 'A', + }, { + 'name': 'B', + }, { + 'name': 'C', + 'targets': [ + ('create', [{'name': 'A'}]), + ], + }, + ]) + + domain = [('rec_name', '=', 'A')] + self.assertEqual(Model.search(domain), [model_a, model_c]) + self.assertIn('UNION', str(Model.search(domain, query=True))) + @with_transaction() def test_search_limit(self): "Test searching with limit"