Timetracking and billing with (h)ledger
The timelog is separate to make interaction with time tracking tools.
timeclock.el can generate such a file, usually in
~/.timelog. In my case, I use org-mode's clocking work time
system to "punch" in and out of different tasks. I then use
John Wiegley's org2tc script to export the clock entry to the
timeclock format. (Also note that I have
made a few improvements to org2tc that you might be interested
Looking at past entries
The resulting ledger balance looks like this:
$ ledger -f ledger.lgr bal 10€ assets:cash 1.00h income:client -------------------- 1.00h 10€
You see we have
10€ in cash, which is about right. However, the
ledger is unbalanced: there's a
10€ and a
1h that are not matched. That is
because the time entries are "virtual" and so entered only against one
account. To ignore time entries, use the
$ ledger -f ledger.lgr bal -B -R 10€ assets:cash -10€ income:client -------------------- 0
Now our ledger is properly balanced. The downside is that we don't see
1h that still has to be billed. Also notice how we need to
convert the units with
-B) otherwise it will show up like
this, which is expected given the different units:
$ ledger -f ledger.lgr bal -R 10€ assets:cash -10.00h income:client -------------------- -10.00h 10€
Billing new entries
To issue new bills, we will look at those unbalanced virtual entries. They allow you to notice there is another hour of client work to bill. You can issue a bill against that extra hour to complete your billing with an entry like:
2016/01/28 bill income:client -1h @ 1€ assets:receivables
Then you see something like this:
$ ledger -f ledger.lgr bal 11€ assets 10€ cash 1€ receivables -------------------- 11€
Congratulations, you billed all your hours! It is still
unbalanced, but you can fix that with
-R, as we did before:
$ ledger -f ledger.lgr bal -B -R 11€ assets 10€ cash 1€ receivables -11€ income:client -------------------- 0
Notice how this shows a 1€ unpaid bill that we are waiting a payment for, which is expected because we only issued the bill and not the payment.
Generating actual invoices
The is the part I am stuck at. I have tried to make a
shell script to generate a bill, but I can't figure
out how to extract the hourly rate. I'd also love to get the details
of the affected punches, but I don't think there's a way to map
transactions like this in ledger. I could extract only the uncleared
punches, set the invoice then clear them, but this would be
overwritten at the next run of
I have even tried to set a commodity price, inspired by adams rate example:
P 2016/01/28 00:00:00 h 1€
But that didn't seem to actually work: the price doesn't apply. But I am not very familiar with this part of ledger.
I have also tried using the Python API but failed to go very far: i could not extract cost there either.
I want to print invoices. More todos above and in the shell script.
The ledger file fails to load in hledger:
$ hledger -f ledger.lgr bal creating default conversion rules file /home/anarcat/src/ledger-timetracking/ledger.lgr.rules, edit this file for better results hledger: "/home/anarcat/src/ledger-timetracking/ledger.lgr" (line 1, column 1): unexpected 'a' expecting journal transaction or directive or end of input 1$
It first chokes on the
apply account directive from ledger (this was
fixed in commit a2b989d). But even using the regular
$ hledger -f hledger.lgr bal using conversion rules file /home/anarcat/src/ledger-timetracking/hledger.lgr.rules hledger: "/home/anarcat/src/ledger-timetracking/hledger.lgr" (line 2, column 1) in included file "timelog": "/home/anarcat/src/ledger-timetracking/timelog" (line 1, column 1): unexpected 'i' expecting journal transaction or directive or end of input 1$
This was filed as issue #320 in hledger.
I may be able to feed the timetracking data directly in the
hledger.lgr file, but
that's rather painful: i'd like to keep that messy file separate from
the main accounting.
The way transactions are imported, above, makes time entries show up
as unbalanced. It's confusing and annoying - there should be a way to
balance them with the right account, maybe the
But then that would mean the
income account would empty when we
bill, which is not correct: it should be debited with the size of the
bill, so that we have the running expenses showing up in balance
So in fact, unbalanced entries may be exactly the point of this.
Equity and reporting
There's this strange error that happens when doing a monthly registry report:
$ ledger -f ledger.lgr reg -p monthly Error: 'equity' cannot accept virtual and non-virtual postings to the same account
This is not a problem when doing a daily report, as the invoice is (deliberately) sent the day after the time entries:
$ ledger -f ledger.lgr reg -p daily 70-Jan-01 - 70-Jan-01 (income:client) 9.99h 9.99h 70-Jan-02 - 70-Jan-02 assets:cash 10€ 9.99h 10€ equity:volunteer 59.5m 10.98h 10€ income:client -10.99h -30s 10€
How can I work around that issue?
If I understand this right, such an assertion should check that, at the given time, the balance on the account is a given amount:
1970/01/02 assert we have billed everything [income:client] = 0s
In the above case, there should be zero seconds to be billed to the client on January 2nd. Unfortunately, this doesn't work: if there are punches after that date, they still count towards that balance:
$ ledger -f ledger.lgr bal While parsing file "/home/anarcat/src/ledger-timetracking/ledger.lgr", line 19: While balancing transaction from "/home/anarcat/src/ledger-timetracking/ledger.lgr", lines 18-19: > 1970/01/02 assert we have billed everything > [income:client] = 0s Unbalanced remainder is: -3600s Amount to balance against: 0 Error: Transaction does not balance
Whereas the punch was after the given date:
i 1970-02-01 12:00:00 client client:test4 1h o 1970-02-01 13:00:00
A month later!