Building a Scalable Accounting Ledger
scratchdata.com
scratchdata.com
The rules are unambiguous. An increase in assets are a DR, increase in liabilities a CR, in income a CR, in expenses a DR, in owners equity a CR.
Decreases the opposite.
Using 1 and -1 is nonsensical because their meaning in mathematics is fixed, while as shown by the rules above, in accounting DR/CR meanings change.
So a couple of example journal entries…
Product sale for cash
Sales CR 100
Bank DR 100
Payment of rent
Rent DR 50
Bank CR 50
Sale for cash where tax collected and owed
Income CR 70
Tax Payable CR 30
Bank DR 100
Monthly petty cash tin entry
Postage DR 5
Accounts receivable DR 20 (loan to John)
Transport DR 15 (taxi Paul)
Bank CR 40
Note that your bank statement is from the banks perspective. When you put money into the bank it is a CR because it is increase in the banks liability.Is this too hard to model? I suggest not?
Then use currency specific rounding rules and always defer to CLDR [0] when displaying.
1. https://cldr.unicode.org/translation/number-currency-formats...
The rules are unambiguous. Values which indicate capital are positive. Values which indicate ownership are negative. An increase in capital corresponds to an increase in ownership of said capital, which add up to zero. Perfectly balanced, as bookkeeping should be.
I find CR DR to be more confusing than +/-, because the latter works out naturally with basic arithmetic, whereas the former requires this arbitrary DR CR crud, which are made up terms that literally mean nothing and you have to rote memorize how they apply to different accounts (and to add insult to injury, the terms often have the exact opposite meaning to consumers due to how banks present the terminology, which means the terms literally can mean either thing depending on the context).
Sales DR 100
Bank CR 100
while an annulled sales invoice is Sales CR -100
Bank DR -100
The point of using debit/credit vs +/- is just that, the ability to have correct account turnovers with corrections, and maybe some conventional understanding of what's an expense account in debit and what's a vendor account in credit.I'm sure I could put my mind to following those rules, but what's to be gained?
If 'assets' and 'income' are opposites, and 'income' and 'liabilities' are the same, then I'm just not going to bother. What if my income is paid in assets in the form of $1 bills? CR or DR?
And 'equity', Jesus is that a nebulous concept.
- 1 always represents debit and -1 always represents credit. Regardless of whether it is an asset or liability account.
- Each account has what is called a "normal balance". This tells us whether you increase the value of the account using debits or credits. This is also modeled as 1 or -1.
- Amounts are always positive
- To find the actual dollar value for a transaction, you can multiply: amount * direction * normal. If the direction and normal are the same sign, then that means we increase the value. Otherwise we decrease. Your code doesn't need to know which accounts are assets vs liability vs equity in this scheme.
- Of course, you still need to know whether to insert transactions as debit or credit, and you need to know the normal balance of your accounts. But once you figure that out (by googling, or talking to your finance team) then the data model takes care of the rest.
I work on ClickHouse and am a big fan. That said, this consistency issue has arisen from time to time in customer cases when dealing with financial data. I'm curious if you have seen it in this case.
[0]: https://egrove.olemiss.edu/aah_journal/vol13/iss2/12/
Edit: I should add that CR and DR at one point in time were related to creditor and debitor. I referenced that article, because it's the journey of the author to find an answer that I enjoyed about it.
Almost always multiple, depending on what you consider a transaction, and the PoV of the accounts involved, etc.
I cannot think of a transaction that has a single leg only.
Here's a possibility: You buy something online. You pay $100 by credit card ($80 cost plus $20 shipping).
The accounting system needs to record your purchase. Maybe dr 'Mr ClientName' with $100, cr 'Clearing' with $100.
At some point bank recon will happen, the payment will reflect and the amount will be considered 'cleared'. At this point dr 'Clearing' with $100, cr 'depot' with $100 and delivery details.
The depot will cr 'Stock' for $80 worth of stock, dr 'Courier' for $20[1] using the order number and the companys client number at the courier for folio. Payment request fired off to people with authority to approve payments (PWATAP).
PWATAP will place order at supplier for $80 of stock (to replenish), dr 'PurchaseInProgress' with $80, pay courier service and cr 'Courier' with $20.
In reality, all of those things either happen in a more streamlined way (a holding account is used and replenishments are purchased periodically in batches, not individually), or behind the scenes and invisible to the end-user (dispatcher simply puts "fulfilled order" into the system, and the system will split it up however it needs to).
[1] The courier will go through the same process, for their services rendered
I think a lot of people are glossing over the fact that you not only need 1/-1 for DR/CR, but also the "normal" balance of the account to tabulate balances.
- I believe this is a good application of columnar stores (ie, Clickhouse) rather than traditional Postgres, where handling 1M transactions is really fast.
- You might still choose to use materialized views! This article is a suggestion for a table structure that powers those views.
Physics may have gotten the direction of current flow wrong, but at least they were _consistent_ and didn't start talking about "source voltage" and "load voltage" which would have muddled KVL into `sum{delta_sources} = sum{delta_loads}` compared to `sum{delta_voltage} = 0`.
The real issue is that besides the famous Kleppmann article, it's hard to find material on accounting that sheds this legacy baggage.
On software that was written by accountants: look no further than DATEV. It’s an abomination I would not inflict on my worst enemy.
With hundred thousandth of transactions, performing the sums will be expensive.
And nothing ensure the safeness of the order of entries...
«The production release of TigerBeetle is imminent.»
Not putting money into this system any time soon in other words.