totals.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. # GPL3 or any later version
  2. import os
  3. import json
  4. import gi
  5. import time
  6. import threading
  7. import datetime
  8. gi.require_version('Gtk', '3.0')
  9. from gi.repository import Gtk
  10. from gi.repository import Gdk
  11. from gi.repository import GLib
  12. from modules import graphs
  13. from modules import wallet
  14. from modules import transactions
  15. def EDB(payday, balance, today):
  16. # Estimated Daily Budget.
  17. date_format = "%Y/%m/%d"
  18. datetime_today = datetime.datetime.strptime(today, date_format)
  19. if payday < datetime_today.day:
  20. nm = int(datetime_today.month)
  21. nm = nm + 1
  22. if nm > 12:
  23. nm = 1
  24. nm = str(nm)
  25. if len(nm) < 2:
  26. nm = "0"+nm
  27. nextm = today[:today.find("/")+1]+nm+today[today.rfind("/"):]
  28. else:
  29. nextm = today
  30. # Converting
  31. payday = str(payday)
  32. if len(payday) < 2:
  33. payday = "0"+payday
  34. payday = nextm[:nextm.rfind("/")+1]+payday
  35. tpayday = datetime.datetime.strptime(payday, date_format)
  36. days_between = int((tpayday - datetime_today).days)
  37. try:
  38. mpd = balance / days_between
  39. except:
  40. mpd = balance
  41. return mpd
  42. def update_totals(win):
  43. # Updates the totals view
  44. box = win.totals_box
  45. the_wallet = win.wallet
  46. for i in box.get_children():
  47. i.destroy()
  48. data = wallet.get_totals(the_wallet)
  49. print(data)
  50. # Important settings
  51. currancy = data.get("currancy", "$")
  52. payday = data.get("payday", 10)
  53. try:
  54. int(payday)
  55. except:
  56. payday = 10
  57. # loading balance
  58. balance = 0
  59. balance_before_today = 0
  60. balance_of_today = 0
  61. graph_data = {"items":[],
  62. "zoom":[int(time.time()-(60*60*24*365/4)), # One Quarter of a year
  63. int(time.time())],
  64. "allow_negative":True
  65. }
  66. pulse_graph_data = {"items":[],
  67. "zoom":[int(time.time()-(60*60*24*365/4)), # One Quarter of a year
  68. int(time.time())],
  69. "allow_negative":True
  70. }
  71. EDB_graph_data = {"items":[],
  72. "zoom":[int(time.time()-(60*60*24*365/4)), # One Quarter of a year
  73. int(time.time())],
  74. "allow_negative":True
  75. }
  76. EDB_leftovers_graph_data = {"items":[],
  77. "zoom":[int(time.time()-(60*60*24*365/4)), # One Quarter of a year
  78. int(time.time())],
  79. "allow_negative":True
  80. }
  81. folder = wallet.save_folder()+"wallets/"+win.wallet+"/transactions/"
  82. try:
  83. transactions = list(os.walk(folder))[0][2]
  84. transactions = sorted(transactions)
  85. except:
  86. transactions = []
  87. pre_date = "0000/00/00"
  88. dates_EDB = 0
  89. balance_at_EDB = 0
  90. leftover = 0
  91. for i in transactions:
  92. try:
  93. with open(folder+i) as json_file:
  94. tdata = json.load(json_file)
  95. timestamp = int(i.replace(".json", ""))
  96. date_format = "%Y/%m/%d"
  97. date_of_transaction = time.strftime(date_format, time.gmtime(timestamp))
  98. today = time.strftime(date_format, time.gmtime(time.time()))
  99. prebalance = balance
  100. balance = balance + tdata.get("total", 0)
  101. if date_of_transaction != today:
  102. balance_before_today = balance
  103. else:
  104. balance_of_today = balance_of_today + tdata.get("total", 0)
  105. # Balance Graph
  106. a = {}
  107. a["amount"] = balance
  108. a["timestamp"] = timestamp
  109. graph_data["items"].append(a)
  110. # Pulse Graph
  111. a = {}
  112. a["amount"] = tdata.get("total", 0)
  113. a["timestamp"] = timestamp
  114. pulse_graph_data["items"].append(a)
  115. # EDB Graph
  116. if date_of_transaction != pre_date:
  117. dates_EDB = EDB(payday, prebalance, date_of_transaction)
  118. balance_at_EDB = prebalance
  119. a = {}
  120. a["amount"] = dates_EDB
  121. a["timestamp"] = timestamp
  122. EDB_graph_data["items"].append(a)
  123. print()
  124. leftover = balance - balance_at_EDB + dates_EDB
  125. a = {}
  126. a["amount"] = leftover
  127. a["timestamp"] = timestamp
  128. EDB_leftovers_graph_data["items"].append(a)
  129. pre_date = date_of_transaction
  130. except Exception as e:
  131. print(e)
  132. balance = round(balance, 2)
  133. balance_label = Gtk.Label()
  134. balance_label.set_line_wrap_mode( Gtk.WrapMode.WORD )
  135. balance_label.set_line_wrap(True)
  136. balance_label.set_markup('<span size="x-large"> '+currancy+str(balance)+'</span> ')
  137. balance_label.set_selectable(True)
  138. balance_label.set_css_name("")
  139. def on_balance_button(w):
  140. balance_calculator(win, balance)
  141. balance_button = Gtk.Button()
  142. balance_button.add(balance_label)
  143. balance_button.set_relief(Gtk.ReliefStyle.NONE)
  144. balance_button.connect("clicked", on_balance_button)
  145. box.pack_start(balance_button, 0,0,10)
  146. # Money per day till pay day
  147. date_format = "%Y/%m/%d"
  148. today = datetime.datetime.strftime(datetime.datetime.today(), date_format)
  149. mpd = EDB(payday, balance_before_today, today)
  150. show_mpd = currancy+str(round(mpd, 2))+" : yesterday's estimated daily budget (EDB)"
  151. box.pack_start(Gtk.Label(show_mpd), 0,0,10)
  152. # Today used
  153. show_today_user = currancy+str(round(balance_of_today, 2))+" : today's difference"
  154. box.pack_start(Gtk.Label(show_today_user), 0,0,10)
  155. # Left for today
  156. show_left_for_today = currancy+str(round(mpd+balance_of_today, 2))+" : today's budget"
  157. box.pack_start(Gtk.Label(show_left_for_today), 0,0,10)
  158. edb = EDB(payday, balance, today)
  159. show_mpd = currancy+str(round(edb, 2))+" : estimated daily budget (EDB)"
  160. box.pack_start(Gtk.Label(show_mpd), 0,0,10)
  161. # Notebook
  162. notebook = Gtk.Notebook()
  163. notebook.set_scrollable(True)
  164. box.pack_start(notebook, 1,1,10)
  165. the_graph = graphs.graph(win, graph_data, "Balance", currancy=currancy, graph_addition="last")
  166. detailsbox = Gtk.HBox()
  167. detailsbox.pack_start(Gtk.Label(" Balance "), True, True, True)
  168. detailsbox.show_all()
  169. notebook.append_page(the_graph, detailsbox)
  170. pulse_graph = graphs.graph(win, pulse_graph_data, "Pulse", currancy=currancy, graph_addition="add", add_value=0)
  171. detailsbox = Gtk.HBox()
  172. detailsbox.pack_start(Gtk.Label(" Difference "), True, True, True)
  173. detailsbox.show_all()
  174. notebook.append_page(pulse_graph, detailsbox)
  175. edb_graph = graphs.graph(win, EDB_graph_data, "EDB", currancy=currancy, graph_addition="last")
  176. detailsbox = Gtk.HBox()
  177. detailsbox.pack_start(Gtk.Label(" EDB "), True, True, True)
  178. detailsbox.show_all()
  179. notebook.append_page(edb_graph, detailsbox)
  180. leftovers_graph = graphs.graph(win, EDB_leftovers_graph_data, "gains", currancy=currancy, graph_addition="last", add_value=0)
  181. detailsbox = Gtk.HBox()
  182. detailsbox.pack_start(Gtk.Label(" Gains / Losses "), True, True, True)
  183. detailsbox.show_all()
  184. notebook.append_page(leftovers_graph, detailsbox)
  185. box.show_all()
  186. def balance_calculator(win, balance):
  187. # This window will help people calculate the money.
  188. dialogWindow = Gtk.Dialog("Balance Calculator",
  189. buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
  190. Gtk.STOCK_OK, Gtk.ResponseType.OK),
  191. )
  192. dialogWindow.set_size_request(200, 200)
  193. data = wallet.get_totals(win.wallet)
  194. currancy = data.get("currancy", "$")
  195. box = dialogWindow.get_content_area()
  196. # Types of coins
  197. amounts = [0.01,
  198. 0.1,
  199. 0.25,
  200. 0.5,
  201. 1,
  202. 2,
  203. 5,
  204. 10,
  205. 20,
  206. 50,
  207. 100,
  208. 200,
  209. 500,
  210. 1000]
  211. wdg = []
  212. def calculate(w):
  213. b = 0
  214. for n, i in enumerate(wdg):
  215. b = b + ( i[1].get_value() * amounts[n])
  216. total_amount_entry.set_value(b)
  217. for n, coin in enumerate(amounts):
  218. abox = Gtk.HBox()
  219. box.pack_start(abox, 0,0,5)
  220. abox.pack_start(Gtk.Label(currancy+" "+str(coin)), 0,0,10)
  221. amount_adjust = Gtk.Adjustment(0,
  222. lower=-10000000000000000000,
  223. upper=10000000000000000000,
  224. step_increment=1)
  225. amount_entry = Gtk.SpinButton(adjustment=amount_adjust,
  226. digits=0)
  227. abox.pack_end(amount_entry, 0,0,10)
  228. amount_entry.connect("changed", calculate)
  229. wdg.append([amount_adjust, amount_entry])
  230. box.pack_start(Gtk.HSeparator(), 0,0,10)
  231. abox = Gtk.HBox()
  232. box.pack_start(abox, 0,0,5)
  233. abox.pack_start(Gtk.Label("Total: "+currancy+" "), 0,0,10)
  234. total_amount_adjust = Gtk.Adjustment(0,
  235. lower=-10000000000000000000,
  236. upper=10000000000000000000,
  237. step_increment=1)
  238. total_amount_entry = Gtk.SpinButton(adjustment=total_amount_adjust,
  239. digits=2)
  240. abox.pack_end(total_amount_entry, 0,0,10)
  241. box.show_all()
  242. response = dialogWindow.run()
  243. if response == Gtk.ResponseType.OK:
  244. name = str(int(time.time()))+".json"
  245. the_wallet = win.wallet
  246. folder = wallet.save_folder()+"wallets/"+the_wallet+"/transactions/"
  247. tfile = folder+name
  248. comment = "Calculated Balance:\n"
  249. for n, i in enumerate(wdg):
  250. v = i[1].get_value()
  251. if v:
  252. comment = comment +"\n"+currancy+" "+str(amounts[n])+" X "+str(int(v))
  253. comment = comment + "\n\nTotal: "+currancy+" "+str(total_amount_entry.get_value())
  254. comment = comment + "\nError: "+currancy+" "+str(total_amount_entry.get_value()-balance)
  255. transaction = {
  256. "items": [
  257. {
  258. "item": "count_feature",
  259. "amount": 1,
  260. "price": total_amount_entry.get_value()-balance
  261. }
  262. ],
  263. "total": total_amount_entry.get_value()-balance,
  264. "comment":comment
  265. }
  266. with open(tfile, "w") as fp:
  267. json.dump(transaction, fp, indent=4)
  268. transactions.update_transactions(win)
  269. update_totals(win)
  270. dialogWindow.destroy()