diff --git a/addons/web/static/src/legacy/js/views/pivot/pivot_model.js b/addons/web/static/src/legacy/js/views/pivot/pivot_model.js
index 72296444aa4..6fc3f6bc136 100644
--- a/addons/web/static/src/legacy/js/views/pivot/pivot_model.js
+++ b/addons/web/static/src/legacy/js/views/pivot/pivot_model.js
@@ -719,7 +719,11 @@ var PivotModel = AbstractModel.extend({
values.slice(0, values.length - 1).forEach(function (value) {
tree = tree.directSubTrees.get(value);
});
- tree.directSubTrees.set(values[values.length - 1], {
+ const value = values[values.length - 1];
+ if (tree.directSubTrees.has(value)) {
+ return;
+ }
+ tree.directSubTrees.set(value, {
root: {
labels: labels,
values: values,
diff --git a/addons/web/static/src/views/pivot/pivot_model.js b/addons/web/static/src/views/pivot/pivot_model.js
index fe30557458b..fb3b353773d 100644
--- a/addons/web/static/src/views/pivot/pivot_model.js
+++ b/addons/web/static/src/views/pivot/pivot_model.js
@@ -779,7 +779,11 @@ export class PivotModel extends Model {
values.slice(0, values.length - 1).forEach(function (value) {
tree = tree.directSubTrees.get(value);
});
- tree.directSubTrees.set(values[values.length - 1], {
+ const value = values[values.length - 1];
+ if (tree.directSubTrees.has(value)) {
+ return;
+ }
+ tree.directSubTrees.set(value, {
root: {
labels: labels,
values: values,
diff --git a/addons/web/static/tests/legacy/views/pivot_tests.js b/addons/web/static/tests/legacy/views/pivot_tests.js
index 8a85ea42361..36ecf32b5b8 100644
--- a/addons/web/static/tests/legacy/views/pivot_tests.js
+++ b/addons/web/static/tests/legacy/views/pivot_tests.js
@@ -3434,6 +3434,70 @@ QUnit.module('Views', {
pivot.destroy();
});
+ QUnit.test('comparison with two groupbys: rows from reference period should be displayed', async function (assert) {
+ assert.expect(3);
+
+ this.data.partner.records = [
+ { id: 1, date: "2021-10-10", product_id: 1, customer: 1 },
+ { id: 2, date: "2020-10-10", product_id: 2, customer: 1 },
+ ]
+ this.data.product.records = [
+ { id: 1, display_name: "A" },
+ { id: 2, display_name: "B" },
+ ]
+ this.data.customer.records = [
+ { id: 1, display_name: "P" },
+ ]
+
+ const pivot = await createView({
+ View: PivotView,
+ model: "partner",
+ data: this.data,
+ arch: '',
+ archs: {
+ "partner,false,search": ""
+ },
+ });
+
+ // compare 2021 to 2020
+ await cpHelpers.toggleFilterMenu(pivot.el);
+ await cpHelpers.toggleMenuItem(pivot.el, "Date");
+ await cpHelpers.toggleMenuItemOption(pivot.el, "Date", "2021");
+ await cpHelpers.toggleComparisonMenu(pivot.el);
+ await cpHelpers.toggleMenuItem(pivot.el, 0);
+
+ assert.strictEqual(
+ pivot.$('th').slice(0, 6).text(),
+ [
+ "Total",
+ "Count",
+ "2020", "2021", "Variation"
+ ].join(''),
+ "The col headers should be as expected"
+ );
+
+ assert.strictEqual(
+ pivot.$('th').slice(6).text(),
+ [
+ 'Total',
+ 'P',
+ 'B',
+ 'A',
+ ].join(''),
+ "The row headers should be as expected"
+ );
+
+ const values = [
+ "1", "1", "0%",
+ "1", "1", "0%",
+ "1", "0", "-100%",
+ "0", "1", "100%",
+ ];
+ assert.strictEqual(getCurrentValues(pivot), values.join());
+
+ pivot.destroy();
+ });
+
QUnit.test('pivot rendering with boolean field', async function (assert) {
assert.expect(4);
diff --git a/addons/web/static/tests/views/pivot_view_tests.js b/addons/web/static/tests/views/pivot_view_tests.js
index f08ce150816..2ca8c08afa5 100644
--- a/addons/web/static/tests/views/pivot_view_tests.js
+++ b/addons/web/static/tests/views/pivot_view_tests.js
@@ -5335,4 +5335,60 @@ QUnit.module("Views", (hooks) => {
// No separator should be displayed in the menu "Measures"
assert.containsNone(pivot, ".o_cp_bottom_left .dropdown-menu div.dropdown-divider");
});
+
+ QUnit.test(
+ "comparison with two groupbys: rows from reference period should be displayed",
+ async function (assert) {
+ assert.expect(3);
+
+ serverData.models.partner.records = [
+ { id: 1, date: "2021-10-10", product_id: 1, customer: 1 },
+ { id: 2, date: "2020-10-10", product_id: 2, customer: 1 },
+ ];
+ serverData.models.product.records = [
+ { id: 1, display_name: "A" },
+ { id: 2, display_name: "B" },
+ ];
+ serverData.models.customer.records = [{ id: 1, display_name: "P" }];
+
+ const pivot = await makeView({
+ type: "pivot",
+ resModel: "partner",
+ serverData,
+ arch: `
+
+
+
+
+ `,
+ searchViewArch: `
+
+
+
+ `,
+ });
+
+ // compare 2021 to 2020
+ await toggleFilterMenu(pivot);
+ await toggleMenuItem(pivot, "Date");
+ await toggleMenuItemOption(pivot, "Date", "2021");
+ await toggleComparisonMenu(pivot);
+ await toggleMenuItem(pivot, 0);
+
+ assert.deepEqual(
+ [...pivot.el.querySelectorAll("th")].slice(0, 6).map((el) => el.innerText),
+ ["", "Total", "Count", "2020", "2021", "Variation"],
+ "The col headers should be as expected"
+ );
+
+ assert.deepEqual(
+ [...pivot.el.querySelectorAll("th")].slice(6).map((el) => el.innerText),
+ ["Total", "P", "B", "A"],
+ "The row headers should be as expected"
+ );
+
+ const values = ["1", "1", "0%", "1", "1", "0%", "1", "0", "-100%", "0", "1", "100%"];
+ assert.strictEqual(getCurrentValues(pivot), values.join());
+ }
+ );
});