147 lines
4.7 KiB
JavaScript
147 lines
4.7 KiB
JavaScript
import { animationFrame } from "@odoo/hoot-mock";
|
|
import { PivotArchParser } from "@web/views/pivot/pivot_arch_parser";
|
|
import { OdooPivot } from "@spreadsheet/pivot/odoo_pivot";
|
|
import { getBasicPivotArch, getPyEnv } from "@spreadsheet/../tests/helpers/data";
|
|
import { createModelWithDataSource } from "@spreadsheet/../tests/helpers/model";
|
|
import { waitForDataLoaded } from "@spreadsheet/helpers/model";
|
|
import { helpers } from "@odoo/o-spreadsheet";
|
|
const { parseDimension, isDateOrDatetimeField } = helpers;
|
|
|
|
/**
|
|
* @typedef {import("@spreadsheet").OdooSpreadsheetModel} OdooSpreadsheetModel
|
|
* @typedef {import("@spreadsheet").Zone} Zone
|
|
*/
|
|
|
|
function addEmptyGranularity(dimensions, fields) {
|
|
return dimensions.map((dimension) => {
|
|
if (dimension.fieldName !== "id" && isDateOrDatetimeField(fields[dimension.fieldName])) {
|
|
return {
|
|
granularity: "month",
|
|
...dimension,
|
|
};
|
|
}
|
|
return dimension;
|
|
});
|
|
}
|
|
|
|
/**
|
|
* @param {OdooSpreadsheetModel} model
|
|
* @param {string} pivotId
|
|
* @param {object} params
|
|
* @param {string} [params.arch]
|
|
* @param {string} [params.resModel]
|
|
* @param {object} [params.serverData]
|
|
* @param {string} [params.sheetId]
|
|
* @param {[number, number]} [params.anchor]
|
|
*/
|
|
export async function insertPivotInSpreadsheet(model, pivotId, params) {
|
|
const archInfo = new PivotArchParser().parse(params.arch || getBasicPivotArch());
|
|
const resModel = params.resModel || "partner";
|
|
|
|
const pyEnv = getPyEnv();
|
|
const pivot = {
|
|
type: "ODOO",
|
|
sortedColumn: null,
|
|
domain: [],
|
|
context: {},
|
|
measures: archInfo.activeMeasures.map((measure) => ({
|
|
id: pyEnv[resModel]._fields[measure]?.aggregator
|
|
? `${measure}:${pyEnv[resModel]._fields[measure].aggregator}`
|
|
: measure,
|
|
fieldName: measure,
|
|
aggregator: pyEnv[resModel]._fields[measure]?.aggregator,
|
|
})),
|
|
model: resModel,
|
|
columns: addEmptyGranularity(
|
|
archInfo.colGroupBys.map(parseDimension),
|
|
pyEnv[resModel]._fields
|
|
),
|
|
rows: addEmptyGranularity(
|
|
archInfo.rowGroupBys.map(parseDimension),
|
|
pyEnv[resModel]._fields
|
|
),
|
|
name: "Partner Pivot",
|
|
};
|
|
model.dispatch("ADD_PIVOT", {
|
|
pivotId,
|
|
pivot,
|
|
});
|
|
const ds = model.getters.getPivot(pivotId);
|
|
if (!(ds instanceof OdooPivot)) {
|
|
throw new Error("The pivot data source is not an OdooPivot");
|
|
}
|
|
await ds.load();
|
|
const { cols, rows, measures, fieldsType } = ds.getTableStructure().export();
|
|
const table = {
|
|
cols,
|
|
rows,
|
|
measures,
|
|
fieldsType,
|
|
};
|
|
const [col, row] = params.anchor || [0, 0];
|
|
model.dispatch("INSERT_PIVOT", {
|
|
pivotId,
|
|
sheetId: params.sheetId || model.getters.getActiveSheetId(),
|
|
col,
|
|
row,
|
|
table,
|
|
});
|
|
await animationFrame();
|
|
}
|
|
|
|
/**
|
|
* @param {object} params
|
|
* @param {string} [params.arch]
|
|
* @param {object} [params.serverData]
|
|
* @param {function} [params.mockRPC]
|
|
* @returns {Promise<{ model: OdooSpreadsheetModel, env: object, pivotId: string}>}
|
|
*/
|
|
export async function createSpreadsheetWithPivot(params = {}) {
|
|
const model = await createModelWithDataSource({
|
|
mockRPC: params.mockRPC,
|
|
serverData: params.serverData,
|
|
});
|
|
const arch = params.arch || getBasicPivotArch();
|
|
const pivotId = "PIVOT#1";
|
|
await insertPivotInSpreadsheet(model, pivotId, { arch });
|
|
const env = model.config.custom.env;
|
|
env.model = model;
|
|
await waitForDataLoaded(model);
|
|
return { model, env, pivotId };
|
|
}
|
|
|
|
/**
|
|
* Return the zone that contains all the cells of the given data source
|
|
*
|
|
* TODO: Un-duplicate this once this or #50623 is merged
|
|
*
|
|
* @param model
|
|
* @param {"pivot" | "list"} dataSourceType
|
|
* @param {string} id
|
|
* @returns {Zone}
|
|
*/
|
|
export function getZoneOfInsertedDataSource(model, dataSourceType, id) {
|
|
const sheetId = model.getters.getActiveSheetId();
|
|
const cells = model.getters.getCells(sheetId);
|
|
const positions = Object.keys(cells).map(model.getters.getCellPosition);
|
|
|
|
let top = 0;
|
|
let left = 0;
|
|
let bottom = 0;
|
|
let right = 0;
|
|
for (const position of positions) {
|
|
const cellDataSourceId =
|
|
dataSourceType === "pivot"
|
|
? model.getters.getPivotIdFromPosition({ sheetId, ...position })
|
|
: model.getters.getListIdFromPosition({ sheetId, ...position });
|
|
if (id !== cellDataSourceId) {
|
|
continue;
|
|
}
|
|
top = Math.min(top, position.row);
|
|
left = Math.min(left, position.col);
|
|
bottom = Math.max(bottom, position.row);
|
|
right = Math.max(right, position.col);
|
|
}
|
|
return { top, bottom, left, right };
|
|
}
|