Validating Checksums in Power Apps
Recently I was asked to implement validation for Australian Medicare numbers. This uses a combination of regular expression and calculation based on the provided numbers and compared against a checksum digit. You can find an example of this validation in Javascript in StackOverflow: javascript - How do I validate an Australian Medicare number? - Stack Overflow.
There are two parts to this. The first is the number format. The number should start with any of these numbers: 2, 3, 4, 5, 6 followed by 8 digits, and ends with the issue number. In some cases, the IRN number is also provided as the 11th digit. (See here: Clearwater Software)
Secondly, the 9th digit represents the check number. We take the first 8 digits and multiply each individual digit to a corresponding sequence of 1, 3, 7, 9, 1, 3, 7, 9 (#1 digit x 1, #2 digit x 3, #3 digit x 7, #4 x 9, #5 x 1...). Then we take the sum of all the values from the multiplications, and then divide it by 10. The remainder of this division must match the number at the 9th digit.
How do we "low-code" this in Power Fx?
Here's how:
First, set up the calculation table in memory by creating a new collection:
ClearCollect(checksums,
{ num: 1, value: 1, med: 0, total: 0}, { num: 2, value: 3, med: 0, total: 0},
{ num: 3, value: 7, med: 0, total: 0}, { num: 4, value: 9, med: 0, total: 0},
{ num: 5, value: 1, med: 0, total: 0}, { num: 6, value: 3, med: 0, total: 0},
{ num: 7, value: 7, med: 0, total: 0}, { num: 8, value: 9, med: 0, total: 0}
);
Set(_isValid, false);
I can do this in the app on start or on my screen's on visible. value here is the multiplier, and med here is the medicare number's digit.
Next to a textinput control for the medicare number, I added a Check button to run the validation logic. Here's the code:
If(IsMatch(TextInput1.Text, "[2,3,4,5,6]\d{9}\d?"),
With({ medicareNums: Split(TextInput1.Text, "")},
ForAll(Sequence(8, 1) As seq,
With({ checksum: LookUp(checksums, num = seq.Value), medNum: Value(Last(FirstN(medicareNums, seq.Value)).Result)},
Patch(checksums, checksum, { med: medNum, total: medNum * checksum.value })
)
);
Set(_isMedicareValid, RoundDown(Mod(Sum(checksums, total), 10),0) = Value(Last(FirstN(medicareNums, 9)).Result))
),
Set(_isMedicareValid, false)
);
The first check is simply a regex check using IsMatch expression. It basically verifies that the first digit should be either one of [2, 3, 4, 5, 6], followed by 8 digits + 1 issue number (total 9 digits), and ends with 1 optional digit if the IRN is provided.
If the input matches the regex pattern, I use the With function to split the input into individual digits, and loops through the 8 records in my checksum table and the corresponding digit in the medicare number (medNum), and set the value into the table (med) with total holding the value of the multiplication result using Patch function (writes back to the collection in memory). The _isMedicareValid variable stores the result of the sum of the totals in the table, divided by 10 with the remainder compared against the 9th digit of the medicare number. If it matches, it is valid.
Here's a sample app that demonstrates this in action, with a table rendered to show the calculation (actual medicare number redacted):
Download the example here (.msapp file - go to https://create.powerapps.com and open from your download location).
Note: Similarly for TFN (Australian Tax File Number) validations - just different weighted multipliers and checksums.
Thanks for sharing FooShen Wu this is really helpful
Nice work FooShen!
Awesome 👏
Brilliant!