育休中なので家計簿を自動化しました
最初に
地方でしがないエンジニアをやっています。
PG歴はそこそこながらもDBはさわり初めて2年くらいのペーペー。
我が家は妻である私が変動費を支えておりますが、昨今の物価上昇などでちょい厳しくなってきました
夫に増資要求するためにもエビデンスが必要
これまで家計簿はExcelでつけており一部はマネーフォワードから一括でさらってきてなどして手動でつけておりましたが、最近はつけられていませんでした。
2人目のちびちゃんが出来て育休中で多少時間がある今、もうなんか通販は自動取り込み、足での買い物はレシート読み取りくらい簡略化したいです。
やりたいこと
以下の購入品リストの作成
項目:購入日 品名 値段 カテゴリ 購入場所 支払い元
これをデータベース化できれば家計簿として欲しい情報は手に入るでしょう。
あとはメールの自動取り込み(日次で自働更新と手動で取り込みが可能)
レシートは指定フォルダに保存したら上と同じ対応で自動取り込み
現在の状況
出費の大枠は
通販が Amazon 楽天 ヨドバシ の3種
食品宅配系が コープ自然派(口座引落) ヨシケイ の2種類
クレカが kyash(リクルートカード) イオン 楽天カード の3種
を使い分け
後は保育料などの定額引き落としがあります
現金の利用は病院と交通系ICチャージ位
情報の取得方法
色々思いつくところはありますが、この通りに行こうと思います
ネット通販,定期宅配 → メールbox
それ以外の日常の買い物 → レシート(これは多分一般的ではないのですが、私はレシートを基本全スキャンしています)
注文受付メールの取得
キャンセルをすることはほぼ無いので、注文受付メールから購入履歴を取得します。
もちろんブラウザからスクレイピングしても良かったのですが、各サイトごとにコーディングが必要だったり、サイト側のソース変更されると使えなくなるし、ログイン周りがちょっと面倒だと思ったので自動返信メールから取得で十分と判断
それぞれのメール件名は下記の通り
・Amazon
Amazon.co.jpでのご注文[注文番号xxx-xxxxxxx-xxxxxxx](x点)
※注文詳細はwebページを開かないと見えない
・楽天市場
【楽天市場】注文内容ご確認(自動配信メール)
・ヨドバシドットコム
ヨドバシ・ドット・コム:ご注文ありがとうございます
・コープ自然派
[ 自然派オンライン ] ご注文を承りました。[ 通常注文 ]
・ヨシケイ
m/dd週ご利用明細【ヨシケイ○○】
プラットフォームは何でもいいんですが、欲言えばブラウザから閲覧できたらいいな
もっと欲言えば自宅LANから誰でもアクセスできて、権限管理とかできたら家族にも共有できる と最高
(そんなことがパパっとできるならしがないエンジニアやってないんですけどね)
とりあえず阿保みたいに脳死でpythonを選択します
手順
webアプリケーション
ローカルサーバーにwebシステム構築
DBの購入品リストや月別家計簿などを表示
メール読み取り
outlookのメールボックス内を取得
メールは件名フィルタでフォルダに保存
楽天やAmazon別
ショッピングサイトの追加が容易となるように設計
取得期間の指定ができること
保存したフォルダ内のメール仕分け
DBに保存する
レシート読み取り
後回し
技術調査
出来ないで積むとしんどいので先に出来るかどうかを判断するため大枠技術を確認します。
ちなみに普通にChatGPTを使っています。
メール抽出
まず期間を指定して件名ごとにmsgファイルを保存する関数を作成しました。
def save_gmail_emails(subject_keyword, start_date, end_date, save_folder):
# Format dates to match Outlook filter criteria
start_date_str = start_date.strftime("%m/%d/%Y %H:%M %p")
end_date_str = end_date.strftime("%m/%d/%Y %H:%M %p")
outlook = win32com.client.Dispatch("Outlook.Application").GetNamespace("MAPI")
accounts = outlook.Folders
for account in accounts:
if account.Name == "...@gmail.com": # Gmailアカウントのフォルダを見つける
for folder in account.Folders:
print(folder)
inbox = account.Folders("受信トレイ") # Gmailの受信トレイにアクセス
filter_str = f"[ReceivedTime] >= '{start_date_str}' AND [ReceivedTime] <= '{end_date_str}'"
emails = inbox.Items
filtered_emails = inbox.Items.Restrict(filter_str)
for email in filtered_emails:
if subject_keyword.lower() in email.Subject.lower():
sanitized_subject = re.sub(r'[\\/*?:"<>|]', "", email.Subject)
received_time_str = email.ReceivedTime.strftime('%Y%m%d%H%M')
safe_subject = "".join(x for x in email.Subject if x.isalnum() or x in "._- ")
save_path = os.path.join(save_folder, f"{received_time_str}_{safe_subject}.msg")
email.SaveAs(save_path) # Save as .msg format
DB作成
仕事で使ってるという安直な理由でOracle選択
仕事でSQL使って無かったらMySQLだったと思う
公式サイトからOracleXE213_Win64を落としてインストールしました。
起動するとカーネルが結構食うのでいずれは別PCへ移したい
接続はchatGPTにクラスを作ってもらったのが修正不要でそのまま使えそうです。
web
flaskでdbのテーブル内容表示までは確認
app.py
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# Make the WSGI interface available at the top level so wfastcgi can get it.
wsgi_app = app.wsgi_app
app.config['SQLALCHEMY_DATABASE_URI'] = 'oracle://system:admin@localhost:1521/XE'
db = SQLAlchemy(app)
class sample(db.Model):
__tablename__ = "test_table"
id = db.Column(db.Integer, primary_key=True)
val = db.Column(db.Text())
@app.route('/')
def hello():
"""Renders a sample page."""
#return "Hello World!"
sample_table = sample.query.all()
return render_template('index.html', message='Hello', sample_vals = sample_table)
if __name__ == '__main__':
import os
HOST = os.environ.get('SERVER_HOST', 'localhost')
try:
PORT = int(os.environ.get('SERVER_PORT', '5555'))
except ValueError:
PORT = 5555
app.run(HOST, PORT)
index.html
{% extends "base.html" %}
{% block content %}
<p>this is template</p>
<table>
{% for sample in sample_vals: %}
<tr>
<td>{{sample.id}}</td>
<td>{{sample.val}}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
上で使ったDBクラスは必要なさそう
設計
無形含めてもモノづくりにおいて一番肝心なところだと思ってるけど
デザインツールも使わずUMLも作成せず・・・。
見た目
元々使っていたExcelがあるのでこのままデザインは流用
topページは当月が表示され左側にまとめ、右側にリストです。
固定費は月ごとに若干変動するので(←固定費とは?)つど入力できるようにしたい。
予算は1年間共通
収入はその月ごとに記録
後は、集計ページ
Excelではここで予算を決めているので同じようにします。
手当金など臨時収入もまとめページで入力させます。
まとめると
・月ごとの集計
リストは自動取り込み
手動入力、編集可(+ボタンで追加、ダブルクリックで編集モードとできたらいいな)
予算は集計ページから引用
計算はリアルタイムで
・年ごとの集計
月ごとのカテゴリ別集計が自動でされる
臨時収入を追加できる
予算を手入力できる
メモ欄があり記載できる
ヘッダーにメニューを表示して遷移
テーブル構成
◆購入リストテーブル
買った物すべてのリストです。月ページに表示します。
列は
・ID(yymmddhhmmss形式)
メールの受信日時を念のため秒まで含めてユニークIDとします。多分大丈夫でしょう。
・購入年(例:2024)
・購入日(7/10)
・カテゴリID
・商品名(マッシュルーム(スライス)90g)
・値段(173円)
・購入個数(1)
・購入店舗(ヨドバシ・ドット・コム)
・備考
このくらいあればいい気がします。
◆カテゴリマスタ
・カテゴリID
・カテゴリ名
◆月収支テーブル
月ごとの固定費と収入を記録します。
・対象年
・対象月
・項目
・金額
◆年収支テーブル
月を考慮したくない特別費を記録します。
・対象年
・項目
・金額
・備考
◆予算テーブル
予算を記録します
・対象年
・カテゴリID
・予算
後は作りながら必要なものがあれば追加していきます。
作成
実は此処まで記事で作成しておいて数か月経ってやらなきゃと思い約半月ほどの育児の合間の時間で作成しました。
殆どChatGPTに作ってもらったが、正に仕事で外注さんとやり取りする感覚でちょいちょいできる。
自分の技量量の増加は全く見込めないがその分めちゃ早い。今回趣味だけど勉強ではなく非常に実用として必要なものなのでこれでいいです。
とりあえず、ヨドバシだけメールから取得して表示まで完了した。
購入品リストはダブルクリックで編集可能
カテゴリーの設定がめちゃくちゃ面倒くさくて悩み中
既存の家計簿で一番面倒だったのがヨドバシだったのでここまでできればだいぶ楽かな
(宅配系は全て食料品計上でAmazonは拡張機能でcsvを取得でき、楽天は購入履歴遡りやすいのでそこまで手間がかかってない。ヨドバシが特に購入履歴と値段の確認が面倒だった)
かなり作りこまないとExcelの方が圧倒的に操作性とか楽だからVBAの方が有用だったかもしれない
Excelそのままweb表示出来るし共有も出来るしそれで良かったなと作ってから思った
ということで今回は此処までやって力尽きた
一旦別作業(資格の勉強)がしたいのでそっちに尽力しつつせっかく作ったので合間があれば他のメール取得やレシート読み込みとかできたらいいなと思います。
あとカテゴリーの自動設定
この記事が気に入ったらサポートをしてみませんか?