Add admin panel, cart, checkout, and digital key delivery
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+82
@@ -0,0 +1,82 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from decimal import Decimal
|
||||
|
||||
from fastapi import Request
|
||||
from sqlalchemy import func, select
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models import Product, ProductKey
|
||||
|
||||
|
||||
def get_cart_map(request: Request) -> dict[str, int]:
|
||||
raw = request.session.get("cart") or {}
|
||||
cart: dict[str, int] = {}
|
||||
for key, value in raw.items():
|
||||
try:
|
||||
qty = int(value)
|
||||
except (TypeError, ValueError):
|
||||
continue
|
||||
if qty > 0:
|
||||
cart[str(key)] = qty
|
||||
return cart
|
||||
|
||||
|
||||
def save_cart(request: Request, cart: dict[str, int]) -> None:
|
||||
request.session["cart"] = {str(k): int(v) for k, v in cart.items() if int(v) > 0}
|
||||
|
||||
|
||||
def cart_count(request: Request) -> int:
|
||||
return sum(get_cart_map(request).values())
|
||||
|
||||
|
||||
def available_stock(db: Session, product_id: int) -> int:
|
||||
return int(
|
||||
db.scalar(
|
||||
select(func.count())
|
||||
.select_from(ProductKey)
|
||||
.where(ProductKey.product_id == product_id, ProductKey.is_sold.is_(False))
|
||||
)
|
||||
or 0
|
||||
)
|
||||
|
||||
|
||||
def build_cart_items(db: Session, request: Request) -> tuple[list[dict], Decimal]:
|
||||
cart = get_cart_map(request)
|
||||
items: list[dict] = []
|
||||
total = Decimal("0.00")
|
||||
if not cart:
|
||||
return items, total
|
||||
|
||||
product_ids = [int(pid) for pid in cart.keys()]
|
||||
products = {
|
||||
p.id: p
|
||||
for p in db.scalars(select(Product).where(Product.id.in_(product_ids))).all()
|
||||
}
|
||||
|
||||
clean_cart = dict(cart)
|
||||
for pid_str, qty in cart.items():
|
||||
product = products.get(int(pid_str))
|
||||
if not product or not product.is_active:
|
||||
clean_cart.pop(pid_str, None)
|
||||
continue
|
||||
stock = available_stock(db, product.id)
|
||||
qty = min(qty, max(stock, 0))
|
||||
if qty <= 0:
|
||||
clean_cart.pop(pid_str, None)
|
||||
continue
|
||||
clean_cart[pid_str] = qty
|
||||
line_total = product.price * qty
|
||||
total += line_total
|
||||
items.append(
|
||||
{
|
||||
"product": product,
|
||||
"quantity": qty,
|
||||
"stock": stock,
|
||||
"line_total": line_total,
|
||||
}
|
||||
)
|
||||
|
||||
if clean_cart != cart:
|
||||
save_cart(request, clean_cart)
|
||||
return items, total
|
||||
Reference in New Issue
Block a user