odoo18/addons/spreadsheet/static/src/pivot/pivot_helpers.js

95 lines
3.0 KiB
JavaScript

// @ts-check
import { _t } from "@web/core/l10n/translation";
import { EvaluationError, helpers } from "@odoo/o-spreadsheet";
import { sprintf } from "@web/core/utils/strings";
const { isDateOrDatetimeField } = helpers;
/**
* @typedef {import("@odoo/o-spreadsheet").Token} Token
* @typedef {import("@odoo/o-spreadsheet").Granularity} Granularity
* */
export const pivotFormulaRegex = /^=.*PIVOT/;
const AGGREGATOR_NAMES = {
count: _t("Count"),
count_distinct: _t("Count Distinct"),
bool_and: _t("Boolean And"),
bool_or: _t("Boolean Or"),
max: _t("Maximum"),
min: _t("Minimum"),
avg: _t("Average"),
sum: _t("Sum"),
};
const NUMBER_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
const DATE_AGGREGATORS = ["max", "min", "count_distinct", "count"];
const AGGREGATORS_BY_FIELD_TYPE = {
integer: NUMBER_AGGREGATORS,
float: NUMBER_AGGREGATORS,
monetary: NUMBER_AGGREGATORS,
date: DATE_AGGREGATORS,
datetime: DATE_AGGREGATORS,
boolean: ["count_distinct", "count", "bool_and", "bool_or"],
char: ["count_distinct", "count"],
many2one: ["count_distinct", "count"],
reference: ["count_distinct", "count"],
};
export const ODOO_AGGREGATORS = {};
for (const type in AGGREGATORS_BY_FIELD_TYPE) {
ODOO_AGGREGATORS[type] = {};
for (const aggregator of AGGREGATORS_BY_FIELD_TYPE[type]) {
ODOO_AGGREGATORS[type][aggregator] = AGGREGATOR_NAMES[aggregator];
}
}
//--------------------------------------------------------------------------
// Public
//--------------------------------------------------------------------------
/**
* @typedef {import("@spreadsheet").OdooField} OdooField
*/
/**
* Parses the positional char (#), the field and operator string of pivot group.
* e.g. "create_date:month"
* @param {Record<string, OdooField | undefined>} allFields
* @param {string} groupFieldString
* @returns {{field: OdooField, granularity: Granularity, isPositional: boolean, dimensionWithGranularity: string}}
*/
export function parseGroupField(allFields, groupFieldString) {
let fieldName = groupFieldString;
let granularity = undefined;
const index = groupFieldString.indexOf(":");
if (index !== -1) {
fieldName = groupFieldString.slice(0, index);
granularity = groupFieldString.slice(index + 1);
}
const isPositional = fieldName.startsWith("#");
fieldName = isPositional ? fieldName.substring(1) : fieldName;
const field = allFields[fieldName];
if (field === undefined) {
throw new EvaluationError(sprintf(_t("Field %s does not exist"), fieldName));
}
if (isDateOrDatetimeField(field)) {
granularity = granularity || "month";
}
const dimensionWithGranularity = granularity ? `${fieldName}:${granularity}` : fieldName;
return {
isPositional,
field,
granularity,
dimensionWithGranularity,
};
}
export function domainHasNoRecordAtThisPosition(domain) {
return domain.some((node) => node.value === "NO_RECORD_AT_THIS_POSITION");
}