changeset b5fec49cfc79 in trytond:5.8
details: https://hg.tryton.org/trytond?cmd=changeset&node=b5fec49cfc79
description:
        Set field context when validate domain

        issue10386
        review336171002
        (grafted from 3f6ad2b8a63147715020daa288c4a3fe30d51769)
diffstat:

 trytond/cache.py              |   7 ++++
 trytond/model/modelstorage.py |  72 ++++++++++++++++++++++++------------------
 2 files changed, 48 insertions(+), 31 deletions(-)

diffs (114 lines):

diff -r 663abd0643bb -r b5fec49cfc79 trytond/cache.py
--- a/trytond/cache.py  Sat May 15 22:38:43 2021 +0200
+++ b/trytond/cache.py  Sun Jun 06 09:27:28 2021 +0200
@@ -43,6 +43,13 @@
         return o
 
 
+def unfreeze(o):
+    if isinstance(o, frozenset):
+        return dict((x, unfreeze(y)) for x, y in o)
+    else:
+        return o
+
+
 class BaseCache(object):
     _instances = {}
 
diff -r 663abd0643bb -r b5fec49cfc79 trytond/model/modelstorage.py
--- a/trytond/model/modelstorage.py     Sat May 15 22:38:43 2021 +0200
+++ b/trytond/model/modelstorage.py     Sun Jun 06 09:27:28 2021 +0200
@@ -23,7 +23,7 @@
 from trytond.i18n import gettext, lazy_gettext
 from trytond.transaction import Transaction
 from trytond.pool import Pool
-from trytond.cache import LRUDict, LRUDictTransaction, freeze
+from trytond.cache import LRUDict, LRUDictTransaction, freeze, unfreeze
 from trytond.rpc import RPC
 from .modelview import ModelView
 from .descriptors import dualmethod
@@ -1080,44 +1080,54 @@
                 Relation = field.get_target()
             else:
                 Relation = cls
-            domains = defaultdict(list)
-            if is_pyson(field.domain):
-                pyson_domain = PYSONEncoder().encode(field.domain)
+            domains = defaultdict(lambda: defaultdict(list))
+            if is_pyson(field.domain) or is_pyson(field.context):
+                encoder = PYSONEncoder()
+                pyson_domain = encoder.encode(field.domain)
+                pyson_context = encoder.encode(field.context)
                 for record in records:
                     domain = freeze(_record_eval_pyson(
                             record, pyson_domain, encoded=True))
-                    domains[domain].append(record)
+                    context = freeze(_record_eval_pyson(
+                            record, pyson_context, encoded=True))
+                    domains[context][domain].append(record)
                 # Select strategy depending if it is closer to one domain per
                 # record or one domain for all records
-                if len(domains) > len(records) * 0.5:
-                    # Do not use IN_MAX to let spaces for the pyson domain
-                    in_max = Transaction().database.IN_MAX
-                    count = in_max // 10
-                    new_domains = {}
-                    for sub_domains in grouped_slice(
-                            list(domains.keys()), count):
-                        grouped_domain = ['OR']
-                        grouped_records = []
-                        for d in sub_domains:
-                            sub_records = domains[d]
-                            grouped_records.extend(sub_records)
-                            relations = relation_domain(field, sub_records)
-                            if len(relations) > in_max:
-                                break
-                            grouped_domain.append(
-                                [('id', 'in', [r.id for r in relations]), d])
+                # Do not use IN_MAX to let spaces for the pyson domain
+                in_max = Transaction().database.IN_MAX
+                count = in_max // 10
+                for context, ctx_domains in domains.items():
+                    if len(ctx_domains) > len(records) * 0.5:
+                        new_domains = {}
+                        for sub_domains in grouped_slice(
+                                list(ctx_domains.keys()), count):
+                            grouped_domain = ['OR']
+                            grouped_records = []
+                            for d in sub_domains:
+                                sub_records = ctx_domains[d]
+                                grouped_records.extend(sub_records)
+                                relations = relation_domain(field, sub_records)
+                                if len(relations) > in_max:
+                                    break
+                                grouped_domain.append(
+                                    [('id', 'in',
+                                            [r.id for r in relations]), d])
+                            else:
+                                new_domains[freeze(grouped_domain)] = \
+                                    grouped_records
+                                continue
+                            break
                         else:
-                            new_domains[freeze(grouped_domain)] = \
-                                grouped_records
-                            continue
-                        break
-                    else:
-                        domains = new_domains
+                            domains[context] = new_domains
             else:
-                domains[freeze(field.domain)].extend(records)
+                domains[freeze(field.context)][freeze(field.domain)].extend(
+                    records)
 
-            for domain, sub_records in domains.items():
-                validate_relation_domain(field, sub_records, Relation, domain)
+            for context, ctx_domains in domains.items():
+                for domain, sub_records in ctx_domains.items():
+                    with Transaction().set_context(unfreeze(context)):
+                        validate_relation_domain(
+                            field, sub_records, Relation, unfreeze(domain))
 
         def relation_domain(field, records):
             if field._type in ('many2one', 'one2many', 'many2many', 'one2one'):

Reply via email to