feat: Probably functional
This commit is contained in:
191
app/routes.py
191
app/routes.py
@@ -1,8 +1,195 @@
|
||||
from flask import Blueprint, render_template
|
||||
from datetime import datetime
|
||||
|
||||
from flask import Blueprint, redirect, render_template, request, url_for
|
||||
from sqlalchemy import distinct, select
|
||||
from werkzeug.wrappers.response import Response
|
||||
|
||||
from app.db import SessionLocal
|
||||
from app.models import Drink, Transaction
|
||||
|
||||
bp = Blueprint("main", __name__)
|
||||
|
||||
|
||||
@bp.route("/")
|
||||
@bp.get("/")
|
||||
def index() -> str:
|
||||
return render_template("index.html")
|
||||
|
||||
|
||||
@bp.get("/add")
|
||||
def create_drink_get() -> str:
|
||||
return render_template("add.html")
|
||||
|
||||
|
||||
@bp.post("/add")
|
||||
def create_drink_post() -> Response | tuple[str, int]:
|
||||
name = request.form.get("name")
|
||||
stock_raw = request.form.get("stock")
|
||||
price_raw = request.form.get("price")
|
||||
contact = request.form.get("phone_number")
|
||||
|
||||
if name is None or stock_raw is None or price_raw is None or contact is None:
|
||||
return "Missing required fields", 400
|
||||
|
||||
name = name.strip()
|
||||
contact = contact.strip()
|
||||
|
||||
try:
|
||||
stock = int(stock_raw)
|
||||
price = float(price_raw)
|
||||
except ValueError:
|
||||
return "Invalid numeric input", 400
|
||||
|
||||
if stock <= 0 or price <= 0:
|
||||
return "Invalid stock or price", 400
|
||||
|
||||
session = SessionLocal()
|
||||
|
||||
drink = Drink(name=name, stock=stock, price=price, stocked_by=contact)
|
||||
|
||||
session.add(drink)
|
||||
session.commit()
|
||||
|
||||
return redirect(url_for("main.list_drinks_get", id=drink.id))
|
||||
|
||||
|
||||
@bp.get("/drink/<id>/manage")
|
||||
def manage_drink_get(id: int) -> str | tuple[str, int]: # noqa: A002
|
||||
session = SessionLocal()
|
||||
|
||||
drink = session.get(Drink, id)
|
||||
if drink is None:
|
||||
return "Drink not found", 404
|
||||
|
||||
return render_template("drink_manage.html", drink=drink)
|
||||
|
||||
|
||||
@bp.post("/drink/<id>/restock")
|
||||
def restock_drink_post(id: int) -> Response | tuple[str, int]: # noqa: A002
|
||||
session = SessionLocal()
|
||||
|
||||
drink = session.get(Drink, id)
|
||||
if drink is None:
|
||||
return "Drink not found", 404
|
||||
|
||||
amount_raw = request.form.get("amount")
|
||||
|
||||
if amount_raw is None:
|
||||
return "Missing fields", 400
|
||||
|
||||
try:
|
||||
amount = int(amount_raw)
|
||||
except ValueError:
|
||||
return "Non numeric amount", 400
|
||||
|
||||
if amount <= 0:
|
||||
return "Invalid amount", 400
|
||||
|
||||
drink.stock += amount
|
||||
session.commit()
|
||||
|
||||
return redirect(url_for("main.manage_drink_get", id=id))
|
||||
|
||||
|
||||
@bp.post("/drink/<id>/delete")
|
||||
def delete_drink_post(id: int) -> Response | tuple[str, int]: # noqa: A002
|
||||
session = SessionLocal()
|
||||
|
||||
drink = session.get(Drink, id)
|
||||
if drink is None:
|
||||
return "Drink not found", 404
|
||||
|
||||
session.delete(drink)
|
||||
session.commit()
|
||||
|
||||
return redirect(url_for("main.list_drinks_get"))
|
||||
|
||||
|
||||
@bp.get("/drinks")
|
||||
def list_drinks_get() -> str:
|
||||
session = SessionLocal()
|
||||
|
||||
stmt = select(Drink)
|
||||
result = session.execute(stmt)
|
||||
drinks = [row[0] for row in result if row[0]]
|
||||
|
||||
return render_template("drink_list.html", drinks=drinks)
|
||||
|
||||
|
||||
@bp.get("/drink/<id>")
|
||||
def buy_drink_get(id: int) -> str | tuple[str, int]: # noqa: A002
|
||||
session = SessionLocal()
|
||||
|
||||
drink = session.get(Drink, id)
|
||||
if drink is None:
|
||||
return "Drink not found", 404
|
||||
|
||||
# Find user names
|
||||
stmt = select(distinct(Transaction.user_name)).order_by(Transaction.user_name)
|
||||
result = session.execute(stmt).all()
|
||||
names = [row[0] for row in result if row[0]]
|
||||
|
||||
return render_template("drink_buy.html", drink=drink, names=names)
|
||||
|
||||
|
||||
@bp.post("/drink/<id>/buy")
|
||||
def buy_drink_post(id: int) -> Response | tuple[str, int]: # noqa: A002
|
||||
session = SessionLocal()
|
||||
|
||||
drink = session.get(Drink, id)
|
||||
if drink is None:
|
||||
return "Drink not found", 404
|
||||
|
||||
name = request.form.get("name")
|
||||
qty_raw = request.form.get("quantity")
|
||||
|
||||
if name is None or qty_raw is None:
|
||||
return "Missing fields", 400
|
||||
|
||||
name = name.strip()
|
||||
|
||||
try:
|
||||
quantity = int(qty_raw)
|
||||
except ValueError:
|
||||
return "Invalid quantity", 400
|
||||
|
||||
if quantity <= 0:
|
||||
return "Quantity must be positive", 400
|
||||
|
||||
if drink.stock < quantity:
|
||||
return "Not enough stock", 400
|
||||
|
||||
# Update stock
|
||||
drink.stock -= quantity
|
||||
|
||||
# Create transaction
|
||||
transaction = Transaction(drink=drink.id, user_name=name, quantity=quantity, timestamp=datetime.now().astimezone())
|
||||
|
||||
session.add(transaction)
|
||||
session.commit()
|
||||
|
||||
return redirect(url_for("main.list_drinks_get", id=id))
|
||||
|
||||
|
||||
@bp.get("/transactions")
|
||||
def list_transactions_get() -> str:
|
||||
session = SessionLocal()
|
||||
|
||||
stmt = select(Transaction).order_by(Transaction.timestamp)
|
||||
result = session.execute(stmt).all()
|
||||
txs: list[Transaction] = [row[0] for row in result if row[0]]
|
||||
|
||||
stmt = select(Drink)
|
||||
result = session.execute(stmt).all()
|
||||
drinks: dict[int, Drink] = {row[0].id: row[0] for row in result if row[0]}
|
||||
|
||||
patched = [
|
||||
{
|
||||
"drink_name": drinks[t.drink].name if t.drink in drinks else "<removed drink>",
|
||||
"user_name": t.user_name,
|
||||
"quantity": t.quantity,
|
||||
"timestamp": t.timestamp,
|
||||
}
|
||||
for t in txs
|
||||
]
|
||||
|
||||
return render_template("transactions.html", transactions=patched)
|
||||
|
||||
Reference in New Issue
Block a user