# Dominio Ticket

## Propósito

Genera, valida, consulta y exporta entradas asociadas a compras pagadas de productos o variantes ticketables.

## Modelo

- `Ticket`: pertenece a tenant y usuario, y conserva referencias a compra, producto, variante y usuario escáner.
- El nombre y la descripción se calculan dinámicamente desde el producto y la variante; los tickets no
  persisten una copia de esos textos.
- `ValidityTime`: define ventanas absolutas o relativas de vigencia para fechas de evento y opciones de atributos.
- `ValidityTimeType`: enum de estrategias de vigencia.

`TicketValidityResolver` deriva la vigencia desde la variante asociada. Las alternativas de un mismo atributo
se combinan con OR y las dimensiones diferentes se combinan con AND. El modelo calcula si un ticket está
vigente, vencido o usado, y resuelve sus fechas efectivas de inicio y fin sin persistir vigencias en el ticket.

## Flujo de generación

1. `Purchase` emite `PurchasePaid` al confirmarse el pago.
2. `GenerateTicketsForPaidPurchase` atiende el evento.
3. `TicketGeneratorService` crea los tickets requeridos según ítems, cantidades y vigencia.
4. `Notification` envía la confirmación de compra después de la generación y adjunta los tickets cuando existen.

## Endpoints

Bajo `/tenants/{tenant:codigo}`, protegidos por `auth:sanctum`:

- `GET /tickets`.
- `POST /tickets/pdf`.

`TicketPdfService` genera la descarga y `TicketResource`/`ValidityTimeResource` definen las respuestas.

## Dependencias y reglas

Depende de `Purchase`, `Catalog`, `Tenant` y `Auth`. La generación debe ser idempotente ante reintentos del evento. `TicketNotAvailableException` y `TicketGenerationException` separan indisponibilidad de errores de generación.
