summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
authorqsm-odoo <qsm@odoo.com>2017-03-15 15:19:46 +0100
committerqsm-odoo <qsm@odoo.com>2017-03-24 15:03:54 +0100
commitb2d66d0c1468b9d321d9ffa5782e370e92525a43 (patch)
tree96de95d445e28ffe827f3ae7cfa074372593a976 /addons/web/static/src
parent874c7aa2dd7708ade32396a4ca4307a6342cfb29 (diff)
[FIX] web: properly combine domains with "OR" in CompoundDomain
The CompoundDomain class allows to regroup several domains with an implicit "AND"; these domains can be either a string, an array or another CompoundDomain. A CompoundDomain can then be converted to an array thanks to pyeval.js. For example, if a CompoundDomain is initialized with `[A, B]` and `[C]`, the array conversion gave `[A, B, C]` (which is expected). However, a hackish method was used with CompoundDomain. If one of the domain of a CompoundDomain is equal to `["|"]` (an array with the OR operator in it), the two next subdomains were supposed to be joined by a OR operator. Indeed, for the case of a CompoundDomain initialized with `["|"]`, `[A]` and `[B]`, the array conversion gave `["|", A, B]` (which is expected). However, if initialized with `["|"]`, `[A, B]` and `[C]`, the array conversion gave `["|", A, B, C]` which is very wrong as what was expected is `["|", "&", A, B, C]`. The problem is that the given `[A, B]` contains implicit "&" operators. This commit fixes the problem by normalizing only if the CompoundDomain starts with a ["|"] or ["!"] array which is the standard odoo case. This allows to limit breaking custom code (e.g we want a simple "AND" of `[A]` and `[B]` to stay `[A, B]`, not become `["&", A, B]`). The commit also modifies a test so that it checks that the problem is properly solved.
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/js/pyeval.js47
1 files changed, 39 insertions, 8 deletions
diff --git a/addons/web/static/src/js/pyeval.js b/addons/web/static/src/js/pyeval.js
index c132b8365fb..a651c7d8bfa 100644
--- a/addons/web/static/src/js/pyeval.js
+++ b/addons/web/static/src/js/pyeval.js
@@ -852,29 +852,60 @@
var eval_domains = function (domains, evaluation_context) {
evaluation_context = _.extend(instance.web.pyeval.context(), evaluation_context || {});
var result_domain = [];
+ // Normalize only if the first domain is the array ["|"] or ["!"]
+ var need_normalization = (
+ domains.length > 0
+ && domains[0].length === 1
+ && (domains[0][0] === "|" || domains[0][0] === "!")
+ );
_(domains).each(function (domain) {
if (_.isString(domain)) {
// wrap raw strings in domain
domain = { __ref: 'domain', __debug: domain };
}
+ var domain_array_to_combine;
switch(domain.__ref) {
case 'domain':
evaluation_context.context = evaluation_context;
- result_domain.push.apply(
- result_domain, py.eval(domain.__debug, wrap_context(evaluation_context)));
+ domain_array_to_combine = py.eval(domain.__debug, wrap_context(evaluation_context));
break;
case 'compound_domain':
var eval_context = eval_contexts([domain.__eval_context]);
- result_domain.push.apply(
- result_domain, eval_domains(
- domain.__domains, _.extend(
- {}, evaluation_context, eval_context)));
+ domain_array_to_combine = eval_domains(
+ domain.__domains,
+ _.extend({}, evaluation_context, eval_context)
+ );
break;
default:
- result_domain.push.apply(result_domain, domain);
+ domain_array_to_combine = domain;
+ }
+ if (need_normalization) {
+ domain_array_to_combine = get_normalized_domain(domain_array_to_combine);
}
+ result_domain.push.apply(result_domain, domain_array_to_combine);
});
return result_domain;
+
+ /**
+ * Returns a normalized copy of the given domain array. Normalization is
+ * is making the implicit "&" at the start of the domain explicit, e.g.
+ * [A, B, C] would become ["&", "&", A, B, C].
+ *
+ * @param {Array} domain_array
+ * @returns {Array} normalized copy of the given array
+ */
+ function get_normalized_domain(domain_array) {
+ var expected = 1; // Holds the number of expected domain expressions
+ _.each(domain_array, function (item) {
+ if (item === "&" || item === "|") {
+ expected++;
+ } else if (item !== "!") {
+ expected--;
+ }
+ });
+ var new_explicit_ands = _.times(-expected, _.constant("&"));
+ return new_explicit_ands.concat(domain_array);
+ }
};
var eval_groupbys = function (contexts, evaluation_context) {
evaluation_context = _.extend(instance.web.pyeval.context(), evaluation_context || {});
@@ -995,7 +1026,7 @@
instance.web._t("Local evaluation failure\n%s\n\n%s"),
e.message, JSON.stringify(source))
}
- }};
+ }};
}
d.resolve(result);
}, 0); });