diff options
| author | Christophe Matthieu <chm@odoo.com> | 2018-07-11 13:27:30 +0200 |
|---|---|---|
| committer | Christophe Matthieu <chm@odoo.com> | 2018-08-13 17:09:28 +0200 |
| commit | 6ca026119e918e5de19316c71ab50b4034dd6f99 (patch) | |
| tree | 9f659b95b2d24f13d4a2208171fb7967d4d2cd49 /addons/web/static/src/js/core/domain.js | |
| parent | cad272d5b62a0769703f825a569dd360b2bf074a (diff) | |
[IMP] web: add method to convert JS domain into python condition
Diffstat (limited to 'addons/web/static/src/js/core/domain.js')
| -rw-r--r-- | addons/web/static/src/js/core/domain.js | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/addons/web/static/src/js/core/domain.js b/addons/web/static/src/js/core/domain.js index e8f089dca76..c4011b049b9 100644 --- a/addons/web/static/src/js/core/domain.js +++ b/addons/web/static/src/js/core/domain.js @@ -3,6 +3,7 @@ odoo.define("web.Domain", function (require) { var collections = require("web.collections"); var pyUtils = require("web.py_utils"); +var py = window.py; // look py.js /** * The Domain Class allows to work with a domain as a tree and provides tools @@ -346,6 +347,117 @@ var Domain = collections.Tree.extend({ } return domain; }, + /** + * Converts JS prefix-array representation of a domain to a python condition + * + * @static + * @param {Array} domain + * @returns {string} + */ + domainToCondition: function (domain) { + if (!domain.length) { + return 'True'; + } + var self = this; + function consume(stack) { + var len = stack.length; + if (len <= 1) { + return stack; + } else if (stack[len-1] === '|' || stack[len-1] === '&' || stack[len-2] === '|' || stack[len-2] === '&') { + return stack; + } else if (len == 2) { + stack.splice(-2, 2, stack[len-2] + ' and ' + stack[len-1]); + } else if (stack[len-3] == '|') { + if (len === 3) { + stack.splice(-3, 3, stack[len-2] + ' or ' + stack[len-1]); + } else { + stack.splice(-3, 3, '(' + stack[len-2] + ' or ' + stack[len-1] + ')'); + } + } else { + stack.splice(-3, 3, stack[len-2] + ' and ' + stack[len-1]); + } + consume(stack); + } + + var stack = []; + _.each(domain, function (dom) { + if (dom === '|' || dom === '&') { + stack.push(dom); + } else { + var operator = dom[1] === '=' ? '==' : dom[1]; + if (!operator) { + throw new Error('Wrong operator for this domain'); + } + if (operator === '!=' && dom[2] === false) { // the field is set + stack.push(dom[0]); + } else if (dom[2] === null || dom[2] === true || dom[2] === false) { + stack.push(dom[0] + ' ' + (operator === '!=' ? 'is not ' : 'is ') + (dom[2] === null ? 'None' : (dom[2] ? 'True' : 'False'))); + } else { + stack.push(dom[0] + ' ' + operator + ' ' + JSON.stringify(dom[2])); + } + consume(stack); + } + }); + + if (stack.length !== 1) { + throw new Error('Wrong domain'); + } + + return stack[0]; + }, + /** + * Converts python condition to a JS prefix-array representation of a domain + * + * @static + * @param {string} domain + * @returns {Array} + */ + conditionToDomain: function (condition) { + if (!condition || condition.match(/^\s*(True)?\s*$/)) { + return []; + } + + var ast = py.parse(py.tokenize(condition)); + + + function astToStackValue (node) { + switch (node.id) { + case '(name)': return node.value; + case '.': return astToStackValue(node.first) + '.' + astToStackValue(node.second); + case '(string)': return node.value; + case '(number)': return node.value; + case '(constant)': return node.value === 'None' ? null : node.value === 'True' ? true : false; + case '[': return _.map(node.first, function (node) {return astToStackValue(node);}); + } + } + function astToStack (node) { + switch (node.id) { + case '(name)': return [[astToStackValue(node), '!=', false]]; + case '.': return [[astToStackValue(node.first) + '.' + astToStackValue(node.second), '!=', false]]; + case 'not': return [[astToStackValue(node.first), '=', false]]; + + case 'or': return ['|'].concat(astToStack(node.first)).concat(astToStack(node.second)); + case 'and': return ['&'].concat(astToStack(node.first)).concat(astToStack(node.second)); + case '(comparator)': + if (node.operators.length !== 1) { + throw new Error('Wrong condition to convert in domain'); + } + var right = astToStackValue(node.expressions[0]); + var left = astToStackValue(node.expressions[1]); + var operator = node.operators[0]; + switch (operator) { + case 'is': operator = '='; break; + case 'is not': operator = '!='; break; + case '==': operator = '='; break; + } + return [[right, operator, left]]; + default: + throw "Condition cannot be transformed into domain"; + } + } + + return astToStack(ast); + }, }); return Domain; |
