From e0f7105fea5d1d279604aba4366618933170be02 Mon Sep 17 00:00:00 2001 From: David Rodenkirchen Date: Sat, 1 Feb 2025 15:07:47 +0100 Subject: [PATCH] add status control elements --- src/EzLanManager.py | 2 +- .../CateringManagementOrderDisplay.py | 99 ++++++++++++++----- .../pages/ManageCateringPage.py | 35 ++++++- src/ez_lan_manager/pages/RulesPage.py | 2 +- src/ez_lan_manager/types/CateringOrder.py | 1 + 5 files changed, 111 insertions(+), 28 deletions(-) diff --git a/src/EzLanManager.py b/src/EzLanManager.py index 5c3383f..5d5de67 100644 --- a/src/EzLanManager.py +++ b/src/EzLanManager.py @@ -171,7 +171,7 @@ if __name__ == "__main__": "robots": "INDEX,FOLLOW", "description": f"Info und Verwaltungs-Seite der LAN Party '{lan_info.name} - {lan_info.iteration}'.", "og:description": f"Info und Verwaltungs-Seite der LAN Party '{lan_info.name} - {lan_info.iteration}'.", - "keywords": "Gaming, Clan, Guild, Verein, Club, Einfach, Zocken, Genuss, Gesellschaft, Videospiele, " + "keywords": "Gaming, Clan, Guild, Verein, Club, Einfach, Zocken, Gesellschaft, Videospiele, " "Videogames, LAN, Party, EZ, LAN, Manager", "author": "David Rodenkirchen", "publisher": "EZ GG e.V.", diff --git a/src/ez_lan_manager/components/CateringManagementOrderDisplay.py b/src/ez_lan_manager/components/CateringManagementOrderDisplay.py index 162d128..91356f2 100644 --- a/src/ez_lan_manager/components/CateringManagementOrderDisplay.py +++ b/src/ez_lan_manager/components/CateringManagementOrderDisplay.py @@ -1,14 +1,29 @@ -from typing import Optional +from functools import partial +from typing import Optional, Callable -from rio import Component, Row, Card, Column, Text, TextStyle, Spacer +from rio import Component, Row, Card, Column, Text, TextStyle, Spacer, PointerEventListener, Button +from src.ez_lan_manager.services.CateringService import CateringService from src.ez_lan_manager.types.CateringOrder import CateringOrder, CateringOrderStatus from src.ez_lan_manager.types.Seat import Seat +class CateringManagementOrderDisplayStatusButton(Component): + status: CateringOrderStatus + clicked_cb: Callable + def build(self) -> Component: + return Button( + content=Text( + CateringOrder.translate_order_status(self.status) + ), + shape="rectangle", + on_press=partial(self.clicked_cb, self.status) + ) + class CateringManagementOrderDisplay(Component): order: CateringOrder seat: Optional[Seat] + clicked_cb: Callable def format_order_status(self, status: CateringOrderStatus) -> Text: status_text = CateringOrder.translate_order_status(status) @@ -21,27 +36,65 @@ class CateringManagementOrderDisplay(Component): return Text(text=status_text, style=TextStyle(fill=color)) - def build(self) -> Component: - return Card( - content=Column( - Row( - Text(f"Status: ", margin_left=0.3, margin_top=0.2), - self.format_order_status(self.order.status), - Spacer(), - Text(self.order.order_date.strftime("%d.%m. - %H:%M Uhr"), margin_right=0.3), - ), - Row( - Text(f"Gast: {self.order.customer.user_name}", margin_left=0.3), - Spacer(), - Text(f"Sitzplatz: {'-' if not self.seat else self.seat.seat_id}", margin_right=0.3), - ), - Row( - Text("Diese Bestellung wird:", margin_left=0.3), - Spacer(), - Text("Geliefert" if self.order.is_delivery else "Abgeholt", margin_right=0.3, margin_bottom=0.2), + async def status_button_clicked(self, new_status: CateringOrderStatus) -> None: + if self.order.status == CateringOrderStatus.CANCELED: + return + + if new_status == CateringOrderStatus.CANCELED: + # ToDo: Hier sollten wir nochmal nachfragen ob der Bediener sich wirklich sicher ist, + # und anwarnen das eine stornierte Bestellung nicht ent-storniert werden kann. + pass + + if self.order.status != new_status: + if new_status == CateringOrderStatus.CANCELED: + success = await self.session[CateringService].cancel_order(self.order) + else: + success = await self.session[CateringService].update_order_status(self.order.order_id, new_status) + + if success: + self.order = CateringOrder( + order_id=self.order.order_id, + order_date=self.order.order_date, + status=new_status, + items=self.order.items, + customer=self.order.customer, + is_delivery=self.order.is_delivery ) + + def build(self) -> Component: + return PointerEventListener( + content=Card( + content=Column( + Row( + Text(f"Status: ", margin_left=0.3, margin_top=0.2), + self.format_order_status(self.order.status), + Spacer(), + Text(self.order.order_date.strftime("%d.%m. - %H:%M Uhr"), margin_right=0.3), + ), + Row( + Text(f"Gast: {self.order.customer.user_name}", margin_left=0.3), + Spacer(), + Text(f"Sitzplatz: {'-' if not self.seat else self.seat.seat_id}", margin_right=0.3), + ), + Row( + Text("Diese Bestellung wird:", margin_left=0.3, margin_bottom=0.5), + Spacer(), + Text("Geliefert" if self.order.is_delivery else "Abgeholt", margin_right=0.3, margin_bottom=0.5), + ), + Row( + CateringManagementOrderDisplayStatusButton(CateringOrderStatus.RECEIVED, self.status_button_clicked), + CateringManagementOrderDisplayStatusButton(CateringOrderStatus.CANCELED, self.status_button_clicked), + CateringManagementOrderDisplayStatusButton(CateringOrderStatus.EN_ROUTE, self.status_button_clicked) + ), + Row( + CateringManagementOrderDisplayStatusButton(CateringOrderStatus.READY_FOR_PICKUP, self.status_button_clicked), + CateringManagementOrderDisplayStatusButton(CateringOrderStatus.COMPLETED, self.status_button_clicked), + CateringManagementOrderDisplayStatusButton(CateringOrderStatus.DELAYED, self.status_button_clicked), + ) + ), + color=self.session.theme.hud_color, + colorize_on_hover=True, + margin=1 ), - color=self.session.theme.hud_color, - colorize_on_hover=True, - margin=1 + on_press=partial(self.clicked_cb, self.order) ) \ No newline at end of file diff --git a/src/ez_lan_manager/pages/ManageCateringPage.py b/src/ez_lan_manager/pages/ManageCateringPage.py index bef7c07..2983b88 100644 --- a/src/ez_lan_manager/pages/ManageCateringPage.py +++ b/src/ez_lan_manager/pages/ManageCateringPage.py @@ -3,7 +3,7 @@ from dataclasses import field, dataclass from datetime import datetime from typing import Optional -from rio import Column, Component, event, TextStyle, Text, Spacer +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 @@ -47,6 +47,14 @@ class ManageCateringPage(Component): 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( @@ -83,10 +91,31 @@ class ManageCateringPage(Component): font_size=0.7 ), margin_top=0.2, - margin_bottom=2, + margin_bottom=0.2, align_x=0.5 ), - *[CateringManagementOrderDisplay(v.catering_order, v.seat) for v in self.get_all_pending_orders()], + 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() diff --git a/src/ez_lan_manager/pages/RulesPage.py b/src/ez_lan_manager/pages/RulesPage.py index e699fb0..727214d 100644 --- a/src/ez_lan_manager/pages/RulesPage.py +++ b/src/ez_lan_manager/pages/RulesPage.py @@ -16,7 +16,7 @@ RULES: list[str] = [ AGB: dict[str, list[str]] = { "§1": [ - "Die Veranstaltung wird von der Einfach Zocken Genuss Gesellschaft e.V. organisiert.", + "Die Veranstaltung wird von der Einfach Zocken Gaming Gesellschaft e.V. organisiert.", "Unser Event verfolgt gemeinnützige Ziele und ist nicht auf Profit ausgerichtet. Die erhobenen Teilnahmebeiträge dienen lediglich der Kostendeckung. Überschüsse werden für die Organisation und Durchführung zukünftiger ähnlicher Veranstaltungen verwendet.", "Die Organisatoren haben das Recht, unerwünschte oder störende Personen jederzeit von der Veranstaltung auszuschließen (siehe §3). Im Falle eines Ausschlusses aufgrund eines Regelverstoßes erfolgt keine Rückerstattung des Eintrittspreises." ], diff --git a/src/ez_lan_manager/types/CateringOrder.py b/src/ez_lan_manager/types/CateringOrder.py index 5385c90..41221bc 100644 --- a/src/ez_lan_manager/types/CateringOrder.py +++ b/src/ez_lan_manager/types/CateringOrder.py @@ -1,6 +1,7 @@ from dataclasses import dataclass from datetime import datetime from enum import StrEnum +from typing import Optional, Iterable, Self from src.ez_lan_manager.types.CateringMenuItem import CateringMenuItem, CateringMenuItemCategory from src.ez_lan_manager.types.User import User