changeset 96c7d07a3eed in sao:5.0
details: https://hg.tryton.org/sao?cmd=changeset&node=96c7d07a3eed
description:
        Use specific search domain for reference field searches

        issue9997
        review324781002
        (grafted from eab0883326841dcaa1770e3c7d2aaeda27edb28b)
diffstat:

 src/common.js |  105 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 src/model.js  |    6 ++-
 tests/sao.js  |   58 +++++++++++++++++++++++++++++--
 3 files changed, 151 insertions(+), 18 deletions(-)

diffs (217 lines):

diff -r ca080990835a -r 96c7d07a3eed src/common.js
--- a/src/common.js     Fri Apr 16 19:07:33 2021 +0200
+++ b/src/common.js     Mon Apr 12 20:54:03 2021 +0200
@@ -2269,23 +2269,104 @@
             }
         },
         prepare_reference_domain: function(domain, reference) {
+
+            var value2reference = function(value) {
+                var model = null;
+                var ref_id = null;
+                if ((typeof(value) == 'string') && value.contains(',')) {
+                    var split = value.split(',');
+                    var result = split.splice(0, 1);
+                    result.push(split.join(','));
+                    model = result[0];
+                    ref_id = result[1];
+                    if (ref_id != '%') {
+                        ref_id = parseInt(ref_id, 10);
+                        if (isNaN(ref_id)) {
+                            model = null;
+                            ref_id = value;
+                        }
+                    }
+                } else if ((value instanceof Array) &&
+                        (value.length == 2) &&
+                        (typeof(value[0]) == 'string') &&
+                        ((typeof(value[1]) == 'number') ||
+                            (value[1] == '%'))) {
+                    model = value[0];
+                    ref_id = value[1];
+                } else {
+                    ref_id = value;
+                }
+                return [model, ref_id];
+            };
+
             if (~['AND', 'OR'].indexOf(domain)) {
                 return domain;
             } else if (this.is_leaf(domain)) {
-                if ((domain[0].split('.').length > 1) &&
-                        (domain.length > 3)) {
-                    var parts = domain[0].split('.');
-                    var local_name = parts[0];
-                    var target_name = parts.slice(1).join('.');
+                if (domain[0] == reference) {
+                    var model, ref_id, splitted;
+                    if ((domain[1] == '=') || (domain[1] ==  '!=')) {
+                        splitted = value2reference(domain[2]);
+                        model = splitted[0];
+                        ref_id = splitted[1];
+                        if (model) {
+                            if (ref_id == '%') {
+                                if (domain[1] == '=') {
+                                    return [
+                                        reference + '.id', '!=', null, model];
+                                } else {
+                                    return [reference, 'not like', domain[2]];
+                                }
+                            }
+                            return [
+                                reference + '.id', domain[1], ref_id, model];
+                        }
+                    } else if ((domain[1] == 'in') || (domain[1] == 'not in')) 
{
+                        var model_values = {};
+                        var break_p = false;
+                        for (var i=0; i < domain[2].length; i++) {
+                            splitted = value2reference(domain[2][i]);
+                            model = splitted[0];
+                            ref_id = splitted[1];
+                            if (!model) {
+                                break_p = true;
+                                break;
+                            }
+                            if (!(model in model_values)) {
+                                model_values[model] = [];
+                            }
+                            model_values[model].push(ref_id);
+                        }
 
-                    if (local_name == reference) {
-                        var where = [];
-                        where.push(target_name);
-                        where = where.concat(
-                            domain.slice(1, 3), domain.slice(4));
-                        return where;
+                        if (!break_p) {
+                            var ref_ids;
+                            var new_domain;
+                            if (domain[1] == 'in') {
+                                new_domain = ['OR'];
+                            } else {
+                                new_domain = ['AND'];
+                            }
+                            for (model in model_values) {
+                                ref_ids = model_values[model];
+                                if (~ref_ids.indexOf('%')) {
+                                    if (domain[1] == 'in') {
+                                        new_domain.push(
+                                            [reference + '.id', '!=', null,
+                                                model]);
+                                    } else {
+                                        new_domain.push(
+                                            [reference, 'not like',
+                                                model + ',%']);
+                                    }
+                                } else {
+                                    new_domain.push(
+                                        [reference + '.id', domain[1],
+                                            ref_ids.map(Number), model]);
+                                }
+                            }
+                            return new_domain;
+                        }
                     }
-                    return domain;
+                    return [];
                 }
                 return domain;
             } else {
diff -r ca080990835a -r 96c7d07a3eed src/model.js
--- a/src/model.js      Fri Apr 16 19:07:33 2021 +0200
+++ b/src/model.js      Mon Apr 12 20:54:03 2021 +0200
@@ -2480,14 +2480,16 @@
             screen_domain = inversion.prepare_reference_domain(
                 screen_domain, this.name);
             return inversion.concat([
-                inversion.localize_domain(screen_domain, undefined, true),
+                inversion.localize_domain(screen_domain, this.name, true),
                 attr_domain]);
         },
         get_models: function(record) {
             var domains = this.get_domains(record);
             var inversion = new Sao.common.DomainInversion();
+            var screen_domain = inversion.prepare_reference_domain(
+                domains[0], this.name);
             return inversion.extract_reference_models(
-                inversion.concat([domains[0], domains[1]]),
+                inversion.concat([screen_domain, domains[1]]),
                 this.name);
         },
         _is_empty: function(record) {
diff -r ca080990835a -r 96c7d07a3eed tests/sao.js
--- a/tests/sao.js      Fri Apr 16 19:07:33 2021 +0200
+++ b/tests/sao.js      Mon Apr 12 20:54:03 2021 +0200
@@ -2445,17 +2445,67 @@
         var domain = [['x', 'like', 'A%']];
         QUnit.ok(compare(
             prepare_reference_domain(domain, 'x'),
-            [['x', 'like', 'A%']]));
+            [[]]));
+
+        domain = [['x', '=', 'A']];
+        QUnit.ok(compare(
+            prepare_reference_domain(domain, 'x'),
+            [[]]));
+
+        domain = [['x.y', 'child_of', [1], 'model', 'parent']];
+        QUnit.ok(compare(
+            prepare_reference_domain(domain, 'x'),
+            [['x.y', 'child_of', [1], 'model', 'parent']]));
 
         domain = [['x.y', 'like', 'A%', 'model']];
         QUnit.ok(compare(
             prepare_reference_domain(domain, 'x'),
-            [['y', 'like', 'A%']]));
+            [['x.y', 'like', 'A%', 'model']]));
+
+        domain = [['x', '=', 'model,1']];
+        QUnit.ok(compare(
+            prepare_reference_domain(domain, 'x'),
+            [['x.id', '=', 1, 'model']]));
 
-        domain = [['x.y', 'child_of', [1], 'model', 'parent']];
+        domain = [['x', '!=', 'model,1']];
+        QUnit.ok(compare(
+            prepare_reference_domain(domain, 'x'),
+            [['x.id', '!=', 1, 'model']]));
+
+        domain = [['x', '=', 'model,%']];
+        QUnit.ok(compare(
+            prepare_reference_domain(domain, 'x'),
+            [['x.id', '!=', null, 'model']]));
+
+        domain = [['x', '!=', 'model,%']];
         QUnit.ok(compare(
             prepare_reference_domain(domain, 'x'),
-            [['y', 'child_of', [1], 'parent']]));
+            [['x', 'not like', 'model,%']]));
+
+        domain = [['x', 'in',
+            ['model_a,1', 'model_b,%', 'model_c,3', 'model_a,2']]];
+        QUnit.ok(compare(
+            prepare_reference_domain(domain, 'x'),
+            [['OR',
+                ['x.id', 'in', [1, 2], 'model_a'],
+                ['x.id', '!=', null, 'model_b'],
+                ['x.id', 'in', [3], 'model_c'],
+                ]]));
+
+        domain = [['x', 'not in',
+            ['model_a,1', 'model_b,%', 'model_c,3', 'model_a,2']]];
+        QUnit.ok(compare(
+            prepare_reference_domain(domain, 'x'),
+            [['AND',
+                ['x.id', 'not in', [1, 2], 'model_a'],
+                ['x', 'not like', 'model_b,%'],
+                ['x.id', 'not in', [3], 'model_c'],
+                ]]));
+
+        domain = [['x', 'in', ['model_a,1', 'foo']]];
+        QUnit.ok(compare(
+            prepare_reference_domain(domain, 'x'),
+            [[]]));
     });
 
     QUnit.test('DomainInversion.extract_reference_models', function() {

Reply via email to