Developer Tools

invoicechase

Built by Ronnel Ilagan

A command-line tool that reads my invoice folder and tells me which clients are late and what I should send them, because I hated doing it.

  • Builder email verified

    Verification

Type
Personal
Category
Developer Tools
Published
Jul 26, 2026
Updated
Jul 26, 2026
Built withPythonSQLiteGit
TopicsProductivityFintech

About this project

What I built & why

Chasing an invoice is the least pleasant twenty minutes of a freelancer's month and I am bad at it — I would let something sit for six weeks rather than write the email. At one point I had about four months of income outstanding across three clients, purely because I had not asked. I wrote this to remove the part I avoid, which is not the sending, it is the working out of who is late and by how much and what I said last time. Now it is a command I run on the first Monday of the month, it prints a list, and it drafts the messages. I still send them by hand, which was deliberate.

The problem

It is for one person: me, and anyone else who invoices a handful of clients and does not want accounting software. It reads the PDFs in the folder I already put invoices in, pulls out the number, date, amount and client, matches them against my bank export, and produces a list of what is unpaid and how overdue it is. Then for anything past terms it drafts a follow-up in a tone I picked, referencing the last one it drafted, so a third reminder does not read like a first. The point of the whole thing is that I never have to open a spreadsheet to find out how I am doing.

What I owned

All of it. The parsing is the ugly part and it is not clever: it is a set of patterns per invoice template, because I have used three templates in ten years and adding a fourth is a five-minute job, whereas a general PDF extractor is a project. The matching against the bank export is the bit I am mildly proud of — payments arrive with references that are approximately the invoice number, and a small amount of fuzzy matching plus an amount check gets it right almost always, with anything ambiguous listed for me rather than guessed. The drafting is a template with fields, not a model.

Technical & product decisions

The main decision was that it drafts and never sends. I built the sending in an early version and turned it off after it produced a reminder to a client I had already spoken to that morning; the risk-reward on automated money emails is terrible. I also decided to keep it entirely local with no service and no account, since it is reading my invoices and my bank export, and there is no version of this where uploading that somewhere makes my life better. Storing state in one SQLite file next to the invoices means backup is whatever backs up that folder.

Hardest challenge

The hardest thing was that bank exports are lies, or at least they are inconsistent — the same client pays sometimes from a business account with a clean reference and sometimes from a different entity with a reference that is a person's name. My first matcher was strict and useless. What works now is a scoring approach across reference similarity, amount, and date proximity, with a threshold above which it matches and a band below which it asks me. Getting that threshold right took about six months of real use and one embarrassing incident where it decided two invoices had been paid by one payment.

Result & impact

My average time-to-payment went from something I did not measure to about thirty-eight days, which I do now measure because the tool prints it. More usefully I no longer have the low-level dread about whether I have forgotten to chase someone. It has run every month for four years. A friend who does design contract work asked for it, could not get it running, and I decided that was a reasonable place for the project to stop.