Add Catering Management (#4)
Co-authored-by: David Rodenkirchen <davidr.develop@gmail.com> Reviewed-on: Vereins-IT/ez-lan-manager#4
This commit was merged in pull request #4.
This commit is contained in:
@@ -25,6 +25,6 @@ class CateringCartItem(Component):
|
||||
return Row(
|
||||
Text(self.ellipsize_string(self.article_name), align_x=0, overflow="wrap", min_width=19, style=TextStyle(fill=self.session.theme.background_color, font_size=0.9)),
|
||||
Text(AccountingService.make_euro_string_from_int(self.article_price), style=TextStyle(fill=self.session.theme.background_color, font_size=0.9)),
|
||||
IconButton(icon="material/close", size=2, color=self.session.theme.danger_color, style="plain-text", on_press=lambda: self.remove_item_cb(self.list_id)),
|
||||
IconButton(icon="material/close", min_size=2, color=self.session.theme.danger_color, style="plain-text", on_press=lambda: self.remove_item_cb(self.list_id)),
|
||||
proportions=(19, 5, 2)
|
||||
)
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
from functools import partial
|
||||
from typing import Optional, Callable
|
||||
|
||||
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)
|
||||
|
||||
color = self.session.theme.warning_color
|
||||
if status == CateringOrderStatus.DELAYED or status == CateringOrderStatus.CANCELED:
|
||||
color = self.session.theme.danger_color
|
||||
elif status == CateringOrderStatus.COMPLETED:
|
||||
color = self.session.theme.success_color
|
||||
|
||||
return Text(text=status_text, style=TextStyle(fill=color))
|
||||
|
||||
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
|
||||
),
|
||||
on_press=partial(self.clicked_cb, self.order)
|
||||
)
|
||||
@@ -65,8 +65,9 @@ class ShoppingCartAndOrders(Component):
|
||||
|
||||
user_id = self.session[SessionStorage].user_id
|
||||
cart = self.session[CateringService].get_cart(user_id)
|
||||
show_popup_task = None
|
||||
if len(cart) < 1:
|
||||
_ = create_task(self.show_popup("Warenkorb leer", True))
|
||||
show_popup_task = create_task(self.show_popup("Warenkorb leer", True))
|
||||
else:
|
||||
items_with_amounts: CateringMenuItemsWithAmount = {}
|
||||
for item in cart:
|
||||
@@ -78,14 +79,15 @@ class ShoppingCartAndOrders(Component):
|
||||
await self.session[CateringService].place_order(items_with_amounts, user_id)
|
||||
except CateringError as catering_error:
|
||||
if catering_error.error_type == CateringErrorType.INCLUDES_DISABLED_ITEM:
|
||||
_ = create_task(self.show_popup("Warenkorb enthält gesperrte Artikel", True))
|
||||
show_popup_task = create_task(self.show_popup("Warenkorb enthält gesperrte Artikel", True))
|
||||
elif catering_error.error_type == CateringErrorType.INSUFFICIENT_FUNDS:
|
||||
_ = create_task(self.show_popup("Guthaben nicht ausreichend", True))
|
||||
show_popup_task = create_task(self.show_popup("Guthaben nicht ausreichend", True))
|
||||
else:
|
||||
_ = create_task(self.show_popup("Unbekannter Fehler", True))
|
||||
show_popup_task = create_task(self.show_popup("Unbekannter Fehler", True))
|
||||
self.session[CateringService].save_cart(self.session[SessionStorage].user_id, [])
|
||||
self.order_button_loading = False
|
||||
_ = create_task(self.show_popup("Bestellung erfolgreich aufgegeben!", False))
|
||||
if not show_popup_task:
|
||||
show_popup_task = create_task(self.show_popup("Bestellung erfolgreich aufgegeben!", False))
|
||||
|
||||
async def _create_order_info_modal(self, order: CateringOrder) -> None:
|
||||
def build_dialog_content() -> rio.Component:
|
||||
|
||||
@@ -65,6 +65,8 @@ class UserInfoBox(Component):
|
||||
self.session[AccountingService].add_update_hook(self.update)
|
||||
|
||||
async def update(self) -> None:
|
||||
if not self.user:
|
||||
self.user = await self.session[UserService].get_user(self.session[SessionStorage].user_id)
|
||||
self.user_balance = await self.session[AccountingService].get_balance(self.user.user_id)
|
||||
self.user_ticket = await self.session[TicketingService].get_user_ticket(self.user.user_id)
|
||||
self.user_seat = await self.session[SeatingService].get_user_seat(self.user.user_id)
|
||||
|
||||
Reference in New Issue
Block a user