details: https://code.tryton.org/tryton/commit/13d2279f2154
branch: default
user: Nicolas Évrard <[email protected]>
date: Thu Feb 13 01:02:11 2025 +0100
description:
Consider in-leaf with a unique value as constrained for domain inversion
Closes #13869
diffstat:
sao/src/common.js | 15 ++-----
sao/tests/sao.js | 54 +++++++++++++++++++++++++++++++
tryton/tryton/common/domain_inversion.py | 9 ++--
trytond/trytond/tests/test_tools.py | 33 ++++++++++++++++++
trytond/trytond/tools/domain_inversion.py | 9 ++--
5 files changed, 100 insertions(+), 20 deletions(-)
diffs (215 lines):
diff -r 191f2e9503a1 -r 13d2279f2154 sao/src/common.js
--- a/sao/src/common.js Wed Feb 12 18:59:33 2025 +0100
+++ b/sao/src/common.js Thu Feb 13 01:02:11 2025 +0100
@@ -2418,12 +2418,10 @@
(expression.length > 2) &&
(typeof expression[1] == 'string'));
},
- constrained_leaf: function(part, boolop) {
- if (boolop === undefined) {
- boolop = this.and;
- }
+ constrained_leaf: function(part) {
var operand = part[1];
- if ((operand === '=') & (boolop === this.and)) {
+ let value = part[2];
+ if ((operand === '=') || ((operand == 'in') && (value.length ==
1))) {
// We should consider that other domain inversion will set a
// correct value to this field
return true;
@@ -3049,8 +3047,7 @@
((field in context) &&
(this.domain_inversion.eval_leaf(
part, context, this.domain_inversion.and) ||
- this.domain_inversion.constrained_leaf(
- part, this.domain_inversion.and)))) {
+
this.domain_inversion.constrained_leaf(part)))) {
result.push(true);
} else {
return false;
@@ -3105,9 +3102,7 @@
field = this.base(field);
if ((field in context) &&
(this.domain_inversion.eval_leaf(
- part, context, this.domain_inversion.or)) ||
- this.domain_inversion.constrained_leaf(
- part, this.domain_inversion.or)) {
+ part, context, this.domain_inversion.or))) {
return true;
} else if ((field in context) &&
!this.domain_inversion.eval_leaf(part, context,
diff -r 191f2e9503a1 -r 13d2279f2154 sao/tests/sao.js
--- a/sao/tests/sao.js Wed Feb 12 18:59:33 2025 +0100
+++ b/sao/tests/sao.js Thu Feb 13 01:02:11 2025 +0100
@@ -2494,6 +2494,60 @@
'domain_inversion(' + JSON.stringify(domain) + ', \'x\')');
});
+ QUnit.test('DomainInversion unconstrained_inversion', function() {
+ let domain_inversion = new Sao.common.DomainInversion();
+ domain_inversion = domain_inversion.domain_inversion.bind(
+ domain_inversion);
+ let compare = Sao.common.compare;
+
+ let domain = [['x', '=', 3], ['y', 'in', ['a', 'b']]];
+ QUnit.assert.ok(
+ compare(domain_inversion(domain, 'x'), [['x', '=', 3]]),
+ `domain_inversion(${domain}, 'x')`);
+ QUnit.assert.ok(
+ compare(domain_inversion(domain, 'x', {'y': 'a'}), [['x', '=',
3]]),
+ `domain_inversion(${domain}, 'x', {'y': 'a'})`);
+ QUnit.assert.strictEqual(
+ domain_inversion(domain, 'x', {'y': 'c'}), false,
+ `domain_inversion(${domain}, 'x', {'y': 'c'})`);
+ });
+
+ QUnit.test('DomainInversion constrained_equal_inversion', function() {
+ let domain_inversion = new Sao.common.DomainInversion();
+ domain_inversion = domain_inversion.domain_inversion.bind(
+ domain_inversion);
+ let compare = Sao.common.compare;
+
+ let domain = [['x', '=', 3], ['y', '=', 'a']];
+ QUnit.assert.ok(
+ compare(domain_inversion(domain, 'x'), [['x', '=', 3]]),
+ `domain_inversion(${domain}, 'x')`);
+ QUnit.assert.ok(
+ compare(domain_inversion(domain, 'x', {'y': 'a'}), [['x', '=',
3]]),
+ `domain_inversion(${domain}, 'x', {'y': 'a'})`);
+ QUnit.assert.ok(
+ compare(domain_inversion(domain, 'x', {'y': 'c'}), [['x', '=',
3]]),
+ `domain_inversion(${domain}, 'x', {'y': 'c'})`);
+ });
+
+ QUnit.test('DomainInversion constrained_in_inversion', function() {
+ let domain_inversion = new Sao.common.DomainInversion();
+ domain_inversion = domain_inversion.domain_inversion.bind(
+ domain_inversion);
+ let compare = Sao.common.compare;
+
+ let domain = [['x', '=', 3], ['y', 'in', ['a']]];
+ QUnit.assert.ok(
+ compare(domain_inversion(domain, 'x'), [['x', '=', 3]]),
+ `domain_inversion(${domain}, 'x')`);
+ QUnit.assert.ok(
+ compare(domain_inversion(domain, 'x', {'y': 'a'}), [['x', '=',
3]]),
+ `domain_inversion(${domain}, 'x', {'y': 'a'})`);
+ QUnit.assert.ok(
+ compare(domain_inversion(domain, 'x', {'y': 'c'}), [['x', '=',
3]]),
+ `domain_inversion(${domain}, 'x', {'y': 'c'})`);
+ });
+
QUnit.test('DomainInversion and_inversion', function() {
var domain_inversion = new Sao.common.DomainInversion();
domain_inversion = domain_inversion.domain_inversion.bind(
diff -r 191f2e9503a1 -r 13d2279f2154 tryton/tryton/common/domain_inversion.py
--- a/tryton/tryton/common/domain_inversion.py Wed Feb 12 18:59:33 2025 +0100
+++ b/tryton/tryton/common/domain_inversion.py Thu Feb 13 01:02:11 2025 +0100
@@ -79,9 +79,9 @@
and isinstance(expression[1], str))
-def constrained_leaf(part, boolop=operator.and_):
+def constrained_leaf(part):
field, operand, value = part[:3]
- if operand == '=' and boolop == operator.and_:
+ if operand == '=' or (operand == 'in' and len(value) == 1):
# We should consider that other domain inversion will set a correct
# value to this field
return True
@@ -502,7 +502,7 @@
if (field not in context
or field in context
and (eval_leaf(part, context, operator.and_)
- or constrained_leaf(part, operator.and_))):
+ or constrained_leaf(part))):
result.append(True)
else:
return False
@@ -544,8 +544,7 @@
field = part[0]
field = self.base(field)
if (field in context
- and (eval_leaf(part, context, operator.or_)
- or constrained_leaf(part, operator.or_))):
+ and eval_leaf(part, context, operator.or_)):
return True
elif (field in context
and not eval_leaf(part, context, operator.or_)):
diff -r 191f2e9503a1 -r 13d2279f2154 trytond/trytond/tests/test_tools.py
--- a/trytond/trytond/tests/test_tools.py Wed Feb 12 18:59:33 2025 +0100
+++ b/trytond/trytond/tests/test_tools.py Thu Feb 13 01:02:11 2025 +0100
@@ -596,6 +596,39 @@
domain = [['x.id', '>', 5]]
self.assertEqual(domain_inversion(domain, 'x'), [['x.id', '>', 5]])
+ def test_unconstrained_inversion(self):
+ domain = [['x', '=', 3], ['y', 'in', ['a', 'b']]]
+
+ self.assertEqual(domain_inversion(domain, 'x'), [['x', '=', 3]])
+ self.assertEqual(
+ domain_inversion(domain, 'x', {'y': 'a'}),
+ [['x', '=', 3]])
+ self.assertEqual(
+ domain_inversion(domain, 'x', {'y': 'c'}),
+ False)
+
+ def test_constrained_equal_inversion(self):
+ domain = [['x', '=', 3], ['y', '=', 'a']]
+
+ self.assertEqual(domain_inversion(domain, 'x'), [['x', '=', 3]])
+ self.assertEqual(
+ domain_inversion(domain, 'x', {'y': 'a'}),
+ [['x', '=', 3]])
+ self.assertEqual(
+ domain_inversion(domain, 'x', {'y': 'c'}),
+ [['x', '=', 3]])
+
+ def test_constrained_in_inversion(self):
+ domain = [['x', '=', 3], ['y', 'in', ['a']]]
+
+ self.assertEqual(domain_inversion(domain, 'x'), [['x', '=', 3]])
+ self.assertEqual(
+ domain_inversion(domain, 'x', {'y': 'a'}),
+ [['x', '=', 3]])
+ self.assertEqual(
+ domain_inversion(domain, 'x', {'y': 'c'}),
+ [['x', '=', 3]])
+
def test_and_inversion(self):
domain = [['x', '=', 3], ['y', '>', 5]]
self.assertEqual(domain_inversion(domain, 'x'), [['x', '=', 3]])
diff -r 191f2e9503a1 -r 13d2279f2154 trytond/trytond/tools/domain_inversion.py
--- a/trytond/trytond/tools/domain_inversion.py Wed Feb 12 18:59:33 2025 +0100
+++ b/trytond/trytond/tools/domain_inversion.py Thu Feb 13 01:02:11 2025 +0100
@@ -79,9 +79,9 @@
and isinstance(expression[1], str))
-def constrained_leaf(part, boolop=operator.and_):
+def constrained_leaf(part):
field, operand, value = part[:3]
- if operand == '=' and boolop == operator.and_:
+ if operand == '=' or (operand == 'in' and len(value) == 1):
# We should consider that other domain inversion will set a correct
# value to this field
return True
@@ -502,7 +502,7 @@
if (field not in context
or field in context
and (eval_leaf(part, context, operator.and_)
- or constrained_leaf(part, operator.and_))):
+ or constrained_leaf(part))):
result.append(True)
else:
return False
@@ -544,8 +544,7 @@
field = part[0]
field = self.base(field)
if (field in context
- and (eval_leaf(part, context, operator.or_)
- or constrained_leaf(part, operator.or_))):
+ and eval_leaf(part, context, operator.or_)):
return True
elif (field in context
and not eval_leaf(part, context, operator.or_)):