-
Notifications
You must be signed in to change notification settings - Fork 0
/
budgetApp.py
143 lines (113 loc) · 4.34 KB
/
budgetApp.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
131
132
133
134
135
136
137
138
139
140
141
142
143
import configparser
import json
import logging
import sys
import tkinter
import uuid
from dataclasses import dataclass, field
from pathlib import Path
from tkinter import filedialog
from typing import Dict, List, Set
from PySide2 import QtWidgets
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
@dataclass(frozen=True)
class Transaction:
amount: float
category: str
expense: str
comment: str
id: str
class Budget:
"""
The class is managing the database:
adding the data if the new expense/category added to the UI
saves the update to the database
"""
def __init__(self, file_path: str):
self.file_path = file_path
self._data = set_json_data(file_path)
self.budget_transactions = BudgetTransactions()
from budgetUI import BudgetEditorWindow
budget_editor = BudgetEditorWindow(self)
budget_editor.show()
budget_editor.add_new_transaction_signal.connect(self.add_new_transaction)
budget_editor.del_transaction_signal.connect(self.del_transaction)
budget_editor.del_row_signal.connect(self.delete_category)
@property
def data(self):
return self._data
@data.setter
def data(self, value):
self._data = value
@property
def transactions(self):
return self.budget_transactions.transactions
def add_new_category(self, year: str, month: str, category: str, expense: str, allotted: str, comment: str) -> None:
"""
Updates the database when the new expense is added to the UI
"""
month_data = self.data[year][month]
expense_data = {expense: {"Allotted": allotted,
"Spending": 0,
"Comment": comment}}
if category in month_data:
month_data[category].update(expense_data)
else:
month_data[category] = expense_data
self.data[year][month] = month_data
def delete_category(self, *args):
year = args[0]
month = args[1]
category = args[2]
expense = args[3]
data_expense = self.data.get(year).get(month).get(category).get(expense)
if data_expense:
print("deleting expense")
del self.data[year][month][category][expense]
else:
del self.data[year][month][category]
def add_new_transaction(self, *args, **kwargs) -> None:
self.budget_transactions.add_new_transaction(*args)
def del_transaction(self, transaction: Dict[str, str]) -> None:
if transaction is None:
return
self.budget_transactions.del_transaction(Transaction(**transaction))
def save(self):
with open(self.file_path, 'w') as jsonfile:
json.dump(self.data, jsonfile, indent=4)
@dataclass
class BudgetTransactions:
transactions: Set[Transaction] = field(default_factory=set)
def add_new_transaction(self, category: str, expense: str, amount: float, comment: str) -> None:
transaction_id = str(uuid.uuid4())
self.transactions.add(Transaction(amount, category, expense, comment, transaction_id))
logger.info(f'transaction {transaction_id} added')
def del_transaction(self, transaction: Transaction) -> None:
logger.info(f'deleting transaction {transaction}')
self.transactions.discard(transaction)
def set_json_data(data_path):
with open(data_path, 'r') as jsonfile:
return json.load(jsonfile)
if __name__ == '__main__':
config_file = Path(__file__).parent / r"config.ini"
config = configparser.ConfigParser()
if not config_file.exists():
config.add_section('settings')
config.set('settings', 'last_file', '.')
with open(config_file, 'w') as configfile:
config.write(configfile)
config.read(config_file)
last_file = Path(config['settings']['last_file'])
root = tkinter.Tk()
root.withdraw()
app = QtWidgets.QApplication(sys.argv)
file_path = filedialog.askopenfilename(
parent=root, title='Select data JSON file', initialfile=last_file,
initialdir=last_file.parent, filetypes=[('JSON', '*.json')])
last_file = Path(file_path)
config.set('settings', 'last_file', last_file.as_posix())
with open(config_file, 'w') as configfile:
config.write(configfile)
bud = Budget(file_path)
sys.exit(app.exec_())