benasieve-ezirmusitua 0.1.0
A small tools for arrange beancount files
Requires Python: >=3.7

# beansieve 账单整理工具

beansieve 是一个用于整理 beancount 账本的小工具。这个工具主要实现以下两个功能：

1. 通过 `--type aggregate` 将账单中包含特定账户的条目放到一个新账本文件中。
2. 通过 `--type archive` 将特定时间范围内的 Transaction 条目保留到一个新账本文件中。

## 一些术语

- `type`：操作类型，即 `aggregate` 按账户拆分账本或 `archive` 按时间范围归档账本；
- `source`：源文件，即要操作的账本文件；
- `dest`：目标文件，即新生成的账本文件的保存目录；
- `rule`：使用 `aggregate` 时用于指定聚合规则；
- `keep`：使用 `archive` 时用于指定保留时间范围。

## Structure 输出文件的结构

该工具运行会重新组织账本文件，组织规则如下：

```bash
── account.beancount      # 账户相关指令，即 `open` 和 `close`
├── commodity.beancount   # commodity 指令
├── custom.beancount      # custom 指令（如 fava 中提供的 balance 指令）
├── document.beancount    # document 指令
├── event.beancount       # event 指令
├── history.beancount     # 如果使用 `archive`，则 `keep` 范围外的 Transaction 会被移动到此文件夹中
├── main.beancount        # 主账本文件，include 其他账本文件，如果使用 `archive` 则会包含 `keep` 范围内的 Transaction，如果使用 `aggregate` 则未匹配上的 Transaction 文件会被移动到此文件
├── note.beancount        # note 指令
├── price.beancount       # price 指令
├── <key>.beancount       # 使用 `aggregate` 时按 `rule` 拆分出来的账本
└── query.beancount       # query 指令
```

## aggregate 的用法

使用 `aggregate` 将账单中包含特定账户的条目放到一个新账本文件中。
通过使用 `--rule` 设置账户匹配规则，支持设置多种规则，单条规则的格式为 `<key>:<pattern>`，其中 `<key>` 为文件名称，`<pattern>` 为一个用于匹配账户名称的正则表达式。如果有多条规则则使用 `,` 分割匹配规则。

例如下面的脚本会将 ：

1. posting 中账户名称匹配 `Income:US:ETrade:.*` 的 Transaction 移动到 `Etrade.beancount` 文件；
2. posting 中账户名称匹配 `Income:US:Babble:Salary` 的 Transaction 移动到 `Payroll.beancount` 文件；
3. 其他的 Transaction 移动到 `main.beancount` 文件；
4. 其他的 Directive 会按照 Structure 规则移动到特定的文件中。

```bash
# generate sample beancount files
bean-example > .artifacts/example.beancount
bean-report .artifacts/example.beancount balances > .artifacts/example-balances.txt

# aggregate
rm -rf .artifacts/example_aggregate
python -m beansieve \
  --type aggregate \
  --source ".artifacts/example.beancount" \
  --dest ".artifacts/example_aggregate" \
  --rule "Etrade|Income:US:ETrade:.*,Payroll|Income:US:Babble:Salary"
bean-report .artifacts/example_aggregate/main.beancount balances > .artifacts/example_aggregate-balances.txt
```

## archive 的用法

使用 `archive` 能够保留将特定时间范围内的 Transaction 条目保留到 `main.beancount` 文件中，时间范围外的 Transaction 会被移动到 `archive.beancount` 文件中。
其中 `--keep` 用于指定从当前时刻其回溯的时间范围，比如 `1d` 表示自当前时刻起前 1 天的 Transaction 会被保留到 `main.beancount` 文件中，`1w` 则保留前 7 天的条目，`1m` 保留前 30 天的条目。
例如下面的脚本会将：

1. 从当前时刻起前 7 天的 Transaction 移动到 `main.beancount` 文件；
2. 其他 Transaction 移动到 `archive.beancount` 文件；
4. 其他的 Directive 会按照 Structure 规则移动到特定的文件中。

```bash
# generate sample beancount files
bean-example > .artifacts/example.beancount
bean-report .artifacts/example.beancount balances > .artifacts/example-balances.txt

rm -rf .artifacts/example_archive
python -m beansieve \
  --type archive \
  --source ".artifacts/example.beancount" \
  --dest ".artifacts/example_archive" \
  --keep 7d
bean-report .artifacts/example_archive/main.beancount balances > .artifacts/example_archive-balances.txt
```

## 其他说明

1. 这个工具不能保证输入(`--source`)文件结构的完整性，因此如果有使用 `include` 拆分账本文件的习惯，请先确保你认同 `Structure` 的拆分规则；
2. `aggregate` 和 `archive` 这两个命令不能同时使用，因为对我而言只是当有拆分 Transaction 的时候才会使用 `aggregate` 拆分账本，更多时候是通过 `archive` 来确保最近一段时间的账本文件（`main.beancount`）足够精简；
3. 使用前做好备份，以防止数据丢失，在使用前后使用 bean-report 生成 balance 报表进行对比，可以确保转换无误。