Monday, 4 June 2012


Since I’ve been given the opportunity to play with K2 smartforms, I’ve constructed quite a few scenarios, each of which aimed at a specific area (or component) within the product.

This week I decided to target the Expression builder, in order to test whether the component could handle complex functions, and if they passed, if it made a noticeable impact on performance.

For this implementation, I built a tax calculator, incorporating the various tax brackets we have in South Africa. The different brackets, and their respective tax calculations, are represented by the below spread sheet:

0                <     160000       Tax = (Salary * 0.18) - Rebate
160000       <     250000       Tax = (28000 + 0.25*(Salary - 160000)) - Rebate
250000       <     346000       Tax = (51300 + 0.3*(Salary - 250000)) - Rebate
346000       <     484000       Tax = (80100 + 0.35*(Salary - 346000)) - Rebate
484000       <     617000       Tax = (128400 + 0.38*(Salary - 484000)) - Rebate
617000       >=                    Tax = (178940 + 0.4*(Salary - 617000)) - Rebate
*The rebate used in this example amounted to R 11 440.00.

This can be calculated by means of the following console app:
using System;
public class TaxCalc
{
    static void Main()
    {
        Console.Write("Enter your yearly salary: ");
        string input = Console.ReadLine();

        decimal mySalary = Convert.ToDecimal(input);

        decimal myTax = 0.0m;

        if ((mySalary > 0) & (mySalary <= 160000))
        {
            myTax = (0.18m * mySalary) - 11440;
        }
        else if ((mySalary > 160000) & (mySalary <= 250000))
        {
            myTax = (28000 + 0.25m * (mySalary - 160000)) - 11440;
        }
        else if ((mySalary > 250000) & (mySalary <= 346000))
        {
            myTax = (51300 + 0.3m * (mySalary - 250000)) - 11440;
        }
        else if ((mySalary > 346000) & (mySalary <= 484000))
        {
            myTax = (80100 + 0.35m * (mySalary - 346000)) - 11440;
        }
        else if ((mySalary > 484000) & (mySalary <= 617000))
        {
            myTax = (128400 + 0.38m * (mySalary - 484000)) - 11440;
        }
        else
        {
            myTax = (178940 + 0.4m * (mySalary - 617000)) - 11440;
        }

        Console.WriteLine("Your yearly tax is: {0}", myTax);
        Console.ReadKey();

    }
}

Using K2 smartforms, I created a Form which looked as follows:

The Forms consists of:
·         An Item View – which is used to enter and capture new salary line items
·         A List View – which is used to display all previously captured items
·         Various Form-level [Label] and [DataLabel] controls, used to do the various calculations

I started with a basic Rule to transfer the data from the Item- to the List View. The List View contains a [Sum] aggregation on the “Value” column, which is hidden in this instance. From here I simply transfer the value of this hidden aggregation, to the “Monthly Income [DataLabel]” from there the actual calculations start. The value of the “Monthly Income [DataLabel]” is multiplied by twelve and transferred to the “Yearly Income [DataLabel]”.

Once I have this value, I execute a rather complex nested “IF” inline function, in order to determine the appropriate bracket, and the yearly tax thereof. A simple example of the expression would look something like this:
IF ((mySalary > 0) & (mySalary <=160000), 0.18*mySalary, (IF ((mySalary > 160000) & (mySalary <= 250000), 28000 + 0.25*(mySalary - 160000), IF ((mySalary > 250000) & (mySalary <= 346000), 51300 + 0.3*(mySalary – 250000), etc…

Here’s a screenshot of the actual Expression:


I used various other simple expressions in order to calculate the monthly tax, and both Nett Income amounts (including null checks, validation etc.)

In my test I found that the runtime execution of the Expression via K2 smartforms was both accurate and immediate from the user perspective.

Here is a comparison between the results from K2 smartforms and the console application:

[Console]

[K2 smartforms]


On a side note, I initially created this Expression on two controls in an Item View just in order to test the functionality. Only afterwards, I decided that I wanted to try this in the above pictured scenario. The problem was though, that the Expression now resided on a View which I did not want to use in my scenario.

As a workaround, I created the above Form, complete with everything except this complex Expression. I then used ‘Firebug’ to determine the GUID of the control to which I wanted to point the Expression (as the Expression only uses a single ‘source’ control in order to execute). The next step was to query the K2 smartforms DB’s, and extract my expression which was saved in XML format in the [Form].[View_Design].

Once I had the extracted XML, I could replace the old GUID’s with the GUID of the new control. I then simply ran an update script against my Form in the [Forms].[Form_Design] table to inject my Expression into the new Form, bound the Expression to a new ‘destination’ control, and presto!