Accounting Like a Developer
The story so far
Finance, sometimes easy, sometimes difficult and in my experience almost always a headache when deviating from the basics of entry & reporting. This headache is compounded when your beliefs end up at odds with those the finance tools you use.
Back in 2017, I wanted to revisit taking my finances seriously. Research provided me with a number of viable options, and trial runs led me to the easiest one to use. Being a student and doing some freelance work, my finances were fairly simple. The goal was to learn a system, get comfortable, and adapt it to whatever happened in the future.
Things were straightforward
- Keep receipts in envelopes & match up with transactions
- Occasionally reconcile statements from bank accounts & credit cards
- Make sure everything was properly categorized
A year or two passed, and I was still using this basic system. Over that time, I began taking advantage of more convenient features. Ones like account transaction auto importing, automatic period reconciliation, receipt OCR and uploading. All these features and "fixes" for the annoyances of keeping on top of your finances, were easy to incorporate and felt valuable using because of the raw time saved.
The biggest problem with the platform so far was a huge (and recent) redesign that made navigating the app slower and more time-consuming. Details were hidden multiple clicks away and almost everything was now hidden in a popup menu.
Still functional, but this felt like a regression, making the day-to-day more difficult to cater to those only using the most basic of the platform's offerings.
The first 2 problems
The platform's built-in reporting tools were not flexible enough for my needs. Using familiar tools, I built a complicated Google apps script to login to my finance platform account, download transactions from the past year into a Google Sheet, and split out pivot tables for the "meta-categories" that needed to be combined and summarized.
The receipt uploading system got completely reworked, no more OCR or easy upload mobile app, now the receipts were just something to be attached to the auto-imported transactions. Still useful, but much less convenient. Paperless-ngx swooped in and made organizing business receipts and other documents as easy as could be. When it was necessary, I could drag receipts from paperless across to the finance app.
At this point, a custom reporting and receipt management system has been attached to solve problems I had with the platform itself.
The growing problem
The platform hopped on the AI bandwagon and created an "AI Auto-Categorizer" that would occasionally fill in "uncategorized" transactions with a guessed category. It's a neat feature for personal accounts, but for a business account it's nearly impossible for it to have enough data to make educated guesses.
What would have been a great new feature has in my opinion became a platform killer.
- There is no way to turn the AI categorizer off
- It's a 4 step process to "filter" and check on what the AI did across your transactions
- the categorizer consistiently makes more work by forcing users to clean up its mistakes
- the categorizer was given FREE REIGN over my entire transaction history and went INTO PAST YEARS of data and incorrectly assigned transactions messing up multiple already reconsiled periods
Ok, this is super annoying, but dealing with a few missed and wrong categories is not the end of the world. If I check up on it often enough. I can put up with this to still use the other helpful tools.
Jumping ship
A few weeks ago (at the end of January) an email came through laying out pricing changes to the platform, as well as a restructuring of the available features. I understand that times change, especially in the past couple years while cost and user expectations never go down.
The changes most notably involve loosing access to, or paying the equliavant of a Netflix subscription to keep using
- transaction auto import
- receipt uploading
- auto transaction de-duplicating
I'm not upset with the platform, but I can't justify paying to keep living with this constant change, uncertainty, annoyance, and unreliability when it comes to managing my finances.
Additionally, if the majority of my finances are automated, it lets me detach and slowly/accidentally build a backlog of problems to have to sort through when tax season comes or when I want to answer financial questions. The majority of the processes I now use are custom built solutions that I had to create while catering to this specific platform. There has got to be an alternative that fits my values, and is more consistient.
What's Next
I want a solution that isn't a VC backed SASS platform, online only, sign in with Google, automatic AI everything. Obsidian.md has been a game changer when it comes to my personal, professional, and family knowledge management. Owning your data, and being able to adapt processes to your needs instead of adapting to a specific apps's needs is something I really belive in. As a developer, I also want the system to be hackable, tweakable, and extensible.
Plain Text Accounting
It did not take long to stumble across the Plain Text Accounting (PTA) community. At first glance, using plain text seemed WAY too tedious, niche, and picky. I disregarded the idea and kept looking for other options, and there is no shortage of software and opionions about managing finances on the internet.
I kept circling back to PTA, and then decided "Ok, I'm going to try this for real and prove that it's not a viable option for me". Next was to download some software & setup a finance
folder on my computer with:
- ledger for managing the
.ledger
files - paisa for its pretty charts, read-only reports, easy ledger editing
- obsidian to keep notes and how-to documents organized
The motto during this time was "get something working, polish and make it easier to use later"
Step 1 was to convert the transaction data from the finance platform into a .ledger
file. It was not too difficult, mainly some string substitution and 40 lines of python to open a .csv
and write out a text file. Step 2 came as a suprise, even though it should not have. The categories I had used for years were not "hierarchical" and some of the nicities of PTA relied on that. Paisa's docs have a good explanation of why this is important. So with some freshly renamed categories, and my brand new multi-thousand-line .ledger
file, I hooked the apps up.
Paisa picked up the file, using the CLI to ask ledger for balances immediately gave me well formatted output, and it seemed too easy.
ledger -f main.ledger balance
Seeing these new apps in action was awesome, but the real power of switching to plain text was not the new shiny software, it's how portable, flexible, and familar it is. I didn't need my "platform" to do everything in one place, I could
- pipe account balances to
grep
andsed
to do cleanup for reports - use vscodium for quick full-text searches and find/replace
- use a git repo to change track all my ledgers & scripts
There was no "propritary data format", no 3 step data export sent to my email, it was just text. The habits I built as a developer and consultant in
- handling standard operating procedures
- writing code
- tracking changes across files & folders
- backing up and storing my files safely
all immediately started providing value in the context of my finances. It was time to start polishing, this is going to work great, and it could work indefinately.
Extending the extensible
Importing Data
Getting programatic access to my Financial institutions' transactions is troublesome. Some people seemed to have success with Plaid or OFX importing, but I found the most readily available data was in downloading .csv
files. Thankfully Paisa has a really useful import system that takes .csv
s and applies a handlebars template to them row by row. It's a clever and approachable way to import a single file at a time.
I want to take this approach and apply it to any number of .csv
s at the same time with a single click. To accomplish this, the rust-pta-importer
project was created.
You can learn more by checking out it's project page.
I hooked this up to VSCodium by installing the vscode-tasks extension and using a task like this:
{
"label": "Import CSVs",
"detail": "converts and apppends imports/**/*.csv files to recently_imported.ledger",
"type": "process",
"command": "../applications/rust-pta-importer",
"args": [
"./imports"
],
"presentation": {
"reveal": "always",
"panel": "dedicated"
},
"options": {
"statusbar": {
"filePattern": ".*(imported|main).ledger",
"label": "$(extensions-install-count) Import CSVs",
"color": "#ffb45f"
}
}
},
Editing Ledgers
Paisa has some really useful features like ledger auto-formatting & inline diagnostics, it's super convenient to have errors bubble up into the UI.
Around this time I found the awesome vscode-ledger extension that provides account & payee auto-completion when editing ledgers.
It became apparent that paisa was easier to use for its
- inline errors
- clicking links to jump from the reports' UI straight to ledger files
While vscodium was more convenient beacuase of
- how customizable the UI is
- the autofill extension
- the git integration
- my comfort using its keybinds and shortcuts
I got the crazy idea of taking the best of both worlds and creating an updated extension. It took a few tries to hype myself up enough to commit and start the project. Progress was relatively fast, it took a couple days of spare time and reading vscode's extensive extension docs.
The vscode-ledger-helper
extension features the best parts of both editors and a few new features to "smoothify" the experience.
Learn more by checking out it's project page.
Because vscodium was now the best place to work on ledger files, I wanted to try "hijacking" the "jump to ledger editor" links from Paisa to go straight to vscodium. Turns out this was possible with a few lines of javascript and the TamperMonkey extension lets you add it to paisa's webapp.
// ==UserScript==
// @name Paisa Editor Redirect
// @namespace http://tampermonkey.net/
// @version 2024-02-17
// @description open links in vscode
// @author Seth
// @match http://localhost:7500/*
// @grant none
// ==/UserScript==
const homeFolder = '/home/seth'
const pathBase = `${homeFolder}/Documents/paisa/finance/`
const urlBase = `vscodium://file/${pathBase}`
;(function () {
'use strict'
setInterval(function () {
const urlsToRedirect = Array.from(
document.querySelectorAll('.secondary-link'),
).filter((x) => x.href.includes('/ledger/editor/'))
urlsToRedirect.forEach((el) => {
const ledgerPath = el.href
.split('/ledger/editor/')
.pop()
.replace('#', ':')
el.href = urlBase + '' + ledgerPath
})
}, 2 * 1000)
})()
Overall Thoughts
It's a really cool feeling to adapt my software development experience, terms, and programming language features into a finance context. After forming some habits with the new system, it's suprisingly fast to use, easy to answer questions with, and it fits all the goals from my wishlist.
I took this project a bit far into the technical side, but it meets my needs and will be around until I choose to make changes. I highly reccomend trying out plain text accounting with whatever tools/approach is comfortable for you. The simplicity of "its just text" and being able try anything with the data is truly remarkable.
A high level how-to
- Explore plaintextaccounting.org and get a feel for how others are using this type of financial system
- Decide on the ways you want to enter data (cli, gui, vscode, mobile app, etc) and pick some software to try out
- Explore the new software and do some tests
- Entering transactions
- Doing balance checks
- Getting simple/complex reports
- Convert your existing data into the ledger format and use it
- Make time to update your finances, schedule a bit of time each week or each month
- Setup a backup of your data, one huge part of "owning your data", is being truly responsible for it. If you took a hammer to your PC, what would you lose? Back that up.
Thanks for reading 👍