About a week ago I got an email from the invoicing service that I use that the free tier that I’ve been on for years is being phased out and that I’ll have to upgrade to a paid tier. The monthly subscription would be $15 a month. At most I generate two invoices a month and that’s only if I’m diligent and not falling behind on my invoices.
I couldn’t justify paying the price since really all I do is change maybe three things every time I generate an invoice. Behind the scenes, I’m sure the service does a lot more on my behalf but really I need it to generate PDF versions of my invoices and email it to my client.
Unfortunately as a programmer, I’m presented with this scenario far too often. Where I see a service and think to myself, I could do it myself. I thought about the service and extracted a small set of things I would need my own invoice generator to do. I would need it to take in data and generate an HTML invoice. From there I could open up the HTML invoice and generate a PDF from Chrome.
I put a constraint on myself to only spend two hours in building this thing. But I did have to wonder if this was the most efficient method of generating invoices. After all, it probably is more cost efficient to just pay for the service instead of spending a couple of hours hacking together a solution based on my current consulting rate.
Another thought I had, why not just use a word processor to just generate the invoice. Now that I think of it, I’m not sure why I didn’t. My need to create something I think overcame my ability to see the simpler solution.
Finally there’s the issue of not supporting others who create. As someone who makes things, I definitely want to be paid for things when it provides value to others. It’s weird cause again, I couldn’t justify paying for the service. This is because of the infrequency of use versus what it’ll cost me. I suppose that’s the danger in providing something for free. My value system for paying for the service is all jacked up.
Take for example Netflix, I pay $8 per month. But between my wife, the kids and I, it is used everyday for our entertainment, its an easy sale. Compare this with a $15 service that I would at most use twice a month, I just couldn’t come to pay for it. I think it also comes down to the fact that I can’t recreate Netflix, but I can recreate the invoicing service.
So last night I set out to create my invoicing solution. Instead of the two hours I limited myself, I ended up spending close to four hours. Figuring out the input and output wasn’t that bad it was actually getting the invoice to look decent that took a lot of time.
I ended up going with a Node and JavaScript solution, because use what you got. The workflow goes like this, whenever I want to generate a new invoice, I duplicate a TOML file that has all the data for the invoice. Then I run it through my Node script which parses the TOML and generates a JSON representation of the data. The JSON is then passed to a Handlebars template that takes the data and generates the layout of the invoice. The layout is then saved as an HTML file. From there I can just open up the HTML file in Chrome and generate the PDF.
What the paid invoicing service did provide me was a database to have a historical trail of all my invoices. It’s for this reason I decided to go with TOML files. I can duplicate the files and have them synced across my Dropbox. No surprise since I keep all my notes synced across Dropbox in just plain text files.
It’s actually my first time using TOML, I’m more familiar with YAML. While I could’ve used JSON, I decided to go with TOML because of its clean syntax. With TOML I don’t have to worry about commas and curly brackets. It also resonates with me as a dev because it’s something I’m familiar with. It’s like the first time I saw dev.to’s post editor, it supports markdown but more importantly it looks just like a post you would find in Jekyll. With a section for front matter and then markdown for the actual post. I totally geeked out the first time I saw that.
In the future I’ll probably extend the tool to make it interchangeable with YAML. Another thing I might do is integrate a process with PhantomJS to automatically generate the PDF for me instead of manually taking the HTML and generating the PDF in Chrome. This would reduce a couple of steps and make the process even easier. But for now, the invoice generation works, I think I accomplished what I had set out to do in saving money and rolling my own invoicing system. And it satisfies my nerdy side in that it takes TOML and generates a PDF invoice.