All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 11m37s
Rename all sexp directories, files, identifiers, and references to sx. artdag/ excluded (separate media processing DSL). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
123 lines
4.7 KiB
Python
123 lines
4.7 KiB
Python
# bp/cart/page_routes.py — Per-page cart (view + checkout)
|
|
|
|
from __future__ import annotations
|
|
|
|
from quart import Blueprint, g, redirect, make_response, url_for
|
|
|
|
from shared.browser.app.utils.htmx import is_htmx_request
|
|
from shared.sx.helpers import sx_response
|
|
from shared.infrastructure.actions import call_action
|
|
from .services import (
|
|
total,
|
|
calendar_total,
|
|
ticket_total,
|
|
)
|
|
from .services.page_cart import get_cart_for_page, get_calendar_entries_for_page, get_tickets_for_page
|
|
from .services.ticket_groups import group_tickets
|
|
from .services import current_cart_identity
|
|
|
|
|
|
def register(url_prefix: str) -> Blueprint:
|
|
bp = Blueprint("page_cart", __name__, url_prefix=url_prefix)
|
|
|
|
@bp.get("/")
|
|
async def page_view():
|
|
post = g.page_post
|
|
cart = await get_cart_for_page(g.s, post.id)
|
|
cal_entries = await get_calendar_entries_for_page(g.s, post.id)
|
|
page_tickets = await get_tickets_for_page(g.s, post.id)
|
|
|
|
ticket_groups = group_tickets(page_tickets)
|
|
|
|
tpl_ctx = dict(
|
|
page_post=post,
|
|
page_config=getattr(g, "page_config", None),
|
|
cart=cart,
|
|
calendar_cart_entries=cal_entries,
|
|
ticket_cart_entries=page_tickets,
|
|
ticket_groups=ticket_groups,
|
|
total=total,
|
|
calendar_total=calendar_total,
|
|
ticket_total=ticket_total,
|
|
)
|
|
|
|
from shared.sx.page import get_template_context
|
|
from sx.sx_components import render_page_cart_page, render_page_cart_oob
|
|
|
|
ctx = await get_template_context()
|
|
if not is_htmx_request():
|
|
html = await render_page_cart_page(
|
|
ctx, post, cart, cal_entries, page_tickets,
|
|
ticket_groups, total, calendar_total, ticket_total,
|
|
)
|
|
return await make_response(html)
|
|
else:
|
|
sx_src = await render_page_cart_oob(
|
|
ctx, post, cart, cal_entries, page_tickets,
|
|
ticket_groups, total, calendar_total, ticket_total,
|
|
)
|
|
return sx_response(sx_src)
|
|
|
|
@bp.post("/checkout/")
|
|
async def page_checkout():
|
|
post = g.page_post
|
|
|
|
cart = await get_cart_for_page(g.s, post.id)
|
|
cal_entries = await get_calendar_entries_for_page(g.s, post.id)
|
|
page_tickets = await get_tickets_for_page(g.s, post.id)
|
|
|
|
if not cart and not cal_entries and not page_tickets:
|
|
return redirect(url_for("page_cart.page_view"))
|
|
|
|
product_total_val = total(cart) or 0
|
|
calendar_amount = calendar_total(cal_entries) or 0
|
|
ticket_amount = ticket_total(page_tickets) or 0
|
|
cart_total = product_total_val + calendar_amount + ticket_amount
|
|
|
|
if cart_total <= 0:
|
|
return redirect(url_for("page_cart.page_view"))
|
|
|
|
ident = current_cart_identity()
|
|
|
|
# Serialize cart items for the orders service
|
|
cart_items_data = []
|
|
for ci in cart:
|
|
cart_items_data.append({
|
|
"product_id": ci.product_id,
|
|
"product_title": ci.product_title,
|
|
"product_slug": ci.product_slug,
|
|
"product_image": ci.product_image,
|
|
"product_regular_price": float(ci.product_regular_price) if ci.product_regular_price else None,
|
|
"product_special_price": float(ci.product_special_price) if ci.product_special_price else None,
|
|
"product_price_currency": ci.product_price_currency,
|
|
"quantity": ci.quantity,
|
|
})
|
|
|
|
cal_data = [{"id": e.id, "calendar_container_id": getattr(e, "calendar_container_id", None)} for e in cal_entries]
|
|
ticket_data = [{"id": t.id, "calendar_container_id": getattr(t, "calendar_container_id", None)} for t in page_tickets]
|
|
|
|
result = await call_action("orders", "create-order", payload={
|
|
"cart_items": cart_items_data,
|
|
"calendar_entries": cal_data,
|
|
"tickets": ticket_data,
|
|
"user_id": ident.get("user_id"),
|
|
"session_id": ident.get("session_id"),
|
|
"product_total": float(product_total_val),
|
|
"calendar_total": float(calendar_amount),
|
|
"ticket_total": float(ticket_amount),
|
|
"page_post_id": post.id,
|
|
})
|
|
|
|
hosted_url = result.get("sumup_hosted_url")
|
|
|
|
if not hosted_url:
|
|
from shared.sx.page import get_template_context
|
|
from sx.sx_components import render_checkout_error_page
|
|
tctx = await get_template_context()
|
|
html = await render_checkout_error_page(tctx, error="No hosted checkout URL returned from SumUp.")
|
|
return await make_response(html, 500)
|
|
|
|
return redirect(hosted_url)
|
|
|
|
return bp
|