diff --git a/src/utils/expression-parser.test.ts b/src/utils/expression-parser.test.ts index 57910f798..fe154269e 100644 --- a/src/utils/expression-parser.test.ts +++ b/src/utils/expression-parser.test.ts @@ -7,9 +7,15 @@ import { linkReferencedFieldValues, parseExpression, replaceFieldRefWithValuePath, + expressionFormatter, } from './expression-parser'; import { testFields } from './expression-runner.test'; +const testFieldValues = { + patientIdentificationNumber: 'test value 1', + linkedToCare: 'test value 2', +}; + describe('Expression parsing', () => { it('should split expression 1 into parts correctly', () => { const input = @@ -306,3 +312,36 @@ describe('hasParentheses', () => { expect(hasParentheses(expression)).toBe(true); }); }); + +describe('expression formatter function', () => { + it('should not care about whether there are spaces around operators', () => { + const expressionA = "linkedToCare!=='a8aaf3e2-1350-11df-a1f1-0026b9348838"; + const expressionB = 'patientIdentificationNumber+linkedToCare'; + const expressionC = "patientIdentificationNumber== 'a8aaf3e2-1350-11df-a1f1-0026b9348838"; + const expressionD = + "!isEmpty(referredToPreventionServices)&&isEmpty(myValue) && (bodyTemperature==='a890d1ba-1350-11df-a1f1-0026b9348838')"; + + const testFieldValues = { + patientIdentificationNumber: 'test value 1', + linkedToCare: 'test value 2', + bodyTemperature: 'test value 3', + referredToPreventionServices: 'test value 4', + }; + + expect(expressionFormatter(expressionA, testFields, testFieldValues)).toBe( + "fieldValues.linkedToCare!=='a8aaf3e2-1350-11df-a1f1-0026b9348838", + ); + + expect(expressionFormatter(expressionB, testFields, testFieldValues)).toBe( + 'fieldValues.patientIdentificationNumber+fieldValues.linkedToCare', + ); + + expect(expressionFormatter(expressionC, testFields, testFieldValues)).toBe( + "fieldValues.patientIdentificationNumber== 'a8aaf3e2-1350-11df-a1f1-0026b9348838", + ); + + expect(expressionFormatter(expressionD, testFields, testFieldValues)).toBe( + "!isEmpty(fieldValues.referredToPreventionServices)&&isEmpty(myValue) && (fieldValues.bodyTemperature==='a890d1ba-1350-11df-a1f1-0026b9348838')", + ); + }); +}); diff --git a/src/utils/expression-parser.ts b/src/utils/expression-parser.ts index 8243e7254..855c486d1 100644 --- a/src/utils/expression-parser.ts +++ b/src/utils/expression-parser.ts @@ -156,3 +156,21 @@ function findReferencedFieldIfExists(fieldId: string, fields: FormField[]): Form } return fields.find((field) => field.id === fieldId); } + +export function expressionFormatter(expression: string, fields: FormField[], fieldValues: Record): string { + const matchedFields = []; + let formattedExpression = expression; + + fields.forEach((field) => { + if (expression.includes(field.id) && !expression.includes(`fieldValues.${field.id}`)) { + matchedFields.push(field); + } + }); + + if (matchedFields?.length) { + matchedFields.forEach((field) => { + formattedExpression = replaceFieldRefWithValuePath(field, fieldValues[field.id], formattedExpression); + }); + } + return formattedExpression; +} diff --git a/src/utils/expression-runner.ts b/src/utils/expression-runner.ts index d64fd0147..3df478290 100644 --- a/src/utils/expression-runner.ts +++ b/src/utils/expression-runner.ts @@ -2,7 +2,12 @@ import { getRegisteredExpressionHelpers } from '../registry/registry'; import { isEmpty } from 'lodash-es'; import { type OpenmrsEncounter, type FormField, type FormPage, type FormSection } from '../types'; import { CommonExpressionHelpers } from './common-expression-helpers'; -import { findAndRegisterReferencedFields, linkReferencedFieldValues, parseExpression } from './expression-parser'; +import { + expressionFormatter, + findAndRegisterReferencedFields, + linkReferencedFieldValues, + parseExpression, +} from './expression-parser'; import { HistoricalDataSourceService } from '../datasources/historical-data-source'; import { type Visit } from '@openmrs/esm-framework'; @@ -75,7 +80,7 @@ export function evaluateExpression( _, }; - expression = linkReferencedFieldValues(fields, fieldValues, parts); + expression = expressionFormatter(linkReferencedFieldValues(fields, fieldValues, parts), fields, fieldValues); try { return evaluate(expression, expressionContext);