写给非程序员出身的女朋友的 Beancount 记账及 Fava 自建服务器指南

本文最后更新于:2021年12月19日 晚上

一、为什么要记账

关于为什么要记账以及记账的好处是什么,每个人的答案肯定是不一样的。这里我只谈一谈我个人的情况,我从大学毕业后开始记账,到现在四年半的时间。记账可以跟踪这几年来自己资产的一个变化,根据你记账的周期,可以画出一条由多点构成的折线。换句话说,你可以很清晰地知道你当前经济情况,知道自己的存款以及负债水平。注意我这里提到的是资产而不是存款,这是两个不一样的概念,简单讲,资产=存款-负债。你不仅需要了解自己的储蓄卡账户余额,也需要知道自己的信用卡和花呗等账户的负债情况。

二、如何记账

如上文提到,我记账已经有几年了,一开始使用 excel 来记录,每周做一次整理,记录自己这周衣食住行等所有的开支以及收入情况,以及记录所有账户的存款和负债情况,从而了解资产情况。这样的记录是很花费时间的,尤其是当你忘记了某一笔开销是什么的时候,需要花费大量的时间来查找消费记录和回忆消费目的,甚至想不起来的情况也是时有发生的。

直到后来,从 ByVoid 大神的博客里了解到了一种开源的记账软件 Beancount,从此便爱上了它。这个软件让我的记账工作轻松了不少,也让记账成为了一种乐趣。它的学习曲线并不陡峭,入门很容易。

三、Beancount 及 Fava 用法

Beancount

Beancount 是一款使用 python 开发的纯文本记账软件,你可以很容易的将你的账单记录下来,如果搭配微信支付宝的账单自动导入,你甚至可以清楚地知道你的每一分钱都花在了什么地方。

这里讲一下 Beancount 或者说复式记账的要点。掌握了这些,你就基本掌握了 Beancount 的核心。首先Beancount 将你的账户分为如下几类,

1
2
3
4
Income (收入)
Assets (资产)
Expenses (花费)
Liabilities (负债)

我们可以把这四个账户比作四个小桶,而你的每一分钱比作一粒豆子,你的钱在不停的流动,就好像是豆子从这个桶倒入了另一个桶中。这也是 Beancount 这个软件名字的由来。
其中每一个账户下面还可以不断细分为更小的账户,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Income (收入)
- Salary (工资)
- Overtime (加班工资)
- PnL (投资盈亏 Profit and Loss)
- RedPacket (红包收入)
- House-Found (公积金)
Assets (资产)
- Cash:CNY (人民币现金)
- Bank:CBC (建设银行借记卡)
- Ali:Alipay (支付宝余额)
Expenses (消费)
- Clothing (服装)
- Makeup (化妆品)
- Food (食物)
Liabilities (负债)
- Ali:Huabei (花呗)
- CreditCard:Bank:GDB (信用卡)

如下便是四个很简单的例子,第一笔记录显示了年会中奖的收入,豆子从收入桶中倒入了资产桶中,代表我获得了新的收入;
第二笔记录显示了我通过微信零钱早餐店花费了 5 元购买了早餐,豆子从资产桶中导入了消费桶中,便是我消费了某些东西;
第三笔记录显示了我通过花呗为手机充值了 100 元,豆子从负债桶中倒入了消费桶中,和第三笔的区别在于,我使用的是负债的方式来消费,而不是资产的方式来消费;
第四笔记录则显示了我为花呗还款,豆子从资产的桶中导入了负债的桶中。
基本上,在日常生活中的金钱往来都可以被整理为如下类似的记录。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2021-12-17 * "年会中奖" 
Income:Gift -500.00 CNY
Assets:Cash:CNY

2021-12-09 * "徐记饼店" "收款方备注:二维码收款"
Assets:Wechat:WechatPay -5.00 CNY
Expenses:Food:Breakfast

2021-12-08 * "淘宝" "手机充值"
Liabilities:Ali:HuaBei -99.80 CNY
Expenses:Phone-Bill

2021-12-05 * "花呗" "主动还款-花呗2021年12月账单"
Assets:Bank:CBC:7183 -296.23 CNY
Liabilities:Ali:HuaBei

用一幅图来表示上述的变化,
bean count flow

通过上面的例子,很简单的指出了 Beancount 的工作原理。而你所需要做的就是,将你的每一笔收入和开支情况,转换成如上类似的记录。剩下的事,就交由 fava 来处理。

fava

Fava 则是一款 Beancount 的 UI 界面,可以很直观的显示每一个账户的数额,以及开销情况。同时,配合 Beancount 自有的标签功能,你可以为某一类记录打上特有的标签,从而在 fava 上检索出来。
例如:下图显示了我在 4 月购置厨房用品的所有开销,我将其赋予了 #2021-04-Cooking 的标签。

fava

再比如:如下是近期在家做饭购买食材的花销。

expense

Beancount 最佳实践

为了更好的使用 Beancount,推荐尽可能减少你的活跃账户,这可以尽量减少你的记账负担。例如:

  • 尽量只使用一张银行卡,
  • 尽量不使用现金,
  • 尽量使用微信和支付宝作为支付工具,京东购物是通过微信支付,美团等不支持微信和支付宝支付的平台尽量不用。

四、远程访问 Fava 页面

为什么要远程访问

一直以来,Fava 界面都只能运行在本地的 localhost:5000 下,这使得远程访问账单情况变得很难。如果知道关键字,还可以到代码仓库查找到某一条记录,要是只想知道目前的资产情况,打不开 Fava 那将是不可能的。因此,我个人的做法是,在使用 Beancount 的同时,我会维护另一个账单表格,里面有每一个账户的情况,并且如同代码更新一样,表格可以通过 onedrive 来同步,和账单代码保持一致。这样一来可以在任何时候打开表格就可以查看到资产情况,二来可以在作为 Beancount 自动记账的校对工具,毕竟自动导入的账单还是会遗漏一些数据,例如现金以及无法提供账单或账单导入不方便的平台的消费。

如何实现远程访问

实现远程访问,需要将 fava 部署在自己的服务器,从而通过公网IP来访问。我这里简单的画了一个原理图。

workflow

首先,需要通过 webhook 监听 git push 事件。
其次,由于 fava 本身没有鉴权功能,因此把个人页面公布在公网是很可怕的事情,这意味着任何人访问这个页面都可以看到你的账单情况。因此,我这里使用的是 fava-management 这个仓库,利用 Django 来实现一个用户管理,只有密码正确的情况下才可以访问到该页面。

五、未完成的事

这个记账的流程还有很多可以优化的地方。
服务器上的 fava 页面既可以查看数据,也可以修改数据,但是目前修改的数据不会主动 push 回 github 仓库。这也就意味着它的编辑功能其实并不可用。
账单的导入还是依靠于人工下载和分类,下一步可以考虑在产生消费后进行增量更新。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!