fix HyperFormula custom functions and add FIXED formula (#6645)

* fix custom HyperFormula functions

* add FIXED formula

* note

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Matt Fiddaman
2026-01-19 17:00:40 +00:00
committed by GitHub
parent 59233c4786
commit cdae09e554
7 changed files with 67 additions and 4 deletions

View File

@@ -148,6 +148,7 @@ const LOGICAL_FUNCTIONS = new Set([
const TEXT_FUNCTIONS = new Set([
'TEXT',
'FIXED',
'CONCATENATE',
'LEFT',
'RIGHT',

View File

@@ -511,6 +511,14 @@ export const queryModeFunctions: Record<string, FunctionDef> = {
{ name: 'format', description: 'Format' },
],
},
FIXED: {
name: 'FIXED',
description: t('Formats a number to a fixed amount of decimal places.'),
parameters: [
{ name: 'number', description: 'Number' },
{ name: 'decimals', description: 'Decimals' },
],
},
REPT: {
name: 'REPT',
description: t('Repeats text specified number of times.'),

View File

@@ -122,6 +122,14 @@ export const transactionModeFunctions: Record<string, FunctionDef> = {
{ name: 'format', description: 'Format' },
],
},
FIXED: {
name: 'FIXED',
description: t('Formats a number to a fixed amount of decimal places.'),
parameters: [
{ name: 'number', description: 'Number' },
{ name: 'decimals', description: 'Decimals' },
],
},
REPT: {
name: 'REPT',
description: t('Repeats text specified number of times.'),

View File

@@ -1,5 +1,7 @@
import { useEffect, useState } from 'react';
import { HyperFormula } from 'hyperformula';
import { send } from 'loot-core/platform/client/fetch';
import * as monthUtils from 'loot-core/shared/months';
import { q, type Query } from 'loot-core/shared/query';
@@ -40,7 +42,6 @@ export function useFormulaExecution(
let cancelled = false;
async function executeFormula() {
const { HyperFormula } = await import('hyperformula');
let hfInstance: ReturnType<typeof HyperFormula.buildEmpty> | null = null;
if (!formula || !formula.startsWith('=')) {
@@ -118,6 +119,7 @@ export function useFormulaExecution(
hfInstance = HyperFormula.buildEmpty({
licenseKey: 'gpl-v3',
localeLang: typeof locale === 'string' ? locale : 'en-US',
language: 'enUS',
});
// Add a sheet and set the formula in cell A1

View File

@@ -2,6 +2,7 @@
import * as dateFns from 'date-fns';
import * as Handlebars from 'handlebars';
import { HyperFormula } from 'hyperformula';
import enUS from 'hyperformula/i18n/languages/enUS';
import { amountToInteger } from 'loot-core/shared/util';
@@ -10,9 +11,18 @@ import { currentDay, format, parseDate } from '../../shared/months';
import { FIELD_TYPES } from '../../shared/rules';
import { type TransactionForRules } from '../transactions/transaction-rules';
import { CustomFunctionsPlugin } from './customFunctions';
import {
CustomFunctionsPlugin,
customFunctionsTranslations,
} from './customFunctions';
import { assert } from './rule-utils';
HyperFormula.registerLanguage('enUS', enUS);
HyperFormula.registerFunctionPlugin(
CustomFunctionsPlugin,
customFunctionsTranslations,
);
const ACTION_OPS = [
'set',
'set-split-amount',
@@ -258,10 +268,9 @@ export class Action {
}
try {
HyperFormula.registerFunctionPlugin(CustomFunctionsPlugin);
hfInstance = HyperFormula.buildEmpty({
licenseKey: 'gpl-v3',
language: 'enUS',
});
const sheetName = hfInstance.addSheet('Sheet1');

View File

@@ -15,6 +15,17 @@ export class CustomFunctionsPlugin extends FunctionPlugin {
},
);
}
fixed(ast: ProcedureAst, state: InterpreterState) {
return this.runFunction(
ast.args,
state,
this.metadata('FIXED'),
(number: number, decimals: number = 0) => {
return Number(number).toFixed(decimals);
},
);
}
}
CustomFunctionsPlugin.implementedFunctions = {
@@ -29,4 +40,22 @@ CustomFunctionsPlugin.implementedFunctions = {
},
],
},
FIXED: {
method: 'fixed',
parameters: [
{ argumentType: FunctionArgumentType.NUMBER },
{
argumentType: FunctionArgumentType.NUMBER,
optionalArg: true,
defaultValue: 0,
},
],
},
};
export const customFunctionsTranslations = {
enUS: {
INTEGER_TO_AMOUNT: 'INTEGER_TO_AMOUNT',
FIXED: 'FIXED',
},
};