In the last episode we’ve seen how documents write data to the accumulation register, and the register calculates balances putting them on debit or credit side of an account depending on its type.
Looks almost identical to what an accumulation register does for us. Is there anything else to it? Of course there is. Unlike an accumulation register an accounting one provides us with so many different ways of slicing and dicing balances to give us as detailed a picture as we need.
This is what we’re gonna talk about today.
These are three features an accounting register supports that an accumulation register doesn’t: Accounts hierarchy, Optional dimensions and Extra dimensions
Let’s start with the hierarchy.
The thing with the accounts hierarchy is that you don’t even need to turn it on. It’s always here, which this Parent field kinda tips off.
So, I can just go ahead and add the Cash sub-account to our Assets, like this. I can also switch the dynamic list to the tree view, and here is my accounts tree in all its beauty.
Now. What level of the tree can I post my transactions to? Let’s register a loan and see what works and what doesn’t. Debiting the top-level Assets account. Crediting the Liabilities. And all works just fine. How about debiting the second-level Cash account instead? Posting it. And everything works just fine.
So, the answer is: I can post records to any level of the tree. But here is a better question for you: what level should I post records to?
Let’s think for a second: why did we start building the tree in the first place? Here is why. Say, I split this loaned money between my Chequing and Savings accounts. At this moment I can see only the total sum loaned without this split. To see their balances separately, I have to add two next-level accounts to the chart. Now I can distribute the sum between these new sub-accounts and the balance gets split accordingly.
I’m still not forbidden from posting a transaction to the parent account but if I do, I won’t be able to tell which part of this five thousand went where, and what is the correct current balance of these sub-accounts. So, posting to anything but the lowest level of the accounts tree literally defeats the purpose of this entire affair with sub-accounts.
This was our account hierarchy. Another way of slicing the account balances is called optional dimensions.
Let’s say we buy and sell stuff both in American and Canadian dollars. How do we account both currencies in the same accounting register? The most natural way of doing this is to add the Currency dimension that refers to the Currencies catalog like this. We also need the similar field here in the Business Transactions document, on it’s form and in its Posting event handler.
And now, let’s switch the accounts tree to the list view, add a couple more accounts and register a Sales transaction.
Let’s say somebody comes to the store and buys few essentials for cash: twenty Canadian dollars and ten American. The same amounts go to the credit side of the Sales account, and now these two account balances are split between Canadian and American dollars like this.
Now. What happens if I try to make a Sales transaction debiting amount in one currency and crediting the same amount in another one? This is what. The Platform cannot accept this transaction, and the reason is that the amount debited is not equal to the amount credited if we take into account the dimension values. Which is exactly what the Platform does. So, I need to fix it like this. Now the transaction is posted successfully and US Dollars balances are changed for both accounts.
So far, the accounting register dimensions look fairly similar to the accumulation register ones: they split the register balances by dimension values. But here is a unique feature of accounting register dimensions for you: they are optional.
You can choose which accounts to use and not to use them for. Here is an example for you. My imaginary shop accepts cash in both Candian and American dollars. So, this Cash on hand account should use the currency dimension. But these Checking and Savings guys are real bank accounts and, probably, accept the only currency. So I might as well just rename them like this and always consider their balances to be in this currency.
I also need to prevent a user from using currencies for this accounts at all. And this is how it’s done. Here in the Chart of Accounts metadata structure live attributes of a special type called Accounting flags. Their values control whether we want to use specific dimensions for specific accounts or not.
So, this is what I do. I’m adding a new accounting flag called UseCurrency, that can have only the Boolean type. Then I go to the accounting register and tell the currency dimension that its usage is dependent on the UseCurrency flag. To be able to set this flag for specific accounts, I’m showing it here on the account form. And I also added it to the account list on this form behind the scenes.
Let’s see how it works. So, this is my Cash on hand account I’m turning the UseCurrency flag on, and trying to repost this Sales transaction, and… And the Platform says that the second line of the document must not specify the Currency field value. And the second line is the one crediting this Sales account that has the UseCurrency flag off, so the Platform does not allow to specify currency here. But as soon as I turn the flag on the transaction becomes valid and the data goes to the register.
But wait a second. What happens to these guys? These are records posted by this Sales document, but the Currencies are now gone and the balance is all wrong - US and Canadian dollar amounts are mixed together.
Here is the thing. After we added this accounting flag to the application, its value was set to False by default for all accounts. Therefore, the Platform recalculated the balances disregarding the Currency value. Now, I switched the flags on, So as soon as I repost this document the currency is back and the balances are good.
So, the moral of the story is: never post transactions before you set the accounting flags, kids. Otherwise you will need to repost all these transactions once again.
This was the optional dimensions. The last feature that allows us to slice and dice the accounting register balance is called Extra dimensions.
This feature uses Chart of Characteristics - old friend of ours from episode 1. And this is what it looks like.
This is our Chart of Accounts, and this is the Accounting Register balance table with some records in it. Let’s say a user adds a new account called Inventory to track how much produce his company has on hand in monetary form. It seems like a good idea to break this account balance by products, but developers didn’t add such a dimension to the register. What they did add though is this Chart of Characteristics that users can fill out by themselves.
They also told the Chart of Accounts that it should use this Chart of Characteristics as a source for Extra Dimensions. So, what the Chart of Accounts does is add the standard tabular section called ExtraDimesions for a user to store what Extra Dimension belongs to what account.
After that a user can add an Extra Dimension to the chart and tell any number of accounts to use it. At this point the Accounting Register grows itself a couple of new fields, storing the Extra Dimension 1 value and its type. So, now a user can finally break this balance down by these two products.
This Type field is used to store the reference to the correspondent extra dimension record of this Chart because, of course, other accounts can use the same pair of fields to store different values. For example, we might want the Liabilities account to have a Company extra dimension. When we write this account records to the register, these values will sit right here - in the same value field, but the Type field reference will point at another Chart of Characteristics record. This allows us (and the register) to tell companies from products, etc.
This is how it works in a nutshell. Now let’s go implement this in a flesh, shall we?
First, I am adding a new Chart of Characteristics called ExtraDimensions. Then I’m allowing users to use any of these catalogs’ references as an extra dimension value. In case a user wants to create his own lists of values for extra dimensions, I’m adding a new catalog called ExtraDimensionValueLists, making it subordinate to the ExtraDimensions chart, and checking it in the same allowed types list.
Now let’s add these two new objects to the Accounting subsystem but hide them from the command interface like this.
I also need to tell the Chart of Accounts that it should use this Chart of Characteristic as a list of available extra dimensions. And that there might be no more than three extra dimensions per account. This is how many additional fields will be added to the accounting register and its Balance table, so please don’t go too crazy on this one. Set a reasonable limit - 3 or 5 dimensions is a way to go.
Now. If I go to the account form over here, this is the tabular section I need to specify the extra dimension set for each individual account. So, I’m dropping it to the form, tidying it up a little bit, and we’re all set here.
Now we need to retrofit the Business Transactions document over here with new attributes to store the extra dimension values and their types. This is where they will be posted to the register from along with the Account reference, etc. So, I’m adding a new ExtDim1 attribute to store the extra dimension value. This one should accept values of any type allowed by our Chart of Characteristics. Now I’m adding this Type brother to store a reference to the Chart record representing this value type. Now let’s just clone both of these a couple of times and we’re all set here.
Next step: post these extra dimensions to the register. This is my Posting event handler and this piece of code I’m adding is responsible for posting extra dimension values to the accounting register.
Let me explain to you what’s going on here. This is our main cycle through all the rows in the tabular section. For each row we add a new record to the register and fill it out with the current row attribute values. Then we check if the first Extra Dimension type is specified and fill out the register record’s Extra Dimension value. This ExtDimensions property of the accounting register record can be looked up here in the Syntax Assistant, and it’s, basically, a key-value map you can insert things into. This map accepts a reference to a Chart of Characteristics as a key and an extra dimension value as a second parameter. So, this is exactly what we do here and then repeat for the rest of the extra dimensions.
So, this is our posting procedure. Besides that I performed some serious user interface magic behind the scenes, so let’s see how it works.
Now I can add the Inventory account and tell it to grow itself the Product extra dimension, just like this. Now, let’s purchase something, shall we? I’m creating a new business transaction document, and as you can see these three extra dimension fields are now in the table. So, let’s put them to good use. I’m debiting my Inventory account with 150 dollars worth of Pringles, and with 200 dollars worth of Coke. I paid in cash for both, so the 350 credit goes to the Cash on Hand account. Posting it… And, oops.
Forgot to switch on the currency for the Inventory account. Fixing it. How about now? Looks good.
And this is the Inventory balance broken down by the Product extra dimension I just added. Now. Let’s say, I want to break down my liabilities by companies I owe to. So, I’m going to the Liabilities account and adding the Company extra dimension just like this. Now let’s buy some Pringles on credit from my favorite grocery supplier. As you can see, I’m using the same extra dimension both for the Product and the Company depending on the account. And as soon as I post the transaction, I can see how much I now owe to the Gross Grocery company over here.
So, these were our extra dimensions and how to use them. One last thing left to discuss here is which way of slicing and dicing accounts’ balances to use when.
First thing worth considering here is who controls the slicing factor - a developer or a user. When it comes to the accounts’ hierarchy, a user is a king. They can add and delete accounts left and right getting as general or as detailed of a balance as they need.
The same is true for the extra dimensions. A user can add any number of those at any time and get the level of balance detail they need.
As for the optional dimensions like Currency, they are defined by a developer in design time. A user can turn them on or off but they cannot use this feature to add new dimensions.
Next question is how should users choose between the accounts’ hierarchy and the extra dimensions. The answer is that you want your accounts’ hierarchy to be fairly stable. New sub-accounts should appear very rarely or never. So, the Inventory account has to be a part of the hierarchy, but I definitely shouldn’t split it further adding sub-accounts for individual products down here like this. Instead I should use extra dimension Product to get the same result - account balances broken down by individual products.
This is how we analyze the accounts’ balances.