Skip to main content

Command Palette

Search for a command to run...

The first General Journal attempt

Using F# to model Financial Accounting

Published
3 min read
I

Trying to change MY world, and if helps others too, then awesome.

Continuing my quest to create an accounting system, I will work on creating a Journal. The Journal (or General Journal) is basically the database of all the transactions we want to track.

Following along in the "The Joy of Accounting" book, chapter 8 I need to create the first journal entry. This is a loan for $30,000.

let cashDebit :Debit = {Account=Cash;Amount=30000.00m}
let loanCredit :Credit = {Account=Loan;Amount=30000.00m}
let jeLoan = {Date=DateOnly(2022,01,01);Debits=[cashDebit];Credits=[loanCredit]}

Now I put that in the General Journal and print out.

let generalJournal = {JournalEntries=[jeLoan]}

printfn $"%A{generalJournal}"
{ JournalEntries =
   [{ Date = 1/1/2022
      Debits = [{ Account = Assets { AccountName = "Cash" }
                  Amount = 30000.00M }]
      Credits = [{ Account = Liabilities { AccountName = "Loan" }
                   Amount = 30000.00M }] }] }

OK, seems legit. The next event in the book is to do an equity injection (owner of company puts in investment).

let equityInjectionDebit :Debit = {Account=Cash;Amount=20000.00m}
let equityInjectionCredit :Credit = {Account=IssuedEquity;Amount=20000.00m}
let jeEquityInjection =
    { Date=DateOnly(2022,01,02)
      Debits=[equityInjectionDebit]
      Credits=[equityInjectionCredit]}

let generalJournal2 = {JournalEntries=(generalJournal.JournalEntries @ [jeEquityInjection])}

printfn $"%A{generalJournal2}"
{ JournalEntries =
   [{ Date = 1/1/2022
      Debits = [{ Account = Assets { AccountName = "Cash" }
                  Amount = 30000.00M }]
      Credits = [{ Account = Liabilities { AccountName = "Loan" }
                   Amount = 30000.00M }] };
    { Date = 1/2/2022
      Debits = [{ Account = Assets { AccountName = "Cash" }
                  Amount = 20000.00M }]
      Credits = [{ Account = Equity { AccountName = "Issued Equity" }
                   Amount = 20000.00M }] }] }

Allright. That seems to satisfy this step. I am also a bit impressed by myself that I have a General Journal now. This is not verifying that having multiple debits or credits in one entry works, but my familiarity with lists says it should. There is also no validation yet for the rules of a journal entry like there must be one or more debits and one or more credits and the totals of the debits must match the total of the credits and that the numbers are always positive, etc. Those rules will be coded later.

Next step? The Balance Sheet

UPDATE: After a couple failed attempts at producing a balance sheet, I realized I am not following the traditional flow of accounting procedures.

The next step is the General Ledger.


GIST of code LINK

PREVIOUS related blog post

NEXT related blog post

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

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

C

Hi Ivan - I find your blog interesting as I have a similar goal (using F#, Maui, etc.) to build a budgeting app (à la YNAB or envelope budgeting) rather than a full accounting app.

1
I

Several years ago I used an app called goodbudget, based on envelope bugeting. In my mind's eye, there will be modules, even maybe nuget packages like financial accounting domain and invoicing libraries. Not sure how that all works yet. But I have more specific app dreams and everything always comes back to needing an accounting module. I have options of MAUI, bolero, fable, uno, and others too. I am not ready to decide totally on one yet, but I have been most interested in bolero. Do you have anything started yet (GitHub)? You can email me using my name and the domain of the blog if you care to share anything privately.

C

To the extent that I'm interested in webassembly, it's with the idea of being able to run a desktop app in a web browser.

One of the nice things with YNAB is the ability to see multiple months at once - in effect a spreadsheet view where categories are rows, and the columns are months. And changing the budgeted amount in one category cascades a balance forward across the months.

One of my key goals with my app design is to do those calculations client side (on the desktop/phone/browser) and not on a central server (which causes scalability issues when lots of people try to budget at the start of a month.)

The number of transactions entered is actually small - the number of calculations required to determine category balances for a month's view are much higher.

Another goal for me is supporting multiple devices per budget (both myself and my wife using our phones) and offline operation (so I can enter a transaction while in a big warehouse store with poor data reception.) So devices are a source of transactions, but balances are never stored (except in a local device cache) and are discarded when transactions from other devices arrive.

I'm also working to design transactions to represent the creation of categories (accounts in your perspective) and their ordering, renaming, hiding, etc. These are in addition to the journal transactions you're describing above. I also have budget transactions, which represent the movement of budget values between categories. So each category has two balances within a period, one's the sum of the budget transactions, and the other's the sum of actual transactions.

A further distinction for me is that journal transactions have 2 dates, one is the date the transaction took place, the other represents the budget period (the column in the view) in which the transaction applies.