<commit_before>
openerp.web.data = function(openerp) {

/**
 * Serializes the sort criterion array of a dataset into a form which can be
 * consumed by OpenERP's RPC APIs.
 *
 * @param {Array} criterion array of fields, from first to last criteria, prefixed with '-' for reverse sorting
 * @returns {String} SQL-like sorting string (``ORDER BY``) clause
 */
openerp.web.serialize_sort = function (criterion) {
    return _.map(criterion,
        function (criteria) {
            if (criteria[0] === '-') {
                return criteria.slice(1) + ' DESC';
            }
            return criteria + ' ASC';
        }).join(', ');
};

openerp.web.Query = openerp.web.Class.extend({
    init: function (model, fields) {
        this._model = model;
        this._fields = fields;
        this._filter = [];
        this._context = {};
        this._limit = false;
        this._offset = 0;
        this._order_by = [];
    },
    clone: function (to_set) {
        to_set = to_set || {};
        var q = new openerp.web.Query(this._model, this._fields);
        q._context = this._context;
        q._filter = this._filter;
        q._limit = this._limit;
        q._offset = this._offset;
        q._order_by = this._order_by;

        for(var key in to_set) {
            if (!to_set.hasOwnProperty(key)) { continue; }
            switch(key) {
            case 'filter':
                q._filter = new openerp.web.CompoundDomain(
                        q._filter, to_set.filter);
                break;
            case 'context':
                q._context = new openerp.web.CompoundContext(
                        q._context, to_set.context);
                break;
            case 'limit':
            case 'offset':
            case 'order_by':
                q['_' + key] = to_set[key];
            }
        }
        return q;
    },
    _execute: function () {
        var self = this;
        return openerp.connection.rpc('/web/dataset/search_read', {
            model: this._model.name,
            fields: this._fields || false,
            domain: this._model.domain(this._filter),
            context: this._model.context(this._context),
            offset: this._offset,
            limit: this._limit,
            sort: openerp.web.serialize_sort(this._order_by)
        }).pipe(function (results) {
            self._count = results.length;
            return results.records;
        }, null);
    },
    /**
     * Fetches the first record matching the query, or null
     *
     * @returns {jQuery.Deferred<Object|null>}
     */
    first: function () {
        var self = this;
        return this.clone({limit: 1})._execute().pipe(function (records) {
            delete self._count;
            if (records.length) { return records[0]; }
            return null;
        });
    },
    /**
     * Fetches all records matching the query
     *
     * @returns {jQuery.Deferred<Array<>>}
     */
    all: function () {
        return this._execute();
    },
    /**
     * Fetches the number of records matching the query in the database
     *
     * @returns {jQuery.Deferred<Number>}
     */
    count: function () {
        if (this._count) { return $.when(this._count); }
        return this._model.call(
            'search_count', [this._filter], {
                context: this._model.context(this._context)});
    },
    /**
     * Performs a groups read according to the provided grouping criterion
     *
     * @param {String|Array<String>} grouping
     * @returns {jQuery.Deferred<Array<openerp.web.data.Group>> | null}
     */
    group_by: function (grouping) {
        if (grouping === undefined) {
            return null;
        }

        if (!(grouping instanceof Array)) {
            grouping = _.toArray(arguments);
        }
        if (_.isEmpty(grouping)) { return null; }

        var self = this;
        return this._model.call('read_group', {
            groupby: grouping,
            fields: _.uniq(grouping.concat(this._fields || [])),
            domain: this._model.domain(this._filter),
            context: this._model.context(this._context),
            offset: this._offset,
            limit: this._limit,
            orderby: openerp.web.serialize_sort(this._order_by) || false
        }).pipe(function (results) {
            return _(results).map(function (result) {
                return new openerp.web.data.Group(
                    self._model.name, grouping[0], result);
            });
        });
    },
    /**
     * Creates a new query with the union of the current query's context and
     * the new context.
     *
     * @param context context data to add to the query
     * @returns {openerp.web.Query}
     */
    context: function (context) {
        if (!context) { return this; }
        return this.clone({context: context});
    },
    /**
     * Creates a new query with the union of the current query's filter and
     * the new domain.
     *
     * @param domain domain data to AND with the current query filter
     * @returns {openerp.web.Query}
     */
    filter: function (domain) {
        if (!domain) { return this; }
        return this.clone({filter: domain});
    },
    /**
     * Creates a new query with the provided limit replacing the current
     * query's own limit
     *
     * @param {Number} limit maximum number of records the query should retrieve
     * @returns {openerp.web.Query}
     */
    limit: function (limit) {
        return this.clone({limit: limit});
    },
    /**
     * Creates a new query with the provided offset replacing the current
     * query's own offset
     *
     * @param {Number} offset number of records the query should skip before starting its retrieval
     * @returns {openerp.web.Query}
     */
    offset: function (offset) {
        return this.clone({offset: offset});
    },
    /**
     * Creates a new query with the provided ordering parameters replacing
     * those of the current query
     *
     * @param {String...} fields ordering clauses
     * @returns {openerp.web.Query}
     */
    order_by: function (fields) {
        if (!(fields instanceof Array)) {
            fields = _.toArray(arguments);
        }
        if (_.isEmpty(fields)) { return this; }
        return this.clone({order_by: fields});
    }
});

openerp.web.Model = openerp.web.Class.extend(/** @lends openerp.web.Model# */{
    /**
     * @constructs openerp.web.Model
     * @extends openerp.web.Class
     *
     * @param {String} model_name name of the OpenERP model this object is bound to
     * @param {Object} [context]
     * @param {Array} [domain]
     */
    init: function (model_name, context, domain) {
        this.name = model_name;
        this._context = context || {};
        this._domain = domain || [];
    },
    /**
     * @deprecated does not allow to specify kwargs, directly use call() instead
     */
    get_func: function (method_name) {
        var self = this;
        return function () {
            return self.call(method_name, _.toArray(arguments));
        };
    },
    /**
     * Call a method (over RPC) on the bound OpenERP model.
     *
     * @param {String} method name of the method to call
     * @param {Array} [args] positional arguments
     * @param {Object} [kwargs] keyword arguments
     * @returns {jQuery.Deferred<>} call result
     */
    call: function (method, args, kwargs) {
        args = args || [];
        kwargs = kwargs || {};
        if (!_.isArray(args)) {
            // call(method, kwargs)
            kwargs = args;
            args = [];
        }
        return openerp.connection.rpc('/web/dataset/call_kw', {
            model: this.name,
            method: method,
            args: args,
            kwargs: kwargs
        });
    },
    /**
     * Fetches a Query instance bound to this model, for searching
     *
     * @param {Array<String>} [fields] fields to ultimately fetch during the search
     * @returns {openerp.web.Query}
     */
    query: function (fields) {
        return new openerp.web.Query(this, fields);
    },
    /**
     * Executes a signal on the designated workflow, on the bound OpenERP model
     *
     * @param {Number} id workflow identifier
     * @param {String} signal signal to trigger on the workflow
     */
    exec_workflow: function (id, signal) {
        return openerp.connection.rpc('/web/dataset/exec_workflow', {
            model: this.name,
            id: id,
            signal: signal
        });
    },
    /**
     * Fetches the model's domain, combined with the provided domain if any
     *
     * @param {Array} [domain] to combine with the model's internal domain
     * @returns The model's internal domain, or the AND-ed union of the model's internal domain and the provided domain
     */
    domain: function (domain) {
        if (!domain) { return this._domain; }
        return new openerp.web.CompoundDomain(
            this._domain, domain);
    },
    /**
     * Fetches the combination of the user's context and the domain context,
     * combined with the provided context if any
     *
     * @param {Object} [context] to combine with the model's internal context
     * @returns The union of the user's context and the model's internal context, as well as the provided context if any. In that order.
     */
    context: function (context) {
        return new openerp.web.CompoundContext(
            openerp.connection.user_context, this._context, context || {});
    },
    /**
     * Button action caller, needs to perform cleanup if an action is returned
     * from the button (parsing of context and domain, and fixup of the views
     * collection for act_window actions)
     *
     * FIXME: remove when evaluator integrated
     */
    call_button: function (method, args) {
        return this.rpc('/web/dataset/call_button', {
            model: this.model,
            method: method,
            domain_id: null,
            context_id: args.length - 1,
            args: args || []
        });
    },
});

openerp.web.Traverser = openerp.web.Class.extend(/** @lends openerp.web.Traverser# */{
    /**
     * @constructs openerp.web.Traverser
     * @extends openerp.web.Class
     *
     * @param {openerp.web.Model} model instance this traverser is bound to
     */
    init: function (model) {
        this._model = model;
        this._index = 0;<commit_msg>[FIX] call_button implementation in model<commit_after>
openerp.web.data = function(openerp) {

/**
 * Serializes the sort criterion array of a dataset into a form which can be
 * consumed by OpenERP's RPC APIs.
 *
 * @param {Array} criterion array of fields, from first to last criteria, prefixed with '-' for reverse sorting
 * @returns {String} SQL-like sorting string (``ORDER BY``) clause
 */
openerp.web.serialize_sort = function (criterion) {
    return _.map(criterion,
        function (criteria) {
            if (criteria[0] === '-') {
                return criteria.slice(1) + ' DESC';
            }
            return criteria + ' ASC';
        }).join(', ');
};

openerp.web.Query = openerp.web.Class.extend({
    init: function (model, fields) {
        this._model = model;
        this._fields = fields;
        this._filter = [];
        this._context = {};
        this._limit = false;
        this._offset = 0;
        this._order_by = [];
    },
    clone: function (to_set) {
        to_set = to_set || {};
        var q = new openerp.web.Query(this._model, this._fields);
        q._context = this._context;
        q._filter = this._filter;
        q._limit = this._limit;
        q._offset = this._offset;
        q._order_by = this._order_by;

        for(var key in to_set) {
            if (!to_set.hasOwnProperty(key)) { continue; }
            switch(key) {
            case 'filter':
                q._filter = new openerp.web.CompoundDomain(
                        q._filter, to_set.filter);
                break;
            case 'context':
                q._context = new openerp.web.CompoundContext(
                        q._context, to_set.context);
                break;
            case 'limit':
            case 'offset':
            case 'order_by':
                q['_' + key] = to_set[key];
            }
        }
        return q;
    },
    _execute: function () {
        var self = this;
        return openerp.connection.rpc('/web/dataset/search_read', {
            model: this._model.name,
            fields: this._fields || false,
            domain: this._model.domain(this._filter),
            context: this._model.context(this._context),
            offset: this._offset,
            limit: this._limit,
            sort: openerp.web.serialize_sort(this._order_by)
        }).pipe(function (results) {
            self._count = results.length;
            return results.records;
        }, null);
    },
    /**
     * Fetches the first record matching the query, or null
     *
     * @returns {jQuery.Deferred<Object|null>}
     */
    first: function () {
        var self = this;
        return this.clone({limit: 1})._execute().pipe(function (records) {
            delete self._count;
            if (records.length) { return records[0]; }
            return null;
        });
    },
    /**
     * Fetches all records matching the query
     *
     * @returns {jQuery.Deferred<Array<>>}
     */
    all: function () {
        return this._execute();
    },
    /**
     * Fetches the number of records matching the query in the database
     *
     * @returns {jQuery.Deferred<Number>}
     */
    count: function () {
        if (this._count) { return $.when(this._count); }
        return this._model.call(
            'search_count', [this._filter], {
                context: this._model.context(this._context)});
    },
    /**
     * Performs a groups read according to the provided grouping criterion
     *
     * @param {String|Array<String>} grouping
     * @returns {jQuery.Deferred<Array<openerp.web.data.Group>> | null}
     */
    group_by: function (grouping) {
        if (grouping === undefined) {
            return null;
        }

        if (!(grouping instanceof Array)) {
            grouping = _.toArray(arguments);
        }
        if (_.isEmpty(grouping)) { return null; }

        var self = this;
        return this._model.call('read_group', {
            groupby: grouping,
            fields: _.uniq(grouping.concat(this._fields || [])),
            domain: this._model.domain(this._filter),
            context: this._model.context(this._context),
            offset: this._offset,
            limit: this._limit,
            orderby: openerp.web.serialize_sort(this._order_by) || false
        }).pipe(function (results) {
            return _(results).map(function (result) {
                return new openerp.web.data.Group(
                    self._model.name, grouping[0], result);
            });
        });
    },
    /**
     * Creates a new query with the union of the current query's context and
     * the new context.
     *
     * @param context context data to add to the query
     * @returns {openerp.web.Query}
     */
    context: function (context) {
        if (!context) { return this; }
        return this.clone({context: context});
    },
    /**
     * Creates a new query with the union of the current query's filter and
     * the new domain.
     *
     * @param domain domain data to AND with the current query filter
     * @returns {openerp.web.Query}
     */
    filter: function (domain) {
        if (!domain) { return this; }
        return this.clone({filter: domain});
    },
    /**
     * Creates a new query with the provided limit replacing the current
     * query's own limit
     *
     * @param {Number} limit maximum number of records the query should retrieve
     * @returns {openerp.web.Query}
     */
    limit: function (limit) {
        return this.clone({limit: limit});
    },
    /**
     * Creates a new query with the provided offset replacing the current
     * query's own offset
     *
     * @param {Number} offset number of records the query should skip before starting its retrieval
     * @returns {openerp.web.Query}
     */
    offset: function (offset) {
        return this.clone({offset: offset});
    },
    /**
     * Creates a new query with the provided ordering parameters replacing
     * those of the current query
     *
     * @param {String...} fields ordering clauses
     * @returns {openerp.web.Query}
     */
    order_by: function (fields) {
        if (!(fields instanceof Array)) {
            fields = _.toArray(arguments);
        }
        if (_.isEmpty(fields)) { return this; }
        return this.clone({order_by: fields});
    }
});

openerp.web.Model = openerp.web.Class.extend(/** @lends openerp.web.Model# */{
    /**
     * @constructs openerp.web.Model
     * @extends openerp.web.Class
     *
     * @param {String} model_name name of the OpenERP model this object is bound to
     * @param {Object} [context]
     * @param {Array} [domain]
     */
    init: function (model_name, context, domain) {
        this.name = model_name;
        this._context = context || {};
        this._domain = domain || [];
    },
    /**
     * @deprecated does not allow to specify kwargs, directly use call() instead
     */
    get_func: function (method_name) {
        var self = this;
        return function () {
            return self.call(method_name, _.toArray(arguments));
        };
    },
    /**
     * Call a method (over RPC) on the bound OpenERP model.
     *
     * @param {String} method name of the method to call
     * @param {Array} [args] positional arguments
     * @param {Object} [kwargs] keyword arguments
     * @returns {jQuery.Deferred<>} call result
     */
    call: function (method, args, kwargs) {
        args = args || [];
        kwargs = kwargs || {};
        if (!_.isArray(args)) {
            // call(method, kwargs)
            kwargs = args;
            args = [];
        }
        return openerp.connection.rpc('/web/dataset/call_kw', {
            model: this.name,
            method: method,
            args: args,
            kwargs: kwargs
        });
    },
    /**
     * Fetches a Query instance bound to this model, for searching
     *
     * @param {Array<String>} [fields] fields to ultimately fetch during the search
     * @returns {openerp.web.Query}
     */
    query: function (fields) {
        return new openerp.web.Query(this, fields);
    },
    /**
     * Executes a signal on the designated workflow, on the bound OpenERP model
     *
     * @param {Number} id workflow identifier
     * @param {String} signal signal to trigger on the workflow
     */
    exec_workflow: function (id, signal) {
        return openerp.connection.rpc('/web/dataset/exec_workflow', {
            model: this.name,
            id: id,
            signal: signal
        });
    },
    /**
     * Fetches the model's domain, combined with the provided domain if any
     *
     * @param {Array} [domain] to combine with the model's internal domain
     * @returns The model's internal domain, or the AND-ed union of the model's internal domain and the provided domain
     */
    domain: function (domain) {
        if (!domain) { return this._domain; }
        return new openerp.web.CompoundDomain(
            this._domain, domain);
    },
    /**
     * Fetches the combination of the user's context and the domain context,
     * combined with the provided context if any
     *
     * @param {Object} [context] to combine with the model's internal context
     * @returns The union of the user's context and the model's internal context, as well as the provided context if any. In that order.
     */
    context: function (context) {
        return new openerp.web.CompoundContext(
            openerp.connection.user_context, this._context, context || {});
    },
    /**
     * Button action caller, needs to perform cleanup if an action is returned
     * from the button (parsing of context and domain, and fixup of the views
     * collection for act_window actions)
     *
     * FIXME: remove when evaluator integrated
     */
    call_button: function (method, args) {
        return openerp.connection.rpc('/web/dataset/call_button', {
            model: this.name,
            method: method,
            domain_id: null,
            context_id: args.length - 1,
            args: args || []
        });
    },
});

openerp.web.Traverser = openerp.web.Class.extend(/** @lends openerp.web.Traverser# */{
    /**
     * @constructs openerp.web.Traverser
     * @extends openerp.web.Class
     *
     * @param {openerp.web.Model} model instance this traverser is bound to
     */
    init: function (model) {
        this._model = model;
        this._index = 0;
{'fraction_non_alphanumeric': 0.11820410517713792, 'fraction_numerical': 0.0007691198384848339, 'mean_word_length': 1.9459076748796376, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3929415', 'n_tokens_mistral': 5901, 'n_tokens_neox': 5769, 'n_words': 1699}