From 09860796e36c1a5c384b849608822acff2fbcd2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20Lef=C3=A8vre=20=28lul=29?= Date: Tue, 5 Nov 2024 07:55:58 +0000 Subject: [PATCH] [FIX] pivot: skip cells on manipulated pivot array formulas MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Steps to reproduce in odoo: - insert a pivot with more rows than columns - write in a cell =TRANSPOSE(ODOO.PIVOT.TABLE(1)) - right-click on the grand total value => boom When computing which cell of the pivot table is clicked, we assume the matrix comes directly from the ODOO.PIVOT.TABLE(...) function to compute the offsets from the array formula. But it's completely wrong as the cell could at a completely different place if the matrix is manipulated by other functions before being outputted to the grid. closes odoo/o-spreadsheet#5162 X-original-commit: 360550579767b39ec8fc0fb2a07adc0363295127 Task: 4292134 Signed-off-by: Lucas Lefèvre (lul) Signed-off-by: Rémi Rahir (rar) --- src/plugins/ui_core_views/pivot_ui.ts | 6 ++++++ tests/pivots/pivot_plugin.test.ts | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/plugins/ui_core_views/pivot_ui.ts b/src/plugins/ui_core_views/pivot_ui.ts index 9b3551a267..00b1e9255a 100644 --- a/src/plugins/ui_core_views/pivot_ui.ts +++ b/src/plugins/ui_core_views/pivot_ui.ts @@ -209,6 +209,12 @@ export class PivotUIPlugin extends UIPlugin { if (!pivot.isValid()) { return EMPTY_PIVOT_CELL; } + if ( + functionName === "PIVOT" && + !cell.content.replaceAll(" ", "").toUpperCase().startsWith("=PIVOT") + ) { + return EMPTY_PIVOT_CELL; + } if (functionName === "PIVOT") { const includeTotal = args[2] === false ? false : undefined; const includeColumnHeaders = args[3] === false ? false : undefined; diff --git a/tests/pivots/pivot_plugin.test.ts b/tests/pivots/pivot_plugin.test.ts index 7d07ad2c09..36fdad5c2c 100644 --- a/tests/pivots/pivot_plugin.test.ts +++ b/tests/pivots/pivot_plugin.test.ts @@ -165,6 +165,26 @@ describe("Pivot plugin", () => { expect(thirdCalculatedName).toBe("Calculated measure 1"); }); + test("getPivotCellFromPosition cannot get the pivot cell when the table is manipulated by other functions", () => { + // prettier-ignore + const grid = { + A1: "Customer", B1: "Price", C1: '=PIVOT.VALUE(1,"Price","5","Bob")', + A2: "Alice", B2: "10", + A3: "Bob", B3: "30", + A4: "=TRANSPOSE(PIVOT(1))", + }; + const model = createModelFromGrid(grid); + addPivot(model, "A1:B3", { + columns: [], + rows: [{ fieldName: "Customer" }], + measures: [{ id: "price:sum", fieldName: "Price", aggregator: "sum" }], + }); + selectCell(model, "C5"); + expect(model.getters.getPivotCellFromPosition(model.getters.getActivePosition())).toEqual( + EMPTY_PIVOT_CELL + ); + }); + test("forbidden characters are removed from new sheet name when duplicating a pivot", () => { const grid = { A1: "Customer",