The sad state of accounting software

A rant first, then some background, and then screenshots!

Book-keeping is a drag

For some time now I’ve been incredibly frustrated about the state of accounting software available to small businesses that want to run Linux. In the commercial world there’s QuickBooks, of course, which is ok, and here in Australia a major player is MYOB. But both are, well, too cuddly, and although they have slick interfaces, they are actually incredibly clicky and as a result make large quantities of data entry a pain and worse are just hard to use at speed. They’re proprietary, making them impossible to extend, and worst of all run on Windows. In fact, the only reason I have a VMware install is to run the Windows instance that our MYOB books are in. Yuk!

Like many people, I’ve had my eye out for a while, trying to find something Linux side that would be of use, but usually such things were some combination of incomplete, hard to install, ugly, meant for much larger enterprises, or just plain difficult to use.

I’d been using SQL-Ledger for several months, and although it was functional I’d been not terribly impressed by it. I gave it a good go, and even paid the author for his non-free manual, but after a while I finally gave up in disgust. For one thing, it’s a web application (only), which I hate. Another was that there was no simple way to just “Spend Money” without creating a vendor for each transaction and then raising an invoice and then paying it. (I was not about to create a vendor for the Prague Transit Authority just so I can enter my $1.50 underground train fare). The final straw came a couple months ago. I had been entering a payment I’d just received from one of my overseas clients. Instead of accounting a certain differential as “Currency Gain/Loss” it decided to enter it as an expense under “Discount’s Given”. I didn’t give a discount. I lost (a small differential) because of changing exchange rates. So why the heck did it decide to put in as a discount? Grr. Enough.

I run a small business. Our bookkeeping needs are, I’d like to think, very straight forward. But one thing I’ve found is that, for the certain few use cases that I pound on like entering the expenses I incur when I’m on the road, I just want a user interface that will scream — do what I want, the way I want it, and do it fast.

You can see where this is going. I have many better things to do. I also agree with Michael Meeks’s oft stated point that it’s better to improve existing software than to start afresh. But I couldn’t find anything out there that seemed to be amenable to me hacking on it, so I very reluctantly started to think about what coding something specifically suited to our needs would be like.

I don’t know if my efforts will result any differently than any myriad other such projects that get started with such great intentions. All things considered, it’s entirely probable that this will end up unfinished or unworkable and in the bin; even if it does work out its not like it is necessarily going to be of any use to anyone else. For all these reasons I’m not inclined too make too much noise about it.

However, it’s what I’ve been spending my spare time on lately, and since I’m writing it using the java-gnome GTK Java bindings (of course!) there is a growing amount of code in there that I’ve been able to use as examples to help others. A couple of nights ago in #java-gnome I was doing just that, and Andrew Overholt suggested I should blog it. So ok :)

Initial progress

It’s actually going pretty well. I have the domain model pretty much complete, a straight forward persistence mechanism working, and have been working on some prototype user interface elements.

One innovation I had was to leverage the Java type system to deal with the nastiness that double-entry book-keeping creates. Early on the gnucash team said “We have no debits or credits! We just use positive and negative numbers.” Well that’s silly — proper double entry accounting does use Debits and Credits, and you have to deal with them appropriately. And it’s not trivial – the classic case of how complex it gets is depreciation: Fixed Assets, as Assets, are Debit positive, as is the “at cost” amount that you record on the firm’s balance sheet. However, as an asset ages, you record the “accumulated depreciation” against that asset. That is a Credit positive number — and while ultimately it will be subtracted from the “at cost ” amount to get your totals, “accumulated depreciation” is not negative. Things like GST Collected/Paid are similarly complex.

Complex it may be, but nevertheless, like anyone with high-school accounting, I understand it, and the complexity doesn’t bother me terribly much. So I got to work.

After I’d worked out a system that just used subclassing to take care of all of this complexity, it occurred to me that what I’d done was to have the Amount of an Entry be a scalar quantity, but to treat the value of said Entry in a Transaction as a vector quantity, with the Debit-ness or Credit-ness dealt with as if they represented direction. As I said, coding this turned out to be easy:

if (entry instanceof Debit) {
    _balance.incrementBy(entry.getAmount());
} else {
    _balance.decrementBy(entry.getAmount());
}

and so on for Credits, then up the ladder of Ledgers and Accounts. And it all works beautifully. Since the various Account types are subclasses of something I called DebitPositiveAccount (Assests and Expenses) and CreditPositiveAccount (Liabilities, Equities, and Revenues), getting balances for accounts is easy.

Ok, whoopie – anyone can come up with a data model. The real key is a UI that will support rapid data entry. If I can come up with some sensible layouts and UI elements [composite widgets] to help ease & speed the data entry task, then I think this project will be worth pursuing.

Selecting Dates

One things about MYOB and SQL-Ledger both that pissed me off enormously was that it is a pain to enter dates. The SQL-Ledger web app just gives you a blank field, which is pretty useless. MYOB has formatting assist, sort of, but if you only enter part of a date it will either wrongly interpret it or equally unhelpfully clear the field. So the first thing I wrote was a “Date Picker” (perhaps Chooser would have been a better verb, but whatever).

In mine, if you enter

5 Jun

You get 5 Jun 05, as you’d expect. If you just enter

8 April 2002

You will, as expected, get 08 Apr 02, because that happens to be the format I like dates in. And if you then enter

17

It will fill it in as 17 Apr 02, because it remembers the last date you entered and assumes that you’re doing groups of related data entry at the same time. (If you’re behind on your bookkeeping, or even just entering receipts from the last trip, chances are that you’re entering data from roughly the same period. So help me along, yo!)

Date Picker

As you can see, there’s also a button to popup a window with the GtkCalendar widget in it; it’s all tied together so the current selection is the selected date, and selecting a date in the calendar actions back to the GtkEntry field in the appropriate format. (That took quite a bit of obscure meandering through java.util.Calendar and java.text.SimpleDateFormat!)

Selecting accounts

On of the other hugely frustrating things in most accounting programs is how hard it is to quickly pick which account you want (ie, when you’re entering expenses). Sometimes they give you a dropdown with a thousand entries. MYOB gives you code numbers and sub-account names, but doesn’t show what the parent account is a sub-account of, resulting in confusion (is that Travel::Meals Expense, or Client Entertainment::Meals Expense?)

So I took a swipe at creating a UI element which would assist in finding accounts quickly. Without boring you to tears with details about the Class hierarchy I’ve used for accounts, when you type a character into this AccountPicker widget, it pops up a window with an Entry where you can narrow the search, and a TreeView with the account/ledger combinations which match the characters entered are shown.

[Incidentally, yes, TreeView has a built in search capability, but it's only on one column (I needed it to filter across two columns, and possibly even 3 if I decided to expose "account numbers") and the built in search only jumps through the list - it doesn't narrow it, which is what I wanted]

It’s pretty awesome. Usually within about three keystrokes you can see the account you’re trying to pick, select it, and you’re done.

Account Picker

I also exposed (in the small print) a human readable String of whatever Type a given account happens to be. The colours are blue for Debit-positive, and green for Credit-positive, which seemed a nice touch.

This one exercised a huge amount of the API – TreeModelFilter to narrow the list, DataColumnObject to store references to the underlying objects in my domain model, FocusListeners, EntryListeners, a TreeViewListener, and KeyListeners all over the place. I’m pretty pleased that it all worked. Clearly, java-gnome is maturing.

AfC