From f8f7018ccd540add723b6b44dac7431e7c89cabb Mon Sep 17 00:00:00 2001 From: Holger Brunn Date: Wed, 16 Jul 2014 13:42:11 +0200 Subject: [PATCH] [ADD] web_compute_domain_x2many --- web_compute_domain_x2many/__init__.py | 20 +++ web_compute_domain_x2many/__openerp__.py | 58 ++++++ .../static/src/img/icon.png | Bin 0 -> 7939 bytes .../src/js/web_compute_domain_x2many.js | 167 ++++++++++++++++++ .../static/test/web_compute_domain_x2many.js | 106 +++++++++++ 5 files changed, 351 insertions(+) create mode 100644 web_compute_domain_x2many/__init__.py create mode 100644 web_compute_domain_x2many/__openerp__.py create mode 100644 web_compute_domain_x2many/static/src/img/icon.png create mode 100644 web_compute_domain_x2many/static/src/js/web_compute_domain_x2many.js create mode 100644 web_compute_domain_x2many/static/test/web_compute_domain_x2many.js diff --git a/web_compute_domain_x2many/__init__.py b/web_compute_domain_x2many/__init__.py new file mode 100644 index 00000000..9dd152f9 --- /dev/null +++ b/web_compute_domain_x2many/__init__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2014 Therp BV (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## diff --git a/web_compute_domain_x2many/__openerp__.py b/web_compute_domain_x2many/__openerp__.py new file mode 100644 index 00000000..b5ec7e14 --- /dev/null +++ b/web_compute_domain_x2many/__openerp__.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2014 Therp BV (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## +{ + "name": "Compute client-side domains on x2many fields correctly", + "version": "1.0", + "author": "Therp BV", + "license": "AGPL-3", + "complexity": "normal", + "description": """ +When using ``attrs="..."``, evaluation of x2many fields nearly always goes +wrong in ways not to be expected when being used to server side domains in +Model.search(). + +This addon fixes those cases while keeping backwards compatibility for cases +where you might have checks in a somewhat hacky way, ie. ``attrs="{'invisible': +[('category_id', '=', [[6, False, []]])]}"``. + """, + "category": "Dependency", + "depends": [ + 'web', + ], + "data": [ + ], + "js": [ + 'static/src/js/web_compute_domain_x2many.js', + ], + "css": [ + ], + "qweb": [ + ], + "test": [ + 'static/test/web_compute_domain_x2many.js', + ], + "auto_install": False, + "installable": True, + "application": False, + "external_dependencies": { + 'python': [], + }, +} diff --git a/web_compute_domain_x2many/static/src/img/icon.png b/web_compute_domain_x2many/static/src/img/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f1006195e0220e5b38e4a1b8f17870ec9359f7bb GIT binary patch literal 7939 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 literal 0 HcmV?d00001 diff --git a/web_compute_domain_x2many/static/src/js/web_compute_domain_x2many.js b/web_compute_domain_x2many/static/src/js/web_compute_domain_x2many.js new file mode 100644 index 00000000..27f14f34 --- /dev/null +++ b/web_compute_domain_x2many/static/src/js/web_compute_domain_x2many.js @@ -0,0 +1,167 @@ +//-*- coding: utf-8 -*- +//############################################################################ +// +// OpenERP, Open Source Management Solution +// This module copyright (C) 2014 Therp BV (). +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +//############################################################################ + +openerp.web_compute_domain_x2many = function(instance) +{ + var _t = instance.web._t; + + function find_in_commands(commands, id) + //check if a list of commands contains an id in a way that it will be + //contained after the command list is evaluated + { + return _.reduce( + _.map( + commands, + function(command) + { + switch(command[0]) + { + case 1: + case 4: + return 1; + case 2: + case 3: + case 5: + return -1 + case 6: + return _(command[2]).contains(id); + default: + return 0; + } + } + ), + function(a, b) {return a + b}, + 0 + ) > 0; + } + var comparators = { + scalar: function(field_value, op, val, field) + { + switch (op.toLowerCase()) { + case '=': + case '==': + return _.isEqual(field_value, val); + case '!=': + case '<>': + return !_.isEqual(field_value, val); + case '<': + return field_value < val; + case '>': + return field_value > val; + case '<=': + return field_value <= val; + case '>=': + return field_value >= val; + case 'in': + if (!_.isArray(val)) val = [val]; + return _(val).contains(field_value); + case 'not in': + if (!_.isArray(val)) val = [val]; + return !_(val).contains(field_value); + default: + console.warn( + _t("Unsupported operator %s in domain %s"), + op, JSON.stringify(expr)); + return true; + } + }, + one2many: function(field_value, op, val, field) + { + switch(op.toLowerCase()) + { + case '=': + case '==': + if(!_.isArray(val)) + { + return find_in_commands(field_value, val); + } + else + { + return comparators.scalar(field_value, op, val, field); + } + case '!=': + case '<>': + return !comparators.one2many(field_value, '=', val, field); + case 'in': + var found = false; + _.each(val, function(v) + { + found |= find_in_commands(field_value, v); + }); + return found; + case 'not in': + return !comparators.one2many(field_value, 'in', val, field); + default: + return comparators.scalar(field_value, op, val, field); + } + }, + many2many: function() + { + return comparators.one2many.apply(this, arguments);; + }, + }; + //start OpenERP compute_domain from web/static/src/view_form.js + instance.web.form.compute_domain = function(expr, fields) { + if (! (expr instanceof Array)) + return !! expr; + var stack = []; + for (var i = expr.length - 1; i >= 0; i--) { + var ex = expr[i]; + if (ex.length == 1) { + var top = stack.pop(); + switch (ex) { + case '|': + stack.push(stack.pop() || top); + continue; + case '&': + stack.push(stack.pop() && top); + continue; + case '!': + stack.push(!top); + continue; + default: + throw new Error(_.str.sprintf( + _t("Unknown operator %s in domain %s"), + ex, JSON.stringify(expr))); + } + } + + var field = fields[ex[0]]; + if (!field) { + throw new Error(_.str.sprintf( + _t("Unknown field %s in domain %s"), + ex[0], JSON.stringify(expr))); + } + var field_value = field.get_value ? field.get_value() : field.value; + var op = ex[1]; + var val = ex[2]; + //begin local changes + var field_type = field.field ? field.field.type : 'scalar'; + var comparator = comparators[field_type] ? comparators[field_type] : comparators.scalar; + stack.push(comparator(field_value, op, val, field)); + //end local changes + } + return _.all(stack, _.identity); + }; + //end OpenERP compute_domain + + instance.web_compute_domain_x2many.comparators = comparators; +} diff --git a/web_compute_domain_x2many/static/test/web_compute_domain_x2many.js b/web_compute_domain_x2many/static/test/web_compute_domain_x2many.js new file mode 100644 index 00000000..50213f25 --- /dev/null +++ b/web_compute_domain_x2many/static/test/web_compute_domain_x2many.js @@ -0,0 +1,106 @@ +//-*- coding: utf-8 -*- +//############################################################################ +// +// OpenERP, Open Source Management Solution +// This module copyright (C) 2014 Therp BV (). +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// +//############################################################################ + +openerp.testing.section( + 'web_compute_domain_x2many', + function(test) + { + //start OpenERP core tests from web/static/test/form.js + test("basic", function (instance) { + var fields = { + 'a': {value: 3}, + 'group_method': {value: 'line'}, + 'select1': {value: 'day'}, + 'rrule_type': {value: 'monthly'} + }; + ok(instance.web.form.compute_domain( + [['a', '=', 3]], fields)); + ok(instance.web.form.compute_domain( + [['group_method','!=','count']], fields)); + ok(instance.web.form.compute_domain( + [['select1','=','day'], ['rrule_type','=','monthly']], fields)); + }); + test("or", function (instance) { + var web = { + 'section_id': {value: null}, + 'user_id': {value: null}, + 'member_ids': {value: null} + }; + + var domain = ['|', ['section_id', '=', 42], + '|', ['user_id','=',3], + ['member_ids', 'in', [3]]]; + + ok(instance.web.form.compute_domain(domain, _.extend( + {}, web, {'section_id': {value: 42}}))); + ok(instance.web.form.compute_domain(domain, _.extend( + {}, web, {'user_id': {value: 3}}))); + + ok(instance.web.form.compute_domain(domain, _.extend( + {}, web, {'member_ids': {value: 3}}))); + }); + test("not", function (instance) { + var fields = { + 'a': {value: 5}, + 'group_method': {value: 'line'} + }; + ok(instance.web.form.compute_domain( + ['!', ['a', '=', 3]], fields)); + ok(instance.web.form.compute_domain( + ['!', ['group_method','=','count']], fields)); + }); + //end OpenERP core tests + var fields = { + one2many_empty: {value: [], field: {type: 'one2many'}}, + one2many_one_entry: {value: [[4, 42, false]], field: {type: 'one2many'}}, + one2many_multiple_entries: {value: [[4, 42, false], [4, 43, false]], field: {type: 'one2many'}}, + many2many_empty: {value: [[6, false, []]], field: {type: 'many2many'}}, + many2many_one_entry: {value: [[6, false, [42]]], field: {type: 'many2many'}}, + many2many_multiple_entries: {value: [[6, false, [42, 43]]], field: {type: 'many2many'}}, + }; + test('legacy behavior', function(instance) + { + var eval = function(expression, fields) + { + expression = instance.web.pyeval.eval('domain', expression, {}, {}); + return instance.web.form.compute_domain(expression, fields) + } + ok(eval("[('one2many_empty', '=', [])]", fields), 'empty one2many'); + ok(eval("[('many2many_empty', '=', [[6, False, []]])]", fields), 'empty many2many'); + }); + test('x2many tests', function(instance) + { + var eval = function(expression, fields) + { + expression = instance.web.pyeval.eval('domain', expression, {}, {}); + return instance.web.form.compute_domain(expression, fields) + } + ok(!eval("[('one2many_empty', '=', 42)]", fields), 'empty one2many == value'); + ok(eval("[('one2many_one_entry', '=', 42)]", fields), 'one2many with one entry == value'); + ok(eval("[('one2many_multiple_entries', '=', 42)]", fields), 'one2many with multiple entries == value'); + ok(eval("[('one2many_multiple_entries', 'in', [42])]", fields), 'one2many with multiple entries in [value]'); + ok(!eval("[('many2many_empty', '=', 42)]", fields), 'empty many2many == value'); + ok(eval("[('many2many_one_entry', '=', 42)]", fields), 'many2many with one entry == value'); + ok(eval("[('many2many_multiple_entries', '=', 42)]", fields), 'many2many with multiple entries == value'); + ok(eval("[('many2many_multiple_entries', 'in', [42])]", fields), 'many2many with multiple entries in [value]'); + ok(eval("[('many2many_multiple_entries', 'not in', [44])]", fields), 'many2many with multiple entries not in [value]'); + }); + });