refactor catering, add orders view
This commit is contained in:
@@ -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)
|
||||
Reference in New Issue
Block a user