Add ticket-to-cart integration
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m6s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m6s
Tickets now appear as cart line items, are included in checkout totals, confirmed on payment, and displayed on the checkout return page. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
12
app.py
12
app.py
@@ -21,10 +21,13 @@ from bp.cart.services import (
|
||||
total,
|
||||
get_calendar_cart_entries,
|
||||
calendar_total,
|
||||
get_ticket_cart_entries,
|
||||
ticket_total,
|
||||
)
|
||||
from bp.cart.services.page_cart import (
|
||||
get_cart_for_page,
|
||||
get_calendar_entries_for_page,
|
||||
get_tickets_for_page,
|
||||
)
|
||||
|
||||
|
||||
@@ -53,27 +56,32 @@ async def cart_context() -> dict:
|
||||
# Cart app owns cart data — use g.cart from _load_cart
|
||||
all_cart = getattr(g, "cart", None) or []
|
||||
all_cal = await get_calendar_cart_entries(g.s)
|
||||
all_tickets = await get_ticket_cart_entries(g.s)
|
||||
|
||||
# Global counts for cart-mini (always global)
|
||||
cart_qty = sum(ci.quantity for ci in all_cart) if all_cart else 0
|
||||
ctx["cart_count"] = cart_qty + len(all_cal)
|
||||
ctx["cart_total"] = (total(all_cart) or 0) + (calendar_total(all_cal) or 0)
|
||||
ctx["cart_count"] = cart_qty + len(all_cal) + len(all_tickets)
|
||||
ctx["cart_total"] = (total(all_cart) or 0) + (calendar_total(all_cal) or 0) + (ticket_total(all_tickets) or 0)
|
||||
|
||||
# Page-scoped data when viewing a page cart
|
||||
page_post = getattr(g, "page_post", None)
|
||||
if page_post:
|
||||
page_cart = await get_cart_for_page(g.s, page_post.id)
|
||||
page_cal = await get_calendar_entries_for_page(g.s, page_post.id)
|
||||
page_tickets = await get_tickets_for_page(g.s, page_post.id)
|
||||
ctx["cart"] = page_cart
|
||||
ctx["calendar_cart_entries"] = page_cal
|
||||
ctx["ticket_cart_entries"] = page_tickets
|
||||
ctx["page_post"] = page_post
|
||||
ctx["page_config"] = getattr(g, "page_config", None)
|
||||
else:
|
||||
ctx["cart"] = all_cart
|
||||
ctx["calendar_cart_entries"] = all_cal
|
||||
ctx["ticket_cart_entries"] = all_tickets
|
||||
|
||||
ctx["total"] = total
|
||||
ctx["calendar_total"] = calendar_total
|
||||
ctx["ticket_total"] = ticket_total
|
||||
|
||||
ctx["menu_items"] = await get_navigation_tree(g.s)
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@ from .services import (
|
||||
clear_cart_for_order,
|
||||
get_calendar_cart_entries,
|
||||
calendar_total,
|
||||
get_ticket_cart_entries,
|
||||
ticket_total,
|
||||
check_sumup_status,
|
||||
)
|
||||
from .services.checkout import (
|
||||
@@ -107,19 +109,21 @@ def register(url_prefix: str) -> Blueprint:
|
||||
"""Legacy global checkout (for orphan items without page scope)."""
|
||||
cart = await get_cart(g.s)
|
||||
calendar_entries = await get_calendar_cart_entries(g.s)
|
||||
tickets = await get_ticket_cart_entries(g.s)
|
||||
|
||||
if not cart and not calendar_entries:
|
||||
if not cart and not calendar_entries and not tickets:
|
||||
return redirect(url_for("cart_overview.overview"))
|
||||
|
||||
product_total = total(cart) or 0
|
||||
calendar_amount = calendar_total(calendar_entries) or 0
|
||||
cart_total = product_total + calendar_amount
|
||||
ticket_amount = ticket_total(tickets) or 0
|
||||
cart_total = product_total + calendar_amount + ticket_amount
|
||||
|
||||
if cart_total <= 0:
|
||||
return redirect(url_for("cart_overview.overview"))
|
||||
|
||||
try:
|
||||
page_config = await resolve_page_config(g.s, cart, calendar_entries)
|
||||
page_config = await resolve_page_config(g.s, cart, calendar_entries, tickets)
|
||||
except ValueError as e:
|
||||
html = await render_template(
|
||||
"_types/cart/checkout_error.html",
|
||||
@@ -137,6 +141,7 @@ def register(url_prefix: str) -> Blueprint:
|
||||
ident.get("session_id"),
|
||||
product_total,
|
||||
calendar_amount,
|
||||
ticket_total=ticket_amount,
|
||||
)
|
||||
|
||||
if page_config:
|
||||
@@ -144,7 +149,7 @@ def register(url_prefix: str) -> Blueprint:
|
||||
|
||||
redirect_url = url_for("cart_global.checkout_return", order_id=order.id, _external=True)
|
||||
order.sumup_reference = build_sumup_reference(order.id, page_config=page_config)
|
||||
description = build_sumup_description(cart, order.id)
|
||||
description = build_sumup_description(cart, order.id, ticket_count=len(tickets))
|
||||
|
||||
webhook_base_url = url_for("cart_global.checkout_webhook", order_id=order.id, _external=True)
|
||||
webhook_url = build_webhook_url(webhook_base_url)
|
||||
@@ -253,6 +258,7 @@ def register(url_prefix: str) -> Blueprint:
|
||||
status = (order.status or "pending").lower()
|
||||
|
||||
calendar_entries = await services.calendar.get_entries_for_order(g.s, order.id)
|
||||
order_tickets = await services.calendar.get_tickets_for_order(g.s, order.id)
|
||||
await g.s.flush()
|
||||
|
||||
html = await render_template(
|
||||
@@ -260,6 +266,7 @@ def register(url_prefix: str) -> Blueprint:
|
||||
order=order,
|
||||
status=status,
|
||||
calendar_entries=calendar_entries,
|
||||
order_tickets=order_tickets,
|
||||
)
|
||||
return await make_response(html)
|
||||
|
||||
|
||||
@@ -11,8 +11,9 @@ from .services import (
|
||||
total,
|
||||
clear_cart_for_order,
|
||||
calendar_total,
|
||||
ticket_total,
|
||||
)
|
||||
from .services.page_cart import get_cart_for_page, get_calendar_entries_for_page
|
||||
from .services.page_cart import get_cart_for_page, get_calendar_entries_for_page, get_tickets_for_page
|
||||
from .services.checkout import (
|
||||
create_order_from_cart,
|
||||
build_sumup_description,
|
||||
@@ -30,14 +31,17 @@ def register(url_prefix: str) -> Blueprint:
|
||||
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)
|
||||
|
||||
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,
|
||||
total=total,
|
||||
calendar_total=calendar_total,
|
||||
ticket_total=ticket_total,
|
||||
)
|
||||
|
||||
if not is_htmx_request():
|
||||
@@ -53,13 +57,15 @@ def register(url_prefix: str) -> Blueprint:
|
||||
|
||||
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:
|
||||
if not cart and not cal_entries and not page_tickets:
|
||||
return redirect(url_for("page_cart.page_view"))
|
||||
|
||||
product_total = total(cart) or 0
|
||||
calendar_amount = calendar_total(cal_entries) or 0
|
||||
cart_total = product_total + calendar_amount
|
||||
ticket_amount = ticket_total(page_tickets) or 0
|
||||
cart_total = product_total + calendar_amount + ticket_amount
|
||||
|
||||
if cart_total <= 0:
|
||||
return redirect(url_for("page_cart.page_view"))
|
||||
@@ -74,6 +80,7 @@ def register(url_prefix: str) -> Blueprint:
|
||||
ident.get("session_id"),
|
||||
product_total,
|
||||
calendar_amount,
|
||||
ticket_total=ticket_amount,
|
||||
page_post_id=post.id,
|
||||
)
|
||||
|
||||
@@ -84,7 +91,7 @@ def register(url_prefix: str) -> Blueprint:
|
||||
# Build SumUp checkout details — webhook/return use global routes
|
||||
redirect_url = url_for("cart_global.checkout_return", order_id=order.id, _external=True)
|
||||
order.sumup_reference = build_sumup_reference(order.id, page_config=page_config)
|
||||
description = build_sumup_description(cart, order.id)
|
||||
description = build_sumup_description(cart, order.id, ticket_count=len(page_tickets))
|
||||
|
||||
webhook_base_url = url_for("cart_global.checkout_webhook", order_id=order.id, _external=True)
|
||||
webhook_url = build_webhook_url(webhook_base_url)
|
||||
|
||||
@@ -2,11 +2,12 @@ from .get_cart import get_cart
|
||||
from .identity import current_cart_identity
|
||||
from .total import total
|
||||
from .clear_cart_for_order import clear_cart_for_order
|
||||
from .calendar_cart import get_calendar_cart_entries, calendar_total
|
||||
from .calendar_cart import get_calendar_cart_entries, calendar_total, get_ticket_cart_entries, ticket_total
|
||||
from .check_sumup_status import check_sumup_status
|
||||
from .page_cart import (
|
||||
get_cart_for_page,
|
||||
get_calendar_entries_for_page,
|
||||
get_tickets_for_page,
|
||||
get_cart_grouped_by_page,
|
||||
)
|
||||
|
||||
|
||||
@@ -26,3 +26,18 @@ def calendar_total(entries) -> float:
|
||||
for e in entries
|
||||
if e.cost is not None
|
||||
)
|
||||
|
||||
|
||||
async def get_ticket_cart_entries(session):
|
||||
"""Return all reserved tickets (as TicketDTOs) for the current identity."""
|
||||
ident = current_cart_identity()
|
||||
return await services.calendar.pending_tickets(
|
||||
session,
|
||||
user_id=ident["user_id"],
|
||||
session_id=ident["session_id"],
|
||||
)
|
||||
|
||||
|
||||
def ticket_total(tickets) -> float:
|
||||
"""Total cost of reserved tickets."""
|
||||
return sum(float(t.price or 0) for t in tickets)
|
||||
|
||||
@@ -16,6 +16,7 @@ async def check_sumup_status(session, order):
|
||||
await services.calendar.confirm_entries_for_order(
|
||||
session, order.id, order.user_id, order.session_id
|
||||
)
|
||||
await services.calendar.confirm_tickets_for_order(session, order.id)
|
||||
await emit_event(session, "order.paid", "order", order.id, {
|
||||
"order_id": order.id,
|
||||
"user_id": order.user_id,
|
||||
|
||||
@@ -65,6 +65,7 @@ async def resolve_page_config(
|
||||
session: AsyncSession,
|
||||
cart: list[CartItem],
|
||||
calendar_entries: list[CalendarEntryDTO],
|
||||
tickets=None,
|
||||
) -> Optional["PageConfig"]:
|
||||
"""Determine the PageConfig for this order.
|
||||
|
||||
@@ -85,6 +86,11 @@ async def resolve_page_config(
|
||||
if entry.calendar_container_id:
|
||||
post_ids.add(entry.calendar_container_id)
|
||||
|
||||
# From tickets via calendar_container_id
|
||||
for tk in (tickets or []):
|
||||
if tk.calendar_container_id:
|
||||
post_ids.add(tk.calendar_container_id)
|
||||
|
||||
if len(post_ids) > 1:
|
||||
raise ValueError("Cannot checkout items from multiple pages")
|
||||
|
||||
@@ -110,16 +116,17 @@ async def create_order_from_cart(
|
||||
product_total: float,
|
||||
calendar_total: float,
|
||||
*,
|
||||
ticket_total: float = 0,
|
||||
page_post_id: int | None = None,
|
||||
) -> Order:
|
||||
"""
|
||||
Create an Order and OrderItems from the current cart + calendar entries.
|
||||
Create an Order and OrderItems from the current cart + calendar entries + tickets.
|
||||
|
||||
When *page_post_id* is given, only calendar entries whose calendar
|
||||
When *page_post_id* is given, only calendar entries/tickets whose calendar
|
||||
belongs to that page are marked as "ordered". Otherwise all pending
|
||||
entries are updated (legacy behaviour).
|
||||
"""
|
||||
cart_total = product_total + calendar_total
|
||||
cart_total = product_total + calendar_total + ticket_total
|
||||
|
||||
# Determine currency from first product
|
||||
first_product = cart[0].product if cart else None
|
||||
@@ -154,6 +161,11 @@ async def create_order_from_cart(
|
||||
session, order.id, user_id, session_id, page_post_id
|
||||
)
|
||||
|
||||
# Claim reserved tickets for this order
|
||||
await services.calendar.claim_tickets_for_order(
|
||||
session, order.id, user_id, session_id, page_post_id
|
||||
)
|
||||
|
||||
await emit_event(session, "order.created", "order", order.id, {
|
||||
"order_id": order.id,
|
||||
"user_id": user_id,
|
||||
@@ -163,20 +175,24 @@ async def create_order_from_cart(
|
||||
return order
|
||||
|
||||
|
||||
def build_sumup_description(cart: list[CartItem], order_id: int) -> str:
|
||||
def build_sumup_description(cart: list[CartItem], order_id: int, *, ticket_count: int = 0) -> str:
|
||||
"""Build a human-readable description for SumUp checkout."""
|
||||
titles = [ci.product.title for ci in cart if ci.product and ci.product.title]
|
||||
item_count = sum(ci.quantity for ci in cart)
|
||||
|
||||
parts = []
|
||||
if titles:
|
||||
if len(titles) <= 3:
|
||||
summary = ", ".join(titles)
|
||||
parts.append(", ".join(titles))
|
||||
else:
|
||||
summary = ", ".join(titles[:3]) + f" + {len(titles) - 3} more"
|
||||
else:
|
||||
summary = "order items"
|
||||
parts.append(", ".join(titles[:3]) + f" + {len(titles) - 3} more")
|
||||
if ticket_count:
|
||||
parts.append(f"{ticket_count} ticket{'s' if ticket_count != 1 else ''}")
|
||||
|
||||
return f"Order {order_id} ({item_count} item{'s' if item_count != 1 else ''}): {summary}"
|
||||
summary = ", ".join(parts) if parts else "order items"
|
||||
total_count = item_count + ticket_count
|
||||
|
||||
return f"Order {order_id} ({total_count} item{'s' if total_count != 1 else ''}): {summary}"
|
||||
|
||||
|
||||
def build_sumup_reference(order_id: int, page_config=None) -> str:
|
||||
|
||||
@@ -57,6 +57,16 @@ async def get_calendar_entries_for_page(session, post_id: int):
|
||||
)
|
||||
|
||||
|
||||
async def get_tickets_for_page(session, post_id: int):
|
||||
"""Return reserved tickets (DTOs) scoped to a specific page."""
|
||||
ident = current_cart_identity()
|
||||
return await services.calendar.tickets_for_page(
|
||||
session, post_id,
|
||||
user_id=ident["user_id"],
|
||||
session_id=ident["session_id"],
|
||||
)
|
||||
|
||||
|
||||
async def get_cart_grouped_by_page(session) -> list[dict]:
|
||||
"""
|
||||
Load all cart items + calendar entries for the current identity,
|
||||
@@ -80,12 +90,13 @@ async def get_cart_grouped_by_page(session) -> list[dict]:
|
||||
Items without a market_place go in an orphan bucket (post=None).
|
||||
"""
|
||||
from .get_cart import get_cart
|
||||
from .calendar_cart import get_calendar_cart_entries
|
||||
from .calendar_cart import get_calendar_cart_entries, get_ticket_cart_entries
|
||||
from .total import total as calc_product_total
|
||||
from .calendar_cart import calendar_total as calc_calendar_total
|
||||
from .calendar_cart import calendar_total as calc_calendar_total, ticket_total as calc_ticket_total
|
||||
|
||||
cart_items = await get_cart(session)
|
||||
cal_entries = await get_calendar_cart_entries(session)
|
||||
all_tickets = await get_ticket_cart_entries(session)
|
||||
|
||||
# Group cart items by market_place_id
|
||||
market_groups: dict[int | None, dict] = {}
|
||||
@@ -97,6 +108,7 @@ async def get_cart_grouped_by_page(session) -> list[dict]:
|
||||
"post_id": ci.market_place.container_id if ci.market_place else None,
|
||||
"cart_items": [],
|
||||
"calendar_entries": [],
|
||||
"tickets": [],
|
||||
}
|
||||
market_groups[mp_id]["cart_items"].append(ci)
|
||||
|
||||
@@ -121,11 +133,31 @@ async def get_cart_grouped_by_page(session) -> list[dict]:
|
||||
"post_id": pid,
|
||||
"cart_items": [],
|
||||
"calendar_entries": [],
|
||||
"tickets": [],
|
||||
}
|
||||
if pid is not None:
|
||||
page_to_market[pid] = key
|
||||
market_groups[key]["calendar_entries"].append(ce)
|
||||
|
||||
# Attach tickets to page groups (via calendar_container_id)
|
||||
for tk in all_tickets:
|
||||
pid = tk.calendar_container_id or None
|
||||
if pid in page_to_market:
|
||||
market_groups[page_to_market[pid]]["tickets"].append(tk)
|
||||
else:
|
||||
key = ("tk", pid)
|
||||
if key not in market_groups:
|
||||
market_groups[key] = {
|
||||
"market_place": None,
|
||||
"post_id": pid,
|
||||
"cart_items": [],
|
||||
"calendar_entries": [],
|
||||
"tickets": [],
|
||||
}
|
||||
if pid is not None:
|
||||
page_to_market[pid] = key
|
||||
market_groups[key]["tickets"].append(tk)
|
||||
|
||||
# Batch-load Post DTOs and PageConfig objects
|
||||
post_ids = list({
|
||||
grp["post_id"] for grp in market_groups.values()
|
||||
@@ -155,8 +187,10 @@ async def get_cart_grouped_by_page(session) -> list[dict]:
|
||||
):
|
||||
items = grp["cart_items"]
|
||||
entries = grp["calendar_entries"]
|
||||
tks = grp["tickets"]
|
||||
prod_total = calc_product_total(items) or 0
|
||||
cal_total = calc_calendar_total(entries) or 0
|
||||
tk_total = calc_ticket_total(tks) or 0
|
||||
pid = grp["post_id"]
|
||||
|
||||
result.append({
|
||||
@@ -165,11 +199,14 @@ async def get_cart_grouped_by_page(session) -> list[dict]:
|
||||
"market_place": grp["market_place"],
|
||||
"cart_items": items,
|
||||
"calendar_entries": entries,
|
||||
"tickets": tks,
|
||||
"product_count": sum(ci.quantity for ci in items),
|
||||
"product_total": prod_total,
|
||||
"calendar_count": len(entries),
|
||||
"calendar_total": cal_total,
|
||||
"total": prod_total + cal_total,
|
||||
"ticket_count": len(tks),
|
||||
"ticket_total": tk_total,
|
||||
"total": prod_total + cal_total + tk_total,
|
||||
})
|
||||
|
||||
return result
|
||||
|
||||
2
shared
2
shared
Submodule shared updated: 71729ffb28...7ee8638d6e
@@ -1,7 +1,7 @@
|
||||
{% macro show_cart(oob=False) %}
|
||||
<div id="cart" {% if oob %} hx-swap-oob="{{oob}}" {% endif%}>
|
||||
{# Empty cart #}
|
||||
{% if not cart and not calendar_cart_entries %}
|
||||
{% if not cart and not calendar_cart_entries and not ticket_cart_entries %}
|
||||
<div class="rounded-2xl border border-dashed border-stone-300 bg-white/80 p-6 sm:p-8 text-center">
|
||||
<div class="inline-flex h-10 w-10 sm:h-12 sm:w-12 items-center justify-center rounded-full bg-stone-100 mb-3">
|
||||
<i class="fa fa-shopping-cart text-stone-500 text-sm sm:text-base" aria-hidden="true"></i>
|
||||
@@ -60,8 +60,41 @@
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if ticket_cart_entries %}
|
||||
<div class="mt-6 border-t border-stone-200 pt-4">
|
||||
<h2 class="text-base font-semibold mb-2">
|
||||
Event tickets
|
||||
</h2>
|
||||
|
||||
<ul class="space-y-2">
|
||||
{% for tk in ticket_cart_entries %}
|
||||
<li class="flex items-start justify-between text-sm">
|
||||
<div>
|
||||
<div class="font-medium">
|
||||
{{ tk.entry_name }}
|
||||
</div>
|
||||
{% if tk.ticket_type_name %}
|
||||
<div class="text-xs text-stone-500">
|
||||
{{ tk.ticket_type_name }}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="text-xs text-stone-500">
|
||||
{{ tk.entry_start_at.strftime('%-d %b %Y, %H:%M') }}
|
||||
{% if tk.entry_end_at %}
|
||||
– {{ tk.entry_end_at.strftime('%-d %b %Y, %H:%M') }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-4 font-medium">
|
||||
£{{ "%.2f"|format(tk.price or 0) }}
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</section>
|
||||
{{summary(cart, total, calendar_total, calendar_cart_entries,)}}
|
||||
{{summary(cart, total, calendar_total, calendar_cart_entries, ticket_total, ticket_cart_entries)}}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -70,7 +103,7 @@
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro summary(cart, total, calendar_total, calendar_cart_entries, oob=False) %}
|
||||
{% macro summary(cart, total, calendar_total, calendar_cart_entries, ticket_total, ticket_cart_entries, oob=False) %}
|
||||
<aside id="cart-summary" class="lg:pl-2" {% if oob %} hx-swap-oob="{{oob}}" {% endif %}>
|
||||
<div class="rounded-2xl bg-white shadow-sm border border-stone-200 p-4 sm:p-5">
|
||||
<h2 class="text-sm sm:text-base font-semibold text-stone-900 mb-3 sm:mb-4">
|
||||
@@ -87,7 +120,7 @@
|
||||
<div class="flex items-center justify-between">
|
||||
<dt class="text-stone-600">Subtotal</dt>
|
||||
<dd class="text-stone-900">
|
||||
{{ cart_grand_total(cart, total, calendar_total, calendar_cart_entries ) }}
|
||||
{{ cart_grand_total(cart, total, calendar_total, calendar_cart_entries, ticket_total, ticket_cart_entries) }}
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
@@ -154,10 +187,11 @@
|
||||
{% endmacro %}
|
||||
|
||||
|
||||
{% macro cart_grand_total(cart, total, calendar_total, calendar_cart_entries) %}
|
||||
{% macro cart_grand_total(cart, total, calendar_total, calendar_cart_entries, ticket_total, ticket_cart_entries) %}
|
||||
{% set product_total = total(cart) or 0 %}
|
||||
{% set cal_total = calendar_total(calendar_cart_entries) or 0 %}
|
||||
{% set grand = product_total + cal_total %}
|
||||
{% set tk_total = ticket_total(ticket_cart_entries) or 0 %}
|
||||
{% set grand = product_total + cal_total + tk_total %}
|
||||
|
||||
{% if cart and cart[0].product.regular_price_currency %}
|
||||
{% set symbol = "£" if cart[0].product.regular_price_currency == "GBP" else cart[0].product.regular_price_currency %}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
{# Check if there are any items at all across all groups #}
|
||||
{% set ns = namespace(has_items=false) %}
|
||||
{% for grp in page_groups %}
|
||||
{% if grp.cart_items or grp.calendar_entries %}
|
||||
{% if grp.cart_items or grp.calendar_entries or grp.get('tickets') %}
|
||||
{% set ns.has_items = true %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
@@ -30,7 +30,7 @@
|
||||
{% else %}
|
||||
<div class="space-y-4">
|
||||
{% for grp in page_groups %}
|
||||
{% if grp.cart_items or grp.calendar_entries %}
|
||||
{% if grp.cart_items or grp.calendar_entries or grp.get('tickets') %}
|
||||
|
||||
{% if grp.post %}
|
||||
{# Market / page cart card #}
|
||||
@@ -76,6 +76,12 @@
|
||||
{{ grp.calendar_count }} booking{{ 's' if grp.calendar_count != 1 }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if grp.ticket_count is defined and grp.ticket_count > 0 %}
|
||||
<span class="inline-flex items-center gap-1 px-2 py-0.5 rounded-full bg-stone-100">
|
||||
<i class="fa fa-ticket" aria-hidden="true"></i>
|
||||
{{ grp.ticket_count }} ticket{{ 's' if grp.ticket_count != 1 }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -115,6 +121,12 @@
|
||||
{{ grp.calendar_count }} booking{{ 's' if grp.calendar_count != 1 }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% if grp.ticket_count is defined and grp.ticket_count > 0 %}
|
||||
<span class="inline-flex items-center gap-1 px-2 py-0.5 rounded-full bg-amber-100">
|
||||
<i class="fa fa-ticket" aria-hidden="true"></i>
|
||||
{{ grp.ticket_count }} ticket{{ 's' if grp.ticket_count != 1 }}
|
||||
</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user