im adding a new func in js but its variable is can not be used
below is my js code
/** @odoo-module **/
var rpc = require('web.rpc');
import { patch } from "@web/core/utils/patch";
import { browser } from "@web/core/browser/browser";
import { CheckBox } from "@web/core/checkbox/checkbox";
import { Dropdown } from "@web/core/dropdown/dropdown";
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
import { getActiveHotkey } from "@web/core/hotkeys/hotkey_service";
import { Pager } from "@web/core/pager/pager";
import { evaluateExpr } from "@web/core/py_js/py";
import { registry } from "@web/core/registry";
import { useBus, useService } from "@web/core/utils/hooks";
import { useSortable } from "@web/core/utils/sortable";
import { getTabableElements } from "@web/core/utils/ui";
import { Field } from "@web/views/fields/field";
import { getTooltipInfo } from "@web/views/fields/field_tooltip";
import { evalDomain, getClassNameFromDecoration } from "@web/views/utils";
import { ViewButton } from "@web/views/view_button/view_button";
import { useBounceButton } from "@web/views/view_hook";
import { Widget } from "@web/views/widgets/widget";
import { localization } from "@web/core/l10n/localization";
import { ListRenderer } from "@web/views/list/list_renderer";
const formatters = registry.category("formatters");
patch(ListRenderer.prototype, 'ListRenderer_custom', {
get aggregates() {
function checkCharNumberThreeFromEnd(inputString) {
// Check if the inputString is a string and has at least 3 characters
if (typeof inputString === 'string' && inputString.length >= 3) {
// Get the character at the third position from the end
const char = inputString.charAt(inputString.length - 3);
if (char === ','){
inputString = inputString.replace(/\s/g, '');
inputString = inputString.replace(/,/g, '.');
}
else if(char === '.'){
inputString = inputString.replace(/,/g, '');
}
return parseFloat(inputString)
}
}
let values;
if (this.props.list.selection && this.props.list.selection.length) {
values = this.props.list.selection.map((r) => r.data);
} else if (this.props.list.isGrouped) {
values = this.props.list.groups.map((g) => g.aggregates);
} else {
values = this.props.list.records.map((r) => r.data);
}
const aggregates = {};
for (const fieldName in this.props.list.activeFields) {
const field = this.fields[fieldName];
const fieldValues = values.map((v) => v[fieldName]).filter((v) => v || v === 0);
if (!fieldValues.length) {
continue;
}
const type = field.type;
if (type !== "integer" && type !== "float" && type !== "monetary") {
if (field.name !== "margin" && field.name !== "cost_discount_percent" && field.name !== "sale_discount_percent" && field.name !== "gross_margin_percentage"){
continue;
}
}
const { rawAttrs, widget } = this.props.list.activeFields[fieldName];
let currencyId;
if (type === "monetary" || widget === "monetary") {
const currencyField =
this.props.list.activeFields[fieldName].options.currency_field ||
this.fields[fieldName].currency_field ||
"currency_id";
currencyId =
currencyField in this.props.list.activeFields &&
values[0][currencyField] &&
values[0][currencyField][0];
if (currencyId) {
const sameCurrency = values.every(
(value) => currencyId === value[currencyField][0]
);
if (!sameCurrency) {
aggregates[fieldName] = {
help: _t("Different currencies cannot be aggregated"),
value: "—",
};
continue;
}
}
}
const func =
(rawAttrs.sum && "sum") ||
(rawAttrs.avg && "avg") ||
(rawAttrs.max && "max") ||
(rawAttrs.min && "min") ||
(rawAttrs.custom_margin && "custom_margin") ||
(rawAttrs.custom_cost_economic && "custom_cost_economic") ||
(rawAttrs.custom_sale_economic && "custom_sale_economic") ||
(rawAttrs.custom_gross_economic && "custom_gross_economic");
if (func) {
let aggregateValue = 0;
if (func === "max") {
aggregateValue = Math.max(-Infinity, ...fieldValues);
} else if (func === "min") {
aggregateValue = Math.min(Infinity, ...fieldValues);
} else if (func === "avg") {
aggregateValue =
fieldValues.reduce((acc, val) => acc + val) / fieldValues.length;
} else if (func === "sum") {
aggregateValue = fieldValues.reduce((acc, val) => acc + val);
} else if (func === "custom_margin") {
var margin_value = checkCharNumberThreeFromEnd(aggregates['margin_integer']['value']);
var cost_final_value = checkCharNumberThreeFromEnd(aggregates['cost_final']['value']);
if (cost_final_value === 0){
aggregateValue = 0 + " %";
}
else{
var margin = (margin_value / cost_final_value) * 100
margin = margin.toFixed(2) + " %";
aggregateValue = margin;
}
aggregates[fieldName] = {
help: rawAttrs[func],
value: aggregateValue,
};
continue
} else if (func === "custom_cost_economic") {
var cost_value = checkCharNumberThreeFromEnd(aggregates['cost_price']['value']);
var cost_discount_value = checkCharNumberThreeFromEnd(aggregates['cost_discount']['value']);
if (cost_value === 0){
aggregateValue = 0 + " %";
}
else{
var margin = (cost_discount_value / cost_value) * 100
margin = margin.toFixed(2) + " %";
aggregateValue = margin;
}
aggregates[fieldName] = {
help: rawAttrs[func],
value: aggregateValue,
};
continue
} else if (func === "custom_sale_economic") {
var sale_value = checkCharNumberThreeFromEnd(aggregates['sale_price']['value']);
var sale_discount = checkCharNumberThreeFromEnd(aggregates['sale_discount']['value']);
if (sale_value === 0){
aggregateValue = 0 + " %";
}
else{
var margin = (sale_discount / sale_value) * 100
margin = margin.toFixed(2) + " %";
aggregateValue = margin;
}
aggregates[fieldName] = {
help: rawAttrs[func],
value: aggregateValue,
};
continue
} else if (func === "custom_gross_economic") {
var saleFinalValue = checkCharNumberThreeFromEnd(aggregates['sale_final_no_tax']['value']);
var grossDiscount = checkCharNumberThreeFromEnd(aggregates['sale_final_tax']['value']);
if (saleFinalValue === 0) {
aggregateValue = "0 %";
} else {
var margin = (grossDiscount / saleFinalValue) * 100;
margin = margin.toFixed(2) + " %";
aggregateValue = margin;
}
aggregates[fieldName] = {
help: rawAttrs[func],
value: aggregateValue,
};
continue;
}
const formatter = formatters.get(widget, false) || formatters.get(type, false);
const formatOptions = {
digits: rawAttrs.digits ? JSON.parse(rawAttrs.digits) : undefined,
escape: true,
};
if (currencyId) {
formatOptions.currencyId = currencyId;
}
aggregates[fieldName] = {
help: rawAttrs[func],
value: formatter ? formatter(aggregateValue, formatOptions) : aggregateValue,
};
}
}
return aggregates;
}
});
below is my xml
Tree Vehicles Database Month
vdl.vehicles_database
and it shows below eror
2024-05-28 03:37:45,367 11469 ERROR ihzacappassion odoo.tools.view_validation: :17:0:ERROR:RELAXNGV:RELAXNG_ERR_NOELEM: Expecting an element data, got nothing 2024-05-28 03:37:45,367 11469 ERROR ihzacappassion odoo.tools.view_validation: :17:0:ERROR:RELAXNGV:RELAXNG_ERR_INVALIDATTR: Invalid attribute custom_gross_economic for element field 2024-05-28 03:37:45,367 11469 ERROR ihzacappassion odoo.tools.view_validation: :3:0:ERROR:RELAXNGV:RELAXNG_ERR_EXTRACONTENT: Element tree has extra content: field 2024-05-28 03:37:45,367 11469 ERROR ihzacappassion odoo.tools.view_validation: Invalid XML: Get RNG validator and validate RNG file. 2024-05-28 03:37:45,368 11469 DEBUG ihzacappassion odoo.tools.translate: translation went wrong for "'Invalid view %(name)s definition in %(file)s'", skipped
raise ParseError(msg) from None # Restart with "--log-handler odoo.tools.convert:DEBUG" for complete traceback
odoo.tools.convert.ParseError: while parsing /opt/odoo/Odoo16_VDL/catalog/views/vehicles_database_month_view.xml:41
Invalid view Tree Vehicles Database Month (catalog.tree_vehicles_database_month) definition in catalog/views/vehicles_database_month_view.xml
View error context:
'-no context-'