[FIX] web: sort pivot rows in comparison mode
Before this commit, it was not possible to sort the rows of a pivot view while in comparison mode. This fix makes it now possible. Note that in comparison mode, a click on a header of type "measure" will sort the rows according to the column values coming from the data of interest. closes odoo/odoo#28411
This commit is contained in:
@@ -336,7 +336,8 @@ var PivotController = AbstractController.extend({
|
||||
var col_id = $target.data('id');
|
||||
var measure = $target.data('measure');
|
||||
var isAscending = $target.hasClass('o_pivot_measure_row_sorted_asc');
|
||||
this.model.sortRows(col_id, measure, isAscending);
|
||||
var dataType = $target.data('data_type');
|
||||
this.model.sortRows(col_id, measure, isAscending, dataType);
|
||||
this.update({}, {reload: false});
|
||||
},
|
||||
/**
|
||||
|
||||
@@ -457,16 +457,23 @@ var PivotModel = AbstractModel.extend({
|
||||
* @param {any} col_id
|
||||
* @param {any} measure
|
||||
* @param {any} descending
|
||||
* @param {'data'|'comparisonData'|'variation'} [dataType]
|
||||
*/
|
||||
sortRows: function (col_id, measure, descending) {
|
||||
sortRows: function (col_id, measure, descending, dataType) {
|
||||
var cells = this.data.cells;
|
||||
var comparisonFunction = compare;
|
||||
if (this.data.compare) {
|
||||
dataType = dataType || 'data';
|
||||
comparisonFunction = specialCompare;
|
||||
}
|
||||
this._traverseTree(this.data.main_row.root, function (header) {
|
||||
header.children.sort(compare);
|
||||
header.children.sort(comparisonFunction);
|
||||
});
|
||||
this.data.sorted_column = {
|
||||
id: col_id,
|
||||
measure: measure,
|
||||
order: descending ? 'desc' : 'asc',
|
||||
dataType: dataType,
|
||||
};
|
||||
function _getValue (id1, id2) {
|
||||
if ((id1 in cells) && (id2 in cells[id1])) {
|
||||
@@ -476,12 +483,26 @@ var PivotModel = AbstractModel.extend({
|
||||
}
|
||||
|
||||
function compare (row1, row2) {
|
||||
var values1 = _getValue(row1.id, col_id),
|
||||
values2 = _getValue(row2.id, col_id),
|
||||
value1 = values1 ? values1[measure] : 0,
|
||||
value2 = values2 ? values2[measure] : 0;
|
||||
var values1 = _getValue(row1.id, col_id);
|
||||
var values2 = _getValue(row2.id, col_id);
|
||||
var value1 = values1 ? values1[measure] : 0;
|
||||
var value2 = values2 ? values2[measure] : 0;
|
||||
return descending ? value1 - value2 : value2 - value1;
|
||||
}
|
||||
function specialCompare (row1, row2) {
|
||||
var values1 = _getValue(row1.id, col_id);
|
||||
var values2 = _getValue(row2.id, col_id);
|
||||
var value1 = values1 ? values1[measure] : {data: 0, comparisonData: 0, variation: {magnitude: 0}};
|
||||
var value2 = values2 ? values2[measure] : {data: 0, comparisonData: 0, variation: {magnitude: 0}};
|
||||
if (dataType === 'variation') {
|
||||
return descending ?
|
||||
value1[dataType].magnitude - value2[dataType].magnitude:
|
||||
value2[dataType].magnitude - value1[dataType].magnitude;
|
||||
}
|
||||
return descending ?
|
||||
value1[dataType] - value2[dataType]:
|
||||
value2[dataType] - value1[dataType];
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Toggle the active state for a given measure, then reload the data.
|
||||
|
||||
@@ -116,6 +116,8 @@ var PivotRenderer = AbstractRenderer.extend({
|
||||
_renderHeaders: function ($thead, headers, nbrCols) {
|
||||
var self = this;
|
||||
var i, j, cell, $row, $cell;
|
||||
var measure, dataType;
|
||||
var id, measureCellIds = [];
|
||||
|
||||
var groupbyLabels = _.map(this.state.colGroupBys, function (gb) {
|
||||
return self.state.fields[gb.split(':')[0]].string;
|
||||
@@ -144,10 +146,13 @@ var PivotRenderer = AbstractRenderer.extend({
|
||||
$cell.data('id', cell.id);
|
||||
}
|
||||
if (cell.measure) {
|
||||
measure = cell.measure;
|
||||
measureCellIds.push(cell.id);
|
||||
$cell.addClass('o_pivot_measure_row text-muted')
|
||||
.text(this.state.fields[cell.measure].string);
|
||||
$cell.data('id', cell.id).data('measure', cell.measure);
|
||||
if (!this.compare && cell.id === this.state.sortedColumn.id && cell.measure === this.state.sortedColumn.measure) {
|
||||
.text(this.state.fields[measure].string);
|
||||
$cell.data('id', cell.id).data('measure', measure);
|
||||
if (cell.id === this.state.sortedColumn.id &&
|
||||
measure === this.state.sortedColumn.measure) {
|
||||
$cell.addClass('o_pivot_measure_row_sorted_' + this.state.sortedColumn.order);
|
||||
if (this.state.sortedColumn.order == 'asc') {
|
||||
$cell.attr('aria-sorted', 'ascending');
|
||||
@@ -167,12 +172,30 @@ var PivotRenderer = AbstractRenderer.extend({
|
||||
}
|
||||
if (this.compare) {
|
||||
var colLabels = [this.timeRangeDescription, this.comparisonTimeRangeDescription, 'Variation'];
|
||||
var dataTypes = ['data', 'comparisonData', 'variation'];
|
||||
$row = $('<tr>');
|
||||
for (i = 0; i < 3 * nbrCols; i++) {
|
||||
id = measureCellIds[~~(i / 3)];
|
||||
measure = this.state.measures[(~~(i / 3)) % this.state.measures.length];
|
||||
dataType = dataTypes[i % 3];
|
||||
$cell = $('<th>')
|
||||
.addClass('o_pivot_measure_row text-muted')
|
||||
.data('data_type', dataType)
|
||||
.data('id', id)
|
||||
.data('measure', measure)
|
||||
.text(colLabels[i % 3])
|
||||
.attr('rowspan', 1)
|
||||
.attr('colspan', 1);
|
||||
if (dataType === this.state.sortedColumn.dataType &&
|
||||
id === this.state.sortedColumn.id &&
|
||||
measure === this.state.sortedColumn.measure) {
|
||||
$cell.addClass('o_pivot_measure_row_sorted_' + this.state.sortedColumn.order);
|
||||
if (this.state.sortedColumn.order === 'asc') {
|
||||
$cell.attr('aria-sorted', 'ascending');
|
||||
} else {
|
||||
$cell.attr('aria-sorted', 'descending');
|
||||
}
|
||||
}
|
||||
$row.append($cell);
|
||||
}
|
||||
$thead.append($row);
|
||||
|
||||
@@ -1417,7 +1417,7 @@ QUnit.module('Views', {
|
||||
actionManager.destroy();
|
||||
});
|
||||
|
||||
QUnit.test('export data in excel with comparison', function (assert) {
|
||||
QUnit.test('export data in excel with comparison', function (assert) {
|
||||
assert.expect(10);
|
||||
|
||||
this.data.partner.records[0].date = '2016-12-15';
|
||||
@@ -1572,5 +1572,147 @@ QUnit.module('Views', {
|
||||
unpatchDate();
|
||||
actionManager.destroy();
|
||||
});
|
||||
|
||||
QUnit.module('Sort in comparison mode', {
|
||||
beforeEach: function () {
|
||||
this.data.partner.records[0].date = '2016-12-15';
|
||||
this.data.partner.records[1].date = '2016-12-17';
|
||||
this.data.partner.records[2].date = '2016-11-22';
|
||||
this.data.partner.records[3].date = '2016-11-03';
|
||||
|
||||
this.data.partner.fields.company_type = {string: "Company Type", type: "selection", selection: [["company", "Company"], ["individual", "individual"]], searchable: true, store: true, sortable: true};
|
||||
|
||||
this.data.partner.records[0].company_type = 'company';
|
||||
this.data.partner.records[1].company_type = 'individual';
|
||||
this.data.partner.records[2].company_type = 'company';
|
||||
this.data.partner.records[3].company_type = 'individual';
|
||||
|
||||
|
||||
this.unpatchDate = patchDate(2016, 11, 20, 1, 0, 0);
|
||||
|
||||
this.actualResult = function () {
|
||||
var actualResult = $('.o_pivot .o_pivot_cell_value div').map(function() {
|
||||
return $( this ).text();
|
||||
}).get().join();
|
||||
return actualResult;
|
||||
};
|
||||
|
||||
// create an action manager to test the interactions with the search view
|
||||
this.actionManager = createActionManager({
|
||||
data: this.data,
|
||||
archs: {
|
||||
'partner,false,pivot': '<pivot>' +
|
||||
'<field name="date" interval="day" type="row"/>' +
|
||||
'<field name="company_type" type="col"/>' +
|
||||
'<field name="foo" type="measure"/>' +
|
||||
'</pivot>',
|
||||
'partner,false,search': '<search></search>',
|
||||
},
|
||||
debug: 1,
|
||||
});
|
||||
|
||||
this.actionManager.doAction({
|
||||
res_model: 'partner',
|
||||
type: 'ir.actions.act_window',
|
||||
views: [[false, 'pivot']],
|
||||
flags: {
|
||||
pivot: {
|
||||
additionalMeasures: ['product_id'],
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// open time range menu
|
||||
testUtils.dom.click($('.o_control_panel .o_time_range_menu_button'));
|
||||
// select 'Today' as range
|
||||
testUtils.fields.editInput($('.o_control_panel .o_time_range_selector'), 'this_month');
|
||||
// check checkbox 'Compare To'
|
||||
testUtils.dom.click($('.o_control_panel .o_time_range_menu .o_comparison_checkbox'));
|
||||
// Click on 'Apply' button
|
||||
testUtils.dom.click($('.o_control_panel .o_time_range_menu .o_apply_range'));
|
||||
// We are in comparison mode
|
||||
},
|
||||
afterEach: function () {
|
||||
this.unpatchDate();
|
||||
this.actionManager.destroy();
|
||||
},
|
||||
}, function () {
|
||||
QUnit.test('when clicking on measure, sort by "This Month" (period of interest)', function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
// click on 'Foo' in column Total/Company
|
||||
testUtils.dom.click($('.o_pivot_measure_row').eq(0));
|
||||
var results = [
|
||||
"12", "17", "-29.41%", "1", "2", "-50%", "13", "19", "-31.58%",
|
||||
"12", "0", "100%", "12", "0" , "100%",
|
||||
"1", "0", "100%", "1" , "0", "100%",
|
||||
"0", "17", "-100%", "0", "17", "-100%",
|
||||
"0", "2", "-100%", "0" , "2" , "-100%"
|
||||
];
|
||||
assert.strictEqual(this.actualResult(), results.join());
|
||||
});
|
||||
|
||||
QUnit.test(
|
||||
'click on a period of interest header sort according to the appropriate column ' +
|
||||
'first in ascending order then in descending order',
|
||||
function (assert) {
|
||||
assert.expect(2);
|
||||
|
||||
// click on 'This Month' in column Total/Individual/Foo
|
||||
testUtils.dom.click($('.o_pivot_measure_row').eq(6));
|
||||
var results = [
|
||||
"12", "17", "-29.41%", "1", "2", "-50%", "13", "19", "-31.58%",
|
||||
"1", "0", "100%", "1" , "0", "100%",
|
||||
"12", "0", "100%", "12", "0" , "100%",
|
||||
"0", "17", "-100%", "0", "17", "-100%",
|
||||
"0", "2", "-100%", "0" , "2" , "-100%"
|
||||
];
|
||||
var actualResult = $('.o_pivot .o_pivot_cell_value div').text();
|
||||
assert.strictEqual(actualResult, results.join(''));
|
||||
|
||||
// click once again on 'This Month' in column Total/Individual/Foo
|
||||
testUtils.dom.click($('.o_pivot_measure_row').eq(6));
|
||||
results = [
|
||||
"12", "17", "-29.41%", "1", "2", "-50%", "13", "19", "-31.58%",
|
||||
"12", "0", "100%", "12", "0" , "100%",
|
||||
"0", "17", "-100%", "0", "17", "-100%",
|
||||
"0", "2", "-100%", "0" , "2" , "-100%",
|
||||
"1", "0", "100%", "1" , "0", "100%"
|
||||
];
|
||||
assert.strictEqual(this.actualResult(), results.join());
|
||||
});
|
||||
|
||||
QUnit.test('click on a period of comparison header sort according to appropriate column',
|
||||
function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
// click on 'Previous Period' in column Total/Individual/Foo
|
||||
testUtils.dom.click($('.o_pivot_measure_row').eq(7));
|
||||
var results = [
|
||||
"12", "17", "-29.41%", "1", "2", "-50%", "13", "19", "-31.58%",
|
||||
"0", "2", "-100%", "0" , "2" , "-100%",
|
||||
"12", "0", "100%", "12", "0" , "100%",
|
||||
"1", "0", "100%", "1" , "0", "100%",
|
||||
"0", "17", "-100%", "0", "17", "-100%"
|
||||
];
|
||||
assert.strictEqual(this.actualResult(), results.join());
|
||||
});
|
||||
|
||||
QUnit.test('click on a variation header sort according to appropriate column',
|
||||
function (assert) {
|
||||
assert.expect(1);
|
||||
|
||||
// click on 'Variation' in column Total/Individual/Foo
|
||||
testUtils.dom.click($('.o_pivot_measure_row').eq(11));
|
||||
var results = [
|
||||
"12", "17", "-29.41%", "1", "2", "-50%", "13", "19", "-31.58%",
|
||||
"12", "0", "100%", "12", "0" , "100%",
|
||||
"1", "0", "100%", "1" , "0", "100%",
|
||||
"0", "17", "-100%", "0", "17", "-100%",
|
||||
"0", "2", "-100%", "0" , "2" , "-100%"
|
||||
];
|
||||
assert.strictEqual(this.actualResult(), results.join());
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user