Consulta de estado (/info)
Ruta independiente del wizard que permite a un cliente consultar una devolución ya creada. Componentes: app/info/page.tsx → FormRetrieveCase (vista form) o ReturnDetails (vista details).
La vista cambia a details en cuanto hay una devolución en RefundContext, y hace history.pushState, de modo que el botón atrás del navegador vuelve al formulario destruyendo la devolución cargada.
1. Formulario de recuperación
FormRetrieveCase pide número de devolución y email, validados con zod:
| Campo | Reglas |
|---|---|
returnId | Obligatorio (trim) y debe empezar por HWRET (Form.error.returnId.startsWith) |
email | Obligatorio y con formato de email válido |
El campo de devolución se precarga desde el query param ?orderNum= de la URL. Esto permite enlazar directamente desde los emails de Marketing Cloud o desde Salesforce Service Cloud: https://returns.hawkersco.com/info?orderNum=HWRET12345.
El parámetro se llama orderNum pero su valor es el número de devolución (HWRET…), no el del pedido. Es una herencia de una iteración anterior del formulario (commits 469c8e5 y 5826e0d).
Al enviar, getReturnDetails() llama a POST /api/get-return y mapea la respuesta de robo-api a un objeto Refund: filtra la línea de gastos de envío (SKU S00233), calcula shippingCost, traduce el método de devolución al idioma activo y guarda id_return_status y orderEmail.
2. Estados de una devolución
ReturnDetails no tiene los estados hardcodeados: los pide a robo-api al montar, con sus traducciones.
POST /api/get-return-status→ catálogo de estados de devolución.POST /api/get-return-line-status→ catálogo de estados de línea (artículo).
Los estados de devolución reconocidos por nombre en el componente son:
| Estado | Significado | Color en la línea temporal |
|---|---|---|
CREATED | Devolución creada | Verde (siempre completado) |
IN_REVIEW | En revisión | Amarillo |
APPROVED | Aprobada | Verde |
REFUNDED | Reembolsada (estado final) | Verde |
CANCELLED | Cancelada | Rojo |
El componente LabelStatus reutiliza la misma lógica para pintar el badge de estado de cada línea: amarillo para CREATED, azul para IN_REVIEW, verde para APPROVED/REFUNDED y rojo para CANCELLED. Si el estado no está entre esos cinco, o no hay traducción para el idioma activo, no se muestra badge.
3. Refresco automático
ReturnDetails vuelve a pedir el detalle con getReturnDetails() y compara el resultado con el estado actual (JSON.stringify); si difiere, actualiza RefundContext. Esto mantiene la vista al día sin recargar la página.
El useEffect que hace ese refresco tiene refund entre sus dependencias, por lo que se re-ejecuta en cada cambio del objeto. La comparación por JSON.stringify es lo único que corta el bucle. Ver Notas técnicas.
4. Descarga de PDFs
Al cargar el detalle se piden dos URLs firmadas (ver PDFs y URLs firmadas):
| Endpoint que firma | Ruta que renderiza | Contenido | |
|---|---|---|---|
| Documento de devolución | POST /api/get-pdf-url | /doc/[data] | Datos del cliente, QR del pedido, artículos, método e instrucciones |
| Documento de estado | POST /api/get-pdf-status-url | /status/[data] | Lo mismo con el estado de la devolución y de cada línea, sin QR |
De cada uno se generan dos variantes: la URL tal cual (se abre en el navegador, Content-Disposition: inline) y la misma con ?download=true (fuerza la descarga como HWRET….pdf).