# API de promociones disponibles para participantes

Este módulo permite a un dependiente autenticado:

- listar promociones disponibles para su farmacia
- ver detalle de promoción
- conocer productos y la regla de boletos aplicable
- revisar y aceptar términos vigentes

## Regla de boletos por producto

Cada producto participante devuelve:

```json
{
  "id": "uuid-producto",
  "code": "PROD-001",
  "name": "Cortax",
  "presentation": "Caja",
  "rule": {
    "required_quantity": 5,
    "tickets_awarded": 1,
    "calculation_mode": "per_complete_block",
    "calculation_mode_label": "Por cada bloque completo",
    "description": "Por cada 5 unidades genera 1 boleto"
  }
}
```

Modo soportado actualmente:

- `per_complete_block`

## Relación con facturas y participaciones

Este módulo no registra facturas. La factura general y las participaciones vigentes se documentan en:

- `docs/frontend/invoices-api.md`
- `docs/frontend/participant-participations-api.md`

## Endpoints

| Método | Ruta | Permiso |
|---|---|---|
| GET | `/api/v1/participant/promotions` | `participant_promotions.view_any` |
| GET | `/api/v1/participant/promotions/{promotion}` | `participant_promotions.view` |
| POST | `/api/v1/participant/promotions/{promotion}/accept-terms` | `participant_promotions.accept_terms` |

## Configuración Axios

```ts
import axios from 'axios';

export const api = axios.create({
  baseURL: import.meta.env.VITE_API_URL,
  withCredentials: true,
  withXSRFToken: true,
  headers: { Accept: 'application/json' },
});
```

## Estado actual

Las promociones disponibles siguen siendo la base para detectar aplicaciones automáticas cuando un administrador registra una factura general.

## Aceptación vigente

Una aceptación cuenta como vigente solo cuando coincide con:

- el mismo usuario dependiente
- la misma promoción
- la versión vigente publicada en `terms_version`
- el contenido vigente de `terms_and_conditions`

Si el dependiente aceptó una versión anterior y luego se publica una nueva versión, la promoción vuelve a mostrarse pendiente pero con contexto de nueva versión.

## Estado de términos

Cada promoción devuelve en `terms`:

```json
{
  "version": "2.0",
  "accepted": false,
  "accepted_at": null,
  "requires_acceptance": true,
  "status": "new_version_pending",
  "status_label": "Nueva versión pendiente",
  "message": "Existe una nueva versión de los términos que debe ser aceptada."
}
```

Estados posibles:

- `accepted`
- `pending`
- `new_version_pending`

Todavía no están implementados:
- reportes
- sorteos
- ganadores
- puntos

## Imagen de portada

Las promociones de participante también exponen:

```json
{
  "cover_image": {
    "url": "https://app.test/storage/promotions/covers/uuid.webp",
    "alt": "Arte principal de la promoción"
  }
}
```

Si la promoción no tiene imagen:

```json
{
  "cover_image": null
}
```

## Aceptación rápida y control de versión

El endpoint existente de aceptación se reutiliza desde el dashboard.

Payload mínimo:

```json
{
  "accepted": true
}
```

Payload recomendado cuando el frontend muestra una versión concreta en pantalla:

```json
{
  "accepted": true,
  "terms_version": "2.0"
}
```

Si la versión enviada ya no coincide con la vigente, la API responde `409` con `PROMOTION_TERMS_VERSION_OUTDATED`.
