PLEASE NOTE: There is an updated article which explains how to use direct calls from a Power App using Custom Actions instead of Power Automate Flows. This is a much simpler and more performant way of achieving the same result. See the details here: https://support.north52.com/knowledgebase/article/KA-10514-dynamics-crm-365-xRM-Formula-284-Complex-rules-in-Canvas-Power-App-using-direct-Custom-Action-call/en-us
Overview
Complex rules are often required to be executed as part of a Canvas Power App. North52's business rules engine for Microsoft Dynamics 365 and the Power Platform is a perfect partner when you need to evaluate complex rules in a Canvas App.
In this article, we will use the example of calculating a risk score for Coronary Heart Disease via a Canvas App. The rules and Decision Table structure for the calculation have been outlined in a previous article where the calculation is being made in a Model-Driven App.
This example shows how stateless processing can be used with North52's business rules engine.
Rules for Calculating Coronary Heart Disease Risk
Please see the previous article for the rules table.
North52 Decision Suite Solution
The North52 Decision Suite solution works like this:
- A Custom Action is set up with one input and one output parameter
- The Custom Action is triggered from the Canvas App via a Power Automate Flow
- The Canvas App passes data from the App to the Flow
- A Formula is set up on the Custom Action which:
- Takes the data from the Canvas App
- Evaluates the data using risk criteria on several Decision Tables
- Returns results of the Risk Score as JSON
- The JSON is returned to the Canvas App via the Flow and converted into a Collection
- The data from the Collection is used to display the Risk Score and Messages on the Canvas App
Set up Global Action, Formula, Flow and Canvas App
There are 4 parts to configure for this example: Global Action, Formula, Power Automate Flow and a Canvas App.
Global Action
Set up a Global Action with two parameters:
- PayloadInRiskParametersJSON
- Type = String
- Direction = Input
- PayloadOutRiskResultsJSON
- Type = String
- Direction = Output
Formula
For details of how to construct the evaluation criteria for the risk score see the xRM Formula #161 - Coronary Heart Disease Risk Score article.
The major differences for this example are:
- The Formula is of Type Action
- Source Entity is N52 Command
- JSON is parsed on the Global Calculations sheet
- These values are used on the Decision Sheets evaluating the risk
- The Risk Score and Messages are output to the Action parameter PayloadOutRiskResultsJSON
Formula Type
- The Formula is of Type Action bound to the Action Event n52demo_HeartDiseaseRiskAction
- First Decision Sheet calculating the Smoking risk is shown below:
Global Calculations Sheet
- The Global Calculations sheet maps values from the PayloadInRiskParametersJSON input parameter to individual calculations that can be easily referenced in the Decision Sheets (like the Smoking one above)
- Firstly the PayloadInRiskParametersJSON input parameter is assigned to the North52 internal variable called responsecontent
- Then individual values are assigned, for example, Current Smoker is assigned on row 4
Risk Calculation Sheet
- Column J is an incremental inline calculation
- Column K is an inline calculation that calls a parameterized Global Action (see next image below for details)
- The highlighted cell K4 shows the BuildJSON Global Action with the first parameter 'Smoke Risk' and the second parameter 'The patient has a smoke risk.'
BuildJSON Global Action
- The BuildJSON Global Action shows how we are constructing JSON to collate the messages for each matching risk
- An example of the output for this Global Action:
{ "risktype": "Smoke Risk", "message": "The patient has a smoke risk." }
Action Response Sheet
- This sheet provides the response to the Action's PayloadOutRiskResultsJSON output parameter
- The highlighted contents of cell A4 shows construction of the JSON, including the Risk Messages JSON from above
- An example of the output for this output parameter:
{ "Results": { "RiskScore": 3, "RiskMessages": [ { "risktype": "Smoke Risk", "message": "The patient has a smoke risk." }, { "risktype": "Dyslipidemia Risk", "message": "The patient has a dyslipidemia risk." }, { "risktype": "Family History Risk", "message": "The patient has a family history risk." } ] } }
Power Automate Flow
The Power is relatively simple with just 3 steps:
- Trigger from PowerApps
- Perform an unbound action - this connects to our n52demo_HeartDiseaseRiskAction Action
- Assign the output from the Canvas Power App to the PayloadInRiskParametersJSON input parameter
- Response
- Set the Body to the output from the previous step: PayloadOutRiskResultsJSON
- Create the Response Body JSON Schema from sample JSON - this can be easily obtained by running the Flow and analysing the results
- NOTE: do not use the Respond to a PowerApp or flow step as this will return the JSON to the Canvas Power App as a string and cannot be added directly to a collection in the Canvas Power App
Canvas App
Within the Canvas App there are two important parts to review:
- The OnSelect property of a button to collect the values and submit them to the Power Automate Flow
- The DataTable which shows the messages that have been returned as part of the JSON response
OnSelect of Button
- The values from many input objects are collated in a Collection called FormulaData (1)
- This FormulaData Collection is passed to the PowerApp->CallNorth52HeartDiseaseRiskAction (2) Power Automate Flow as JSON (3)
- The Flow returns the Results (4) and adds this to another Collection called RiskScoreResults
- The property RiskScore (5) is obtained from the RiskScoreResults collection
DataTable
- A DataTable is shown using the RiskMessages property of the RiskScoreResults Collection