Buchhaltung
What advantages does he derive from the system of book-keeping by double entry! It is among the finest inventions of the human mind; every prudent master of a house should introduce it into his economy.
-- Johann Wolfgang von Goethe
Buchhaltung (['buːχˌhaltʊŋ], German book keeping), written in Haskell, helps you keep track of your finances on the command line with minimal effort. It provides tools that help you in creating a complete ledger of all your bank and savings accounts', credit cards', and other transactions, in a text-based ledger format, that is readable by the ledger CLI tool and its many derivatives.
- Fetch your bank transaction directly via FinTS/HBCI/OFXDirectConnect
- Import transactions from
- PayPal
- Barclaycard Visa
- comdirect Visa
- Revolut
- Barclays UK CSV
- NatWest International CSV
- and Monefy expense tracker app
- ... or define your own formats
- Semi-automatically match transactions to accounts using Bayesian classification
- Semi-automatic transaction entry with meaningful suggestions in keyboard-based speed mode
- It is couples/room-mates aware: Create several transaction simultaneously (see Multi-user add)
Status & aim
I am actively and successfully using this software since 2010 and my ledger now contains more than 12,000 transactions accurately and continuously tracking the finances of my spouse and me including four checking and two savings accounts, one credit card, two PayPal accounts, two cash wallets in EUR, bitcoin trading (both physical and on exchanges) and other currencies like USD, GPB used on trips.
The software is in alpha phase and I am looking for early adopters and their use cases. The aim of this stage is to agree about the functionality and customizability and produce a first shippable version, that can be used without tinkering with the source.
Right now, I am using it on Linux but it should also run wherever GHC runs.
Installation
Prerequisites
-
Haskell Stack, more specifically the Glasgow Haskell Compiler and Stack
Required to compile the software.
-
AqBanking Command Line Tool (optional)
This is required for direct retrieval of bank transactions via FinTS/HBCI/EBICS (Germany) or OFXDirectConnect (USA, Canada, UK). Packages available e.g. on Ubuntu (aqbanking-tools) and ArchLinux (aqbanking). (AqBanking is also the used by GnuCash for this purpose.)
-
dbacl (optional, needed to run match
)
Bayesian classifier used to match transaction to accounts. Packages available e.g. on Ubuntu and ArchLinux (AUR).
-
ledger CLI tool or a compatible derivative (optional)
... to query the ledger, create balance and report statements, web interface, etc.
Under the hood
AqBanking or any other supported CSV source provides the raw transaction data. The buchhaltung
binary converts this data into the ledger format and puts the original source in the comments; thereby producing selfcontained transactions without the need for an external database or log. These comments are used later for duplicates detection and account classification.
The buchhaltung
binary internally uses the great hledger
library. The resulting ledger files can be processed/queried with one of the hledger
tools or any other compatible tool.
Download, compile & install
# download
git clone https://github.com/johannesgerer/buchhaltung.git
cd buchhaltung
# compile and install (usually in ~/.local/bin)
stack install
-
Create a folder that will hold all your config and possibly ledger files:
mkdir ~/.buchhaltung
cp /path/to/buchhaltung/config.yml ~/.buchhaltung/config.yml
If you want a folder under a different location, either create a symlink or set the BUCHHALTUNG
environment variable to that location.
-
Edit the config.yml
.
-
Make sure the configured ledger files exist.
Getting help
- The
config.yml
file provides excessive comments.
- This readme documents most functionality.
- Every command and subcommand shows a help message when invoked with
-h
.
- Read the haddock documentation and source code on Hackage.
- Open an issue.
- Write an email.
Usage
First usage / clean
To initialize AqBanking after you edited the config file, you need to run:
buchhaltung setup
To clean everything aqbanking related remove the configured aqBanking.configDir
and rerun the setup
command.
Manual AqBanking setup
Currently only the HBCI PinTan
method is supported by the setup
command (pull requests welcome). For other methods or if the AqBanking setup fails due to other reasons, you can configure AqBanking manually into the configured aqBanking.configDir
(see for help here or here, usually via aqhbci-tool4 -C <aqBanking.configDir>
).
So far, I have not tested the OFXDirectConnect capabilities of AqBanking (please share your experiences), but buchhaltung
should transparently support any method offered by AqBanking.
Importing transactions
There various ways (including from PayPal CSV files) to import transactions into your configured ledgers.imported
file. They are presented in the following, but consult
buchhaltung import -h
and the -h
calls to its subcommands to see the currently available functionality.
The accounts of the imported transactions will be taken from the configured bankAccounts
and the offsetting balance will be posted to an account named TODO
, and will be replaced by match
.
The original source information will be included in the second posting's comment and used for learning the account mappings and to find and handle duplicates.
AqBanking
buchhaltung update
This command fetches and imports all available transactions from all configured AqBanking connections.
In order to import an existing file in AqBanking format, use:
buchhaltung import <file.csv> aqbanking
For other CSV formats you have two options:
-
Use the importers for PayPal, Barclaycard Visa, comdirect Visa, Revolut, and Monefy expense tracker app.
-
Bring your CSV into a currently supported format. The AqBanking format works especially well
-
Hack the source, which is fun and should be easy since you only need to
copy and adapt from the other importers.
You can look at aqbankingImporter
, comdirectVisaImporter
and
paypalImporter
in
Buchhaltung/Importers.hs (or on GitHub).
Resolve duplicates
Banks often minimally change the way they report transactions which leads to unwanted duplicates.
When importing, Buchhaltung will identify duplicates based on ([(Commodity,Quantity)], AccountName, Day)
and interactively resolve them by showing the user what fields have changed. If there are several candidates, it sorts the candidates according to similarity using levenshteinDistance
from edit-distance. (See Buchhaltung.Uniques.addNew
)
Match accounts
buchhaltung match
This command asks the user for the offsetting accounts of imported transactions, or more specifically, transaction whose second posting's account begins with TODO
and does not match any regex in ignoredAccountsOnMatch
.
Have a look at the example output here.
The significantly speed up this process, it learns the account mapping from existing transactions in the configured ledgers.imported
file using the original source of the imported transaction.
Please note that you will have to enter account information in reverse order: for example Expenses:Food
has to be entered as Food:Expenses
.
See this information about the account input field.
Best practices
The Bayesian classifier can only work if similar transactions are always matched with the same account.
Consider frequent credit card payments to Starbucks:
See also this issues on how you could use this.
Enter transactions
buchhaltung add
This command opens a transaction editor. Here is an example of the output of this command.
The amount of manual typing is kept to a minimum by two clever suggestion mechanisms and TAB completion.
All input fields save their history in the current directory. It can be browsed using up and down arrow keys.
The account input fields support TAB completion. To make this even more useful, the account hierarchy is read in reverse order. For example Expenses:Food
has to be entered as Food:Expenses
. This behaviour can be deactivated by setting reverseAccountInput
to False
.
Suggested transactions
After the amount is entered, the user can select a transaction whose title, date, amount and second posting's account will used to pre fill an offsetting transaction. Suggestions will consist of all transactions
- whose second posting has not been cleared (i.e. marked with an asterisk in front of the account name, and
- whose first posting's amount has the absolute value as the entered amount
- whose first posting's account is contained in the configured
bankAccounts
and does not match any of regexes in ignoredAccountsOnAdd
.
Suggested accounts
Once the first posting's account has been entered, the editor suggests accounts for the second posting based on the frequency of the resulting transaction's accounts in the configured ledgers.addedByThisUser
file.
Assertions & assignments
Amounts can be entered with assertions or can be assigned.
Default currency
In order to be able to enter naked amounts and have the currency added automatically, add a default currency to the configured addedByThisUser
ledger file. Example:
D 1,000.000 EUR
Multi-user add
buchhaltung add -w alice
If there is more than one user configured — possibly each with their own ledger, they can be included/activated via the command-line argument -w
. This enables you to enter a transaction where postings belong to different users. When done, a transaction for each user will be generated containing their respective postings and a balancing posting to an account prefixed with the configured accountPrefixOthers
.
Example taken from the output of the above command:
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2016/12/19 Dinner
Account | Amount | Assertion
-------------------------+----------+-----------+----------
0,jo Wallet:Assets | $ -100.0 | |
1,jo Food:Expenses | $ 50 | |
2,alice Food:Expenses | $ 50 | |
-------------------------+----------+-----------+----------
Open Balance | 0 |
generates the following transactions
####### jo: Balanced Transaction #######
2016/12/19 Dinner ; Entered on "2016-12-19T19:01:00Z" by 'buchhaltung' user jo
Wallet:Assets $ -100.0
Food:Expenses $ 50
Accounts receivable:Friends:alice:jo $ 50
####### alice: Balanced Transaction #######
2016/12/19 Dinner ; Entered on "2016-12-19T19:01:00Z" by 'buchhaltung' user jo
Accounts receivable:Friends:jo:jo $ -50
Food:Expenses $ 50
Getting results
Get current AqBanking account balances
buchhaltung lb
Call ledger
or hledger
buchhaltung ledger
buchhaltung hledger
This calls the respective program with the LEDGER
environment variable set to the configured mainLedger
or mainHledger
.
Commit the changes
buchhaltung commit -a -m'checking account ok'
or
buchhaltung commitHledger -a -m'checking account ok'
this commits all changes to the git repository that contains the mainLedger
file. The commit message will also contain the output of buchhaltung lb
and buchhaltung ledger balance --end tomorrow
.