This demo shows how to define conditional groups. The report for this demo creates a Profit and Loss Statement report for the Open Source accounting package jGnash. The expected output looks like:
Income Account 1 9999.99 Account 2 9999.99 Total Income 99999.99 Expense Account A Account Z 99.99 Account Y 999.99 Total Account A 9999.99 Account B 9999.99 Total Expense 99999.99 Net Profit/Loss 99999.99
As you can see, account 'A' has sub accounts, which should be printed, while account 'B' has no sub accounts. According to the control-break-algorithm, either each group must have sub groups, or no group must have sub groups.
We can solve the conflict rather easily by hiding the second level group header and footer when the account has no sub groups. We will discuss the used function later.
The data is formatted as follows:
type | level-one-account | level-two-account | balance |
---|---|---|---|
Income | Account 1 | - | 9999.99 |
Income | Account 2 | - | 9999.99 |
Expense | Account A | Account Z | 9999.99 |
Expense | Account A | Account Y | 9999.99 |
Expense | Account B | - | 9999.99 |
As you can see here, the table contains the necessary structures to support two levels of accounts. If an account has no sub accounts, the 'level-two-account' column is null for these rows. We will use that null-value as indicator whether the second level group header should be hidden.
The magical work is done by two functions, TriggerNestedGroupFunction and TriggerTypeFunction.
The TriggerTypeFunction processes the top group and shows and hides the income and expense headers depending on the content of the "type" column of the assigned tablemodel.
The TriggerNestedGroupFunction checks, whether the current group is a nested group. A nested group is recognized by its non-null content in the column "level-two-account". Depending on whether a nested group is found, either the itemband for the nested group and the group header and footer for that group are made visible or the normal, non-nested itemband is made visible.
A third custom function collects the totals from the income and expense group and computes the netto profit. As this function reuses the results from other function, we have to make sure, that the used functions are executed before the netto-profit function tries to query the sums. This is done by declaring a dependency level for the used functions, which is higher than the dependency level for the netto-profit function (which defaults to '0').