Sunday, March 14, 2010

Sharing the budget with hledger

This time I'd like to tell you how we use hledger in our small family. Here I'll present our experience in question/answer form.

  1. How to make ledger file accessible by different users?

    First, choose a location for the ledger file. According to FHS it probably belongs somewhere in /var. For ourselves I just chose to place it in my home directory.

    Then, for hledger to find your ledger file, just set the environment variable LEDGER to the location chosen. E.g. append

    export LEDGER=~you/.ledger
    

    to the /etc/profile. If you chose to place ledger file in your home, make sure that other users have permissions to access them. Like:

    chgrp users ~you ~you/.ledger
    chmod g+x ~you
    chmod g+r ~you/.ledger
    
  2. How to organize accounts?

    The overall account structure won't be much different from what you'd use without sharing. However, for each account you have to decide whether to make it shared or per-user. For example, some expenses are shared (such as house-keeping expenses) and some may be not (differentiating transport expenses may give an evidence about how much everybody spends on that).

    Shared accounts will have the usual form Expenses:Taxes and per-user ones will have the form Expenses:Transport:Leonard, Expenses:Transport:Sheldon etc.

    In our case, we only divide (for obvious reasons) the «wallet» account which tracks the cash one carries with himself.

    In general, some support for shared/differentiated accounts could be built in hledger itself, but we still can solve many problems, see below.

  3. Our transactions interfere when finding similar transactions.

    Ours did too! Until I came up with the patch (now merged into the main repository) which allows filtering relevant transactions by account.

    To demonstrate the problem, suppose my wife has just ended entering her transactions. Among others was:

    2010/02/26 tansport
        Expenses:Transport       20
        Assets:Wallet:Maria
    

    Now I'm going to enter my transactions. Among others there is similar transaction for my transportation, but it differs in the second account, it is Assets:Wallet:Roman. Of course, hledger doesn't know about this, so it suggest Maria's transaction for me as a template and I have to enter the correct account manually.

    As a workaround for this with the patch mentioned above you can invoke hledger add with additional parameter -- filter for relevant transaction. For example, I will invoke hledger as hledger add Roman which will result in the correct template transaction.

    To automate this, you can add to your ~/.profile the following code:

    function hledger
    {
        HLEDGER=/usr/local/bin/hledger
        case "$1" in
            add)
                shift
                $HLEDGER add Roman "$@";;
            *)
                $HLEDGER "$@" ;;
        esac
    }
    

    This works for us because almost every transaction involves wallet account. In a different workflow this may work not so well (because some transactions may not involve any of the differentiated accounts). In some sense this is a hack caused by hledger not making distinction between shared and diffirentiated account.

  4. How to achieve consistency in using ledger?

    By the definition of the ledger file format, hledger does not and cannot force you to explicitly create account before using it. Thus nothing prevent you (or other users) from making a typo or just using different account names -- for instance you use Expenses:Transport:Subway but your wife uses Expenses:Subway. If you are aware of this, it can be easily corrected using sed (thanks to simple ledger format), but it is usually difficult to spot.

    That's why I added a new option, --no-new-accounts (now in the main repo), which makes hledger add not to accept new accounts, i.e. accounts which are not yet present in ledger file. This is of course not a guarantee (users already have access to ledger file, so they can do whatever they want) but a good measure.

    Thus, for other users you can add to their ~/.profile the following definition:

    function hledger
    {
        HLEDGER=/usr/local/bin/hledger
        case "$1" in
            add)
                shift
                $HLEDGER add Maria --no-new-accounts "$@";;
            *)
                $HLEDGER "$@" ;;
        esac
    }
    

    You can also use this option by default for yourself, turning it off in the rare cases when you really want to add a new account.

1 comment:

Simon Michael said...

Thanks for the post, it's always interesting to see real-world usage examples. Here, we do something similar, except command-line data entry won't fly in our household, so for now I take care of that. I'm hoping the web ui will solve this problem eventually.

I keep a simple-as-possible household.ledger, separate from my personal ledger. This means duplicate data entry for me, but keeps things simple for now. Eg:

2/21 groceries
expenses:food:groceries $50
simon

2/21 groceries
expenses:food:groceries $50
herself

Each of us is an asset account, which sounds similar to your wallet:* accounts. Some of the reporting on this turns out harder than I expected, I find myself needing to filter in multiple steps, eg:

hledger -f household.ledger print -p $PERIOD simon | hledger -f- balance register expenses

hledger -f household.ledger print -p $PERIOD herself | hledger -f- balance register expenses