RF-005 — Entrega: retiro en sucursal, envío a domicilio y promesa de plazo
|
|
| Estado |
Implementado |
| Tipo |
Lógica propia en el paso de entrega del checkout |
| Ubicación |
src/modules/checkout/components/shipping/index.tsx · src/lib/data/fulfillment.ts · src/modules/shipping/components/free-shipping-price-nudge/ |
| Depende de |
RF-000 · RF-004 · cotización de flete del backend |
Requisito
Presentar por separado el retiro en sucursal y el envío a domicilio; informar al cliente, antes de
elegir, cuánto va a demorar el retiro en cada sucursal según los artículos de su carrito; cotizar
en vivo el precio de cada opción de envío; e incentivar el envío gratuito informando cuánto falta
para alcanzar el umbral.
Solución adoptada
Separar las opciones por el tipo de su conjunto de fulfillment (pickup frente al resto) y
presentarlas como dos grupos excluyentes. La promesa de plazo se calcula en el navegador a partir
de la metadata de las variantes del carrito, tomando el máximo por sucursal.
flowchart TD
C[Carrito] --> IT[Ítems]
IT --> S{supplier_id de la variante}
S -->|1 · interno| A[t_entrega_aviadores · t_entrega_multi]
S -->|otro · externo| B[t_entrega para ambas sucursales]
A --> MAX[Máximo por sucursal]
B --> MAX
MAX --> P[Promesa por sucursal]
OPT[Opciones de envío] --> T{service_zone.fulfillment_set.type}
T -->|pickup| G1[Retiro en sucursal + promesa]
T -->|otro| G2[Envío a domicilio + precio cotizado]
Funciones
| Función |
Detalle |
| Separación de modalidades |
Dos grupos excluyentes: retiro en sucursal y envío a domicilio |
| Promesa de plazo por sucursal |
calculateMaxDeliveryTimes() recorre los ítems y toma el mayor plazo de cada sucursal |
| Redacción de la promesa |
Distingue «retiro inmediato en horas hábiles» de una cantidad de horas, con singular y plural |
| Cotización en vivo |
calculatePriceForShippingOption() por opción, resuelto en paralelo y tolerante a fallas individuales |
| Incentivo de envío gratuito |
Informa el monto restante y el avance hacia el umbral, en línea o como aviso emergente |
Reglas de negocio
- Tomar el plazo mayor del carrito: el pedido se retira completo, no por artículo.
- Leer los plazos por sucursal solo para el proveedor interno (
supplier_id = 1); para el resto,
aplicar el plazo general a ambas sucursales.
- Asociar cada opción de retiro con su sucursal por coincidencia de texto en el nombre
(
aviadores o central, y multiplaza).
- Expresar el plazo en horas hábiles, no en días corridos.
- Cotizar cada opción de envío por separado y no descartar el resto cuando una falla.
- Excluir mutuamente las dos modalidades: elegir retiro descarta la opción de envío y viceversa.
- Ofrecer envío a domicilio solo cuando la dirección del carrito tiene ciudad: las zonas se
resuelven por ciudad, así que sin ella no hay cobertura ni precio que mostrar. En ese caso se
explica la situación y se ofrece volver a cargar la dirección, y el retiro sigue disponible.
Criterios de aceptación
| # |
Criterio |
| 1 |
Presentar retiro y envío como grupos separados, y solo cuando existen opciones de cada tipo |
| 2 |
Exhibir el plazo de retiro por sucursal según el artículo de mayor demora del carrito |
| 3 |
Enunciar «retiro inmediato» cuando el plazo es cero para el proveedor interno |
| 4 |
Cotizar el precio de cada opción de envío para la dirección cargada |
| 5 |
Informar el monto restante para alcanzar el envío gratuito |
| 6 |
Explicar la ausencia de envío a domicilio y distinguir la falta de dirección de la falta de cobertura |
Limitaciones conocidas
- Quedar la promesa en cero cuando la metadata de la variante no viene cargada desde Medusa
(
supplier_id, t_entrega, t_entrega_aviadores, t_entrega_multi), sin distinguir «sin
demora» de «sin dato».
- Fijar las dos sucursales en el código y resolverlas por texto de su nombre.
- Calcular la promesa en el navegador a partir de metadata del carrito, sin validación del backend.