20090515

Ledger — бухучёт в командной строке

Решил, что надо наводить порядок в своей жизни и деньги считать. В общем, вести домашнюю бухгалтерию. Познания в бухучёте у меня очень скромные (хотя когда-то и прослушал вводный курс), помню только, что такое двойная запись, и дебет/кредит. Когда-то, правда, пользовался GNUcash.

Кроме GNUcash в линуксе есть ещё несколько программ для учёта личных финансов: KMyMoney и Grisbi. Программы красивые, удобные, наглядные. Однако меня впечалил и заинтересовал ledger. Это бухучёт в стиле unix. В общем, для фанатов.

Идея проста: записываем все расходы/доходы в текстовый файл (файл редактируем сами, программа его не трогает), а программа всегда поможет проверить баланс и составить отчёт о текущем состоянии или по периоду. Что может быть естественней, проще, надёжней? Полный простор в организации учёта.

Отмечу, что вначале я нашёл не сам ledger, а его клон hledger, написанный на Haskell. Есть ещё и вариант написанный на Python — beancount. Какую программу выбрать — дело вкуса. Формат файла, к счастью, у них (почти) одинаковый. «Старший» ledger уже есть в репозиториях Ubuntu и Debian, но мне пока больше понравился вариант на Haskell (исходники короче и понятнее), про него и буду рассказывать.

Хотя сложного в использовании ledger вроде ничего нет, трудно начать, потому что все примеры в сети на английском и используют английскую бухгалтерскую терминологию. Для меня, чтобы разобраться, было важно понять формат в котором вести записи. Итак, файл состоит из записей, формат каждой записи
ДАТА[=ФАКТИЧЕСКАЯ ДАТА] [*|!] [(КОД)] [ОПИСАНИЕ] [ ; КОММЕНТАРИЙ ]
отступ НАЗВАНИЕ СЧЕТА хотя бы два пробела СУММА [ ; КОММЕНТАРИЙ ]
отступ НАЗВАНИЕ ДРУГОГО СЧЕТА [ хотя бы два пробела СУММА ] [ ; КОММЕНТАРИЙ ]
[другие счета, если необходимо]
Каждая запись начинается с цифры, то есть даты. Даты пишем в формате ISO, ГГГГ-ММ-ДД. Для краткости можем указать в файле
Y2009
и все последующие записи без указания года будут относится к 2009-му году.

Описание проводки может быть любым. Номера квитанций, счетов и тому подобные коды можно вписывать в поле (КОД) (указывать перед описанием в скобках).

СУММЫ можно писать так, как удобно, «13», «$42», «17 EUR», «121 Kb», «9 L». Ledger понимает, что разные единицы измерения нужно считать отдельно. Единицы можно указывать любые, те, которые нужно учитывать. В том числе и неденежные (и программа умеет их правильно пересчитывать, если ей дать файл с историей цен).

В каждой записи обычно два или три счета, но указывать сумму для одного из них необязательно, понятно, что изменение будет равно сумме всех других, но с противоположенным знаком:
2009-05-14
расходы:обед 123 RUB
актив:наличные ; понятно, что здесь должно быть -123 RUB
Счета можно называть как угодно. В том числе и по-русски. Можно делать подсчета, используя двоеточие в названии счёта, например, «расходы:услуги:интернет». Видимо, необходимо иметь счета как минимум пяти категорий: актив, долги, доходы, расходы и какой-то счёт для уравнивания балансов. Я назвал его «собственные», в англоязычных примерах его обычно называют «equity».

Дело в том, что двойная запись подразумевает, что всегда выполняется закон сохранения денег. Всегда, когда к какому-то счёту мы их приписываем, точно такую же сумму мы должны с какого-то счёта списать. Поэтому уже в начале, чтобы указать сумму денег в кошельке и на счету в банке, нужно ввести некий счёт, с которого они «пришли».

Составим такой файл со счетами, для начала. Пусть у нас есть текущий счёт в банке, на котором лежит 1001 рубль (единицы не будем указывать для краткости), есть что-то в кошельке, скажем 150 рублей. Пишем файл:
Y2009

05-14 начальное состояние счета в банке
актив:банк 1001
собственные:начало

05-14 начальное содержимое кошелька
актив:наличные 150
собственные:начало
Сохраняем в файл, например ~/.ledger (там его по-умолчанию ищет hledger). Смотрим, что получилось:
~$ hledger
1151 актив
1001 банк
150 наличные
-1151 собственные:начало
Программа сама догадалась подсчитать баланс виртуального счёта «актив». Всё сходится: всё, что было списано со счёта «собственные:начало» оказалось в «активе». Если что-то не сходится, программа будет страшно ругаться.

Как записывать расход-приход — см пример записи выше. Допустим, мы что-то купили и что-то получили в подарок:
05-15 * подарок
актив:наличные 100
доходы:подарки
05-15 * яблоко
расходы:покупки 9
актив:наличные
Я добавил звёздочку перед описнием проводок. Как её интерпретировать — дело хозяйское. Я помечаю ей те операции, которые уже завершены (а восклицательным знаком — те, которые запланированы). Программа потом позволяет легко отбирать проводки со звёздочкой и без.

Предположим, например, что на завтра я запланировал ответный подарок, но ещё его не сделал:
05-16 ! ответный подарок
расходы:подарки 90
актив:наличные
Теперь, если посмотреть баланс с ключиком -C, увидим только то, что завершено:
$ hledger -C bal
91 актив:наличные
-100 доходы:подарки
9 расходы:покупки
Чтобы посмотреть не баланс, а список проводок, есть команда register:
~$ hledger reg
2009/05/14 начальное состояни.. актив:банк 1001 1001
собственные:начало -1001 0
2009/05/14 начальное содержим.. актив:наличные 150 150
собственные:начало -150 0
2009/05/15 подарок актив:наличные 100 100
доходы:подарки -100 0
2009/05/15 яблоко расходы:покупки 9 9
актив:наличные -9 0
2009/05/16 ! ответный подарок расходы:подарки 90 90
актив:наличные -90 0
Отмечу, что в «сишной» версии ledger колонки здесь разъедутся. А вот в hledger-0.5 уже всё в порядке (и для 0.4 я тоже сделал патчик).

В общем, баланс (balance) и проводки (register) — два главных отчёта. Можно ограничивать отчёты по диапазону дат или периодам. Или по названиям счетов. Так, чтобы выбрать все счета со словом «подарки» в названии, используем регулярное выражение:
$ hledger reg .*подарки.*
2009/05/15 подарок доходы:подарки -100 -100
2009/05/16 ! ответный подарок расходы:подарки 90 -10
Чтобы выбрать записи по описанию, поступаем так:
$ hledger reg desc:яблоко
2009/05/15 яблоко расходы:покупки 9 9
актив:наличные -9 0
В общем, идея понятна. Для отчётов по неделям и по месяцам есть ключики -W и -M.

Бывают ещё периодические записи, но только в ledger, в hledger их пока нет. Они не означают, что со счёта что-то автоматически списывается. Проводку нужно всё равно вносить вручную, но периодические записи позволяют рассчитывать прогноз бюджета. В ledger также можно делать виртуальные записи, ими можно автоматически учитывать разные комиссии или проценты.

Вот такая программка. Думаю, не одному мне понравится. Вижу большое достоинство программы в том, что формат данных очень простой и естественный. Посмотрю теперь, будет ли её хватать для моих нужд.

Вот пример ledger-файла.