From 3d4a4fc60d682480b6cfc69a68f5dc33894a9cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Tue, 5 Dec 2023 11:19:29 +0100 Subject: [PATCH 1/2] Handle NaN in safediv, empty string, and subsitute = by == --- src/components/dataentry/CodeGenerator.js | 17 ++++++++++------- src/components/dataentry/FunctionRegistry.js | 2 +- .../dataentry/FunctionRegistry.test.js | 6 ++++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/components/dataentry/CodeGenerator.js b/src/components/dataentry/CodeGenerator.js index 8ab1b0c8..1640db7b 100644 --- a/src/components/dataentry/CodeGenerator.js +++ b/src/components/dataentry/CodeGenerator.js @@ -13,6 +13,8 @@ export const defaultSubstitutions = () => { export const fixIfStatement = (expression) => { expression = expression.replace("if (", "IF("); expression = expression.replace("if(", "IF("); + expression = expression.split(" = ").join(" == "); + expression = expression.split(" =0").join(" == 0"); return expression; }; export const generateGetterSetterForState = (hesabuPackage, activity, state, orgunitid, period) => { @@ -27,6 +29,7 @@ export const generateGetterSetterForState = (hesabuPackage, activity, state, org ); codes.push(" const v = calculator.indexedValues()[k]"); codes.push(' if(v && v[0].value == "") { return 0 }'); + codes.push(' if(v && v[0].value == " ") { return 0 }'); codes.push(" if(v) { return parseFloat(v[0].value) }"); codes.push(" }"); codes.push(` return calculator.field_${field_name} == undefined ? 0 : this.field_${field_name}`); @@ -54,6 +57,7 @@ export const generateGetterSetterForStateQuarterly = (hesabuPackage, activity, s ); codes.push(" const v = calculator.indexedValues()[k]"); codes.push(' if(v && v[0].value == "") { return 0 }'); + codes.push(' if(v && v[0].value == " ") { return 0 }'); codes.push(" if(v) { return parseFloat(v[0].value) }"); codes.push(" }"); codes.push(` return calculator.field_${field_name} == undefined ? 0 : this.field_${field_name}`); @@ -81,6 +85,7 @@ export const generateGetterSetterForStateLevel1Quarterly = (hesabuPackage, activ ); codes.push(" const v = calculator.indexedValues()[k]"); codes.push(' if(v && v[0].value == "") { return 0 }'); + codes.push(' if(v && v[0].value == " ") { return 0 }'); codes.push(" if(v) { return parseFloat(v[0].value) }"); codes.push(" }"); codes.push(` return calculator.field_${field_name} == undefined ? 0 : this.field_${field_name}`); @@ -124,8 +129,6 @@ export const generateActivityFormula = ( stateOrFormulaCodes, states, ) => { - let expandedformula = "" + formula.expression; - expandedformula = fixIfStatement(expandedformula); const substitutions = defaultSubstitutions(); for (let substit of stateOrFormulaCodes) { substitutions[substit] = `calculator.${hesabuPackage.code}_${activity.code}_${substit}_${orgunitid}_${period}()`; @@ -138,7 +141,6 @@ export const generateActivityFormula = ( substitutions[ substit + "_quarterly" ] = `calculator.${hesabuPackage.code}_${activity.code}_${substit}_quarterly_${orgunitid}_${period}()`; - } if (hesabuPackage.activity_decision_tables) { for (let rawDecisionTable of hesabuPackage.activity_decision_tables) { @@ -160,10 +162,12 @@ export const generateActivityFormula = ( for (let substit of states) { substit = substit + "_level_1_quarterly"; substitutions[substit] = `calculator.${hesabuPackage.code}_${activity.code}_${substit}_${orgunitid}_${period}()`; - } - const tokens = tokenize(formula.expression); + let expandedformula = "" + formula.expression; + expandedformula = fixIfStatement(expandedformula); + + const tokens = tokenize(expandedformula); expandedformula = tokens.map((token) => substitutions[token] || token).join(""); @@ -321,9 +325,8 @@ export const generateCode = ( ), ); - const states = stateOrFormulaCodes.filter((k) => !allFormulaCodes.includes(k)); - + for (let period of DatePeriods.split(invoicePeriod, hesabuPackage.frequency)) { for (let activity of hesabuPackage.activities) { // states getter/setter diff --git a/src/components/dataentry/FunctionRegistry.js b/src/components/dataentry/FunctionRegistry.js index 98c0b492..e27853aa 100644 --- a/src/components/dataentry/FunctionRegistry.js +++ b/src/components/dataentry/FunctionRegistry.js @@ -2,7 +2,7 @@ import _ from "lodash" export const SAFE_DIV = (a, b) => { - if (b !== 0) { + if (!isNaN(a) && !isNaN(b) && a!== undefined && b !== 0) { return a / b; } return 0; diff --git a/src/components/dataentry/FunctionRegistry.test.js b/src/components/dataentry/FunctionRegistry.test.js index a9a29bf6..9112f66a 100644 --- a/src/components/dataentry/FunctionRegistry.test.js +++ b/src/components/dataentry/FunctionRegistry.test.js @@ -171,6 +171,12 @@ describe("FunctionRegistry", () => { it("divide a by b", () => { expect(safeDiv(8, 10)).toEqual(0.8) }) + it("divide NaN by b", () => { + expect(safeDiv(NaN, 10)).toEqual(0) + }) + it("divide a by NaN", () => { + expect(safeDiv(10, NaN)).toEqual(0) + }) }) describe("ABS", () => { From a9d5e6575dafab8e30bfb5694a674859d6ab7e24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Mestach?= Date: Tue, 5 Dec 2023 11:22:01 +0100 Subject: [PATCH 2/2] Changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b25058d..cb2305bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ + +# @blsq/blsq-report-components + +- [dateentry] solve problems with NaN in safediv function +- [dateentry] solve problems single equals not turned into == leading to "SyntaxError: invalid assignment left-hand side" + # @blsq/blsq-report-components@1.1.6 - [invoices] fix [previous bug](https://community.dhis2.org/t/api-datavaluesets-dont-allow-to-mix-dataset-and-dataelementgroup-anymore/51517) where datavalues can be loaded twice once via the deg and once via the ds causing double amounts