IMPORTANT: REVIEW your Program Rules before updating to Android 2.2 in production

The evaluation parser used by the rule engine of DHIS2 has been updated and some of your program rules might stop working in the new version of the Android App (2.2). The web interface might incorporate this changes at a different pace hence behaviour in web and Android might differ. Below you can find the changes that might impact your setup and some help on how to identify the problems.

PLEASE read carefuly this message and review your configuration before deploying the Android App 2.2 in production environments.

Change in d2:hasValue

Description

d2:hasValue now works with both single quotes or full variable expression (d2:hasValue(‘variable_name’) and d2:hasValue(#{variable_name}))

How to identify via API?

Get programRules where either the condition or the program rule action uses the d2:hasValue function.

https://example.org/api/programRules?fields=program[name],name,programRuleActions[data],condition&filter=programRuleActions.data:like:hasValue&filter=condition:like:hasValue&rootJunction=OR

<programRule name="PR01 - Check variable with hasValue(#{variable})">
  <condition>d2:hasValue(#{Age in years})</condition> <---- HERE
  <program name="JB_Testing_2.2"/>
  <programRuleActions>
    <programRuleAction/>
</programRuleActions>
</programRule>
<programRule name="PR01 - Check variable with hasValue('variable')">
  <condition>d2:hasValue('Age in years')</condition> <---- HERE
  <program name="JB_Testing_2.2"/>
  <programRuleActions>
    <programRuleAction/>
  </programRuleActions>
</programRule>

How to fix it?

The example above shows how different ways of using the hasValue function will have the same effect as from version 2.2. There are no mandatory changes but have in mind that while writing new program rules being consistent might help avoiding problems.

Change in evaluation of a variable

Description

!#{varible_name} will only work with boolean type variables (BOOLEAN and TRUE_ONLY).

How to identify via API?

Get programRulesVariables with dataElements of the type NOT BOOLEAN or TRUE_ONLY

https://example.org/api/programRuleVariables?fields=name&filter=dataElement.valueType:!in:[TRUE_ONLY,BOOLEAN]&paging=False

Get all programRule.conditions

https://example.org/api/programRules?fields=displayName,condition&paging=False

Check manually (or programmatically via a script) if in the list of programRule.conditions (obtained via the second API call) any of the program rules variables (obtained via the first API call) is being used.

For example, from the first list we get:

<programRuleVariable name="AdditionalMedication"/>
<programRuleVariable name="age"/>
<programRuleVariable name="Age in years"/> <--------------------- HERE
<programRuleVariable name="AgeYears"/>
<programRuleVariable name="allergies"/>
<programRuleVariable name="apgarcomment"/>

And we can compare with the second list:

<programRule>
  <condition>!#{Pregant}</condition>
  <displayName>PR03- !#{varible_name} - BOOLEAN</displayName>
</programRule>
<programRule>
  <condition>!#{Age in years}</condition> <------------------------ HERE 
  <displayName>PR03- !#{varible_name} - NOT BOOLEAN</displayName>
</programRule>
  <programRule>
  <condition>#{PregnancyStatus} != 'YES'</condition>
<displayName>Pregnancy status : false</displayName>
</programRule>

This shows that a NON BOOLEAN variable (Age in years) is being used wrongly.

How to fix it?

Make sure that you are evaluating BOOLEAN or TRUE_ONLY variables in your conditions. In case the program rule variable is not of that type update your program rule condition with d2:hasValue(#{variable_name}) or d2:hasValue(‘variable_name’)

In the example above the condition should change from:

<condition>!#{Age in years}</condition>

To:

<condition>!d2:hasValue(‘Age in years’)</condition>

Change in the evaluation of texts

Description

In program rule actions (ASSIGN, DISPLAY TEXT, DISPLAY KEY/VALUE PAIR) If the Expression to evaluate and assign/display is a text, it has to be in single quotes.

How to identify via API?

Get the Program Rules which actions are of type text, with something on the field data and verify their data content to find strings without quotes.

https://example.org/api/programRules?fields=program[name],name,programRuleActions[programRuleActionType,content,data]&filter=programRuleActions.programRuleActionType:in:[ASSIGN,DISPLAYTEXT,DISPLAYKEYVALUEPAIR,SHOWWARNING,SHOWERROR]&filter=programRuleActions.data:!null&paging=false

For example we can detect here an error of a text field without quotes in the first Program Rule Action while the second one is correct.

<programRule name="PR04- !#{varible_name} - BOOLEAN - Assign text without quotes">
<program name="JB_Testing_2.2"/>
  <programRuleActions>
    <programRuleAction>
      <programRuleActionType>SHOWWARNING</programRuleActionType>
      <data>embarazada</data>  <--------------------------- HERE
      <content>PR04 text with quotes is: </content>
     </programRuleAction>
  </programRuleActions>
</programRule>
<programRule name="PR04- !#{varible_name} - BOOLEAN - Assign text with quotes">
  <program name="JB_Testing_2.2"/>
  <programRuleActions>
    <programRuleAction>
      <programRuleActionType>SHOWWARNING</programRuleActionType>
      <data>'embarazada'</data> <------------------------- HERE
      <content>PR04 text with quotes is: </content>
    </programRuleAction>
  </programRuleActions>
</programRule>

How to fix it?

Scan the generated list (via the suggested API calls) to find data components of the Program Rule Action where text is not quoted, then go to each of the identified Program Rules and update them.

Change in concatenation of string and objects

Description

In program rule actions (ASSIGN, DISPLAY TEXT, DISPLAY KEY/VALUE PAIR) If the Expression to evaluate and assign/display is a text, it has to be in single quotes (same as previous change) but, on top of that, if it requires to concatenate two strings or a combination of functions it is mandatory to use the d2:concatenate function.

How to identify via API?

Get the Program Rules which actions are of type text, with any content on the field data and verify their data content to check if in case of two or more strings (or other objects) are being joined the d2:concatenate function is used

Get the Program Rules which actions are of type text and verify their data content to find strings without quotes.

http://localhost:8034/api/programRules?fields=program[name],name,programRuleActions[programRuleActionType,content,data]&filter=programRuleActions.programRuleActionType:in:[ASSIGN,DISPLAYTEXT,DISPLAYKEYVALUEPAIR,SHOWWARNING,SHOWERROR]&filter=programRuleActions.data:!null&paging=false

For example we can detect here an error of two strings in an action without the use of d2:concatenate.

<programRule name="PR08- Assign text and variable without concatenate">
<program name="JB_Testing_2.2"/>
  <programRuleActions>
    <programRuleAction>
      <programRuleActionType>SHOWWARNING</programRuleActionType>
      <data>'Age is 10 and modulus' 'another string'</data> <-------------- HERE
      <content>PR05 text without concat is: </content>
    </programRuleAction>
  </programRuleActions>
</programRule>

How to fix it?

Scan the generated list (via the suggested API calls) to find data components of the Program Rule Action where two or more objects are being concatenated and update them to use the d2:concatenate function.

In the example above the data should change from:

<data>'Age is 10 and modulus' 'another string'</data>

To:

<data>d2:concatenate('Age is 10 and modulus','another string')</data>

These changes have been registered in the official documentation (https://docs.dhis2.org/2.34/en/dhis2_android_capture_app/program-rules-supported-in-android-capture-app.html#changes-in-program-rules-from-22-version) but we are listing them here in case you need help.
2 Likes