Skip to main content

Alta manual de devoluciones (/returns/create)

Permite a un empleado crear una devolución en nombre del cliente — el caso típico de una devolución en tienda o gestionada por ATC por teléfono. Es el equivalente interno del wizard del portal del cliente, con tres diferencias de fondo: se piden los datos logísticos (origen, mercancía reclamada, almacén), el email de confirmación es opcional y la devolución queda asociada al empleado que la crea.

La UI es un acordeón de 4 pasos más una pantalla de éxito (accordionValue 1 → 5). Solo el paso activo está desplegado; los ya completados muestran un check verde y un botón Editar para volver.

flowchart LR
S1[1 · Recuperar pedido<br/>nº pedido + email] --> S2[2 · Artículos<br/>origen · mercancía · almacén]
S2 --> S3[3 · Método de<br/>devolución]
S3 --> S4[4 · Revisar<br/>y confirmar]
S4 -->|POST /api/set-return| S5[5 · Éxito<br/>HWRET… + email opcional]

Estado del proceso (RefundContext)

Todo el wizard se apoya en context/RefundContext.tsx, que guarda { refund, order, accordionValue } y lo persiste en localStorage bajo la clave refundProcess:

  • Se rehidrata al montar (isMounted evita parpadeos: hasta entonces se muestran skeletons).
  • Se reescribe en cada cambio del proceso.
  • Se borra al llegar al paso 5, para que la siguiente devolución empiece limpia.

El botón Iniciar nueva devolución (visible desde el paso 2) pide confirmación y llama a destroyRefund().

note

El portal del cliente usa sessionStorage y este usa localStorage: aquí el proceso sobrevive al cierre de la pestaña, lo que resulta práctico en tienda pero deja datos de pedido en el equipo hasta completar o reiniciar el alta.

Paso 1 — Recuperar el pedido

form-get-order.tsx: número de pedido y email, validados con zod (ambos obligatorios, email con formato válido; placeholder HWXX999999). Llama a POST /api/get-order, guarda el pedido en el contexto y avanza al paso 2.

A diferencia del portal del cliente, este handler no envía is_customer: true a robo-api, por lo que la respuesta no está restringida a la vista de cliente.

Paso 2 — Artículos y datos logísticos

form-return-items.tsx es el paso con más reglas. Por cada artículo seleccionado hay que fijar tres campos:

CampoValor por defecto
OrigenEl origen WITHDRAWAL del catálogo (/return-origin/info)
Mercancía reclamada (CLAIMED_GOODS.yes)
AlmacénEl almacén del pedido (order.id_return_store), salvo Grecia (ver abajo)

Almacén por defecto y caso Grecia

const userDefaultWarehouse =
order?.country === GREECE_COUNTRY_CODE // "GR"
? GREECE_WAREHOUSE_ID // 61
: order?.id_return_store || -1;

Los pedidos de Grecia se asignan al almacén 61 de forma incondicional, ignorando el almacén del pedido (commit 27594a3). Ambos valores están codificados en constants/warehouses.ts.

Validaciones (zod + superRefine)

  • Al menos un artículo seleccionado.
  • Mercancía reclamada obligatoria en cada artículo.
  • Si la mercancía reclamada es , el almacén es obligatorio y debe ser mayor que 0.

Gastos de envío y cancelaciones

  • La línea de gastos de envío (SKU S00233) se muestra con un icono de camión en lugar de imagen y no permite editar los datos logísticos.
  • Si todos los productos quedan con origen CANCELLED, la línea de gastos de envío se marca también como cancelada automáticamente. Se avisa por diálogo antes de continuar.

Paso 3 — Método de devolución

form-return-method.tsx ofrece los métodos habilitados para el país del pedido (POST /api/methods/getSearchMethods, que en robo-api es /return-method/search). El precio del método se resta del total.

Paso 4 — Revisar y confirmar

resume.tsx muestra el resumen completo: artículos con su origen, mercancía reclamada y almacén (solo si la mercancía es ), gastos de envío, método elegido y total.

Incluye un checkbox opt-in para enviar el email de confirmación al cliente. Sin marcarlo, la devolución se crea sin notificar — comportamiento deliberado para altas internas o correcciones.

Al confirmar (diálogo de confirmación mediante):

  1. Si todos los productos están cancelados, propaga la cancelación a la línea de gastos de envío.
  2. POST /api/set-return, que añade customer: <sub de Auth0>la devolución queda vinculada al empleado que la crea.
  3. Con el return_name_id devuelto, firma la URL del PDF en el idioma del pedido (order.locale recortado a dos letras).
  4. Si el checkbox estaba marcado, dispara el journey CREATED de Marketing Cloud (una sola vez, journeyTriggered).
  5. Avanza al paso 5 y limpia localStorage.

Paso 5 — Éxito

success-message.tsx confirma el alta con el número de devolución generado y permite iniciar otra.

Diferencias con el wizard del portal del cliente

AspectoPortal del clienteBack-office
Navegación4 pasos con Stepper e historialAcordeón de 4 pasos con botón Editar por paso
PersistenciasessionStoragelocalStorage
Motivo de devoluciónObligatorio por artículoNo se pide
Origen / mercancía / almacénNo se pidenObligatorios por artículo
Email de confirmaciónSiempre se envíaOpcional (checkbox)
IdentidadCliente (pedido + email)Empleado autenticado (customer: sub)