import logging from dataclasses import field, dataclass from datetime import datetime from typing import Optional from rio import Column, Component, event, TextStyle, Text, Spacer, PointerEvent, Button from src.ez_lan_manager import ConfigurationService, CateringService, SeatingService from src.ez_lan_manager.components.CateringManagementOrderDisplay import CateringManagementOrderDisplay from src.ez_lan_manager.components.MainViewContentBox import MainViewContentBox from src.ez_lan_manager.types.CateringOrder import CateringOrder, CateringOrderStatus from src.ez_lan_manager.types.Seat import Seat logger = logging.getLogger(__name__.split(".")[-1]) @dataclass class CateringOrderWithSeat: catering_order: CateringOrder seat: Optional[Seat] class ManageCateringPage(Component): all_orders: list[CateringOrderWithSeat] = field(default_factory=list) last_updated: Optional[datetime] = None @event.on_populate async def on_populate(self) -> None: await self.session.set_title(f"{self.session[ConfigurationService].get_lan_info().name} - Catering Verwaltung") self.all_orders = await self.populate_seating(await self.session[CateringService].get_orders()) self.last_updated = datetime.now() @event.periodic(30) async def update_orders(self) -> None: polled_orders = await self.session[CateringService].get_orders() self.all_orders = await self.populate_seating(polled_orders) self.last_updated = datetime.now() async def populate_seating(self, orders: list[CateringOrder]) -> list[CateringOrderWithSeat]: result = [] for order in orders: seat = await self.session[SeatingService].get_user_seat(order.customer.user_id) result.append(CateringOrderWithSeat(catering_order=order, seat=seat)) return result def get_all_pending_orders(self) -> list[CateringOrderWithSeat]: filtered_list = list(filter(lambda o: o.catering_order.status != CateringOrderStatus.COMPLETED and o.catering_order.status != CateringOrderStatus.CANCELED, self.all_orders)) sorted_list = sorted(filtered_list, key=lambda o: o.catering_order.order_date) return sorted_list def get_all_completed_orders(self) -> list[CateringOrderWithSeat]: filtered_list = list(filter(lambda o: o.catering_order.status == CateringOrderStatus.COMPLETED or o.catering_order.status == CateringOrderStatus.CANCELED, self.all_orders)) sorted_list = sorted(filtered_list, key=lambda o: o.catering_order.order_date) return sorted_list async def order_clicked(self, order: CateringOrder, _: PointerEvent) -> None: pass def build(self) -> Component: return Column( MainViewContentBox( Column( Text( text="Catering Verwaltung", style=TextStyle( fill=self.session.theme.background_color, font_size=1.2 ), margin_top=2, margin_bottom=2, align_x=0.5 ) ) ), MainViewContentBox( Column( Text( text="Offene Bestellungen", style=TextStyle( fill=self.session.theme.background_color, font_size=1.2 ), margin_top=2, margin_bottom=0.2, align_x=0.5 ), Text( text=f"Letzte Aktualisierung: {'-' if not self.last_updated else self.last_updated.strftime('%H:%M:%S')}", style=TextStyle( fill=self.session.theme.background_color, font_size=0.7 ), margin_top=0.2, margin_bottom=0.2, align_x=0.5 ), Button( content=Text("Jetzt aktualisieren", style=TextStyle(font_size=0.7), justify="center"), shape="rectangle", margin_bottom=1, on_press=self.update_orders ), *[CateringManagementOrderDisplay(v.catering_order, v.seat, self.order_clicked) for v in self.get_all_pending_orders()], ) ), MainViewContentBox( Column( Text( text="Abgeschlossene Bestellungen", style=TextStyle( fill=self.session.theme.background_color, font_size=1.2 ), margin_top=2, margin_bottom=0.2, align_x=0.5 ), *[CateringManagementOrderDisplay(v.catering_order, v.seat, self.order_clicked) for v in self.get_all_completed_orders()], ) ), Spacer() )