EdgeVerve / feel

Expression Language for creating and executing business rules in decision table based on DMN 1.1 specification for conformance level 3
MIT License
93 stars 48 forks source link

Little bug when we try to nest decimal function #29

Closed OlivierAlbertini closed 2 years ago

OlivierAlbertini commented 2 years ago

Hi,

Currently I try to do the following thing :

const rule = 'decimal(decimal(0.22 * a, 0) * 223.65, 0)';
const context = {
    a: 10
};

const parsedGrammar = feel.parse(rule);

parsedGrammar.build(context).then(result => {
    console.log(result);
}).catch(err => console.error(err));

Expected behaviour

I expect to have 447 in the result

Current behaviour

I currently have Error: 'string * number : operation unsupported for one or more operands types'

The reason

After investigating why we have this error, I found that decimal function is const decimal = (n, scale) => n.toFixed(scale) toFixed is a formatting function, which has a sole purpose of converting a number to a string, formatting it using the specified number of decimals.

After checking the DMN Spec shared in the readme decimal should return a number and not a string (at page 103, page 109 (10.3.2.3.1 number), page 113 (10.3.2.10 Mapping between FEEL and other domains), page 133 (Table 62: Semantics of numeric functions)) FEEL Expression Value
decimal(1, 2) 1.00

Proposed solution

By changing the decimal function to :

const decimal = (n, scale) => {
  const pow = Math.pow(10, scale);
  return Math.round(n*pow) / pow;
};

If you are agree with this solution, I could make a PR. Let me know thanks !