diff --git a/addons/spreadsheet/static/src/pivot/pivot_model.js b/addons/spreadsheet/static/src/pivot/pivot_model.js index 25b202c7b8b..379373d43f3 100644 --- a/addons/spreadsheet/static/src/pivot/pivot_model.js +++ b/addons/spreadsheet/static/src/pivot/pivot_model.js @@ -462,8 +462,9 @@ export class SpreadsheetPivotModel extends PivotModel { * @override */ _getGroupValues(group, groupBys) { - return groupBys.map((groupBy) => { - const { field, aggregateOperator } = this.parseGroupField(groupBy); + return groupBys.map((gb) => { + const groupBy = this._normalize(gb); + const { field, aggregateOperator } = this.parseGroupField(gb); if (this._isDateField(field)) { return pivotTimeAdapter(aggregateOperator).normalizeServerValue( groupBy, diff --git a/addons/web/static/src/views/pivot/pivot_model.js b/addons/web/static/src/views/pivot/pivot_model.js index 475ce5bb6da..b8ad33606c3 100644 --- a/addons/web/static/src/views/pivot/pivot_model.js +++ b/addons/web/static/src/views/pivot/pivot_model.js @@ -933,6 +933,19 @@ export class PivotModel extends Model { return values[0]; } } + /** + * @protected + * @param {string[]} rowGroupBy + * @param {string[]} colGroupBy + * @returns {string[]} + */ + _getGroupBySpecs(rowGroupBy, colGroupBy) { + const set = rowGroupBy.concat(colGroupBy).reduce((acc, gb) => { + acc.add(this._normalize(gb)); + return acc; + }, new Set()); + return [...set]; + } /** * Returns a domain representation of a group * @@ -959,7 +972,8 @@ export class PivotModel extends Model { * @returns {string[]} */ _getGroupLabels(group, groupBys, config) { - return groupBys.map((groupBy) => { + return groupBys.map((gb) => { + const groupBy = this._normalize(gb); return this._sanitizeLabel(group[groupBy], groupBy, config); }); } @@ -977,7 +991,7 @@ export class PivotModel extends Model { async _getGroupSubdivision(group, rowGroupBy, colGroupBy, config) { const groupDomain = this._getGroupDomain(group, config); const measureSpecs = this._getMeasureSpecs(config); - const groupBy = rowGroupBy.concat(colGroupBy); + const groupBy = this._getGroupBySpecs(rowGroupBy, colGroupBy); const kwargs = { lazy: false, context: this.searchParams.context }; const subGroups = await this.orm.readGroup( config.metaData.resModel, @@ -1002,7 +1016,8 @@ export class PivotModel extends Model { * @returns {Array} */ _getGroupValues(group, groupBys) { - return groupBys.map((groupBy) => { + return groupBys.map((gb) => { + const groupBy = this._normalize(gb); return this._sanitizeValue(group[groupBy]); }); } @@ -1411,6 +1426,20 @@ export class PivotModel extends Model { this.data = config.data; this.metaData = config.metaData; } + /** + * @protected + * @param {string} gb + * @returns {string} + */ + _normalize(gb) { + const [fieldName, interval] = gb.split(":"); + const field = this.metaData.fields[fieldName]; + if (["date", "datetime"].includes(field.type)) { + return `${fieldName}:${interval || "month"}`; + } else { + return fieldName; + } + } /** * Extract the information in the read_group results (groupSubdivisions) * and develop this.data.rowGroupTree, colGroupTree, measurements, counts, and diff --git a/addons/web/static/tests/views/pivot_view_tests.js b/addons/web/static/tests/views/pivot_view_tests.js index 9847b304245..33b973b80ea 100644 --- a/addons/web/static/tests/views/pivot_view_tests.js +++ b/addons/web/static/tests/views/pivot_view_tests.js @@ -5753,4 +5753,24 @@ QUnit.module("Views", (hooks) => { assert.strictEqual(columns[1].innerText, "aaa"); assert.strictEqual(columns[2].innerText, "bbb"); }); + + QUnit.test("avoid duplicates in read_group parameter 'groupby'", async function (assert) { + await makeView({ + type: "pivot", + resModel: "partner", + serverData, + arch: ` + + + + + `, + mockRPC(_, { method, kwargs }) { + if (method === "read_group") { + assert.step(JSON.stringify(kwargs.groupby)); + } + }, + }); + assert.verifySteps([`[]`, `["date:month"]`, `["date:month"]`, `["date:month"]`]); + }); });