changeset 558aeef898cd in tryton:default
details: https://hg.tryton.org/tryton?cmd=changeset&node=558aeef898cd
description:
Use specific search domain for reference field searches
issue9997
review324781002
diffstat:
tryton/common/domain_inversion.py | 57 ++++++++++++++++++++++++++---
tryton/gui/window/view_form/model/field.py | 3 +-
2 files changed, 53 insertions(+), 7 deletions(-)
diffs (86 lines):
diff -r e440811334aa -r 558aeef898cd tryton/common/domain_inversion.py
--- a/tryton/common/domain_inversion.py Sun Apr 11 18:28:37 2021 +0200
+++ b/tryton/common/domain_inversion.py Mon Apr 12 20:54:03 2021 +0200
@@ -170,15 +170,60 @@
def prepare_reference_domain(domain, reference):
"convert domain to replace reference fields by their local part"
+
+ def value2reference(value):
+ model, ref_id = None, None
+ if isinstance(value, str) and ',' in value:
+ model, ref_id = value.split(',', 1)
+ if ref_id != '%':
+ try:
+ ref_id = int(ref_id)
+ except ValueError:
+ model, ref_id = None, value
+ elif (isinstance(value, (list, tuple))
+ and len(value) == 2
+ and isinstance(value[0], str)
+ and (isinstance(value[1], int) or value[1] == '%')):
+ model, ref_id = value
+ else:
+ ref_id = value
+ return model, ref_id
+
if domain in ('AND', 'OR'):
return domain
elif is_leaf(domain):
- # When a Reference field is using the dotted notation the model
- # specified must be removed from the clause
- if domain[0].count('.') and len(domain) > 3:
- local_name, target_name = domain[0].split('.', 1)
- if local_name == reference:
- return [target_name] + list(domain[1:3] + domain[4:])
+ if domain[0] == reference:
+ if domain[1] in {'=', '!='}:
+ model, ref_id = value2reference(domain[2])
+ if model is not None:
+ if ref_id == '%':
+ if domain[1] == '=':
+ return [reference + '.id', '!=', None, model]
+ else:
+ return [reference, 'not like', domain[2]]
+ return [reference + '.id', domain[1], ref_id, model]
+ elif domain[1] in {'in', 'not in'}:
+ model_values = {}
+ for value in domain[2]:
+ model, ref_id = value2reference(value)
+ if model is None:
+ break
+ model_values.setdefault(model, []).append(ref_id)
+ else:
+ new_domain = ['OR'] if domain[1] == 'in' else ['AND']
+ for model, ref_ids in model_values.items():
+ if '%' in ref_ids:
+ if domain[1] == 'in':
+ new_domain.append(
+ [reference + '.id', '!=', None, model])
+ else:
+ new_domain.append(
+ [reference, 'not like', model + ',%'])
+ else:
+ new_domain.append(
+ [reference + '.id', domain[1], ref_ids, model])
+ return new_domain
+ return []
return domain
else:
return [prepare_reference_domain(d, reference) for d in domain]
diff -r e440811334aa -r 558aeef898cd tryton/gui/window/view_form/model/field.py
--- a/tryton/gui/window/view_form/model/field.py Sun Apr 11 18:28:37
2021 +0200
+++ b/tryton/gui/window/view_form/model/field.py Mon Apr 12 20:54:03
2021 +0200
@@ -971,10 +971,11 @@
screen_domain = filter_leaf(screen_domain, self.name, model)
screen_domain = prepare_reference_domain(screen_domain, self.name)
return concat(localize_domain(
- screen_domain, strip_target=True), attr_domain)
+ screen_domain, self.name, strip_target=True), attr_domain)
def get_models(self, record):
screen_domain, attr_domain = self.domains_get(record)
+ screen_domain = prepare_reference_domain(screen_domain, self.name)
return extract_reference_models(
concat(screen_domain, attr_domain), self.name)