-
Notifications
You must be signed in to change notification settings - Fork 0
/
esun-checking.py
130 lines (109 loc) · 3.43 KB
/
esun-checking.py
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
from dataclasses import dataclass
from datetime import datetime
from argparse import ArgumentParser
@dataclass
class EsunTransaction:
account_no: str
date: datetime
db_cr: str
amount: int
fee: int
subtotal: int
type: str
remark: str
def parse_row(row: str):
account_no = row[:13] # account no.
roc_date = row[14:21] # date in ROC format
date = datetime(int(roc_date[:3]) + 1911, int(roc_date[3:5]), int(roc_date[5:7]))
db_cr = row[21:23] # debit or credit?
amount = int(row[24:36])
fee = int(row[36:38])
subtotal = int(row[39:51])
type = row[53:59].strip()
remark = row[59:64].strip()
return EsunTransaction(
account_no,
date,
db_cr,
amount,
fee,
subtotal,
type,
remark
)
def print_human(transactions: list[EsunTransaction]):
for transaction in transactions:
print_row_human(transaction)
def print_row_human(transaction: EsunTransaction):
print(f"Account #: {transaction.account_no}")
print(f"Date: {transaction.date}")
print(f"DB/CR: {transaction.db_cr}")
print(f"Amount: {transaction.amount}")
print(f"Fee: {transaction.fee}")
print(f"Subtotal: {transaction.subtotal}")
print(f"Type: {transaction.type}")
print(f"Remark: {transaction.remark}")
def print_csv(transactions: list[EsunTransaction]):
fields = [
"account_no",
"date",
"DB/CR",
"amount",
"fee",
"subtotal",
"type",
"remark"
]
print(",".join(fields))
for transaction in transactions:
print_row_csv(transaction)
def print_row_csv(transaction: EsunTransaction):
fields = [
transaction.account_no,
transaction.date.strftime("%Y-%m-%d"),
transaction.db_cr,
str(transaction.amount),
str(transaction.fee),
str(transaction.subtotal),
transaction.type,
transaction.remark
]
print(",".join(fields))
def print_beancount(transactions: list[EsunTransaction]):
for transaction in transactions:
print_row_beancount(transaction)
def print_row_beancount(transaction: EsunTransaction):
remark = "Bank Transfer"
if transaction.remark != "":
remark = transaction.remark
print(f"{transaction.date.strftime("%Y-%m-%d")} * \"{remark}\"")
if transaction.db_cr == "DB":
print(f"\tAssets:Checking:ESUN -{transaction.amount} NTD")
print(f"\tExpenses:Uncategorised {transaction.amount} NTD")
if transaction.db_cr == "CR":
print(f"\tAssets:Checking:ESUN {transaction.amount} NTD")
print(f"\tIncome:Uncategorised -{transaction.amount} NTD")
print()
def main():
parser = ArgumentParser()
parser.add_argument("source")
parser.add_argument("--format", choices=["csv","human","beancount"], default="human")
parsed = parser.parse_args()
with open(parsed.source, encoding="Big5") as source:
rows = []
while True:
row = source.readline()
if row == "": break
try:
transaction = parse_row(row)
rows.append(transaction)
except Exception:
continue
if parsed.format == "csv":
print_csv(rows)
elif parsed.format == "human":
print_human(rows)
elif parsed.format == "beancount":
print_beancount(rows)
if __name__ == "__main__":
main()