前言
本文假定读者知晓 beancount 的相关知识,会使用 importer。使用汇丰香港账户,需要导入结单记账。
结单
与我朝银行不同,国际上的银行多用月结单形式交付账单。一份结单有资产、储蓄账户交易(本币、外币、定期)、投资等部分组成。用于 beancount 主要需要明细部分。我朝银行大抵可以选择时间范围导出 CSV 格式账单,这个是可以非常便利的使用 benacount 官方 csv impoter 导入。
结单类似于
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| ┌───────────────────────────────────────────┐ │ HSBC │ │ │ │ Your Bank Number │ │ Address │ │ │ ├───────────────────────────────────────────┤ │ Protfolio Summary │ │ |Account│CCY│Rate│Balance│HKD Equivalent│ │HKD│123-456│HKD│ │ 900 │ 900 │ │FCY│ │NZD│4.82│ 500 │ 2,410 │ │Total 3,310 │ ├───────────────────────────────────────────┤ │ Account Transaction History │ ├───────────────────────────────────────────┤ │ HKDSavings │ │ Date │ Details │Deposit│Withdrawal│Balance│ │ 1 Apr│ CASH │1000 │ │ │ │ 2 Apr│ ATM │ │ 100 │ 900 │ ├───────────────────────────────────────────┤ │ FCYSavings │ │CCY|Date│Details│Deposit│Withdrawal│Balance│ │NZD|3Apr│ NOTE │1000 │ │ │ │NZD│5Apr│ ATM │ │ 500 │ 500 │ └───┴────┴───────┴───────┴──────────┴───────┘
|
而国际不少银行只提供 PDF 格式。要给 beancount 记账就需要转换。
PDF 转换
感谢 primefission的项目,你可以便利地转换 pdf 到 csv。
CSV 分析
举一个使用 primefission 的解析器转换后的 CSV 例子。展示 ATM 存款、换汇、取款操作。
1 2 3 4 5
| account,post_date,transaction_date,description,currency,amount,st_date,main_account,file_path HKDSavings,2023-04-01 00:00:00,2023-04-01 00:00:00,CASH DEPOSIT (01APR23),HKD,10000.0,2023-04-29,123-456789-833,/path/to/2023-04-29_Statement.pdf HKDSavings,2023-04-03 00:00:00,2023-04-03 00:00:00,N1234567890 - GOLD/EXCHANGE DEBIT,HKD,-10000.0,2023-04-29,123-456789-833,/path/to/2023-04-29_Statement.pdf FCYSavings,2023-04-03 00:00:00,2023-04-03 00:00:00,WITHDRAWAL,NZD,-2030.46,2023-04-29,123-456789-833,/path/to/2023-04-29_Statement.pdf
|
由于结单中港币储蓄记录与外币储蓄分别记录,csv中在 account 列分成两个。汇丰账户是多币种账户,交易记录出现各种货币是正常现象,因此有 currency 列记载货币。
与调用 benacount 官方 csv importer 相比,这个账单就不太适合使用。官方 importer 假定账单中使用一种货币,计入一个账户,而汇丰结单是两账户、多币种。因此需要写自定义 importer。
Importer
笔者并不是 python 程序员,python 水平也就简单调用库完成一些脚本操作,要写出 importer 类就犯难。幸好碰上 AI 浪潮,可以借助 chatGPT 辅助编写。尝试在使用 AI 买办1的自建站中描述需求,给出了样例代码。实际使用中还是有小瑕疵,debug一番才可以使用。
代码解析
完成的 importer 已发布 github
这里解说特殊部分
1 2 3 4
| def __init__(self, account_mapping, last4_map, file_account_name): self.account_mapping = account_mapping self.last4_map = last4_map self.file_account_name = file_account_name
|
由于有两个账户,定义了 account_mapping
,自行对应自己的 beancount 账户。虽然账单分了两个账户,但文件是一份,用 bean-file
时要用一个名称 file_account_name。官方的 last4_map
转换为 meta 中 card 字段功能不错,这里复刻一份。
1 2 3
| def identify(self, file): clean_filename = path.basename(file.name) return clean_filename.startswith('BANK-') and clean_filename.endswith('.csv')
|
pdf解析后生成的文件名是 BANK-你的账户号-年月.csv
格式,用这种规则判断。如有更好的判别可以提 issue。
1 2 3 4 5
| currency = row['currency'] amount = D(row['amount']) units = Amount(amount, currency) account = self.account_mapping[row['account']] posting = Posting(account, units, None, None, None, None)
|
extract 方法中取值生成 Posting 时,units 要使用 Amount 合并 amount 列和 currency 列,而不是官方的传入 currency。账户要用 mapping 解出不同账户。
1 2 3 4 5 6
| meta = { 'filename': filename, 'lineno': index, 'card': self.last4_map.get(main_account.strip()), 'date': date }
|
beancount meta 必须要 filename 和 lineno,AI 代码并没有生成,需要自己补上。
结论
观察 github,国际银行 pdf 结单转换项目有不少,相比之下 beancount importer 就少了。但大抵有提供转换到 csv,可以借助 csv importer 导入。再看我朝银行、支付宝、微信的 importer 就见到一些,给人一种中文圈的 beancount 热度高的感觉,猜想一是 csv 比较简便导入,二是中文圈使用者多是程序员。
chatGPT为代表的 AI 技术突飞猛进也给了非 python 程序员编写对于其自身水平更高的代码的辅助。以前面对特殊的账单 importer 要不只能花费大量时间自学,要不等待大佬开发。而借助 AI 可以短时间写出能用的代码,对于推广 beancount 记账非常有好处。
看程序界最开始也是小作坊、手艺人。业界的发展爆发软件危机,于是诞生了软工学科。编程走向工程化,构建出更复杂软件。手艺人变成工程师没有让业界💊,反而更加繁荣。AI 应当作更趁手的工具。要是抱着“工匠”心态,将其视为“玷污”了神圣手艺,感慨人心不古,这样的群体,那才是💊。
注释
[1] 指 openAI 禁了陆港澳后,搭建代理站提供服务的人