Skip to content

Commit

Permalink
feat: show add account dialog when new account detected in OFX file +…
Browse files Browse the repository at this point in the history
… add local loop event on dialog
  • Loading branch information
opierre committed Oct 29, 2023
1 parent 838b80c commit cd48881
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 24 deletions.
1 change: 1 addition & 0 deletions budgetter/utils/ofxtools.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ def convert_ofx_to_json(ofx_file_path: str) -> Tuple[dict, dict, str]:
# Get account info
account = {
"account_id": statement.account.acctid,
# "account_type": statement.account.accttype,
"amount": float(statement.balance.balamt),
"last_update": statement.balance.dtasof.strftime("%Y-%m-%d"),
}
Expand Down
1 change: 1 addition & 0 deletions budgetter/view/panels/home.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,4 @@ def handle_convert_ofx(self, header: dict, message: str):
"""

self._transactions.handle_convert_ofx(header, message)
self._accounts.handle_convert_ofx(header)
56 changes: 46 additions & 10 deletions budgetter/view/panels/home_panel/accounts.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from PySide6.QtCore import QObject, QCoreApplication, QSize, Signal
from PySide6.QtCore import QObject, QCoreApplication, QSize, Signal, QEventLoop
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import QListView, QWidget, QHBoxLayout

Expand Down Expand Up @@ -43,6 +43,9 @@ def __init__(self, gui, main_window):
# Store dialogs for adding account
self.dialogs = []

# Store local event loop
self._event_loop = QEventLoop()

# Model to handle data in accounts list
self.accounts_model = AccountsModel()

Expand Down Expand Up @@ -120,15 +123,17 @@ def set_banks(self, banks: list):
self.bank_identifiers[bank.get("name")] = bank.get("id")
self.accounts_model.add_bank({bank.get("id"): bank.get("name")})

def add_account(self):
def add_account(self, account_info: dict = None):
"""
Open dialog to add new account
:param account_info: account info to rely on before adding
:return: None
"""

# Set dialog content
dialog_content = AddAccountDialog(self.bank_identifiers, self.main_window)
dialog_content = AddAccountDialog(self.bank_identifiers, self.main_window,
account_info=account_info)

# Set icon
header_icon = QIcon()
Expand All @@ -139,29 +144,33 @@ def add_account(self):
QIcon.State.On,
)

# Connect signal from popup to add new account
dialog_content.addAccount.connect(self.pre_add_account)

# Connect signal to open color picker
dialog_content.openColorDialog.connect(self.open_color_dialog)

# Open dialog
self.dialogs.append(
Dialog(
QCoreApplication.translate("Accounts", "Add Account"),
QCoreApplication.translate("Accounts", "Add Account", None),
header_icon,
dialog_content,
self.main_window,
closable=account_info is not None
)
)

# Connect signal from popup to add new account
dialog_content.addAccount.connect(self.pre_add_account)

# Connect signal to open color picker
dialog_content.openColorDialog.connect(self.open_color_dialog)

# Connect signal coming from click on Confirm button
self.dialogs[-1].confirm.connect(dialog_content.check_inputs)
self.dialogs[-1].escape.connect(self.escape_dialog)

# Set focus on first widget when opening
dialog_content.content.account_name.setFocus()

# Start event loop
self._event_loop.exec()

def open_color_dialog(self):
"""
Open color picker dialog
Expand Down Expand Up @@ -231,6 +240,9 @@ def escape_dialog(self):
self.dialogs[-1].close()
self.dialogs.pop()

# Quit event loop
self._event_loop.quit()

if len(self.dialogs) > 0:
self.dialogs[-1].show(False)

Expand Down Expand Up @@ -334,6 +346,9 @@ def add_account_details(self, account: dict):
# Open toaster
_ = Toaster("Account added", ToasterType.SUCCESS, self.main_window)

# Stop event loop
self._event_loop.quit()

def set_accounts(self, accounts: list):
"""
Store accounts for popups
Expand All @@ -351,3 +366,24 @@ def set_accounts(self, accounts: list):
self.balance_chart.add_slice(
float(account.get("amount")), account.get("color")
)

def handle_convert_ofx(self, header: dict):
"""
Handle conversion from OFX to check new accounts to create
:param header: header data
:return: None
"""

# Update info on dialog
new_accounts = []
for account in header.get("accounts", []):
if account.get("account_id", "") not in self.account_identifiers:
new_accounts.append(account)

# Open new dialogs to create new accounts
if new_accounts:
i = 0
for account in new_accounts:
print(i)
self.add_account(account)
3 changes: 1 addition & 2 deletions budgetter/view/panels/home_panel/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,6 @@ def import_transaction(self):
dialog_content = ImportTransactionsDialog(self.main_window)

# Set icon
# TODO: to change
header_icon = QIcon()
header_icon.addFile(
":/images/images/upload_file_FILL0_wght200_GRAD0_opsz24.svg",
Expand Down Expand Up @@ -683,7 +682,7 @@ def handle_convert_ofx(self, header: dict, message: str):
new_accounts = []
for account in header.get("accounts", []):
if account.get("account_id", "") not in self.account_identifiers:
new_accounts.append(account.get("account_id", ""))
new_accounts.append(account)

self.dialogs[-1].central_widget().set_header_info(
header.get("count", -1),
Expand Down
12 changes: 9 additions & 3 deletions budgetter/view/widgets/dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def __init__(
parent=None,
show_overlay: bool = True,
confirm_label: Union[str, None] = "",
closable: bool = True
):
super().__init__(parent)

Expand All @@ -70,7 +71,10 @@ def __init__(
self._dialog.confirm.setVisible(False)

# Store shortcuts
self.escape_shortcut = QShortcut(QKeySequence(Qt.Key.Key_Escape), self, self.escape.emit)
if closable is True:
self.escape_shortcut = QShortcut(QKeySequence(Qt.Key.Key_Escape), self, self.escape.emit)
else:
self._dialog.close.setVisible(False)
self.confirm_shortcut = QShortcut(QKeySequence(Qt.Modifier.CTRL | Qt.Key.Key_Return), self, self.confirm.emit)

# Store overlay
Expand All @@ -83,7 +87,7 @@ def __init__(
self.parallel_animation_group = QParallelAnimationGroup(self)

# Configure widgets
self.configure_widgets(dialog_title, header_icon, central_widget)
self.configure_widgets(dialog_title, header_icon, central_widget, closable)

# Connect all slots and signals
self.connect_all_slots_and_signals()
Expand All @@ -104,13 +108,15 @@ def connect_all_slots_and_signals(self):
# Connect click on confirm to emit signal
self._dialog.confirm.clicked.connect(self.confirm.emit) # pylint: disable=no-member

def configure_widgets(self, dialog_title: str, header_icon: QIcon, central_widget: QWidget):
def configure_widgets(self, dialog_title: str, header_icon: QIcon, central_widget: QWidget,
closable: bool):
"""
Configure title, central widget and animations
:param dialog_title: dialog main title
:param header_icon: dialog header icon
:param central_widget: central widget
:param closable: is widget closable
:return: None
"""

Expand Down
21 changes: 14 additions & 7 deletions budgetter/view/widgets/dialog_widgets/add_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class AddAccountDialog(QWidget):
# Signal emitted to open color picker dialog
openColorDialog = Signal()

def __init__(self, bank_ids: dict, parent=None):
def __init__(self, bank_ids: dict, parent=None, account_info: dict = None):
super().__init__(parent)

# Store dialog content
Expand All @@ -35,15 +35,16 @@ def __init__(self, bank_ids: dict, parent=None):
self.bank_completer = QCompleter(self.content.account_bank)

# Configure widgets
self.configure()
self.configure(account_info)

# Connect slots and signals
self.connect_slots_and_signals()

def configure(self):
def configure(self, account_info: dict = None):
"""
Configure all widgets
:param account_info: account info to rely on
:return: None
"""

Expand All @@ -60,12 +61,18 @@ def configure(self):
self.content.account_amount.set_label_color(QColor(224, 224, 224, 150))
self.content.account_amount.setValidator(QDoubleValidator(0, 100000, 2))
self.content.account_amount.set_trailing_symbol("€")
if account_info is not None:
self.content.account_amount.setText(str(account_info.get("amount")))

# Configure date edit
self.content.account_amount_date.set_label("Date")
self.content.account_amount_date.set_label_background_color(QColor("#1C293B"))
self.content.account_amount_date.set_text_color(QColor(255, 255, 255, 255))
self.content.account_amount_date.set_label_color(QColor(224, 224, 224, 150))
if account_info is not None:
self.content.account_amount_date.setText(
account_info.get("last_update")
)

# Configure combobox for bank choice
self.content.account_bank.set_label("Bank")
Expand Down Expand Up @@ -148,10 +155,10 @@ def check_inputs(self):
account_bank = self.content.account_bank.text()

if (
account_name != ""
and account_amount != ""
and account_amount_date != ""
and account_bank != ""
account_name != ""
and account_amount != ""
and account_amount_date != ""
and account_bank != ""
):
# Find corresponding bank identifier
bank_id = self.bank_ids.get(account_bank, None)
Expand Down
6 changes: 4 additions & 2 deletions budgetter/view/widgets/dialog_widgets/import_transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def set_header_info(
nb_transactions: int,
start_date: str,
end_date: str,
new_accounts: List[str],
new_accounts: List[dict],
):
"""
Update header info
Expand All @@ -89,7 +89,9 @@ def set_header_info(

# Set content
if new_accounts:
accounts_list = "\n".join(new_accounts)
accounts_list = ''
for account in new_accounts:
accounts_list += f"{account.get('account_id')}\n"
end_message = (
f"{len(new_accounts)} new accounts detected: \n{accounts_list}"
)
Expand Down

0 comments on commit cd48881

Please sign in to comment.