refactor catering, add orders view

This commit is contained in:
David Rodenkirchen
2024-08-28 14:20:41 +02:00
parent b00a819325
commit 90a344e460
10 changed files with 472 additions and 120 deletions
@@ -0,0 +1,40 @@
from datetime import datetime
from typing import Callable
import rio
from rio import Component, Row, Text, IconButton, TextStyle, Color
from src.ez_lan_manager import AccountingService
from src.ez_lan_manager.types.CateringOrder import CateringOrderStatus
MAX_LEN = 24
class CateringOrderItem(Component):
order_id: int
order_datetime: datetime
order_status: CateringOrderStatus
def get_display_text_and_color_for_order_status(self, order_status: CateringOrderStatus) -> tuple[str, Color]:
match order_status:
case CateringOrderStatus.RECEIVED:
return "In Bearbeitung", self.session.theme.success_color
case CateringOrderStatus.DELAYED:
return "Verspätet", Color.from_hex("eed202")
case CateringOrderStatus.READY_FOR_PICKUP:
return "Abholbereit", self.session.theme.success_color
case CateringOrderStatus.EN_ROUTE:
return "Unterwegs", self.session.theme.success_color
case CateringOrderStatus.COMPLETED:
return "Abgeschlossen", self.session.theme.success_color
case CateringOrderStatus.CANCELED:
return "Storniert", self.session.theme.danger_color
case _:
return "Unbekannt(wtf?)", self.session.theme.danger_color
def build(self) -> rio.Component:
order_status, color = self.get_display_text_and_color_for_order_status(self.order_status)
return Row(
Text(f"ID: {str(self.order_id):0>6}", align_x=0, wrap=True, min_width=10, style=TextStyle(fill=self.session.theme.background_color, font_size=0.9), margin_right=1),
Text(order_status, wrap=True, min_width=10, style=TextStyle(fill=color, font_size=0.9), margin_right=1),
Text(self.order_datetime.strftime("%d.%m. %H:%M"), style=TextStyle(fill=self.session.theme.background_color, font_size=0.9), align_x=1)
)
@@ -0,0 +1,70 @@
from typing import Callable
import rio
from rio import Component, Row, Text, IconButton, TextStyle, Column, Spacer, Card, Color
from src.ez_lan_manager import AccountingService
MAX_LEN = 24
class CateringSelectionItem(Component):
article_name: str
article_price: int
article_id: int
on_add_callback: Callable
is_sensitive: bool
additional_info: str
is_grey: bool
@staticmethod
def split_article_name(article_name: str) -> tuple[str, str]:
if len(article_name) <= MAX_LEN:
return article_name, ""
top, bottom = "", ""
words = article_name.split(" ")
last_word_added = ""
while len(top) <= MAX_LEN:
w = words.pop(0)
top += f" {w}"
last_word_added = w
top = top.replace(last_word_added, "")
bottom = f"{last_word_added} " + " ".join(words)
return top.strip(), bottom.strip()
def build(self) -> rio.Component:
article_name_top, article_name_bottom = self.split_article_name(self.article_name)
return Card(
content=Column(
Row(
Text(article_name_top, align_x=0, wrap=True, 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/add",
size=2,
color=self.session.theme.success_color,
style="plain",
on_press=lambda: self.on_add_callback(self.article_id),
is_sensitive=self.is_sensitive
),
proportions=(19, 5, 2),
margin_bottom=0
),
Spacer() if not article_name_bottom else Text(article_name_bottom, align_x=0, wrap=True, min_width=19, style=TextStyle(fill=self.session.theme.background_color, font_size=0.9)),
Row(
Text(
self.additional_info,
align_x=0,
wrap=True,
min_width=19,
style=TextStyle(fill=self.session.theme.background_color, font_size=0.6)
),
margin_top=0
),
margin_bottom=0.5,
),
color=Color.from_hex("d3d3d3") if self.is_grey else self.session.theme.primary_color
)
@@ -16,7 +16,7 @@ class MainViewContentBox(Component):
fill=self.session.theme.primary_color,
margin_left=1,
margin_right=1,
margin_top=2,
margin_top=1,
margin_bottom=1,
shadow_radius=0.5,
shadow_color=self.session.theme.hud_color,
@@ -0,0 +1,116 @@
import rio
from rio import Component, Column, Text, TextStyle, Button, Row, ScrollContainer, Spacer
from src.ez_lan_manager.components.CateringCartItem import CateringCartItem
from src.ez_lan_manager.components.CateringOrderItem import CateringOrderItem
from src.ez_lan_manager.services.AccountingService import AccountingService
from src.ez_lan_manager.services.CateringService import CateringService
from src.ez_lan_manager.types.CateringOrder import CateringOrder
from src.ez_lan_manager.types.SessionStorage import SessionStorage
class ShoppingCartAndOrders(Component):
show_cart: bool = True
async def switch(self) -> None:
self.show_cart = not self.show_cart
async def on_remove_item(self, list_id: int) -> None:
catering_service = self.session[CateringService]
user_id = self.session[SessionStorage].user_id
cart = catering_service.get_cart(user_id)
try:
cart.pop(list_id)
except IndexError:
return
catering_service.save_cart(user_id, cart)
await self.force_refresh()
async def on_empty_cart_pressed(self) -> None:
self.session[CateringService].save_cart(self.session[SessionStorage].user_id, [])
await self.force_refresh()
async def on_add_item(self, article_id: int) -> None:
catering_service = self.session[CateringService]
user_id = self.session[SessionStorage].user_id
if not user_id:
return
cart = catering_service.get_cart(user_id)
cart.append(catering_service.get_menu_item_by_id(article_id))
catering_service.save_cart(user_id, cart)
await self.force_refresh()
def build(self) -> rio.Component:
user_id = self.session[SessionStorage].user_id
catering_service = self.session[CateringService]
if self.show_cart:
cart = catering_service.get_cart(user_id)
cart_container = ScrollContainer(
content=Column(
*[CateringCartItem(
article_name=cart_item.name,
article_price=cart_item.price,
article_id=cart_item.item_id,
remove_item_cb=self.on_remove_item,
list_id=idx
) for idx, cart_item in enumerate(cart)],
Spacer(grow_y=True)
),
min_height=8,
min_width=33,
margin=1
)
return Column(
cart_container,
Row(
Text(
text=f"Preis: {AccountingService.make_euro_string_from_int(sum(cart_item.price for cart_item in cart))}",
style=TextStyle(
fill=self.session.theme.background_color,
font_size=0.8
),
margin=1
),
Button(
content=Text(
"Warenkorb leeren",
style=TextStyle(fill=self.session.theme.danger_color, font_size=0.9),
align_x=0.2
),
margin=1,
margin_left=0,
shape="rectangle",
style="major",
color="primary",
on_press=self.on_empty_cart_pressed
),
Button(
content=Text(
"Bestellen",
style=TextStyle(fill=self.session.theme.success_color, font_size=0.9),
align_x=0.2
),
margin=1,
margin_left=0,
shape="rectangle",
style="major",
color="primary"
)
)
)
else:
orders = catering_service.get_orders_for_user(user_id)
orders_container = ScrollContainer(
content=Column(
*[CateringOrderItem(
order_id=order_item.order_id,
order_datetime=order_item.order_date,
order_status=order_item.status,
) for order_item in orders],
Spacer(grow_y=True)
),
min_height=8,
min_width=33,
margin=1
)
return Column(orders_container)