<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>记账 on 華鳥風月</title>
    <link>https://blog.9-ch.com/tags/%E8%AE%B0%E8%B4%A6/</link>
    <description>Recent content in 记账 on 華鳥風月</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>zh-cn</language>
    <lastBuildDate>Fri, 03 Feb 2023 14:37:13 +0800</lastBuildDate><atom:link href="https://blog.9-ch.com/tags/%E8%AE%B0%E8%B4%A6/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>通过Python自动生成Beancount月度账单</title>
      <link>https://blog.9-ch.com/post/homelab-beancount-bill/</link>
      <pubDate>Fri, 03 Feb 2023 14:37:13 +0800</pubDate>
      
      <guid>https://blog.9-ch.com/post/homelab-beancount-bill/</guid>
      <description>通过BQL查询生成Latex格式Beancount月度账单, 再导出为PDF后发送到邮箱</description>
      <content:encoded><![CDATA[<p>
  <img loading="lazy" src="https://s1.ax1x.com/2023/02/03/pSsQws1.png" alt="截图"  /></p>
<h3 id="背景">背景</h3>
<p>最近几个月开始使用 Beancount 记账, 并且每月通过 Github actions 自动生成一份 markdown 格式的汇总单(<a href="https://www.bmpi.dev/self/beancount-my-accounting-tool-v2/#%E5%AE%9A%E6%97%B6%E8%8E%B7%E5%8F%96%E6%94%B6%E6%94%AF%E6%8A%A5%E8%A1%A8">参考</a>), 由于觉得显示效果不太好, 决定手撸一份新的生成程序</p>
<h3 id="代码">代码</h3>
<h4 id="文档生成">文档生成</h4>
<p>首先是生成 latex 文档的部分, 直接使用文本模板+占位符替换的模式实现, 这样就不用和 latex 的包打交道了(懒狗</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span><span class="lnt">164
</span><span class="lnt">165
</span><span class="lnt">166
</span><span class="lnt">167
</span><span class="lnt">168
</span><span class="lnt">169
</span><span class="lnt">170
</span><span class="lnt">171
</span><span class="lnt">172
</span><span class="lnt">173
</span><span class="lnt">174
</span><span class="lnt">175
</span><span class="lnt">176
</span><span class="lnt">177
</span><span class="lnt">178
</span><span class="lnt">179
</span><span class="lnt">180
</span><span class="lnt">181
</span><span class="lnt">182
</span><span class="lnt">183
</span><span class="lnt">184
</span><span class="lnt">185
</span><span class="lnt">186
</span><span class="lnt">187
</span><span class="lnt">188
</span><span class="lnt">189
</span><span class="lnt">190
</span><span class="lnt">191
</span><span class="lnt">192
</span><span class="lnt">193
</span><span class="lnt">194
</span><span class="lnt">195
</span><span class="lnt">196
</span><span class="lnt">197
</span><span class="lnt">198
</span><span class="lnt">199
</span><span class="lnt">200
</span><span class="lnt">201
</span><span class="lnt">202
</span><span class="lnt">203
</span><span class="lnt">204
</span><span class="lnt">205
</span><span class="lnt">206
</span><span class="lnt">207
</span><span class="lnt">208
</span><span class="lnt">209
</span><span class="lnt">210
</span><span class="lnt">211
</span><span class="lnt">212
</span><span class="lnt">213
</span><span class="lnt">214
</span><span class="lnt">215
</span><span class="lnt">216
</span><span class="lnt">217
</span><span class="lnt">218
</span><span class="lnt">219
</span><span class="lnt">220
</span><span class="lnt">221
</span><span class="lnt">222
</span><span class="lnt">223
</span><span class="lnt">224
</span><span class="lnt">225
</span><span class="lnt">226
</span><span class="lnt">227
</span><span class="lnt">228
</span><span class="lnt">229
</span><span class="lnt">230
</span><span class="lnt">231
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="ch">#!/usr/bin/env python3</span>
</span></span><span class="line"><span class="cl"><span class="c1"># -*- coding: UTF-8 -*-</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">datetime</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">decimal</span> <span class="kn">import</span> <span class="n">Decimal</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">beancount</span> <span class="kn">import</span> <span class="n">loader</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">beancount.query</span> <span class="kn">import</span> <span class="n">query</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">calendar</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">sys</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">os</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">dateutil.relativedelta</span> <span class="kn">import</span> <span class="n">relativedelta</span>
</span></span><span class="line"><span class="cl"><span class="n">_template</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;&#39;&#39;
</span></span></span><span class="line"><span class="cl"><span class="s1">\documentclass[UTF8]</span><span class="si">{ctexart}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\usepackage</span><span class="si">{multicol}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\usepackage</span><span class="si">{geometry}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\setlength\columnsep</span><span class="si">{1cm}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\geometry{a4paper,left=1.5cm,right=1.5cm,top=0cm,bottom=1.5cm}
</span></span></span><span class="line"><span class="cl"><span class="s1">\columnseprule=1pt
</span></span></span><span class="line"><span class="cl"><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\title{Monthly Beancount Report}
</span></span></span><span class="line"><span class="cl"><span class="s1">\author{GitHub Actions}
</span></span></span><span class="line"><span class="cl"><span class="s1">\date</span><span class="si">{}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin</span><span class="si">{document}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\maketitle
</span></span></span><span class="line"><span class="cl"><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin</span><span class="si">{center}</span><span class="s1">\small
</span></span></span><span class="line"><span class="cl"><span class="s1">\textbf{\Large Statement of Comprehensive Income} \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\date{ENV_YEAR-ENV_MONTH-01 to ENV_YEAR-ENV_MONTH-ENV_DAY}
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin</span><span class="si">{multicols}{2}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin</span><span class="si">{center}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\textbf{Income Detail} \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin{tabular*}{\hsize}{@</span><span class="si">{}</span><span class="s1">@{\extracolsep{\fill}}lr@</span><span class="si">{}</span><span class="s1">}
</span></span></span><span class="line"><span class="cl"><span class="s1">ACCOUNT &amp; TOTAL(CNY) \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\hline
</span></span></span><span class="line"><span class="cl"><span class="s1">ENV_LINES_INCOME
</span></span></span><span class="line"><span class="cl"><span class="s1">\end{tabular*}
</span></span></span><span class="line"><span class="cl"><span class="s1">\vfill\null
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin{tabular*}{\hsize}{@</span><span class="si">{}</span><span class="s1">@{\extracolsep{\fill}}lr@</span><span class="si">{}</span><span class="s1">}
</span></span></span><span class="line"><span class="cl"><span class="s1">\hline
</span></span></span><span class="line"><span class="cl"><span class="s1">Total &amp; ENV_TOTAL_INCOME \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\end{tabular*}
</span></span></span><span class="line"><span class="cl"><span class="s1">\end</span><span class="si">{center}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\columnbreak
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin</span><span class="si">{center}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\textbf{Expenses Detail} \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin{tabular*}{\hsize}{@</span><span class="si">{}</span><span class="s1">@{\extracolsep{\fill}}lr@</span><span class="si">{}</span><span class="s1">}
</span></span></span><span class="line"><span class="cl"><span class="s1">ACCOUNT &amp; TOTAL(CNY) \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\hline
</span></span></span><span class="line"><span class="cl"><span class="s1">ENV_LINES_EXPENSES
</span></span></span><span class="line"><span class="cl"><span class="s1">\end{tabular*}
</span></span></span><span class="line"><span class="cl"><span class="s1">\vfill\null
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin{tabular*}{\hsize}{@</span><span class="si">{}</span><span class="s1">@{\extracolsep{\fill}}lr@</span><span class="si">{}</span><span class="s1">}
</span></span></span><span class="line"><span class="cl"><span class="s1">\hline
</span></span></span><span class="line"><span class="cl"><span class="s1">Total &amp; ENV_TOTAL_EXPENSES \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\end{tabular*}
</span></span></span><span class="line"><span class="cl"><span class="s1">\end</span><span class="si">{center}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\end</span><span class="si">{multicols}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin</span><span class="si">{center}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin{tabular*}{\hsize}{@</span><span class="si">{}</span><span class="s1">@{\extracolsep{\fill}}lr@</span><span class="si">{}</span><span class="s1">}
</span></span></span><span class="line"><span class="cl"><span class="s1">\hline
</span></span></span><span class="line"><span class="cl"><span class="s1">Net Profit &amp; ENV_NET_PROFIT \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\end{tabular*}
</span></span></span><span class="line"><span class="cl"><span class="s1">\end</span><span class="si">{center}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\vfill\null
</span></span></span><span class="line"><span class="cl"><span class="s1">\textbf{\Large Statement of Financial Position} \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\date{As of ENV_YEAR-ENV_MONTH-ENV_DAY}
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin</span><span class="si">{multicols}{2}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin</span><span class="si">{center}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\textbf{Assets Detail} \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin{tabular*}{\hsize}{@</span><span class="si">{}</span><span class="s1">@{\extracolsep{\fill}}lr@</span><span class="si">{}</span><span class="s1">}
</span></span></span><span class="line"><span class="cl"><span class="s1">ACCOUNT &amp; TOTAL(CNY) \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\hline
</span></span></span><span class="line"><span class="cl"><span class="s1">ENV_LINES_ASSETS
</span></span></span><span class="line"><span class="cl"><span class="s1">\end{tabular*}
</span></span></span><span class="line"><span class="cl"><span class="s1">\vfill\null
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin{tabular*}{\hsize}{@</span><span class="si">{}</span><span class="s1">@{\extracolsep{\fill}}lr@</span><span class="si">{}</span><span class="s1">}
</span></span></span><span class="line"><span class="cl"><span class="s1">\hline
</span></span></span><span class="line"><span class="cl"><span class="s1">Total &amp; ENV_TOTAL_ASSETS \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\end{tabular*}
</span></span></span><span class="line"><span class="cl"><span class="s1">\end</span><span class="si">{center}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\columnbreak
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin</span><span class="si">{center}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\textbf{Liabilities Detail} \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin{tabular*}{\hsize}{@</span><span class="si">{}</span><span class="s1">@{\extracolsep{\fill}}lr@</span><span class="si">{}</span><span class="s1">}
</span></span></span><span class="line"><span class="cl"><span class="s1">ACCOUNT &amp; TOTAL(CNY) \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\hline
</span></span></span><span class="line"><span class="cl"><span class="s1">ENV_LINES_LIABILITIES
</span></span></span><span class="line"><span class="cl"><span class="s1">\end{tabular*}
</span></span></span><span class="line"><span class="cl"><span class="s1">\vfill\null
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin{tabular*}{\hsize}{@</span><span class="si">{}</span><span class="s1">@{\extracolsep{\fill}}lr@</span><span class="si">{}</span><span class="s1">}
</span></span></span><span class="line"><span class="cl"><span class="s1">\hline
</span></span></span><span class="line"><span class="cl"><span class="s1">Total &amp; ENV_TOTAL_LIABILITIES \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\end{tabular*}
</span></span></span><span class="line"><span class="cl"><span class="s1">\end</span><span class="si">{center}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\end</span><span class="si">{multicols}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin</span><span class="si">{center}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\begin{tabular*}{\hsize}{@</span><span class="si">{}</span><span class="s1">@{\extracolsep{\fill}}lr@</span><span class="si">{}</span><span class="s1">}
</span></span></span><span class="line"><span class="cl"><span class="s1">\hline
</span></span></span><span class="line"><span class="cl"><span class="s1">Debt Ratio &amp; ENV_DEBT_RATIO \\
</span></span></span><span class="line"><span class="cl"><span class="s1">\end{tabular*}
</span></span></span><span class="line"><span class="cl"><span class="s1">\vfill\null
</span></span></span><span class="line"><span class="cl"><span class="s1">\end</span><span class="si">{center}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\end</span><span class="si">{center}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">\end</span><span class="si">{document}</span><span class="s1">
</span></span></span><span class="line"><span class="cl"><span class="s1">&#39;&#39;&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Buffer</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="nf">replace</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">_old</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">_new</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="bp">self</span><span class="o">.</span><span class="n">value</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">_old</span><span class="p">,</span> <span class="n">_new</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">value</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># load file</span>
</span></span><span class="line"><span class="cl">    <span class="n">ledger_data</span><span class="p">,</span> <span class="n">errors</span><span class="p">,</span> <span class="n">options</span> <span class="o">=</span> <span class="n">loader</span><span class="o">.</span><span class="n">load_file</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">getcwd</span><span class="p">(),</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">]))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># init buffer</span>
</span></span><span class="line"><span class="cl">    <span class="n">_buffer</span> <span class="o">=</span> <span class="n">Buffer</span><span class="p">(</span><span class="n">_template</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># init time</span>
</span></span><span class="line"><span class="cl">    <span class="n">lm</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="o">-</span> <span class="n">relativedelta</span><span class="p">(</span><span class="n">months</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">year</span> <span class="o">=</span> <span class="n">lm</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&#34;%Y&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">month</span> <span class="o">=</span> <span class="n">lm</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&#34;%m&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">ENV_YEAR</span> <span class="o">=</span> <span class="n">year</span>
</span></span><span class="line"><span class="cl">    <span class="n">ENV_MONTH</span> <span class="o">=</span> <span class="n">month</span>
</span></span><span class="line"><span class="cl">    <span class="n">year</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">year</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">month</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">month</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">day</span> <span class="o">=</span> <span class="n">calendar</span><span class="o">.</span><span class="n">monthrange</span><span class="p">(</span><span class="n">year</span><span class="p">,</span> <span class="n">month</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">ENV_DAY</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">day</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># ENV_LINES_INCOME</span>
</span></span><span class="line"><span class="cl">    <span class="n">sql_query</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;SELECT account, abs(sum(cost(position))) as total WHERE account ~ &#34;^Income:*&#34; and year = &#39;</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">        <span class="n">ENV_YEAR</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; and month = &#39;</span> <span class="o">+</span> <span class="n">ENV_MONTH</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">        <span class="sa">r</span><span class="s1">&#39; GROUP BY month, account ORDER BY account, total DESC&#39;</span>
</span></span><span class="line"><span class="cl">    <span class="n">rrows</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">run_query</span><span class="p">(</span><span class="n">ledger_data</span><span class="p">,</span> <span class="n">options</span><span class="p">,</span> <span class="n">sql_query</span><span class="p">,</span> <span class="n">numberify</span><span class="o">=</span><span class="kc">True</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">ENV_LINES_INCOME</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">rrow</span> <span class="ow">in</span> <span class="n">rrows</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">ENV_LINES_INCOME</span> <span class="o">+=</span> <span class="n">rrow</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; &amp; &#39;</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;</span><span class="si">{0:.2f}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rrow</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; </span><span class="se">\\</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># ENV_TOTAL_INCOME</span>
</span></span><span class="line"><span class="cl">    <span class="n">sql_query</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;SELECT abs(sum(cost(position))) WHERE account ~ &#34;^Income:*&#34; and year = &#39;</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">        <span class="n">ENV_YEAR</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; and month =  &#39;</span> <span class="o">+</span> <span class="n">ENV_MONTH</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; GROUP BY month&#39;</span>
</span></span><span class="line"><span class="cl">    <span class="n">rrows</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">run_query</span><span class="p">(</span><span class="n">ledger_data</span><span class="p">,</span> <span class="n">options</span><span class="p">,</span> <span class="n">sql_query</span><span class="p">,</span> <span class="n">numberify</span><span class="o">=</span><span class="kc">True</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">ENV_TOTAL_INCOME</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">{0:.2f}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rrows</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># ENV_LINES_EXPENSES</span>
</span></span><span class="line"><span class="cl">    <span class="n">sql_query</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;SELECT account, sum(cost(position)) as total WHERE account ~ &#34;^Expenses:*&#34; and year = &#39;</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">        <span class="n">ENV_YEAR</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; and month = &#39;</span> <span class="o">+</span> <span class="n">ENV_MONTH</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">        <span class="sa">r</span><span class="s1">&#39; GROUP BY month, account ORDER BY account, total DESC&#39;</span>
</span></span><span class="line"><span class="cl">    <span class="n">rrows</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">run_query</span><span class="p">(</span><span class="n">ledger_data</span><span class="p">,</span> <span class="n">options</span><span class="p">,</span> <span class="n">sql_query</span><span class="p">,</span> <span class="n">numberify</span><span class="o">=</span><span class="kc">True</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">ENV_LINES_EXPENSES</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">rrow</span> <span class="ow">in</span> <span class="n">rrows</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">ENV_LINES_EXPENSES</span> <span class="o">+=</span> <span class="n">rrow</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; &amp; &#39;</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;</span><span class="si">{0:.2f}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rrow</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; </span><span class="se">\\</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># ENV_TOTAL_EXPENSES</span>
</span></span><span class="line"><span class="cl">    <span class="n">sql_query</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;SELECT sum(cost(position)) WHERE account ~ &#34;^Expenses:*&#34; and year = &#39;</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">        <span class="n">ENV_YEAR</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; and month = &#39;</span> <span class="o">+</span> <span class="n">ENV_MONTH</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; GROUP BY month&#39;</span>
</span></span><span class="line"><span class="cl">    <span class="n">rrows</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">run_query</span><span class="p">(</span><span class="n">ledger_data</span><span class="p">,</span> <span class="n">options</span><span class="p">,</span> <span class="n">sql_query</span><span class="p">,</span> <span class="n">numberify</span><span class="o">=</span><span class="kc">True</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">ENV_TOTAL_EXPENSES</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">{0:.2f}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rrows</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># ENV_NET_PROFIT</span>
</span></span><span class="line"><span class="cl">    <span class="n">sql_query</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;SELECT abs(sum(cost(position))) WHERE year = &#39;</span> <span class="o">+</span> <span class="n">ENV_YEAR</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; and month = &#39;</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">        <span class="n">ENV_MONTH</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">        <span class="sa">r</span><span class="s1">&#39; and ( account ~ &#34;^Expenses:*&#34; or account ~ &#34;^Income:*&#34; ) GROUP BY month&#39;</span>
</span></span><span class="line"><span class="cl">    <span class="n">rrows</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">run_query</span><span class="p">(</span><span class="n">ledger_data</span><span class="p">,</span> <span class="n">options</span><span class="p">,</span> <span class="n">sql_query</span><span class="p">,</span> <span class="n">numberify</span><span class="o">=</span><span class="kc">True</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">ENV_NET_PROFIT</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">{0:.2f}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rrows</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># ENV_LINES_ASSETS</span>
</span></span><span class="line"><span class="cl">    <span class="n">sql_query</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;SELECT account, sum(cost(position)) as total WHERE account ~ &#34;^Assets:*&#34; and year &lt;= &#39;</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">        <span class="n">ENV_YEAR</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; and month &lt;= &#39;</span> <span class="o">+</span> <span class="n">ENV_MONTH</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; and day &lt;= &#39;</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">        <span class="n">ENV_DAY</span><span class="o">+</span><span class="sa">r</span><span class="s1">&#39; ORDER BY account, total DESC&#39;</span>
</span></span><span class="line"><span class="cl">    <span class="n">rrows</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">run_query</span><span class="p">(</span><span class="n">ledger_data</span><span class="p">,</span> <span class="n">options</span><span class="p">,</span> <span class="n">sql_query</span><span class="p">,</span> <span class="n">numberify</span><span class="o">=</span><span class="kc">True</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">ENV_LINES_ASSETS</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">rrow</span> <span class="ow">in</span> <span class="n">rrows</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">ENV_LINES_ASSETS</span> <span class="o">+=</span> <span class="n">rrow</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; &amp; &#39;</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;</span><span class="si">{0:.2f}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rrow</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; </span><span class="se">\\</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># ENV_TOTAL_ASSETS</span>
</span></span><span class="line"><span class="cl">    <span class="n">sql_query</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;SELECT sum(cost(position)) as total WHERE account ~ &#34;^Assets:*&#34; and year &lt;= &#39;</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">        <span class="n">ENV_YEAR</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; and month &lt;= &#39;</span> <span class="o">+</span> <span class="n">ENV_MONTH</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; and day &lt;= &#39;</span><span class="o">+</span><span class="n">ENV_DAY</span>
</span></span><span class="line"><span class="cl">    <span class="n">rrows</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">run_query</span><span class="p">(</span><span class="n">ledger_data</span><span class="p">,</span> <span class="n">options</span><span class="p">,</span> <span class="n">sql_query</span><span class="p">,</span> <span class="n">numberify</span><span class="o">=</span><span class="kc">True</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">ENV_TOTAL_ASSETS</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">{0:.2f}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rrows</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># ENV_LINES_LIABILITIES</span>
</span></span><span class="line"><span class="cl">    <span class="n">sql_query</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;SELECT account, abs(sum(cost(position))) as total WHERE account ~ &#34;^Liabilities:*&#34; and year &lt;= &#39;</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">        <span class="n">ENV_YEAR</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; and month &lt;= &#39;</span> <span class="o">+</span> <span class="n">ENV_MONTH</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; and day &lt;= &#39;</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">        <span class="n">ENV_DAY</span><span class="o">+</span><span class="sa">r</span><span class="s1">&#39; ORDER BY account, total DESC&#39;</span>
</span></span><span class="line"><span class="cl">    <span class="n">rrows</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">run_query</span><span class="p">(</span><span class="n">ledger_data</span><span class="p">,</span> <span class="n">options</span><span class="p">,</span> <span class="n">sql_query</span><span class="p">,</span> <span class="n">numberify</span><span class="o">=</span><span class="kc">True</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">ENV_LINES_LIABILITIES</span> <span class="o">=</span> <span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">rrow</span> <span class="ow">in</span> <span class="n">rrows</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">ENV_LINES_LIABILITIES</span> <span class="o">+=</span> <span class="n">rrow</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; &amp; &#39;</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;</span><span class="si">{0:.2f}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rrow</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; </span><span class="se">\\</span><span class="s1">&#39;</span> <span class="o">+</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># ENV_TOTAL_LIABILITIES</span>
</span></span><span class="line"><span class="cl">    <span class="n">sql_query</span> <span class="o">=</span> <span class="sa">r</span><span class="s1">&#39;SELECT abs(sum(cost(position))) as total WHERE account ~ &#34;^Liabilities:*&#34; and year &lt;= &#39;</span> <span class="o">+</span> \
</span></span><span class="line"><span class="cl">        <span class="n">ENV_YEAR</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; and month &lt;= &#39;</span> <span class="o">+</span> <span class="n">ENV_MONTH</span> <span class="o">+</span> <span class="sa">r</span><span class="s1">&#39; and day &lt;= &#39;</span><span class="o">+</span><span class="n">ENV_DAY</span>
</span></span><span class="line"><span class="cl">    <span class="n">rrows</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">run_query</span><span class="p">(</span><span class="n">ledger_data</span><span class="p">,</span> <span class="n">options</span><span class="p">,</span> <span class="n">sql_query</span><span class="p">,</span> <span class="n">numberify</span><span class="o">=</span><span class="kc">True</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="n">ENV_TOTAL_LIABILITIES</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="si">{0:.2f}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">rrows</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># ENV_DEBT_RATIO</span>
</span></span><span class="line"><span class="cl">    <span class="n">ENV_DEBT_RATIO</span> <span class="o">=</span> <span class="s2">&#34;</span><span class="si">{:.2%}</span><span class="s2">&#34;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="n">Decimal</span><span class="p">(</span><span class="n">ENV_TOTAL_LIABILITIES</span><span class="p">)</span><span class="o">/</span><span class="n">Decimal</span><span class="p">(</span><span class="n">ENV_TOTAL_ASSETS</span><span class="p">))</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;%&#39;</span><span class="p">,</span> <span class="sa">r</span><span class="s1">&#39;\%&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">_buffer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;ENV_YEAR&#34;</span><span class="p">,</span> <span class="n">ENV_YEAR</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">_buffer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;ENV_MONTH&#34;</span><span class="p">,</span> <span class="n">ENV_MONTH</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">_buffer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;ENV_DAY&#34;</span><span class="p">,</span> <span class="n">ENV_DAY</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">_buffer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;ENV_LINES_INCOME&#34;</span><span class="p">,</span> <span class="n">ENV_LINES_INCOME</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">_buffer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;ENV_TOTAL_INCOME&#34;</span><span class="p">,</span> <span class="n">ENV_TOTAL_INCOME</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">_buffer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;ENV_LINES_EXPENSES&#34;</span><span class="p">,</span> <span class="n">ENV_LINES_EXPENSES</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">_buffer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;ENV_TOTAL_EXPENSES&#34;</span><span class="p">,</span> <span class="n">ENV_TOTAL_EXPENSES</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">_buffer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;ENV_NET_PROFIT&#34;</span><span class="p">,</span> <span class="n">ENV_NET_PROFIT</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">_buffer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;ENV_LINES_ASSETS&#34;</span><span class="p">,</span> <span class="n">ENV_LINES_ASSETS</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">_buffer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;ENV_TOTAL_ASSETS&#34;</span><span class="p">,</span> <span class="n">ENV_TOTAL_ASSETS</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">_buffer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;ENV_LINES_LIABILITIES&#34;</span><span class="p">,</span> <span class="n">ENV_LINES_LIABILITIES</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">_buffer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;ENV_TOTAL_LIABILITIES&#34;</span><span class="p">,</span> <span class="n">ENV_TOTAL_LIABILITIES</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">_buffer</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="sa">r</span><span class="s2">&#34;ENV_DEBT_RATIO&#34;</span><span class="p">,</span> <span class="n">ENV_DEBT_RATIO</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">_buffer</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>可以在这个<a href="https://github.com/RyoLee/beancount-template/blob/master/tool/get_bill.py">github 仓库</a>查看后续更新</p>
<h4 id="github-actions-配置">Github actions 配置</h4>
<p>Github actions 配置部分比较简单, 每月月初定时生成后邮件发出即可</p>
<p>敏感信息已用*号代替, 请自行替换(邮箱密码需在 github 添加 secrets <code>MAIL_PASSWORD</code>)</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">schedule-email</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">on</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">schedule</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">cron</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;30 16 1 */1 *&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">workflow_dispatch</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">jobs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">make-monthly-bill</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">make-monthly-bill</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">runs-on</span><span class="p">:</span><span class="w"> </span><span class="l">ubuntu-latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">steps</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Checkout repository</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/checkout@master</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Set up Python3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">actions/setup-python@v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">python-version</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;3.7&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">BSFishy/pip-action@v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">packages</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">            beancount</span><span class="w">            
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l">python3 tool/get_bill.py main.bean &gt; report.tex</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">Github Action for LaTeX</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">xu-cheng/latex-action@v2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">root_file</span><span class="p">:</span><span class="w"> </span><span class="l">report.tex</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">latexmk_use_xelatex</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">send-email</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l">dawidd6/action-send-mail@v3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">with</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">server_address</span><span class="p">:</span><span class="w"> </span><span class="cp">******</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">server_port</span><span class="p">:</span><span class="w"> </span><span class="cp">******</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">username</span><span class="p">:</span><span class="w"> </span><span class="cp">******</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">password</span><span class="p">:</span><span class="w"> </span><span class="l">${{secrets.MAIL_PASSWORD}}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">subject</span><span class="p">:</span><span class="w"> </span><span class="l">Monthly Beancount Report</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">attachments</span><span class="p">:</span><span class="w"> </span><span class="l">./report.pdf</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">to</span><span class="p">:</span><span class="w"> </span><span class="cp">******</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">from</span><span class="p">:</span><span class="w"> </span><span class="cp">******</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div>]]></content:encoded>
    </item>
    
  </channel>
</rss>
