summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/core/rpc.js
blob: e0d33355001077d9c9f76761d81cc2f7108871f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
odoo.define('web.rpc', function (require) {
"use strict";

var ajax = require('web.ajax');

const rpc = {
    /**
     * Perform a RPC.  Please note that this is not the preferred way to do a
     * rpc if you are in the context of a widget.  In that case, you should use
     * the this._rpc method.
     *
     * @param {Object} params @see buildQuery for a description
     * @param {Object} options
     * @returns {Promise<any>}
     */
    query: function (params, options) {
        var query = rpc.buildQuery(params);
        return ajax.rpc(query.route, query.params, options);
    },
    /**
     * @param {Object} options
     * @param {any[]} [options.args]
     * @param {Object} [options.context]
     * @param {any[]} [options.domain]
     * @param {string[]} [options.fields]
     * @param {string[]} [options.groupBy]
     * @param {Object} [options.kwargs]
     * @param {integer|false} [options.limit]
     * @param {string} [options.method]
     * @param {string} [options.model]
     * @param {integer} [options.offset]
     * @param {string[]} [options.orderBy]
     * @param {Object} [options.params]
     * @param {string} [options.route]
     * @returns {Object} with 2 keys: route and params
     */
    buildQuery: function (options) {
        var route;
        var params = options.params || {};
        var orderBy;
        if (options.route) {
            route = options.route;
        } else if (options.model && options.method) {
            route = '/web/dataset/call_kw/' + options.model + '/' + options.method;
        }
        if (options.method) {
            params.args = options.args || [];
            params.model = options.model;
            params.method = options.method;
            params.kwargs = _.extend(params.kwargs || {}, options.kwargs);
            params.kwargs.context = options.context || params.context || params.kwargs.context;
        }

        if (options.method === 'read_group' || options.method === 'web_read_group') {
            if (!(params.args && params.args[0] !== undefined)) {
                params.kwargs.domain = options.domain || params.domain || params.kwargs.domain || [];
            }
            if (!(params.args && params.args[1] !== undefined)) {
                params.kwargs.fields = options.fields || params.fields || params.kwargs.fields || [];
            }
            if (!(params.args && params.args[2] !== undefined)) {
                params.kwargs.groupby = options.groupBy || params.groupBy || params.kwargs.groupby || [];
            }
            params.kwargs.offset = options.offset || params.offset || params.kwargs.offset;
            params.kwargs.limit = options.limit || params.limit || params.kwargs.limit;
            // In kwargs, we look for "orderby" rather than "orderBy" (note the absence of capital B),
            // since the Python argument to the actual function is "orderby".
            orderBy = options.orderBy || params.orderBy || params.kwargs.orderby;
            params.kwargs.orderby = orderBy ? rpc._serializeSort(orderBy) : orderBy;
            params.kwargs.lazy = 'lazy' in options ? options.lazy : params.lazy;

            if (options.method === 'web_read_group') {
                params.kwargs.expand = options.expand || params.expand || params.kwargs.expand;
                params.kwargs.expand_limit = options.expand_limit || params.expand_limit || params.kwargs.expand_limit;
                var expandOrderBy = options.expand_orderby || params.expand_orderby || params.kwargs.expand_orderby;
                params.kwargs.expand_orderby = expandOrderBy ? rpc._serializeSort(expandOrderBy) : expandOrderBy;
            }
        }

        if (options.method === 'search_read') {
            // call the model method
            params.kwargs.domain = options.domain || params.domain || params.kwargs.domain;
            params.kwargs.fields = options.fields || params.fields || params.kwargs.fields;
            params.kwargs.offset = options.offset || params.offset || params.kwargs.offset;
            params.kwargs.limit = options.limit || params.limit || params.kwargs.limit;
            // In kwargs, we look for "order" rather than "orderBy" since the Python
            // argument to the actual function is "order".
            orderBy = options.orderBy || params.orderBy || params.kwargs.order;
            params.kwargs.order = orderBy ? rpc._serializeSort(orderBy) : orderBy;
        }

        if (options.route === '/web/dataset/search_read') {
            // specifically call the controller
            params.model = options.model || params.model;
            params.domain = options.domain || params.domain;
            params.fields = options.fields || params.fields;
            params.limit = options.limit || params.limit;
            params.offset = options.offset || params.offset;
            orderBy = options.orderBy || params.orderBy;
            params.sort = orderBy ? rpc._serializeSort(orderBy) : orderBy;
            params.context = options.context || params.context || {};
        }

        return {
            route: route,
            params: JSON.parse(JSON.stringify(params)),
        };
    },
    /**
     * Helper method, generates a string to describe a ordered by sequence for
     * SQL.
     *
     * For example, [{name: 'foo'}, {name: 'bar', asc: false}] will
     * be converted into 'foo ASC, bar DESC'
     *
     * @param {Object[]} orderBy list of objects {name:..., [asc: ...]}
     * @returns {string}
     */
    _serializeSort: function (orderBy) {
        return _.map(orderBy, function (order) {
            return order.name + (order.asc !== false ? ' ASC' : ' DESC');
        }).join(', ');
    },
};

return rpc;

});