Replace ticket qty input with +/- buttons, show sold/basket counts
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 57s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 57s
- Entry page shows tickets sold count, remaining, and "in basket" count - Replace numeric input + Buy button with add-to-basket / +/- controls - New POST /tickets/adjust/ route creates/cancels tickets to target count - Keep buy form active after adding (no confirmation replacement) - New service functions: get_sold_ticket_count, get_user_reserved_count, cancel_latest_reserved_ticket Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -160,13 +160,22 @@ def register():
|
||||
|
||||
@bp.context_processor
|
||||
async def inject_root():
|
||||
from ..tickets.services.tickets import get_available_ticket_count
|
||||
from ..tickets.services.tickets import (
|
||||
get_available_ticket_count,
|
||||
get_sold_ticket_count,
|
||||
get_user_reserved_count,
|
||||
)
|
||||
from shared.infrastructure.cart_identity import current_cart_identity
|
||||
from sqlalchemy.orm import selectinload
|
||||
|
||||
view_args = getattr(request, "view_args", {}) or {}
|
||||
entry_id = view_args.get("entry_id")
|
||||
calendar_entry = None
|
||||
entry_posts = []
|
||||
ticket_remaining = None
|
||||
ticket_sold_count = 0
|
||||
user_ticket_count = 0
|
||||
user_ticket_counts_by_type = {}
|
||||
|
||||
stmt = (
|
||||
select(CalendarEntry)
|
||||
@@ -174,6 +183,7 @@ def register():
|
||||
CalendarEntry.id == entry_id,
|
||||
CalendarEntry.deleted_at.is_(None),
|
||||
)
|
||||
.options(selectinload(CalendarEntry.ticket_types))
|
||||
)
|
||||
result = await g.s.execute(stmt)
|
||||
calendar_entry = result.scalar_one_or_none()
|
||||
@@ -190,11 +200,33 @@ def register():
|
||||
entry_posts = await get_entry_posts(g.s, calendar_entry.id)
|
||||
# Get ticket availability
|
||||
ticket_remaining = await get_available_ticket_count(g.s, calendar_entry.id)
|
||||
# Get sold count
|
||||
ticket_sold_count = await get_sold_ticket_count(g.s, calendar_entry.id)
|
||||
# Get current user's reserved count
|
||||
ident = current_cart_identity()
|
||||
user_ticket_count = await get_user_reserved_count(
|
||||
g.s, calendar_entry.id,
|
||||
user_id=ident["user_id"],
|
||||
session_id=ident["session_id"],
|
||||
)
|
||||
# Per-type counts for multi-type entries
|
||||
if calendar_entry.ticket_types:
|
||||
for tt in calendar_entry.ticket_types:
|
||||
if tt.deleted_at is None:
|
||||
user_ticket_counts_by_type[tt.id] = await get_user_reserved_count(
|
||||
g.s, calendar_entry.id,
|
||||
user_id=ident["user_id"],
|
||||
session_id=ident["session_id"],
|
||||
ticket_type_id=tt.id,
|
||||
)
|
||||
|
||||
return {
|
||||
"entry": calendar_entry,
|
||||
"entry_posts": entry_posts,
|
||||
"ticket_remaining": ticket_remaining,
|
||||
"ticket_sold_count": ticket_sold_count,
|
||||
"user_ticket_count": user_ticket_count,
|
||||
"user_ticket_counts_by_type": user_ticket_counts_by_type,
|
||||
}
|
||||
@bp.get("/")
|
||||
@require_admin
|
||||
|
||||
Reference in New Issue
Block a user