79 lines
2.3 KiB
Python
79 lines
2.3 KiB
Python
from datetime import datetime
|
|
|
|
import uvicorn
|
|
from fastapi import FastAPI, HTTPException
|
|
from fastapi.params import Header
|
|
from pydantic import BaseModel
|
|
|
|
from escpos.printer import Usb
|
|
|
|
MAX_LINE_LEN = 30
|
|
|
|
PRINTER = Usb(0x28e9, 0x0289)
|
|
|
|
SECRET_PASSWORD = "Alkohol1"
|
|
|
|
class OrderItem(BaseModel):
|
|
menu_item_name: str
|
|
amount: int
|
|
|
|
class Order(BaseModel):
|
|
order_id: str
|
|
order_date: datetime
|
|
customer_name: str
|
|
seat_id: str
|
|
items: list[OrderItem]
|
|
|
|
def build_header(order_id: str, order_date: datetime, customer_name: str, seat_id: str) -> str:
|
|
return (f"EZ GG e.V. - EZ LAN 1.0\n\n"
|
|
f"Bestellungs-ID: {order_id}\n"
|
|
f"Bestellt: {order_date.strftime('%d.%m. - %H:%M')}\n"
|
|
f"Gast: {customer_name}\n"
|
|
f"Sitzplatz: {seat_id}\n\n")
|
|
|
|
def format_order(order: list[OrderItem]) -> list[str]:
|
|
formatted_order = []
|
|
for item in order:
|
|
formatted_text = f"{item.amount}x {item.menu_item_name}"
|
|
formatted_text = formatted_text.replace("ä", "ae")
|
|
formatted_text = formatted_text.replace("ö", "oe")
|
|
formatted_text = formatted_text.replace("ü", "ue")
|
|
formatted_text = formatted_text.replace("ß", "ss")
|
|
if len(formatted_text) < MAX_LINE_LEN:
|
|
while len(formatted_text) < MAX_LINE_LEN:
|
|
formatted_text = formatted_text.replace(" ", " ", 1)
|
|
else:
|
|
formatted_text = formatted_text[:MAX_LINE_LEN]
|
|
|
|
formatted_order.append(formatted_text + "\n")
|
|
return formatted_order
|
|
|
|
def print_order(order: Order, printer_: Usb) -> None:
|
|
header = build_header(order.order_id, order.order_date, order.customer_name, order.seat_id)
|
|
items = format_order(order.items)
|
|
printer_.image("logo.png")
|
|
printer_.text(header)
|
|
for item in items:
|
|
printer_.text(item)
|
|
printer_.cut()
|
|
|
|
api = FastAPI()
|
|
|
|
|
|
@api.post("/print_order")
|
|
async def print_order_api_endpoint(order: Order, x_password: str = Header(None)):
|
|
if x_password != SECRET_PASSWORD:
|
|
raise HTTPException(status_code=401, detail="Unauthorized")
|
|
|
|
for item in order.items:
|
|
if item.amount < 1:
|
|
return 422
|
|
|
|
print_order(order, PRINTER)
|
|
|
|
return "done"
|
|
|
|
if __name__ == "__main__":
|
|
print("Starting receipt printing server...")
|
|
uvicorn.run(api, host="0.0.0.0", port=5000, log_level="warning")
|