From 8960108bb499b69ca5dbd2beac631a6d167e4ea0 Mon Sep 17 00:00:00 2001 From: David Rodenkirchen Date: Mon, 26 Aug 2024 01:20:12 +0200 Subject: [PATCH] add accounting page and fix issue with db selects --- src/EzLanManager.py | 2 +- src/ez_lan_manager/pages/Account.py | 158 ++++++++++++++++++ src/ez_lan_manager/pages/__init__.py | 1 + .../services/AccountingService.py | 3 + .../services/DatabaseService.py | 13 ++ 5 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 src/ez_lan_manager/pages/Account.py diff --git a/src/EzLanManager.py b/src/EzLanManager.py index f535f99..1542e7c 100644 --- a/src/EzLanManager.py +++ b/src/EzLanManager.py @@ -115,7 +115,7 @@ if __name__ == "__main__": Page( name="Account", page_url="account", - build=lambda: pages.PlaceholderPage(placeholder_name="Guthabenkonto"), + build=pages.AccountPage, guard=logged_in_guard ), Page( diff --git a/src/ez_lan_manager/pages/Account.py b/src/ez_lan_manager/pages/Account.py new file mode 100644 index 0000000..5f3adbf --- /dev/null +++ b/src/ez_lan_manager/pages/Account.py @@ -0,0 +1,158 @@ +from rio import Column, Component, event, Text, TextStyle, Button, Color, Spacer, Revealer, Row + +from src.ez_lan_manager import ConfigurationService, UserService, AccountingService +from src.ez_lan_manager.components.MainViewContentBox import MainViewContentBox +from src.ez_lan_manager.pages import BasePage +from src.ez_lan_manager.types.SessionStorage import SessionStorage + + +class AccountPage(Component): + @event.on_populate + async def on_populate(self) -> None: + await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Guthabenkonto") + + async def _on_banking_info_press(self): + self.banking_info_revealer.is_open = not self.banking_info_revealer.is_open + + def build(self) -> Component: + user = self.session[UserService].get_user(self.session[SessionStorage].user_id) + a_s = self.session[AccountingService] + self.banking_info_revealer = Revealer( + header=None, + content=Column( + Text( + "Bankverbindung:", + style=TextStyle( + fill=self.session.theme.background_color + ), + margin=0, + margin_top=0, + margin_bottom=1, + align_x=0.5 + ), + Text( + "Kontoinhaber: Einfach Zocken Gaming Gesellschaft\n" + "IBAN: DE47 5176 2434 0019 8566 07\n" + "BLZ: 51762434\n" + "BIC: GENODE51BIK\n\n" + "Verwendungszweck:", + style=TextStyle( + fill=self.session.theme.background_color, + font_size=0.78 + ), + margin=0, + margin_bottom=1, + align_x=0.2 + ), + Text( + f"AUFLADUNG - {user.user_id} - {user.user_name}", + style=TextStyle( + fill=self.session.theme.neutral_color + ), + margin=0, + margin_bottom=1, + align_x=0.5 + ) + ), + margin = 2, + margin_top = 0, + margin_bottom = 1, + grow_x=True + ) + + transaction_history = Column( + Text( + "Transaktionshistorie", + style=TextStyle( + fill=self.session.theme.background_color, + font_size=1.2 + ), + margin_top=1, + margin_bottom=1, + align_x=0.5 + ) + ) + + for transaction in sorted(self.session[AccountingService].get_transaction_history(user.user_id), key=lambda t: t.transaction_date, reverse=True): + transaction_history.add( + Row( + Text( + f"{transaction.reference} ({transaction.transaction_date.strftime('%d.%m - %H:%M')})", + style=TextStyle( + fill=self.session.theme.danger_color if transaction.is_debit else self.session.theme.success_color, + font_size=0.8 + ), + margin=0, + margin_top=0, + margin_left=0.5, + margin_bottom=0.4, + align_x=0 + ), + Text( + f"{'-' if transaction.is_debit else '+'}{a_s.make_euro_string_from_int(transaction.value)}", + style=TextStyle( + fill=self.session.theme.danger_color if transaction.is_debit else self.session.theme.success_color, + font_size=0.8 + ), + margin=0, + margin_top=0, + margin_right=0.5, + margin_bottom=0.4, + align_x=1 + ) + ) + ) + return BasePage( + content=Column( + MainViewContentBox( + content=Text( + f"Kontostand: {a_s.make_euro_string_from_int(a_s.get_balance(user.user_id))}", + style=TextStyle( + fill=self.session.theme.background_color, + font_size=1.2 + ), + margin=2, + align_x=0.5 + ) + ), + MainViewContentBox( + content=Column( + Text( + "LAN-Konto aufladen", + style=TextStyle( + fill=self.session.theme.background_color, + font_size=1.2 + ), + margin=2, + align_x=0.5 + ), + Button( + content=Text("BANKÜBERWEISUNG", style=TextStyle(fill=Color.from_hex("121212"), font_size=0.8), justify="center"), + shape="rectangle", + style="major", + color="secondary", + grow_x=True, + margin=2, + margin_top=0, + margin_bottom=1, + on_press=self._on_banking_info_press + ), + self.banking_info_revealer, + Button( + content=Text("PAYPAL", style=TextStyle(fill=Color.from_hex("121212"), font_size=0.8), justify="center"), + shape="rectangle", + style="major", + color="secondary", + grow_x=True, + margin=2, + margin_top=0, + is_sensitive=False + ) + ) + ), + MainViewContentBox( + content=transaction_history + ), + align_y=0, + ) + ) diff --git a/src/ez_lan_manager/pages/__init__.py b/src/ez_lan_manager/pages/__init__.py index 599b20e..f4a41d1 100644 --- a/src/ez_lan_manager/pages/__init__.py +++ b/src/ez_lan_manager/pages/__init__.py @@ -2,3 +2,4 @@ from .BasePage import BasePage from .NewsPage import NewsPage from .PlaceholderPage import PlaceholderPage from .Logout import LogoutPage +from.Account import AccountPage diff --git a/src/ez_lan_manager/services/AccountingService.py b/src/ez_lan_manager/services/AccountingService.py index 2190319..e3bec1e 100644 --- a/src/ez_lan_manager/services/AccountingService.py +++ b/src/ez_lan_manager/services/AccountingService.py @@ -47,6 +47,9 @@ class AccountingService: balance_buffer += transaction.value return balance_buffer + def get_transaction_history(self, user_id: int) -> list[Transaction]: + return self._db_service.get_all_transactions_for_user(user_id) + @staticmethod def make_euro_string_from_int(cent_int: int) -> str: """ Internally, all money values are cents as ints. Only when showing them to the user we generate a string. Prevents float inaccuracy. """ diff --git a/src/ez_lan_manager/services/DatabaseService.py b/src/ez_lan_manager/services/DatabaseService.py index 5ca0ca6..9c70795 100644 --- a/src/ez_lan_manager/services/DatabaseService.py +++ b/src/ez_lan_manager/services/DatabaseService.py @@ -63,6 +63,7 @@ class DatabaseService: def get_user_by_name(self, user_name: str) -> Optional[User]: cursor = self._get_cursor() cursor.execute("SELECT * FROM users WHERE user_name=?", (user_name,)) + self._connection.commit() result = cursor.fetchone() if not result: return @@ -71,6 +72,7 @@ class DatabaseService: def get_user_by_id(self, user_id: int) -> Optional[User]: cursor = self._get_cursor() cursor.execute("SELECT * FROM users WHERE user_id=?", (user_id,)) + self._connection.commit() result = cursor.fetchone() if not result: return @@ -79,6 +81,7 @@ class DatabaseService: def get_user_by_mail(self, user_mail: str) -> Optional[User]: cursor = self._get_cursor() cursor.execute("SELECT * FROM users WHERE user_mail=?", (user_mail.lower(),)) + self._connection.commit() result = cursor.fetchone() if not result: return @@ -135,6 +138,7 @@ class DatabaseService: cursor = self._get_cursor() try: cursor.execute("SELECT * FROM transactions WHERE user_id=?", (user_id,)) + self._connection.commit() result = cursor.fetchall() except mariadb.Error as e: logger.error(f"Error getting all transactions for user: {e}") @@ -167,6 +171,7 @@ class DatabaseService: cursor = self._get_cursor() try: cursor.execute("SELECT * FROM news INNER JOIN users ON news.news_author = users.user_id WHERE news_date BETWEEN ? AND ?;", (dt_start, dt_end)) + self._connection.commit() except Exception as e: logger.warning(f"Error fetching news: {e}") return [] @@ -189,6 +194,7 @@ class DatabaseService: cursor = self._get_cursor() try: cursor.execute("SELECT * FROM tickets INNER JOIN users ON tickets.user = users.user_id;", ()) + self._connection.commit() except Exception as e: logger.warning(f"Error fetching tickets: {e}") return [] @@ -208,6 +214,7 @@ class DatabaseService: cursor = self._get_cursor() try: cursor.execute("SELECT * FROM tickets INNER JOIN users ON tickets.user = users.user_id WHERE user_id=?;", (user_id, )) + self._connection.commit() except Exception as e: logger.warning(f"Error fetching ticket for user: {e}") return @@ -273,6 +280,7 @@ class DatabaseService: cursor = self._get_cursor() try: cursor.execute("SELECT seats.*, users.* FROM seats LEFT JOIN users ON seats.user = users.user_id;") + self._connection.commit() except Exception as e: logger.warning(f"Error getting seats table: {e}") return results @@ -303,6 +311,7 @@ class DatabaseService: cursor = self._get_cursor() try: cursor.execute("SELECT * FROM catering_menu_items;") + self._connection.commit() except Exception as e: logger.warning(f"Error fetching menu items: {e}") return results @@ -323,6 +332,7 @@ class DatabaseService: cursor = self._get_cursor() try: cursor.execute("SELECT * FROM catering_menu_items WHERE catering_menu_item_id = ?;", (menu_item_id, )) + self._connection.commit() except Exception as e: logger.warning(f"Error fetching menu items: {e}") return @@ -439,6 +449,7 @@ class DatabaseService: cursor = self._get_cursor() try: cursor.execute(query) + self._connection.commit() except Exception as e: logger.warning(f"Error getting orders: {e}") return fetched_orders @@ -467,6 +478,7 @@ class DatabaseService: "WHERE order_id = ?;", (order_id, ) ) + self._connection.commit() except Exception as e: logger.warning(f"Error getting order items: {e}") return result @@ -498,6 +510,7 @@ class DatabaseService: cursor = self._get_cursor() try: cursor.execute("SELECT (picture) FROM user_profile_picture WHERE user_id = ?", (user_id, )) + self._connection.commit() r = cursor.fetchone() if r is None: return