from typing import Optional from rio import Text, Column, TextStyle, Component, event, Button, Popup from src.ez_lan_manager import ConfigurationService, UserService, TicketingService from src.ez_lan_manager.components.MainViewContentBox import MainViewContentBox from src.ez_lan_manager.components.TicketBuyCard import TicketBuyCard from src.ez_lan_manager.services.AccountingService import InsufficientFundsError from src.ez_lan_manager.services.TicketingService import TicketNotAvailableError, UserAlreadyHasTicketError from src.ez_lan_manager.types.SessionStorage import SessionStorage from src.ez_lan_manager.types.Ticket import Ticket from src.ez_lan_manager.types.User import User class BuyTicketPage(Component): user: Optional[User] = None user_ticket: Optional[Ticket] = None is_popup_open: bool = False popup_message: str = "" is_popup_success: bool = False is_buying_enabled: bool = False @event.on_populate async def on_populate(self) -> None: await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Ticket kaufen") self.user = await self.session[UserService].get_user(self.session[SessionStorage].user_id) if self.user is None: # No user logged in self.is_buying_enabled = False else: # User is logged in possible_ticket = await self.session[TicketingService].get_user_ticket(self.user.user_id) self.user_ticket = possible_ticket if possible_ticket is not None: # User already has a ticket self.is_buying_enabled = False else: self.is_buying_enabled = True async def on_buy_pressed(self, category: str) -> None: if not self.user: return self.is_buying_enabled = False self.force_refresh() try: t_s = self.session[TicketingService] ticket = await t_s.purchase_ticket(self.user.user_id, category) self.popup_message = f"Ticket erfolgreich gekauft. Deine Ticket-ID lautet: {ticket.ticket_id}." self.is_popup_success = True except TicketNotAvailableError: self.popup_message = "Das ausgewählte Ticket ist nicht verfügbar." self.is_popup_success = False except InsufficientFundsError: self.popup_message = "Dein Guthaben reicht nicht aus um dieses Ticket zu kaufen." self.is_popup_success = False except UserAlreadyHasTicketError: self.popup_message = (f"Du besitzt bereits ein Ticket. Um dein aktuelles Ticket zu stornieren, kontaktiere bitte den Support unter " f"{self.session[ConfigurationService].get_lan_info().organizer_mail}.") self.is_popup_success = False except RuntimeError: self.popup_message = "Ein unbekannter Fehler ist aufgetreten." self.is_popup_success = False self.is_popup_open = True await self.on_populate() async def on_popup_close_pressed(self) -> None: self.is_popup_open = False self.popup_message = "" def build(self) -> Component: ticket_infos = self.session[ConfigurationService].get_ticket_info() header = Text( "Tickets & Preise", style=TextStyle( fill=self.session.theme.background_color, font_size=1.2 ), margin_top=2, margin_bottom=2, align_x=0.5 ) return Column( MainViewContentBox( Column( header, Popup( anchor=header, content=Column( Text( self.popup_message, style=TextStyle(font_size=1.1, fill=self.session.theme.success_color if self.is_popup_success else self.session.theme.danger_color), overflow="wrap", grow_y=True, margin=1 ), Button("Bestätigen", shape="rounded", grow_y=False, on_press=self.on_popup_close_pressed), min_width=34, min_height=10 ), is_open=self.is_popup_open, position="bottom", margin=1, corner_radius=0.2, color=self.session.theme.primary_color ), *[TicketBuyCard( description=t.description, additional_info=t.additional_info, price=t.price, category=t.category, pressed_cb=self.on_buy_pressed, is_enabled=self.is_buying_enabled, total_tickets=t.total_tickets, user_ticket=self.user_ticket ) for t in ticket_infos] ), ), align_y=0 )