[FIX] correctly handle group_by_no_leaf when no grouping applied
If there are no grouping field specified *but* group_by_no_leaf is specified, should call read_group with no grouping fields: will generate a single group (which can not be opened) for all of the model. Necessary for analysis views since individual "records" make no sense. bzr revid: xmo@openerp.com-20130416092344-2pqog8f7xprn6hsh
This commit is contained in:
parent
d7b63202f3
commit
a455d6c2b2
|
@ -77,6 +77,7 @@ This module provides the core of the OpenERP Web Client.
|
||||||
"static/test/class.js",
|
"static/test/class.js",
|
||||||
"static/test/registry.js",
|
"static/test/registry.js",
|
||||||
"static/test/form.js",
|
"static/test/form.js",
|
||||||
|
"static/test/data.js",
|
||||||
"static/test/list-utils.js",
|
"static/test/list-utils.js",
|
||||||
"static/test/formats.js",
|
"static/test/formats.js",
|
||||||
"static/test/rpc.js",
|
"static/test/rpc.js",
|
||||||
|
|
|
@ -112,24 +112,27 @@ instance.web.Query = instance.web.Class.extend({
|
||||||
* @returns {jQuery.Deferred<Array<openerp.web.QueryGroup>> | null}
|
* @returns {jQuery.Deferred<Array<openerp.web.QueryGroup>> | null}
|
||||||
*/
|
*/
|
||||||
group_by: function (grouping) {
|
group_by: function (grouping) {
|
||||||
if (grouping === undefined) {
|
var ctx = instance.web.pyeval.eval(
|
||||||
return null;
|
'context', this._model.context(this._context));
|
||||||
|
|
||||||
|
// undefined passed in explicitly (!)
|
||||||
|
if (_.isUndefined(grouping)) {
|
||||||
|
grouping = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(grouping instanceof Array)) {
|
if (!(grouping instanceof Array)) {
|
||||||
grouping = _.toArray(arguments);
|
grouping = _.toArray(arguments);
|
||||||
}
|
}
|
||||||
if (_.isEmpty(grouping)) { return null; }
|
if (_.isEmpty(grouping) && !ctx['group_by_no_leaf']) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
var ctx = instance.web.pyeval.eval(
|
|
||||||
'context', this._model.context(this._context));
|
|
||||||
return this._model.call('read_group', {
|
return this._model.call('read_group', {
|
||||||
groupby: grouping,
|
groupby: grouping,
|
||||||
fields: _.uniq(grouping.concat(this._fields || [])),
|
fields: _.uniq(grouping.concat(this._fields || [])),
|
||||||
domain: this._model.domain(this._filter),
|
domain: this._model.domain(this._filter),
|
||||||
context: this._model.context(this._context),
|
context: ctx,
|
||||||
offset: this._offset,
|
offset: this._offset,
|
||||||
limit: this._limit,
|
limit: this._limit,
|
||||||
orderby: instance.web.serialize_sort(this._order_by) || false
|
orderby: instance.web.serialize_sort(this._order_by) || false
|
||||||
|
@ -325,7 +328,7 @@ instance.web.Model = instance.web.Class.extend({
|
||||||
* Fetches the model's domain, combined with the provided domain if any
|
* Fetches the model's domain, combined with the provided domain if any
|
||||||
*
|
*
|
||||||
* @param {Array} [domain] to combine with the model's internal domain
|
* @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
|
* @returns {instance.web.CompoundDomain} The model's internal domain, or the AND-ed union of the model's internal domain and the provided domain
|
||||||
*/
|
*/
|
||||||
domain: function (domain) {
|
domain: function (domain) {
|
||||||
if (!domain) { return this._domain; }
|
if (!domain) { return this._domain; }
|
||||||
|
@ -337,7 +340,7 @@ instance.web.Model = instance.web.Class.extend({
|
||||||
* combined with the provided context if any
|
* combined with the provided context if any
|
||||||
*
|
*
|
||||||
* @param {Object} [context] to combine with the model's internal context
|
* @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.
|
* @returns {instance.web.CompoundContext} 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) {
|
context: function (context) {
|
||||||
return new instance.web.CompoundContext(
|
return new instance.web.CompoundContext(
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
openerp.testing.section('data.model.group_by', {
|
||||||
|
rpc: 'mock',
|
||||||
|
dependencies: ['web.data'],
|
||||||
|
}, function (test) {
|
||||||
|
var group_result = [{
|
||||||
|
bar: 3, bar_count: 5, __context: {}, __domain: [['bar', '=', 3]],
|
||||||
|
}, {
|
||||||
|
bar: 5, bar_count: 3, __context: {}, __domain: [['bar', '=', 5]],
|
||||||
|
}, {
|
||||||
|
bar: 8, bar_count: 0, __context: {}, __domain: [['bar', '=', 8]],
|
||||||
|
}];
|
||||||
|
test('basic', {asserts: 7}, function (instance, $fix, mock) {
|
||||||
|
var m = new instance.web.Model('foo');
|
||||||
|
mock('foo:read_group', function (args, kwargs) {
|
||||||
|
deepEqual(kwargs.fields, ['bar'],
|
||||||
|
"should read grouping field");
|
||||||
|
deepEqual(kwargs.groupby, ['bar'],
|
||||||
|
"should have single grouping field");
|
||||||
|
return group_result;
|
||||||
|
});
|
||||||
|
mock('/web/dataset/search_read', function (args) {
|
||||||
|
deepEqual(args.params.domain, [['bar', '=', 3]],
|
||||||
|
"should have domain matching that of group_by result");
|
||||||
|
return {records: [
|
||||||
|
{bar: 3, id: 1},
|
||||||
|
{bar: 3, id: 2},
|
||||||
|
{bar: 3, id: 4},
|
||||||
|
{bar: 3, id: 8},
|
||||||
|
{bar: 3, id: 16}
|
||||||
|
], length: 5};
|
||||||
|
});
|
||||||
|
|
||||||
|
return m.query().group_by('bar')
|
||||||
|
.then(function (groups) {
|
||||||
|
ok(groups, "should have data");
|
||||||
|
equal(groups.length, 3, "should have three results");
|
||||||
|
var first = groups[0];
|
||||||
|
ok(first.attributes.has_children, "should have children");
|
||||||
|
return first.query().all();
|
||||||
|
}).done(function (first) {
|
||||||
|
equal(first.length, 5, "should have 5 records")
|
||||||
|
});
|
||||||
|
});
|
||||||
|
test('noleaf', {asserts: 5}, function (instance, $fix, mock) {
|
||||||
|
var m = new instance.web.Model('foo', {group_by_no_leaf: true});
|
||||||
|
mock('foo:read_group', function (args, kwargs) {
|
||||||
|
deepEqual(kwargs.fields, ['bar'],
|
||||||
|
"should read grouping field");
|
||||||
|
deepEqual(kwargs.groupby, ['bar'],
|
||||||
|
"should have single grouping field");
|
||||||
|
|
||||||
|
return group_result;
|
||||||
|
});
|
||||||
|
return m.query().group_by('bar')
|
||||||
|
.then(function (groups) {
|
||||||
|
ok(groups, "should have data");
|
||||||
|
equal(groups.length, 3, "should have three results");
|
||||||
|
ok(!groups[0].attributes.has_children,
|
||||||
|
"should not have children because no_leaf");
|
||||||
|
})
|
||||||
|
});
|
||||||
|
test('nogroup', {rpc: false}, function (instance, $f, mock) {
|
||||||
|
var m = new instance.web.Model('foo');
|
||||||
|
strictEqual(m.query().group_by(), null, "should not group");
|
||||||
|
});
|
||||||
|
test('empty.noleaf', {asserts: 1}, function (instance, $f, mock) {
|
||||||
|
var m = new instance.web.Model('foo', {group_by_no_leaf: true});
|
||||||
|
mock('foo:read_group', function (args, kwargs) {
|
||||||
|
return [{__context: [], __domain: []}];
|
||||||
|
});
|
||||||
|
return m.query().group_by().done(function (groups) {
|
||||||
|
strictEqual(groups.length, 1,
|
||||||
|
"should generate a single fake-ish group");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue