Plain Text Accounting

I’ve been a happy user of sql-ledger for many years (I think close to 14). I like that it is browser based so my wife and I can easily use it at any time. Additionally, anyone doing work on my projects can simply enter their time directly. It has been very stable. Perhaps my only gripe is it is a bit fussy to set up (antiquated Perl technology, and requires PostgreSQL – overkill in my opinion for a small business.

This morning I looked at bit at: https://plaintextaccounting.org/

Seems to be a significant movement. The two most popular implementations (ledger and hledger (https://github.com/simonmichael/hledger/graphs/contributors) both seem to be healthy projects.

One thing I need is a place to enter time on projects, and then generate invoices from the time log. Sql-ledger does this fairly well. The hledger timedot format looks interesting – essentially you can enter time in 15m increments as a ‘.’ or as a number of hours:

# on this day, 6h was spent on client work, 1.5h on 
# haskell FOSS work, etc.
2016/2/1
inc:client1   .... .... .... .... .... ....
fos:haskell   .... ..
biz:research  .

2016/2/2
inc:client1   .... ....
biz:research  .

2016/2/3
inc:client1   4
fos:hledger   3
biz:research  1

This is very similar to what I already do with the emergent task timer.

So, to translate what I do now to timedot, it might look something like:

The idea is you have a dot filled in for every 15m of the workday. I really like this format as it allows you to make sure all the time for the day was accounted for, and it also shows you where your time is going and where you are wasting time.

With multiple developers on a project, it seems like it might be simple to have a git repo for each project with a single timelog file in it, and developers simply modified the time log and pushed it.

How to generate invoices, track invoice payments, etc – is this all possible in hledger – not sure yet …

Spent an hour or so catching up on finances – was able to crank through 6 months of credit card and checking statements. I export CSV files from my bank account, and then hledger imports them for me. There is a rules file that describes how to import the CSV files and contains rules to automatically categorize entries. Below is a sample.

if TECHNOLOGIC
 account2 expenses:supplies

if NEWARK
 account2 expenses:supplies

if WORKFLOWY
 account2 expenses:software

if HOME DEPOT
 account2 expenses:supplies

if GOOGLE STORAGE
 account2 expenses:software

Then I can do things like run a report (a few numbers are x’d out). The categories can be made as granular as you like, and you can also specify the report to summarize at a higher level.

[cbrake@ceres ledger]$ hl is -b 2022-01-01
Income Statement 2022-01-01..2022-10-24

                                      || 2022-01-01..2022-10-24 
======================================++========================
 Revenues                             ||                        
--------------------------------------++------------------------
 <deleted income section>
======================================++========================
 Expenses                             ||                        
--------------------------------------++------------------------
 expenses:business                    ||                $243.75 
 expenses:communication:cell          ||              $2,064.95 
 expenses:communication:kajeet        ||                $483.80 
 expenses:communication:leap          ||                $140.00 
 expenses:communication:lucidview     ||                 $14.94 
 expenses:communication:start meeting ||                $114.29 
 expenses:communication:twilio        ||                 $61.77 
 expenses:education                   ||                 $27.96 
 expenses:hosting:aws                 ||                $391.15 
 expenses:hosting:digital ocean       ||                $513.01 
 expenses:hosting:fathom              ||                $126.00 
 expenses:hosting:godaddy             ||                 $20.17 
 expenses:hosting:linode              ||                 $97.59 
 expenses:hosting:name cheap          ||                 $45.48 
 expenses:hosting:vultr               ||                 $56.16 
 expenses:hosting:wasabi              ||                 $49.90 
 expenses:insurance:HSA               ||              $7,200.00 
 expenses:insurance:health            ||              $8,799.33 
 expenses:it                          ||                $478.19 
 expenses:shipping                    ||                 $61.55 
 expenses:software                    ||                $313.86 
 expenses:software:ossfunding         ||                $254.02 
 expenses:supplies                    ||              $3,450.56 
 expenses:tax:fed                     ||                 xxx
 expenses:tax:school                  ||                xxx
 expenses:tax:state                   ||                xxx
 expenses:travel                      ||                $996.20 
--------------------------------------++------------------------
                                      ||             $xxxxxxx
======================================++========================
 Net:                                 ||             $xxxxxxx


I also have a envsetup.sh file that has a bit of automation:

hl_sort() {
  hl rewrite >x && mv x "$LEDGER_FILE"
}

# used to import csv files and automatically apply rules file
# can be run with options like --dry-run
hl_import() {
  IMPORT_FILE=$1
  # find base name (before _)
  echo "$IMPORT_FILE"
  BASE=$(echo "$IMPORT_FILE" | awk -F "/" '{print $2}' | awk -F "_" '{print $1}')
  RULES=$BASE.csv.rules
  hl import --rules "$RULES" "$@"
  hl_sort
}

hl_import_check_unknown() {
  hl_import "$1" --dry-run 2>&1 | grep -B3 -e unknown -e error -e import
}

hl_update_accounts() {
  hl accounts >accounts.txt
}

# run this periodically
hl_maint() {
  hl_update_accounts
  hl_sort
}

Now, if I could figure out time-tracking and invoices, I could stop using sql-ledger. To be fair, sql-ledger has been an excellent accounting solution for over 15 years – a very stable product. It just can’t import bank statements.