Add ticket +/- quantity support to shared contracts and services
- Add ticket_type_id field to TicketDTO for grouping - Add adjust_ticket_quantity to CalendarService protocol + SQL impl - Add stub for adjust_ticket_quantity Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -72,6 +72,7 @@ def _ticket_to_dto(ticket: Ticket) -> TicketDTO:
|
||||
created_at=ticket.created_at,
|
||||
checked_in_at=ticket.checked_in_at,
|
||||
entry_id=entry.id if entry else None,
|
||||
ticket_type_id=ticket.ticket_type_id,
|
||||
price=price,
|
||||
order_id=ticket.order_id,
|
||||
calendar_container_id=cal.container_id if cal else None,
|
||||
@@ -563,3 +564,59 @@ class SqlCalendarService:
|
||||
)
|
||||
for ticket in result.scalars().all():
|
||||
ticket.user_id = user_id
|
||||
|
||||
async def adjust_ticket_quantity(
|
||||
self, session: AsyncSession, entry_id: int, count: int, *,
|
||||
user_id: int | None, session_id: str | None,
|
||||
ticket_type_id: int | None = None,
|
||||
) -> int:
|
||||
"""Adjust reserved ticket count to target. Returns new count."""
|
||||
import uuid
|
||||
|
||||
count = max(count, 0)
|
||||
|
||||
# Current reserved count
|
||||
filters = [
|
||||
Ticket.entry_id == entry_id,
|
||||
Ticket.state == "reserved",
|
||||
]
|
||||
if user_id is not None:
|
||||
filters.append(Ticket.user_id == user_id)
|
||||
elif session_id is not None:
|
||||
filters.append(Ticket.session_id == session_id)
|
||||
else:
|
||||
return 0
|
||||
if ticket_type_id is not None:
|
||||
filters.append(Ticket.ticket_type_id == ticket_type_id)
|
||||
|
||||
current = await session.scalar(
|
||||
select(func.count(Ticket.id)).where(*filters)
|
||||
) or 0
|
||||
|
||||
if count > current:
|
||||
# Create tickets
|
||||
for _ in range(count - current):
|
||||
ticket = Ticket(
|
||||
entry_id=entry_id,
|
||||
ticket_type_id=ticket_type_id,
|
||||
user_id=user_id,
|
||||
session_id=session_id,
|
||||
code=uuid.uuid4().hex,
|
||||
state="reserved",
|
||||
)
|
||||
session.add(ticket)
|
||||
await session.flush()
|
||||
elif count < current:
|
||||
# Cancel newest tickets
|
||||
to_cancel = current - count
|
||||
result = await session.execute(
|
||||
select(Ticket)
|
||||
.where(*filters)
|
||||
.order_by(Ticket.created_at.desc())
|
||||
.limit(to_cancel)
|
||||
)
|
||||
for ticket in result.scalars().all():
|
||||
ticket.state = "cancelled"
|
||||
await session.flush()
|
||||
|
||||
return count
|
||||
|
||||
@@ -132,6 +132,11 @@ class StubCalendarService:
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
async def adjust_ticket_quantity(
|
||||
self, session, entry_id, count, *, user_id, session_id, ticket_type_id=None,
|
||||
) -> int:
|
||||
return 0
|
||||
|
||||
async def entry_ids_for_content(self, session, content_type, content_id):
|
||||
return set()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user