Fix Decimal precision issue
This commit is contained in:
parent
0ca06c244c
commit
43ce42052e
@ -1,4 +1,5 @@
|
|||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
import rio
|
import rio
|
||||||
from rio import Component, Row, Text, IconButton, TextStyle
|
from rio import Component, Row, Text, IconButton, TextStyle
|
||||||
@ -9,7 +10,7 @@ MAX_LEN = 24
|
|||||||
|
|
||||||
class CateringCartItem(Component):
|
class CateringCartItem(Component):
|
||||||
article_name: str
|
article_name: str
|
||||||
article_price: int
|
article_price: Decimal
|
||||||
article_id: int
|
article_id: int
|
||||||
list_id: int
|
list_id: int
|
||||||
remove_item_cb: Callable
|
remove_item_cb: Callable
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
from decimal import Decimal
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
|
||||||
import rio
|
import rio
|
||||||
@ -7,9 +8,10 @@ from src.ez_lan_manager import AccountingService
|
|||||||
|
|
||||||
MAX_LEN = 24
|
MAX_LEN = 24
|
||||||
|
|
||||||
|
|
||||||
class CateringSelectionItem(Component):
|
class CateringSelectionItem(Component):
|
||||||
article_name: str
|
article_name: str
|
||||||
article_price: int
|
article_price: Decimal
|
||||||
article_id: int
|
article_id: int
|
||||||
on_add_callback: Callable
|
on_add_callback: Callable
|
||||||
is_sensitive: bool
|
is_sensitive: bool
|
||||||
@ -33,15 +35,16 @@ class CateringSelectionItem(Component):
|
|||||||
|
|
||||||
return top.strip(), bottom.strip()
|
return top.strip(), bottom.strip()
|
||||||
|
|
||||||
|
|
||||||
def build(self) -> rio.Component:
|
def build(self) -> rio.Component:
|
||||||
article_name_top, article_name_bottom = self.split_article_name(self.article_name)
|
article_name_top, article_name_bottom = self.split_article_name(self.article_name)
|
||||||
|
|
||||||
return Card(
|
return Card(
|
||||||
content=Column(
|
content=Column(
|
||||||
Row(
|
Row(
|
||||||
Text(article_name_top, align_x=0, overflow="wrap", min_width=19, style=TextStyle(fill=self.session.theme.background_color, font_size=0.9)),
|
Text(article_name_top, align_x=0, overflow="wrap", min_width=19,
|
||||||
Text(AccountingService.make_euro_string_from_decimal(self.article_price), style=TextStyle(fill=self.session.theme.background_color, font_size=0.9)),
|
style=TextStyle(fill=self.session.theme.background_color, font_size=0.9)),
|
||||||
|
Text(AccountingService.make_euro_string_from_decimal(self.article_price),
|
||||||
|
style=TextStyle(fill=self.session.theme.background_color, font_size=0.9)),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon="material/add",
|
icon="material/add",
|
||||||
min_size=2,
|
min_size=2,
|
||||||
@ -53,7 +56,10 @@ class CateringSelectionItem(Component):
|
|||||||
proportions=(19, 5, 2),
|
proportions=(19, 5, 2),
|
||||||
margin_bottom=0
|
margin_bottom=0
|
||||||
),
|
),
|
||||||
Spacer() if not article_name_bottom else Text(article_name_bottom, align_x=0, overflow="wrap", min_width=19, style=TextStyle(fill=self.session.theme.background_color, font_size=0.9)),
|
Spacer() if not article_name_bottom else Text(article_name_bottom, align_x=0, overflow="wrap",
|
||||||
|
min_width=19,
|
||||||
|
style=TextStyle(fill=self.session.theme.background_color,
|
||||||
|
font_size=0.9)),
|
||||||
Row(
|
Row(
|
||||||
Text(
|
Text(
|
||||||
self.additional_info,
|
self.additional_info,
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
from decimal import Decimal
|
||||||
from typing import Optional, Callable
|
from typing import Optional, Callable
|
||||||
|
|
||||||
from rio import Component, Column, Text, TextStyle, Button, Spacer
|
from rio import Component, Column, Text, TextStyle, Button, Spacer
|
||||||
@ -9,23 +10,30 @@ class SeatingPlanInfoBox(Component):
|
|||||||
is_booking_blocked: bool
|
is_booking_blocked: bool
|
||||||
seat_id: Optional[str] = None
|
seat_id: Optional[str] = None
|
||||||
seat_occupant: Optional[str] = None
|
seat_occupant: Optional[str] = None
|
||||||
seat_price: int = 0
|
seat_price: Decimal = Decimal("0")
|
||||||
is_blocked: bool = False
|
is_blocked: bool = False
|
||||||
|
|
||||||
|
|
||||||
def build(self) -> Component:
|
def build(self) -> Component:
|
||||||
if not self.show:
|
if not self.show:
|
||||||
return Spacer()
|
return Spacer()
|
||||||
if self.is_blocked:
|
if self.is_blocked:
|
||||||
return Column(Text(f"Sitzplatz gesperrt", margin=1, style=TextStyle(fill=self.session.theme.neutral_color, font_size=1.4), overflow="wrap", justify="center"), min_height=10)
|
return Column(Text(f"Sitzplatz gesperrt", margin=1,
|
||||||
|
style=TextStyle(fill=self.session.theme.neutral_color, font_size=1.4), overflow="wrap",
|
||||||
|
justify="center"), min_height=10)
|
||||||
if self.seat_id is None and self.seat_occupant is None:
|
if self.seat_id is None and self.seat_occupant is None:
|
||||||
return Column(Text(f"Sitzplatz auswählen...", margin=1, style=TextStyle(fill=self.session.theme.neutral_color), overflow="wrap", justify="center"), min_height=10)
|
|
||||||
return Column(
|
return Column(
|
||||||
Text(f"Dieser Sitzplatz ({self.seat_id}) ist gebucht von:", margin=1, style=TextStyle(fill=self.session.theme.neutral_color), overflow="wrap", justify="center"),
|
Text(f"Sitzplatz auswählen...", margin=1, style=TextStyle(fill=self.session.theme.neutral_color),
|
||||||
Text(f"{self.seat_occupant}", margin_bottom=1, style=TextStyle(fill=self.session.theme.neutral_color, font_size=1.4), overflow="wrap", justify="center"),
|
overflow="wrap", justify="center"), min_height=10)
|
||||||
|
return Column(
|
||||||
|
Text(f"Dieser Sitzplatz ({self.seat_id}) ist gebucht von:", margin=1,
|
||||||
|
style=TextStyle(fill=self.session.theme.neutral_color), overflow="wrap", justify="center"),
|
||||||
|
Text(f"{self.seat_occupant}", margin_bottom=1,
|
||||||
|
style=TextStyle(fill=self.session.theme.neutral_color, font_size=1.4), overflow="wrap",
|
||||||
|
justify="center"),
|
||||||
min_height=10
|
min_height=10
|
||||||
) if self.seat_id and self.seat_occupant else Column(
|
) if self.seat_id and self.seat_occupant else Column(
|
||||||
Text(f"Dieser Sitzplatz ({self.seat_id}) ist frei", margin=1, style=TextStyle(fill=self.session.theme.neutral_color), overflow="wrap", justify="center"),
|
Text(f"Dieser Sitzplatz ({self.seat_id}) ist frei", margin=1,
|
||||||
|
style=TextStyle(fill=self.session.theme.neutral_color), overflow="wrap", justify="center"),
|
||||||
Button(
|
Button(
|
||||||
Text(
|
Text(
|
||||||
f"Buchen",
|
f"Buchen",
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
from asyncio import sleep, create_task
|
from asyncio import sleep, create_task
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
import rio
|
import rio
|
||||||
from rio import Component, Column, Text, TextStyle, Button, Row, ScrollContainer, Spacer, Popup, Table
|
from rio import Component, Column, Text, TextStyle, Button, Row, ScrollContainer, Spacer, Popup, Table
|
||||||
@ -158,7 +159,7 @@ class ShoppingCartAndOrders(Component):
|
|||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
Text(
|
Text(
|
||||||
text=f"Preis: {AccountingService.make_euro_string_from_decimal(sum(cart_item.price for cart_item in cart))}",
|
text=f"Preis: {AccountingService.make_euro_string_from_decimal(sum((cart_item.price for cart_item in cart), Decimal(0)))}",
|
||||||
style=TextStyle(
|
style=TextStyle(
|
||||||
fill=self.session.theme.background_color,
|
fill=self.session.theme.background_color,
|
||||||
font_size=0.8
|
font_size=0.8
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
from functools import partial
|
from functools import partial
|
||||||
from typing import Callable, Optional
|
from typing import Callable, Optional
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
import rio
|
import rio
|
||||||
from rio import Component, Card, Column, Text, Row, Button, TextStyle, ProgressBar, event, Spacer
|
from rio import Component, Card, Column, Text, Row, Button, TextStyle, ProgressBar, event, Spacer
|
||||||
@ -12,7 +13,7 @@ from src.ez_lan_manager.types.Ticket import Ticket
|
|||||||
class TicketBuyCard(Component):
|
class TicketBuyCard(Component):
|
||||||
description: str
|
description: str
|
||||||
additional_info: str
|
additional_info: str
|
||||||
price: int
|
price: Decimal
|
||||||
category: str
|
category: str
|
||||||
pressed_cb: Callable
|
pressed_cb: Callable
|
||||||
is_enabled: bool
|
is_enabled: bool
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
from random import choice
|
from random import choice
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
from rio import Component, TextStyle, Color, Button, Text, Rectangle, Column, Row, Spacer, Link, event, EventHandler
|
from rio import Component, TextStyle, Color, Button, Text, Rectangle, Column, Row, Spacer, Link, event, EventHandler
|
||||||
|
|
||||||
@ -38,11 +39,12 @@ class StatusButton(Component):
|
|||||||
grow_y=False
|
grow_y=False
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class UserInfoBox(Component):
|
class UserInfoBox(Component):
|
||||||
status_change_cb: EventHandler = None
|
status_change_cb: EventHandler = None
|
||||||
TEXT_STYLE = TextStyle(fill=Color.from_hex("02dac5"), font_size=0.9)
|
TEXT_STYLE = TextStyle(fill=Color.from_hex("02dac5"), font_size=0.9)
|
||||||
user: Optional[User] = None
|
user: Optional[User] = None
|
||||||
user_balance: Optional[int] = 0
|
user_balance: Optional[Decimal] = Decimal("0")
|
||||||
user_ticket: Optional[Ticket] = None
|
user_ticket: Optional[Ticket] = None
|
||||||
user_seat: Optional[Seat] = None
|
user_seat: Optional[Seat] = None
|
||||||
|
|
||||||
@ -80,8 +82,10 @@ class UserInfoBox(Component):
|
|||||||
return Spacer()
|
return Spacer()
|
||||||
return Rectangle(
|
return Rectangle(
|
||||||
content=Column(
|
content=Column(
|
||||||
Text(f"{self.get_greeting()},", style=TextStyle(fill=Color.from_hex("02dac5"), font_size=0.9), justify="center"),
|
Text(f"{self.get_greeting()},", style=TextStyle(fill=Color.from_hex("02dac5"), font_size=0.9),
|
||||||
Text(f"{self.user.user_name}", style=TextStyle(fill=Color.from_hex("02dac5"), font_size=1.2), justify="center"),
|
justify="center"),
|
||||||
|
Text(f"{self.user.user_name}", style=TextStyle(fill=Color.from_hex("02dac5"), font_size=1.2),
|
||||||
|
justify="center"),
|
||||||
Row(
|
Row(
|
||||||
StatusButton(label="TICKET", target_url="./buy_ticket",
|
StatusButton(label="TICKET", target_url="./buy_ticket",
|
||||||
enabled=self.user_ticket is not None),
|
enabled=self.user_ticket is not None),
|
||||||
@ -91,7 +95,9 @@ class UserInfoBox(Component):
|
|||||||
grow_y=False
|
grow_y=False
|
||||||
),
|
),
|
||||||
UserInfoBoxButton("Profil bearbeiten", "./edit-profile"),
|
UserInfoBoxButton("Profil bearbeiten", "./edit-profile"),
|
||||||
UserInfoBoxButton(f"Guthaben: {self.session[AccountingService].make_euro_string_from_decimal(self.user_balance)}", "./account"),
|
UserInfoBoxButton(
|
||||||
|
f"Guthaben: {self.session[AccountingService].make_euro_string_from_decimal(self.user_balance)}",
|
||||||
|
"./account"),
|
||||||
Button(
|
Button(
|
||||||
content=Text("Ausloggen", style=TextStyle(fill=Color.from_hex("02dac5"), font_size=0.6)),
|
content=Text("Ausloggen", style=TextStyle(fill=Color.from_hex("02dac5"), font_size=0.6)),
|
||||||
shape="rectangle",
|
shape="rectangle",
|
||||||
|
|||||||
@ -49,7 +49,6 @@ async def run() -> None:
|
|||||||
DEMO_USERS[2]["password_clear_text"])
|
DEMO_USERS[2]["password_clear_text"])
|
||||||
await accounting_service.add_balance(jason.user_id, Decimal("1000.00"), "DEMO EINZAHLUNG")
|
await accounting_service.add_balance(jason.user_id, Decimal("1000.00"), "DEMO EINZAHLUNG")
|
||||||
await ticket_service.purchase_ticket(jason.user_id, "NORMAL")
|
await ticket_service.purchase_ticket(jason.user_id, "NORMAL")
|
||||||
await seating_service.seat_user(jason.user_id, "D10")
|
|
||||||
|
|
||||||
# LISA
|
# LISA
|
||||||
lisa = await user_service.create_user(DEMO_USERS[3]["user_name"], DEMO_USERS[3]["user_mail"],
|
lisa = await user_service.create_user(DEMO_USERS[3]["user_name"], DEMO_USERS[3]["user_mail"],
|
||||||
@ -68,110 +67,110 @@ async def run() -> None:
|
|||||||
|
|
||||||
if not input("Generate catering menu? (Y/n): ").lower() == "n":
|
if not input("Generate catering menu? (Y/n): ").lower() == "n":
|
||||||
# MAIN_COURSE
|
# MAIN_COURSE
|
||||||
await catering_service.add_menu_item("Schnitzel Wiener Art", "mit Pommes", 1050,
|
await catering_service.add_menu_item("Schnitzel Wiener Art", "mit Pommes", Decimal("10.00"),
|
||||||
CateringMenuItemCategory.MAIN_COURSE)
|
CateringMenuItemCategory.MAIN_COURSE)
|
||||||
await catering_service.add_menu_item("Jäger Schnitzel mit Champignonrahm Sauce", "mit Pommes", 1150,
|
await catering_service.add_menu_item("Jäger Schnitzel mit Champignonrahm Sauce", "mit Pommes", Decimal("11.50"),
|
||||||
CateringMenuItemCategory.MAIN_COURSE)
|
CateringMenuItemCategory.MAIN_COURSE)
|
||||||
await catering_service.add_menu_item("Tortellini in Käsesauce mit Fleischfüllung", "", 1050,
|
await catering_service.add_menu_item("Tortellini in Käsesauce mit Fleischfüllung", "", Decimal("10.50"),
|
||||||
CateringMenuItemCategory.MAIN_COURSE)
|
CateringMenuItemCategory.MAIN_COURSE)
|
||||||
await catering_service.add_menu_item("Tortellini in Käsesauce ohne Fleischfüllung", "Vegetarisch", 1050,
|
await catering_service.add_menu_item("Tortellini in Käsesauce ohne Fleischfüllung", "Vegetarisch", Decimal("10.50"),
|
||||||
CateringMenuItemCategory.MAIN_COURSE)
|
CateringMenuItemCategory.MAIN_COURSE)
|
||||||
|
|
||||||
# SNACK
|
# SNACK
|
||||||
await catering_service.add_menu_item("Käse Schinken Wrap", "", 500, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Käse Schinken Wrap", "", Decimal("5.00"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Puten Paprika Wrap", "", 700, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Puten Paprika Wrap", "", Decimal("7.00"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Tomate Mozzarella Wrap", "", 600, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Tomate Mozzarella Wrap", "", Decimal("6.00"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Portion Pommes", "", 400, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Portion Pommes", "", Decimal("4.00"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Rinds-Currywurst", "", 450, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Rinds-Currywurst", "", Decimal("4.50"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Rinds-Currywurst mit Pommes", "", 650, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Rinds-Currywurst mit Pommes", "", Decimal("6.50"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Nudelsalat", "", 450, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Nudelsalat", "", Decimal("4.50"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Nudelsalat mit Bockwurst", "", 600, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Nudelsalat mit Bockwurst", "", Decimal("6.00"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Kartoffelsalat", "", 450, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Kartoffelsalat", "", Decimal("4.50"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Kartoffelsalat mit Bockwurst", "", 600, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Kartoffelsalat mit Bockwurst", "", Decimal("6.00"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Sandwichtoast - Schinken", "", 180, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Sandwichtoast - Schinken", "", Decimal("1.80"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Sandwichtoast - Käse", "", 180, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Sandwichtoast - Käse", "", Decimal("1.80"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Sandwichtoast - Schinken/Käse", "", 210, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Sandwichtoast - Schinken/Käse", "", Decimal("2.10"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Sandwichtoast - Salami", "", 180, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Sandwichtoast - Salami", "", Decimal("1.80"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Sandwichtoast - Salami/Käse", "", 210, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Sandwichtoast - Salami/Käse", "", Decimal("2.10"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Chips - Western Style", "", 130, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Chips - Western Style", "", Decimal("1.30"), CateringMenuItemCategory.SNACK)
|
||||||
await catering_service.add_menu_item("Nachos - Salted", "", 130, CateringMenuItemCategory.SNACK)
|
await catering_service.add_menu_item("Nachos - Salted", "", Decimal("1.30"), CateringMenuItemCategory.SNACK)
|
||||||
|
|
||||||
# DESSERT
|
# DESSERT
|
||||||
await catering_service.add_menu_item("Panna Cotta mit Erdbeersauce", "", 700, CateringMenuItemCategory.DESSERT)
|
await catering_service.add_menu_item("Panna Cotta mit Erdbeersauce", "", Decimal("7.00"), CateringMenuItemCategory.DESSERT)
|
||||||
await catering_service.add_menu_item("Panna Cotta mit Blaubeersauce", "", 700, CateringMenuItemCategory.DESSERT)
|
await catering_service.add_menu_item("Panna Cotta mit Blaubeersauce", "", Decimal("7.00"), CateringMenuItemCategory.DESSERT)
|
||||||
await catering_service.add_menu_item("Mousse au Chocolat", "", 700, CateringMenuItemCategory.DESSERT)
|
await catering_service.add_menu_item("Mousse au Chocolat", "", Decimal("7.00"), CateringMenuItemCategory.DESSERT)
|
||||||
|
|
||||||
# BREAKFAST
|
# BREAKFAST
|
||||||
await catering_service.add_menu_item("Fruit Loops", "", 150, CateringMenuItemCategory.BREAKFAST)
|
await catering_service.add_menu_item("Fruit Loops", "", Decimal("1.50"), CateringMenuItemCategory.BREAKFAST)
|
||||||
await catering_service.add_menu_item("Smacks", "", 150, CateringMenuItemCategory.BREAKFAST)
|
await catering_service.add_menu_item("Smacks", "", Decimal("1.50"), CateringMenuItemCategory.BREAKFAST)
|
||||||
await catering_service.add_menu_item("Knuspermüsli", "Schoko", 200, CateringMenuItemCategory.BREAKFAST)
|
await catering_service.add_menu_item("Knuspermüsli", "Schoko", Decimal("2.00"), CateringMenuItemCategory.BREAKFAST)
|
||||||
await catering_service.add_menu_item("Cini Minis", "", 150, CateringMenuItemCategory.BREAKFAST)
|
await catering_service.add_menu_item("Cini Minis", "", Decimal("2.50"), CateringMenuItemCategory.BREAKFAST)
|
||||||
await catering_service.add_menu_item("Brötchen - Schinken", "mit Margarine", 120,
|
await catering_service.add_menu_item("Brötchen - Schinken", "mit Margarine", Decimal("1.20"),
|
||||||
CateringMenuItemCategory.BREAKFAST)
|
CateringMenuItemCategory.BREAKFAST)
|
||||||
await catering_service.add_menu_item("Brötchen - Käse", "mit Margarine", 120,
|
await catering_service.add_menu_item("Brötchen - Käse", "mit Margarine", Decimal("1.20"),
|
||||||
CateringMenuItemCategory.BREAKFAST)
|
CateringMenuItemCategory.BREAKFAST)
|
||||||
await catering_service.add_menu_item("Brötchen - Schinken/Käse", "mit Margarine", 140,
|
await catering_service.add_menu_item("Brötchen - Schinken/Käse", "mit Margarine", Decimal("1.40"),
|
||||||
CateringMenuItemCategory.BREAKFAST)
|
CateringMenuItemCategory.BREAKFAST)
|
||||||
await catering_service.add_menu_item("Brötchen - Salami", "mit Margarine", 120,
|
await catering_service.add_menu_item("Brötchen - Salami", "mit Margarine", Decimal("1.20"),
|
||||||
CateringMenuItemCategory.BREAKFAST)
|
CateringMenuItemCategory.BREAKFAST)
|
||||||
await catering_service.add_menu_item("Brötchen - Salami/Käse", "mit Margarine", 140,
|
await catering_service.add_menu_item("Brötchen - Salami/Käse", "mit Margarine", Decimal("1.40"),
|
||||||
CateringMenuItemCategory.BREAKFAST)
|
CateringMenuItemCategory.BREAKFAST)
|
||||||
await catering_service.add_menu_item("Brötchen - Nutella", "mit Margarine", 120,
|
await catering_service.add_menu_item("Brötchen - Nutella", "mit Margarine", Decimal("1.20"),
|
||||||
CateringMenuItemCategory.BREAKFAST)
|
CateringMenuItemCategory.BREAKFAST)
|
||||||
|
|
||||||
# BEVERAGE_NON_ALCOHOLIC
|
# BEVERAGE_NON_ALCOHOLIC
|
||||||
await catering_service.add_menu_item("Wasser - Still", "1L Flasche", 200,
|
await catering_service.add_menu_item("Wasser - Still", "1L Flasche", Decimal("2.00"),
|
||||||
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
||||||
await catering_service.add_menu_item("Wasser - Medium", "1L Flasche", 200,
|
await catering_service.add_menu_item("Wasser - Medium", "1L Flasche", Decimal("2.00"),
|
||||||
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
||||||
await catering_service.add_menu_item("Wasser - Spritzig", "1L Flasche", 200,
|
await catering_service.add_menu_item("Wasser - Spritzig", "1L Flasche", Decimal("2.00"),
|
||||||
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
||||||
await catering_service.add_menu_item("Coca-Cola", "1L Flasche", 200,
|
await catering_service.add_menu_item("Coca-Cola", "1L Flasche", Decimal("2.00"),
|
||||||
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
||||||
await catering_service.add_menu_item("Coca-Cola Zero", "1L Flasche", 200,
|
await catering_service.add_menu_item("Coca-Cola Zero", "1L Flasche", Decimal("2.00"),
|
||||||
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
||||||
await catering_service.add_menu_item("Fanta", "1L Flasche", 200,
|
await catering_service.add_menu_item("Fanta", "1L Flasche", Decimal("2.00"),
|
||||||
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
||||||
await catering_service.add_menu_item("Sprite", "1L Flasche", 200,
|
await catering_service.add_menu_item("Sprite", "1L Flasche", Decimal("2.00"),
|
||||||
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
||||||
await catering_service.add_menu_item("Spezi", "von Paulaner, 0,5L Flasche", 150,
|
await catering_service.add_menu_item("Spezi", "von Paulaner, 0,5L Flasche", Decimal("1.50"),
|
||||||
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
||||||
await catering_service.add_menu_item("Red Bull", "", 200, CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
await catering_service.add_menu_item("Red Bull", "", Decimal("2.00"), CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
||||||
await catering_service.add_menu_item("Energy", "Hausmarke", 150,
|
await catering_service.add_menu_item("Energy", "Hausmarke", Decimal("1.50"),
|
||||||
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
CateringMenuItemCategory.BEVERAGE_NON_ALCOHOLIC)
|
||||||
|
|
||||||
# BEVERAGE_ALCOHOLIC
|
# BEVERAGE_ALCOHOLIC
|
||||||
await catering_service.add_menu_item("Pils", "0,33L Flasche", 190, CateringMenuItemCategory.BEVERAGE_ALCOHOLIC)
|
await catering_service.add_menu_item("Pils", "0,33L Flasche", Decimal("1.90"), CateringMenuItemCategory.BEVERAGE_ALCOHOLIC)
|
||||||
await catering_service.add_menu_item("Radler", "0,33L Flasche", 190,
|
await catering_service.add_menu_item("Radler", "0,33L Flasche", Decimal("1.90"),
|
||||||
CateringMenuItemCategory.BEVERAGE_ALCOHOLIC)
|
CateringMenuItemCategory.BEVERAGE_ALCOHOLIC)
|
||||||
await catering_service.add_menu_item("Diesel", "0,33L Flasche", 190,
|
await catering_service.add_menu_item("Diesel", "0,33L Flasche", Decimal("1.90"),
|
||||||
CateringMenuItemCategory.BEVERAGE_ALCOHOLIC)
|
CateringMenuItemCategory.BEVERAGE_ALCOHOLIC)
|
||||||
await catering_service.add_menu_item("Apfelwein Pur", "0,33L Flasche", 190,
|
await catering_service.add_menu_item("Apfelwein Pur", "0,33L Flasche", Decimal("1.90"),
|
||||||
CateringMenuItemCategory.BEVERAGE_ALCOHOLIC)
|
CateringMenuItemCategory.BEVERAGE_ALCOHOLIC)
|
||||||
await catering_service.add_menu_item("Apfelwein Sauer", "0,33L Flasche", 190,
|
await catering_service.add_menu_item("Apfelwein Sauer", "0,33L Flasche", Decimal("1.90"),
|
||||||
CateringMenuItemCategory.BEVERAGE_ALCOHOLIC)
|
CateringMenuItemCategory.BEVERAGE_ALCOHOLIC)
|
||||||
await catering_service.add_menu_item("Apfelwein Cola", "0,33L Flasche", 190,
|
await catering_service.add_menu_item("Apfelwein Cola", "0,33L Flasche", Decimal("1.90"),
|
||||||
CateringMenuItemCategory.BEVERAGE_ALCOHOLIC)
|
CateringMenuItemCategory.BEVERAGE_ALCOHOLIC)
|
||||||
|
|
||||||
# BEVERAGE_COCKTAIL
|
# BEVERAGE_COCKTAIL
|
||||||
await catering_service.add_menu_item("Vodka Energy", "", 400, CateringMenuItemCategory.BEVERAGE_COCKTAIL)
|
await catering_service.add_menu_item("Vodka Energy", "", Decimal("4.00"), CateringMenuItemCategory.BEVERAGE_COCKTAIL)
|
||||||
await catering_service.add_menu_item("Vodka O-Saft", "", 400, CateringMenuItemCategory.BEVERAGE_COCKTAIL)
|
await catering_service.add_menu_item("Vodka O-Saft", "", Decimal("4.00"), CateringMenuItemCategory.BEVERAGE_COCKTAIL)
|
||||||
await catering_service.add_menu_item("Whiskey Cola", "mit Bourbon", 400,
|
await catering_service.add_menu_item("Whiskey Cola", "mit Bourbon", Decimal("4.00"),
|
||||||
CateringMenuItemCategory.BEVERAGE_COCKTAIL)
|
CateringMenuItemCategory.BEVERAGE_COCKTAIL)
|
||||||
await catering_service.add_menu_item("Jägermeister Energy", "", 400, CateringMenuItemCategory.BEVERAGE_COCKTAIL)
|
await catering_service.add_menu_item("Jägermeister Energy", "", Decimal("4.00"), CateringMenuItemCategory.BEVERAGE_COCKTAIL)
|
||||||
await catering_service.add_menu_item("Sex on the Beach", "", 550, CateringMenuItemCategory.BEVERAGE_COCKTAIL)
|
await catering_service.add_menu_item("Sex on the Beach", "", Decimal("5.50"), CateringMenuItemCategory.BEVERAGE_COCKTAIL)
|
||||||
await catering_service.add_menu_item("Long Island Ice Tea", "", 550, CateringMenuItemCategory.BEVERAGE_COCKTAIL)
|
await catering_service.add_menu_item("Long Island Ice Tea", "", Decimal("5.50"), CateringMenuItemCategory.BEVERAGE_COCKTAIL)
|
||||||
await catering_service.add_menu_item("Caipirinha", "", 550, CateringMenuItemCategory.BEVERAGE_COCKTAIL)
|
await catering_service.add_menu_item("Caipirinha", "", Decimal("5.50"), CateringMenuItemCategory.BEVERAGE_COCKTAIL)
|
||||||
|
|
||||||
# BEVERAGE_SHOT
|
# BEVERAGE_SHOT
|
||||||
await catering_service.add_menu_item("Jägermeister", "", 200, CateringMenuItemCategory.BEVERAGE_SHOT)
|
await catering_service.add_menu_item("Jägermeister", "", Decimal("2.00"), CateringMenuItemCategory.BEVERAGE_SHOT)
|
||||||
await catering_service.add_menu_item("Tequila", "", 200, CateringMenuItemCategory.BEVERAGE_SHOT)
|
await catering_service.add_menu_item("Tequila", "", Decimal("2.00"), CateringMenuItemCategory.BEVERAGE_SHOT)
|
||||||
await catering_service.add_menu_item("PfEZzi", "Getunter Pfefferminz-Schnaps", 199,
|
await catering_service.add_menu_item("PfEZzi", "Getunter Pfefferminz-Schnaps", Decimal("1.99"),
|
||||||
CateringMenuItemCategory.BEVERAGE_SHOT)
|
CateringMenuItemCategory.BEVERAGE_SHOT)
|
||||||
|
|
||||||
# NON_FOOD
|
# NON_FOOD
|
||||||
await catering_service.add_menu_item("Zigaretten", "Elixyr", 800, CateringMenuItemCategory.NON_FOOD)
|
await catering_service.add_menu_item("Zigaretten", "Elixyr", Decimal("8.00"), CateringMenuItemCategory.NON_FOOD)
|
||||||
await catering_service.add_menu_item("Mentholfilter", "passend für Elixyr", 120,
|
await catering_service.add_menu_item("Mentholfilter", "passend für Elixyr", Decimal("1.20"),
|
||||||
CateringMenuItemCategory.NON_FOOD)
|
CateringMenuItemCategory.NON_FOOD)
|
||||||
|
|
||||||
if not input("Generate default new post? (Y/n): ").lower() == "n":
|
if not input("Generate default new post? (Y/n): ").lower() == "n":
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import logging
|
import logging
|
||||||
from asyncio import sleep
|
from asyncio import sleep
|
||||||
|
from decimal import Decimal
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
from rio import Text, Column, TextStyle, Component, event, PressEvent, ProgressCircle
|
from rio import Text, Column, TextStyle, Component, event, PressEvent, ProgressCircle
|
||||||
@ -21,7 +22,7 @@ class SeatingPlanPage(Component):
|
|||||||
seating_info: Optional[list[Seat]] = None
|
seating_info: Optional[list[Seat]] = None
|
||||||
current_seat_id: Optional[str] = None
|
current_seat_id: Optional[str] = None
|
||||||
current_seat_occupant: Optional[str] = None
|
current_seat_occupant: Optional[str] = None
|
||||||
current_seat_price: int = 0
|
current_seat_price: Decimal = Decimal("0")
|
||||||
current_seat_is_blocked: bool = False
|
current_seat_is_blocked: bool = False
|
||||||
user: Optional[User] = None
|
user: Optional[User] = None
|
||||||
show_info_box: bool = True
|
show_info_box: bool = True
|
||||||
@ -54,7 +55,7 @@ class SeatingPlanPage(Component):
|
|||||||
self.current_seat_is_blocked = seat.is_blocked
|
self.current_seat_is_blocked = seat.is_blocked
|
||||||
self.current_seat_id = seat.seat_id
|
self.current_seat_id = seat.seat_id
|
||||||
ticket_info = self.session[TicketingService].get_ticket_info_by_category(seat.category)
|
ticket_info = self.session[TicketingService].get_ticket_info_by_category(seat.category)
|
||||||
price = 0 if not ticket_info else ticket_info.price
|
price = Decimal("0") if not ticket_info else ticket_info.price
|
||||||
self.current_seat_price = price
|
self.current_seat_price = price
|
||||||
if seat.user:
|
if seat.user:
|
||||||
self.current_seat_occupant = seat.user.user_name
|
self.current_seat_occupant = seat.user.user_name
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
|
from decimal import Decimal
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
@ -10,11 +11,13 @@ from src.ez_lan_manager.types.CateringMenuItem import CateringMenuItem, Catering
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__.split(".")[-1])
|
logger = logging.getLogger(__name__.split(".")[-1])
|
||||||
|
|
||||||
|
|
||||||
class CateringErrorType(Enum):
|
class CateringErrorType(Enum):
|
||||||
INCLUDES_DISABLED_ITEM = 0
|
INCLUDES_DISABLED_ITEM = 0
|
||||||
INSUFFICIENT_FUNDS = 1
|
INSUFFICIENT_FUNDS = 1
|
||||||
GENERIC = 99
|
GENERIC = 99
|
||||||
|
|
||||||
|
|
||||||
class CateringError(Exception):
|
class CateringError(Exception):
|
||||||
def __init__(self, message: str, error_type: CateringErrorType = CateringErrorType.GENERIC) -> None:
|
def __init__(self, message: str, error_type: CateringErrorType = CateringErrorType.GENERIC) -> None:
|
||||||
self.message = message
|
self.message = message
|
||||||
@ -30,7 +33,8 @@ class CateringService:
|
|||||||
|
|
||||||
# ORDERS
|
# ORDERS
|
||||||
|
|
||||||
async def place_order(self, menu_items: CateringMenuItemsWithAmount, user_id: int, is_delivery: bool = True) -> CateringOrder:
|
async def place_order(self, menu_items: CateringMenuItemsWithAmount, user_id: int,
|
||||||
|
is_delivery: bool = True) -> CateringOrder:
|
||||||
for menu_item in menu_items:
|
for menu_item in menu_items:
|
||||||
if menu_item.is_disabled:
|
if menu_item.is_disabled:
|
||||||
raise CateringError("Order includes disabled items", CateringErrorType.INCLUDES_DISABLED_ITEM)
|
raise CateringError("Order includes disabled items", CateringErrorType.INCLUDES_DISABLED_ITEM)
|
||||||
@ -39,14 +43,15 @@ class CateringService:
|
|||||||
if not user:
|
if not user:
|
||||||
raise CateringError("User does not exist")
|
raise CateringError("User does not exist")
|
||||||
|
|
||||||
total_price = sum([item.price * quantity for item, quantity in menu_items.items()])
|
total_price = sum([item.price * quantity for item, quantity in menu_items.items()], Decimal(0))
|
||||||
if await self._accounting_service.get_balance(user_id) < total_price:
|
if await self._accounting_service.get_balance(user_id) < total_price:
|
||||||
raise CateringError("Insufficient funds", CateringErrorType.INSUFFICIENT_FUNDS)
|
raise CateringError("Insufficient funds", CateringErrorType.INSUFFICIENT_FUNDS)
|
||||||
|
|
||||||
order = await self._db_service.add_new_order(menu_items, user_id, is_delivery)
|
order = await self._db_service.add_new_order(menu_items, user_id, is_delivery)
|
||||||
if order:
|
if order:
|
||||||
await self._accounting_service.remove_balance(user_id, total_price, f"CATERING - {order.order_id}")
|
await self._accounting_service.remove_balance(user_id, total_price, f"CATERING - {order.order_id}")
|
||||||
logger.info(f"User '{order.customer.user_name}' (ID:{order.customer.user_id}) ordered from catering for {self._accounting_service.make_euro_string_from_decimal(total_price)}")
|
logger.info(
|
||||||
|
f"User '{order.customer.user_name}' (ID:{order.customer.user_id}) ordered from catering for {self._accounting_service.make_euro_string_from_decimal(total_price)}")
|
||||||
# await self.cancel_order(order) # ToDo: Check if commented out before commit. Un-comment to auto-cancel every placed order
|
# await self.cancel_order(order) # ToDo: Check if commented out before commit. Un-comment to auto-cancel every placed order
|
||||||
return order
|
return order
|
||||||
|
|
||||||
@ -68,7 +73,8 @@ class CateringService:
|
|||||||
async def cancel_order(self, order: CateringOrder) -> bool:
|
async def cancel_order(self, order: CateringOrder) -> bool:
|
||||||
change_result = await self._db_service.change_order_status(order.order_id, CateringOrderStatus.CANCELED)
|
change_result = await self._db_service.change_order_status(order.order_id, CateringOrderStatus.CANCELED)
|
||||||
if change_result:
|
if change_result:
|
||||||
await self._accounting_service.add_balance(order.customer.user_id, order.price, f"CATERING REFUND - {order.order_id}")
|
await self._accounting_service.add_balance(order.customer.user_id, order.price,
|
||||||
|
f"CATERING REFUND - {order.order_id}")
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -86,7 +92,8 @@ class CateringService:
|
|||||||
raise CateringError("Menu item not found")
|
raise CateringError("Menu item not found")
|
||||||
return item
|
return item
|
||||||
|
|
||||||
async def add_menu_item(self, name: str, info: str, price: int, category: CateringMenuItemCategory, is_disabled: bool = False) -> CateringMenuItem:
|
async def add_menu_item(self, name: str, info: str, price: Decimal, category: CateringMenuItemCategory,
|
||||||
|
is_disabled: bool = False) -> CateringMenuItem:
|
||||||
if new_item := await self._db_service.add_menu_item(name, info, price, category, is_disabled):
|
if new_item := await self._db_service.add_menu_item(name, info, price, category, is_disabled):
|
||||||
return new_item
|
return new_item
|
||||||
raise CateringError(f"Could not add item '{name}' to the menu.")
|
raise CateringError(f"Could not add item '{name}' to the menu.")
|
||||||
@ -134,3 +141,4 @@ class CateringService:
|
|||||||
return self.cached_cart[user_id]
|
return self.cached_cart[user_id]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|||||||
@ -520,7 +520,7 @@ class DatabaseService:
|
|||||||
is_disabled=bool(raw_data[5])
|
is_disabled=bool(raw_data[5])
|
||||||
)
|
)
|
||||||
|
|
||||||
async def add_menu_item(self, name: str, info: str, price: int, category: CateringMenuItemCategory,
|
async def add_menu_item(self, name: str, info: str, price: Decimal, category: CateringMenuItemCategory,
|
||||||
is_disabled: bool = False) -> Optional[CateringMenuItem]:
|
is_disabled: bool = False) -> Optional[CateringMenuItem]:
|
||||||
async with self._connection_pool.acquire() as conn:
|
async with self._connection_pool.acquire() as conn:
|
||||||
async with conn.cursor(aiomysql.Cursor) as cursor:
|
async with conn.cursor(aiomysql.Cursor) as cursor:
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from decimal import Decimal
|
||||||
from enum import StrEnum
|
from enum import StrEnum
|
||||||
from typing import Self
|
from typing import Self
|
||||||
|
|
||||||
@ -19,7 +20,7 @@ class CateringMenuItemCategory(StrEnum):
|
|||||||
class CateringMenuItem:
|
class CateringMenuItem:
|
||||||
item_id: int
|
item_id: int
|
||||||
name: str
|
name: str
|
||||||
price: int
|
price: Decimal
|
||||||
category: CateringMenuItemCategory
|
category: CateringMenuItemCategory
|
||||||
additional_info: str = str()
|
additional_info: str = str()
|
||||||
is_disabled: bool = False
|
is_disabled: bool = False
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
from decimal import Decimal
|
||||||
from enum import StrEnum
|
from enum import StrEnum
|
||||||
from typing import Optional, Iterable, Self
|
from typing import Optional, Iterable, Self
|
||||||
|
|
||||||
@ -27,10 +28,10 @@ class CateringOrder:
|
|||||||
is_delivery: bool = True
|
is_delivery: bool = True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def price(self) -> int:
|
def price(self) -> Decimal:
|
||||||
total = 0
|
total = Decimal("0")
|
||||||
for item, amount in self.items.items():
|
for item, amount in self.items.items():
|
||||||
total += (item.price * amount)
|
total += (item.price * Decimal(amount))
|
||||||
return total
|
return total
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user