-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcli.py
More file actions
executable file
·157 lines (141 loc) · 5.45 KB
/
cli.py
File metadata and controls
executable file
·157 lines (141 loc) · 5.45 KB
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env python3
import os, sys, re, datetime
"""
FruityBanking command line interface for viewing and adding transactions.
"""
PATH = os.path.dirname(os.path.abspath(__file__)) + os.sep
sys.path.append(PATH)
import accounts
import db
import transactions
import web
from sitedefs import SHOW_VAT, DB_TYPE, DB_NAME, DB_USER, DB_PASSWORD
web.config.debug = False
if DB_TYPE == "postgres" or DB_TYPE == "mysql":
db.db = web.database(dbn=DB_TYPE, db=DB_NAME, user=DB_USER, pw=DB_PASSWORD)
else:
if not DB_NAME.startswith("/"): DB_NAME = "%s%s" % (PATH, DB_NAME)
db.db = web.database(dbn="sqlite", db=DB_NAME)
def currency_out(num):
return "£%0.2f" % (int(num) / 100.0)
def spaceleft(s, spaces):
"""
leftpads a string to a number of spaces
"""
sp = " "*255
if len(s) > spaces: return s
nr = spaces - len(s)
return sp[0:nr] + s
def spaceright(s, spaces):
"""
rightpads a string to a number of spaces
"""
sp = " "*255
if len(s) > spaces: return s
nr = spaces - len(s)
return s + sp[0:nr]
def ascii_table(data, separator=" | "):
"""
Given a 2D array of table values, outputs them as an ASCII table.
Columns are sized to the widest value.
"""
# Iterate the data once to find the widest value in each column
colwidths = [0] * len(data[0]) # initialise a 0 for each column
for row in data:
for i, v in enumerate(row):
if len(v) > colwidths[i]:
colwidths[i] = len(v)
# Calculate the total width
totalwidth = 0
for c in colwidths:
totalwidth += c
totalwidth += len(colwidths) * len(separator) # add separators to the width
# Build output
buffer = []
for ri, row in enumerate(data):
for i, v in enumerate(row):
# Right align money, Left align strings
if v.find("£") != -1:
buffer.append(spaceleft(v, colwidths[i]))
else:
buffer.append(spaceright(v, colwidths[i]))
# Leave a separator between columns if this isn't the last column
if i != len(colwidths)-1:
buffer.append(separator)
buffer.append("\n")
if ri == 0:
buffer.append("-" * (totalwidth-1))
buffer.append("\n")
return "".join(buffer)
def show_accounts():
"""
Output the list of accounts and balances.
"""
try:
# Show account period if one is set
from sitedefs import NAMED_PERIOD
period = "Income/expense totals shown for period: %s" % NAMED_PERIOD
print(period)
print("")
except:
period = ""
header = [ "ID", "Code", "Type", "Description", "Reconciled", "Balance" ]
data = [ header ]
acs = accounts.getAllAccounts()
for a in acs:
data.append([ str(a.id), a.code, accounts.getAccountTypeForID(a.type), a.description, currency_out(a.reconciledtotal), currency_out(a.balance) ])
print(ascii_table(data))
def show_trx(accountid, datefrom="", dateto=""):
"""
Output the list of transactions for an account.
"""
d31 = datetime.timedelta(days = 31)
if dateto == "":
dto = transactions.toUnixDate(datetime.datetime.today() + d31)
dateto = transactions.pythonToDisplayDate(datetime.datetime.today() + d31)
else:
dto = transactions.toUnixDate(transactions.displayToPythonDate(dateto))
if datefrom == "":
dfrom = transactions.toUnixDate(datetime.datetime.today() - d31)
datefrom = transactions.pythonToDisplayDate(datetime.datetime.today() - d31)
else:
dfrom = transactions.toUnixDate(transactions.displayToPythonDate(datefrom))
trx = transactions.getTransactions(accountid, dfrom, dto)
print("Transactions - %s (%s): %s to %s" % (accounts.getAccountById(accountid).code, accountid, datefrom, dateto))
print("")
header = [ "Date", "R", "V", "Description", "Account", "Deposit", "Withdrawal", "Balance" ]
data = [ header ]
displayedToday = False
for t in trx:
outputdate = transactions.pythonToDisplayDate(t.date)
outputreconciled = t.reconciled == 1 and "R" or ""
outputvat = t.vat == 1 and "V" or ""
outputwithdrawal = ""
outputdeposit = ""
if t.deposit > 0:
outputdeposit = currency_out(t.deposit)
if t.withdrawal > 0:
outputwithdrawal = currency_out(t.withdrawal)
outputbalance = currency_out(t.balance)
if not displayedToday and t.date > datetime.date.today():
displayedToday = True
data.append([ "--", "--", "--", "--", "--", "--", "--", "--" ])
pass # TODO: display horizontal bar
# highlight bad transactions where source/dest are the same
outputotheraccount = "%s (%s)" % (t.otheraccountcode, t.otheraccountid)
if t.otheraccountid == int(accountid):
outputotheraccount = "<--> %s" % outputotheraccount
data.append([ outputdate, outputreconciled, outputvat, t.description, outputotheraccount, outputdeposit,
outputwithdrawal, outputbalance ])
print(ascii_table(data))
if len(sys.argv) == 1:
show_accounts()
if len(sys.argv) == 2 and sys.argv[1] == "help":
print("Usage:")
print(" cli [no args]")
print(" cli show <accountid>")
print(" cli show <accountid> 01/02/2022 31/03/2022")
if len(sys.argv) == 3 and sys.argv[1] == "show":
show_trx(sys.argv[2])
if len(sys.argv) == 5 and sys.argv[1] == "show":
show_trx(sys.argv[2], sys.argv[3], sys.argv[4])