Saltar a contenido

⚠ Vigencia por confirmar. Los widgets que describe este documento (location-geozones.tsx, location-shipping-config.tsx) no existen en las ramas publicadas (main/staging/develop, todas en 14749d6 al 2026-08-19).

Widgets de Administración de Envíos

Este documento describe los widgets de administración implementados para gestionar la configuración de envíos en el panel de administración de Medusa v2.

Ubicación

Todos los widgets se inyectan en la zona location.details.after, es decir, aparecen en la vista de detalle de un Stock Location.


Widget 1: Gestión de GeoZones

Archivo: src/admin/widgets/location-geozones.tsx

Propósito

Permite gestionar las ciudades (geo_zones) de las zonas de servicio asociadas a un location, incluyendo la configuración de proveedores de envío disponibles para cada ciudad.

Funcionalidades

  • Selector de zona de servicio (filtra solo fulfillment sets de tipo "shipping")
  • Tabla de ciudades configuradas con búsqueda
  • Agregar nueva ciudad con:
  • Nombre de ciudad
  • Departamento (lista de departamentos de Paraguay)
  • Configuración de proveedores (CLX, MC Group, AEX)
  • Horas de entrega por proveedor
  • Editar ciudad existente
  • Eliminar ciudad

Estructura de Datos

// GeoZone.metadata
{
  "city_code": "PY001",
  "clx_available": true,
  "clx_hours": 24,
  "mc_available": true,
  "mc_hours": 48,
  "aex_available": false,
  "aex_hours": null
}

Archivos Relacionados

src/admin/components/geozones/
├── index.ts
├── types.ts
├── constants.ts              # Departamentos de Paraguay
├── utils.ts
├── hooks/
│   ├── useServiceZonesLoader.ts
│   └── useGeoZonesManager.ts
└── components/
    ├── ServiceZoneSelector.tsx
    ├── GeoZonesTable.tsx
    ├── AddCityModal.tsx
    ├── EditCityModal.tsx
    └── ProviderMetadataForm.tsx

Widget 2: Configuración de Envíos

Archivo: src/admin/widgets/location-shipping-config.tsx

Propósito

Permite gestionar los tipos de caja para cálculo de envío y los precios por zona de servicio, incluyendo precios especiales por categoría de producto.

Pestañas

Pestaña 1: Tipos de Caja

Gestiona los tamaños de caja disponibles para el cálculo de envío. Los tipos de caja se almacenan en FulfillmentSet.metadata.box_types y son compartidos por todas las zonas de servicio.

Funcionalidades: - Listar tipos de caja con dimensiones y peso máximo - Agregar nuevo tipo de caja - Editar tipo existente - Eliminar tipo de caja - Ordenamiento por sort_order (prioridad de selección) - Caja default (fallback): Permite crear una caja sin dimensiones que se usa cuando el producto excede el tamaño de todas las demás cajas

Caja Default:

Una caja puede marcarse como "default" (fallback) para manejar productos que exceden las dimensiones de las cajas regulares. Características: - Solo puede existir una caja default por FulfillmentSet - No requiere configurar dimensiones (largo, ancho, alto) ni peso máximo - Se usa automáticamente cuando ninguna caja regular es suficiente para el producto - Debe tener un precio configurado en la pestaña de Precios para funcionar - En la tabla se muestra con un badge "Default" y "Sin límite" en dimensiones

Estructura de Datos:

// FulfillmentSet.metadata.box_types
[
  {
    "code": "sobre",
    "name": "Sobre",
    "max_length": 30,
    "max_width": 20,
    "max_height": 5,
    "max_weight": 1,
    "sort_order": 1
  },
  {
    "code": "caja_1",
    "name": "Caja 1",
    "max_length": 40,
    "max_width": 30,
    "max_height": 20,
    "max_weight": 5,
    "sort_order": 2
  },
  {
    "code": "caja_especial",
    "name": "Caja Especial (productos grandes)",
    "max_length": 0,
    "max_width": 0,
    "max_height": 0,
    "max_weight": 0,
    "sort_order": 99,
    "is_default": true  // Caja fallback
  }
]

Pestaña 2: Precios por Zona

Gestiona los precios de envío por tipo de caja para cada opción de envío (ShippingOption), además de precios especiales por categoría de producto.

Funcionalidades: - Selector de zona de servicio - Selector de opción de envío (MC Group, CLX, etc.) - Tabla editable de precios por tipo de caja - Gestión de precios especiales por categoría: - Agregar categoría con precio fijo - Editar precio de categoría - Eliminar categoría - Indicador de cambios sin guardar - Advertencia de tipos de caja sin precio asignado

Estructura de Datos:

// ShippingOption.metadata
{
  "prices": {
    "sobre": 25000,
    "caja_1": 30000,
    "caja_2": 35000,
    "caja_3": 40000
  },
  "special_categories": [
    {
      "category_id": "pcat_01ABC123",
      "category_name": "Sillas Gamer",
      "price": 50000
    },
    {
      "category_id": "pcat_02DEF456",
      "category_name": "Colchones",
      "price": 60000
    }
  ]
}

Archivos Relacionados

src/admin/components/shipping-config/
├── index.ts
├── types.ts
├── constants.ts
├── utils.ts
├── hooks/
│   ├── useBoxTypesManager.ts
│   ├── useShippingOptionsLoader.ts
│   └── useShippingPrices.ts
└── components/
    ├── BoxTypesTab.tsx
    ├── BoxTypesTable.tsx
    ├── BoxTypeModal.tsx
    ├── PricesTab.tsx
    ├── PricesTable.tsx
    ├── SpecialCategoriesTable.tsx
    └── SpecialCategoryModal.tsx

Endpoints API Personalizados

Dado que el SDK de Medusa v2 no expone métodos directos para actualizar metadata de FulfillmentSet y ShippingOption, se crearon endpoints personalizados:

GET/POST /admin/fulfillment-sets/:id

Archivo: src/api/admin/fulfillment-sets/[id]/route.ts

  • GET: Obtiene un fulfillment set con sus relaciones
  • POST: Actualiza el fulfillment set (incluyendo metadata)

POST /admin/shipping-options/:id/metadata

Archivo: src/api/admin/shipping-options/[id]/metadata/route.ts

  • POST: Actualiza solo la metadata de una shipping option (merge con metadata existente)

Jerarquía de Datos

StockLocation
└── FulfillmentSet (type: "shipping")
    ├── metadata.box_types[]           ← Tipos de caja (global)
    │
    └── ServiceZone
        ├── GeoZone[]                   ← Ciudades con proveedores
        │   └── metadata                ← CLX/MC/AEX config
        │
        └── ShippingOption
            └── metadata
                ├── prices{}            ← Precios por caja
                └── special_categories[] ← Precios por categoría

Lógica de Cálculo de Precio (Referencia)

El fulfillment provider implementa la siguiente lógica:

  1. Verificar categoría especial: Si el producto pertenece a una categoría con precio especial, usar ese precio directamente.

  2. Si no hay categoría especial:

  3. Obtener dimensiones del producto más grande del carrito (desde base de datos)
  4. Nota: Las dimensiones del producto están en mm, las cajas en cm. Se divide por 10 para convertir.
  5. Buscar el tipo de caja más pequeño que contenga el producto entre las cajas regulares (no default)
  6. Si ninguna caja regular es suficiente, usar la caja default como fallback
  7. Si no hay caja default configurada y ninguna caja regular es suficiente, retornar error NO_FITTING_BOX
  8. Obtener el precio de la caja seleccionada desde ShippingOption.metadata.prices[caja.code]

  9. Retornar precio final

Ejemplo de flujo:

Producto: Silla Gamer (850mm x 650mm x 350mm = 85cm x 65cm x 35cm)

1. Evaluar caja_1 (40x30x20 cm): NO CABE
2. Evaluar caja_2 (50x40x30 cm): NO CABE
3. Evaluar caja_3 (60x50x40 cm): NO CABE
4. Ninguna caja regular es suficiente
5. Usar caja_especial (is_default: true): PRECIO = 80.000 Gs


Formato de Precios

  • Los precios se almacenan en guaraníes (PYG) como enteros
  • El widget formatea con separador de miles (ej: 25.000)
  • Los inputs aceptan formato con puntos/comas y los parsean automáticamente

Validaciones

Tipos de Caja

  • Código único (alfanumérico + guiones bajos)
  • Nombre requerido
  • Cajas regulares: Dimensiones > 0 y Peso máximo > 0
  • Caja default: No requiere dimensiones ni peso (se ignoran)
  • Solo puede existir una caja default por FulfillmentSet

Precios

  • Precio >= 0
  • Advertencia visual si faltan precios para algún tipo de caja

Categorías Especiales

  • Categoría única por shipping option
  • Precio > 0

Uso

  1. Ir a Inventory → Stock Locations en el admin
  2. Seleccionar un location con fulfillment set de tipo "shipping"
  3. Los widgets aparecen automáticamente debajo de los detalles del location:
  4. Gestión de GeoZones: Para configurar ciudades y proveedores
  5. Configuración de Envíos: Para tipos de caja y precios