Ivan Rainbolt
Blog of Crazy Ivan

Blog of Crazy Ivan

Starting from ZERO

Using F# to model Financial Accounting

Ivan Rainbolt's photo
Ivan Rainbolt
·Jul 24, 2022·

4 min read

This is a really good explanation of accounting (financial) as described in the book:

Accounting is a system of describing and categorizing the nature and size of a business entity’s assets, the ways they were funded, and what the entity did to increase and diminish them.

The simplistic view as the main purpose for financial accounting is to create reports. Specifically, the Balance Sheet, Profit & Loss and Cash Flow.

If you start an accounting education journey, a word one hears a lot is "Account". These accounts create the "Chart of Accounts". Top level types of accounts are "Assets", "Liabilities", "Equity", "Revenue" and "Expenses". However, these are more of a category, meaning that specifics of data are always given an account name below one of these 'types'.

More terms are a "Journal Entry", which must include a date, and at least one debit and at least one credit. The Journal Entries are rolled up in a Journal, the "General Journal". The journal consists of raw accounting entries that record business transactions, in sequential order by date. The journal is the primary source of data, also called the record of first entry or record of prime entry.

The journal information gets "POSTED" to the general ledger is more formalized and tracks five key accounting items: assets, liabilities, owner’s capital, revenues, and expenses. The book of second entry.

The process is outlined here by Investopedia. This seems a fairly good model to use in the F# world. I would say a Transaction is like a trigger or concept. But we can at least make a type:

type Transaction = exn

A Journal is next:

type Journal = { JournalEntries : JournalEntry list }

and I need a JournalEntry

type JournalEntry =
    { Date : DateOnly
      Debits : Debit list
      Credits : Credit list }

which leads to needing a Debit and Credit type.

type Debit =
    { Account : Account
      Amount : decimal }

type Credit =
    { Account : Account
      Amount : decimal }

I now have the missing Account.

I am struggling quite hard with the account model. At this basic level, every account will be one of the following types: Assets, Liabilities, Equity, Revenue or Expenses. I start like:

type AccountData = { AccountName : string }

type Account =
    | Assets of AccountData
    | Liabilities of AccountData
    | Equity of AccountData
    | Revenue of AccountData
    | Expenses of AccountData

type ChartOfAccounts = { Accounts : Account list }

The "normal balance" concept has yet to be addressed.

First, the top layer of accounting item types will not actually be in a journal entry. The entry will always be at least a sub-category of one of these (to be expanded later). Accounting has many traditional account names, with many variants, like anything old. But still, lets follow along the accounting book and see what we come up with.

"Cash" is a common account of type Asset. So my ChartOfAccounts type will have a Cash type OR do I have a universal Asset account type and can name it Cash? I feel like I am not getting this yet.

Trying some tests to work this out. I create three accounts (that will correspond to chapter 8 in the accounting book:

let Cash : Account = Assets {AccountName = "Cash"}
let Loan : Account = Liabilities {AccountName = "Loan"}
let IssuedEquity : Account = Equity {AccountName = "Issued Equity"}

Having now wrestled with the next steps that lead to the Journal, I will create a new post for it.

A gist has been created here that has the above code so far.


DISCLAIMER: Links on this blog may earn commissions or other benefits for the author.

REFERENCES:

Scott Wlaschin's amazing F# book:

Domain Modeling Made Functional: Tackle Software Complexity with Domain-Driven Design and F#

The Joy of Accounting: A Game-Changing Approach That Makes Accounting Easy

DotNet 7 preview 5

GIST of code LINK

Blog post about WHY I am working on this: Lofty Goals

Did you find this article valuable?

Support Ivan Rainbolt by becoming a sponsor. Any amount is appreciated!

Learn more about Hashnode Sponsors
 
Share this