WIP: Catering Orders

This commit is contained in:
David Rodenkirchen 2024-08-21 23:44:39 +02:00
parent 21b2d59b82
commit cb0dad1916
6 changed files with 79 additions and 9 deletions

View File

@ -11,6 +11,7 @@ from src.ez_lan_manager.services.NewsService import NewsService
from src.ez_lan_manager.services.SeatingService import SeatingService from src.ez_lan_manager.services.SeatingService import SeatingService
from src.ez_lan_manager.services.TicketingService import TicketingService from src.ez_lan_manager.services.TicketingService import TicketingService
from src.ez_lan_manager.services.UserService import UserService from src.ez_lan_manager.services.UserService import UserService
from src.ez_lan_manager.types.CateringMenuItem import CateringMenuItemCategory, CateringMenuItem
logger = logging.getLogger(__name__.split(".")[-1]) logger = logging.getLogger(__name__.split(".")[-1])
@ -27,4 +28,13 @@ if __name__ == "__main__":
mailing_service = MailingService(configuration_service.get_mailing_service_configuration()) mailing_service = MailingService(configuration_service.get_mailing_service_configuration())
ticketing_service = TicketingService(lan_info, db_service, accounting_service) ticketing_service = TicketingService(lan_info, db_service, accounting_service)
seating_service = SeatingService(seating_config, lan_info, db_service, ticketing_service) seating_service = SeatingService(seating_config, lan_info, db_service, ticketing_service)
catering_service = CateringService(db_service, accounting_service) catering_service = CateringService(db_service, accounting_service, user_service)
#print(catering_service.get_menu())
# catering_service.place_order(
# {
# CateringMenuItem(item_id=5, name='Bier', price=250, category=CateringMenuItemCategory.BEVERAGE_ALCOHOLIC, additional_info="Pils", is_disabled=False): 12,
# CateringMenuItem(item_id=6, name='Pizza Hawaii', price=900, category=CateringMenuItemCategory.MAIN_COURSE, additional_info = '', is_disabled = False): 2
# },
# 19
# )

View File

@ -1,23 +1,47 @@
import logging
from typing import Optional from typing import Optional
from src.ez_lan_manager.services.AccountingService import AccountingService from src.ez_lan_manager.services.AccountingService import AccountingService
from src.ez_lan_manager.services.DatabaseService import DatabaseService from src.ez_lan_manager.services.DatabaseService import DatabaseService
from src.ez_lan_manager.types.CateringOrder import CateringOrder, CateringOrderStatus from src.ez_lan_manager.services.UserService import UserService
from src.ez_lan_manager.types.CateringOrder import CateringOrder, CateringOrderStatus, CateringMenuItemsWithAmount
from src.ez_lan_manager.types.CateringMenuItem import CateringMenuItem, CateringMenuItemCategory from src.ez_lan_manager.types.CateringMenuItem import CateringMenuItem, CateringMenuItemCategory
logger = logging.getLogger(__name__.split(".")[-1])
class CateringError(Exception): class CateringError(Exception):
def __init__(self, message: str) -> None: def __init__(self, message: str) -> None:
self.message = message self.message = message
class CateringService: class CateringService:
def __init__(self, db_service: DatabaseService, accounting_service: AccountingService): def __init__(self, db_service: DatabaseService, accounting_service: AccountingService, user_service: UserService):
self._db_service = db_service self._db_service = db_service
self._accounting_service = accounting_service self._accounting_service = accounting_service
self._user_service = user_service
# ORDERS # ORDERS
def place_order(self, menu_items: list[CateringMenuItem], user_id: int, is_delivery: bool = True) -> CateringOrder: def place_order(self, menu_items: CateringMenuItemsWithAmount, user_id: int, is_delivery: bool = True) -> CateringOrder:
for menu_item in menu_items:
if menu_item.is_disabled:
raise CateringError("Order includes disabled items")
user = self._user_service.get_user(user_id)
if not user:
raise CateringError("User does not exist")
total_price = sum([item.price * quantity for item, quantity in menu_items.items()])
if self._accounting_service.get_balance(user_id) < total_price:
raise CateringError("Insufficient funds")
order = self._db_service.add_new_order(menu_items, user_id, is_delivery)
if order:
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_int(total_price)}")
return order
def update_order_status(self, order_id: int, new_status: CateringOrderStatus) -> None:
pass pass
def get_orders(self) -> list[CateringOrder]: def get_orders(self) -> list[CateringOrder]:

View File

@ -1,12 +1,14 @@
import logging import logging
import sys import sys
from datetime import date from datetime import date, datetime
from typing import Optional from typing import Optional
import mariadb import mariadb
from mariadb import Cursor from mariadb import Cursor
from src.ez_lan_manager.types.CateringOrder import CateringOrder
from src.ez_lan_manager.types.CateringMenuItem import CateringMenuItem, CateringMenuItemCategory from src.ez_lan_manager.types.CateringMenuItem import CateringMenuItem, CateringMenuItemCategory
from src.ez_lan_manager.types.CateringOrder import CateringMenuItemsWithAmount, CateringOrderStatus
from src.ez_lan_manager.types.ConfigurationTypes import DatabaseConfiguration from src.ez_lan_manager.types.ConfigurationTypes import DatabaseConfiguration
from src.ez_lan_manager.types.News import News from src.ez_lan_manager.types.News import News
from src.ez_lan_manager.types.Seat import Seat from src.ez_lan_manager.types.Seat import Seat
@ -381,3 +383,30 @@ class DatabaseService:
logger.warning(f"Error updating menu item: {e}") logger.warning(f"Error updating menu item: {e}")
return False return False
return bool(affected_rows) return bool(affected_rows)
def add_new_order(self, menu_items: CateringMenuItemsWithAmount, user_id: int, is_delivery: bool) -> Optional[CateringOrder]:
now = datetime.now()
cursor = self._get_cursor()
try:
cursor.execute(
"INSERT INTO orders (status, user, is_delivery, order_date) VALUES (?, ?, ?, ?);",
(CateringOrderStatus.RECEIVED.value, user_id, is_delivery, now)
)
order_id = cursor.lastrowid
for menu_item, quantity in menu_items.items():
cursor.execute(
"INSERT INTO order_catering_menu_item (order_id, catering_menu_item_id, quantity) VALUES (?, ?, ?);",
(order_id, menu_item.item_id, quantity)
)
self._connection.commit()
return CateringOrder(
order_id=order_id,
order_date=now,
status=CateringOrderStatus.RECEIVED,
items=menu_items,
customer=self.get_user_by_id(user_id),
is_delivery=is_delivery
)
except Exception as e:
logger.warning(f"Error placing order: {e}")
return

View File

@ -16,7 +16,7 @@ class UserService:
def __init__(self, db_service: DatabaseService) -> None: def __init__(self, db_service: DatabaseService) -> None:
self._db_service = db_service self._db_service = db_service
def get_user(self, accessor: Union[str, int]) -> User: def get_user(self, accessor: Union[str, int]) -> Optional[User]:
if isinstance(accessor, int): if isinstance(accessor, int):
return self._db_service.get_user_by_id(accessor) return self._db_service.get_user_by_id(accessor)
if "@" in accessor: if "@" in accessor:

View File

@ -21,3 +21,6 @@ class CateringMenuItem:
category: CateringMenuItemCategory category: CateringMenuItemCategory
additional_info: str = str() additional_info: str = str()
is_disabled: bool = False is_disabled: bool = False
def __hash__(self) -> int:
return hash(str(self.item_id) + self.name)

View File

@ -1,9 +1,12 @@
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime
from enum import StrEnum from enum import StrEnum
from src.ez_lan_manager.types.CateringMenuItem import CateringMenuItem from src.ez_lan_manager.types.CateringMenuItem import CateringMenuItem, CateringMenuItemCategory
from src.ez_lan_manager.types.User import User from src.ez_lan_manager.types.User import User
CateringMenuItemsWithAmount = dict[CateringMenuItem, int]
class CateringOrderStatus(StrEnum): class CateringOrderStatus(StrEnum):
RECEIVED = "RECEIVED" RECEIVED = "RECEIVED"
@ -16,11 +19,12 @@ class CateringOrderStatus(StrEnum):
@dataclass(frozen=True) @dataclass(frozen=True)
class CateringOrder: class CateringOrder:
order_id: int order_id: int
order_date: datetime
status: CateringOrderStatus status: CateringOrderStatus
items: list[CateringMenuItem] items: CateringMenuItemsWithAmount
customer: User customer: User
is_delivery: bool = True is_delivery: bool = True
@property @property
def price(self) -> int: def price(self) -> int:
return sum([item.price for item in self.items]) return sum([item.price for item in self.items.keys()])